diff --git a/.github/workflows/build_test.Dockerfile b/.github/workflows/build_test.Dockerfile index a8bf62741..305575dc9 100644 --- a/.github/workflows/build_test.Dockerfile +++ b/.github/workflows/build_test.Dockerfile @@ -13,7 +13,8 @@ RUN apt update && \ lldb \ software-properties-common \ tar \ - zstd && \ + zstd \ + protobuf-compiler && \ add-apt-repository ppa:deadsnakes/ppa && \ apt install -y python3.10 && \ curl https://bootstrap.pypa.io/get-pip.py > get-pip.py && \ diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml index 8b488d0a4..05be4c392 100644 --- a/.github/workflows/build_test.yaml +++ b/.github/workflows/build_test.yaml @@ -8,7 +8,7 @@ jobs: build-and-test: runs-on: [self-hosted, poc] container: - image: threefolddev/tfchain:1 + image: threefolddev/tfchain:2 env: DEBIAN_FRONTEND: noninteractive steps: @@ -25,8 +25,8 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ substrate-node/target/ - key: ${{ runner.os }}-tfchain-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: ${{ runner.os }}-tfchain-cargo- + key: ${{ runner.os }}-tfchain-build-cache-${{ hashFiles('**/Cargo.lock') }} + restore-keys: ${{ runner.os }}-tfchain-build-cache - name: Build run: | @@ -47,3 +47,9 @@ jobs: cd substrate-node/tests robot -d _output_tests/ . + - uses: actions/upload-artifact@v3 + if: always() + with: + name: integration test output + path: substrate-node/tests/_output_tests/ + diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 000000000..b03ded136 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @DylanVerstraete @brandonpille @renauter @robvanmieghem @leesmet diff --git a/docs/architecture/0002-smart-contract-billing-changed.md b/docs/architecture/0002-smart-contract-billing-changed.md new file mode 100644 index 000000000..2f5c1c41d --- /dev/null +++ b/docs/architecture/0002-smart-contract-billing-changed.md @@ -0,0 +1,28 @@ +# 2. Changed smart contract billing workflow + +Date: 2022-10-12 + +## Status + +Accepted + +## Context + +TFchain bills contract using an internal feature of susbtrate called `on_finalize`. This function / hook is executed after every block, in this function the time to compute is limited since this runs before the block production is finished. We are worried that if the usage of the grid grows, this on finalize method would need to do too much computations and that the block time would be impacted. + +## Decision + +We searched for an alternative to this `on_finalize` method within the substrate framework. We found a hook that fires after a block is produced, but in that hook the result of some computation must be submitted onchain with an extrinsic. This offchain worker cannot modify chain storage directly, rather it can only do that through an extrinsic. + +## Consequences + +### the good + +- The billing for a contract is now executed after a block is produced and not within that same block. +- Atleast one offchain worker must run with the `smct` keytype in order to bill contracts. +- Contracts billing cycles do not rely anymore on a previously successful bill. +- External users can call `bill_contract` but don't need to. + +### the worrying + +- If no validators run an offchain worker with the `smct` keytype, no contracts will be billed. diff --git a/docs/architecture/0003-third-party-service-contract.md b/docs/architecture/0003-third-party-service-contract.md new file mode 100644 index 000000000..6329d0078 --- /dev/null +++ b/docs/architecture/0003-third-party-service-contract.md @@ -0,0 +1,25 @@ +# 3. Third party service contract + +Date: 2022-10-17 + +## Status + +Accepted + +## Context + +See [here](https://github.com/threefoldtech/tfchain/issues/445) for more details. + +## Decision + +The third party service contract flow is described [here](../../substrate-node/pallets/pallet-smart-contract/third-party_service_contract.md#flow). + +## Consequences + +### the good + +- It is now possible to create generic contract between two `TFChain` users (without restriction of account type) for some service and bill for it. + +### the worrying + +- Keep eyes on potential abuses and be prepared to handle all the malicious cases that can show up. \ No newline at end of file diff --git a/readme.md b/readme.md index ec1782edd..da2c55f1a 100644 --- a/readme.md +++ b/readme.md @@ -10,6 +10,7 @@ Ensure you have the following installed first: - libclang-dev - clang lldb lld - build-essential +- protoc You will also need rust and nightly installed. diff --git a/substrate-node/Cargo.lock b/substrate-node/Cargo.lock index fa5d6db62..09ec58d43 100644 --- a/substrate-node/Cargo.lock +++ b/substrate-node/Cargo.lock @@ -18,7 +18,16 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ - "gimli", + "gimli 0.26.2", +] + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli 0.27.0", ] [[package]] @@ -33,7 +42,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", ] [[package]] @@ -68,20 +77,29 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -93,9 +111,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.58" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "approx" @@ -107,19 +125,16 @@ dependencies = [ ] [[package]] -name = "arrayref" -version = "0.3.6" +name = "array-bytes" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" [[package]] -name = "arrayvec" -version = "0.4.12" +name = "arrayref" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -dependencies = [ - "nodrop", -] +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" @@ -141,9 +156,9 @@ checksum = "e22d1f4b888c298a027c99dc9048015fac177587de20fc30232a057dfbe24a21" [[package]] name = "async-channel" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" dependencies = [ "concurrent-queue", "event-listener", @@ -152,23 +167,23 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" dependencies = [ + "async-lock", "async-task", "concurrent-queue", "fastrand", "futures-lite", - "once_cell", "slab", ] [[package]] name = "async-global-executor" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" dependencies = [ "async-channel", "async-executor", @@ -176,108 +191,50 @@ dependencies = [ "async-lock", "blocking", "futures-lite", - "num_cpus", "once_cell", ] [[package]] name = "async-io" -version = "1.7.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" +checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" dependencies = [ + "async-lock", + "autocfg", "concurrent-queue", "futures-lite", "libc", "log", - "once_cell", "parking", "polling", "slab", "socket2", "waker-fn", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "async-lock" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-process" -version = "1.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" dependencies = [ - "async-io", - "blocking", - "cfg-if", "event-listener", "futures-lite", - "libc", - "once_cell", - "signal-hook", - "winapi", -] - -[[package]] -name = "async-std" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" -dependencies = [ - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite 0.2.9", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-std-resolver" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2f8a4a203be3325981310ab243a28e6e4ea55b6519bffce05d41ab60e09ad8" -dependencies = [ - "async-std", - "async-trait", - "futures-io", - "futures-util", - "pin-utils", - "socket2", - "trust-dns-resolver", ] [[package]] name = "async-task" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.56" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" +checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" dependencies = [ "proc-macro2", "quote", @@ -286,9 +243,9 @@ dependencies = [ [[package]] name = "asynchronous-codec" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0de5164e5edbf51c45fb8c2d9664ae1c095cce1b265ecf7569093c0d66ef690" +checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182" dependencies = [ "bytes", "futures-sink", @@ -309,7 +266,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -322,24 +279,24 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.65" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ - "addr2line", + "addr2line 0.19.0", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.28.4", + "object 0.30.0", "rustc-demangle", ] [[package]] name = "base-x" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc19a4937b4fbd3fe3379793130e42060d10627a360f2127802b10b87e7baf74" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" [[package]] name = "base16ct" @@ -355,9 +312,15 @@ checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64ct" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] name = "beef" @@ -368,12 +331,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bimap" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0455254eb5c6964c4545d8bac815e1a1be4f3afe0ae695ea539c12d728d44b" - [[package]] name = "bincode" version = "1.3.3" @@ -385,9 +342,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.59.2" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" dependencies = [ "bitflags", "cexpr", @@ -410,9 +367,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitvec" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", "radium", @@ -422,21 +379,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" -dependencies = [ - "digest 0.10.3", -] - -[[package]] -name = "blake2-rfc" -version = "0.2.18" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "arrayvec 0.4.12", - "constant_time_eq", + "digest 0.10.6", ] [[package]] @@ -447,7 +394,7 @@ checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] @@ -458,20 +405,20 @@ checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] name = "blake3" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" dependencies = [ "arrayref", "arrayvec 0.7.2", "cc", "cfg-if", - "constant_time_eq", + "constant_time_eq 0.2.4", ] [[package]] @@ -480,7 +427,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding 0.1.5", + "block-padding", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -492,17 +439,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding 0.2.1", - "generic-array 0.14.5", + "generic-array 0.14.6", ] [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", ] [[package]] @@ -514,24 +460,18 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "blocking" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" +checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" dependencies = [ "async-channel", + "async-lock", "async-task", "atomic-waker", "fastrand", "futures-lite", - "once_cell", ] [[package]] @@ -560,15 +500,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "byte-slice-cast" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "byte-tools" @@ -584,9 +524,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "bzip2-sys" @@ -599,17 +539,11 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" - [[package]] name = "camino" -version = "1.0.9" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" +checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" dependencies = [ "serde", ] @@ -625,22 +559,22 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.14.3" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1007653411165d371d51e7174a6f0e81ec815ecb425c0440c30d5f1ae64e0f" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.10", + "semver 1.0.16", "serde", "serde_json", ] [[package]] name = "cc" -version = "1.0.73" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" dependencies = [ "jobserver", ] @@ -654,17 +588,32 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-expr" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db" +dependencies = [ + "smallvec", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chacha20" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" +checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" dependencies = [ "cfg-if", "cipher", @@ -674,9 +623,9 @@ dependencies = [ [[package]] name = "chacha20poly1305" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" +checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" dependencies = [ "aead", "chacha20", @@ -687,22 +636,24 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", "time", + "wasm-bindgen", "winapi", ] [[package]] name = "cid" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc949bff6704880faf064c42a4854032ab07bfcf3a4fcb82a57470acededb69c" +checksum = "f6ed9c8b2d17acb8110c46f1da5bf4a696d745e1474a16db0cd2b49cd0249bf2" dependencies = [ "core2", "multibase", @@ -717,18 +668,18 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", ] [[package]] name = "clang-sys" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" dependencies = [ "glob", "libc", - "libloading 0.7.3", + "libloading", ] [[package]] @@ -741,33 +692,31 @@ dependencies = [ "atty", "bitflags", "strsim 0.8.0", - "textwrap 0.11.0", + "textwrap", "unicode-width", "vec_map", ] [[package]] name = "clap" -version = "3.2.6" +version = "4.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a" +checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" dependencies = [ - "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", + "is-terminal", "once_cell", "strsim 0.10.0", "termcolor", - "textwrap 0.15.0", ] [[package]] name = "clap_derive" -version = "3.2.6" +version = "4.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6db9e867166a43a53f7199b5e4d1f522a1e5bd626654be263c999ce59df39a" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -778,27 +727,28 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" dependencies = [ "os_str_bytes", ] [[package]] -name = "cmake" -version = "0.1.48" +name = "codespan-reporting" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ - "cc", + "termcolor", + "unicode-width", ] [[package]] name = "comfy-table" -version = "5.0.1" +version = "6.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b103d85ca6e209388771bfb7aa6b68a7aeec4afbf6f0a0264bfbf50360e5212e" +checksum = "e621e7e86c46fd8a14c32c6ae3cb95656621b4743a27d0cffedb831d46e7ad21" dependencies = [ "strum", "strum_macros", @@ -807,18 +757,18 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "1.2.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" dependencies = [ - "cache-padded", + "crossbeam-utils", ] [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" [[package]] name = "constant_time_eq" @@ -826,6 +776,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "constant_time_eq" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" + [[package]] name = "core-foundation" version = "0.9.3" @@ -862,68 +818,71 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "52056f6d0584484b57fa6c1a65c1fcb15f3780d8b6a758426d9e3084169b2ddd" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "18fed94c8770dc25d01154c3ffa64ed0b3ba9d583736f305fed7beebe5d9cf74" dependencies = [ + "arrayvec 0.7.2", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-entity", - "gimli", + "cranelift-isle", + "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "1c451b81faf237d11c7e4f3165eeb6bac61112762c5cfe7b4c0fb7241474358f" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "e7c940133198426d26128f08be2b40b0bd117b84771fd36798969c4d712d81fc" [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "87a0f1b2fdc18776956370cf8d9b009ded3f855350c480c1c52142510961f352" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "34897538b36b216cc8dd324e73263596d51b8cf610da6498322838b2546baf8a" dependencies = [ "cranelift-codegen", "log", @@ -931,11 +890,17 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cranelift-isle" +version = "0.88.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b2629a569fae540f16a76b70afcc87ad7decb38dc28fa6c648ac73b51e78470" + [[package]] name = "cranelift-native" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501241b0cdf903412ec9075385ac9f2b1eb18a89044d1538e97fab603231f70c" +checksum = "20937dab4e14d3e225c5adfc9c7106bafd4ac669bdb43027b911ff794c6fb318" dependencies = [ "cranelift-codegen", "libc", @@ -944,9 +909,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.82.3" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d9e4211bbc3268042a96dd4de5bd979cda22434991d035f5f8eacba987fad2" +checksum = "80fc2288957a94fd342a015811479de1837850924166d1f1856d8406e6f3609b" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -990,25 +955,24 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.11" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset", + "memoffset 0.7.1", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.9" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -1019,23 +983,23 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array 0.14.5", - "rand_core 0.6.3", + "generic-array 0.14.6", + "rand_core 0.6.4", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", "typenum", ] @@ -1045,7 +1009,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", "subtle", ] @@ -1055,20 +1019,10 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", "subtle", ] -[[package]] -name = "ctor" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "ctr" version = "0.8.0" @@ -1078,17 +1032,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "cuckoofilter" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" -dependencies = [ - "byteorder", - "fnv", - "rand 0.7.3", -] - [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -1117,22 +1060,67 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0-pre.1" +version = "4.0.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4033478fbf70d6acf2655ac70da91ee65852d69daf7a67bf7a2f518fb47aafcf" +checksum = "67bc65846be335cb20f4e52d49a437b773a2c1fdb42b19fc84e79e6f6771536f" dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.3", + "cfg-if", + "fiat-crypto", + "packed_simd_2", + "platforms 3.0.2", "subtle", "zeroize", ] +[[package]] +name = "cxx" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "data-encoding-macro" @@ -1156,11 +1144,12 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", ] [[package]] @@ -1174,6 +1163,12 @@ dependencies = [ "syn", ] +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "digest" version = "0.8.1" @@ -1189,16 +1184,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", ] [[package]] name = "digest" -version = "0.10.3" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.2", + "block-buffer 0.10.3", "crypto-common", "subtle", ] @@ -1254,6 +1249,12 @@ dependencies = [ "quick-error", ] +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + [[package]] name = "downcast-rs" version = "1.2.0" @@ -1262,9 +1263,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "dtoa" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5caaa75cbd2b960ff1e5392d2cfb1f44717fffe12fc1f32b7b5d1267f99732a6" +checksum = "c00704156a7de8df8da0911424e30c2049957b0a714542a44e05fe693dd85313" [[package]] name = "dyn-clonable" @@ -1289,15 +1290,15 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "140206b78fb2bc3edbcfc9b5ccbd0b30699cfe8d348b8b31b330e47df5291a5a" +checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1328,25 +1329,40 @@ dependencies = [ "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", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", + "digest 0.10.6", "ff", - "generic-array 0.14.5", + "generic-array 0.14.6", "group", - "rand_core 0.6.3", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -1354,9 +1370,9 @@ dependencies = [ [[package]] name = "enum-as-inner" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" +checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ "heck 0.4.0", "proc-macro2", @@ -1366,9 +1382,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -1378,10 +1394,23 @@ dependencies = [ ] [[package]] -name = "environmental" -version = "1.1.3" +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "environmental" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" +checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" [[package]] name = "errno" @@ -1406,9 +1435,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "exit-future" @@ -1433,9 +1462,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -1451,45 +1480,63 @@ dependencies = [ [[package]] name = "ff" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" + [[package]] name = "file-per-thread-logger" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21e16290574b39ee41c71aeb90ae960c504ebaf1e2a1c87bd52aa56ed6e1a02f" dependencies = [ - "env_logger", + "env_logger 0.9.3", "log", ] +[[package]] +name = "filetime" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.42.0", +] + [[package]] name = "finality-grandpa" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9def033d8505edf199f6a5d07aa7e6d2d6185b164293b77f0efd108f4f3e11d" +checksum = "b22349c6a11563a202d95772a68e0fcf56119e74ea8a2a19cf2301460fcd0df5" dependencies = [ "either", "futures", "futures-timer", "log", "num-traits", - "parity-scale-codec 3.1.5", - "parking_lot 0.11.2", + "parity-scale-codec 3.2.1", + "parking_lot 0.12.1", "scale-info", ] [[package]] name = "fixed-hash" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", "rand 0.8.5", @@ -1499,21 +1546,30 @@ dependencies = [ [[package]] name = "fixedbitset" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", "libz-sys", "miniz_oxide", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1523,65 +1579,72 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", ] [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", "linregress", "log", - "parity-scale-codec 3.1.5", - "paste 1.0.7", + "parity-scale-codec 3.2.1", + "paste 1.0.11", "scale-info", "serde", "sp-api", "sp-application-crypto", + "sp-core", "sp-io", "sp-runtime", "sp-runtime-interface", - "sp-std", + "sp-std 5.0.0", "sp-storage", ] [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "Inflector", + "array-bytes", "chrono", - "clap 3.2.6", + "clap 4.0.32", "comfy-table", "frame-benchmarking", "frame-support", "frame-system", + "gethostname", "handlebars", "hash-db", - "hex", "itertools", "kvdb", "lazy_static", "linked-hash-map", "log", "memory-db", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "rand 0.8.5", "rand_pcg 0.3.1", "sc-block-builder", @@ -1603,6 +1666,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "sp-state-machine", + "sp-std 5.0.0", "sp-storage", "sp-trie", "tempfile", @@ -1613,16 +1677,17 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "frame-try-runtime", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-tracing", ] @@ -1633,15 +1698,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df6bb8542ef006ef0de09a5c4420787d79823c0ed7924225822362fd2bf2ff2d" dependencies = [ "cfg-if", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", ] +[[package]] +name = "frame-remote-externalities" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" +dependencies = [ + "env_logger 0.9.3", + "futures", + "log", + "parity-scale-codec 3.2.1", + "serde", + "serde_json", + "sp-core", + "sp-io", + "sp-runtime", + "sp-version", + "substrate-rpc-client", + "tokio", +] + [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "bitflags", "frame-metadata", @@ -1650,11 +1734,12 @@ dependencies = [ "k256", "log", "once_cell", - "parity-scale-codec 3.1.5", - "paste 1.0.7", + "parity-scale-codec 3.2.1", + "paste 1.0.11", "scale-info", "serde", "smallvec", + "sp-api", "sp-arithmetic", "sp-core", "sp-core-hashing-proc-macro", @@ -1663,18 +1748,21 @@ dependencies = [ "sp-runtime", "sp-staking", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-tracing", + "sp-weights", "tt-call", ] [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "Inflector", + "cfg-expr", "frame-support-procedural-tools", + "itertools", "proc-macro2", "quote", "syn", @@ -1683,7 +1771,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -1695,7 +1783,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "proc-macro2", "quote", @@ -1705,65 +1793,55 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-version", + "sp-weights", ] [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-api", ] [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", + "parity-scale-codec 3.2.1", "sp-api", "sp-runtime", - "sp-std", -] - -[[package]] -name = "fs-swap" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d47dad3685eceed8488986cad3d5027165ea5edb164331770e2059555f10a5" -dependencies = [ - "lazy_static", - "libc", - "libloading 0.5.2", - "winapi", + "sp-std 5.0.0", ] [[package]] @@ -1790,9 +1868,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -1805,9 +1883,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -1815,15 +1893,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" dependencies = [ "futures-core", "futures-task", @@ -1833,9 +1911,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-lite" @@ -1854,9 +1932,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ "proc-macro2", "quote", @@ -1865,9 +1943,9 @@ dependencies = [ [[package]] name = "futures-rustls" -version = "0.22.1" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01fe9932a224b72b45336d96040aa86386d674a31d0af27d800ea7bc8ca97fe" +checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" dependencies = [ "futures-io", "rustls", @@ -1876,15 +1954,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-timer" @@ -1894,9 +1972,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -1910,6 +1988,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.12.4" @@ -1921,14 +2008,24 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", ] +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -1944,9 +2041,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "js-sys", @@ -1967,15 +2064,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" dependencies = [ "fallible-iterator", "indexmap", "stable_deref_trait", ] +[[package]] +name = "gimli" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" + [[package]] name = "glob" version = "0.3.0" @@ -1995,34 +2098,22 @@ dependencies = [ "regex", ] -[[package]] -name = "gloo-timers" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "group" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] [[package]] name = "h2" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -2039,9 +2130,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.3.1" +version = "4.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66d0c1b6e3abfd1e72818798925e16e02ed77e1b47f6c25a95a23b377ee4299" +checksum = "035ef95d03713f2c347a72547b7cd38cbc9af7cd51e6099fb62d586d4a6dee3a" dependencies = [ "log", "pest", @@ -2068,18 +2159,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] @@ -2108,6 +2190,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -2139,12 +2230,6 @@ dependencies = [ "proc-macro-hack", ] -[[package]] -name = "hex_fmt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" - [[package]] name = "hmac" version = "0.8.1" @@ -2165,6 +2250,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "hmac-drbg" version = "0.3.0" @@ -2172,7 +2266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ "digest 0.9.0", - "generic-array 0.14.5", + "generic-array 0.14.6", "hmac 0.8.1", ] @@ -2195,7 +2289,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.2", + "itoa", ] [[package]] @@ -2209,11 +2303,17 @@ dependencies = [ "pin-project-lite 0.2.9", ] +[[package]] +name = "http-range-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" + [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -2229,9 +2329,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.19" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -2242,7 +2342,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.2", + "itoa", "pin-project-lite 0.2.9", "socket2", "tokio", @@ -2253,9 +2353,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.0" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ "http", "hyper", @@ -2266,6 +2366,30 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "idna" version = "0.2.3" @@ -2277,6 +2401,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "if-addrs" version = "0.7.0" @@ -2289,9 +2423,9 @@ dependencies = [ [[package]] name = "if-watch" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774d59367a3d26965d21ac70a86fcb697d83405d1c4312d1d8a6855296af0cf7" +checksum = "065c008e570a43c00de6aed9714035e5ea6a498c255323db9091722af6ee67dd" dependencies = [ "async-io", "core-foundation", @@ -2311,14 +2445,14 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", ] [[package]] name = "impl-serde" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" dependencies = [ "serde", ] @@ -2334,14 +2468,20 @@ dependencies = [ "syn", ] +[[package]] +name = "index-fixed" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161ceaf2f41b6cd3f6502f5da085d4ad4393a51e0c70ed2fce1d5698d798fae" + [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown 0.12.1", + "hashbrown", "serde", ] @@ -2365,9 +2505,19 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "0.5.3" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074" + +[[package]] +name = "io-lifetimes" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec58677acfea8a15352d42fc87d11d63596ade9239e0a7c9352914417515dbe6" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] [[package]] name = "ip_network" @@ -2377,9 +2527,9 @@ checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" [[package]] name = "ipconfig" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98" +checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" dependencies = [ "socket2", "widestring", @@ -2389,45 +2539,51 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" [[package]] -name = "itertools" -version = "0.10.3" +name = "is-terminal" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ - "either", + "hermit-abi 0.2.6", + "io-lifetimes 1.0.3", + "rustix 0.36.5", + "windows-sys 0.42.0", ] [[package]] -name = "itoa" -version = "0.4.8" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.58" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -2449,30 +2605,29 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.13.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f2ab5a60e558e74ea93bcf5164ebc47939a7fff8938fa9b5233bbc63e16061" +checksum = "7d291e3a5818a2384645fd9756362e6d89cf0541b0b916fa7702ea4a9833608e" dependencies = [ "jsonrpsee-core", - "jsonrpsee-http-server", "jsonrpsee-proc-macros", + "jsonrpsee-server", "jsonrpsee-types", "jsonrpsee-ws-client", - "jsonrpsee-ws-server", "tracing", ] [[package]] name = "jsonrpsee-client-transport" -version = "0.13.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d682f4a55081a2be3e639280c640523070e4aeb8ee2fd8dd9168fdae57a9db" +checksum = "965de52763f2004bc91ac5bcec504192440f0b568a5d621c59d9dbd6f886c3fb" dependencies = [ "futures-util", "http", "jsonrpsee-core", "jsonrpsee-types", - "pin-project 1.0.10", + "pin-project", "rustls-native-certs", "soketto", "thiserror", @@ -2485,9 +2640,9 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.13.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e27462b21279edf9a6a91f46ffbe125e9cdc58b901d2e08bf59b31a47d7d0ab" +checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" dependencies = [ "anyhow", "arrayvec 0.7.2", @@ -2497,6 +2652,7 @@ dependencies = [ "futures-channel", "futures-timer", "futures-util", + "globset", "hyper", "jsonrpsee-types", "parking_lot 0.12.1", @@ -2511,41 +2667,45 @@ dependencies = [ ] [[package]] -name = "jsonrpsee-http-server" -version = "0.13.1" +name = "jsonrpsee-proc-macros" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" +dependencies = [ + "heck 0.4.0", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7178f16eabd7154c094e24d295b9ee355ec1e5f24c328759c56255ff7bbd4548" +checksum = "1fb69dad85df79527c019659a992498d03f8495390496da2f07e6c24c2b356fc" dependencies = [ "futures-channel", "futures-util", - "globset", + "http", "hyper", "jsonrpsee-core", "jsonrpsee-types", - "lazy_static", + "serde", "serde_json", + "soketto", "tokio", + "tokio-stream", + "tokio-util", + "tower", "tracing", - "unicase", -] - -[[package]] -name = "jsonrpsee-proc-macros" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8d7f449cab3b747f12c3efc27f5cad537f3b597c6a3838b0fac628f4bf730a" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", ] [[package]] name = "jsonrpsee-types" -version = "0.13.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd11763134104122ddeb0f97e4bbe393058017dfb077db63fbf44b4dd0dd86e" +checksum = "5bd522fe1ce3702fd94812965d7bb7a3364b1c9aba743944c5a00529aae80f8c" dependencies = [ "anyhow", "beef", @@ -2557,92 +2717,64 @@ dependencies = [ [[package]] name = "jsonrpsee-ws-client" -version = "0.13.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f15180afb3761c7a3a32c0a8b680788176dcfdfe725b24c1758c90b1d1595b" +checksum = "0b83daeecfc6517cfe210df24e570fb06213533dfb990318fae781f4c7119dd9" dependencies = [ + "http", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", ] -[[package]] -name = "jsonrpsee-ws-server" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb6c21556c551582b56e4e8e6e6249b0bbdb69bb7fa39efe9b9a6b54af9f206" -dependencies = [ - "futures-channel", - "futures-util", - "jsonrpsee-core", - "jsonrpsee-types", - "serde_json", - "soketto", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", + "sha2 0.10.6", ] [[package]] name = "keccak" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" - -[[package]] -name = "kv-log-macro" -version = "1.0.7" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" dependencies = [ - "log", + "cpufeatures", ] [[package]] name = "kvdb" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a301d8ecb7989d4a6e2c57a49baca77d353bdbf879909debe3f375fe25d61f86" +checksum = "e7d770dcb02bf6835887c3a979b5107a04ff4bbde97a5f0928d27404a155add9" dependencies = [ - "parity-util-mem", "smallvec", ] [[package]] name = "kvdb-memorydb" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece7e668abd21387aeb6628130a6f4c802787f014fa46bc83221448322250357" +checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2" dependencies = [ "kvdb", - "parity-util-mem", "parking_lot 0.12.1", ] [[package]] name = "kvdb-rocksdb" -version = "0.15.2" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca7fbdfd71cd663dceb0faf3367a99f8cf724514933e9867cec4995b6027cbc1" +checksum = "2182b8219fee6bd83aacaab7344e840179ae079d5216aa4e249b4d704646a844" dependencies = [ - "fs-swap", "kvdb", - "log", "num_cpus", - "owning_ref", - "parity-util-mem", "parking_lot 0.12.1", "regex", "rocksdb", @@ -2654,6 +2786,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "lazycell" @@ -2663,54 +2798,46 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libloading" -version = "0.5.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ - "cc", + "cfg-if", "winapi", ] [[package]] -name = "libloading" -version = "0.7.3" +name = "libm" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" [[package]] name = "libm" -version = "0.2.2" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" [[package]] name = "libp2p" -version = "0.45.1" +version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41726ee8f662563fafba2d2d484b14037cc8ecb8c953fbfc8439d4ce3a0a9029" +checksum = "ec878fda12ebec479186b3914ebc48ff180fa4c51847e11a1a68bf65249e02c1" dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.7", + "getrandom 0.2.8", "instant", "lazy_static", - "libp2p-autonat", - "libp2p-core 0.33.0", - "libp2p-deflate", + "libp2p-core", "libp2p-dns", - "libp2p-floodsub", - "libp2p-gossipsub", "libp2p-identify", "libp2p-kad", "libp2p-mdns", @@ -2718,83 +2845,24 @@ dependencies = [ "libp2p-mplex", "libp2p-noise", "libp2p-ping", - "libp2p-plaintext", - "libp2p-pnet", - "libp2p-relay", - "libp2p-rendezvous", "libp2p-request-response", "libp2p-swarm", "libp2p-swarm-derive", "libp2p-tcp", - "libp2p-uds", "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", "multiaddr", "parking_lot 0.12.1", - "pin-project 1.0.10", - "rand 0.7.3", + "pin-project", "smallvec", ] -[[package]] -name = "libp2p-autonat" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d45945fd2f96c4b133c23d5c28a8b7fc8d7138e6dd8d5a8cd492dd384f888e3" -dependencies = [ - "async-trait", - "futures", - "futures-timer", - "instant", - "libp2p-core 0.33.0", - "libp2p-request-response", - "libp2p-swarm", - "log", - "prost 0.10.4", - "prost-build 0.10.4", - "rand 0.8.5", -] - [[package]] name = "libp2p-core" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db5b02602099fb75cb2d16f9ea860a320d6eb82ce41e95ab680912c454805cd5" -dependencies = [ - "asn1_der", - "bs58", - "ed25519-dalek", - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "lazy_static", - "log", - "multiaddr", - "multihash", - "multistream-select", - "parking_lot 0.12.1", - "pin-project 1.0.10", - "prost 0.9.0", - "prost-build 0.9.0", - "rand 0.8.5", - "ring", - "rw-stream-sink 0.2.1", - "sha2 0.10.2", - "smallvec", - "thiserror", - "unsigned-varint", - "void", - "zeroize", -] - -[[package]] -name = "libp2p-core" -version = "0.33.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d46fca305dee6757022e2f5a4f6c023315084d0ed7441c3ab244e76666d979" +checksum = "799676bb0807c788065e57551c6527d461ad572162b0519d1958946ff9e0539d" dependencies = [ "asn1_der", "bs58", @@ -2805,19 +2873,17 @@ dependencies = [ "futures-timer", "instant", "lazy_static", - "libsecp256k1", "log", "multiaddr", "multihash", "multistream-select", "parking_lot 0.12.1", - "pin-project 1.0.10", - "prost 0.10.4", - "prost-build 0.10.4", + "pin-project", + "prost", + "prost-build", "rand 0.8.5", - "ring", - "rw-stream-sink 0.3.0", - "sha2 0.10.2", + "rw-stream-sink", + "sha2 0.10.6", "smallvec", "thiserror", "unsigned-varint", @@ -2825,93 +2891,35 @@ dependencies = [ "zeroize", ] -[[package]] -name = "libp2p-deflate" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86adefc55ea4ed8201149f052fb441210727481dff1fb0b8318460206a79f5fb" -dependencies = [ - "flate2", - "futures", - "libp2p-core 0.33.0", -] - [[package]] name = "libp2p-dns" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb462ec3a51fab457b4b44ac295e8b0a4b04dc175127e615cf996b1f0f1a268" -dependencies = [ - "async-std-resolver", - "futures", - "libp2p-core 0.33.0", - "log", - "parking_lot 0.12.1", - "smallvec", - "trust-dns-resolver", -] - -[[package]] -name = "libp2p-floodsub" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a505d0c6f851cbf2919535150198e530825def8bd3757477f13dc3a57f46cbcc" -dependencies = [ - "cuckoofilter", - "fnv", - "futures", - "libp2p-core 0.33.0", - "libp2p-swarm", - "log", - "prost 0.10.4", - "prost-build 0.10.4", - "rand 0.7.3", - "smallvec", -] - -[[package]] -name = "libp2p-gossipsub" -version = "0.38.1" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e064ba4d7832e01c738626c6b274ae100baba05f5ffcc7b265c2a3ed398108" +checksum = "2322c9fb40d99101def6a01612ee30500c89abbbecb6297b3cd252903a4c1720" dependencies = [ - "asynchronous-codec", - "base64", - "byteorder", - "bytes", - "fnv", - "futures", - "hex_fmt", - "instant", - "libp2p-core 0.33.0", - "libp2p-swarm", + "futures", + "libp2p-core", "log", - "prometheus-client", - "prost 0.10.4", - "prost-build 0.10.4", - "rand 0.7.3", - "regex", - "sha2 0.10.2", + "parking_lot 0.12.1", "smallvec", - "unsigned-varint", - "wasm-timer", + "trust-dns-resolver", ] [[package]] name = "libp2p-identify" -version = "0.36.1" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84b53490442d086db1fa5375670c9666e79143dccadef3f7c74a4346899a984" +checksum = "dcf9a121f699e8719bda2e6e9e9b6ddafc6cff4602471d6481c1067930ccb29b" dependencies = [ "asynchronous-codec", "futures", "futures-timer", - "libp2p-core 0.33.0", + "libp2p-core", "libp2p-swarm", "log", "lru", - "prost 0.10.4", - "prost-build 0.10.4", + "prost", + "prost-build", "prost-codec", "smallvec", "thiserror", @@ -2920,9 +2928,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.37.1" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6b5d4de90fcd35feb65ea6223fd78f3b747a64ca4b65e0813fbe66a27d56aa" +checksum = "6721c200e2021f6c3fab8b6cf0272ead8912d871610ee194ebd628cecf428f22" dependencies = [ "arrayvec 0.7.2", "asynchronous-codec", @@ -2932,13 +2940,13 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core 0.33.0", + "libp2p-core", "libp2p-swarm", "log", - "prost 0.10.4", - "prost-build 0.10.4", - "rand 0.7.3", - "sha2 0.10.2", + "prost", + "prost-build", + "rand 0.8.5", + "sha2 0.10.6", "smallvec", "thiserror", "uint", @@ -2948,75 +2956,72 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.37.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4783f8cf00c7b6c1ff0f1870b4fcf50b042b45533d2e13b6fb464caf447a6951" +checksum = "761704e727f7d68d58d7bc2231eafae5fc1b9814de24290f126df09d4bd37a15" dependencies = [ - "async-io", "data-encoding", "dns-parser", "futures", "if-watch", - "lazy_static", - "libp2p-core 0.33.0", + "libp2p-core", "libp2p-swarm", "log", "rand 0.8.5", "smallvec", "socket2", + "tokio", "void", ] [[package]] name = "libp2p-metrics" -version = "0.6.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "564a7e5284d7d9b3140fdfc3cb6567bc32555e86a21de5604c2ec85da05cf384" +checksum = "9ee31b08e78b7b8bfd1c4204a9dd8a87b4fcdf6dafc57eb51701c1c264a81cb9" dependencies = [ - "libp2p-core 0.33.0", - "libp2p-gossipsub", + "libp2p-core", "libp2p-identify", "libp2p-kad", "libp2p-ping", - "libp2p-relay", "libp2p-swarm", "prometheus-client", ] [[package]] name = "libp2p-mplex" -version = "0.33.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ff9c893f2367631a711301d703c47432af898c9bb8253bea0e2c051a13f7640" +checksum = "692664acfd98652de739a8acbb0a0d670f1d67190a49be6b4395e22c37337d89" dependencies = [ "asynchronous-codec", "bytes", "futures", - "libp2p-core 0.33.0", + "libp2p-core", "log", "nohash-hasher", "parking_lot 0.12.1", - "rand 0.7.3", + "rand 0.8.5", "smallvec", "unsigned-varint", ] [[package]] name = "libp2p-noise" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2cee1dad1c83325bbd182a8e94555778699cec8a9da00086efb7522c4c15ad" +checksum = "048155686bd81fe6cb5efdef0c6290f25ad32a0a42e8f4f72625cf6a505a206f" dependencies = [ "bytes", "curve25519-dalek 3.2.0", "futures", "lazy_static", - "libp2p-core 0.33.0", + "libp2p-core", "log", - "prost 0.10.4", - "prost-build 0.10.4", + "prost", + "prost-build", "rand 0.8.5", - "sha2 0.10.2", + "sha2 0.10.6", "snow", "static_assertions", "x25519-dalek", @@ -3025,133 +3030,53 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41516c82fe8dd148ec925eead0c5ec08a0628f7913597e93e126e4dfb4e0787" -dependencies = [ - "futures", - "futures-timer", - "instant", - "libp2p-core 0.33.0", - "libp2p-swarm", - "log", - "rand 0.7.3", - "void", -] - -[[package]] -name = "libp2p-plaintext" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db007e737adc5d28b2e03223b0210164928ad742591127130796a72aa8eaf54f" -dependencies = [ - "asynchronous-codec", - "bytes", - "futures", - "libp2p-core 0.33.0", - "log", - "prost 0.10.4", - "prost-build 0.10.4", - "unsigned-varint", - "void", -] - -[[package]] -name = "libp2p-pnet" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1a458bbda880107b5b36fcb9b5a1ef0c329685da0e203ed692a8ebe64cc92c" -dependencies = [ - "futures", - "log", - "pin-project 1.0.10", - "rand 0.7.3", - "salsa20", - "sha3 0.9.1", -] - -[[package]] -name = "libp2p-relay" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624ead3406f64437a0d4567c31bd128a9a0b8226d5f16c074038f5d0fc32f650" -dependencies = [ - "asynchronous-codec", - "bytes", - "either", - "futures", - "futures-timer", - "instant", - "libp2p-core 0.33.0", - "libp2p-swarm", - "log", - "pin-project 1.0.10", - "prost 0.10.4", - "prost-build 0.10.4", - "prost-codec", - "rand 0.8.5", - "smallvec", - "static_assertions", - "thiserror", - "void", -] - -[[package]] -name = "libp2p-rendezvous" -version = "0.6.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59967ea2db2c7560f641aa58ac05982d42131863fcd3dd6dcf0dd1daf81c60c" +checksum = "7228b9318d34689521349a86eb39a3c3a802c9efc99a0568062ffb80913e3f91" dependencies = [ - "asynchronous-codec", - "bimap", "futures", "futures-timer", "instant", - "libp2p-core 0.33.0", + "libp2p-core", "libp2p-swarm", "log", - "prost 0.10.4", - "prost-build 0.10.4", "rand 0.8.5", - "sha2 0.10.2", - "thiserror", - "unsigned-varint", "void", ] [[package]] name = "libp2p-request-response" -version = "0.18.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b02e0acb725e5a757d77c96b95298fd73a7394fe82ba7b8bbeea510719cbe441" +checksum = "8827af16a017b65311a410bb626205a9ad92ec0473967618425039fa5231adc1" dependencies = [ "async-trait", "bytes", "futures", "instant", - "libp2p-core 0.33.0", + "libp2p-core", "libp2p-swarm", "log", - "rand 0.7.3", + "rand 0.8.5", "smallvec", "unsigned-varint", ] [[package]] name = "libp2p-swarm" -version = "0.36.1" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4bb21c5abadbf00360c734f16bf87f1712ed4f23cd46148f625d2ddb867346" +checksum = "46d13df7c37807965d82930c0e4b04a659efcb6cca237373b206043db5398ecf" dependencies = [ "either", "fnv", "futures", "futures-timer", "instant", - "libp2p-core 0.33.0", + "libp2p-core", "log", - "pin-project 1.0.10", - "rand 0.7.3", + "pin-project", + "rand 0.8.5", "smallvec", "thiserror", "void", @@ -3159,52 +3084,40 @@ dependencies = [ [[package]] name = "libp2p-swarm-derive" -version = "0.27.2" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f693c8c68213034d472cbb93a379c63f4f307d97c06f1c41e4985de481687a5" +checksum = "a0eddc4497a8b5a506013c40e8189864f9c3a00db2b25671f428ae9007f3ba32" dependencies = [ + "heck 0.4.0", "quote", "syn", ] [[package]] name = "libp2p-tcp" -version = "0.33.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4933e38ef21b50698aefc87799c24f2a365c9d3f6cf50471f3f6a0bc410892" +checksum = "9839d96761491c6d3e238e70554b856956fca0ab60feb9de2cd08eed4473fa92" dependencies = [ - "async-io", "futures", "futures-timer", "if-watch", - "ipnet", "libc", - "libp2p-core 0.33.0", + "libp2p-core", "log", "socket2", -] - -[[package]] -name = "libp2p-uds" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24bdab114f7f2701757d6541266e1131b429bbae382008f207f2114ee4222dcb" -dependencies = [ - "async-std", - "futures", - "libp2p-core 0.32.1", - "log", + "tokio", ] [[package]] name = "libp2p-wasm-ext" -version = "0.33.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f066f2b8b1a1d64793f05da2256e6842ecd0293d6735ca2e9bda89831a1bdc06" +checksum = "a17b5b8e7a73e379e47b1b77f8a82c4721e97eca01abcd18e9cd91a23ca6ce97" dependencies = [ "futures", "js-sys", - "libp2p-core 0.33.0", + "libp2p-core", "parity-send-wrapper", "wasm-bindgen", "wasm-bindgen-futures", @@ -3212,18 +3125,18 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.35.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39d398fbb29f432c4128fabdaac2ed155c3bcaf1b9bd40eeeb10a471eefacbf5" +checksum = "3758ae6f89b2531a24b6d9f5776bda6a626b60a57600d7185d43dfa75ca5ecc4" dependencies = [ "either", "futures", "futures-rustls", - "libp2p-core 0.33.0", + "libp2p-core", "log", "parking_lot 0.12.1", "quicksink", - "rw-stream-sink 0.3.0", + "rw-stream-sink", "soketto", "url", "webpki-roots", @@ -3231,12 +3144,13 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.37.0" +version = "0.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe653639ad74877c759720febb0cbcbf4caa221adde4eed2d3126ce5c6f381f" +checksum = "0d6874d66543c4f7e26e3b8ca9a6bead351563a13ab4fafd43c7927f7c0d6c12" dependencies = [ "futures", - "libp2p-core 0.33.0", + "libp2p-core", + "log", "parking_lot 0.12.1", "thiserror", "yamux", @@ -3244,9 +3158,9 @@ dependencies = [ [[package]] name = "librocksdb-sys" -version = "0.6.1+6.28.2" +version = "0.8.0+7.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc587013734dadb7cf23468e531aa120788b87243648be42e2d3a072186291" +checksum = "611804e4666a25136fcc5f8cf425ab4d26c7f74ea245ffe92ea23b85b6420b5d" dependencies = [ "bindgen", "bzip2-sys", @@ -3259,9 +3173,9 @@ dependencies = [ [[package]] name = "libsecp256k1" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0452aac8bab02242429380e9b2f94ea20cea2b37e2c1777a1358799bbe97f37" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" dependencies = [ "arrayref", "base64", @@ -3316,11 +3230,20 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linked_hash_set" @@ -3343,9 +3266,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.0.42" +version = "0.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5284f00d480e1c39af34e72f8ad60b94f47007e3481cd3b731c1d67190ddc7b7" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "lite-json" @@ -3367,9 +3296,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -3382,16 +3311,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", - "value-bag", ] [[package]] name = "lru" -version = "0.7.7" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84e6fe5655adc6ce00787cf7dcaf8dc4f998a0565d23eafc207a8b08ca3349a" +checksum = "b6e8aaa3f231bb4bd57b84b2d5dc3ae7f350265df8aa96492e0bc394a1571909" dependencies = [ - "hashbrown 0.11.2", + "hashbrown", ] [[package]] @@ -3405,9 +3333,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.23.3" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edcb94251b1c375c459e5abe9fb0168c1c826c3370172684844f8f3f8d1a885" +checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" dependencies = [ "libc", "lz4-sys", @@ -3415,9 +3343,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.3" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7be8908e2ed6f31c02db8a9fa962f03e36c53fbfde437363eae3306b85d7e17" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" dependencies = [ "cc", "libc", @@ -3432,12 +3360,6 @@ dependencies = [ "libc", ] -[[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" @@ -3476,56 +3398,55 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memfd" -version = "0.4.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6627dc657574b49d6ad27105ed671822be56e0d2547d413bfbf3e8d8fa92e7a" +checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" dependencies = [ - "libc", + "rustix 0.36.5", ] [[package]] name = "memmap2" -version = "0.2.3" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" +checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" dependencies = [ "libc", ] [[package]] -name = "memmap2" -version = "0.5.4" +name = "memoffset" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "libc", + "autocfg", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] name = "memory-db" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6566c70c1016f525ced45d7b7f97730a2bafb037c788211d0c186ef5b2189f0a" +checksum = "5e0c7cba9ce19ac7ffd2053ac9f49843bbd3f4318feedfd74e85c19d5fb0ba66" dependencies = [ "hash-db", - "hashbrown 0.12.1", - "parity-util-mem", + "hashbrown", ] [[package]] name = "memory_units" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" [[package]] name = "merlin" @@ -3547,30 +3468,51 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] -name = "more-asserts" -version = "0.2.2" +name = "mockall" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" +checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn", +] [[package]] name = "multiaddr" @@ -3603,18 +3545,18 @@ dependencies = [ [[package]] name = "multihash" -version = "0.16.2" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3db354f401db558759dfc1e568d010a5d4146f4d3f637be1275ec4a3cf09689" +checksum = "1c346cf9999c631f002d8f977c4eaeaa0e6386f16007202308d0b3757522c2cc" dependencies = [ "blake2b_simd", "blake2s_simd", "blake3", "core2", - "digest 0.10.3", + "digest 0.10.6", "multihash-derive", - "sha2 0.10.2", - "sha3 0.10.1", + "sha2 0.10.6", + "sha3", "unsigned-varint", ] @@ -3640,14 +3582,14 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "multistream-select" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "363a84be6453a70e63513660f4894ef815daf88e3356bffcda9ca27d810ce83b" +checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" dependencies = [ "bytes", "futures", "log", - "pin-project 1.0.10", + "pin-project", "smallvec", "unsigned-varint", ] @@ -3662,7 +3604,7 @@ dependencies = [ "matrixmultiply", "nalgebra-macros", "num-complex", - "num-rational 0.4.0", + "num-rational", "num-traits", "rand 0.8.5", "rand_distr", @@ -3704,9 +3646,9 @@ dependencies = [ [[package]] name = "netlink-packet-route" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733ea73609acfd7fa7ddadfb7bf709b0471668c456ad9513685af543a06342b2" +checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" dependencies = [ "anyhow", "bitflags", @@ -3724,29 +3666,30 @@ checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e" dependencies = [ "anyhow", "byteorder", - "paste 1.0.7", + "paste 1.0.11", "thiserror", ] [[package]] name = "netlink-proto" -version = "0.9.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8785b8141e8432aa45fceb922a7e876d7da3fad37fa7e7ec702ace3aa0826b" +checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ "bytes", "futures", "log", "netlink-packet-core", "netlink-sys", + "thiserror", "tokio", ] [[package]] name = "netlink-sys" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c9f9547a08241bee7b6558b9b98e1f290d187de8b7cfca2bbb4937bcaa8f8" +checksum = "92b654097027250401127914afb37cb1f311df6610a9891ff07a757e94199027" dependencies = [ "async-io", "bytes", @@ -3757,23 +3700,15 @@ dependencies = [ [[package]] name = "nix" -version = "0.22.3" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ "bitflags", - "cc", "cfg-if", "libc", - "memoffset", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "nohash-hasher" version = "0.2.0" @@ -3790,11 +3725,17 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + [[package]] name = "num-bigint" -version = "0.2.6" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg", "num-integer", @@ -3812,12 +3753,12 @@ dependencies = [ [[package]] name = "num-format" -version = "0.4.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" dependencies = [ - "arrayvec 0.4.12", - "itoa 0.4.8", + "arrayvec 0.7.2", + "itoa", ] [[package]] @@ -3832,9 +3773,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.2.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", "num-bigint", @@ -3842,17 +3783,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -3860,44 +3790,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", - "libm", + "libm 0.2.6", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "object" -version = "0.27.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "crc32fast", + "hashbrown", "indexmap", "memchr", ] [[package]] name = "object" -version = "0.28.4" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.12.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -3919,63 +3850,64 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] -name = "owning_ref" -version = "0.4.1" +name = "packed_simd_2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" +checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" dependencies = [ - "stable_deref_trait", + "cfg-if", + "libm 0.1.4", ] [[package]] name = "pallet-aura" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", "pallet-timestamp", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-application-crypto", "sp-consensus-aura", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", "impl-trait-for-tuples", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-authorship", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -3986,57 +3918,59 @@ dependencies = [ "frame-system", "pallet-balances", "pallet-timestamp", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-storage", ] [[package]] name = "pallet-collective" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-dao" version = "3.0.0" dependencies = [ + "env_logger 0.9.3", "frame-benchmarking", "frame-support", "frame-system", + "log", "pallet-collective", "pallet-membership", "pallet-tfgrid", "pallet-timestamp", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "tfchain-support", ] [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-benchmarking", "frame-support", @@ -4044,7 +3978,7 @@ dependencies = [ "log", "pallet-authorship", "pallet-session", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-application-crypto", "sp-core", @@ -4053,7 +3987,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -4062,44 +3996,44 @@ version = "3.0.0" dependencies = [ "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-storage", ] [[package]] name = "pallet-membership" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-randomness-collective-flip" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "safe-mix", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -4108,46 +4042,47 @@ version = "3.0.0" dependencies = [ "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-io", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", + "sp-weights", ] [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", "impl-trait-for-tuples", "log", "pallet-timestamp", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "sp-trie", ] @@ -4155,37 +4090,43 @@ dependencies = [ name = "pallet-smart-contract" version = "3.0.0" dependencies = [ + "env_logger 0.10.0", "frame-benchmarking", "frame-support", "frame-system", "frame-try-runtime", "log", + "pallet-authorship", "pallet-balances", + "pallet-session", "pallet-tfgrid", "pallet-tft-price", "pallet-timestamp", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", + "parking_lot 0.12.1", "scale-info", "sp-core", "sp-io", + "sp-keystore", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "substrate-fixed", + "substrate-validator-set", "tfchain-support", ] [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -4203,12 +4144,13 @@ dependencies = [ "pallet-collective", "pallet-membership", "pallet-timestamp", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", + "serde_json", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-storage", "tfchain-support", "valip", @@ -4217,17 +4159,18 @@ dependencies = [ [[package]] name = "pallet-tft-bridge" version = "2.4.0" -source = "git+https://github.com/threefoldtech/tfchain_tft_bridge#26e03446266a75c6078363e78a08d5eb2b3b95fb" +source = "git+https://github.com/threefoldtech/tfchain_tft_bridge?branch=feat_upgrade_polkadot-0.9.36#58aea1efa9d48daf8660b20b8671c029a728e99f" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-storage", + "substrate-stellar-sdk", ] [[package]] @@ -4238,7 +4181,9 @@ dependencies = [ "frame-system", "lite-json", "log", - "parity-scale-codec 3.1.5", + "pallet-authorship", + "pallet-session", + "parity-scale-codec 3.2.1", "parking_lot 0.11.2", "scale-info", "serde", @@ -4247,83 +4192,88 @@ dependencies = [ "sp-io", "sp-keystore", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "substrate-fixed", + "substrate-validator-set", + "tfchain-support", ] [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-inherents", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-api", "sp-blockchain", "sp-core", "sp-rpc", "sp-runtime", + "sp-weights", ] [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "pallet-transaction-payment", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-api", "sp-runtime", + "sp-weights", ] [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -4335,30 +4285,30 @@ dependencies = [ "pallet-collective", "pallet-membership", "pallet-session", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "substrate-validator-set", ] [[package]] name = "parity-db" -version = "0.3.14" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "966eb23bd3a09758b8dac09f82b9d417c00f14e5d46171bf04cffdd9cb2e1eb1" +checksum = "3a7511a0bec4a336b5929999d02b560d2439c993cccf98c26481484e811adc43" dependencies = [ - "blake2-rfc", + "blake2", "crc32fast", "fs2", "hex", "libc", "log", "lz4", - "memmap2 0.2.3", - "parking_lot 0.11.2", + "memmap2", + "parking_lot 0.12.1", "rand 0.8.5", "snap", ] @@ -4377,89 +4327,54 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.1.5" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9182e4a71cae089267ab03e67c99368db7cd877baf50f931e5d6d4b71e195ac0" +checksum = "366e44391a8af4cfd6002ef6ba072bae071a96aafca98d7d448a34c5dca38b6a" dependencies = [ "arrayvec 0.7.2", "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive 3.1.3", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[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.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c32561d248d352148124f036cac253a644685a21dc9fea383eb4907d7bd35a8f" -dependencies = [ - "cfg-if", - "hashbrown 0.12.1", - "impl-trait-for-tuples", - "parity-util-mem-derive", - "parking_lot 0.12.1", - "primitive-types", - "smallvec", - "winapi", + "byte-slice-cast", + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec-derive 3.1.3", + "serde", ] [[package]] -name = "parity-util-mem-derive" -version = "0.1.0" +name = "parity-scale-codec-derive" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ + "proc-macro-crate", "proc-macro2", + "quote", "syn", - "synstructure", ] [[package]] -name = "parity-wasm" -version = "0.32.0" +name = "parity-scale-codec-derive" +version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" +checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" dependencies = [ - "byteorder", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", ] +[[package]] +name = "parity-send-wrapper" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" + [[package]] name = "parity-wasm" -version = "0.42.2" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" [[package]] name = "parking" @@ -4475,7 +4390,7 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.5", + "parking_lot_core 0.8.6", ] [[package]] @@ -4485,14 +4400,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.3", + "parking_lot_core 0.9.5", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ "cfg-if", "instant", @@ -4504,15 +4419,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -4527,9 +4442,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.7" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" +checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" [[package]] name = "paste-impl" @@ -4566,24 +4481,25 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.1.3" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" dependencies = [ + "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.1.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +checksum = "cdc078600d06ff90d4ed238f0119d84ab5d43dbaad278b0e33a8820293b32344" dependencies = [ "pest", "pest_generator", @@ -4591,9 +4507,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.1.3" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +checksum = "28a1af60b1c4148bb269006a750cff8e2ea36aff34d2d96cf7be0b14d1bed23c" dependencies = [ "pest", "pest_meta", @@ -4604,13 +4520,13 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.1.3" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +checksum = "fec8605d59fc2ae0c6c1aefc0c7c7a9769732017c0ce07f7a9cfffa7b4404f20" dependencies = [ - "maplit", + "once_cell", "pest", - "sha-1 0.8.2", + "sha1", ] [[package]] @@ -4625,38 +4541,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909" -dependencies = [ - "pin-project-internal 0.4.29", -] - -[[package]] -name = "pin-project" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" -dependencies = [ - "pin-project-internal 1.0.10", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.29" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ - "proc-macro2", - "quote", - "syn", + "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", @@ -4681,11 +4577,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "platforms" @@ -4693,17 +4599,24 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" +[[package]] +name = "platforms" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" + [[package]] name = "polling" -version = "2.2.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" +checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" dependencies = [ + "autocfg", "cfg-if", "libc", "log", "wepoll-ffi", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -4731,15 +4644,55 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "predicates" +version = "2.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54fc5dc63ed3bbf19494623db4f3af16842c0d975818e469022d09e53f0aa05" +dependencies = [ + "difflib", + "float-cmp", + "itertools", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" + +[[package]] +name = "predicates-tree" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "prettyplease" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "2c8992a85d8e93a28bdf76137db888d3874e3b230dee5ed8bebac4c9f7617773" +dependencies = [ + "proc-macro2", + "syn", +] [[package]] name = "primitive-types" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" dependencies = [ "fixed-hash", "impl-codec", @@ -4750,10 +4703,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.1.3" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" dependencies = [ + "once_cell", "thiserror", "toml", ] @@ -4784,24 +4738,24 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.19" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cface98dfa6d645ea4c789839f176e4b072265d085bfcc48eaa8d137f58d3c39" +checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" dependencies = [ "cfg-if", "fnv", @@ -4813,21 +4767,21 @@ dependencies = [ [[package]] name = "prometheus-client" -version = "0.16.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1abe0255c04d15f571427a2d1e00099016506cf3297b53853acd2b7eb87825" +checksum = "83cd1b99916654a69008fd66b4f9397fbe08e6e51dfe23d4417acf5d3b8cb87c" dependencies = [ "dtoa", - "itoa 1.0.2", - "owning_ref", + "itoa", + "parking_lot 0.12.1", "prometheus-client-derive-text-encode", ] [[package]] name = "prometheus-client-derive-text-encode" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e12d01b9d66ad9eb4529c57666b6263fc1993cb30261d83ead658fdd932652" +checksum = "66a455fbcb954c1a7decf3c586e860fd7889cddf4b8e164be736dbac95a953cd" dependencies = [ "proc-macro2", "quote", @@ -4836,97 +4790,54 @@ dependencies = [ [[package]] name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive 0.9.0", -] - -[[package]] -name = "prost" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" -dependencies = [ - "bytes", - "prost-derive 0.10.1", -] - -[[package]] -name = "prost-build" -version = "0.9.0" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" +checksum = "c01db6702aa05baa3f57dec92b8eeeeb4cb19e894e73996b32a4093289e54592" dependencies = [ "bytes", - "heck 0.3.3", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prost 0.9.0", - "prost-types 0.9.0", - "regex", - "tempfile", - "which", + "prost-derive", ] [[package]] name = "prost-build" -version = "0.10.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae5a4388762d5815a9fc0dea33c56b021cdc8dde0c55e0c9ca57197254b0cab" +checksum = "cb5320c680de74ba083512704acb90fe00f28f79207286a848e730c45dd73ed6" dependencies = [ "bytes", - "cfg-if", - "cmake", "heck 0.4.0", "itertools", "lazy_static", "log", "multimap", "petgraph", - "prost 0.10.4", - "prost-types 0.10.1", + "prettyplease", + "prost", + "prost-types", "regex", + "syn", "tempfile", "which", ] [[package]] name = "prost-codec" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00af1e92c33b4813cc79fda3f2dbf56af5169709be0202df730e9ebc3e4cd007" +checksum = "011ae9ff8359df7915f97302d591cdd9e0e27fbd5a4ddc5bd13b71079bb20987" dependencies = [ "asynchronous-codec", "bytes", - "prost 0.10.4", + "prost", "thiserror", "unsigned-varint", ] [[package]] name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "prost-derive" -version = "0.10.1" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" +checksum = "c8842bad1a5419bca14eac663ba798f6bc19c413c2fdceb5f3ba3b0932d96720" dependencies = [ "anyhow", "itertools", @@ -4937,22 +4848,12 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" -dependencies = [ - "bytes", - "prost 0.9.0", -] - -[[package]] -name = "prost-types" -version = "0.10.1" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" +checksum = "017f79637768cde62820bc2d4fe0e45daaa027755c323ad077767c6c5f173091" dependencies = [ "bytes", - "prost 0.10.4", + "prost", ] [[package]] @@ -4983,9 +4884,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -5018,7 +4919,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -5038,7 +4939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -5052,11 +4953,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", ] [[package]] @@ -5093,7 +4994,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -5104,21 +5005,19 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.5.3" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" dependencies = [ - "autocfg", - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -5128,9 +5027,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -5141,25 +5040,25 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "redox_syscall", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.7" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685d58625b6c2b83e4cc88a27c4bf65adb7b6b16dbdc413e515c9405b47432ab" +checksum = "8c78fb8c9293bcd48ef6fce7b4ca950ceaf21210de6e105a883ee280c0f7b9ed" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.7" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a043824e29c94169374ac5183ac0ed43f5724dc4556b19568007486bd840fa1f" +checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f" dependencies = [ "proc-macro2", "quote", @@ -5167,21 +5066,22 @@ dependencies = [ ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] [[package]] name = "regex" -version = "1.5.6" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -5199,38 +5099,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" - -[[package]] -name = "region" -version = "2.2.0" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0" -dependencies = [ - "bitflags", - "libc", - "mach", - "winapi", -] - -[[package]] -name = "remote-externalities" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" -dependencies = [ - "env_logger", - "jsonrpsee", - "log", - "parity-scale-codec 3.1.5", - "serde", - "serde_json", - "sp-core", - "sp-io", - "sp-runtime", - "sp-version", -] +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -5251,20 +5122,14 @@ dependencies = [ "quick-error", ] -[[package]] -name = "retain_mut" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" - [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.11.0", + "hmac 0.12.1", "zeroize", ] @@ -5285,9 +5150,9 @@ dependencies = [ [[package]] name = "rocksdb" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "620f4129485ff1a7128d184bc687470c21c7951b64779ebc9cfdad3dcd920290" +checksum = "7e9562ea1d70c0cc63a34a22d977753b50cca91cc6b6527750463bd5dd8697bc" dependencies = [ "libc", "librocksdb-sys", @@ -5295,19 +5160,20 @@ dependencies = [ [[package]] name = "rpassword" -version = "5.0.1" +version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" +checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" dependencies = [ "libc", + "rtoolbox", "winapi", ] [[package]] name = "rtnetlink" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f54290e54521dac3de4149d83ddf9f62a359b3cc93bcb494a794a41e6f4744b" +checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" dependencies = [ "async-global-executor", "futures", @@ -5318,6 +5184,16 @@ dependencies = [ "thiserror", ] +[[package]] +name = "rtoolbox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -5351,28 +5227,42 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.10", + "semver 1.0.16", ] [[package]] name = "rustix" -version = "0.33.7" +version = "0.35.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938a344304321a9da4973b9ff4f9f8db9caf4597dfd9dda6a60b523340a0fff0" +checksum = "727a1a6d65f786ec22df8a81ca3121107f235970dc1705ed681d3e6e8b9cd5f9" dependencies = [ "bitflags", "errno", - "io-lifetimes", + "io-lifetimes 0.7.5", "libc", - "linux-raw-sys", - "winapi", + "linux-raw-sys 0.0.46", + "windows-sys 0.42.0", +] + +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes 1.0.3", + "libc", + "linux-raw-sys 0.1.4", + "windows-sys 0.42.0", ] [[package]] name = "rustls" -version = "0.20.6" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" dependencies = [ "log", "ring", @@ -5394,29 +5284,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" dependencies = [ "base64", ] [[package]] name = "rustversion" -version = "1.0.7" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf" - -[[package]] -name = "rw-stream-sink" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" -dependencies = [ - "futures", - "pin-project 0.4.29", - "static_assertions", -] +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" [[package]] name = "rw-stream-sink" @@ -5425,15 +5304,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" dependencies = [ "futures", - "pin-project 1.0.10", + "pin-project", "static_assertions", ] [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "safe-mix" @@ -5444,15 +5323,6 @@ dependencies = [ "rustc_version 0.2.3", ] -[[package]] -name = "salsa20" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686" -dependencies = [ - "cipher", -] - [[package]] name = "same-file" version = "1.0.6" @@ -5465,7 +5335,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "log", "sp-core", @@ -5476,12 +5346,12 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", "futures-timer", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sc-block-builder", "sc-client-api", "sc-proposer-metrics", @@ -5499,9 +5369,9 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sc-client-api", "sp-api", "sp-block-builder", @@ -5515,13 +5385,13 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "impl-trait-for-tuples", - "memmap2 0.5.4", - "parity-scale-codec 3.1.5", + "memmap2", + "parity-scale-codec 3.2.1", "sc-chain-spec-derive", - "sc-network", + "sc-network-common", "sc-telemetry", "serde", "serde_json", @@ -5532,7 +5402,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5543,17 +5413,17 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "array-bytes", "chrono", - "clap 3.2.6", + "clap 4.0.32", "fdlimit", "futures", - "hex", "libp2p", "log", "names", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "rand 0.7.3", "regex", "rpassword", @@ -5561,6 +5431,7 @@ dependencies = [ "sc-client-db", "sc-keystore", "sc-network", + "sc-network-common", "sc-service", "sc-telemetry", "sc-tracing", @@ -5582,13 +5453,13 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "fnv", "futures", "hash-db", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "sc-executor", "sc-transaction-pool-api", @@ -5610,7 +5481,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "hash-db", "kvdb", @@ -5619,7 +5490,7 @@ dependencies = [ "linked-hash-map", "log", "parity-db", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "sc-client-api", "sc-state-db", @@ -5635,13 +5506,14 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "futures", "futures-timer", "libp2p", "log", + "mockall", "parking_lot 0.12.1", "sc-client-api", "sc-utils", @@ -5659,12 +5531,12 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "futures", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sc-block-builder", "sc-client-api", "sc-consensus", @@ -5688,13 +5560,13 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "futures", "futures-timer", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sc-client-api", "sc-consensus", "sc-telemetry", @@ -5706,30 +5578,26 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-state-machine", - "sp-timestamp", "thiserror", ] [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "lazy_static", "lru", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "sc-executor-common", "sc-executor-wasmi", "sc-executor-wasmtime", "sp-api", "sp-core", - "sp-core-hashing-proc-macro", "sp-externalities", "sp-io", "sp-panic-handler", "sp-runtime-interface", - "sp-tasks", "sp-trie", "sp-version", "sp-wasm-interface", @@ -5740,14 +5608,10 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "environmental", - "parity-scale-codec 3.1.5", "sc-allocator", "sp-maybe-compressed-blob", - "sp-sandbox", - "sp-serializer", "sp-wasm-interface", "thiserror", "wasm-instrument", @@ -5757,14 +5621,12 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "log", - "parity-scale-codec 3.1.5", "sc-allocator", "sc-executor-common", "sp-runtime-interface", - "sp-sandbox", "sp-wasm-interface", "wasmi", ] @@ -5772,17 +5634,16 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "cfg-if", "libc", "log", - "parity-scale-codec 3.1.5", - "parity-wasm 0.42.2", + "once_cell", + "rustix 0.35.13", "sc-allocator", "sc-executor-common", "sp-runtime-interface", - "sp-sandbox", "sp-wasm-interface", "wasmtime", ] @@ -5790,18 +5651,18 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "ahash", + "array-bytes", "async-trait", "dyn-clone", "finality-grandpa", "fork-tree", "futures", "futures-timer", - "hex", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "rand 0.8.5", "sc-block-builder", @@ -5810,6 +5671,7 @@ dependencies = [ "sc-consensus", "sc-keystore", "sc-network", + "sc-network-common", "sc-network-gossip", "sc-telemetry", "sc-utils", @@ -5830,13 +5692,13 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "finality-grandpa", "futures", "jsonrpsee", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sc-client-api", "sc-finality-grandpa", "sc-rpc", @@ -5851,15 +5713,14 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "ansi_term", "futures", "futures-timer", "log", - "parity-util-mem", "sc-client-api", - "sc-network", + "sc-network-common", "sc-transaction-pool-api", "sp-blockchain", "sp-runtime", @@ -5868,10 +5729,10 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "array-bytes", "async-trait", - "hex", "parking_lot 0.12.1", "serde_json", "sp-application-crypto", @@ -5883,8 +5744,9 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "array-bytes", "async-trait", "asynchronous-codec", "bitflags", @@ -5895,25 +5757,21 @@ dependencies = [ "fork-tree", "futures", "futures-timer", - "hex", "ip_network", "libp2p", "linked-hash-map", "linked_hash_set", "log", "lru", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", - "pin-project 1.0.10", - "prost 0.10.4", - "prost-build 0.9.0", + "pin-project", + "prost", "rand 0.7.3", "sc-block-builder", "sc-client-api", "sc-consensus", "sc-network-common", - "sc-network-light", - "sc-network-sync", "sc-peerset", "sc-utils", "serde", @@ -5923,32 +5781,63 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", - "sp-finality-grandpa", "sp-runtime", "substrate-prometheus-endpoint", "thiserror", "unsigned-varint", - "void", "zeroize", ] +[[package]] +name = "sc-network-bitswap" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" +dependencies = [ + "cid", + "futures", + "libp2p", + "log", + "prost", + "prost-build", + "sc-client-api", + "sc-network-common", + "sp-blockchain", + "sp-runtime", + "thiserror", + "unsigned-varint", + "void", +] + [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "async-trait", + "bitflags", + "bytes", "futures", + "futures-timer", "libp2p", - "parity-scale-codec 3.1.5", - "prost-build 0.9.0", + "linked_hash_set", + "parity-scale-codec 3.2.1", + "prost-build", + "sc-consensus", "sc-peerset", + "serde", "smallvec", + "sp-blockchain", + "sp-consensus", + "sp-finality-grandpa", + "sp-runtime", + "substrate-prometheus-endpoint", + "thiserror", ] [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "ahash", "futures", @@ -5956,7 +5845,8 @@ dependencies = [ "libp2p", "log", "lru", - "sc-network", + "sc-network-common", + "sc-peerset", "sp-runtime", "substrate-prometheus-endpoint", "tracing", @@ -5965,14 +5855,15 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "array-bytes", "futures", "libp2p", "log", - "parity-scale-codec 3.1.5", - "prost 0.10.4", - "prost-build 0.9.0", + "parity-scale-codec 3.2.1", + "prost", + "prost-build", "sc-client-api", "sc-network-common", "sc-peerset", @@ -5985,22 +5876,24 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "bitflags", - "either", + "array-bytes", + "async-trait", "fork-tree", "futures", "libp2p", "log", "lru", - "parity-scale-codec 3.1.5", - "prost 0.10.4", - "prost-build 0.9.0", + "mockall", + "parity-scale-codec 3.2.1", + "prost", + "prost-build", "sc-client-api", "sc-consensus", "sc-network-common", "sc-peerset", + "sc-utils", "smallvec", "sp-arithmetic", "sp-blockchain", @@ -6008,28 +5901,50 @@ dependencies = [ "sp-core", "sp-finality-grandpa", "sp-runtime", + "substrate-prometheus-endpoint", "thiserror", ] +[[package]] +name = "sc-network-transactions" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" +dependencies = [ + "array-bytes", + "futures", + "hex", + "libp2p", + "log", + "parity-scale-codec 3.2.1", + "pin-project", + "sc-network-common", + "sc-peerset", + "sp-consensus", + "sp-runtime", + "substrate-prometheus-endpoint", +] + [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "array-bytes", "bytes", "fnv", "futures", "futures-timer", - "hex", "hyper", "hyper-rustls", + "libp2p", "num_cpus", "once_cell", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "rand 0.7.3", "sc-client-api", - "sc-network", + "sc-network-common", + "sc-peerset", "sc-utils", "sp-api", "sp-core", @@ -6042,7 +5957,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", "libp2p", @@ -6055,7 +5970,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -6064,13 +5979,13 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", "hash-db", "jsonrpsee", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "sc-block-builder", "sc-chain-spec", @@ -6094,12 +6009,12 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", "jsonrpsee", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "sc-chain-spec", "sc-transaction-pool-api", @@ -6117,20 +6032,42 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", + "http", "jsonrpsee", "log", "serde_json", "substrate-prometheus-endpoint", "tokio", + "tower", + "tower-http", +] + +[[package]] +name = "sc-rpc-spec-v2" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" +dependencies = [ + "futures", + "hex", + "jsonrpsee", + "parity-scale-codec 3.2.1", + "sc-chain-spec", + "sc-transaction-pool-api", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-runtime", + "thiserror", ] [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "directories", @@ -6140,10 +6077,9 @@ dependencies = [ "hash-db", "jsonrpsee", "log", - "parity-scale-codec 3.1.5", - "parity-util-mem", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", - "pin-project 1.0.10", + "pin-project", "rand 0.7.3", "sc-block-builder", "sc-chain-spec", @@ -6154,10 +6090,15 @@ dependencies = [ "sc-informant", "sc-keystore", "sc-network", + "sc-network-bitswap", "sc-network-common", + "sc-network-light", + "sc-network-sync", + "sc-network-transactions", "sc-offchain", "sc-rpc", "sc-rpc-server", + "sc-rpc-spec-v2", "sc-sysinfo", "sc-telemetry", "sc-tracing", @@ -6184,6 +6125,7 @@ dependencies = [ "sp-transaction-storage-proof", "sp-trie", "sp-version", + "static_init", "substrate-prometheus-endpoint", "tempfile", "thiserror", @@ -6195,12 +6137,10 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "log", - "parity-scale-codec 3.1.5", - "parity-util-mem", - "parity-util-mem-derive", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "sc-client-api", "sp-core", @@ -6209,7 +6149,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", "libc", @@ -6222,20 +6162,20 @@ dependencies = [ "serde_json", "sp-core", "sp-io", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "chrono", "futures", "libp2p", "log", "parking_lot 0.12.1", - "pin-project 1.0.10", + "pin-project", "rand 0.7.3", "serde", "serde_json", @@ -6246,7 +6186,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "ansi_term", "atty", @@ -6277,7 +6217,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6288,16 +6228,15 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "async-trait", "futures", "futures-timer", "linked-hash-map", "log", - "parity-scale-codec 3.1.5", - "parity-util-mem", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", - "retain_mut", "sc-client-api", "sc-transaction-pool-api", "sc-utils", @@ -6315,8 +6254,9 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "async-trait", "futures", "log", "serde", @@ -6328,7 +6268,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", "futures-timer", @@ -6340,23 +6280,23 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.1.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c46be926081c9f4dd5dd9b6f1d3e3229f2360bc6502dd8836f84a93b7c75e99a" +checksum = "001cf62ece89779fd16105b5f515ad0e5cedcd5440d3dd806bb067978e7c3608" dependencies = [ "bitvec", "cfg-if", "derive_more", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info-derive", "serde", ] [[package]] name = "scale-info-derive" -version = "2.1.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e334bb10a245e28e5fd755cabcafd96cfcd167c99ae63a46924ca8d8703a3c" +checksum = "303959cf613a6f6efd19ed4b4ad5bf79966a13352716299ad532cfb115f4205c" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6371,7 +6311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -6398,6 +6338,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" + [[package]] name = "sct" version = "0.7.0" @@ -6410,30 +6356,32 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", - "generic-array 0.14.5", + "generic-array 0.14.6", + "pkcs8", "subtle", "zeroize", ] [[package]] name = "secp256k1" -version = "0.21.3" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c42e6f1735c5f00f51e43e28d6634141f2bcad10931b2609ddd74a86d751260" +checksum = "d9512ffd81e3a3503ed401f79c33168b9148c75038956039166cd750eaa037c3" dependencies = [ "secp256k1-sys", ] [[package]] name = "secp256k1-sys" -version = "0.4.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" dependencies = [ "cc", ] @@ -6449,9 +6397,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -6490,9 +6438,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.10" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" dependencies = [ "serde", ] @@ -6505,18 +6453,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", @@ -6525,11 +6473,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ - "itoa 1.0.2", + "itoa", "ryu", "serde", ] @@ -6543,18 +6491,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha-1" version = "0.9.8" @@ -6568,6 +6504,17 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + [[package]] name = "sha2" version = "0.8.2" @@ -6595,34 +6542,22 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.6", ] [[package]] name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug 0.3.0", -] - -[[package]] -name = "sha3" -version = "0.10.1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881bf8156c87b6301fc5ca6b27f11eeb2761224c7081e69b409d5a1951a70c86" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", "keccak", ] @@ -6641,16 +6576,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" -[[package]] -name = "signal-hook" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -6662,12 +6587,12 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", - "rand_core 0.6.3", + "digest 0.10.6", + "rand_core 0.6.4", ] [[package]] @@ -6679,26 +6604,35 @@ dependencies = [ "approx", "num-complex", "num-traits", - "paste 1.0.7", + "paste 1.0.11", ] [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "snap" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451" +checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" [[package]] name = "snow" @@ -6709,24 +6643,33 @@ dependencies = [ "aes-gcm", "blake2", "chacha20poly1305", - "curve25519-dalek 4.0.0-pre.1", - "rand_core 0.6.3", + "curve25519-dalek 4.0.0-pre.5", + "rand_core 0.6.4", "ring", "rustc_version 0.4.0", - "sha2 0.10.2", + "sha2 0.10.6", "subtle", ] [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", ] +[[package]] +name = "sodalite" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41784a359d15c58bba298cccb7f30a847a1a42d0620c9bdaa0aa42fdb3c280e0" +dependencies = [ + "index-fixed", +] + [[package]] name = "soketto" version = "0.7.1" @@ -6737,25 +6680,27 @@ dependencies = [ "bytes", "flate2", "futures", + "http", "httparse", "log", "rand 0.8.5", - "sha-1 0.9.8", + "sha-1", ] [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "hash-db", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-api-proc-macro", "sp-core", "sp-runtime", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", + "sp-trie", "sp-version", "thiserror", ] @@ -6763,7 +6708,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "blake2", "proc-macro-crate", @@ -6774,65 +6719,65 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-core", "sp-io", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sp-arithmetic" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "integer-sqrt", "num-traits", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-debug-derive", - "sp-std", + "sp-std 5.0.0", "static_assertions", ] [[package]] name = "sp-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-api", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures", "log", "lru", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "sp-api", "sp-consensus", @@ -6845,18 +6790,18 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "futures", "futures-timer", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-core", "sp-inherents", "sp-runtime", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-version", "thiserror", ] @@ -6864,10 +6809,10 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-api", "sp-application-crypto", @@ -6875,47 +6820,46 @@ dependencies = [ "sp-consensus-slots", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-arithmetic", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] [[package]] name = "sp-core" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "array-bytes", "base58", "bitflags", - "blake2-rfc", + "blake2", "byteorder", "dyn-clonable", - "ed25519-dalek", + "ed25519-zebra", "futures", "hash-db", "hash256-std-hasher", - "hex", "impl-serde", "lazy_static", "libsecp256k1", "log", "merlin", "num-traits", - "parity-scale-codec 3.1.5", - "parity-util-mem", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "primitive-types", "rand 0.7.3", @@ -6929,7 +6873,7 @@ dependencies = [ "sp-debug-derive", "sp-externalities", "sp-runtime-interface", - "sp-std", + "sp-std 5.0.0", "sp-storage", "ss58-registry", "substrate-bip39", @@ -6941,22 +6885,22 @@ dependencies = [ [[package]] name = "sp-core-hashing" -version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "blake2", "byteorder", - "digest 0.10.3", - "sha2 0.10.2", - "sha3 0.10.1", - "sp-std", + "digest 0.10.6", + "sha2 0.10.6", + "sha3", + "sp-std 5.0.0", "twox-hash", ] [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "proc-macro2", "quote", @@ -6967,7 +6911,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -6975,8 +6919,8 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "proc-macro2", "quote", @@ -6985,23 +6929,23 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.12.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "0.13.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "environmental", - "parity-scale-codec 3.1.5", - "sp-std", + "parity-scale-codec 3.2.1", + "sp-std 5.0.0", "sp-storage", ] [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "finality-grandpa", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-api", @@ -7009,33 +6953,35 @@ dependencies = [ "sp-core", "sp-keystore", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "impl-trait-for-tuples", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "thiserror", ] [[package]] name = "sp-io" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "bytes", + "ed25519-dalek", "futures", "hash-db", "libsecp256k1", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "secp256k1", "sp-core", @@ -7043,7 +6989,7 @@ dependencies = [ "sp-keystore", "sp-runtime-interface", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-tracing", "sp-trie", "sp-wasm-interface", @@ -7053,8 +6999,8 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "lazy_static", "sp-core", @@ -7064,13 +7010,13 @@ dependencies = [ [[package]] name = "sp-keystore" -version = "0.12.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "0.13.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "futures", "merlin", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "schnorrkel", "serde", @@ -7082,7 +7028,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "thiserror", "zstd", @@ -7091,7 +7037,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "sp-api", "sp-core", @@ -7100,8 +7046,8 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "backtrace", "lazy_static", @@ -7111,7 +7057,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "rustc-hash", "serde", @@ -7120,16 +7066,15 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "either", "hash256-std-hasher", "impl-trait-for-tuples", "log", - "parity-scale-codec 3.1.5", - "parity-util-mem", - "paste 1.0.7", + "parity-scale-codec 3.2.1", + "paste 1.0.11", "rand 0.7.3", "scale-info", "serde", @@ -7137,20 +7082,22 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-io", - "sp-std", + "sp-std 5.0.0", + "sp-weights", ] [[package]] name = "sp-runtime-interface" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "bytes", "impl-trait-for-tuples", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "primitive-types", "sp-externalities", "sp-runtime-interface-proc-macro", - "sp-std", + "sp-std 5.0.0", "sp-storage", "sp-tracing", "sp-wasm-interface", @@ -7159,8 +7106,8 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "Inflector", "proc-macro-crate", @@ -7169,70 +7116,48 @@ dependencies = [ "syn", ] -[[package]] -name = "sp-sandbox" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" -dependencies = [ - "log", - "parity-scale-codec 3.1.5", - "sp-core", - "sp-io", - "sp-std", - "sp-wasm-interface", - "wasmi", -] - -[[package]] -name = "sp-serializer" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-api", "sp-core", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", + "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sp-state-machine" -version = "0.12.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "0.13.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "hash-db", "log", "num-traits", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "parking_lot 0.12.1", "rand 0.7.3", "smallvec", "sp-core", "sp-externalities", "sp-panic-handler", - "sp-std", + "sp-std 5.0.0", "sp-trie", "thiserror", "tracing", @@ -7242,57 +7167,49 @@ dependencies = [ [[package]] name = "sp-std" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.29#cc370aa61e15c18d23a2f686b812fd576a630afe" + +[[package]] +name = "sp-std" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" [[package]] name = "sp-storage" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "impl-serde", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "ref-cast", "serde", "sp-debug-derive", - "sp-std", -] - -[[package]] -name = "sp-tasks" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" -dependencies = [ - "log", - "sp-core", - "sp-externalities", - "sp-io", - "sp-runtime-interface", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "futures-timer", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sp-api", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "thiserror", ] [[package]] name = "sp-tracing" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", - "sp-std", + "parity-scale-codec 3.2.1", + "sp-std 5.0.0", "tracing", "tracing-core", "tracing-subscriber", @@ -7301,7 +7218,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "sp-api", "sp-runtime", @@ -7310,31 +7227,38 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "async-trait", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-core", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-trie", ] [[package]] name = "sp-trie" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ + "ahash", "hash-db", + "hashbrown", + "lazy_static", + "lru", "memory-db", - "parity-scale-codec 3.1.5", + "nohash-hasher", + "parity-scale-codec 3.2.1", + "parking_lot 0.12.1", "scale-info", "sp-core", - "sp-std", + "sp-std 5.0.0", "thiserror", + "tracing", "trie-db", "trie-root", ] @@ -7342,16 +7266,16 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "impl-serde", - "parity-scale-codec 3.1.5", - "parity-wasm 0.42.2", + "parity-scale-codec 3.2.1", + "parity-wasm", "scale-info", "serde", "sp-core-hashing-proc-macro", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-version-proc-macro", "thiserror", ] @@ -7359,9 +7283,9 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "proc-macro2", "quote", "syn", @@ -7369,28 +7293,54 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "impl-trait-for-tuples", "log", - "parity-scale-codec 3.1.5", - "sp-std", + "parity-scale-codec 3.2.1", + "sp-std 5.0.0", "wasmi", "wasmtime", ] +[[package]] +name = "sp-weights" +version = "4.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec 3.2.1", + "scale-info", + "serde", + "smallvec", + "sp-arithmetic", + "sp-core", + "sp-debug-derive", + "sp-std 5.0.0", +] + [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "ss58-registry" -version = "1.22.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d804c8d48aeab838be31570866fce1130d275b563d49af08b4927a0bd561e7c" +checksum = "23d92659e7d18d82b803824a9ba5a6022cff101c3491d027c1c1d8d30e749284" dependencies = [ "Inflector", "num-format", @@ -7408,10 +7358,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_init" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2a1c578e98c1c16fc3b8ec1328f7659a500737d7a0c6d625e73e830ff9c1f6" +dependencies = [ + "bitflags", + "cfg_aliases", + "libc", + "parking_lot 0.11.2", + "parking_lot_core 0.8.6", + "static_init_macro", + "winapi", +] + +[[package]] +name = "static_init_macro" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf" +dependencies = [ + "cfg_aliases", + "memchr", + "proc-macro2", + "quote", + "syn", +] [[package]] name = "statrs" @@ -7464,20 +7442,20 @@ dependencies = [ [[package]] name = "strum" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.23.1" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck 0.3.3", + "heck 0.4.0", "proc-macro2", "quote", "rustversion", @@ -7500,9 +7478,9 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "platforms", + "platforms 2.0.0", ] [[package]] @@ -7517,13 +7495,13 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "frame-system-rpc-runtime-api", "futures", "jsonrpsee", "log", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "sc-client-api", "sc-rpc-api", "sc-transaction-pool-api", @@ -7538,7 +7516,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "futures-util", "hyper", @@ -7548,6 +7526,33 @@ dependencies = [ "tokio", ] +[[package]] +name = "substrate-rpc-client" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" +dependencies = [ + "async-trait", + "jsonrpsee", + "log", + "sc-rpc-api", + "serde", + "sp-runtime", +] + +[[package]] +name = "substrate-stellar-sdk" +version = "0.2.4" +source = "git+https://github.com/pendulum-chain/substrate-stellar-sdk#f659041c6643f80f4e1f6e9e35268dba3ae2d313" +dependencies = [ + "base64", + "hex", + "lazy_static", + "num-rational", + "sha2 0.9.9", + "sodalite", + "sp-std 4.0.0", +] + [[package]] name = "substrate-validator-set" version = "3.0.0" @@ -7556,30 +7561,31 @@ dependencies = [ "frame-system", "log", "pallet-session", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "serde", "sp-core", "sp-io", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ "ansi_term", "build-helper", "cargo_metadata", + "filetime", "sp-maybe-compressed-blob", "strum", "tempfile", "toml", "walkdir", - "wasm-gc-api", + "wasm-opt", ] [[package]] @@ -7590,9 +7596,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.98" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -7640,9 +7646,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" +checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" [[package]] name = "tempfile" @@ -7667,6 +7673,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "termtree" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" + [[package]] name = "textwrap" version = "0.11.0" @@ -7676,17 +7688,11 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "tfchain" -version = "2.1.3" +version = "2.2.0" dependencies = [ - "clap 3.2.6", + "clap 4.0.32", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -7724,6 +7730,7 @@ dependencies = [ "sp-core", "sp-finality-grandpa", "sp-inherents", + "sp-io", "sp-keyring", "sp-runtime", "sp-timestamp", @@ -7732,14 +7739,13 @@ dependencies = [ "substrate-build-script-utils", "substrate-frame-rpc-system", "tfchain-runtime", - "tracing-core", "try-runtime-cli", "vergen", ] [[package]] name = "tfchain-runtime" -version = "2.1.3" +version = "2.2.0" dependencies = [ "frame-benchmarking", "frame-executive", @@ -7748,7 +7754,7 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", - "getrandom 0.2.7", + "getrandom 0.2.8", "hex-literal 0.3.4", "log", "pallet-aura", @@ -7774,7 +7780,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-utility", "pallet-validator", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "smallvec", "sp-api", @@ -7785,7 +7791,7 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-std", + "sp-std 5.0.0", "sp-transaction-pool", "sp-version", "substrate-validator-set", @@ -7800,26 +7806,27 @@ version = "1.0.0" dependencies = [ "frame-support", "frame-system", - "parity-scale-codec 3.1.5", + "parity-scale-codec 3.2.1", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", + "valip", ] [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -7852,9 +7859,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.4.3+5.2.1-patched.2" +version = "0.5.2+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1792ccb507d955b46af42c123ea8863668fae24d03721e40cad6a41773dbb49" +checksum = "ec45c14da997d0925c7835883e4d5c181f196fa142f8c19d7643d1e9af2592c3" dependencies = [ "cc", "fs_extra", @@ -7863,9 +7870,9 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", @@ -7908,29 +7915,29 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.19.2" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ + "autocfg", "bytes", "libc", "memchr", "mio", "num_cpus", - "once_cell", "parking_lot 0.12.1", "pin-project-lite 0.2.9", "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", @@ -7948,11 +7955,22 @@ dependencies = [ "webpki", ] +[[package]] +name = "tokio-stream" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +dependencies = [ + "futures-core", + "pin-project-lite 0.2.9", + "tokio", +] + [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -7965,13 +7983,48 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" dependencies = [ "serde", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite 0.2.9", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -7980,11 +8033,12 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.34" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite 0.2.9", "tracing-attributes", "tracing-core", @@ -7992,9 +8046,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", @@ -8003,11 +8057,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.26" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ - "lazy_static", + "once_cell", "valuable", ] @@ -8017,7 +8071,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.0.10", + "pin-project", "tracing", ] @@ -8027,10 +8081,8 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ - "ahash", "lazy_static", "log", - "lru", "tracing-core", ] @@ -8069,12 +8121,12 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.23.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32d034c0d3db64b43c31de38e945f15b40cd4ca6d2dcfc26d4798ce8de4ab83" +checksum = "004e1e8f92535694b4cb1444dc5a8073ecf0815e3357f729638b9f8fc4062908" dependencies = [ "hash-db", - "hashbrown 0.12.1", + "hashbrown", "log", "rustc-hex", "smallvec", @@ -8091,9 +8143,9 @@ dependencies = [ [[package]] name = "trust-dns-proto" -version = "0.21.2" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" +checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" dependencies = [ "async-trait", "cfg-if", @@ -8102,33 +8154,35 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "idna", + "idna 0.2.3", "ipnet", "lazy_static", - "log", "rand 0.8.5", "smallvec", "thiserror", "tinyvec", + "tokio", + "tracing", "url", ] [[package]] name = "trust-dns-resolver" -version = "0.21.2" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" dependencies = [ "cfg-if", "futures-util", "ipconfig", "lazy_static", - "log", "lru-cache", "parking_lot 0.12.1", "resolv-conf", "smallvec", "thiserror", + "tokio", + "tracing", "trust-dns-proto", ] @@ -8141,33 +8195,39 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.36#cb4f2491b00af7d7817f3a54209c26b20faa1f51" dependencies = [ - "clap 3.2.6", - "jsonrpsee", + "clap 4.0.32", + "frame-remote-externalities", + "frame-try-runtime", + "hex", "log", - "parity-scale-codec 3.1.5", - "remote-externalities", + "parity-scale-codec 3.2.1", "sc-chain-spec", "sc-cli", "sc-executor", "sc-service", "serde", + "sp-api", "sp-core", + "sp-debug-derive", "sp-externalities", "sp-io", "sp-keystore", + "sp-rpc", "sp-runtime", "sp-state-machine", "sp-version", + "sp-weights", + "substrate-rpc-client", "zstd", ] [[package]] name = "tt-call" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e66dcbec4290c69dd03c57e76c2469ea5c7ce109c6dd4351c13055cf71ea055" +checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df" [[package]] name = "twox-hash" @@ -8176,28 +8236,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", - "digest 0.10.3", + "digest 0.10.6", "rand 0.8.5", "static_assertions", ] [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "uint" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder", "crunchy", @@ -8205,15 +8265,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.8" @@ -8222,36 +8273,36 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unicode-xid" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "universal-hash" @@ -8259,7 +8310,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ - "generic-array 0.14.5", + "generic-array 0.14.6", "subtle", ] @@ -8283,21 +8334,20 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", - "idna", - "matches", + "idna 0.3.0", "percent-encoding", ] [[package]] name = "valip" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bff85cc0b5bf6728a74934372fc925cbbb4433116f25aa3351f417e089cf79" +checksum = "dfbab1f81fcf258f4e5c7822b4b38425520b8ec5065863df813ac76ba040be81" [[package]] name = "valuable" @@ -8305,16 +8355,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "value-bag" -version = "1.0.0-alpha.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" -dependencies = [ - "ctor", - "version_check", -] - [[package]] name = "vcpkg" version = "0.2.15" @@ -8397,9 +8437,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -8407,13 +8447,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -8422,9 +8462,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -8434,9 +8474,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8444,9 +8484,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -8457,28 +8497,58 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] -name = "wasm-gc-api" -version = "0.1.11" +name = "wasm-instrument" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" +checksum = "aa1dafb3e60065305741e83db35c6c2584bb3725b692b5b66148a38d72ace6cd" dependencies = [ - "log", - "parity-wasm 0.32.0", - "rustc-demangle", + "parity-wasm", ] [[package]] -name = "wasm-instrument" -version = "0.1.1" +name = "wasm-opt" +version = "0.110.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68e8037b4daf711393f4be2056246d12d975651b14d581520ad5d1f19219cec" +dependencies = [ + "anyhow", + "libc", + "strum", + "strum_macros", + "tempfile", + "thiserror", + "wasm-opt-cxx-sys", + "wasm-opt-sys", +] + +[[package]] +name = "wasm-opt-cxx-sys" +version = "0.110.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91adbad477e97bba3fbd21dd7bfb594e7ad5ceb9169ab1c93ab9cb0ada636b6f" +dependencies = [ + "anyhow", + "cxx", + "cxx-build", + "wasm-opt-sys", +] + +[[package]] +name = "wasm-opt-sys" +version = "0.110.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "962e5b0401bbb6c887f54e69b8c496ea36f704df65db73e81fd5ff8dc3e63a9f" +checksum = "ec4fa5a322a4e6ac22fd141f498d56afbdbf9df5debeac32380d2dcaa3e06941" dependencies = [ - "parity-wasm 0.42.2", + "anyhow", + "cc", + "cxx", + "cxx-build", + "regex", ] [[package]] @@ -8498,55 +8568,63 @@ dependencies = [ [[package]] name = "wasmi" -version = "0.9.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca00c5147c319a8ec91ec1a0edbec31e566ce2c9cc93b3f9bb86a9efd0eb795d" +checksum = "06c326c93fbf86419608361a2c925a31754cf109da1b8b55737070b4d6669422" dependencies = [ - "downcast-rs", - "libc", - "libm", - "memory_units", - "num-rational 0.2.4", - "num-traits", - "parity-wasm 0.42.2", + "parity-wasm", "wasmi-validation", + "wasmi_core", ] [[package]] name = "wasmi-validation" -version = "0.4.1" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ff416ad1ff0c42e5a926ed5d5fab74c0f098749aa0ad8b2a34b982ce0e867b" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "wasmi_core" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165343ecd6c018fc09ebcae280752702c9a2ef3e6f8d02f1cfcbdb53ef6d7937" +checksum = "57d20cb3c59b788653d99541c646c561c9dd26506f25c0cebfe810659c54c6d7" dependencies = [ - "parity-wasm 0.42.2", + "downcast-rs", + "libm 0.2.6", + "memory_units", + "num-rational", + "num-traits", ] [[package]] name = "wasmparser" -version = "0.83.0" +version = "0.89.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" +checksum = "ab5d3e08b13876f96dd55608d03cd4883a0545884932d5adf11925876c96daef" +dependencies = [ + "indexmap", +] [[package]] name = "wasmtime" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21ffb4705016d5ca91e18a72ed6822dab50e6d5ddd7045461b17ef19071cdef1" +checksum = "4ad5af6ba38311282f2a21670d96e78266e8c8e2f38cbcd52c254df6ccbc7731" dependencies = [ "anyhow", - "backtrace", "bincode", "cfg-if", "indexmap", - "lazy_static", "libc", "log", - "object 0.27.1", + "object 0.29.0", "once_cell", - "paste 1.0.7", + "paste 1.0.11", "psm", "rayon", - "region", "serde", "target-lexicon", "wasmparser", @@ -8555,14 +8633,23 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit", "wasmtime-runtime", - "winapi", + "windows-sys 0.36.1", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45de63ddfc8b9223d1adc8f7b2ee5f35d1f6d112833934ad7ea66e4f4339e597" +dependencies = [ + "cfg-if", ] [[package]] name = "wasmtime-cache" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c6ab24291fa7cb3a181f5669f6c72599b7ef781669759b45c7828c5999d0c0" +checksum = "bcd849399d17d2270141cfe47fa0d91ee52d5f8ea9b98cf7ddde0d53e5f79882" dependencies = [ "anyhow", "base64", @@ -8570,19 +8657,19 @@ dependencies = [ "directories-next", "file-per-thread-logger", "log", - "rustix", + "rustix 0.35.13", "serde", "sha2 0.9.9", "toml", - "winapi", + "windows-sys 0.36.1", "zstd", ] [[package]] name = "wasmtime-cranelift" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04c810078a491b7bc4866ebe045f714d2b95e6b539e1f64009a4a7606be11de" +checksum = "4bd91339b742ff20bfed4532a27b73c86b5bcbfedd6bea2dcdf2d64471e1b5c6" dependencies = [ "anyhow", "cranelift-codegen", @@ -8590,10 +8677,9 @@ dependencies = [ "cranelift-frontend", "cranelift-native", "cranelift-wasm", - "gimli", + "gimli 0.26.2", "log", - "more-asserts", - "object 0.27.1", + "object 0.29.0", "target-lexicon", "thiserror", "wasmparser", @@ -8602,17 +8688,16 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61448266ea164b1ac406363cdcfac81c7c44db4d94c7a81c8620ac6c5c6cdf59" +checksum = "ebb881c61f4f627b5d45c54e629724974f8a8890d455bcbe634330cc27309644" dependencies = [ "anyhow", "cranelift-entity", - "gimli", + "gimli 0.26.2", "indexmap", "log", - "more-asserts", - "object 0.27.1", + "object 0.29.0", "serde", "target-lexicon", "thiserror", @@ -8622,49 +8707,47 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "156b4623c6b0d4b8c24afb846c20525922f538ef464cc024abab7ea8de2109a2" +checksum = "1985c628011fe26adf5e23a5301bdc79b245e0e338f14bb58b39e4e25e4d8681" dependencies = [ - "addr2line", + "addr2line 0.17.0", "anyhow", "bincode", "cfg-if", "cpp_demangle", - "gimli", + "gimli 0.26.2", "log", - "object 0.27.1", - "region", + "object 0.29.0", "rustc-demangle", - "rustix", + "rustix 0.35.13", "serde", "target-lexicon", "thiserror", "wasmtime-environ", "wasmtime-jit-debug", "wasmtime-runtime", - "winapi", + "windows-sys 0.36.1", ] [[package]] name = "wasmtime-jit-debug" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5dc31f811760a6c76b2672c404866fd19b75e5fb3b0075a3e377a6846490654" +checksum = "f671b588486f5ccec8c5a3dba6b4c07eac2e66ab8c60e6f4e53717c77f709731" dependencies = [ - "lazy_static", - "object 0.27.1", - "rustix", + "object 0.29.0", + "once_cell", + "rustix 0.35.13", ] [[package]] name = "wasmtime-runtime" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f907beaff69d4d920fa4688411ee4cc75c0f01859e424677f9e426e2ef749864" +checksum = "ee8f92ad4b61736339c29361da85769ebc200f184361959d1792832e592a1afd" dependencies = [ "anyhow", - "backtrace", "cc", "cfg-if", "indexmap", @@ -8672,22 +8755,22 @@ dependencies = [ "log", "mach", "memfd", - "memoffset", - "more-asserts", + "memoffset 0.6.5", + "paste 1.0.11", "rand 0.8.5", - "region", - "rustix", + "rustix 0.35.13", "thiserror", + "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", - "winapi", + "windows-sys 0.36.1", ] [[package]] name = "wasmtime-types" -version = "0.35.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514ef0e5fd197b9609dc9eb74beba0c84d5a12b2417cbae55534633329ba4852" +checksum = "d23d61cb4c46e837b431196dd06abb11731541021916d03476a178b54dc07aeb" dependencies = [ "cranelift-entity", "serde", @@ -8697,9 +8780,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.58" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -8717,9 +8800,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.3" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ "webpki", ] @@ -8735,13 +8818,13 @@ dependencies = [ [[package]] name = "which" -version = "4.2.5" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", ] [[package]] @@ -8807,6 +8890,27 @@ dependencies = [ "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.34.0" @@ -8819,6 +8923,12 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.34.0" @@ -8831,6 +8941,12 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.34.0" @@ -8843,6 +8959,12 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.34.0" @@ -8855,6 +8977,18 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.34.0" @@ -8867,20 +9001,26 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winreg" -version = "0.7.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] [[package]] name = "wyz" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] @@ -8912,18 +9052,18 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ "proc-macro2", "quote", @@ -8933,18 +9073,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.10.2+zstd.1.5.2" +version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "4.1.6+zstd.1.5.2" +version = "5.0.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" dependencies = [ "libc", "zstd-sys", @@ -8952,9 +9092,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "1.6.3+zstd.1.5.2" +version = "2.0.4+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" +checksum = "4fa202f2ef00074143e219d15b62ffc317d17cc33909feac471c044087cad7b0" dependencies = [ "cc", "libc", diff --git a/substrate-node/Dockerfile b/substrate-node/Dockerfile index 76008bc4a..d9f782255 100644 --- a/substrate-node/Dockerfile +++ b/substrate-node/Dockerfile @@ -1,4 +1,4 @@ -FROM paritytech/ci-linux@sha256:c75cee0971ca54e57a875fac8714eea2db754e621841cde702478783fc28ab90 as builder +FROM docker.io/paritytech/ci-linux:production as builder WORKDIR /tfchain diff --git a/substrate-node/charts/substrate-node/Chart.yaml b/substrate-node/charts/substrate-node/Chart.yaml index b0aba3a7f..491278734 100644 --- a/substrate-node/charts/substrate-node/Chart.yaml +++ b/substrate-node/charts/substrate-node/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: substrate-node description: Tfchain node type: application -version: 0.2.4 -appVersion: "2.1.3" +version: 0.2.9 +appVersion: '2.2.0' diff --git a/substrate-node/charts/substrate-node/templates/deployment.yaml b/substrate-node/charts/substrate-node/templates/deployment.yaml index 5334987b3..1dc193c84 100644 --- a/substrate-node/charts/substrate-node/templates/deployment.yaml +++ b/substrate-node/charts/substrate-node/templates/deployment.yaml @@ -74,6 +74,7 @@ spec: {{ if .Values.is_validator }} "--node-key-file","/keys/node", "--validator", + "--pruning", "archive", {{ else }} "--ws-external", "--pruning", "archive", @@ -136,25 +137,6 @@ spec: - name: keys mountPath: /keys readOnly: true - - name: insert-tft-key - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - args: [ - "key", - "insert", - "--keystore-path=/keystore", - "--key-type", "tft!", - "--suri","/keys/tft", - "--scheme=sr25519" - ] - volumeMounts: - - name: keystore - mountPath: /keystore - - name: keys - mountPath: /keys - readOnly: true {{ end }} volumes: - name: keystore diff --git a/substrate-node/charts/substrate-node/values.yaml b/substrate-node/charts/substrate-node/values.yaml index 091627f25..040ff57b0 100644 --- a/substrate-node/charts/substrate-node/values.yaml +++ b/substrate-node/charts/substrate-node/values.yaml @@ -5,11 +5,11 @@ image: repository: tfchainnode pullPolicy: IfNotPresent - tag: "" + tag: '' imagePullSecrets: [] -nameOverride: "" -fullnameOverride: "" +nameOverride: '' +fullnameOverride: '' serviceAccount: # Specifies whether a service account should be created @@ -18,7 +18,7 @@ serviceAccount: annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template - name: "" + name: '' podAnnotations: {} @@ -39,15 +39,15 @@ service: type: ClusterIP port: 80 -name: "tfchainnode01" +name: 'tfchainnode01' port: 30333 ws_port: 9944 rpc_port: 9933 is_validator: true -chainspec: "/etc/chainspecs/dev/chainSpecRaw.json" +chainspec: '/etc/chainspecs/dev/chainSpecRaw.json' ws_max_connections: 1048576 #rpc_methods: "Unsafe" -rpc_methods: "safe" +rpc_methods: 'safe' disable_offchain_worker: true # telemetry_url: "" @@ -58,8 +58,6 @@ keys: [] # secret: "kkjghjfkkj kjhgkkhhgg" # - name: node # secret: 1a... -# - name: tft -# secret: "kkjghjfkkj kjhgkkhhgg" # boot_node: "/ip4/10.42.1.134/tcp/30333/p2p/12D3KooWGX8JFxZu2dDmGVpa9t9enZnFCLhH4NUBA7PDuhEVQTMg" @@ -91,10 +89,10 @@ resources: volume: size: 10Gi - existingpersistentVolumeClaim: "" + existingpersistentVolumeClaim: '' persistentVolume: create: true - hostPath: "/chain01" + hostPath: '/chain01' nodeSelector: {} @@ -103,4 +101,4 @@ tolerations: [] affinity: {} threefoldVdc: - backup: "" + backup: '' diff --git a/substrate-node/doc/adding_validators.md b/substrate-node/doc/adding_validators.md index 6b56e3f50..fea568c27 100644 --- a/substrate-node/doc/adding_validators.md +++ b/substrate-node/doc/adding_validators.md @@ -8,8 +8,6 @@ subkey generate --scheme sr25519 Take note of the SS58 address. -Transfer some balance to the new address. (0.1 TFT should be enough) - Create a node key ```sh @@ -29,34 +27,69 @@ This will write the node adress on std err followed by the node private key on s --base-path /storage \ --chain chainspecs/main/chainSpecRaw.json \ --validator \ - --bootnodes IP_OF_BOOTNODE --node-key --telemetry-url 'wss://shard1.telemetry.tfchain.grid.tf/submit 1' + --name "somename" ``` -Insert Aura and Grandpa key for this new node. +Insert Aura and Grandpa key for this new node: + +Aura: + +``` +./tfchain key insert --base-path /storage --chain /etc/chainspecs/dev/chainSpecRaw.json --key-type aura --suri "" --scheme sr25519 +``` -#### Insert a key in the session +Grandpa -Connect to the new node deployed with polkadot js apps. You will need to install a local version of this application since you will have to connect over an unsecured websocket. +``` +./tfchain key insert --base-path /storage --chain /etc/chainspecs/dev/chainSpecRaw.json --key-type gran --suri "" --scheme ed25519 +``` + +Smart contract billing: + +``` +./tfchain key insert --base-path /storage --chain /etc/chainspecs/dev/chainSpecRaw.json --key-type smct --suri "" --scheme sr25519 +``` + +### Deploy via Docker + +Install Docker and allow a user to run containers: ```sh -git clone git@github.com:polkadot-js/apps.git -yarn -yarn start +usermod -aG docker ``` -Browse to and connect to the new node over it's public ip. +Disable iptables in Docker. Edit /lib/systemd/system/docker.service and add --iptables=false to ExecStart= .. -Go to `rpc` -> `session` -> `rotateKeys`, execute it and take note of the output. +```sh +ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=false +``` -On the same new node, go to `extrinsics` -> `session` -> `setKeys`, Make sure you execute it this with the newly generated keypair. +Restart Docker -input: +```sh +systemctl daemon-reload +systemctl restart docker +``` -```log -keys: the key from rotate keys ouput -proofs: 0 +Create /storage dir and allow a user to write + +```sh +mkdir /storage +``` + +Start 2 containers to set keys in /storage, these will stop immediately + +```sh +docker run -v /storage/:/storage/ dylanverstraete/tfchain:2.1.0 key insert --base-path /storage --chain /etc/chainspecs/dev/chainSpecRaw.json --key-type aura --suri "" --scheme sr25519 +docker run -v /storage/:/storage/ dylanverstraete/tfchain:2.1.0 key insert --base-path /storage --chain /etc/chainspecs/dev/chainSpecRaw.json --key-type gran --suri "" --scheme ed25519 +``` + +Start another to insert the `smct` key for the billing. Make sure the mneminic is the sr25519 of the validator key (same as the aura key) + +```sh +docker run -v /storage/:/storage/ dylanverstraete/tfchain:2.1.0 key insert --base-path /storage --chain /etc/chainspecs/dev/chainSpecRaw.json --key-type smct --suri "" --scheme sr25519 ``` ### using kubernetes @@ -71,6 +104,8 @@ keys: secret: "" - name: grandpa secret: "" + - name: smct + secret: "" - name: node secret: ``` @@ -106,10 +141,30 @@ install the helm-chart located at `substrate-node/charts/substrate-node` in this Wait until you are synced with the network, you can see the last synced (best) and finalized blocks in the logs and highest block on the network as target. +## Allow the node as a validator to the chain + +Add the newly generated wallet to the polkadot extension of your browser. + +Transfer some balance (0.1 TFT should be enough) to the SS58 address (aura sr25519 key generated using 'subkey generate') + +Browse to https://polkadot.js.org/apps and connect to: wss://tfchain.dev.grid.tf + +Go to `Extrinsics` -> `session` -> `setKeys` -> (make sure to use the generated node account as the 'selected account', created above) -> + +input: + +``` +aura: +grandpa: +proofs: 0 +``` + ## Contact admin to insert the key into the validator set -An admin with access to the sudo key can call following extrinsic to insert the new node as a validator: +An admin with access to the sudo key can call following extrinsic to insert the new node as a validator. For Devnet, is found in encrypted repo. + +Submit the transaction with the SUDO key! -`extrinsics` -> `validatorSet` -> `addValidator` +`Developer` -> `Extrinsics` -> `sudo` -> `sudo(call)` -> -> `validatorSet` -> `addValidator` -> `validatorId` must be the account of the node you are adding -validatorID: SS58 encoded address of newly generated keypair (see step 1) +validatorID: SS58 encoded address of newly generated keypair (aura sr25519 key generated using 'subkey generate') diff --git a/substrate-node/doc/enable_billing.md b/substrate-node/doc/enable_billing.md new file mode 100644 index 000000000..3125a8a56 --- /dev/null +++ b/substrate-node/doc/enable_billing.md @@ -0,0 +1,14 @@ +# Enable billing on tfchain + +Every validator can now actively participate in billing of contracts. This by running the offchain worker with the `smct` key. + +## How to enable on a validator + +Run the validator with offchain worker enabled (by default it will be enabled). Generate a new key and put some funds on it. +Insert the funded key in the keystore: + +``` +tfchain key insert --keystore-path=/path-to-keystore --key-type "smct" --suri "words" --scheme=sr25519 +``` + +The validator should now actively participate in billing. diff --git a/substrate-node/doc/try_runtime.md b/substrate-node/doc/try_runtime.md new file mode 100644 index 000000000..32054eccb --- /dev/null +++ b/substrate-node/doc/try_runtime.md @@ -0,0 +1,18 @@ +# Trying out a runtime migration on a running network + +List of available endpoints for our networks: + +- Devnet: 10.10.0.151 +- QAnet: 10.10.0.152 +- Testnet: 10.10.0.22 +- Mainnet: 10.10.0.19 + +(If you are not in lochristi office you probably need vpn to reach to ips) + +## Select a network you wish to try the runtime upgrade upon + +Now go the release you want to test with try-runtime and compile as following: + +``` +cargo run --release --features=try-runtime try-runtime --runtime ./target/release/wbuild/tfchain-runtime/tfchain_runtime.compact.wasm --chain chainspecs/NETWORK/chainSpecRaw.json on-runtime-upgrade live --uri NETWORK_URL +``` diff --git a/substrate-node/node/Cargo.toml b/substrate-node/node/Cargo.toml index 32fe3362b..5cdd7662b 100644 --- a/substrate-node/node/Cargo.toml +++ b/substrate-node/node/Cargo.toml @@ -7,7 +7,7 @@ homepage = 'https://substrate.dev' license = 'Unlicense' name = 'tfchain' repository = 'https://github.com/substrate-developer-hub/substrate-node-template/' -version = '2.1.3' +version = '2.2.0' [[bin]] name = 'tfchain' @@ -16,7 +16,7 @@ name = 'tfchain' targets = ['x86_64-unknown-linux-gnu'] [build-dependencies] -substrate-build-script-utils = {package = "substrate-build-script-utils", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} +substrate-build-script-utils = {package = "substrate-build-script-utils", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} vergen = "3.1.0" [dependencies] @@ -25,53 +25,52 @@ hex-literal = "0.2.1" jsonrpc-core = "18.0.0" log = "0.4" structopt = "0.3.8" +jsonrpsee = { version = "0.16.2", features = ["server"] } +clap = { version = "4.0.9", features = ["derive"] } serde = { version = "1.0.119", features = ["derive"] } serde_json = "1.0.64" -jsonrpsee = { version = "0.13.0", features = ["server"] } -clap = { version = "3.1.18", features = ["derive"] } -tracing-core = "=0.1.26" -frame-benchmarking = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24"} -frame-system = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24"} -frame-benchmarking-cli = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24"} -pallet-transaction-payment-rpc = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -pallet-transaction-payment = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-basic-authorship = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-cli = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", features = ["wasmtime"]} -sc-client-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-executor = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-service = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-consensus = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-consensus-aura = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-finality-grandpa = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-finality-grandpa-rpc = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-keystore = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-keyring = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-network = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-rpc = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-rpc-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-telemetry = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-transaction-pool = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sc-transaction-pool-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-block-builder = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-blockchain = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-consensus = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-consensus-aura = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-core = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-finality-grandpa = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-inherents = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-runtime = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-timestamp = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -sp-transaction-pool = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -frame-rpc-system = {package = "substrate-frame-rpc-system", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24"} -frame-try-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24", optional = true } -try-runtime-cli = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24", optional = true } +frame-benchmarking = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.36"} +frame-system = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.36"} +frame-benchmarking-cli = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.36"} +pallet-transaction-payment-rpc = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +pallet-transaction-payment = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-basic-authorship = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-cli = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36" } +sc-client-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-executor = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-service = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-consensus = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-consensus-aura = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-finality-grandpa = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-finality-grandpa-rpc = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-keystore = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-keyring = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-network = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-rpc = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-rpc-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-telemetry = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-transaction-pool = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sc-transaction-pool-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-api = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-block-builder = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-blockchain = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-consensus = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-consensus-aura = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-core = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-finality-grandpa = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-inherents = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-runtime = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-io = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-timestamp = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +sp-transaction-pool = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +frame-rpc-system = {package = "substrate-frame-rpc-system", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36"} +frame-try-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.36", optional = true } +try-runtime-cli = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.36", optional = true } tfchain-runtime = { path = '../runtime' } [features] default = [] runtime-benchmarks = ["tfchain-runtime/runtime-benchmarks"] -cli = [ "try-runtime-cli" ] -try-runtime = [ "tfchain-runtime/try-runtime", "try-runtime-cli" ] +try-runtime = [ "tfchain-runtime/try-runtime", "try-runtime-cli/try-runtime"] diff --git a/substrate-node/node/src/chain_spec.rs b/substrate-node/node/src/chain_spec.rs index 5ac2d6376..113356d99 100644 --- a/substrate-node/node/src/chain_spec.rs +++ b/substrate-node/node/src/chain_spec.rs @@ -3,11 +3,12 @@ use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{ed25519, sr25519, Pair, Public}; use sp_finality_grandpa::AuthorityId as GrandpaId; use sp_runtime::traits::{IdentifyAccount, Verify}; +use std::convert::TryInto; use tfchain_runtime::opaque::SessionKeys; use tfchain_runtime::{ AccountId, AuraConfig, BalancesConfig, CouncilConfig, CouncilMembershipConfig, GenesisConfig, - GrandpaConfig, SessionConfig, Signature, SudoConfig, SystemConfig, TFTBridgeModuleConfig, - SmartContractModuleConfig, TFTPriceModuleConfig, TfgridModuleConfig, ValidatorSetConfig, + GrandpaConfig, SessionConfig, Signature, SmartContractModuleConfig, SudoConfig, SystemConfig, + TFTBridgeModuleConfig, TFTPriceModuleConfig, TfgridModuleConfig, ValidatorSetConfig, WASM_BINARY, }; @@ -116,8 +117,6 @@ pub fn development_config() -> Result { ], // Bridge fee account get_account_id_from_seed::("Ferdie"), - // TFT price pallet allow account - get_account_id_from_seed::("Alice"), // TFT price pallet min price 10, // TFT price pallet max price @@ -206,8 +205,6 @@ pub fn local_testnet_config() -> Result { ], // Bridge fee account get_account_id_from_seed::("Ferdie"), - // TFT price pallet allow account - get_account_id_from_seed::("Alice"), // TFT price pallet min price 10, // TFT price pallet max price @@ -241,10 +238,9 @@ fn testnet_genesis( _enable_println: bool, bridge_validator_accounts: Vec, bridge_fee_account: AccountId, - tft_price_allowed_account: AccountId, min_tft_price: u32, max_tft_price: u32, - billing_frequency: u64 + billing_frequency: u64, ) -> GenesisConfig { GenesisConfig { system: SystemConfig { @@ -326,17 +322,19 @@ fn testnet_genesis( get_account_id_from_seed::("Alice"), get_account_id_from_seed::("Bob"), get_account_id_from_seed::("Eve"), - ], + ] + .try_into() + .unwrap(), phantom: Default::default(), }, // just some default for development tft_price_module: TFTPriceModuleConfig { - allowed_origin: Some(tft_price_allowed_account), min_tft_price, max_tft_price, + _data: std::marker::PhantomData, }, smart_contract_module: SmartContractModuleConfig { - billing_frequency: billing_frequency + billing_frequency: billing_frequency, }, } } diff --git a/substrate-node/node/src/cli.rs b/substrate-node/node/src/cli.rs index bab3e0bf5..5d8513a1f 100644 --- a/substrate-node/node/src/cli.rs +++ b/substrate-node/node/src/cli.rs @@ -2,52 +2,52 @@ use sc_cli::RunCmd; #[derive(Debug, clap::Parser)] pub struct Cli { - #[clap(subcommand)] - pub subcommand: Option, + #[clap(subcommand)] + pub subcommand: Option, - #[clap(flatten)] - pub run: RunCmd, + #[clap(flatten)] + pub run: RunCmd, } #[derive(Debug, clap::Subcommand)] pub enum Subcommand { - /// Key management cli utilities - #[clap(subcommand)] - Key(sc_cli::KeySubcommand), + /// Key management cli utilities + #[clap(subcommand)] + Key(sc_cli::KeySubcommand), - /// Build a chain specification. - BuildSpec(sc_cli::BuildSpecCmd), + /// Build a chain specification. + BuildSpec(sc_cli::BuildSpecCmd), - /// Validate blocks. - CheckBlock(sc_cli::CheckBlockCmd), + /// Validate blocks. + CheckBlock(sc_cli::CheckBlockCmd), - /// Export blocks. - ExportBlocks(sc_cli::ExportBlocksCmd), + /// Export blocks. + ExportBlocks(sc_cli::ExportBlocksCmd), - /// Export the state of a given block into a chain spec. - ExportState(sc_cli::ExportStateCmd), + /// Export the state of a given block into a chain spec. + ExportState(sc_cli::ExportStateCmd), - /// Import blocks. - ImportBlocks(sc_cli::ImportBlocksCmd), + /// Import blocks. + ImportBlocks(sc_cli::ImportBlocksCmd), - /// Remove the whole chain. - PurgeChain(sc_cli::PurgeChainCmd), + /// Remove the whole chain. + PurgeChain(sc_cli::PurgeChainCmd), - /// Revert the chain to a previous state. - Revert(sc_cli::RevertCmd), + /// Revert the chain to a previous state. + Revert(sc_cli::RevertCmd), - /// Sub-commands concerned with benchmarking. - #[clap(subcommand)] - Benchmark(frame_benchmarking_cli::BenchmarkCmd), + /// Sub-commands concerned with benchmarking. + #[clap(subcommand)] + Benchmark(frame_benchmarking_cli::BenchmarkCmd), - /// Try some command against runtime state. - #[cfg(feature = "try-runtime")] - TryRuntime(try_runtime_cli::TryRuntimeCmd), + /// Try some command against runtime state. + #[cfg(feature = "try-runtime")] + TryRuntime(try_runtime_cli::TryRuntimeCmd), - /// Try some command against runtime state. Note: `try-runtime` feature must be enabled. - #[cfg(not(feature = "try-runtime"))] - TryRuntime, + /// Try some command against runtime state. Note: `try-runtime` feature must be enabled. + #[cfg(not(feature = "try-runtime"))] + TryRuntime, - /// Db meta columns information. - ChainInfo(sc_cli::ChainInfoCmd), -} \ No newline at end of file + /// Db meta columns information. + ChainInfo(sc_cli::ChainInfoCmd), +} diff --git a/substrate-node/node/src/command.rs b/substrate-node/node/src/command.rs index 7cdee4ba0..471840a74 100644 --- a/substrate-node/node/src/command.rs +++ b/substrate-node/node/src/command.rs @@ -1,177 +1,222 @@ use crate::{ - chain_spec, - cli::{Cli, Subcommand}, - command_helper::{inherent_benchmark_data, BenchmarkExtrinsicBuilder}, - service, + chain_spec, + cli::{Cli, Subcommand}, + command_helper::{inherent_benchmark_data, BenchmarkExtrinsicBuilder}, + service, }; use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; -use tfchain_runtime::Block; use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli}; use sc_service::PartialComponents; -use std::sync::Arc; +use tfchain_runtime::Block; impl SubstrateCli for Cli { - fn impl_name() -> String { - "Substrate Node".into() - } + fn impl_name() -> String { + "Substrate Node".into() + } - fn impl_version() -> String { - env!("SUBSTRATE_CLI_IMPL_VERSION").into() - } + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() + } - fn description() -> String { - env!("CARGO_PKG_DESCRIPTION").into() - } + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() + } - fn author() -> String { - env!("CARGO_PKG_AUTHORS").into() - } + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } - fn support_url() -> String { - "support.anonymous.an".into() - } + fn support_url() -> String { + "support.anonymous.an".into() + } - fn copyright_start_year() -> i32 { - 2017 - } + fn copyright_start_year() -> i32 { + 2017 + } - fn load_spec(&self, id: &str) -> Result, String> { - Ok(match id { - "dev" => Box::new(chain_spec::development_config()?), - "" | "local" => Box::new(chain_spec::local_testnet_config()?), - path => - Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?), - }) - } + fn load_spec(&self, id: &str) -> Result, String> { + Ok(match id { + "dev" => Box::new(chain_spec::development_config()?), + "" | "local" => Box::new(chain_spec::local_testnet_config()?), + path => Box::new(chain_spec::ChainSpec::from_json_file( + std::path::PathBuf::from(path), + )?), + }) + } - fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { - &tfchain_runtime::VERSION - } + fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { + &tfchain_runtime::VERSION + } } /// Parse and run command line arguments pub fn run() -> sc_cli::Result<()> { - let cli = Cli::from_args(); + let cli = Cli::from_args(); - match &cli.subcommand { - Some(Subcommand::Key(cmd)) => cmd.run(&cli), - Some(Subcommand::BuildSpec(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) - }, - Some(Subcommand::CheckBlock(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|config| { - let PartialComponents { client, task_manager, import_queue, .. } = - service::new_partial(&config)?; - Ok((cmd.run(client, import_queue), task_manager)) - }) - }, - Some(Subcommand::ExportBlocks(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|config| { - let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?; - Ok((cmd.run(client, config.database), task_manager)) - }) - }, - Some(Subcommand::ExportState(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|config| { - let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?; - Ok((cmd.run(client, config.chain_spec), task_manager)) - }) - }, - Some(Subcommand::ImportBlocks(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|config| { - let PartialComponents { client, task_manager, import_queue, .. } = - service::new_partial(&config)?; - Ok((cmd.run(client, import_queue), task_manager)) - }) - }, - Some(Subcommand::PurgeChain(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run(config.database)) - }, - Some(Subcommand::Revert(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|config| { - let PartialComponents { client, task_manager, backend, .. } = - service::new_partial(&config)?; - let aux_revert = Box::new(|client, _, blocks| { - sc_finality_grandpa::revert(client, blocks)?; - Ok(()) - }); - Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) - }) - }, - Some(Subcommand::Benchmark(cmd)) => { - let runner = cli.create_runner(cmd)?; + match &cli.subcommand { + Some(Subcommand::Key(cmd)) => cmd.run(&cli), + Some(Subcommand::BuildSpec(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) + } + Some(Subcommand::CheckBlock(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + import_queue, + .. + } = service::new_partial(&config)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::ExportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + .. + } = service::new_partial(&config)?; + Ok((cmd.run(client, config.database), task_manager)) + }) + } + Some(Subcommand::ExportState(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + .. + } = service::new_partial(&config)?; + Ok((cmd.run(client, config.chain_spec), task_manager)) + }) + } + Some(Subcommand::ImportBlocks(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + import_queue, + .. + } = service::new_partial(&config)?; + Ok((cmd.run(client, import_queue), task_manager)) + }) + } + Some(Subcommand::PurgeChain(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run(config.database)) + } + Some(Subcommand::Revert(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + let PartialComponents { + client, + task_manager, + backend, + .. + } = service::new_partial(&config)?; + let aux_revert = Box::new(|client, _, blocks| { + sc_finality_grandpa::revert(client, blocks)?; + Ok(()) + }); + Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) + }) + } + Some(Subcommand::Benchmark(cmd)) => { + let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| { - // This switch needs to be in the client, since the client decides - // which sub-commands it wants to support. - match cmd { - BenchmarkCmd::Pallet(cmd) => { - if !cfg!(feature = "runtime-benchmarks") { - return Err( - "Runtime benchmarking wasn't enabled when building the node. \ + runner.sync_run(|config| { + // This switch needs to be in the client, since the client decides + // which sub-commands it wants to support. + match cmd { + BenchmarkCmd::Pallet(cmd) => { + if !cfg!(feature = "runtime-benchmarks") { + return Err( + "Runtime benchmarking wasn't enabled when building the node. \ You can enable it with `--features runtime-benchmarks`." - .into(), - ) - } + .into(), + ); + } - cmd.run::(config) - }, - BenchmarkCmd::Block(cmd) => { - let PartialComponents { client, .. } = service::new_partial(&config)?; - cmd.run(client) - }, - BenchmarkCmd::Storage(cmd) => { - let PartialComponents { client, backend, .. } = - service::new_partial(&config)?; - let db = backend.expose_db(); - let storage = backend.expose_storage(); + cmd.run::(config) + } + BenchmarkCmd::Block(cmd) => { + let PartialComponents { client, .. } = service::new_partial(&config)?; + cmd.run(client) + } + #[cfg(not(feature = "runtime-benchmarks"))] + BenchmarkCmd::Storage(_) => Err( + "Storage benchmarking can be enabled with `--features runtime-benchmarks`." + .into(), + ), + #[cfg(feature = "runtime-benchmarks")] + BenchmarkCmd::Storage(cmd) => { + let PartialComponents { + client, backend, .. + } = service::new_partial(&config)?; + let db = backend.expose_db(); + let storage = backend.expose_storage(); - cmd.run(config, client, db, storage) - }, - BenchmarkCmd::Overhead(cmd) => { - let PartialComponents { client, .. } = service::new_partial(&config)?; - let ext_builder = BenchmarkExtrinsicBuilder::new(client.clone()); + cmd.run(config, client, db, storage) + } + BenchmarkCmd::Overhead(cmd) => { + let PartialComponents { client, .. } = service::new_partial(&config)?; + let ext_builder = BenchmarkExtrinsicBuilder::new(client.clone()); - cmd.run(config, client, inherent_benchmark_data()?, Arc::new(ext_builder)) - }, - BenchmarkCmd::Machine(cmd) => - cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone()), - } - }) - }, - #[cfg(feature = "try-runtime")] - Some(Subcommand::TryRuntime(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.async_run(|config| { - // we don't need any of the components of new_partial, just a runtime, or a task - // manager to do `async_run`. - let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); - let task_manager = - sc_service::TaskManager::new(config.tokio_handle.clone(), registry) - .map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?; - Ok((cmd.run::(config), task_manager)) - }) - }, - #[cfg(not(feature = "try-runtime"))] - Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ + cmd.run( + config, + client, + inherent_benchmark_data()?, + Vec::new(), + &ext_builder, + ) + } + BenchmarkCmd::Machine(cmd) => { + cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone()) + } + BenchmarkCmd::Extrinsic(_cmd) => { + todo!() + } + } + }) + } + #[cfg(feature = "try-runtime")] + Some(Subcommand::TryRuntime(cmd)) => { + use crate::service::ExecutorDispatch; + use sc_executor::{sp_wasm_interface::ExtendedHostFunctions, NativeExecutionDispatch}; + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + // we don't need any of the components of new_partial, just a runtime, or a task + // manager to do `async_run`. + let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); + let task_manager = + sc_service::TaskManager::new(config.tokio_handle.clone(), registry) + .map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?; + Ok(( + cmd.run::::ExtendHostFunctions, + >>(), + task_manager, + )) + }) + } + #[cfg(not(feature = "try-runtime"))] + Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ You can enable it with `--features try-runtime`." - .into()), - Some(Subcommand::ChainInfo(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run::(&config)) - }, - None => { - let runner = cli.create_runner(&cli.run)?; - runner.run_node_until_exit(|config| async move { - service::new_full(config).map_err(sc_cli::Error::Service) - }) - }, - } -} \ No newline at end of file + .into()), + Some(Subcommand::ChainInfo(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run::(&config)) + } + None => { + let runner = cli.create_runner(&cli.run)?; + runner.run_node_until_exit(|config| async move { + service::new_full(config).map_err(sc_cli::Error::Service) + }) + } + } +} diff --git a/substrate-node/node/src/command_helper.rs b/substrate-node/node/src/command_helper.rs index ac2854929..de991eaf2 100644 --- a/substrate-node/node/src/command_helper.rs +++ b/substrate-node/node/src/command_helper.rs @@ -21,111 +21,122 @@ use crate::service::FullClient; -use tfchain_runtime as runtime; use runtime::SystemCall; use sc_cli::Result; use sc_client_api::BlockBackend; use sp_core::{Encode, Pair}; -use sp_inherents::{InherentData, InherentDataProvider}; +use sp_inherents::InherentData; use sp_keyring::Sr25519Keyring; use sp_runtime::{OpaqueExtrinsic, SaturatedConversion}; - -use std::{sync::Arc, time::Duration}; +use std::sync::Arc; +use tfchain_runtime as runtime; /// Generates extrinsics for the `benchmark overhead` command. /// /// Note: Should only be used for benchmarking. pub struct BenchmarkExtrinsicBuilder { - client: Arc, + client: Arc, } impl BenchmarkExtrinsicBuilder { - /// Creates a new [`Self`] from the given client. - pub fn new(client: Arc) -> Self { - Self { client } - } + /// Creates a new [`Self`] from the given client. + pub fn new(client: Arc) -> Self { + Self { client } + } } impl frame_benchmarking_cli::ExtrinsicBuilder for BenchmarkExtrinsicBuilder { - fn remark(&self, nonce: u32) -> std::result::Result { - let acc = Sr25519Keyring::Bob.pair(); - let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( - self.client.as_ref(), - acc, - SystemCall::remark { remark: vec![] }.into(), - nonce, - ) - .into(); - - Ok(extrinsic) - } + fn extrinsic(&self) -> &str { + todo!() + } + + fn build(&self, nonce: u32) -> std::result::Result { + let acc = Sr25519Keyring::Bob.pair(); + let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( + self.client.as_ref(), + acc, + SystemCall::remark { remark: vec![] }.into(), + nonce, + ) + .into(); + + Ok(extrinsic) + } + + fn pallet(&self) -> &str { + todo!() + } } /// Create a transaction using the given `call`. /// /// Note: Should only be used for benchmarking. pub fn create_benchmark_extrinsic( - client: &FullClient, - sender: sp_core::sr25519::Pair, - call: runtime::Call, - nonce: u32, + client: &FullClient, + sender: sp_core::sr25519::Pair, + call: runtime::RuntimeCall, + nonce: u32, ) -> runtime::UncheckedExtrinsic { - let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"); - let best_hash = client.chain_info().best_hash; - let best_block = client.chain_info().best_number; - - let period = runtime::BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; - let extra: runtime::SignedExtra = ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(sp_runtime::generic::Era::mortal( - period, - best_block.saturated_into(), - )), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ); - - let raw_payload = runtime::SignedPayload::from_raw( - call.clone(), - extra.clone(), - ( - (), - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - genesis_hash, - best_hash, - (), - (), - (), - ), - ); - let signature = raw_payload.using_encoded(|e| sender.sign(e)); - - runtime::UncheckedExtrinsic::new_signed( - call.clone(), - sp_runtime::AccountId32::from(sender.public()).into(), - runtime::Signature::Sr25519(signature.clone()), - extra.clone(), - ) + let genesis_hash = client + .block_hash(0) + .ok() + .flatten() + .expect("Genesis block exists; qed"); + let best_hash = client.chain_info().best_hash; + let best_block = client.chain_info().best_number; + + let period = runtime::BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + let extra: runtime::SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(sp_runtime::generic::Era::mortal( + period, + best_block.saturated_into(), + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ); + + let raw_payload = runtime::SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis_hash, + best_hash, + (), + (), + (), + ), + ); + let signature = raw_payload.using_encoded(|e| sender.sign(e)); + + runtime::UncheckedExtrinsic::new_signed( + call.clone(), + sp_runtime::AccountId32::from(sender.public()).into(), + runtime::Signature::Sr25519(signature.clone()), + extra.clone(), + ) } /// Generates inherent data for the `benchmark overhead` command. /// /// Note: Should only be used for benchmarking. pub fn inherent_benchmark_data() -> Result { - let mut inherent_data = InherentData::new(); - let d = Duration::from_millis(0); - let timestamp = sp_timestamp::InherentDataProvider::new(d.into()); - - timestamp - .provide_inherent_data(&mut inherent_data) - .map_err(|e| format!("creating inherent data: {:?}", e))?; - Ok(inherent_data) -} \ No newline at end of file + // TODO, see if we can fix this later + // let mut inherent_data = InherentData::new(); + // let d = Duration::from_millis(0); + // let timestamp = sp_timestamp::InherentDataProvider::new(d.into()); + // timestamp + // .provide_inherent_data(&mut inherent_data) + // .map_err(|e| format!("creating inherent data: {:?}", e))?; + Ok(InherentData::new()) +} diff --git a/substrate-node/node/src/rpc.rs b/substrate-node/node/src/rpc.rs index b048cdf18..d8d684e4c 100644 --- a/substrate-node/node/src/rpc.rs +++ b/substrate-node/node/src/rpc.rs @@ -9,53 +9,54 @@ use std::sync::Arc; use jsonrpsee::RpcModule; -use tfchain_runtime::{opaque::Block, AccountId, Balance, Index}; pub use sc_rpc_api::DenyUnsafe; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; - +use tfchain_runtime::{opaque::Block, AccountId, Balance, Index}; /// Full client dependencies. pub struct FullDeps { - /// The client instance to use. - pub client: Arc, - /// Transaction pool instance. - pub pool: Arc

, - /// Whether to deny unsafe calls - pub deny_unsafe: DenyUnsafe, + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Whether to deny unsafe calls + pub deny_unsafe: DenyUnsafe, } /// Instantiate all full RPC extensions. -pub fn create_full(deps: FullDeps) -> Result, Box> +pub fn create_full( + deps: FullDeps, +) -> Result, Box> where - C: ProvideRuntimeApi, - C: HeaderBackend + HeaderMetadata + 'static, - C: Send + Sync + 'static, - C::Api: frame_rpc_system::AccountNonceApi, - C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - C::Api: BlockBuilder, - P: TransactionPool + 'static, + C: ProvideRuntimeApi, + C: HeaderBackend + HeaderMetadata + 'static, + C: Send + Sync + 'static, + C::Api: frame_rpc_system::AccountNonceApi, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: BlockBuilder, + P: TransactionPool + 'static, { - use frame_rpc_system::{System, SystemApiServer}; - use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; - - let mut module = RpcModule::new(()); - let FullDeps { - client, - pool, - deny_unsafe, - } = deps; - - module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; - module.merge(TransactionPayment::new(client).into_rpc())?; - - // Extend this RPC with a custom API by using the following syntax. - // `YourRpcStruct` should have a reference to a client, which is needed - // to call into the runtime. - // `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, - // ...)))?;` - - Ok(module) -} \ No newline at end of file + use frame_rpc_system::{System, SystemApiServer}; + use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; + + let mut module = RpcModule::new(()); + let FullDeps { + client, + pool, + deny_unsafe, + } = deps; + + module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; + module.merge(TransactionPayment::new(client).into_rpc())?; + + // Extend this RPC with a custom API by using the following syntax. + // `YourRpcStruct` should have a reference to a client, which is needed + // to call into the runtime. + // `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, + // ...)))?;` + + Ok(module) +} diff --git a/substrate-node/node/src/service.rs b/substrate-node/node/src/service.rs index bddca25d8..b85e7690d 100644 --- a/substrate-node/node/src/service.rs +++ b/substrate-node/node/src/service.rs @@ -1,7 +1,6 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. -use tfchain_runtime::{self, opaque::Block, RuntimeApi}; -use sc_client_api::{BlockBackend, ExecutorProvider}; +use sc_client_api::BlockBackend; use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams}; pub use sc_executor::NativeElseWasmExecutor; use sc_finality_grandpa::SharedVoterState; @@ -10,332 +9,367 @@ use sc_service::{error::Error as ServiceError, Configuration, TaskManager}; use sc_telemetry::{Telemetry, TelemetryWorker}; use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; use std::{sync::Arc, time::Duration}; +use tfchain_runtime::{self, opaque::Block, RuntimeApi}; // Our native executor instance. pub struct ExecutorDispatch; impl sc_executor::NativeExecutionDispatch for ExecutorDispatch { - /// Only enable the benchmarking host functions when we actually want to benchmark. - #[cfg(feature = "runtime-benchmarks")] - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - /// Otherwise we only use the default Substrate host functions. - #[cfg(not(feature = "runtime-benchmarks"))] - type ExtendHostFunctions = (); - - fn dispatch(method: &str, data: &[u8]) -> Option> { - tfchain_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - tfchain_runtime::native_version() - } + /// Only enable the benchmarking host functions when we actually want to benchmark. + #[cfg(feature = "runtime-benchmarks")] + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + /// Otherwise we only use the default Substrate host functions. + #[cfg(not(feature = "runtime-benchmarks"))] + type ExtendHostFunctions = (); + + fn dispatch(method: &str, data: &[u8]) -> Option> { + tfchain_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + tfchain_runtime::native_version() + } } pub type FullClient = - sc_service::TFullClient>; + sc_service::TFullClient>; type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; pub fn new_partial( - config: &Configuration, + config: &Configuration, ) -> Result< - sc_service::PartialComponents< - FullClient, - FullBackend, - FullSelectChain, - sc_consensus::DefaultImportQueue, - sc_transaction_pool::FullPool, - ( - sc_finality_grandpa::GrandpaBlockImport< - FullBackend, - Block, - FullClient, - FullSelectChain, - >, - sc_finality_grandpa::LinkHalf, - Option, - ), - >, - ServiceError, + sc_service::PartialComponents< + FullClient, + FullBackend, + FullSelectChain, + sc_consensus::DefaultImportQueue, + sc_transaction_pool::FullPool, + ( + sc_finality_grandpa::GrandpaBlockImport< + FullBackend, + Block, + FullClient, + FullSelectChain, + >, + sc_finality_grandpa::LinkHalf, + Option, + ), + >, + ServiceError, > { - if config.keystore_remote.is_some() { - return Err(ServiceError::Other(format!("Remote Keystores are not supported."))) - } - - let telemetry = config - .telemetry_endpoints - .clone() - .filter(|x| !x.is_empty()) - .map(|endpoints| -> Result<_, sc_telemetry::Error> { - let worker = TelemetryWorker::new(16)?; - let telemetry = worker.handle().new_telemetry(endpoints); - Ok((worker, telemetry)) - }) - .transpose()?; - - let executor = NativeElseWasmExecutor::::new( - config.wasm_method, - config.default_heap_pages, - config.max_runtime_instances, - config.runtime_cache_size, - ); - - let (client, backend, keystore_container, task_manager) = - sc_service::new_full_parts::( - &config, - telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), - executor, - )?; - let client = Arc::new(client); - - let telemetry = telemetry.map(|(worker, telemetry)| { - task_manager.spawn_handle().spawn("telemetry", None, worker.run()); - telemetry - }); - - let select_chain = sc_consensus::LongestChain::new(backend.clone()); - - let transaction_pool = sc_transaction_pool::BasicPool::new_full( - config.transaction_pool.clone(), - config.role.is_authority().into(), - config.prometheus_registry(), - task_manager.spawn_essential_handle(), - client.clone(), - ); - - let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( - client.clone(), - &(client.clone() as Arc<_>), - select_chain.clone(), - telemetry.as_ref().map(|x| x.handle()), - )?; - - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - - let import_queue = - sc_consensus_aura::import_queue::(ImportQueueParams { - block_import: grandpa_block_import.clone(), - justification_import: Some(Box::new(grandpa_block_import.clone())), - client: client.clone(), - create_inherent_data_providers: move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = + if config.keystore_remote.is_some() { + return Err(ServiceError::Other(format!( + "Remote Keystores are not supported." + ))); + } + + let telemetry = config + .telemetry_endpoints + .clone() + .filter(|x| !x.is_empty()) + .map(|endpoints| -> Result<_, sc_telemetry::Error> { + let worker = TelemetryWorker::new(16)?; + let telemetry = worker.handle().new_telemetry(endpoints); + Ok((worker, telemetry)) + }) + .transpose()?; + + let executor = NativeElseWasmExecutor::::new( + config.wasm_method, + config.default_heap_pages, + config.max_runtime_instances, + config.runtime_cache_size, + ); + + let (client, backend, keystore_container, task_manager) = + sc_service::new_full_parts::( + &config, + telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), + executor, + )?; + let client = Arc::new(client); + + let telemetry = telemetry.map(|(worker, telemetry)| { + task_manager + .spawn_handle() + .spawn("telemetry", None, worker.run()); + telemetry + }); + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.role.is_authority().into(), + config.prometheus_registry(), + task_manager.spawn_essential_handle(), + client.clone(), + ); + + let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( + client.clone(), + &(client.clone() as Arc<_>), + select_chain.clone(), + telemetry.as_ref().map(|x| x.handle()), + )?; + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + + let import_queue = + sc_consensus_aura::import_queue::(ImportQueueParams { + block_import: grandpa_block_import.clone(), + justification_import: Some(Box::new(grandpa_block_import.clone())), + client: client.clone(), + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( *timestamp, slot_duration, ); - Ok((timestamp, slot)) - }, - spawner: &task_manager.spawn_essential_handle(), - can_author_with: sp_consensus::CanAuthorWithNativeVersion::new( - client.executor().clone(), - ), - registry: config.prometheus_registry(), - check_for_equivocation: Default::default(), - telemetry: telemetry.as_ref().map(|x| x.handle()), - })?; - - Ok(sc_service::PartialComponents { - client, - backend, - task_manager, - import_queue, - keystore_container, - select_chain, - transaction_pool, - other: (grandpa_block_import, grandpa_link, telemetry), - }) + Ok((slot, timestamp)) + }, + spawner: &task_manager.spawn_essential_handle(), + registry: config.prometheus_registry(), + check_for_equivocation: Default::default(), + telemetry: telemetry.as_ref().map(|x| x.handle()), + compatibility_mode: sc_consensus_aura::CompatibilityMode::UseInitializeBlock { + until: 1195403, + }, + })?; + + Ok(sc_service::PartialComponents { + client, + backend, + task_manager, + import_queue, + keystore_container, + select_chain, + transaction_pool, + other: (grandpa_block_import, grandpa_link, telemetry), + }) } fn remote_keystore(_url: &String) -> Result, &'static str> { - // FIXME: here would the concrete keystore be built, - // must return a concrete type (NOT `LocalKeystore`) that - // implements `CryptoStore` and `SyncCryptoStore` - Err("Remote Keystore not supported.") + // FIXME: here would the concrete keystore be built, + // must return a concrete type (NOT `LocalKeystore`) that + // implements `CryptoStore` and `SyncCryptoStore` + Err("Remote Keystore not supported.") } /// Builds a new service for a full client. pub fn new_full(mut config: Configuration) -> Result { - let sc_service::PartialComponents { - client, - backend, - mut task_manager, - import_queue, - mut keystore_container, - select_chain, - transaction_pool, - other: (block_import, grandpa_link, mut telemetry), - } = new_partial(&config)?; - - if let Some(url) = &config.keystore_remote { - match remote_keystore(url) { - Ok(k) => keystore_container.set_remote_keystore(k), - Err(e) => - return Err(ServiceError::Other(format!( - "Error hooking up remote keystore for {}: {}", - url, e - ))), - }; - } - - let grandpa_protocol_name = sc_finality_grandpa::protocol_standard_name( - &client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"), - &config.chain_spec, - ); - - config - .network - .extra_sets - .push(sc_finality_grandpa::grandpa_peers_set_config( - grandpa_protocol_name.clone(), - )); - let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new( - backend.clone(), - grandpa_link.shared_authority_set().clone(), - Vec::default(), - )); - - let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { - config: &config, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - spawn_handle: task_manager.spawn_handle(), - import_queue, - block_announce_validator_builder: None, - warp_sync: Some(warp_sync), - })?; - - if config.offchain_worker.enabled { - sc_service::build_offchain_workers(&config, task_manager.spawn_handle(), client.clone(), network.clone()); - } - let role = config.role.clone(); - let force_authoring = config.force_authoring; - let backoff_authoring_blocks: Option<()> = None; - let name = config.network.node_name.clone(); - let enable_grandpa = !config.disable_grandpa; - let prometheus_registry = config.prometheus_registry().cloned(); - - let rpc_extensions_builder = { - let client = client.clone(); - let pool = transaction_pool.clone(); - - Box::new(move |deny_unsafe, _| { - let deps = - crate::rpc::FullDeps { client: client.clone(), pool: pool.clone(), deny_unsafe }; - crate::rpc::create_full(deps).map_err(Into::into) - }) - }; - - let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { - network: network.clone(), - client: client.clone(), - keystore: keystore_container.sync_keystore(), - task_manager: &mut task_manager, - transaction_pool: transaction_pool.clone(), - rpc_builder: rpc_extensions_builder, - backend, - system_rpc_tx, - config, - telemetry: telemetry.as_mut(), - })?; - - if role.is_authority() { - let proposer_factory = sc_basic_authorship::ProposerFactory::new( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry.as_ref(), - telemetry.as_ref().map(|x| x.handle()), - ); - - let can_author_with = - sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); - - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - // let raw_slot_duration = slot_duration.slot_duration(); - - let aura = sc_consensus_aura::start_aura::( - StartAuraParams { - slot_duration, - client: client.clone(), - select_chain, - block_import, - proposer_factory, - create_inherent_data_providers: move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = + let sc_service::PartialComponents { + client, + backend, + mut task_manager, + import_queue, + mut keystore_container, + select_chain, + transaction_pool, + other: (block_import, grandpa_link, mut telemetry), + } = new_partial(&config)?; + + if let Some(url) = &config.keystore_remote { + match remote_keystore(url) { + Ok(k) => keystore_container.set_remote_keystore(k), + Err(e) => { + return Err(ServiceError::Other(format!( + "Error hooking up remote keystore for {}: {}", + url, e + ))) + } + }; + } + + let grandpa_protocol_name = sc_finality_grandpa::protocol_standard_name( + &client + .block_hash(0) + .ok() + .flatten() + .expect("Genesis block exists; qed"), + &config.chain_spec, + ); + + config + .network + .extra_sets + .push(sc_finality_grandpa::grandpa_peers_set_config( + grandpa_protocol_name.clone(), + )); + let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + grandpa_link.shared_authority_set().clone(), + Vec::default(), + )); + + let (network, system_rpc_tx, tx_handler_controller, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + block_announce_validator_builder: None, + warp_sync: Some(warp_sync), + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, + task_manager.spawn_handle(), + client.clone(), + network.clone(), + ); + } + + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let backoff_authoring_blocks: Option<()> = None; + let name = config.network.node_name.clone(); + let enable_grandpa = !config.disable_grandpa; + let prometheus_registry = config.prometheus_registry().cloned(); + + let rpc_extensions_builder = { + let client = client.clone(); + let pool = transaction_pool.clone(); + + Box::new(move |deny_unsafe, _| { + let deps = crate::rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + deny_unsafe, + }; + crate::rpc::create_full(deps).map_err(Into::into) + }) + }; + + let compatibility_mode = match config.chain_spec.id() { + "tfchain_devnet" => { + sc_consensus_aura::CompatibilityMode::UseInitializeBlock { until: 1195403 } + } + "tfchain_qa_net" => { + sc_consensus_aura::CompatibilityMode::UseInitializeBlock { until: 608253 } + } + "tfchain_testnet" => { + sc_consensus_aura::CompatibilityMode::UseInitializeBlock { until: 4740026 } + } + "tfchain_mainnet" => { + sc_consensus_aura::CompatibilityMode::UseInitializeBlock { until: 4231659 } + } + _ => sc_consensus_aura::CompatibilityMode::None, + }; + + let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { + network: network.clone(), + client: client.clone(), + keystore: keystore_container.sync_keystore(), + task_manager: &mut task_manager, + transaction_pool: transaction_pool.clone(), + rpc_builder: rpc_extensions_builder, + backend, + system_rpc_tx, + tx_handler_controller, + config, + telemetry: telemetry.as_mut(), + })?; + + if role.is_authority() { + let proposer_factory = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry.as_ref(), + telemetry.as_ref().map(|x| x.handle()), + ); + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + + let aura = sc_consensus_aura::start_aura::( + StartAuraParams { + slot_duration, + client, + select_chain, + block_import, + proposer_factory, + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( *timestamp, slot_duration, ); - Ok((timestamp, slot)) - }, - force_authoring, - backoff_authoring_blocks, - keystore: keystore_container.sync_keystore(), - can_author_with, - sync_oracle: network.clone(), - justification_sync_link: network.clone(), - block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32), - max_block_proposal_slot_portion: None, - telemetry: telemetry.as_ref().map(|x| x.handle()), - }, - )?; - - // the AURA authoring task is considered essential, i.e. if it - // fails we take down the service with it. - task_manager - .spawn_essential_handle() - .spawn_blocking("aura", Some("block-authoring"), aura); - } - - // if the node isn't actively participating in consensus then it doesn't - // need a keystore, regardless of which protocol we use below. - let keystore = - if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None }; - - let grandpa_config = sc_finality_grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_period: 512, - name: Some(name), - observer_enabled: false, - keystore, - local_role: role, - telemetry: telemetry.as_ref().map(|x| x.handle()), - protocol_name: grandpa_protocol_name, - }; - - if enable_grandpa { - // start the full GRANDPA voter - // NOTE: non-authorities could run the GRANDPA observer protocol, but at - // this point the full voter should provide better guarantees of block - // and vote data availability than the observer. The observer has not - // been tested extensively yet and having most nodes in a network run it - // could lead to finality stalls. - let grandpa_config = sc_finality_grandpa::GrandpaParams { - config: grandpa_config, - link: grandpa_link, - network, - voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), - prometheus_registry, - shared_voter_state: SharedVoterState::empty(), - telemetry: telemetry.as_ref().map(|x| x.handle()), - }; - - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - task_manager.spawn_essential_handle().spawn_blocking( - "grandpa-voter", - None, - sc_finality_grandpa::run_grandpa_voter(grandpa_config)?, - ); - } - - network_starter.start_network(); - Ok(task_manager) -} \ No newline at end of file + Ok((slot, timestamp)) + }, + force_authoring, + backoff_authoring_blocks, + keystore: keystore_container.sync_keystore(), + sync_oracle: network.clone(), + justification_sync_link: network.clone(), + block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32), + max_block_proposal_slot_portion: None, + telemetry: telemetry.as_ref().map(|x| x.handle()), + compatibility_mode, + }, + )?; + + // the AURA authoring task is considered essential, i.e. if it + // fails we take down the service with it. + task_manager + .spawn_essential_handle() + .spawn_blocking("aura", Some("block-authoring"), aura); + } + + if enable_grandpa { + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = if role.is_authority() { + Some(keystore_container.sync_keystore()) + } else { + None + }; + + let grandpa_config = sc_finality_grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 512, + name: Some(name), + observer_enabled: false, + keystore, + local_role: role, + telemetry: telemetry.as_ref().map(|x| x.handle()), + protocol_name: grandpa_protocol_name, + }; + // start the full GRANDPA voter + // NOTE: non-authorities could run the GRANDPA observer protocol, but at + // this point the full voter should provide better guarantees of block + // and vote data availability than the observer. The observer has not + // been tested extensively yet and having most nodes in a network run it + // could lead to finality stalls. + let grandpa_config = sc_finality_grandpa::GrandpaParams { + config: grandpa_config, + link: grandpa_link, + network, + voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), + prometheus_registry, + shared_voter_state: SharedVoterState::empty(), + telemetry: telemetry.as_ref().map(|x| x.handle()), + }; + + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + task_manager.spawn_essential_handle().spawn_blocking( + "grandpa-voter", + None, + sc_finality_grandpa::run_grandpa_voter(grandpa_config)?, + ); + } + + network_starter.start_network(); + Ok(task_manager) +} diff --git a/substrate-node/pallets/pallet-burning/Cargo.toml b/substrate-node/pallets/pallet-burning/Cargo.toml index 428c4ef4d..d6289185c 100644 --- a/substrate-node/pallets/pallet-burning/Cargo.toml +++ b/substrate-node/pallets/pallet-burning/Cargo.toml @@ -18,17 +18,17 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [features] default = ['std'] @@ -43,4 +43,7 @@ std = [ 'codec/std', 'sp-io/std', 'scale-info/std' +] +try-runtime = [ + "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-burning/src/lib.rs b/substrate-node/pallets/pallet-burning/src/lib.rs index ca0ff3ea1..c339040a5 100644 --- a/substrate-node/pallets/pallet-burning/src/lib.rs +++ b/substrate-node/pallets/pallet-burning/src/lib.rs @@ -52,7 +52,7 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { - type Event: From> + IsType<::Event>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// Currency type for this pallet. type Currency: Currency + ReservableCurrency; /// Handler for the unbalanced decrement when slashing (burning collateral) @@ -77,6 +77,7 @@ pub mod pallet { #[pallet::call] impl Pallet { + #[pallet::call_index(0)] #[pallet::weight(100_000_000)] pub fn burn_tft( origin: OriginFor, @@ -132,4 +133,4 @@ impl Pallet { Ok(()) } -} +} \ No newline at end of file diff --git a/substrate-node/pallets/pallet-burning/src/mock.rs b/substrate-node/pallets/pallet-burning/src/mock.rs index 5b8042029..26b83609a 100644 --- a/substrate-node/pallets/pallet-burning/src/mock.rs +++ b/substrate-node/pallets/pallet-burning/src/mock.rs @@ -34,25 +34,22 @@ construct_runtime!( parameter_types! { pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); - pub const ExistentialDeposit: u64 = 1; } impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; - type Call = Call; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type DbWeight = (); type Version = (); @@ -69,6 +66,7 @@ impl frame_system::Config for TestRuntime { parameter_types! { pub const MaxLocks: u32 = 50; pub const MaxReserves: u32 = 50; + pub const ExistentialDeposit: u64 = 1; } impl pallet_balances::Config for TestRuntime { @@ -78,7 +76,7 @@ impl pallet_balances::Config for TestRuntime { /// The type for recording an account's balance. type Balance = u64; /// The ubiquitous event type. - type Event = Event; + type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; @@ -86,7 +84,7 @@ impl pallet_balances::Config for TestRuntime { } impl Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type Currency = Balances; type Burn = (); } diff --git a/substrate-node/pallets/pallet-burning/src/tests.rs b/substrate-node/pallets/pallet-burning/src/tests.rs index ce2e2ecda..661c56a64 100644 --- a/substrate-node/pallets/pallet-burning/src/tests.rs +++ b/substrate-node/pallets/pallet-burning/src/tests.rs @@ -6,7 +6,7 @@ use sp_runtime::traits::SaturatedConversion; fn test_burn() { new_test_ext().execute_with(|| { assert_ok!(BurningModule::burn_tft( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 900000000000, "some_message".as_bytes().to_vec() )); @@ -22,7 +22,7 @@ fn test_burn_to_much_fails() { new_test_ext().execute_with(|| { assert_noop!( BurningModule::burn_tft( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1200000000000, "some_message".as_bytes().to_vec() ), diff --git a/substrate-node/pallets/pallet-dao/Cargo.toml b/substrate-node/pallets/pallet-dao/Cargo.toml index 107d54e51..4059a1956 100644 --- a/substrate-node/pallets/pallet-dao/Cargo.toml +++ b/substrate-node/pallets/pallet-dao/Cargo.toml @@ -12,6 +12,10 @@ repository = "https://github.com/substrate-developer-hub/substrate-node-template [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] +[dependencies.log] +default-features = false +version = '0.4.14' + [dependencies] serde = { version = '1.0.100', default-features = false, features = ['derive'], optional = true } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ @@ -19,21 +23,22 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } tfchain-support = { path = "../../support", default-features = false } pallet-tfgrid = { path = "../pallet-tfgrid", default-features = false } [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +env_logger = "*" [features] default = ["std"] @@ -52,9 +57,8 @@ std = [ "tfchain-support/std", 'scale-info/std', 'serde/std', + 'log/std' +] +try-runtime = [ + "frame-support/try-runtime", ] -runtime-benchmarks = [ - "frame-benchmarking", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks" -] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-dao/src/lib.rs b/substrate-node/pallets/pallet-dao/src/lib.rs index 4a168faad..b85677d6c 100644 --- a/substrate-node/pallets/pallet-dao/src/lib.rs +++ b/substrate-node/pallets/pallet-dao/src/lib.rs @@ -1,22 +1,22 @@ #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit = "128"] -use pallet_tfgrid::pallet::{InterfaceOf, PubConfigOf}; +use pallet_tfgrid::pallet::{InterfaceOf, LocationOf, SerialNumberOf, TfgridNode}; use sp_runtime::traits::Hash; use sp_std::prelude::*; use frame_support::{ dispatch::{ - DispatchError, DispatchResult, DispatchResultWithPostInfo, Dispatchable, PostDispatchInfo, + DispatchError, DispatchResult, DispatchResultWithPostInfo, Dispatchable, GetDispatchInfo, + PostDispatchInfo, }, ensure, traits::{EnsureOrigin, Get}, - weights::{GetDispatchInfo, Weight}, + weights::Weight, }; use tfchain_support::{ - constants, resources, + constants, traits::{ChangeNode, Tfgrid}, - types::{Node, Resources}, }; pub use pallet::*; @@ -44,9 +44,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use pallet_tfgrid::farm::FarmName; - use pallet_tfgrid::pub_ip::{GatewayIP, PublicIP}; use sp_std::convert::TryInto; - use tfchain_support::types::PublicIP as SupportPublicIP; #[pallet::config] pub trait Config: @@ -55,12 +53,12 @@ pub mod pallet { + pallet_tfgrid::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event - type Event: From> + IsType<::Event>; - type CouncilOrigin: EnsureOrigin<::Origin>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type CouncilOrigin: EnsureOrigin; /// The outer call dispatch type. type Proposal: Parameter - + Dispatchable + + Dispatchable + From> + GetDispatchInfo; @@ -70,12 +68,8 @@ pub mod pallet { /// The minimum amount of vetos to dissaprove a proposal type MinVetos: Get; - type Tfgrid: Tfgrid< - Self::AccountId, - FarmName, - SupportPublicIP, GatewayIP>, - >; - type NodeChanged: ChangeNode, InterfaceOf>; + type Tfgrid: Tfgrid>; + type NodeChanged: ChangeNode, InterfaceOf, SerialNumberOf>; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; @@ -193,6 +187,7 @@ pub mod pallet { #[pallet::call] impl Pallet { + #[pallet::call_index(0)] #[pallet::weight((::WeightInfo::propose(), DispatchClass::Operational))] pub fn propose( origin: OriginFor, @@ -259,6 +254,7 @@ pub mod pallet { Ok(().into()) } + #[pallet::call_index(1)] #[pallet::weight((::WeightInfo::vote(), DispatchClass::Operational))] pub fn vote( origin: OriginFor, @@ -339,6 +335,7 @@ pub mod pallet { } } + #[pallet::call_index(2)] #[pallet::weight((::WeightInfo::vote(), DispatchClass::Operational))] pub fn veto(origin: OriginFor, proposal_hash: T::Hash) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; @@ -373,6 +370,7 @@ pub mod pallet { return Ok(Pays::No.into()); } + #[pallet::call_index(3)] #[pallet::weight((::WeightInfo::close(), DispatchClass::Operational))] pub fn close( origin: OriginFor, @@ -502,12 +500,6 @@ impl Pallet { ProposalList::::set(active_proposals); } - pub fn get_node_weight(resources: Resources) -> u64 { - let cu = resources::get_cu(resources); - let su = resources::get_su(resources); - cu * 2 + su - } - fn is_council_member(who: T::AccountId) -> DispatchResultWithPostInfo { let council_members = pallet_membership::Pallet::::members(); @@ -518,15 +510,12 @@ impl Pallet { } } -impl ChangeNode, InterfaceOf> for Pallet { - fn node_changed( - old_node: Option<&Node, InterfaceOf>>, - new_node: &Node, InterfaceOf>, - ) { - let new_node_weight = Self::get_node_weight(new_node.resources); +impl ChangeNode, InterfaceOf, SerialNumberOf> for Pallet { + fn node_changed(old_node: Option<&TfgridNode>, new_node: &TfgridNode) { + let new_node_weight = new_node.resources.get_node_weight(); match old_node { Some(node) => { - let old_node_weight = Self::get_node_weight(node.resources); + let old_node_weight = node.resources.get_node_weight(); if node.farm_id != new_node.farm_id { let mut old_farm_weight = FarmWeight::::get(node.farm_id); @@ -553,10 +542,10 @@ impl ChangeNode, InterfaceOf> for Pallet { }; } - fn node_deleted(node: &Node, InterfaceOf>) { - let node_weight = Self::get_node_weight(node.resources); + fn node_deleted(node: &TfgridNode) { + let node_weight = node.resources.get_node_weight(); let mut farm_weight = FarmWeight::::get(node.farm_id); farm_weight = farm_weight.checked_sub(node_weight).unwrap_or(0); FarmWeight::::insert(node.farm_id, farm_weight); } -} +} \ No newline at end of file diff --git a/substrate-node/pallets/pallet-dao/src/mock.rs b/substrate-node/pallets/pallet-dao/src/mock.rs index 25c06f752..1bbe03aed 100644 --- a/substrate-node/pallets/pallet-dao/src/mock.rs +++ b/substrate-node/pallets/pallet-dao/src/mock.rs @@ -1,15 +1,19 @@ use crate::mock::sp_api_hidden_includes_construct_runtime::hidden_include::traits::GenesisBuild; use crate::{self as pallet_dao}; -use frame_support::{construct_runtime, parameter_types, traits::ConstU32}; +use frame_support::{construct_runtime, parameter_types, traits::ConstU32, BoundedVec}; use frame_system::EnsureRoot; use pallet_collective; -use pallet_tfgrid; -use pallet_tfgrid::interface::{InterfaceIp, InterfaceMac, InterfaceName}; +use pallet_tfgrid::node::{CityName, CountryName}; use pallet_tfgrid::{ farm::FarmName, - pub_config::{Domain, GW4, GW6, IP4, IP6}, - pub_ip::{GatewayIP, PublicIP}, + interface::{InterfaceIp, InterfaceMac, InterfaceName}, + node::{Location, SerialNumber}, + terms_cond::TermsAndConditions, twin::TwinIp, + DocumentHashInput, DocumentLinkInput, TwinIpInput, +}; +use pallet_tfgrid::{ + CityNameInput, CountryNameInput, Gw4Input, Ip4Input, LatitudeInput, LongitudeInput, }; use pallet_timestamp; use sp_core::H256; @@ -18,7 +22,8 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, }; use sp_std::convert::{TryFrom, TryInto}; -use tfchain_support::{traits::ChangeNode, types::Node}; +use tfchain_support::traits::{ChangeNode, PublicIpModifier}; +use tfchain_support::types::PublicIP; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -41,25 +46,22 @@ construct_runtime!( parameter_types! { pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); - pub const ExistentialDeposit: u64 = 1; } impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; - type Call = Call; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type DbWeight = (); type Version = (); @@ -79,27 +81,32 @@ parameter_types! { pub const MinVetos: u32 = 2; } -pub(crate) type PubConfig = pallet_tfgrid::pallet::PubConfigOf; +pub(crate) type Serial = pallet_tfgrid::pallet::SerialNumberOf; +pub(crate) type Loc = pallet_tfgrid::pallet::LocationOf; pub(crate) type Interface = pallet_tfgrid::pallet::InterfaceOf; + +pub(crate) type TfgridNode = pallet_tfgrid::pallet::TfgridNode; + pub struct NodeChanged; -impl ChangeNode for NodeChanged { - fn node_changed( - old_node: Option<&Node>, - new_node: &Node, - ) { +impl ChangeNode for NodeChanged { + fn node_changed(old_node: Option<&TfgridNode>, new_node: &TfgridNode) { DaoModule::node_changed(old_node, new_node) } - - fn node_deleted(node: &Node) { + fn node_deleted(node: &TfgridNode) { DaoModule::node_deleted(node); } } +pub struct PublicIpModifierType; +impl PublicIpModifier for PublicIpModifierType { + fn ip_removed(_ip: &PublicIP) {} +} + use super::weights; impl pallet_dao::Config for Test { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type CouncilOrigin = EnsureRoot; - type Proposal = Call; + type Proposal = RuntimeCall; type MotionDuration = DaoMotionDuration; type MinVetos = MinVetos; type Tfgrid = TfgridModule; @@ -114,42 +121,40 @@ parameter_types! { pub const MaxFarmPublicIps: u32 = 512; } +pub(crate) type TestTermsAndConditions = TermsAndConditions; + pub(crate) type TestTwinIp = TwinIp; pub(crate) type TestFarmName = FarmName; -pub(crate) type TestPublicIP = PublicIP; -pub(crate) type TestGatewayIP = GatewayIP; - -pub(crate) type TestIP4 = IP4; -pub(crate) type TestGW4 = GW4; -pub(crate) type TestIP6 = IP6; -pub(crate) type TestGW6 = GW6; -pub(crate) type TestDomain = Domain; pub(crate) type TestInterfaceName = InterfaceName; pub(crate) type TestInterfaceMac = InterfaceMac; pub(crate) type TestInterfaceIp = InterfaceIp; +pub(crate) type TestCountryName = CountryName; +pub(crate) type TestCityName = CityName; +pub(crate) type TestLocation = Location; +pub(crate) type TestSerialNumber = SerialNumber; + impl pallet_tfgrid::Config for Test { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type RestrictedOrigin = EnsureRoot; type WeightInfo = pallet_tfgrid::weights::SubstrateWeight; type NodeChanged = NodeChanged; + type PublicIpModifier = PublicIpModifierType; + type TermsAndConditions = TestTermsAndConditions; type TwinIp = TestTwinIp; type FarmName = TestFarmName; type MaxFarmNameLength = MaxFarmNameLength; type MaxFarmPublicIps = MaxFarmPublicIps; - type PublicIP = TestPublicIP; - type GatewayIP = TestGatewayIP; - type IP4 = TestIP4; - type GW4 = TestGW4; - type IP6 = TestIP6; - type GW6 = TestGW6; - type Domain = TestDomain; type MaxInterfacesLength = MaxInterfacesLength; type InterfaceName = TestInterfaceName; type InterfaceMac = TestInterfaceMac; type InterfaceIP = TestInterfaceIp; type MaxInterfaceIpsLength = MaxInterfaceIpsLength; + type CountryName = TestCountryName; + type CityName = TestCityName; + type Location = TestLocation; + type SerialNumber = TestSerialNumber; } impl pallet_timestamp::Config for Test { @@ -167,9 +172,9 @@ parameter_types! { pub type CouncilCollective = pallet_collective::Instance1; impl pallet_collective::Config for Test { - type Origin = Origin; - type Proposal = Call; - type Event = Event; + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type MotionDuration = CouncilMotionDuration; type MaxProposals = CouncilMaxProposals; type MaxMembers = CouncilMaxMembers; @@ -178,7 +183,7 @@ impl pallet_collective::Config for Test { } impl pallet_membership::Config for Test { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type AddOrigin = EnsureRoot; type RemoveOrigin = EnsureRoot; type SwapOrigin = EnsureRoot; @@ -190,8 +195,40 @@ impl pallet_membership::Config for Test { type WeightInfo = pallet_membership::weights::SubstrateWeight; } -pub(crate) fn get_twin_ip(twin_ip_input: &[u8]) -> TestTwinIp { - TwinIp::try_from(twin_ip_input.to_vec()).expect("Invalid twin ip input.") +pub(crate) fn get_document_link_input(document_link_input: &[u8]) -> DocumentLinkInput { + BoundedVec::try_from(document_link_input.to_vec()).expect("Invalid document link input.") +} + +pub(crate) fn get_document_hash_input(document_hash_input: &[u8]) -> DocumentHashInput { + BoundedVec::try_from(document_hash_input.to_vec()).expect("Invalid document hash input.") +} + +pub(crate) fn get_twin_ip_input(twin_ip_input: &[u8]) -> TwinIpInput { + BoundedVec::try_from(twin_ip_input.to_vec()).expect("Invalid twin ip input.") +} + +pub(crate) fn get_public_ip_ip_input(ip_input: &[u8]) -> Ip4Input { + BoundedVec::try_from(ip_input.to_vec()).expect("Invalid public ip (ip) input.") +} + +pub(crate) fn get_public_ip_gw_input(gw_input: &[u8]) -> Gw4Input { + BoundedVec::try_from(gw_input.to_vec()).expect("Invalid public ip (gw) input.") +} + +pub(crate) fn get_city_name_input(city_input: &[u8]) -> CityNameInput { + BoundedVec::try_from(city_input.to_vec()).expect("Invalid city name input.") +} + +pub(crate) fn get_country_name_input(country_input: &[u8]) -> CountryNameInput { + BoundedVec::try_from(country_input.to_vec()).expect("Invalid country name input.") +} + +pub(crate) fn get_latitude_input(latitude_input: &[u8]) -> LatitudeInput { + BoundedVec::try_from(latitude_input.to_vec()).expect("Invalid latitude input.") +} + +pub(crate) fn get_longitude_input(longitude_input: &[u8]) -> LongitudeInput { + BoundedVec::try_from(longitude_input.to_vec()).expect("Invalid longitude input.") } // Build genesis storage according to the mock runtime. @@ -204,7 +241,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { genesis.assimilate_storage(&mut t).unwrap(); let genesis = pallet_membership::GenesisConfig:: { - members: vec![1, 2, 3], + members: vec![1, 2, 3].try_into().unwrap(), phantom: Default::default(), }; genesis.assimilate_storage(&mut t).unwrap(); diff --git a/substrate-node/pallets/pallet-dao/src/tests.rs b/substrate-node/pallets/pallet-dao/src/tests.rs index 7869943de..e79ee4e76 100644 --- a/substrate-node/pallets/pallet-dao/src/tests.rs +++ b/substrate-node/pallets/pallet-dao/src/tests.rs @@ -1,12 +1,13 @@ use super::Event as DaoEvent; -use crate::{mock::Event as MockEvent, mock::*, Error}; -use frame_support::{assert_noop, assert_ok, bounded_vec, weights::GetDispatchInfo}; +use crate::{mock::RuntimeEvent as MockEvent, mock::*, Error}; +use frame_support::{assert_noop, assert_ok, bounded_vec, dispatch::GetDispatchInfo}; use frame_system::{EventRecord, Phase, RawOrigin}; -use pallet_tfgrid::types::PublicIpInput; +use log::info; +use pallet_tfgrid::{types::LocationInput, PublicIpListInput, ResourcesInput}; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, Hash}; use std::convert::TryInto; -use tfchain_support::types::{FarmCertification, Location, NodeCertification, Resources}; +use tfchain_support::types::{FarmCertification, NodeCertification, IP4}; #[test] fn farmers_vote_no_farm_fails() { @@ -16,7 +17,7 @@ fn farmers_vote_no_farm_fails() { let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 3, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -25,7 +26,7 @@ fn farmers_vote_no_farm_fails() { )); assert_noop!( - DaoModule::vote(Origin::signed(10), 1, hash.clone(), true), + DaoModule::vote(RuntimeOrigin::signed(10), 1, hash.clone(), true), Error::::NotAuthorizedToVote ); }); @@ -42,7 +43,7 @@ fn farmers_vote_proposal_works() { let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 3, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -51,10 +52,20 @@ fn farmers_vote_proposal_works() { )); prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); - assert_ok!(DaoModule::vote(Origin::signed(10), 1, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(10), + 1, + hash.clone(), + true + )); prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); - assert_ok!(DaoModule::vote(Origin::signed(11), 2, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(11), + 2, + hash.clone(), + true + )); }); } @@ -69,7 +80,7 @@ fn farmers_vote_proposal_if_no_nodes_fails() { let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 1, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -80,7 +91,7 @@ fn farmers_vote_proposal_if_no_nodes_fails() { prepare_twin(10); prepare_farm(10, "farm1".as_bytes().to_vec()); assert_noop!( - DaoModule::vote(Origin::signed(10), 1, hash.clone(), true), + DaoModule::vote(RuntimeOrigin::signed(10), 1, hash.clone(), true), Error::::FarmHasNoNodes ); @@ -113,7 +124,7 @@ fn farmer_weight_is_set_properly_when_node_is_added_and_removed_works() { let weight = DaoModule::farm_weight(1); assert_ne!(weight, 0); - TfgridModule::delete_node_farm(Origin::signed(10), 1).unwrap(); + TfgridModule::delete_node_farm(RuntimeOrigin::signed(10), 1).unwrap(); let weight = DaoModule::farm_weight(1); assert_eq!(weight, 0); @@ -131,7 +142,7 @@ fn close_works() { let threshold = 2; assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), threshold, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -141,23 +152,33 @@ fn close_works() { // Farmer 1 votes yes prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); - assert_ok!(DaoModule::vote(Origin::signed(10), 1, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(10), + 1, + hash.clone(), + true + )); System::set_block_number(4); assert_noop!( - DaoModule::close(Origin::signed(4), hash.clone(), 0,), + DaoModule::close(RuntimeOrigin::signed(4), hash.clone(), 0,), Error::::NotCouncilMember ); assert_noop!( - DaoModule::close(Origin::signed(2), hash.clone(), 0,), + DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,), Error::::OngoingVoteAndTresholdStillNotMet ); // Farmer 2 votes yes prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); - assert_ok!(DaoModule::vote(Origin::signed(11), 2, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(11), + 2, + hash.clone(), + true + )); - assert_ok!(DaoModule::close(Origin::signed(2), hash.clone(), 0,)); + assert_ok!(DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,)); let e = System::events(); assert_eq!( @@ -228,7 +249,7 @@ fn close_after_proposal_duration_works() { let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -237,7 +258,7 @@ fn close_after_proposal_duration_works() { )); System::set_block_number(5); // default duration is 4 blocks - assert_ok!(DaoModule::close(Origin::signed(2), hash.clone(), 0,)); + assert_ok!(DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,)); }); } @@ -248,7 +269,7 @@ fn close_if_not_council_member_fails() { let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -256,7 +277,7 @@ fn close_if_not_council_member_fails() { None )); - let not_council_member = Origin::signed(4); // [1, 2, 3] are council members + let not_council_member = RuntimeOrigin::signed(4); // [1, 2, 3] are council members assert_noop!( DaoModule::close(not_council_member, hash.clone(), 0,), @@ -271,14 +292,14 @@ fn motion_approval_works() { System::set_block_number(1); create_farming_policies(); - let proposal = Call::TfgridModule(pallet_tfgrid::Call::set_farm_certification { + let proposal = RuntimeCall::TfgridModule(pallet_tfgrid::Call::set_farm_certification { farm_id: 1, certification: FarmCertification::Gold, }); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -288,18 +309,28 @@ fn motion_approval_works() { // Farmer 1 votes yes prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); - assert_ok!(DaoModule::vote(Origin::signed(10), 1, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(10), + 1, + hash.clone(), + true + )); // Farmer 2 votes yes prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); - assert_ok!(DaoModule::vote(Origin::signed(11), 2, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(11), + 2, + hash.clone(), + true + )); // // Check farm certification type before we close let farm_1 = TfgridModule::farms(1).unwrap(); assert_eq!(farm_1.certification, FarmCertification::NotCertified); System::set_block_number(5); - assert_ok!(DaoModule::close(Origin::signed(2), hash.clone(), 0,)); + assert_ok!(DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,)); let e = System::events(); assert_eq!( @@ -376,14 +407,14 @@ fn motion_veto_works() { System::set_block_number(1); create_farming_policies(); - let proposal = Call::TfgridModule(pallet_tfgrid::Call::set_farm_certification { + let proposal = RuntimeCall::TfgridModule(pallet_tfgrid::Call::set_farm_certification { farm_id: 1, certification: FarmCertification::Gold, }); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -391,8 +422,8 @@ fn motion_veto_works() { None )); - assert_ok!(DaoModule::veto(Origin::signed(2), hash.clone())); - assert_ok!(DaoModule::veto(Origin::signed(3), hash.clone())); + assert_ok!(DaoModule::veto(RuntimeOrigin::signed(2), hash.clone())); + assert_ok!(DaoModule::veto(RuntimeOrigin::signed(3), hash.clone())); System::set_block_number(5); @@ -408,7 +439,7 @@ fn motion_veto_works() { ); for event in e.clone() { - println!("event: {:?}", event); + info!("event: {:?}", event); } assert_eq!( @@ -482,14 +513,14 @@ fn weighted_voting_works() { System::set_block_number(1); create_farming_policies(); - let proposal = Call::TfgridModule(pallet_tfgrid::Call::set_farm_certification { + let proposal = RuntimeCall::TfgridModule(pallet_tfgrid::Call::set_farm_certification { farm_id: 1, certification: FarmCertification::Gold, }); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -499,18 +530,28 @@ fn weighted_voting_works() { // Farmer 1 votes yes prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); - assert_ok!(DaoModule::vote(Origin::signed(10), 1, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(10), + 1, + hash.clone(), + true + )); // Farmer 2 votes no prepare_twin_farm_and_big_node(11, "farm2".as_bytes().to_vec(), 2); - assert_ok!(DaoModule::vote(Origin::signed(11), 2, hash.clone(), false)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(11), + 2, + hash.clone(), + false + )); // // Check farm certification type before we close let farm_1 = TfgridModule::farms(1).unwrap(); assert_eq!(farm_1.certification, FarmCertification::NotCertified); System::set_block_number(5); - assert_ok!(DaoModule::close(Origin::signed(2), hash.clone(), 0,)); + assert_ok!(DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,)); let e = System::events(); assert_eq!( @@ -580,11 +621,12 @@ fn voting_tfgridmodule_call_works() { System::set_block_number(1); create_farming_policies(); - let proposal = Call::TfgridModule(pallet_tfgrid::Call::set_connection_price { price: 100 }); + let proposal = + RuntimeCall::TfgridModule(pallet_tfgrid::Call::set_connection_price { price: 100 }); let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -594,22 +636,32 @@ fn voting_tfgridmodule_call_works() { // Farmer 1 votes yes prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); - assert_ok!(DaoModule::vote(Origin::signed(10), 1, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(10), + 1, + hash.clone(), + true + )); // Farmer 2 votes no prepare_twin_farm_and_node(11, "farm2".as_bytes().to_vec(), 2); - assert_ok!(DaoModule::vote(Origin::signed(11), 2, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(11), + 2, + hash.clone(), + true + )); // Check connection price of node 1 let n1 = TfgridModule::nodes(1).unwrap(); assert_eq!(n1.connection_price, 80); System::set_block_number(5); - assert_ok!(DaoModule::close(Origin::signed(2), hash.clone(), 0,)); + assert_ok!(DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,)); let e = System::events(); for (idx, event) in e.clone().iter().enumerate() { - println!("index: {:?}, event: {:?}", idx, event); + info!("index: {:?}, event: {:?}", idx, event); } assert_eq!( e[4], @@ -691,7 +743,7 @@ fn customize_proposal_duration_works() { let hash = BlakeTwo256::hash_of(&proposal); assert_ok!(DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -701,16 +753,21 @@ fn customize_proposal_duration_works() { // Farmer 1 votes yes prepare_twin_farm_and_node(10, "farm1".as_bytes().to_vec(), 1); - assert_ok!(DaoModule::vote(Origin::signed(10), 1, hash.clone(), true)); + assert_ok!(DaoModule::vote( + RuntimeOrigin::signed(10), + 1, + hash.clone(), + true + )); System::set_block_number(9); assert_noop!( - DaoModule::close(Origin::signed(2), hash.clone(), 0,), + DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,), Error::::OngoingVoteAndTresholdStillNotMet ); System::set_block_number(11); - assert_ok!(DaoModule::close(Origin::signed(2), hash.clone(), 0,)); + assert_ok!(DaoModule::close(RuntimeOrigin::signed(2), hash.clone(), 0,)); }); } @@ -722,7 +779,7 @@ fn customize_proposal_duration_out_of_bounds_fails() { let proposal = make_proposal("some_remark".as_bytes().to_vec()); // assert_noop!( // DaoModule::propose( - // Origin::signed(1), + // RuntimeOrigin::signed(1), // 2, // Box::new(proposal.clone()), // "some_description".as_bytes().to_vec(), @@ -734,7 +791,7 @@ fn customize_proposal_duration_out_of_bounds_fails() { assert_noop!( DaoModule::propose( - Origin::signed(1), + RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), "some_description".as_bytes().to_vec(), @@ -746,7 +803,7 @@ fn customize_proposal_duration_out_of_bounds_fails() { }); } -fn record(event: Event) -> EventRecord { +fn record(event: RuntimeEvent) -> EventRecord { EventRecord { phase: Phase::Initialization, event, @@ -754,8 +811,8 @@ fn record(event: Event) -> EventRecord { } } -fn make_proposal(value: Vec) -> Call { - Call::System(frame_system::Call::remark { remark: value }) +fn make_proposal(value: Vec) -> RuntimeCall { + RuntimeCall::System(frame_system::Call::remark { remark: value }) } pub fn prepare_twin_farm_and_node(account_id: u64, farm_name: Vec, farm_id: u32) { @@ -771,94 +828,88 @@ pub fn prepare_twin_farm_and_big_node(account_id: u64, farm_name: Vec, farm_ } pub fn prepare_twin(account_id: u64) { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - assert_ok!(TfgridModule::user_accept_tc( - Origin::signed(account_id), - document.clone(), - hash.clone(), + RuntimeOrigin::signed(account_id), + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), )); - let ip = get_twin_ip(b"::1"); + let ip = get_twin_ip_input(b"::1"); assert_ok!(TfgridModule::create_twin( - Origin::signed(account_id), - ip.clone().0 + RuntimeOrigin::signed(account_id), + ip )); } const GIGABYTE: u64 = 1024 * 1024 * 1024; fn prepare_node(account_id: u64, farm_id: u32) { - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1024 * GIGABYTE, sru: 512 * GIGABYTE, cru: 8, mru: 16 * GIGABYTE, }; - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; + assert_ok!(TfgridModule::create_node( - Origin::signed(account_id), + RuntimeOrigin::signed(account_id), farm_id, resources, location, - country, - city, bounded_vec![], false, false, - "some_serial".as_bytes().to_vec(), + None, )); } fn prepare_big_node(account_id: u64, farm_id: u32) { - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 20024 * GIGABYTE, sru: 2024 * GIGABYTE, cru: 16, mru: 64 * GIGABYTE, }; - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; + assert_ok!(TfgridModule::create_node( - Origin::signed(account_id), + RuntimeOrigin::signed(account_id), farm_id, resources, location, - country, - city, bounded_vec![], false, false, - "some_serial".as_bytes().to_vec(), + None, )); } pub fn prepare_farm(account_id: u64, farm_name: Vec) { - let mut pub_ips = Vec::new(); - pub_ips.push(PublicIpInput { - ip: "185.206.122.33/24".as_bytes().to_vec().try_into().unwrap(), - gw: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), - }); + let mut pub_ips: PublicIpListInput = bounded_vec![]; + + let ip = get_public_ip_ip_input(b"185.206.122.33/24"); + let gw = get_public_ip_gw_input(b"185.206.122.1"); + + pub_ips.try_push(IP4 { ip, gw }).unwrap(); assert_ok!(TfgridModule::create_farm( - Origin::signed(account_id), + RuntimeOrigin::signed(account_id), farm_name.try_into().unwrap(), - pub_ips.clone().try_into().unwrap(), + pub_ips, )); } diff --git a/substrate-node/pallets/pallet-dao/src/weights.rs b/substrate-node/pallets/pallet-dao/src/weights.rs index f877ffd62..ba5432250 100644 --- a/substrate-node/pallets/pallet-dao/src/weights.rs +++ b/substrate-node/pallets/pallet-dao/src/weights.rs @@ -40,55 +40,57 @@ // --template // ./.maintain/frame-weight-template.hbs - #![allow(unused_parens)] #![allow(unused_imports)] -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use frame_support::{ + traits::Get, + weights::{constants::RocksDbWeight, Weight}, +}; use sp_std::marker::PhantomData; /// Weight functions needed for pallet_dao. pub trait WeightInfo { - fn propose() -> Weight; - fn vote() -> Weight; - fn close() -> Weight; + fn propose() -> Weight; + fn vote() -> Weight; + fn close() -> Weight; } /// Weights for pallet_dao using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn propose() -> Weight { - (162_531_000 as Weight) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - } - fn vote() -> Weight { - (147_194_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn close() -> Weight { - (257_076_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } + fn propose() -> Weight { + Weight::from_ref_time(162_531_000 as u64) + .saturating_add(T::DbWeight::get().reads(4 as u64)) + .saturating_add(T::DbWeight::get().writes(5 as u64)) + } + fn vote() -> Weight { + Weight::from_ref_time(147_194_000 as u64) + .saturating_add(T::DbWeight::get().reads(5 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + fn close() -> Weight { + Weight::from_ref_time(257_076_000 as u64) + .saturating_add(T::DbWeight::get().reads(3 as u64)) + .saturating_add(T::DbWeight::get().writes(4 as u64)) + } } // For backwards compatibility and tests impl WeightInfo for () { - fn propose() -> Weight { - (162_531_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(5 as Weight)) - } - fn vote() -> Weight { - (147_194_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - fn close() -> Weight { - (257_076_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } -} \ No newline at end of file + fn propose() -> Weight { + Weight::from_ref_time(162_531_000 as u64) + .saturating_add(RocksDbWeight::get().reads(4 as u64)) + .saturating_add(RocksDbWeight::get().writes(5 as u64)) + } + fn vote() -> Weight { + Weight::from_ref_time(147_194_000 as u64) + .saturating_add(RocksDbWeight::get().reads(5 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + fn close() -> Weight { + Weight::from_ref_time(257_076_000 as u64) + .saturating_add(RocksDbWeight::get().reads(3 as u64)) + .saturating_add(RocksDbWeight::get().writes(4 as u64)) + } +} diff --git a/substrate-node/pallets/pallet-kvstore/Cargo.toml b/substrate-node/pallets/pallet-kvstore/Cargo.toml index 9f41cea42..99a13ef12 100644 --- a/substrate-node/pallets/pallet-kvstore/Cargo.toml +++ b/substrate-node/pallets/pallet-kvstore/Cargo.toml @@ -18,15 +18,15 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [features] default = ['std'] @@ -40,3 +40,6 @@ std = [ 'sp-io/std', 'scale-info/std' ] +try-runtime = [ + "frame-support/try-runtime", +] diff --git a/substrate-node/pallets/pallet-kvstore/src/lib.rs b/substrate-node/pallets/pallet-kvstore/src/lib.rs index 8beb21db3..9078eb693 100644 --- a/substrate-node/pallets/pallet-kvstore/src/lib.rs +++ b/substrate-node/pallets/pallet-kvstore/src/lib.rs @@ -20,7 +20,7 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { - type Event: From> + IsType<::Event>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; } #[pallet::event] @@ -57,6 +57,7 @@ pub mod pallet { #[pallet::call] impl Pallet { /// Set the value stored at a particular key + #[pallet::call_index(0)] #[pallet::weight(100_000_000)] pub fn set( origin: OriginFor, @@ -74,6 +75,7 @@ pub mod pallet { /// Read the value stored at a particular key, while removing it from the map. /// Also emit the read value in an event + #[pallet::call_index(1)] #[pallet::weight(100_000_000)] pub fn delete(origin: OriginFor, key: Vec) -> DispatchResultWithPostInfo { // A user can only take (delete) their own entry @@ -88,4 +90,4 @@ pub mod pallet { Ok(().into()) } } -} +} \ No newline at end of file diff --git a/substrate-node/pallets/pallet-kvstore/src/tests.rs b/substrate-node/pallets/pallet-kvstore/src/tests.rs index 116f9255f..40cf1780e 100644 --- a/substrate-node/pallets/pallet-kvstore/src/tests.rs +++ b/substrate-node/pallets/pallet-kvstore/src/tests.rs @@ -26,24 +26,22 @@ construct_runtime!( parameter_types! { pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; - type Call = Call; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type DbWeight = (); type Version = (); @@ -58,7 +56,7 @@ impl frame_system::Config for TestRuntime { } impl Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; } struct ExternalityBuilder; @@ -81,7 +79,7 @@ fn test_set_and_get() { let value = "nametest"; // make sure Entry does not exists assert_ok!(TFKVStoreModule::set( - Origin::signed(1), + RuntimeOrigin::signed(1), key.as_bytes().to_vec(), value.as_bytes().to_vec() )); @@ -89,13 +87,13 @@ fn test_set_and_get() { let our_events = System::events(); assert_eq!( - our_events.contains(&record(Event::TFKVStoreModule( - KvStoreEvent::::EntrySet( - 1, - key.as_bytes().to_vec(), - value.as_bytes().to_vec(), - ) - ))), + our_events.contains(&record(RuntimeEvent::TFKVStoreModule(KvStoreEvent::< + TestRuntime, + >::EntrySet( + 1, + key.as_bytes().to_vec(), + value.as_bytes().to_vec(), + )))), true ); @@ -110,7 +108,7 @@ fn test_delete() { let key = "Address"; let value = "Cairo"; assert_ok!(TFKVStoreModule::set( - Origin::signed(1), + RuntimeOrigin::signed(1), key.as_bytes().to_vec(), value.as_bytes().to_vec() )); @@ -118,31 +116,31 @@ fn test_delete() { let our_events = System::events(); assert_eq!( - our_events.contains(&record(Event::TFKVStoreModule( - KvStoreEvent::::EntrySet( - 1, - key.as_bytes().to_vec(), - value.as_bytes().to_vec(), - ) - ))), + our_events.contains(&record(RuntimeEvent::TFKVStoreModule(KvStoreEvent::< + TestRuntime, + >::EntrySet( + 1, + key.as_bytes().to_vec(), + value.as_bytes().to_vec(), + )))), true ); assert_ok!(TFKVStoreModule::delete( - Origin::signed(1), + RuntimeOrigin::signed(1), key.as_bytes().to_vec() )); let our_events = System::events(); assert_eq!( - our_events.contains(&record(Event::TFKVStoreModule( - KvStoreEvent::::EntryTaken( - 1, - key.as_bytes().to_vec(), - value.as_bytes().to_vec(), - ) - ))), + our_events.contains(&record(RuntimeEvent::TFKVStoreModule(KvStoreEvent::< + TestRuntime, + >::EntryTaken( + 1, + key.as_bytes().to_vec(), + value.as_bytes().to_vec(), + )))), true ); @@ -153,7 +151,7 @@ fn test_delete() { }) } -fn record(event: Event) -> EventRecord { +fn record(event: RuntimeEvent) -> EventRecord { EventRecord { phase: Phase::Initialization, event, diff --git a/substrate-node/pallets/pallet-runtime-upgrade/Cargo.toml b/substrate-node/pallets/pallet-runtime-upgrade/Cargo.toml index da5495e78..744e7a6d4 100644 --- a/substrate-node/pallets/pallet-runtime-upgrade/Cargo.toml +++ b/substrate-node/pallets/pallet-runtime-upgrade/Cargo.toml @@ -18,10 +18,10 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [features] default = ['std'] @@ -32,4 +32,7 @@ std = [ 'codec/std', 'sp-io/std', 'scale-info/std' +] +try-runtime = [ + "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs b/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs index 8db19158c..26677f84d 100644 --- a/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs +++ b/substrate-node/pallets/pallet-runtime-upgrade/src/lib.rs @@ -16,11 +16,12 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { /// Origin for runtime upgrades - type SetCodeOrigin: EnsureOrigin; + type SetCodeOrigin: EnsureOrigin; } #[pallet::call] impl Pallet { + #[pallet::call_index(0)] #[pallet::weight(100_000_000)] pub fn set_code(origin: OriginFor, code: Vec) -> DispatchResultWithPostInfo { T::SetCodeOrigin::ensure_origin(origin)?; @@ -28,4 +29,4 @@ pub mod pallet { Ok(Pays::No.into()) } } -} +} \ No newline at end of file diff --git a/substrate-node/pallets/pallet-smart-contract/Cargo.toml b/substrate-node/pallets/pallet-smart-contract/Cargo.toml index a96d3fbed..69ae2a99a 100644 --- a/substrate-node/pallets/pallet-smart-contract/Cargo.toml +++ b/substrate-node/pallets/pallet-smart-contract/Cargo.toml @@ -31,19 +31,29 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } substrate-fixed = { git = 'https://github.com/encointer/substrate-fixed.git', rev = "b33d186888c60f38adafcfc0ec3a21aab263aef1" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } tfchain-support = { path = "../../support", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } + +parking_lot = '0.12.1' # Benchmarking -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } + +[dev-dependencies] +parking_lot = '0.12.1' +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +env_logger = "*" +substrate-validator-set = { path = "../substrate-validator-set" } [features] default = ['std'] @@ -67,6 +77,7 @@ std = [ ] runtime-benchmarks = [ "frame-benchmarking", + "pallet-balances/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", ] diff --git a/substrate-node/pallets/pallet-smart-contract/src/benchmarking.rs b/substrate-node/pallets/pallet-smart-contract/src/benchmarking.rs index 43da757c4..bf3a630c5 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/benchmarking.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/benchmarking.rs @@ -1,52 +1,84 @@ -// This file is part of Substrate. - -// Copyright (C) 2022 Threefold Tech -// Copyright (C) 2020-2021 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. - -//! Vesting pallet benchmarking. - #![cfg(feature = "runtime-benchmarks")] use super::*; -use crate::Module as SmartContractModule; -use frame_benchmarking::{account, benchmarks, whitelisted_caller}; -use frame_support::traits::{Box, Vec}; +use crate::Pallet as SmartContractModule; +use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; +use frame_support::assert_ok; use frame_system::RawOrigin; -use sp_std::vec; +use sp_std::{ + convert::{TryFrom, TryInto}, + fmt::Debug, + vec, +}; -use tfchain_support::types::{Location, Resources, PublicIP}; -use pallet_tfgrid; +use pallet_tfgrid::{ + types::{self as pallet_tfgrid_types, LocationInput}, + CityNameInput, CountryNameInput, DocumentHashInput, DocumentLinkInput, LatitudeInput, + LongitudeInput, ResourcesInput, TwinIpInput, +}; +use tfchain_support::{resources::Resources, types::IP4}; +const GIGABYTE: u64 = 1024 * 1024 * 1024; benchmarks! { + where_clause { + where + ::Moment: TryFrom, + <::Moment as TryFrom>::Error: Debug, + } + create_node_contract { let a1: T::AccountId = account("Alice", 0, 0); prepare_farm_and_node::(a1); let caller: T::AccountId = whitelisted_caller(); create_twin::(caller.clone()); - }: _ (RawOrigin::Signed(caller.clone()), 1, "some_data".as_bytes().to_vec(), "hash".as_bytes().to_vec(), 1) + }: _ (RawOrigin::Signed( + caller.clone()), + 1, + "858f8fb2184b15ecb8c0be8b95398c81".as_bytes().to_vec().try_into().unwrap(), + "some_data".as_bytes().to_vec().try_into().unwrap(), + 1, + None + ) verify { - let contract = SmartContractModule::::contracts(1); + let contract = SmartContractModule::::contracts(1).unwrap(); assert_eq!( contract.contract_id, 1 ); } - add_reports { + add_nru_reports { + let stamp: u64 = 1628082000 * 1000; + pallet_timestamp::Pallet::::set_timestamp(stamp.try_into().unwrap()); + + let a1: T::AccountId = account("Alice", 0, 0); + prepare_farm_and_node::(a1.clone()); + + let caller: T::AccountId = whitelisted_caller(); + create_twin::(caller.clone()); + create_contract::(caller.clone()); + + let mut reports = Vec::new(); + + reports.push(types::NruConsumption { + contract_id: 1, + timestamp: 1628082000 * 1000, + window: 1000, + nru: 10 * GIGABYTE, + }); + + }: _ (RawOrigin::Signed(a1.clone()), reports) + verify { + let contract = SmartContractModule::::contracts(1).unwrap(); + assert_eq!( + contract.contract_id, 1 + ); + } + + bill_contract_for_block { + let stamp: u64 = 1628082000 * 1000; + pallet_timestamp::Pallet::::set_timestamp(stamp.try_into().unwrap()); let a1: T::AccountId = account("Alice", 0, 0); prepare_farm_and_node::(a1.clone()); @@ -56,26 +88,32 @@ benchmarks! { let mut reports = Vec::new(); - let gigabyte = 1000 * 1000 * 1000; reports.push(types::Consumption { contract_id: 1, cru: 2, hru: 0, - mru: 8 * gigabyte, - sru: 25 * gigabyte, + mru: 8 * GIGABYTE, + sru: 25 * GIGABYTE, nru: 0, timestamp: 0, }); - }: _ (RawOrigin::Signed(a1.clone()), reports) + push_contract_resources::(a1.clone()); + + let stamp: u64 = 1628082000 * 1000 * 10 * 6000; + pallet_timestamp::Pallet::::set_timestamp(stamp.try_into().unwrap()); + // run_to_block::(10); + }: _ (RawOrigin::Signed(a1.clone()), 1) verify { - let contract = SmartContractModule::::contracts(1); + let contract = SmartContractModule::::contracts(1).unwrap(); assert_eq!( contract.contract_id, 1 ); } } +impl_benchmark_test_suite! {Pallet, crate::tests::new_test_ext(), crate::tests::Test} + #[cfg(test)] mod benchmarktests { use super::*; @@ -86,70 +124,66 @@ mod benchmarktests { fn test_benchmarks() { new_test_ext().execute_with(|| { assert_ok!(test_benchmark_create_node_contract::()); - assert_ok!(test_benchmark_add_reports::()); + assert_ok!(test_benchmark_add_nru_reports::()); }); } } pub fn create_twin(source: T::AccountId) { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - - pallet_tfgrid::Module::::user_accept_tc( + assert_ok!(pallet_tfgrid::Pallet::::user_accept_tc( RawOrigin::Signed(source.clone()).into(), - document.clone(), - hash.clone(), - ) - .unwrap(); - let ip = "10.2.3.3"; - pallet_tfgrid::Module::::create_twin( + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), + )); + + let ip = get_twin_ip_input(b"::1"); + assert_ok!(pallet_tfgrid::Pallet::::create_twin( RawOrigin::Signed(source).into(), - ip.as_bytes().to_vec(), - ) - .unwrap(); + ip + )); } pub fn prepare_farm_and_node(source: T::AccountId) { create_twin::(source.clone()); prepare_farm::(source.clone()); - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), + let resources = ResourcesInput { + hru: 1024 * GIGABYTE, + sru: 512 * GIGABYTE, + cru: 8, + mru: 16 * GIGABYTE, }; - let resources = Resources { - hru: 1, - sru: 1, - cru: 1, - mru: 1, + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), }; - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); - pallet_tfgrid::Module::::create_node( - RawOrigin::Signed(source).into(), + assert_ok!(pallet_tfgrid::Pallet::::create_node( + RawOrigin::Signed(source.clone()).into(), 1, resources, location, - country, - city, - Vec::new(), + Vec::new().try_into().unwrap(), false, false, - "some_serial".as_bytes().to_vec(), - ) - .unwrap(); + None, + )); } pub fn prepare_farm(source: T::AccountId) { - let farm_name = "test_farm"; + let farm_name = "testfarm"; let mut pub_ips = Vec::new(); - pub_ips.push(PublicIP { - ip: "1.1.1.0".as_bytes().to_vec(), - gateway: "1.1.1.1".as_bytes().to_vec(), - contract_id: 0, + pub_ips.push(IP4 { + ip: "185.206.122.33/24".as_bytes().to_vec().try_into().unwrap(), + gw: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), + }); + pub_ips.push(IP4 { + ip: "185.206.122.34/24".as_bytes().to_vec().try_into().unwrap(), + gw: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), }); let su_policy = pallet_tfgrid_types::Policy { @@ -180,7 +214,7 @@ pub fn prepare_farm(source: T::AccountId) { let x1 = account("ferdie", 0, 2); let x2 = account("eve", 0, 3); - pallet_tfgrid::Module::::create_pricing_policy( + assert_ok!(pallet_tfgrid::Pallet::::create_pricing_policy( RawOrigin::Root.into(), "policy_1".as_bytes().to_vec(), su_policy, @@ -191,24 +225,72 @@ pub fn prepare_farm(source: T::AccountId) { domain_name_policy, x1, x2, - 80 - ) - .unwrap(); + 80, + )); - pallet_tfgrid::Module::::create_farm( + assert_ok!(pallet_tfgrid::Pallet::::create_farm( RawOrigin::Signed(source).into(), - farm_name.as_bytes().to_vec(), - pub_ips.clone(), - ) - .unwrap(); + farm_name.as_bytes().to_vec().try_into().unwrap(), + pub_ips.clone().try_into().unwrap(), + )); } pub fn create_contract(source: T::AccountId) { - SmartContractModule::::create_node_contract( + assert_ok!(SmartContractModule::::create_node_contract( RawOrigin::Signed(source).into(), 1, - "some_data123".as_bytes().to_vec(), - "hash123".as_bytes().to_vec(), - 0 - ).unwrap() -} \ No newline at end of file + "858f8fb2184b15ecb8c0be8b95398c81" + .as_bytes() + .to_vec() + .try_into() + .unwrap(), + "some_data123".as_bytes().to_vec().try_into().unwrap(), + 0, + None, + )); +} + +pub fn push_contract_resources(source: T::AccountId) { + let contract_resources = vec![types::ContractResources { + contract_id: 1, + used: Resources { + sru: 150 * GIGABYTE, + cru: 16, + mru: 8 * GIGABYTE, + hru: 0, + }, + }]; + + assert_ok!(SmartContractModule::::report_contract_resources( + RawOrigin::Signed(source).into(), + contract_resources, + )); +} + +pub(crate) fn get_city_name_input(city_input: &[u8]) -> CityNameInput { + BoundedVec::try_from(city_input.to_vec()).expect("Invalid city name input.") +} + +pub(crate) fn get_country_name_input(country_input: &[u8]) -> CountryNameInput { + BoundedVec::try_from(country_input.to_vec()).expect("Invalid country name input.") +} + +pub(crate) fn get_latitude_input(latitude_input: &[u8]) -> LatitudeInput { + BoundedVec::try_from(latitude_input.to_vec()).expect("Invalid latitude input.") +} + +pub(crate) fn get_longitude_input(longitude_input: &[u8]) -> LongitudeInput { + BoundedVec::try_from(longitude_input.to_vec()).expect("Invalid longitude input.") +} + +pub(crate) fn get_document_link_input(document_link_input: &[u8]) -> DocumentLinkInput { + BoundedVec::try_from(document_link_input.to_vec()).expect("Invalid document link input.") +} + +pub(crate) fn get_document_hash_input(document_hash_input: &[u8]) -> DocumentHashInput { + BoundedVec::try_from(document_hash_input.to_vec()).expect("Invalid document hash input.") +} + +pub(crate) fn get_twin_ip_input(twin_ip_input: &[u8]) -> TwinIpInput { + BoundedVec::try_from(twin_ip_input.to_vec()).expect("Invalid twin ip input.") +} diff --git a/substrate-node/pallets/pallet-smart-contract/src/cost.rs b/substrate-node/pallets/pallet-smart-contract/src/cost.rs index fbae0c3c7..d7270801e 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/cost.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/cost.rs @@ -2,12 +2,11 @@ use crate::pallet; use crate::pallet::BalanceOf; use crate::pallet::Error; use crate::types; -use crate::types::{Contract, ContractBillingInformation}; +use crate::types::{Contract, ContractBillingInformation, ServiceContract, ServiceContractBill}; use crate::Config; -use frame_support::dispatch::DispatchErrorWithPostInfo; +use frame_support::{dispatch::DispatchErrorWithPostInfo, traits::Get}; use pallet_tfgrid::types as pallet_tfgrid_types; -use sp_runtime::Percent; -use sp_runtime::SaturatedConversion; +use sp_runtime::{Percent, SaturatedConversion}; use substrate_fixed::types::U64F64; use tfchain_support::{resources::Resources, types::NodeCertification}; @@ -101,7 +100,8 @@ impl Contract { // Calculate total cost for a name contract types::ContractData::NameContract(_) => { // bill user for name usage for number of seconds elapsed - let total_cost_u64f64 = (U64F64::from_num(pricing_policy.unique_name.value) / 3600) + let total_cost_u64f64 = (U64F64::from_num(pricing_policy.unique_name.value) + / U64F64::from_num(T::BillingReferencePeriod::get())) * U64F64::from_num(seconds_elapsed); total_cost_u64f64.to_num::() } @@ -111,6 +111,36 @@ impl Contract { } } +impl ServiceContract { + pub fn calculate_bill_cost_tft( + &self, + service_bill: ServiceContractBill, + ) -> Result, DispatchErrorWithPostInfo> { + // Calculate the cost in mUSD for service contract bill + let total_cost = self.calculate_bill_cost::(service_bill); + + if total_cost == 0 { + return Ok(BalanceOf::::saturated_from(0 as u128)); + } + + // Calculate the cost in TFT for service contract + let total_cost_tft_64 = calculate_cost_in_tft_from_musd::(total_cost)?; + + // convert to balance object + let amount_due: BalanceOf = BalanceOf::::saturated_from(total_cost_tft_64); + + return Ok(amount_due); + } + + pub fn calculate_bill_cost(&self, service_bill: ServiceContractBill) -> u64 { + // bill user for service usage for elpased usage (window) in seconds + let contract_cost = U64F64::from_num(self.base_fee) * U64F64::from_num(service_bill.window) + / U64F64::from_num(T::BillingReferencePeriod::get()) + + U64F64::from_num(service_bill.variable_amount); + contract_cost.round().to_num::() + } +} + // Calculates the total cost of a node contract. pub fn calculate_resources_cost( resources: Resources, @@ -130,14 +160,16 @@ pub fn calculate_resources_cost( let su_used = hru / 1200 + sru / 200; // the pricing policy su cost value is expressed in 1 hours or 3600 seconds. // we bill every 3600 seconds but here we need to calculate the cost per second and multiply it by the seconds elapsed. - let su_cost = (U64F64::from_num(pricing_policy.su.value) / 3600) + let su_cost = (U64F64::from_num(pricing_policy.su.value) + / U64F64::from_num(T::BillingReferencePeriod::get())) * U64F64::from_num(seconds_elapsed) * su_used; log::debug!("su cost: {:?}", su_cost); let cu = calculate_cu(cru, mru); - let cu_cost = (U64F64::from_num(pricing_policy.cu.value) / 3600) + let cu_cost = (U64F64::from_num(pricing_policy.cu.value) + / U64F64::from_num(T::BillingReferencePeriod::get())) * U64F64::from_num(seconds_elapsed) * cu; log::debug!("cu cost: {:?}", cu_cost); @@ -146,7 +178,8 @@ pub fn calculate_resources_cost( if ipu > 0 { let total_ip_cost = U64F64::from_num(ipu) - * (U64F64::from_num(pricing_policy.ipu.value) / 3600) + * (U64F64::from_num(pricing_policy.ipu.value) + / U64F64::from_num(T::BillingReferencePeriod::get())) * U64F64::from_num(seconds_elapsed); log::debug!("ip cost: {:?}", total_ip_cost); total_cost += total_ip_cost; diff --git a/substrate-node/pallets/pallet-smart-contract/src/lib.rs b/substrate-node/pallets/pallet-smart-contract/src/lib.rs index 5293ae67f..ed1b5365d 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/lib.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/lib.rs @@ -1,9 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::prelude::*; - use frame_support::{ - dispatch::DispatchErrorWithPostInfo, + dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Pays}, ensure, log::info, pallet_prelude::DispatchResult, @@ -11,23 +9,32 @@ use frame_support::{ Currency, EnsureOrigin, ExistenceRequirement, ExistenceRequirement::KeepAlive, Get, LockableCurrency, OnUnbalanced, WithdrawReasons, }, - transactional, - weights::Pays, - BoundedVec, + transactional, BoundedVec, +}; +use frame_system::{ + self as system, ensure_signed, + offchain::{AppCrypto, CreateSignedTransaction, SendSignedTransaction, Signer}, }; -use frame_system::{self as system, ensure_signed}; +pub use pallet::*; +use pallet_authorship; use pallet_tfgrid; -use pallet_tfgrid::pallet::{InterfaceOf, PubConfigOf}; +use pallet_tfgrid::pallet::{InterfaceOf, LocationOf, SerialNumberOf, TfgridNode}; use pallet_tfgrid::types as pallet_tfgrid_types; use pallet_timestamp as timestamp; +use sp_core::crypto::KeyTypeId; use sp_runtime::{ - traits::{CheckedSub, SaturatedConversion}, + traits::{CheckedSub, Convert, SaturatedConversion}, Perbill, }; +use sp_std::prelude::*; use substrate_fixed::types::U64F64; -use tfchain_support::{traits::ChangeNode, types::Node}; +use system::offchain::SignMessage; +use tfchain_support::{ + traits::{ChangeNode, PublicIpModifier}, + types::PublicIP, +}; -pub use pallet::*; +pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"aura"); #[cfg(test)] mod mock; @@ -35,11 +42,48 @@ mod mock; #[cfg(test)] mod tests; -pub mod weights; +#[cfg(test)] +mod test_utils; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + +pub mod crypto { + use crate::KEY_TYPE; + use sp_core::sr25519::Signature as Sr25519Signature; + use sp_runtime::{ + app_crypto::{app_crypto, sr25519}, + traits::Verify, + MultiSignature, MultiSigner, + }; + use sp_std::convert::TryFrom; + + app_crypto!(sr25519, KEY_TYPE); + + pub struct AuthId; + + // implemented for ocw-runtime + impl frame_system::offchain::AppCrypto for AuthId { + type RuntimeAppPublic = Public; + type GenericSignature = sp_core::sr25519::Signature; + type GenericPublic = sp_core::sr25519::Public; + } + + // implemented for mock runtime in test + impl frame_system::offchain::AppCrypto<::Signer, Sr25519Signature> + for AuthId + { + type RuntimeAppPublic = Public; + type GenericSignature = sp_core::sr25519::Signature; + type GenericPublic = sp_core::sr25519::Public; + } +} pub mod cost; +pub mod migrations; pub mod name_contract; pub mod types; +pub mod weights; #[frame_support::pallet] pub mod pallet { @@ -48,11 +92,8 @@ pub mod pallet { use super::*; use codec::FullCodec; use frame_support::pallet_prelude::*; - use frame_support::{ - dispatch::DispatchResultWithPostInfo, - log, - traits::{Currency, Get, LockIdentifier, LockableCurrency, OnUnbalanced}, - }; + use frame_support::traits::Hooks; + use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, OnUnbalanced}; use frame_system::pallet_prelude::*; use sp_core::H256; use sp_std::{ @@ -60,7 +101,7 @@ pub mod pallet { fmt::Debug, vec::Vec, }; - use tfchain_support::traits::ChangeNode; + use tfchain_support::traits::{ChangeNode, PublicIpModifier}; pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; @@ -77,13 +118,12 @@ pub mod pallet { // Version constant that referenced the struct version pub const CONTRACT_VERSION: u32 = 4; + pub type BillingReferencePeriod = ::BillingReferencePeriod; pub type MaxNodeContractPublicIPs = ::MaxNodeContractPublicIps; pub type MaxDeploymentDataLength = ::MaxDeploymentDataLength; pub type DeploymentDataInput = BoundedVec>; pub type DeploymentHash = H256; pub type NameContractNameOf = ::NameContractName; - pub type ContractPublicIP = - PublicIP<::PublicIP, ::GatewayIP>; #[pallet::storage] #[pallet::getter(fn contracts)] @@ -101,15 +141,8 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn node_contract_by_hash)] - pub type ContractIDByNodeIDAndHash = StorageDoubleMap< - _, - Blake2_128Concat, - u32, - Blake2_128Concat, - DeploymentHash, - u64, - ValueQuery, - >; + pub type ContractIDByNodeIDAndHash = + StorageDoubleMap<_, Blake2_128Concat, u32, Blake2_128Concat, HexHash, u64, ValueQuery>; #[pallet::storage] #[pallet::getter(fn active_node_contracts)] @@ -166,24 +199,40 @@ pub mod pallet { #[pallet::getter(fn billing_frequency)] pub type BillingFrequency = StorageValue<_, u64, ValueQuery, DefaultBillingFrequency>; + #[pallet::storage] + #[pallet::getter(fn service_contracts)] + pub type ServiceContracts = + StorageMap<_, Blake2_128Concat, u64, ServiceContract, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn service_contract_id)] + pub type ServiceContractID = StorageValue<_, u64, ValueQuery>; + #[pallet::config] pub trait Config: - frame_system::Config + CreateSignedTransaction> + + frame_system::Config + pallet_timestamp::Config + pallet_balances::Config + pallet_tfgrid::Config + pallet_tft_price::Config + + pallet_authorship::Config + + pallet_session::Config { - type Event: From> + IsType<::Event>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; type Currency: LockableCurrency; /// Handler for the unbalanced decrement when slashing (burning collateral) type Burn: OnUnbalanced>; type StakingPoolAccount: Get; type BillingFrequency: Get; + type BillingReferencePeriod: Get; type DistributionFrequency: Get; type GracePeriod: Get; type WeightInfo: WeightInfo; - type NodeChanged: ChangeNode, InterfaceOf>; + type NodeChanged: ChangeNode, InterfaceOf, SerialNumberOf>; + type PublicIpModifier: PublicIpModifier; + type AuthorityId: AppCrypto; + type Call: From>; #[pallet::constant] type MaxNameContractNameLength: Get; @@ -204,7 +253,7 @@ pub mod pallet { + TryFrom, Error = Error> + MaxEncodedLen; - type RestrictedOrigin: EnsureOrigin; + type RestrictedOrigin: EnsureOrigin; } #[pallet::event] @@ -227,13 +276,13 @@ pub mod pallet { /// IP got reserved by a Node contract IPsReserved { contract_id: u64, - public_ips: BoundedVec, MaxNodeContractPublicIPs>, + public_ips: BoundedVec>, }, /// IP got freed by a Node contract IPsFreed { contract_id: u64, // public ip as a string - public_ips: BoundedVec, MaxNodeContractPublicIPs>, + public_ips: BoundedVec>, }, /// Deprecated event ContractDeployed(u64, T::AccountId), @@ -268,6 +317,26 @@ pub mod pallet { }, SolutionProviderCreated(types::SolutionProvider), SolutionProviderApproved(u64, bool), + /// A Service contract is created + ServiceContractCreated(types::ServiceContract), + /// A Service contract metadata is set + ServiceContractMetadataSet(types::ServiceContract), + /// A Service contract fees are set + ServiceContractFeesSet(types::ServiceContract), + /// A Service contract is approved + ServiceContractApproved(types::ServiceContract), + /// A Service contract is canceled + ServiceContractCanceled { + service_contract_id: u64, + cause: types::Cause, + }, + /// A Service contract is billed + ServiceContractBilled { + service_contract: types::ServiceContract, + bill: types::ServiceContractBill, + amount: BalanceOf, + }, + BillingFrequencyChanged(u64), } #[pallet::error] @@ -299,11 +368,28 @@ pub mod pallet { NodeNotAvailableToDeploy, CannotUpdateContractInGraceState, NumOverflow, - NameContractNameToShort, - NameContractNameToLong, + OffchainSignedTxCannotSign, + OffchainSignedTxAlreadySent, + OffchainSignedTxNoLocalAccountAvailable, + NameContractNameTooShort, + NameContractNameTooLong, InvalidProviderConfiguration, NoSuchSolutionProvider, SolutionProviderNotApproved, + TwinNotAuthorized, + ServiceContractNotExists, + ServiceContractCreationNotAllowed, + ServiceContractModificationNotAllowed, + ServiceContractApprovalNotAllowed, + ServiceContractRejectionNotAllowed, + ServiceContractBillingNotApprovedByBoth, + ServiceContractBillingVariableAmountTooHigh, + ServiceContractBillMetadataTooLong, + ServiceContractMetadataTooLong, + ServiceContractNotEnoughFundsToPayBill, + CanOnlyIncreaseFrequency, + IsNotAnAuthority, + WrongAuthority, } #[pallet::genesis_config] @@ -330,11 +416,12 @@ pub mod pallet { #[pallet::call] impl Pallet { - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::create_node_contract())] pub fn create_node_contract( origin: OriginFor, node_id: u32, - deployment_hash: DeploymentHash, + deployment_hash: HexHash, deployment_data: DeploymentDataInput, public_ips: u32, solution_provider_id: Option, @@ -350,18 +437,20 @@ pub mod pallet { ) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(1)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn update_node_contract( origin: OriginFor, contract_id: u64, - deployment_hash: DeploymentHash, + deployment_hash: HexHash, deployment_data: DeploymentDataInput, ) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; Self::_update_node_contract(account_id, contract_id, deployment_hash, deployment_data) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(2)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn cancel_contract( origin: OriginFor, contract_id: u64, @@ -371,7 +460,8 @@ pub mod pallet { } // DEPRECATED - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(3)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn add_reports( _origin: OriginFor, _reports: Vec, @@ -380,7 +470,8 @@ pub mod pallet { Err(DispatchErrorWithPostInfo::from(Error::::MethodIsDeprecated).into()) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(4)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn create_name_contract( origin: OriginFor, name: Vec, @@ -389,7 +480,8 @@ pub mod pallet { Self::_create_name_contract(account_id, name) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(5)] + #[pallet::weight(::WeightInfo::add_nru_reports())] pub fn add_nru_reports( origin: OriginFor, reports: Vec, @@ -398,7 +490,8 @@ pub mod pallet { Self::_compute_reports(account_id, reports) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(6)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn report_contract_resources( origin: OriginFor, contract_resources: Vec, @@ -407,7 +500,8 @@ pub mod pallet { Self::_report_contract_resources(account_id, contract_resources) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(7)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn create_rent_contract( origin: OriginFor, node_id: u32, @@ -417,7 +511,8 @@ pub mod pallet { Self::_create_rent_contract(account_id, node_id, solution_provider_id) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(8)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn create_solution_provider( origin: OriginFor, description: Vec, @@ -428,7 +523,8 @@ pub mod pallet { Self::_create_solution_provider(description, link, providers) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(9)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn approve_solution_provider( origin: OriginFor, solution_provider_id: u64, @@ -437,44 +533,157 @@ pub mod pallet { ::RestrictedOrigin::ensure_origin(origin)?; Self::_approve_solution_provider(solution_provider_id, approve) } + + #[pallet::call_index(10)] + #[pallet::weight(::WeightInfo::bill_contract_for_block())] + pub fn bill_contract_for_block( + origin: OriginFor, + contract_id: u64, + ) -> DispatchResultWithPostInfo { + let _account_id = ensure_signed(origin)?; + Self::bill_contract(contract_id) + } + + #[pallet::call_index(11)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] + pub fn service_contract_create( + origin: OriginFor, + service_account: T::AccountId, + consumer_account: T::AccountId, + ) -> DispatchResultWithPostInfo { + let caller_account = ensure_signed(origin)?; + Self::_service_contract_create(caller_account, service_account, consumer_account) + } + + #[pallet::call_index(12)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] + pub fn service_contract_set_metadata( + origin: OriginFor, + service_contract_id: u64, + metadata: Vec, + ) -> DispatchResultWithPostInfo { + let account_id = ensure_signed(origin)?; + Self::_service_contract_set_metadata(account_id, service_contract_id, metadata) + } + + #[pallet::call_index(13)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] + pub fn service_contract_set_fees( + origin: OriginFor, + service_contract_id: u64, + base_fee: u64, + variable_fee: u64, + ) -> DispatchResultWithPostInfo { + let account_id = ensure_signed(origin)?; + Self::_service_contract_set_fees( + account_id, + service_contract_id, + base_fee, + variable_fee, + ) + } + + #[pallet::call_index(14)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] + pub fn service_contract_approve( + origin: OriginFor, + service_contract_id: u64, + ) -> DispatchResultWithPostInfo { + let account_id = ensure_signed(origin)?; + Self::_service_contract_approve(account_id, service_contract_id) + } + + #[pallet::call_index(15)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] + pub fn service_contract_reject( + origin: OriginFor, + service_contract_id: u64, + ) -> DispatchResultWithPostInfo { + let account_id = ensure_signed(origin)?; + Self::_service_contract_reject(account_id, service_contract_id) + } + + #[pallet::call_index(16)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] + pub fn service_contract_cancel( + origin: OriginFor, + service_contract_id: u64, + ) -> DispatchResultWithPostInfo { + let account_id = ensure_signed(origin)?; + + let twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&account_id) + .ok_or(Error::::TwinNotExists)?; + + Self::_service_contract_cancel( + twin_id, + service_contract_id, + types::Cause::CanceledByUser, + ) + } + + #[pallet::call_index(17)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] + pub fn service_contract_bill( + origin: OriginFor, + service_contract_id: u64, + variable_amount: u64, + metadata: Vec, + ) -> DispatchResultWithPostInfo { + let account_id = ensure_signed(origin)?; + Self::_service_contract_bill(account_id, service_contract_id, variable_amount, metadata) + } + + #[pallet::call_index(18)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] + pub fn change_billing_frequency( + origin: OriginFor, + frequency: u64, + ) -> DispatchResultWithPostInfo { + ::RestrictedOrigin::ensure_origin(origin)?; + Self::_change_billing_frequency(frequency) + } } #[pallet::hooks] impl Hooks> for Pallet { - fn on_finalize(block: T::BlockNumber) { - match Self::_bill_contracts_at_block(block) { - Ok(_) => { - log::info!( - "types::NodeContract billed successfully at block: {:?}", - block - ); - } - Err(err) => { - log::error!( - "types::NodeContract billed failed at block: {:?} with err {:?}", - block, - err - ); - } + fn offchain_worker(block_number: T::BlockNumber) { + // Let offchain worker check if there are contracts on the map at current index + // Index being current block number % (mod) Billing Frequency + let current_index: u64 = + block_number.saturated_into::() % BillingFrequency::::get(); + + let contracts = ContractsToBillAt::::get(current_index); + if contracts.is_empty() { + log::info!( + "No contracts to bill at block {:?}, index: {:?}", + block_number, + current_index + ); + return; + } + + log::info!( + "{:?} contracts to bill at block {:?}", + contracts, + block_number + ); + + for contract_id in contracts { + let _res = Self::bill_contract_using_signed_transaction(contract_id); } - // clean storage map for billed contracts at block - let current_block_u64: u64 = block.saturated_into::(); - ContractsToBillAt::::remove(current_block_u64); } } } -use frame_support::pallet_prelude::DispatchResultWithPostInfo; +use crate::types::HexHash; use pallet::NameContractNameOf; -// use pallet_tfgrid::pub_ip::{GatewayIP, PublicIP as PalletTfgridPublicIP}; use sp_std::convert::{TryFrom, TryInto}; -use tfchain_support::types::PublicIP; // Internal functions of the pallet impl Pallet { pub fn _create_node_contract( account_id: T::AccountId, node_id: u32, - deployment_hash: DeploymentHash, + deployment_hash: HexHash, deployment_data: DeploymentDataInput, public_ips: u32, solution_provider_id: Option, @@ -510,13 +719,8 @@ impl Pallet { } } - let public_ips_list: BoundedVec< - PublicIP< - ::PublicIP, - ::GatewayIP, - >, - MaxNodeContractPublicIPs, - > = vec![].try_into().unwrap(); + let public_ips_list: BoundedVec> = + vec![].try_into().unwrap(); // Prepare NodeContract struct let node_contract = types::NodeContract { node_id, @@ -662,7 +866,7 @@ impl Pallet { // Start billing frequency loop // Will always be block now + frequency - Self::_reinsert_contract_to_bill(id); + Self::insert_contract_to_bill(id); // insert into contracts map Contracts::::insert(id, &contract); @@ -681,7 +885,7 @@ impl Pallet { pub fn _update_node_contract( account_id: T::AccountId, contract_id: u64, - deployment_hash: DeploymentHash, + deployment_hash: HexHash, deployment_data: DeploymentDataInput, ) -> DispatchResultWithPostInfo { let mut contract = Contracts::::get(contract_id).ok_or(Error::::ContractNotExists)?; @@ -752,10 +956,8 @@ impl Pallet { ); } - // Update state Self::_update_contract_state(&mut contract, &types::ContractState::Deleted(cause))?; - // Bill contract - Self::bill_contract(&mut contract)?; + Self::bill_contract(contract.contract_id)?; // Remove all associated storage Self::remove_contract(contract.contract_id); @@ -862,7 +1064,8 @@ impl Pallet { // calculate NRU used and the cost let used_nru = U64F64::from_num(report.nru) / pricing_policy.nu.factor_base_1000(); let nu_cost = used_nru - * (U64F64::from_num(pricing_policy.nu.value) / 3600) + * (U64F64::from_num(pricing_policy.nu.value) + / U64F64::from_num(T::BillingReferencePeriod::get())) * U64F64::from_num(seconds_elapsed); log::info!("nu cost: {:?}", nu_cost); @@ -876,58 +1079,60 @@ impl Pallet { ContractBillingInformationByID::::insert(report.contract_id, &contract_billing_info); } - pub fn _bill_contracts_at_block(block: T::BlockNumber) -> DispatchResultWithPostInfo { - let current_block_u64: u64 = block.saturated_into::(); - let contracts = ContractsToBillAt::::get(current_block_u64); - for contract_id in contracts { - if !Contracts::::contains_key(contract_id) { - continue; - } - let mut contract = - Contracts::::get(contract_id).ok_or(Error::::ContractNotExists)?; + fn bill_contract_using_signed_transaction(contract_id: u64) -> Result<(), Error> { + let signer = Signer::::AuthorityId>::any_account(); - // Try to bill contract - match Self::bill_contract(&mut contract) { - Ok(_) => { - log::info!( - "billed contract with id {:?} at block {:?}", - contract_id, - block - ); - } - Err(err) => { - log::error!( - "error while billing contract with id {:?}: {:?}", - contract_id, - err - ); - // If billing the contract failed, we should delete the contract and clean up storage - Self::remove_contract(contract.contract_id); - continue; - } - } + // Only allow the author of the next block to trigger the billing + Self::is_next_block_author(&signer)?; - // https://github.com/threefoldtech/tfchain/issues/264 - // if a contract is still in storage and actively getting billed whilst it is in state delete - // remove all associated storage and continue - let ctr = Contracts::::get(contract_id); - if let Some(contract) = ctr { - if contract.contract_id != 0 && contract.is_state_delete() { - Self::remove_contract(contract.contract_id); - continue; - } - - // Reinsert into the next billing frequency - Self::_reinsert_contract_to_bill(contract.contract_id); + if !signer.can_sign() { + log::error!( + "failed billing contract {:?} account cannot be used to sign transaction", + contract_id, + ); + return Err(>::OffchainSignedTxCannotSign); + } + let result = + signer.send_signed_transaction(|_acct| Call::bill_contract_for_block { contract_id }); + + if let Some((acc, res)) = result { + // if res is an error this means sending the transaction failed + // this means the transaction was already send before (probably by another node) + // unfortunately the error is always empty (substrate just logs the error and + // returns Err()) + if res.is_err() { + log::error!( + "signed transaction failed for billing contract {:?} using account {:?}", + contract_id, + acc.id + ); + return Err(>::OffchainSignedTxAlreadySent); } + return Ok(()); } - Ok(().into()) + log::error!("No local account available"); + return Err(>::OffchainSignedTxNoLocalAccountAvailable); } // Bills a contract (NodeContract or NameContract) // Calculates how much TFT is due by the user and distributes the rewards - #[transactional] - fn bill_contract(contract: &mut types::Contract) -> DispatchResultWithPostInfo { + fn bill_contract(contract_id: u64) -> DispatchResultWithPostInfo { + // Clean up contract from blling loop if it not exists anymore + if !Contracts::::contains_key(contract_id) { + log::debug!("cleaning up deleted contract from storage"); + + let index = Self::get_contract_index(); + + // Remove contract from billing list + let mut contracts = ContractsToBillAt::::get(index); + contracts.retain(|&c| c != contract_id); + ContractsToBillAt::::insert(index, contracts); + + return Ok(().into()); + } + + let mut contract = Contracts::::get(contract_id).ok_or(Error::::ContractNotExists)?; + let twin = pallet_tfgrid::Twins::::get(contract.twin_id).ok_or(Error::::TwinNotExists)?; let usable_balance = Self::get_usable_balance(&twin.account_id); @@ -947,13 +1152,22 @@ impl Pallet { let (amount_due, discount_received) = contract.calculate_contract_cost_tft(usable_balance, seconds_elapsed)?; - // If there is nothing to be paid, return - if amount_due == BalanceOf::::saturated_from(0 as u128) { + // If there is nothing to be paid and the contract is not in state delete, return + // Can be that the users cancels the contract in the same block that it's getting billed + // where elapsed seconds would be 0, but we still have to distribute rewards + if amount_due == BalanceOf::::saturated_from(0 as u128) && !contract.is_state_delete() { + log::debug!("amount to be billed is 0, nothing to do"); return Ok(().into()); }; // Handle grace - let contract = Self::handle_grace(contract, usable_balance, amount_due)?; + let contract = Self::handle_grace(&mut contract, usable_balance, amount_due)?; + + // If still in grace period, no need to continue doing locking and other stuff + if matches!(contract.state, types::ContractState::GracePeriod(_)) { + log::debug!("contract {} is still in grace", contract.contract_id); + return Ok(().into()); + } // Handle contract lock operations Self::handle_lock(contract, amount_due)?; @@ -978,6 +1192,8 @@ impl Pallet { Self::remove_contract(contract.contract_id); } + log::info!("successfully billed contract with id {:?}", contract_id,); + Ok(().into()) } @@ -1018,6 +1234,10 @@ impl Pallet { // we can still update the internal contract lock object to figure out later how much was due // whilst in grace period if amount_due >= usable_balance { + log::info!( + "Grace period started at block {:?} due to lack of funds", + current_block + ); Self::_update_contract_state( contract, &types::ContractState::GracePeriod(current_block), @@ -1096,11 +1316,6 @@ impl Pallet { ContractLock::::insert(contract.contract_id, &contract_lock); } - // Contract is in grace state, don't actually lock tokens or distribute rewards - if matches!(contract.state, types::ContractState::GracePeriod(_)) { - return Ok(().into()); - } - // Only lock an amount from the user's balance if the contract is in create state // The lock is specified on the user's account, since a user can have multiple contracts // Just extend the lock with the amount due for this contract billing period (lock will be created if not exists) @@ -1117,9 +1332,8 @@ impl Pallet { ); } - let is_canceled = matches!(contract.state, types::ContractState::Deleted(_)); let canceled_and_not_zero = - is_canceled && contract_lock.amount_locked.saturated_into::() > 0; + contract.is_state_delete() && contract_lock.amount_locked.saturated_into::() > 0; // When the cultivation rewards are ready to be distributed or it's in delete state // Unlock all reserved balance and distribute if contract_lock.cycles >= T::DistributionFrequency::get() || canceled_and_not_zero { @@ -1160,8 +1374,11 @@ impl Pallet { &pricing_policy, twin_balance.min(contract_lock.amount_locked), ) { - Ok(_) => (), - Err(err) => log::error!("error while distributing cultivation rewards {:?}", err), + Ok(_) => {} + Err(err) => { + log::error!("error while distributing cultivation rewards {:?}", err); + return Err(err); + } }; // Reset values contract_lock.lock_updated = now; @@ -1198,7 +1415,6 @@ impl Pallet { &node_contract.deployment_hash, ); NodeContractResources::::remove(contract_id); - ContractBillingInformationByID::::remove(contract_id); Self::deposit_event(Event::NodeContractCanceled { contract_id, @@ -1222,6 +1438,7 @@ impl Pallet { } }; info!("removing contract"); + ContractBillingInformationByID::::remove(contract_id); Contracts::::remove(contract_id); ContractLock::::remove(contract_id); } @@ -1284,7 +1501,7 @@ impl Pallet { .iter() .map(|provider| { let share = Perbill::from_percent(provider.take as u32) * amount; - frame_support::log::info!( + log::info!( "Transfering: {:?} from contract twin {:?} to provider account {:?}", &share, &twin.account_id, @@ -1312,9 +1529,9 @@ impl Pallet { let share = Perbill::from_percent(sales_share.into()) * amount; // Transfer the remaining share to the sales account // By default it is 50%, if a contract has solution providers it can be less - frame_support::log::info!( + log::info!( "Transfering: {:?} from contract twin {:?} to sales account {:?}", - &sales_share, + &share, &twin.account_id, &pricing_policy.certified_sales_account ); @@ -1343,7 +1560,14 @@ impl Pallet { WithdrawReasons::FEE, ExistenceRequirement::KeepAlive, )?; + + log::info!( + "Burning: {:?} from contract twin {:?}", + amount_to_burn, + &twin.account_id + ); T::Burn::on_unbalanced(to_burn); + Self::deposit_event(Event::TokensBurned { contract_id: contract.contract_id, amount: amount_to_burn, @@ -1352,23 +1576,26 @@ impl Pallet { Ok(().into()) } - // Reinserts a contract by id at the next interval we need to bill the contract - pub fn _reinsert_contract_to_bill(contract_id: u64) { + // Inserts a contract in a list where the index is the current block % billing frequency + // This way, we don't need to reinsert the contract everytime it gets billed + pub fn insert_contract_to_bill(contract_id: u64) { if contract_id == 0 { return; } - let now = >::block_number().saturated_into::(); - // Save the contract to be billed in now + BILLING_FREQUENCY_IN_BLOCKS - let future_block = now + BillingFrequency::::get(); - let mut contracts = ContractsToBillAt::::get(future_block); - contracts.push(contract_id); - ContractsToBillAt::::insert(future_block, &contracts); - log::info!( - "Insert contracts: {:?}, to be billed at block {:?}", - contracts, - future_block - ); + // Save the contract to be billed in (now -1 %(mod) BILLING_FREQUENCY_IN_BLOCKS) + let index = Self::get_contract_index().checked_sub(1).unwrap_or(0); + let mut contracts = ContractsToBillAt::::get(index); + + if !contracts.contains(&contract_id) { + contracts.push(contract_id); + ContractsToBillAt::::insert(index, &contracts); + log::info!( + "Insert contracts: {:?}, to be billed at index {:?}", + contracts, + index + ); + } } // Helper function that updates the contract state and manages storage accordingly @@ -1449,13 +1676,7 @@ impl Pallet { Error::::FarmHasNotEnoughPublicIPs ); - let mut ips: BoundedVec< - PublicIP< - ::PublicIP, - ::GatewayIP, - >, - MaxNodeContractPublicIPs, - > = vec![].try_into().unwrap(); + let mut ips: BoundedVec> = vec![].try_into().unwrap(); for i in 0..farm.public_ips.len() { if ips.len() == node_contract.public_ips as usize { @@ -1504,13 +1725,8 @@ impl Pallet { let mut farm = pallet_tfgrid::Farms::::get(node.farm_id).ok_or(Error::::FarmNotExists)?; - let mut public_ips: BoundedVec< - PublicIP< - ::PublicIP, - ::GatewayIP, - >, - MaxNodeContractPublicIPs, - > = vec![].try_into().unwrap(); + let mut public_ips: BoundedVec> = + vec![].try_into().unwrap(); for i in 0..farm.public_ips.len() { // if an ip has contract id 0 it means it's not reserved // reserve it now @@ -1645,16 +1861,415 @@ impl Pallet { } Ok(().into()) } -} -impl ChangeNode, InterfaceOf> for Pallet { - fn node_changed( - _node: Option<&Node, InterfaceOf>>, - _new_node: &Node, InterfaceOf>, - ) { + pub fn get_contract_index() -> u64 { + let now = >::block_number().saturated_into::(); + now % BillingFrequency::::get() + } + + pub fn _service_contract_create( + caller: T::AccountId, + service: T::AccountId, + consumer: T::AccountId, + ) -> DispatchResultWithPostInfo { + let caller_twin_id = + pallet_tfgrid::TwinIdByAccountID::::get(&caller).ok_or(Error::::TwinNotExists)?; + + let service_twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&service) + .ok_or(Error::::TwinNotExists)?; + + let consumer_twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&consumer) + .ok_or(Error::::TwinNotExists)?; + + // Only service or consumer can create contract + ensure!( + caller_twin_id == service_twin_id || caller_twin_id == consumer_twin_id, + Error::::TwinNotAuthorized, + ); + + // Service twin and consumer twin can not be the same + ensure!( + service_twin_id != consumer_twin_id, + Error::::ServiceContractCreationNotAllowed, + ); + + // Get the service contract ID map and increment + let mut id = ServiceContractID::::get(); + id = id + 1; + + // Create service contract + let service_contract = types::ServiceContract { + service_contract_id: id, + service_twin_id, + consumer_twin_id, + base_fee: 0, + variable_fee: 0, + metadata: vec![].try_into().unwrap(), + accepted_by_service: false, + accepted_by_consumer: false, + last_bill: 0, + state: types::ServiceContractState::Created, + }; + + // Insert into service contract map + ServiceContracts::::insert(id, &service_contract); + + // Update Contract ID + ServiceContractID::::put(id); + + // Trigger event for service contract creation + Self::deposit_event(Event::ServiceContractCreated(service_contract)); + + Ok(().into()) + } + + pub fn _service_contract_set_metadata( + account_id: T::AccountId, + service_contract_id: u64, + metadata: Vec, + ) -> DispatchResultWithPostInfo { + let twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&account_id) + .ok_or(Error::::TwinNotExists)?; + + let mut service_contract = ServiceContracts::::get(service_contract_id) + .ok_or(Error::::ServiceContractNotExists)?; + + // Only service or consumer can set metadata + ensure!( + twin_id == service_contract.service_twin_id + || twin_id == service_contract.consumer_twin_id, + Error::::TwinNotAuthorized, + ); + + // Only allow to modify metadata if contract still not approved by both parties + ensure!( + !matches!( + service_contract.state, + types::ServiceContractState::ApprovedByBoth + ), + Error::::ServiceContractModificationNotAllowed, + ); + + service_contract.metadata = BoundedVec::try_from(metadata) + .map_err(|_| Error::::ServiceContractMetadataTooLong)?; + + // If base_fee is set and non-zero (mandatory) + if service_contract.base_fee != 0 { + service_contract.state = types::ServiceContractState::AgreementReady; + } + + // Update service contract in map after modification + ServiceContracts::::insert(service_contract_id, service_contract.clone()); + + // Trigger event for service contract metadata setting + Self::deposit_event(Event::ServiceContractMetadataSet(service_contract)); + + Ok(().into()) + } + + pub fn _service_contract_set_fees( + account_id: T::AccountId, + service_contract_id: u64, + base_fee: u64, + variable_fee: u64, + ) -> DispatchResultWithPostInfo { + let twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&account_id) + .ok_or(Error::::TwinNotExists)?; + + let mut service_contract = ServiceContracts::::get(service_contract_id) + .ok_or(Error::::ServiceContractNotExists)?; + + // Only service can set fees + ensure!( + twin_id == service_contract.service_twin_id, + Error::::TwinNotAuthorized, + ); + + // Only allow to modify fees if contract still not approved by both parties + ensure!( + !matches!( + service_contract.state, + types::ServiceContractState::ApprovedByBoth + ), + Error::::ServiceContractModificationNotAllowed, + ); + + service_contract.base_fee = base_fee; + service_contract.variable_fee = variable_fee; + + // If metadata is filled and not empty (mandatory) + if !service_contract.metadata.is_empty() { + service_contract.state = types::ServiceContractState::AgreementReady; + } + + // Update service contract in map after modification + ServiceContracts::::insert(service_contract_id, service_contract.clone()); + + // Trigger event for service contract fees setting + Self::deposit_event(Event::ServiceContractFeesSet(service_contract)); + + Ok(().into()) + } + + pub fn _service_contract_approve( + account_id: T::AccountId, + service_contract_id: u64, + ) -> DispatchResultWithPostInfo { + let twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&account_id) + .ok_or(Error::::TwinNotExists)?; + + let mut service_contract = ServiceContracts::::get(service_contract_id) + .ok_or(Error::::ServiceContractNotExists)?; + + // Allow to approve contract only if agreement is ready + ensure!( + matches!( + service_contract.state, + types::ServiceContractState::AgreementReady + ), + Error::::ServiceContractApprovalNotAllowed, + ); + + // Only service or consumer can accept agreement + if twin_id == service_contract.service_twin_id { + service_contract.accepted_by_service = true; + } else if twin_id == service_contract.consumer_twin_id { + service_contract.accepted_by_consumer = true + } else { + return Err(DispatchErrorWithPostInfo::from( + Error::::TwinNotAuthorized, + )); + } + + // If both parties (service and consumer) accept then contract is approved and can be billed + if service_contract.accepted_by_service && service_contract.accepted_by_consumer { + // Change contract state to approved and emit event + service_contract.state = types::ServiceContractState::ApprovedByBoth; + + // Initialize billing time + let now = >::get().saturated_into::() / 1000; + service_contract.last_bill = now; + } + + // Update service contract in map after modification + ServiceContracts::::insert(service_contract_id, service_contract.clone()); + + // Trigger event for service contract approval + Self::deposit_event(Event::ServiceContractApproved(service_contract)); + + Ok(().into()) + } + + pub fn _service_contract_reject( + account_id: T::AccountId, + service_contract_id: u64, + ) -> DispatchResultWithPostInfo { + let twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&account_id) + .ok_or(Error::::TwinNotExists)?; + + let service_contract = ServiceContracts::::get(service_contract_id) + .ok_or(Error::::ServiceContractNotExists)?; + + // Only service or consumer can reject agreement + ensure!( + twin_id == service_contract.service_twin_id + || twin_id == service_contract.consumer_twin_id, + Error::::TwinNotAuthorized, + ); + + // Allow to reject contract only if agreement is ready + ensure!( + matches!( + service_contract.state, + types::ServiceContractState::AgreementReady + ), + Error::::ServiceContractRejectionNotAllowed, + ); + + // If one party (service or consumer) rejects agreement + // then contract is canceled and removed from service contract map + Self::_service_contract_cancel(twin_id, service_contract_id, types::Cause::CanceledByUser)?; + + Ok(().into()) + } + + pub fn _service_contract_cancel( + twin_id: u32, + service_contract_id: u64, + cause: types::Cause, + ) -> DispatchResultWithPostInfo { + let service_contract = ServiceContracts::::get(service_contract_id) + .ok_or(Error::::ServiceContractNotExists)?; + + // Only service or consumer can cancel contract + ensure!( + twin_id == service_contract.service_twin_id + || twin_id == service_contract.consumer_twin_id, + Error::::TwinNotAuthorized, + ); + + // Remove contract from service contract map + // Can be done at any state of contract + // so no need to handle state validation + ServiceContracts::::remove(service_contract_id); + + // Trigger event for service contract cancelation + Self::deposit_event(Event::ServiceContractCanceled { + service_contract_id, + cause, + }); + + log::info!( + "successfully removed service contract with id {:?}", + service_contract_id, + ); + + Ok(().into()) + } + + #[transactional] + pub fn _service_contract_bill( + account_id: T::AccountId, + service_contract_id: u64, + variable_amount: u64, + metadata: Vec, + ) -> DispatchResultWithPostInfo { + let twin_id = pallet_tfgrid::TwinIdByAccountID::::get(&account_id) + .ok_or(Error::::TwinNotExists)?; + + let mut service_contract = ServiceContracts::::get(service_contract_id) + .ok_or(Error::::ServiceContractNotExists)?; + + // Only service can bill consumer for service contract + ensure!( + twin_id == service_contract.service_twin_id, + Error::::TwinNotAuthorized, + ); + + // Allow to bill contract only if approved by both + ensure!( + matches!( + service_contract.state, + types::ServiceContractState::ApprovedByBoth + ), + Error::::ServiceContractBillingNotApprovedByBoth, + ); + + // Get elapsed time (in seconds) to bill for service + let now = >::get().saturated_into::() / 1000; + let elapsed_seconds_since_last_bill = now - service_contract.last_bill; + + // Billing time (window) is max 1h by design + // So extra time will not be billed + // It is the service responsability to bill on right frequency + let window = elapsed_seconds_since_last_bill.min(T::BillingReferencePeriod::get()); + + // Billing variable amount is bounded by contract variable fee + ensure!( + variable_amount + <= ((U64F64::from_num(window) + / U64F64::from_num(T::BillingReferencePeriod::get())) + * U64F64::from_num(service_contract.variable_fee)) + .round() + .to_num::(), + Error::::ServiceContractBillingVariableAmountTooHigh, + ); + + let bill_metadata = BoundedVec::try_from(metadata) + .map_err(|_| Error::::ServiceContractBillMetadataTooLong)?; + + // Create service contract bill + let service_contract_bill = types::ServiceContractBill { + variable_amount, + window, + metadata: bill_metadata, + }; + + // Make consumer pay for service contract bill + let amount = + Self::_service_contract_pay_bill(service_contract_id, service_contract_bill.clone())?; + + // Update contract in list after modification + service_contract.last_bill = now; + ServiceContracts::::insert(service_contract_id, service_contract.clone()); + + // Trigger event for service contract billing + Self::deposit_event(Event::ServiceContractBilled { + service_contract, + bill: service_contract_bill, + amount, + }); + + Ok(().into()) } - fn node_deleted(node: &Node, InterfaceOf>) { + // Pay a service contract bill + // Calculates how much TFT is due by the consumer and pay the amount to the service + fn _service_contract_pay_bill( + service_contract_id: u64, + bill: types::ServiceContractBill, + ) -> Result, DispatchErrorWithPostInfo> { + let service_contract = ServiceContracts::::get(service_contract_id) + .ok_or(Error::::ServiceContractNotExists)?; + let amount = service_contract.calculate_bill_cost_tft::(bill.clone())?; + + let service_twin_id = service_contract.service_twin_id; + let service_twin = + pallet_tfgrid::Twins::::get(service_twin_id).ok_or(Error::::TwinNotExists)?; + + let consumer_twin = pallet_tfgrid::Twins::::get(service_contract.consumer_twin_id) + .ok_or(Error::::TwinNotExists)?; + + let usable_balance = Self::get_usable_balance(&consumer_twin.account_id); + + // If consumer is out of funds then contract is canceled + // by service and removed from service contract map + if usable_balance < amount { + Self::_service_contract_cancel( + service_twin_id, + service_contract_id, + types::Cause::OutOfFunds, + )?; + return Err(DispatchErrorWithPostInfo::from( + Error::::ServiceContractNotEnoughFundsToPayBill, + )); + } + + // Transfer amount due from consumer account to service account + ::Currency::transfer( + &consumer_twin.account_id, + &service_twin.account_id, + amount, + ExistenceRequirement::KeepAlive, + )?; + + log::info!( + "bill successfully payed by consumer for service contract with id {:?}", + service_contract_id, + ); + + Ok(amount) + } + + pub fn _change_billing_frequency(frequency: u64) -> DispatchResultWithPostInfo { + let billing_frequency = BillingFrequency::::get(); + ensure!( + frequency > billing_frequency, + Error::::CanOnlyIncreaseFrequency + ); + + BillingFrequency::::put(frequency); + + Self::deposit_event(Event::BillingFrequencyChanged(frequency)); + + Ok(().into()) + } +} + +impl ChangeNode, InterfaceOf, SerialNumberOf> for Pallet { + fn node_changed(_node: Option<&TfgridNode>, _new_node: &TfgridNode) {} + + fn node_deleted(node: &TfgridNode) { // Clean up all active contracts let active_node_contracts = ActiveNodeContracts::::get(node.id); for node_contract_id in active_node_contracts { @@ -1664,7 +2279,7 @@ impl ChangeNode, InterfaceOf> for Pallet { &mut contract, &types::ContractState::Deleted(types::Cause::CanceledByUser), ); - let _ = Self::bill_contract(&mut contract); + let _ = Self::bill_contract(node_contract_id); Self::remove_contract(node_contract_id); } } @@ -1677,9 +2292,68 @@ impl ChangeNode, InterfaceOf> for Pallet { &mut contract, &types::ContractState::Deleted(types::Cause::CanceledByUser), ); - let _ = Self::bill_contract(&mut contract); + let _ = Self::bill_contract(contract.contract_id); Self::remove_contract(contract.contract_id); } } } } + +impl PublicIpModifier for Pallet { + fn ip_removed(ip: &PublicIP) { + if let Some(mut contract) = Contracts::::get(ip.contract_id) { + match contract.contract_type { + types::ContractData::NodeContract(mut node_contract) => { + if node_contract.public_ips > 0 { + if let Err(e) = Self::_free_ip(ip.contract_id, &mut node_contract) { + log::error!("error while freeing ips: {:?}", e); + } + } + contract.contract_type = types::ContractData::NodeContract(node_contract); + + Contracts::::insert(ip.contract_id, &contract); + } + _ => {} + } + } + } +} + +impl Pallet { + // Validates if the given signer is the next block author based on the validators in session + // This can be used if an extrinsic should be refunded by the author in the same block + // It also requires that the keytype inserted for the offchain workers is the validator key + fn is_next_block_author( + signer: &Signer::AuthorityId>, + ) -> Result<(), Error> { + let author = >::author(); + let validators = >::validators(); + + // Sign some arbitrary data in order to get the AccountId, maybe there is another way to do this? + let signed_message = signer.sign_message(&[0]); + if let Some(signed_message_data) = signed_message { + if let Some(block_author) = author { + let validator = + ::ValidatorIdOf::convert(block_author.clone()) + .ok_or(Error::::IsNotAnAuthority)?; + + let validator_count = validators.len(); + let author_index = (validators.iter().position(|a| a == &validator).unwrap_or(0) + + 1) + % validator_count; + + let signer_validator_account = + ::ValidatorIdOf::convert( + signed_message_data.0.id.clone(), + ) + .ok_or(Error::::IsNotAnAuthority)?; + + if signer_validator_account != validators[author_index] { + return Err(Error::::WrongAuthority); + } + } + } + + Ok(().into()) + } +} diff --git a/substrate-node/pallets/pallet-smart-contract/src/migrations/mod.rs b/substrate-node/pallets/pallet-smart-contract/src/migrations/mod.rs new file mode 100644 index 000000000..6ec139373 --- /dev/null +++ b/substrate-node/pallets/pallet-smart-contract/src/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v6; \ No newline at end of file diff --git a/substrate-node/pallets/pallet-smart-contract/src/migrations/v6.rs b/substrate-node/pallets/pallet-smart-contract/src/migrations/v6.rs new file mode 100644 index 000000000..e2bd8bc04 --- /dev/null +++ b/substrate-node/pallets/pallet-smart-contract/src/migrations/v6.rs @@ -0,0 +1,108 @@ +use crate::*; +use frame_support::{traits::OnRuntimeUpgrade, weights::Weight}; +use log::debug; +use sp_std::marker::PhantomData; + +#[cfg(feature = "try-runtime")] +use codec::{Decode, Encode}; +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +pub struct ContractMigrationV5(PhantomData); + +impl OnRuntimeUpgrade for ContractMigrationV5 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V5); + + let contracts_count: u64 = ContractsToBillAt::::iter().count() as u64; + log::info!( + "🔎 ContractMigrationV5 pre migration: Number of existing contracts {:?}", + contracts_count + ); + + info!("👥 Smart Contract pallet to V6 passes PRE migrate checks ✅",); + Ok(contracts_count.encode()) + } + + fn on_runtime_upgrade() -> Weight { + migrate_to_version_6::() + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(pre_contracts_count: Vec) -> Result<(), &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V6); + + // Check number of Contracts against pre-check result + let pre_contracts_count: u64 = Decode::decode(&mut pre_contracts_count.as_slice()) + .expect("the state parameter should be something that was generated by pre_upgrade"); + assert_eq!( + ContractsToBillAt::::iter().count() as u64, + pre_contracts_count, + "Number of Contracts migrated does not match" + ); + + info!( + "👥 Smart Contract pallet to {:?} passes POST migrate checks ✅", + PalletVersion::::get() + ); + + Ok(()) + } +} + +pub fn migrate_to_version_6() -> frame_support::weights::Weight { + if PalletVersion::::get() == types::StorageVersion::V5 { + info!( + " >>> Starting contract pallet migration, pallet version: {:?}", + PalletVersion::::get() + ); + + let mut migrated_count = 0; + + // Collect ContractsToBillAt storage in memory + let contracts_to_bill_at = ContractsToBillAt::::iter().collect::>(); + + // Remove all items under ContractsToBillAt + let _ = frame_support::migration::clear_storage_prefix( + b"SmartContractModule", + b"ContractsToBillAt", + b"", + None, + None, + ); // TODO check parameters + + let billing_freq = 600; + BillingFrequency::::put(billing_freq); + + for (block_number, contract_ids) in contracts_to_bill_at { + migrated_count += 1; + // Construct new index + let index = (block_number - 1) % billing_freq; + // Reinsert items under the new key + debug!( + "inserted contracts:{:?} at index: {:?}", + contract_ids.clone(), + index + ); + ContractsToBillAt::::insert(index, contract_ids); + } + + info!( + " <<< Contracts storage updated! Migrated {} Contracts ✅", + migrated_count + ); + + // Update pallet storage version + PalletVersion::::set(types::StorageVersion::V6); + info!(" <<< Storage version upgraded"); + + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(migrated_count + 1, migrated_count + 1) + } else { + info!(" >>> Unused Smart Contract pallet V6 migration"); + Weight::zero() + } +} diff --git a/substrate-node/pallets/pallet-smart-contract/src/mock.rs b/substrate-node/pallets/pallet-smart-contract/src/mock.rs index 283ae9797..1cd6c2419 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/mock.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/mock.rs @@ -1,37 +1,100 @@ #![cfg(test)] - use super::*; use crate::name_contract::NameContractName; use crate::{self as pallet_smart_contract}; +use codec::{alloc::sync::Arc, Decode}; use frame_support::{ - construct_runtime, parameter_types, + construct_runtime, + dispatch::PostDispatchInfo, + parameter_types, traits::{ConstU32, GenesisBuild}, + BoundedVec, }; use frame_system::EnsureRoot; use pallet_tfgrid::{ farm::FarmName, interface::{InterfaceIp, InterfaceMac, InterfaceName}, - pub_config::{Domain, GW4, GW6, IP4, IP6}, - pub_ip::{GatewayIP, PublicIP}, + node::{CityName, CountryName}, + node::{Location, SerialNumber}, + terms_cond::TermsAndConditions, twin::TwinIp, + CityNameInput, CountryNameInput, DocumentHashInput, DocumentLinkInput, Gw4Input, Ip4Input, + LatitudeInput, LongitudeInput, TwinIpInput, +}; +use parking_lot::RwLock; +use sp_core::{ + crypto::key_types::DUMMY, + crypto::Ss58Codec, + offchain::{ + testing::{self}, + OffchainDbExt, OffchainWorkerExt, TransactionPoolExt, + }, + sr25519, Pair, Public, H256, }; -use sp_core::{crypto::Ss58Codec, sr25519, Pair, Public, H256}; -use sp_runtime::traits::{IdentifyAccount, Verify}; -use sp_runtime::MultiSignature; +use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStore}; use sp_runtime::{ - testing::{Header, TestXt}, - traits::{BlakeTwo256, Extrinsic as ExtrinsicT, IdentityLookup}, - AccountId32, + impl_opaque_keys, + offchain::TransactionPool, + testing::{Header, TestXt, UintAuthorityId}, + traits::{ + BlakeTwo256, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup, OpaqueKeys, Verify, + }, + AccountId32, MultiSignature, }; use sp_std::convert::{TryFrom, TryInto}; -use tfchain_support::{traits::ChangeNode, types::Node}; +use sp_std::marker::PhantomData; +use std::{cell::RefCell, panic, thread}; +use tfchain_support::{ + constants::time::{MINUTES, SECS_PER_HOUR}, + traits::ChangeNode, +}; + +impl_opaque_keys! { + pub struct MockSessionKeys { + pub dummy: UintAuthorityId, + } +} + +impl From for MockSessionKeys { + fn from(dummy: UintAuthorityId) -> Self { + Self { dummy } + } +} + +pub const KEY_ID_A: KeyTypeId = KeyTypeId([4; 4]); +pub const KEY_ID_B: KeyTypeId = KeyTypeId([9; 4]); + +#[derive(Debug, Clone, codec::Encode, codec::Decode, PartialEq, Eq)] +pub struct PreUpgradeMockSessionKeys { + pub a: [u8; 32], + pub b: [u8; 64], +} + +impl OpaqueKeys for PreUpgradeMockSessionKeys { + type KeyTypeIdProviders = (); + + fn key_ids() -> &'static [KeyTypeId] { + &[KEY_ID_A, KEY_ID_B] + } + + fn get_raw(&self, i: KeyTypeId) -> &[u8] { + match i { + i if i == KEY_ID_A => &self.a[..], + i if i == KEY_ID_B => &self.b[..], + _ => &[], + } + } +} +// set environment variable RUST_LOG=debug to see all logs when running the tests and call +// env_logger::init() at the beginning of the test +use env_logger; pub type Signature = MultiSignature; pub type AccountId = <::Signer as IdentifyAccount>::AccountId; pub type Moment = u64; -type Extrinsic = TestXt; +pub type Extrinsic = TestXt; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -46,15 +109,15 @@ construct_runtime!( TfgridModule: pallet_tfgrid::{Pallet, Call, Storage, Event}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, SmartContractModule: pallet_smart_contract::{Pallet, Call, Storage, Event}, - TFTPriceModule: pallet_tft_price::{Pallet, Call, Storage, Event} + TFTPriceModule: pallet_tft_price::{Pallet, Call, Storage, Event}, + Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent}, + ValidatorSet: substrate_validator_set::{Pallet, Call, Storage, Event, Config}, + Session: pallet_session::{Pallet, Call, Storage, Event, Config}, } ); parameter_types! { pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); - pub const ExistentialDeposit: u64 = 1; pub StakingPoolAccount: AccountId = get_staking_pool_account(); } @@ -62,16 +125,16 @@ impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; - type Call = Call; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type DbWeight = (); type Version = (); @@ -88,6 +151,7 @@ impl frame_system::Config for TestRuntime { parameter_types! { pub const MaxLocks: u32 = 50; pub const MaxReserves: u32 = 50; + pub const ExistentialDeposit: u64 = 1; } impl pallet_balances::Config for TestRuntime { @@ -97,26 +161,31 @@ impl pallet_balances::Config for TestRuntime { /// The type for recording an account's balance. type Balance = u64; /// The ubiquitous event type. - type Event = Event; + type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = pallet_balances::weights::SubstrateWeight; } -pub(crate) type PubConfig = pallet_tfgrid::pallet::PubConfigOf; +pub(crate) type Serial = pallet_tfgrid::pallet::SerialNumberOf; +pub(crate) type Loc = pallet_tfgrid::pallet::LocationOf; pub(crate) type Interface = pallet_tfgrid::pallet::InterfaceOf; +pub(crate) type TfgridNode = pallet_tfgrid::pallet::TfgridNode; + pub struct NodeChanged; -impl ChangeNode for NodeChanged { - fn node_changed( - _old_node: Option<&Node>, - _new_node: &Node, - ) { +impl ChangeNode for NodeChanged { + fn node_changed(_old_node: Option<&TfgridNode>, _new_node: &TfgridNode) {} + fn node_deleted(node: &TfgridNode) { + SmartContractModule::node_deleted(node); } +} - fn node_deleted(node: &Node) { - SmartContractModule::node_deleted(node); +pub struct PublicIpModifierType; +impl PublicIpModifier for PublicIpModifierType { + fn ip_removed(ip: &PublicIP) { + SmartContractModule::ip_removed(ip); } } @@ -127,48 +196,46 @@ parameter_types! { pub const MaxFarmPublicIps: u32 = 512; } +pub(crate) type TestTermsAndConditions = TermsAndConditions; + pub(crate) type TestTwinIp = TwinIp; pub(crate) type TestFarmName = FarmName; -pub(crate) type TestPublicIP = PublicIP; -pub(crate) type TestGatewayIP = GatewayIP; - -pub(crate) type TestIP4 = IP4; -pub(crate) type TestGW4 = GW4; -pub(crate) type TestIP6 = IP6; -pub(crate) type TestGW6 = GW6; -pub(crate) type TestDomain = Domain; pub(crate) type TestInterfaceName = InterfaceName; pub(crate) type TestInterfaceMac = InterfaceMac; pub(crate) type TestInterfaceIp = InterfaceIp; +pub(crate) type TestCountryName = CountryName; +pub(crate) type TestCityName = CityName; +pub(crate) type TestLocation = Location; +pub(crate) type TestSerialNumber = SerialNumber; + impl pallet_tfgrid::Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type RestrictedOrigin = EnsureRoot; type WeightInfo = pallet_tfgrid::weights::SubstrateWeight; type NodeChanged = NodeChanged; + type PublicIpModifier = PublicIpModifierType; + type TermsAndConditions = TestTermsAndConditions; type TwinIp = TestTwinIp; type FarmName = TestFarmName; type MaxFarmNameLength = MaxFarmNameLength; type MaxFarmPublicIps = MaxFarmPublicIps; - type PublicIP = TestPublicIP; - type GatewayIP = TestGatewayIP; - type IP4 = TestIP4; - type GW4 = TestGW4; - type IP6 = TestIP6; - type GW6 = TestGW6; - type Domain = TestDomain; type MaxInterfacesLength = MaxInterfacesLength; type InterfaceName = TestInterfaceName; type InterfaceMac = TestInterfaceMac; type InterfaceIP = TestInterfaceIp; type MaxInterfaceIpsLength = MaxInterfaceIpsLength; + type CountryName = TestCountryName; + type CityName = TestCityName; + type Location = TestLocation; + type SerialNumber = TestSerialNumber; } impl pallet_tft_price::Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type AuthorityId = pallet_tft_price::AuthId; - type Call = Call; + type Call = RuntimeCall; type RestrictedOrigin = EnsureRoot; } @@ -181,22 +248,25 @@ impl pallet_timestamp::Config for TestRuntime { parameter_types! { pub const BillingFrequency: u64 = 10; + pub const BillingReferencePeriod: u64 = SECS_PER_HOUR; pub const GracePeriod: u64 = 100; pub const DistributionFrequency: u16 = 24; pub const MaxNameContractNameLength: u32 = 64; pub const MaxNodeContractPublicIPs: u32 = 512; pub const MaxDeploymentDataLength: u32 = 512; + pub const SecondsPerHour: u64 = 3600; } pub(crate) type TestNameContractName = NameContractName; use weights; impl pallet_smart_contract::Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type Currency = Balances; type Burn = (); type StakingPoolAccount = StakingPoolAccount; type BillingFrequency = BillingFrequency; + type BillingReferencePeriod = BillingReferencePeriod; type DistributionFrequency = DistributionFrequency; type GracePeriod = GracePeriod; type WeightInfo = weights::SubstrateWeight; @@ -206,6 +276,86 @@ impl pallet_smart_contract::Config for TestRuntime { type RestrictedOrigin = EnsureRoot; type MaxDeploymentDataLength = MaxDeploymentDataLength; type MaxNodeContractPublicIps = MaxNodeContractPublicIPs; + type AuthorityId = pallet_smart_contract::crypto::AuthId; + type Call = RuntimeCall; + type PublicIpModifier = PublicIpModifierType; +} + +parameter_types! { + pub const UncleGenerations: u32 = 0; +} + +impl pallet_authorship::Config for TestRuntime { + type FindAuthor = (); + type UncleGenerations = UncleGenerations; + type FilterUncle = (); + type EventHandler = (); +} + +parameter_types! { + pub const Period: u32 = 60 * MINUTES; + pub const Offset: u32 = 0; +} + +thread_local! { + pub static VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); + pub static NEXT_VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); + pub static AUTHORITIES: RefCell> = + RefCell::new(vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); + pub static FORCE_SESSION_END: RefCell = RefCell::new(false); + pub static SESSION_LENGTH: RefCell = RefCell::new(2); + pub static SESSION_CHANGED: RefCell = RefCell::new(false); + pub static DISABLED: RefCell = RefCell::new(false); + pub static BEFORE_SESSION_END_CALLED: RefCell = RefCell::new(false); +} + +use pallet_session::SessionHandler; +use sp_runtime::RuntimeAppPublic; +pub struct TestSessionHandler; +impl SessionHandler for TestSessionHandler { + const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[UintAuthorityId::ID]; + fn on_genesis_session(_validators: &[(AccountId, T)]) {} + fn on_new_session( + changed: bool, + validators: &[(AccountId, T)], + _queued_validators: &[(AccountId, T)], + ) { + SESSION_CHANGED.with(|l| *l.borrow_mut() = changed); + AUTHORITIES.with(|l| { + *l.borrow_mut() = validators + .iter() + .map(|(_, id)| id.get::(DUMMY).unwrap_or_default()) + .collect() + }); + } + fn on_disabled(_validator_index: u32) { + DISABLED.with(|l| *l.borrow_mut() = true) + } + fn on_before_session_ending() { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = true); + } +} + +parameter_types! { + pub const MinAuthorities: u32 = 2; +} + +impl substrate_validator_set::Config for TestRuntime { + type AddRemoveOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type MinAuthorities = MinAuthorities; +} + +impl pallet_session::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = ::AccountId; + type ValidatorIdOf = substrate_validator_set::ValidatorOf; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionManager = (); + type SessionHandler = TestSessionHandler; + type Keys = MockSessionKeys; + type WeightInfo = (); } type AccountPublic = ::Signer; @@ -214,8 +364,40 @@ pub(crate) fn get_name_contract_name(contract_name_input: &[u8]) -> TestNameCont NameContractName::try_from(contract_name_input.to_vec()).expect("Invalid farm input.") } -pub(crate) fn get_twin_ip(twin_ip_input: &[u8]) -> TestTwinIp { - TwinIp::try_from(twin_ip_input.to_vec()).expect("Invalid twin ip input.") +pub(crate) fn get_document_link_input(document_link_input: &[u8]) -> DocumentLinkInput { + BoundedVec::try_from(document_link_input.to_vec()).expect("Invalid document link input.") +} + +pub(crate) fn get_document_hash_input(document_hash_input: &[u8]) -> DocumentHashInput { + BoundedVec::try_from(document_hash_input.to_vec()).expect("Invalid document hash input.") +} + +pub(crate) fn get_twin_ip_input(twin_ip_input: &[u8]) -> TwinIpInput { + BoundedVec::try_from(twin_ip_input.to_vec()).expect("Invalid twin ip input.") +} + +pub(crate) fn get_public_ip_ip_input(public_ip_ip_input: &[u8]) -> Ip4Input { + BoundedVec::try_from(public_ip_ip_input.to_vec()).expect("Invalid public ip (ip) input.") +} + +pub(crate) fn get_public_ip_gw_input(public_ip_gw_input: &[u8]) -> Gw4Input { + BoundedVec::try_from(public_ip_gw_input.to_vec()).expect("Invalid public ip (gw) input.") +} + +pub(crate) fn get_city_name_input(city_input: &[u8]) -> CityNameInput { + BoundedVec::try_from(city_input.to_vec()).expect("Invalid city name input.") +} + +pub(crate) fn get_country_name_input(country_input: &[u8]) -> CountryNameInput { + BoundedVec::try_from(country_input.to_vec()).expect("Invalid country name input.") +} + +pub(crate) fn get_latitude_input(latitude_input: &[u8]) -> LatitudeInput { + BoundedVec::try_from(latitude_input.to_vec()).expect("Invalid latitude input.") +} + +pub(crate) fn get_longitude_input(longitude_input: &[u8]) -> LongitudeInput { + BoundedVec::try_from(longitude_input.to_vec()).expect("Invalid longitude input.") } /// Helper function to generate a crypto pair from seed @@ -230,24 +412,24 @@ impl frame_system::offchain::SigningTypes for TestRuntime { type Signature = Signature; } -impl frame_system::offchain::SendTransactionTypes for TestRuntime +impl frame_system::offchain::SendTransactionTypes for TestRuntime where - Call: From, + RuntimeCall: From, { - type OverarchingCall = Call; + type OverarchingCall = RuntimeCall; type Extrinsic = Extrinsic; } impl frame_system::offchain::CreateSignedTransaction for TestRuntime where - Call: From, + RuntimeCall: From, { fn create_transaction>( - call: Call, + call: RuntimeCall, _public: ::Signer, _account: AccountId, nonce: u64, - ) -> Option<(Call, ::SignaturePayload)> { + ) -> Option<(RuntimeCall, ::SignaturePayload)> { Some((call, (nonce, ()))) } } @@ -289,7 +471,10 @@ pub fn get_staking_pool_account() -> AccountId { } pub fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default() + // for showing logs in tests + let _ = env_logger::try_init(); + + let mut storage = frame_system::GenesisConfig::default() .build_storage::() .unwrap(); let genesis = pallet_balances::GenesisConfig:: { @@ -299,14 +484,178 @@ pub fn new_test_ext() -> sp_io::TestExternalities { (charlie(), 150000), ], }; - genesis.assimilate_storage(&mut t).unwrap(); + genesis.assimilate_storage(&mut storage).unwrap(); + + let session_genesis = pallet_session::GenesisConfig:: { + keys: vec![(alice(), alice(), MockSessionKeys::from(UintAuthorityId(1)))], + }; + session_genesis.assimilate_storage(&mut storage).unwrap(); let genesis = pallet_tft_price::GenesisConfig:: { - allowed_origin: Some(bob()), min_tft_price: 10, max_tft_price: 1000, + _data: PhantomData, }; - genesis.assimilate_storage(&mut t).unwrap(); + genesis.assimilate_storage(&mut storage).unwrap(); + + let t = sp_io::TestExternalities::from(storage); + + t +} +pub type TransactionCall = pallet_smart_contract::Call; +pub type ExtrinsicResult = Result; + +#[derive(Default)] +pub struct PoolState { + /// A vector of calls that we expect should be executed + pub expected_calls: Vec<(TransactionCall, ExtrinsicResult, u64)>, + pub calls_to_execute: Vec<(TransactionCall, ExtrinsicResult, u64)>, + pub i: usize, +} + +impl PoolState { + pub fn should_call_bill_contract( + &mut self, + contract_id: u64, + expected_result: ExtrinsicResult, + block_number: u64, + ) { + self.expected_calls.push(( + crate::Call::bill_contract_for_block { contract_id }, + expected_result, + block_number, + )); + } + + pub fn execute_calls_and_check_results(&mut self, block_number: u64) { + if self.calls_to_execute.len() == 0 { + return; + } + + // execute the calls that were submitted to the pool and compare the result + for call_to_execute in self.calls_to_execute.iter() { + let result = match call_to_execute.0 { + // matches bill_contract_for_block + crate::Call::bill_contract_for_block { contract_id } => { + SmartContractModule::bill_contract_for_block( + RuntimeOrigin::signed(bob()), + contract_id, + ) + } + // did not match anything => unkown call => this means you should add + // a capture for that function here + _ => panic!("Unknown call!"), + }; + + // the call should return what we expect it to return + assert_eq!( + call_to_execute.1, result, + "The result of call to {:?} was not as expected!", + call_to_execute.0 + ); + + assert_eq!(block_number, call_to_execute.2); + } + + self.calls_to_execute.clear(); + } +} + +impl Drop for PoolState { + fn drop(&mut self) { + // do not panic if the thread is already panicking! + if !thread::panicking() && self.i < self.expected_calls.len() { + panic!("\nNot all expected calls have been executed! The following calls were still expected: {:?}\n", &self.expected_calls[self.i..]); + } + } +} + +/// Implementation of mocked transaction pool used for testing +/// +/// This transaction pool mocks submitting the transactions to the pool. It does +/// not execute the transactions. Instead it keeps them in list. It does compare +/// the submitted call to the expected call. +#[derive(Default)] +pub struct MockedTransactionPoolExt(Arc>); + +impl MockedTransactionPoolExt { + /// Create new `TestTransactionPoolExt` and a reference to the internal state. + pub fn new() -> (Self, Arc>) { + let ext = Self::default(); + let state = ext.0.clone(); + (ext, state) + } +} + +impl TransactionPool for MockedTransactionPoolExt { + fn submit_transaction(&mut self, extrinsic: Vec) -> Result<(), ()> { + if self.0.read().expected_calls.is_empty() { + return Ok(()); + } + + let extrinsic_decoded: Extrinsic = match Decode::decode(&mut &*extrinsic) { + Ok(xt) => xt, + Err(e) => { + log::error!("Unable to decode extrinsic: {:?}: {}", extrinsic, e); + return Err(()); + } + }; + + if self.0.read().i < self.0.read().expected_calls.len() { + let i = self.0.read().i.clone(); + + log::debug!("Call {:?}: {:?}", i, extrinsic_decoded.call); + // the extrinsic should match the expected call at position i + if extrinsic_decoded.call + != RuntimeCall::SmartContractModule(self.0.read().expected_calls[i].0.clone()) + { + panic!( + "\nEXPECTED call: {:?}\nACTUAL call: {:?}\n", + self.0.read().expected_calls[i].0, + extrinsic_decoded.call + ); + } + + // increment i for the next iteration + let call_to_execute = self.0.read().expected_calls[i].clone(); + // we push the call to be executed later in the "test thread" + self.0.write().calls_to_execute.push(call_to_execute); + self.0.write().i = i + 1; + + // return the expected return value + return self.0.read().expected_calls[i] + .1 + .map_err(|_| ()) + .map(|_| ()); + } + + // we should not end here as it would mean we did not expect any more calls + panic!( + "\nDid not expect any more calls! Still have the call {:?} left.\n", + extrinsic_decoded.call + ); + } +} + +pub fn new_test_ext_with_pool_state( + iterations: u32, +) -> (sp_io::TestExternalities, Arc>) { + let mut ext = new_test_ext(); + let (offchain, offchain_state) = testing::TestOffchainExt::new(); + let (pool, pool_state) = MockedTransactionPoolExt::new(); + let keystore = KeyStore::new(); + keystore + .sr25519_generate_new(KEY_TYPE, Some(&format!("//Alice"))) + .unwrap(); + + let mut seed = [0_u8; 32]; + seed[0..4].copy_from_slice(&iterations.to_le_bytes()); + offchain_state.write().seed = seed; + + ext.register_extension(OffchainWorkerExt::new(offchain.clone())); + ext.register_extension(OffchainDbExt::new(offchain)); + ext.register_extension(TransactionPoolExt::new(pool)); + ext.register_extension(KeystoreExt(Arc::new(keystore))); - t.into() + (ext, pool_state) } diff --git a/substrate-node/pallets/pallet-smart-contract/src/name_contract.rs b/substrate-node/pallets/pallet-smart-contract/src/name_contract.rs index 89ea72a6a..61591f728 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/name_contract.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/name_contract.rs @@ -27,20 +27,23 @@ impl TryFrom> for NameContractName { fn try_from(value: Vec) -> Result { ensure!( value.len() >= MIN_NAME_LENGTH as usize, - Self::Error::NameContractNameToShort + Self::Error::NameContractNameTooShort ); let bounded_vec: BoundedVec = - BoundedVec::try_from(value).map_err(|_| Self::Error::NameContractNameToLong)?; - ensure!(is_valid_name_contract_name(&bounded_vec), Self::Error::NameNotValid); + BoundedVec::try_from(value).map_err(|_| Self::Error::NameContractNameTooLong)?; + ensure!( + is_valid_name_contract_name(&bounded_vec), + Self::Error::NameNotValid + ); Ok(Self(bounded_vec, PhantomData)) } } /// Verify that a given slice can be used as a name contract name. fn is_valid_name_contract_name(input: &[u8]) -> bool { - input - .iter() - .all(|c| matches!(c, b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_')) + input + .iter() + .all(|c| matches!(c, b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_')) } // FIXME: did not find a way to automatically implement this. diff --git a/substrate-node/pallets/pallet-smart-contract/src/test_utils.rs b/substrate-node/pallets/pallet-smart-contract/src/test_utils.rs new file mode 100644 index 000000000..a2b0b7580 --- /dev/null +++ b/substrate-node/pallets/pallet-smart-contract/src/test_utils.rs @@ -0,0 +1,24 @@ +use crate::mock::{PoolState, SmartContractModule, System, Timestamp}; + +use codec::alloc::sync::Arc; +use frame_support::traits::Hooks; +use parking_lot::RwLock; + +pub fn run_to_block(n: u64, pool_state: Option<&mut Arc>>) { + Timestamp::set_timestamp((1628082000 * 1000) + (6000 * n)); + while System::block_number() <= n { + SmartContractModule::offchain_worker(System::block_number()); + SmartContractModule::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + if pool_state.is_some() { + pool_state + .as_ref() + .unwrap() + .write() + .execute_calls_and_check_results(System::block_number() as u64); + } + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + SmartContractModule::on_initialize(System::block_number()); + } +} diff --git a/substrate-node/pallets/pallet-smart-contract/src/tests.rs b/substrate-node/pallets/pallet-smart-contract/src/tests.rs index d126650c4..cfba1b161 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/tests.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/tests.rs @@ -1,22 +1,33 @@ -use super::Event as SmartContractEvent; -use crate::{mock::Event as MockEvent, mock::*, Error}; +use super::{types, Event as SmartContractEvent}; +use crate::cost; +use crate::types::HexHash; +use crate::{mock::RuntimeEvent as MockEvent, mock::*, test_utils::*, Error}; use frame_support::{ assert_noop, assert_ok, bounded_vec, - traits::{LockableCurrency, OnFinalize, OnInitialize, WithdrawReasons}, + dispatch::Pays, + traits::{LockableCurrency, WithdrawReasons}, BoundedVec, }; use frame_system::{EventRecord, Phase, RawOrigin}; +use log::info; +use pallet_tfgrid::{ + types::{self as pallet_tfgrid_types, LocationInput}, + ResourcesInput, +}; use sp_core::H256; use sp_runtime::{assert_eq_error_rate, traits::SaturatedConversion, Perbill, Percent}; -use substrate_fixed::types::U64F64; - -use super::types; -use crate::cost; -use pallet_tfgrid::types as pallet_tfgrid_types; use sp_std::convert::{TryFrom, TryInto}; -use tfchain_support::types::{FarmCertification, Location, NodeCertification, PublicIP, Resources}; +use substrate_fixed::types::U64F64; +use tfchain_support::constants::time::SECS_PER_HOUR; +use tfchain_support::{ + resources::Resources, + types::{FarmCertification, NodeCertification, PublicIP, IP4}, +}; const GIGABYTE: u64 = 1024 * 1024 * 1024; +const BASE_FEE: u64 = 1000; +const VARIABLE_FEE: u64 = 1000; +const VARIABLE_AMOUNT: u64 = 100; // NODE CONTRACT TESTS // // -------------------- // @@ -24,10 +35,11 @@ const GIGABYTE: u64 = 1024 * 1024 * 1024; #[test] fn test_create_node_contract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -40,10 +52,11 @@ fn test_create_node_contract_works() { #[test] fn test_create_node_contract_with_public_ips_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -61,14 +74,14 @@ fn test_create_node_contract_with_public_ips_works() { assert_eq!(c.public_ips, 2); let pub_ip = PublicIP { - ip: "185.206.122.33/24".as_bytes().to_vec().try_into().unwrap(), - gateway: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), + ip: get_public_ip_ip_input(b"185.206.122.33/24"), + gateway: get_public_ip_gw_input(b"185.206.122.1"), contract_id: 1, }; let pub_ip_2 = PublicIP { - ip: "185.206.122.34/24".as_bytes().to_vec().try_into().unwrap(), - gateway: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), + ip: get_public_ip_ip_input(b"185.206.122.34/24"), + gateway: get_public_ip_gw_input(b"185.206.122.1"), contract_id: 1, }; assert_eq!(c.public_ips_list[0], pub_ip); @@ -82,11 +95,12 @@ fn test_create_node_contract_with_public_ips_works() { #[test] fn test_create_node_contract_with_undefined_node_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_noop!( SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 2, generate_deployment_hash(), get_deployment_data(), @@ -101,11 +115,12 @@ fn test_create_node_contract_with_undefined_node_fails() { #[test] fn test_create_node_contract_with_same_hash_and_node_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); let h = generate_deployment_hash(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, h, get_deployment_data(), @@ -115,7 +130,7 @@ fn test_create_node_contract_with_same_hash_and_node_fails() { assert_noop!( SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, h, get_deployment_data(), @@ -130,11 +145,12 @@ fn test_create_node_contract_with_same_hash_and_node_fails() { #[test] fn test_create_node_contract_which_was_canceled_before_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); let h = generate_deployment_hash(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, h, get_deployment_data(), @@ -145,13 +161,13 @@ fn test_create_node_contract_which_was_canceled_before_works() { assert_eq!(contract_id, 1); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1 )); let h = generate_deployment_hash(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, h, get_deployment_data(), @@ -166,10 +182,11 @@ fn test_create_node_contract_which_was_canceled_before_works() { #[test] fn test_update_node_contract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -180,7 +197,7 @@ fn test_update_node_contract_works() { let new_hash = generate_deployment_hash(); let deployment_data = get_deployment_data(); assert_ok!(SmartContractModule::update_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, new_hash, get_deployment_data() @@ -191,7 +208,7 @@ fn test_update_node_contract_works() { deployment_hash: new_hash, deployment_data, public_ips: 0, - public_ips_list: Vec::new().try_into().unwrap(), + public_ips_list: bounded_vec![], }; let contract_type = types::ContractData::NodeContract(node_contract); @@ -220,11 +237,12 @@ fn test_update_node_contract_works() { #[test] fn test_update_node_contract_not_exists_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_noop!( SmartContractModule::update_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data() @@ -237,10 +255,11 @@ fn test_update_node_contract_not_exists_fails() { #[test] fn test_update_node_contract_wrong_twins_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -250,7 +269,7 @@ fn test_update_node_contract_wrong_twins_fails() { assert_noop!( SmartContractModule::update_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data() @@ -263,10 +282,11 @@ fn test_update_node_contract_wrong_twins_fails() { #[test] fn test_cancel_node_contract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -275,7 +295,7 @@ fn test_cancel_node_contract_works() { )); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1 )); @@ -290,10 +310,11 @@ fn test_cancel_node_contract_works() { #[test] fn test_create_multiple_node_contracts_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -302,7 +323,7 @@ fn test_create_multiple_node_contracts_works() { )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -311,7 +332,7 @@ fn test_create_multiple_node_contracts_works() { )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -324,7 +345,7 @@ fn test_create_multiple_node_contracts_works() { // now cancel 1 and check if the storage maps are updated correctly assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1 )); @@ -336,9 +357,10 @@ fn test_create_multiple_node_contracts_works() { #[test] fn test_cancel_node_contract_frees_public_ips_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -351,7 +373,7 @@ fn test_cancel_node_contract_frees_public_ips_works() { assert_eq!(farm.public_ips[1].contract_id, 1); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1 )); @@ -367,7 +389,7 @@ fn test_cancel_node_contract_not_exists_fails() { prepare_farm_and_node(); assert_noop!( - SmartContractModule::cancel_contract(Origin::signed(alice()), 1), + SmartContractModule::cancel_contract(RuntimeOrigin::signed(alice()), 1), Error::::ContractNotExists ); }); @@ -376,10 +398,11 @@ fn test_cancel_node_contract_not_exists_fails() { #[test] fn test_cancel_node_contract_wrong_twins_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -388,7 +411,7 @@ fn test_cancel_node_contract_wrong_twins_fails() { )); assert_noop!( - SmartContractModule::cancel_contract(Origin::signed(bob()), 1), + SmartContractModule::cancel_contract(RuntimeOrigin::signed(bob()), 1), Error::::TwinNotAuthorizedToCancelContract ); }); @@ -400,10 +423,11 @@ fn test_cancel_node_contract_wrong_twins_fails() { #[test] fn test_create_name_contract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_name_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), "foobar".as_bytes().to_vec() )); }); @@ -412,15 +436,16 @@ fn test_create_name_contract_works() { #[test] fn test_cancel_name_contract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_name_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "some_name".as_bytes().to_vec() )); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1 )); @@ -437,15 +462,16 @@ fn test_cancel_name_contract_works() { #[test] fn test_create_name_contract_double_with_same_name_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_name_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), "foobar".as_bytes().to_vec() )); assert_noop!( SmartContractModule::create_name_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "foobar".as_bytes().to_vec() ), Error::::NameExists @@ -456,20 +482,21 @@ fn test_create_name_contract_double_with_same_name_fails() { #[test] fn test_recreate_name_contract_after_cancel_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_name_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), "foobar".as_bytes().to_vec() )); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1 )); assert_ok!(SmartContractModule::create_name_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), "foobar".as_bytes().to_vec() )); }); @@ -478,11 +505,12 @@ fn test_recreate_name_contract_after_cancel_works() { #[test] fn test_create_name_contract_with_invalid_dns_name_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_noop!( SmartContractModule::create_name_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "foo.bar".as_bytes().to_vec() ), Error::::NameNotValid @@ -490,7 +518,7 @@ fn test_create_name_contract_with_invalid_dns_name_fails() { assert_noop!( SmartContractModule::create_name_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "foo!".as_bytes().to_vec() ), Error::::NameNotValid @@ -498,7 +526,7 @@ fn test_create_name_contract_with_invalid_dns_name_fails() { assert_noop!( SmartContractModule::create_name_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "foo;'".as_bytes().to_vec() ), Error::::NameNotValid @@ -506,7 +534,7 @@ fn test_create_name_contract_with_invalid_dns_name_fails() { assert_noop!( SmartContractModule::create_name_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "foo123.%".as_bytes().to_vec() ), Error::::NameNotValid @@ -520,11 +548,12 @@ fn test_create_name_contract_with_invalid_dns_name_fails() { #[test] fn test_create_rent_contract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_dedicated_farm_and_node(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); @@ -541,11 +570,12 @@ fn test_create_rent_contract_works() { #[test] fn test_cancel_rent_contract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_dedicated_farm_and_node(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); @@ -558,7 +588,7 @@ fn test_cancel_rent_contract_works() { ); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1 )); @@ -570,10 +600,11 @@ fn test_cancel_rent_contract_works() { #[test] fn test_create_rent_contract_on_node_in_use_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -582,7 +613,7 @@ fn test_create_rent_contract_on_node_in_use_fails() { )); assert_noop!( - SmartContractModule::create_rent_contract(Origin::signed(bob()), 1, None), + SmartContractModule::create_rent_contract(RuntimeOrigin::signed(bob()), 1, None), Error::::NodeNotAvailableToDeploy ); }) @@ -591,11 +622,12 @@ fn test_create_rent_contract_on_node_in_use_fails() { #[test] fn test_create_rent_contract_non_dedicated_empty_node_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); @@ -605,11 +637,12 @@ fn test_create_rent_contract_non_dedicated_empty_node_works() { #[test] fn test_create_node_contract_on_dedicated_node_without_rent_contract_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_dedicated_farm_and_node(); assert_noop!( SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -624,16 +657,17 @@ fn test_create_node_contract_on_dedicated_node_without_rent_contract_fails() { #[test] fn test_create_node_contract_when_having_a_rentcontract_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_dedicated_farm_and_node(); assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -646,11 +680,12 @@ fn test_create_node_contract_when_having_a_rentcontract_works() { #[test] fn test_create_node_contract_when_someone_else_has_rent_contract_fails() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_dedicated_farm_and_node(); // create rent contract with bob assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, None )); @@ -659,7 +694,7 @@ fn test_create_node_contract_when_someone_else_has_rent_contract_fails() { // Alice not the owner of the rent contract so she is unauthorized to deploy a node contract assert_noop!( SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -673,20 +708,21 @@ fn test_create_node_contract_when_someone_else_has_rent_contract_fails() { #[test] fn test_cancel_rent_contract_with_active_node_contracts_fails() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -695,7 +731,7 @@ fn test_cancel_rent_contract_with_active_node_contracts_fails() { )); assert_noop!( - SmartContractModule::cancel_contract(Origin::signed(bob()), 1,), + SmartContractModule::cancel_contract(RuntimeOrigin::signed(bob()), 1,), Error::::NodeHasActiveContracts ); }); @@ -706,16 +742,17 @@ fn test_cancel_rent_contract_with_active_node_contracts_fails() { #[test] fn test_node_contract_billing_details() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(0); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let twin = TfgridModule::twins(2).unwrap(); let initial_twin_balance = Balances::free_balance(&twin.account_id); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -727,25 +764,26 @@ fn test_node_contract_billing_details() { push_nru_report_for_contract(1, 10); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(10); + let contract_to_bill = SmartContractModule::contract_to_bill_at_block(1); assert_eq!(contract_to_bill, [1]); let initial_total_issuance = Balances::total_issuance(); // advance 25 cycles - let mut i = 0; - while i != 24 { - i += 1; - run_to_block(i * 10 + 1); + for i in 0..25 { + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11 + i * 10); + run_to_block(11 + i * 10, Some(&mut pool_state)); } let free_balance = Balances::free_balance(&twin.account_id); let total_amount_billed = initial_twin_balance - free_balance; - println!("locked balance {:?}", total_amount_billed); + info!("locked balance {:?}", total_amount_billed); - println!("total locked balance {:?}", total_amount_billed); + info!("total locked balance {:?}", total_amount_billed); let staking_pool_account_balance = Balances::free_balance(&get_staking_pool_account()); - println!( + info!( "staking pool account balance, {:?}", staking_pool_account_balance ); @@ -774,9 +812,10 @@ fn test_node_contract_billing_details() { let total_issuance = Balances::total_issuance(); // total issueance is now previous total - amount burned from contract billed (35%) let burned_amount = Perbill::from_percent(35) * total_amount_billed; - assert_eq!( + assert_eq_error_rate!( total_issuance, - initial_total_issuance - burned_amount as u64 + initial_total_issuance - burned_amount as u64, + 1 ); // amount unbilled should have been reset after a transfer between contract owner and farmer @@ -787,20 +826,21 @@ fn test_node_contract_billing_details() { #[test] fn test_node_contract_billing_details_with_solution_provider() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); prepare_solution_provider(); - run_to_block(0); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let twin = TfgridModule::twins(2).unwrap(); let initial_twin_balance = Balances::free_balance(&twin.account_id); let initial_total_issuance = Balances::total_issuance(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -812,18 +852,19 @@ fn test_node_contract_billing_details_with_solution_provider() { push_nru_report_for_contract(1, 10); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(10); + let contract_to_bill = SmartContractModule::contract_to_bill_at_block(1); assert_eq!(contract_to_bill, [1]); // advance 25 cycles - let mut i = 0; - while i != 24 { - i += 1; - run_to_block(i * 10 + 1); + for i in 0..25 { + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11 + i * 10); + run_to_block(11 + i * 10, Some(&mut pool_state)); } - let usable_balance = Balances::usable_balance(&twin.account_id); - let total_amount_billed = initial_twin_balance - usable_balance; + let free_balance = Balances::free_balance(&twin.account_id); + let total_amount_billed = initial_twin_balance - free_balance; validate_distribution_rewards(initial_total_issuance, total_amount_billed, true); @@ -835,13 +876,14 @@ fn test_node_contract_billing_details_with_solution_provider() { #[test] fn test_multiple_contracts_billing_loop_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -849,14 +891,21 @@ fn test_multiple_contracts_billing_loop_works() { None )); assert_ok!(SmartContractModule::create_name_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), "some_name".as_bytes().to_vec(), )); - let contract_to_bill_at_block = SmartContractModule::contract_to_bill_at_block(11); - assert_eq!(contract_to_bill_at_block.len(), 2); + let contracts_to_bill_at_block = SmartContractModule::contract_to_bill_at_block(1); + assert_eq!(contracts_to_bill_at_block.len(), 2); - run_to_block(12); + // 2 contracts => 2 billings + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); // Test that the expected events were emitted let our_events = System::events(); @@ -871,13 +920,14 @@ fn test_multiple_contracts_billing_loop_works() { #[test] fn test_node_contract_billing_cycles() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -889,9 +939,12 @@ fn test_node_contract_billing_cycles() { push_contract_resources_used(1); - let (amount_due_1, discount_received) = calculate_tft_cost(contract_id, twin_id, 11); - run_to_block(12); - check_report_cost(1, amount_due_1, 12, discount_received); + let (amount_due_1, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); + check_report_cost(1, amount_due_1, 11, discount_received); let twin = TfgridModule::twins(twin_id).unwrap(); let usable_balance = Balances::usable_balance(&twin.account_id); @@ -904,12 +957,18 @@ fn test_node_contract_billing_cycles() { ); let (amount_due_2, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(22); - check_report_cost(1, amount_due_2, 22, discount_received); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21); + run_to_block(21, Some(&mut pool_state)); + check_report_cost(1, amount_due_2, 21, discount_received); let (amount_due_3, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(32); - check_report_cost(1, amount_due_3, 32, discount_received); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 31); + run_to_block(31, Some(&mut pool_state)); + check_report_cost(1, amount_due_3, 31, discount_received); let twin = TfgridModule::twins(twin_id).unwrap(); let usable_balance = Balances::usable_balance(&twin.account_id); @@ -925,13 +984,14 @@ fn test_node_contract_billing_cycles() { #[test] fn test_node_multiple_contract_billing_cycles() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -939,7 +999,7 @@ fn test_node_multiple_contract_billing_cycles() { None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -948,15 +1008,21 @@ fn test_node_multiple_contract_billing_cycles() { )); let twin_id = 2; + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 11); push_contract_resources_used(1); push_contract_resources_used(2); let (amount_due_contract_1, discount_received) = calculate_tft_cost(1, twin_id, 11); - run_to_block(12); + run_to_block(12, Some(&mut pool_state)); check_report_cost(1, amount_due_contract_1, 12, discount_received); let (amount_due_contract_2, discount_received) = calculate_tft_cost(2, twin_id, 11); - run_to_block(12); + run_to_block(12, Some(&mut pool_state)); check_report_cost(2, amount_due_contract_2, 12, discount_received); let twin = TfgridModule::twins(twin_id).unwrap(); @@ -973,13 +1039,14 @@ fn test_node_multiple_contract_billing_cycles() { #[test] fn test_node_contract_billing_cycles_delete_node_cancels_contract() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -989,53 +1056,56 @@ fn test_node_contract_billing_cycles_delete_node_cancels_contract() { let contract_id = 1; let twin_id = 2; + for i in 0..5 { + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11 + i * 10); + } push_contract_resources_used(1); - let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 11); - run_to_block(12); - check_report_cost(1, amount_due_as_u128, 12, discount_received); + let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); + run_to_block(11, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 11, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(22); - check_report_cost(1, amount_due_as_u128, 22, discount_received); + run_to_block(21, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 21, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(32); - check_report_cost(1, amount_due_as_u128, 32, discount_received); + run_to_block(31, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 31, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(42); - check_report_cost(1, amount_due_as_u128, 42, discount_received); + run_to_block(41, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 41, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(52); - check_report_cost(1, amount_due_as_u128, 52, discount_received); + run_to_block(51, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 51, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 4); - run_to_block(56); + run_to_block(55, None); // Delete node - TfgridModule::delete_node_farm(Origin::signed(alice()), 1).unwrap(); + TfgridModule::delete_node_farm(RuntimeOrigin::signed(alice()), 1).unwrap(); // After deleting a node, the contract gets billed before it's canceled - check_report_cost(1, amount_due_as_u128, 56, discount_received); + check_report_cost(1, amount_due_as_u128, 55, discount_received); let our_events = System::events(); for e in our_events.clone().iter() { - println!("{:?}", e); + info!("{:?}", e); } let public_ip = PublicIP { - ip: "185.206.122.33/24".as_bytes().to_vec().try_into().unwrap(), - gateway: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), + ip: get_public_ip_ip_input(b"185.206.122.33/24"), + gateway: get_public_ip_gw_input(b"185.206.122.1"), contract_id: 0, }; - let mut ips: BoundedVec< - PublicIP, - crate::MaxNodeContractPublicIPs, - > = vec![].try_into().unwrap(); + let mut ips: BoundedVec> = + vec![].try_into().unwrap(); ips.try_push(public_ip).unwrap(); assert_eq!( @@ -1062,13 +1132,14 @@ fn test_node_contract_billing_cycles_delete_node_cancels_contract() { #[test] fn test_node_contract_only_public_ip_billing_cycles() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1078,38 +1149,47 @@ fn test_node_contract_only_public_ip_billing_cycles() { let contract_id = 1; let twin_id = 2; - let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 11); + for i in 0..5 { + pool_state.write().should_call_bill_contract( + contract_id, + Ok(Pays::Yes.into()), + 11 + i * 10, + ); + } + + let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); assert_ne!(amount_due_as_u128, 0); - run_to_block(12); - check_report_cost(1, amount_due_as_u128, 12, discount_received); + run_to_block(11, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 11, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(22); - check_report_cost(1, amount_due_as_u128, 22, discount_received); + run_to_block(21, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 21, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(32); - check_report_cost(1, amount_due_as_u128, 32, discount_received); + run_to_block(31, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 31, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(42); - check_report_cost(1, amount_due_as_u128, 42, discount_received); + run_to_block(41, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 41, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(52); - check_report_cost(1, amount_due_as_u128, 52, discount_received); + run_to_block(51, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 51, discount_received); }); } #[test] fn test_node_contract_billing_cycles_cancel_contract_during_cycle_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1120,24 +1200,32 @@ fn test_node_contract_billing_cycles_cancel_contract_during_cycle_works() { let contract_id = 1; let twin_id = 2; + // 2 cycles for billing + for i in 0..2 { + pool_state.write().should_call_bill_contract( + contract_id, + Ok(Pays::Yes.into()), + 11 + i * 10, + ); + } push_contract_resources_used(1); - let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 11); - run_to_block(12); - check_report_cost(1, amount_due_as_u128, 12, discount_received); + let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); + run_to_block(11, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 11, discount_received); let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(22); - check_report_cost(1, amount_due_as_u128, 22, discount_received); + run_to_block(21, Some(&mut pool_state)); + check_report_cost(1, amount_due_as_u128, 21, discount_received); - run_to_block(28); - let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 6); + run_to_block(28, Some(&mut pool_state)); + let (amount_due_as_u128, discount_received) = calculate_tft_cost(contract_id, twin_id, 7); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1 )); - run_to_block(29); + run_to_block(29, Some(&mut pool_state)); check_report_cost(1, amount_due_as_u128, 28, discount_received); let contract = SmartContractModule::contracts(1); @@ -1148,20 +1236,62 @@ fn test_node_contract_billing_cycles_cancel_contract_during_cycle_works() { }); } +#[test] +fn test_node_contract_billing_fails() { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { + run_to_block(1, Some(&mut pool_state)); + // Creates a farm and node and sets the price of tft to 0 which raises an error later + prepare_farm_and_node(); + + assert_ok!(SmartContractModule::create_node_contract( + RuntimeOrigin::signed(bob()), + 1, + generate_deployment_hash(), + get_deployment_data(), + 1, + None + )); + + let contracts_to_bill_at_block = SmartContractModule::contract_to_bill_at_block(1); + assert_eq!(contracts_to_bill_at_block.len(), 1); + + let contract_id = contracts_to_bill_at_block[0]; + + // delete twin to make the billing fail + assert_ok!(TfgridModule::delete_twin( + RuntimeOrigin::signed(bob()), + SmartContractModule::contracts(contract_id).unwrap().twin_id, + )); + + // the offchain worker should save the failed ids in local storage and try again + // in subsequent blocks (which will also fail) + for i in 1..3 { + pool_state.write().should_call_bill_contract( + 1, + Err(Error::::TwinNotExists.into()), + 1 + i * 10, + ); + run_to_block(11 * i, Some(&mut pool_state)); + } + }); +} + #[test] fn test_node_contract_billing_cycles_cancel_contract_during_cycle_without_balance_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let twin = TfgridModule::twins(2).unwrap(); let initial_twin_balance = Balances::free_balance(&twin.account_id); - println!("initial twin balance: {:?}", initial_twin_balance); + info!("initial twin balance: {:?}", initial_twin_balance); let initial_total_issuance = Balances::total_issuance(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1174,23 +1304,29 @@ fn test_node_contract_billing_cycles_cancel_contract_during_cycle_without_balanc push_contract_resources_used(1); - let (amount_due_1, discount_received) = calculate_tft_cost(contract_id, twin_id, 11); - run_to_block(12); - check_report_cost(1, amount_due_1, 12, discount_received); + let (amount_due_1, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); + pool_state + .write() + .should_call_bill_contract(contract_id, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); + check_report_cost(1, amount_due_1, 11, discount_received); let (amount_due_2, discount_received) = calculate_tft_cost(contract_id, twin_id, 10); - run_to_block(22); - check_report_cost(1, amount_due_2, 22, discount_received); + pool_state + .write() + .should_call_bill_contract(contract_id, Ok(Pays::Yes.into()), 21); + run_to_block(21, Some(&mut pool_state)); + check_report_cost(1, amount_due_2, 21, discount_received); // Run halfway ish next cycle and cancel - run_to_block(25); + run_to_block(25, Some(&mut pool_state)); let usable_balance = Balances::usable_balance(&twin.account_id); let total_amount_billed = initial_twin_balance - usable_balance; let extrinsic_fee = 10000; Balances::transfer( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), alice(), initial_twin_balance - total_amount_billed - extrinsic_fee, ) @@ -1200,11 +1336,14 @@ fn test_node_contract_billing_cycles_cancel_contract_during_cycle_without_balanc assert_ne!(usable_balance_before_canceling, 0); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1 )); - run_to_block(29); + pool_state + .write() + .should_call_bill_contract(contract_id, Ok(Pays::Yes.into()), 31); + run_to_block(31, Some(&mut pool_state)); // After canceling contract, and not being able to pay for the remainder of the cycle // where the cancel was excecuted, the remaining balance should still be the same @@ -1220,13 +1359,14 @@ fn test_node_contract_billing_cycles_cancel_contract_during_cycle_without_balanc #[test] fn test_node_contract_out_of_funds_should_move_state_to_graceperiod_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1237,11 +1377,17 @@ fn test_node_contract_out_of_funds_should_move_state_to_graceperiod_works() { push_contract_resources_used(1); // cycle 1 - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); // cycle 2 // user does not have enough funds to pay for 2 cycles - run_to_block(22); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21); + run_to_block(21, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::GracePeriod(21)); @@ -1263,13 +1409,14 @@ fn test_node_contract_out_of_funds_should_move_state_to_graceperiod_works() { #[test] fn test_restore_node_contract_in_grace_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1277,14 +1424,19 @@ fn test_restore_node_contract_in_grace_works() { None )); + for i in 0..6 { + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11 + i * 10); + } push_contract_resources_used(1); // cycle 1 - run_to_block(12); + run_to_block(11, Some(&mut pool_state)); // cycle 2 // user does not have enough funds to pay for 2 cycles - run_to_block(22); + run_to_block(21, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::GracePeriod(21)); @@ -1302,24 +1454,12 @@ fn test_restore_node_contract_in_grace_works() { true ); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(31); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(32); - - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(41); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(42); - + run_to_block(31, Some(&mut pool_state)); + run_to_block(41, Some(&mut pool_state)); // Transfer some balance to the owner of the contract to trigger the grace period to stop - Balances::transfer(Origin::signed(bob()), charlie(), 100000000).unwrap(); - - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(51); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(52); - - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(61); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(62); + Balances::transfer(RuntimeOrigin::signed(bob()), charlie(), 100000000).unwrap(); + run_to_block(52, Some(&mut pool_state)); + run_to_block(62, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::Created); @@ -1328,14 +1468,17 @@ fn test_restore_node_contract_in_grace_works() { #[test] fn test_node_contract_grace_period_cancels_contract_when_grace_period_ends_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); + let twin = TfgridModule::twins(3).unwrap(); let initial_total_issuance = Balances::total_issuance(); + let initial_twin_balance = Balances::free_balance(&twin.account_id); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1346,11 +1489,17 @@ fn test_node_contract_grace_period_cancels_contract_when_grace_period_ends_works push_contract_resources_used(1); // cycle 1 - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); // cycle 2 // user does not have enough funds to pay for 2 cycles - run_to_block(22); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21); + run_to_block(21, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::GracePeriod(21)); @@ -1368,23 +1517,27 @@ fn test_node_contract_grace_period_cancels_contract_when_grace_period_ends_works true ); - let twin = TfgridModule::twins(3).unwrap(); - let free_balance = Balances::free_balance(&twin.account_id); + // grace period stops after 100 blocknumbers, so after 121 + for i in 1..11 { + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21 + i * 10); + } - run_to_block(32); - run_to_block(42); - run_to_block(52); - run_to_block(62); - run_to_block(72); - run_to_block(82); - run_to_block(92); - run_to_block(102); - run_to_block(112); - run_to_block(122); - run_to_block(132); + for i in 1..11 { + run_to_block(21 + i * 10, Some(&mut pool_state)); + } + + // pool_state + // .write() + // .should_call_bill_contract(1, Ok(Pays::Yes.into()), 131); + // run_to_block(131, Some(&mut pool_state)); // The user's total free balance should be distributed - validate_distribution_rewards(initial_total_issuance, free_balance, false); + let free_balance = Balances::free_balance(&twin.account_id); + let total_amount_billed = initial_twin_balance - free_balance; + + validate_distribution_rewards(initial_total_issuance, total_amount_billed, false); let c1 = SmartContractModule::contracts(1); assert_eq!(c1, None); @@ -1393,32 +1546,36 @@ fn test_node_contract_grace_period_cancels_contract_when_grace_period_ends_works #[test] fn test_name_contract_billing() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); assert_ok!(SmartContractModule::create_name_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), "foobar".as_bytes().to_vec() )); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(11); - assert_eq!(contract_to_bill, [1]); + let contracts_to_bill = SmartContractModule::contract_to_bill_at_block(1); + assert_eq!(contracts_to_bill, [1]); // let mature 11 blocks // because we bill every 10 blocks - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); + // the contractbill event should look like: let contract_bill_event = types::ContractBill { contract_id: 1, - timestamp: 1628082072, + timestamp: 1628082066, discount_level: types::DiscountLevel::Gold, - amount_billed: 2032, + amount_billed: 1848, }; - let our_events = System::events(); - println!("events: {:?}", our_events.clone()); + info!("events: {:?}", our_events.clone()); assert_eq!( our_events[3], record(MockEvent::SmartContractModule(SmartContractEvent::< @@ -1432,14 +1589,15 @@ fn test_name_contract_billing() { #[test] fn test_rent_contract_billing() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); @@ -1451,24 +1609,28 @@ fn test_rent_contract_billing() { types::ContractData::RentContract(rent_contract) ); - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); - let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 11); + let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 10); assert_ne!(amount_due_as_u128, 0); - check_report_cost(1, amount_due_as_u128, 12, discount_received); + check_report_cost(1, amount_due_as_u128, 11, discount_received); }); } #[test] fn test_rent_contract_billing_cancel_should_bill_reserved_balance() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); @@ -1480,35 +1642,47 @@ fn test_rent_contract_billing_cancel_should_bill_reserved_balance() { types::ContractData::RentContract(rent_contract) ); - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); - let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 11); + let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 10); assert_ne!(amount_due_as_u128, 0); - check_report_cost(1, amount_due_as_u128, 12, discount_received.clone()); + check_report_cost(1, amount_due_as_u128, 11, discount_received.clone()); let twin = TfgridModule::twins(2).unwrap(); let usable_balance = Balances::usable_balance(&twin.account_id); let free_balance = Balances::free_balance(&twin.account_id); assert_ne!(usable_balance, free_balance); - run_to_block(14); + run_to_block(13, Some(&mut pool_state)); // cancel contract + // it will bill before removing the contract and it should bill all + // reserverd balance let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 2); assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1 )); let twin = TfgridModule::twins(2).unwrap(); let usable_balance = Balances::usable_balance(&twin.account_id); assert_ne!(usable_balance, 0); - Balances::transfer(Origin::signed(bob()), alice(), usable_balance).unwrap(); + Balances::transfer(RuntimeOrigin::signed(bob()), alice(), usable_balance).unwrap(); - run_to_block(22); + // we do not call bill contract here as the contract is removed during + // cancel_contract. The contract id will still be in ContractsToBillAt + // but the contract itself will no longer exist + // But the + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21); + run_to_block(22, Some(&mut pool_state)); // Last amount due is the same as the first one assert_ne!(amount_due_as_u128, 0); - check_report_cost(1, amount_due_as_u128, 14, discount_received); + check_report_cost(1, amount_due_as_u128, 13, discount_received); let usable_balance = Balances::usable_balance(&twin.account_id); let free_balance = Balances::free_balance(&twin.account_id); @@ -1518,14 +1692,15 @@ fn test_rent_contract_billing_cancel_should_bill_reserved_balance() { #[test] fn test_rent_contract_canceled_mid_cycle_should_bill_for_remainder() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); @@ -1542,14 +1717,14 @@ fn test_rent_contract_canceled_mid_cycle_should_bill_for_remainder() { let free_balance = Balances::free_balance(&twin.account_id); let locked_balance = free_balance - usable_balance; - println!("locked balance: {:?}", locked_balance); + info!("locked balance: {:?}", locked_balance); - run_to_block(8); + run_to_block(8, Some(&mut pool_state)); // Calculate the cost for 7 blocks of runtime (created a block 1, canceled at block 8) let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 7); // cancel rent contract at block 8 assert_ok!(SmartContractModule::cancel_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1 )); assert_ne!(amount_due_as_u128, 0); @@ -1565,20 +1740,21 @@ fn test_rent_contract_canceled_mid_cycle_should_bill_for_remainder() { #[test] fn test_create_rent_contract_and_node_contract_excludes_node_contract_from_billing_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1586,12 +1762,17 @@ fn test_create_rent_contract_and_node_contract_excludes_node_contract_from_billi None )); push_contract_resources_used(2); - - run_to_block(12); - - let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 11); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); + + let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 10); assert_ne!(amount_due_as_u128, 0); - check_report_cost(1, amount_due_as_u128, 12, discount_received); + check_report_cost(1, amount_due_as_u128, 11, discount_received); let our_events = System::events(); // Event 1: Rent contract created @@ -1604,20 +1785,21 @@ fn test_create_rent_contract_and_node_contract_excludes_node_contract_from_billi #[test] fn test_rent_contract_canceled_due_to_out_of_funds_should_cancel_node_contracts_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), node_id, None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1626,25 +1808,25 @@ fn test_rent_contract_canceled_due_to_out_of_funds_should_cancel_node_contracts_ )); push_contract_resources_used(2); - run_to_block(12); - run_to_block(22); - run_to_block(32); - run_to_block(42); - run_to_block(52); - run_to_block(62); - run_to_block(72); - run_to_block(82); - run_to_block(92); - run_to_block(102); - run_to_block(112); - run_to_block(122); + // run 12 cycles, contracts should cancel after 11 due to lack of funds + for i in 0..11 { + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11 + i * 10); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 11 + i * 10); + } + for i in 0..11 { + run_to_block(12 + 10 * i, Some(&mut pool_state)); + } // let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 11); // assert_ne!(amount_due_as_u128, 0); // check_report_cost(1, 3, amount_due_as_u128, 12, discount_received); let our_events = System::events(); - assert_eq!(our_events.len(), 31); + assert_eq!(our_events.len(), 10); assert_eq!( our_events[5], @@ -1670,7 +1852,7 @@ fn test_rent_contract_canceled_due_to_out_of_funds_should_cancel_node_contracts_ ); assert_eq!( - our_events[29], + our_events[8], record(MockEvent::SmartContractModule(SmartContractEvent::< TestRuntime, >::NodeContractCanceled { @@ -1680,7 +1862,7 @@ fn test_rent_contract_canceled_due_to_out_of_funds_should_cancel_node_contracts_ })) ); assert_eq!( - our_events[30], + our_events[9], record(MockEvent::SmartContractModule(SmartContractEvent::< TestRuntime, >::RentContractCanceled { @@ -1692,20 +1874,21 @@ fn test_rent_contract_canceled_due_to_out_of_funds_should_cancel_node_contracts_ #[test] fn test_create_rent_contract_and_node_contract_with_ip_billing_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1713,16 +1896,23 @@ fn test_create_rent_contract_and_node_contract_with_ip_billing_works() { None )); - run_to_block(12); + // 2 contracts => we expect 2 calls to bill_contract + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); // check contract 1 costs (Rent Contract) - let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 11); + let (amount_due_as_u128, discount_received) = calculate_tft_cost(1, 2, 10); assert_ne!(amount_due_as_u128, 0); - check_report_cost(1, amount_due_as_u128, 12, discount_received); + check_report_cost(1, amount_due_as_u128, 11, discount_received); // check contract 2 costs (Node Contract) - let (amount_due_as_u128, discount_received) = calculate_tft_cost(2, 2, 11); + let (amount_due_as_u128, discount_received) = calculate_tft_cost(2, 2, 10); assert_ne!(amount_due_as_u128, 0); - check_report_cost(2, amount_due_as_u128, 12, discount_received); + check_report_cost(2, amount_due_as_u128, 11, discount_received); let our_events = System::events(); // Event 1: Price Stored @@ -1737,21 +1927,25 @@ fn test_create_rent_contract_and_node_contract_with_ip_billing_works() { #[test] fn test_rent_contract_out_of_funds_should_move_state_to_graceperiod_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), node_id, None )); // cycle 1 // user does not have enough funds to pay for 1 cycle - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::GracePeriod(11)); @@ -1773,20 +1967,24 @@ fn test_rent_contract_out_of_funds_should_move_state_to_graceperiod_works() { #[test] fn test_restore_rent_contract_in_grace_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), node_id, None )); // cycle 1 - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::GracePeriod(11)); @@ -1804,24 +2002,28 @@ fn test_restore_rent_contract_in_grace_works() { })) ); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(21); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(22); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21); + run_to_block(21, Some(&mut pool_state)); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(31); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(32); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 31); + run_to_block(31, Some(&mut pool_state)); // Transfer some balance to the owner of the contract to trigger the grace period to stop - Balances::transfer(Origin::signed(bob()), charlie(), 100000000).unwrap(); + Balances::transfer(RuntimeOrigin::signed(bob()), charlie(), 100000000).unwrap(); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(41); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(42); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 41); + run_to_block(41, Some(&mut pool_state)); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(51); - assert_eq!(contract_to_bill.len(), 1); - run_to_block(52); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 51); + run_to_block(51, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::Created); @@ -1830,19 +2032,20 @@ fn test_restore_rent_contract_in_grace_works() { #[test] fn test_restore_rent_contract_and_node_contracts_in_grace_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, None); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), node_id, None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), 1, generate_deployment_hash(), get_deployment_data(), @@ -1852,7 +2055,13 @@ fn test_restore_rent_contract_and_node_contracts_in_grace_works() { push_contract_resources_used(2); // cycle 1 - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::GracePeriod(11)); @@ -1881,31 +2090,48 @@ fn test_restore_rent_contract_and_node_contracts_in_grace_works() { })) ); - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(21); - assert_eq!(contract_to_bill.len(), 2); - run_to_block(22); - - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(31); - assert_eq!(contract_to_bill.len(), 2); - run_to_block(32); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 21); + run_to_block(22, Some(&mut pool_state)); + + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 31); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 31); + run_to_block(32, Some(&mut pool_state)); // Transfer some balance to the owner of the contract to trigger the grace period to stop - Balances::transfer(Origin::signed(bob()), charlie(), 100000000).unwrap(); - - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(41); - assert_eq!(contract_to_bill.len(), 2); - run_to_block(42); - - let contract_to_bill = SmartContractModule::contract_to_bill_at_block(51); - assert_eq!(contract_to_bill.len(), 2); - run_to_block(52); + Balances::transfer(RuntimeOrigin::signed(bob()), charlie(), 100000000).unwrap(); + + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 41); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 41); + run_to_block(42, Some(&mut pool_state)); + + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 51); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 51); + run_to_block(52, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::Created); let our_events = System::events(); + assert_eq!( - our_events[11], + our_events[8], record(MockEvent::SmartContractModule(SmartContractEvent::< TestRuntime, >::ContractGracePeriodEnded { @@ -1915,7 +2141,7 @@ fn test_restore_rent_contract_and_node_contracts_in_grace_works() { })) ); assert_eq!( - our_events[12], + our_events[9], record(MockEvent::SmartContractModule(SmartContractEvent::< TestRuntime, >::ContractGracePeriodEnded { @@ -1929,20 +2155,24 @@ fn test_restore_rent_contract_and_node_contracts_in_grace_works() { #[test] fn test_rent_contract_grace_period_cancels_contract_when_grace_period_ends_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(charlie()), + RuntimeOrigin::signed(charlie()), node_id, None )); // cycle 1 - run_to_block(12); + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); let c1 = SmartContractModule::contracts(1).unwrap(); assert_eq!(c1.state, types::ContractState::GracePeriod(11)); @@ -1960,18 +2190,16 @@ fn test_rent_contract_grace_period_cancels_contract_when_grace_period_ends_works true ); - run_to_block(22); - run_to_block(32); - run_to_block(42); - run_to_block(52); - run_to_block(62); - run_to_block(72); - run_to_block(82); - run_to_block(92); - run_to_block(102); - run_to_block(112); - run_to_block(122); - run_to_block(132); + // run 12 cycles, after 10 cycles grace period has finished so no more + // billing! + for i in 0..11 { + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 21 + i * 10); + } + for i in 0..12 { + run_to_block(21 + i * 10, Some(&mut pool_state)); + } let c1 = SmartContractModule::contracts(1); assert_eq!(c1, None); @@ -1980,20 +2208,21 @@ fn test_rent_contract_grace_period_cancels_contract_when_grace_period_ends_works #[test] fn test_rent_contract_and_node_contract_canceled_when_node_is_deleted_works() { - new_test_ext().execute_with(|| { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { prepare_dedicated_farm_and_node(); - run_to_block(1); - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + run_to_block(1, Some(&mut pool_state)); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); let node_id = 1; assert_ok!(SmartContractModule::create_rent_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), node_id, None )); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, generate_deployment_hash(), get_deployment_data(), @@ -2002,12 +2231,19 @@ fn test_rent_contract_and_node_contract_canceled_when_node_is_deleted_works() { )); push_contract_resources_used(2); - run_to_block(12); + // 2 contracts => 2 calls to bill_contract + pool_state + .write() + .should_call_bill_contract(1, Ok(Pays::Yes.into()), 11); + pool_state + .write() + .should_call_bill_contract(2, Ok(Pays::Yes.into()), 11); + run_to_block(11, Some(&mut pool_state)); - run_to_block(16); + run_to_block(16, Some(&mut pool_state)); // Delete node - TfgridModule::delete_node_farm(Origin::signed(alice()), 1).unwrap(); + TfgridModule::delete_node_farm(RuntimeOrigin::signed(alice()), 1).unwrap(); let our_events = System::events(); @@ -2036,6 +2272,7 @@ fn test_rent_contract_and_node_contract_canceled_when_node_is_deleted_works() { // SOLUTION PROVIDER TESTS // // ------------------------ // + #[test] fn test_create_solution_provider_works() { new_test_ext().execute_with(|| { @@ -2050,7 +2287,7 @@ fn test_create_solution_provider_works() { let providers = vec![provider1, provider2]; assert_ok!(SmartContractModule::create_solution_provider( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "some_description".as_bytes().to_vec(), "some_link".as_bytes().to_vec(), providers @@ -2075,7 +2312,7 @@ fn test_create_solution_provider_fails_if_take_to_high() { assert_noop!( SmartContractModule::create_solution_provider( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "some_description".as_bytes().to_vec(), "some_link".as_bytes().to_vec(), providers @@ -2088,12 +2325,13 @@ fn test_create_solution_provider_fails_if_take_to_high() { #[test] fn test_create_node_contract_with_solution_provider_works() { new_test_ext().execute_with(|| { + run_to_block(1, None); prepare_farm_and_node(); prepare_solution_provider(); assert_ok!(SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -2115,7 +2353,7 @@ fn test_create_node_contract_with_solution_provider_fails_if_not_approved() { let providers = vec![provider]; assert_ok!(SmartContractModule::create_solution_provider( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), "some_description".as_bytes().to_vec(), "some_link".as_bytes().to_vec(), providers @@ -2123,7 +2361,7 @@ fn test_create_node_contract_with_solution_provider_fails_if_not_approved() { assert_noop!( SmartContractModule::create_node_contract( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, generate_deployment_hash(), get_deployment_data(), @@ -2135,6 +2373,645 @@ fn test_create_node_contract_with_solution_provider_fails_if_not_approved() { }); } +// SERVICE CONTRACT TESTS // +// ---------------------- // + +#[test] +fn test_service_contract_create_works() { + new_test_ext().execute_with(|| { + run_to_block(1, None); + create_service_consumer_contract(); + + let service_contract = get_service_contract(); + assert_eq!( + service_contract, + SmartContractModule::service_contracts(1).unwrap(), + ); + + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule( + SmartContractEvent::ServiceContractCreated(service_contract) + )), + ); + }); +} + +#[test] +fn test_service_contract_create_by_anyone_fails() { + new_test_ext().execute_with(|| { + create_twin(alice()); + create_twin(bob()); + create_twin(charlie()); + + assert_noop!( + SmartContractModule::service_contract_create( + RuntimeOrigin::signed(charlie()), + alice(), + bob(), + ), + Error::::TwinNotAuthorized + ); + }); +} + +#[test] +fn test_service_contract_create_same_account_fails() { + new_test_ext().execute_with(|| { + create_twin(alice()); + + assert_noop!( + SmartContractModule::service_contract_create( + RuntimeOrigin::signed(alice()), + alice(), + alice(), + ), + Error::::ServiceContractCreationNotAllowed + ); + }); +} + +#[test] +fn test_service_contract_set_metadata_works() { + new_test_ext().execute_with(|| { + run_to_block(1, None); + create_service_consumer_contract(); + + assert_ok!(SmartContractModule::service_contract_set_metadata( + RuntimeOrigin::signed(alice()), + 1, + b"some_metadata".to_vec(), + )); + + let mut service_contract = get_service_contract(); + service_contract.metadata = BoundedVec::try_from(b"some_metadata".to_vec()).unwrap(); + assert_eq!( + service_contract, + SmartContractModule::service_contracts(1).unwrap(), + ); + + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule( + SmartContractEvent::ServiceContractMetadataSet(service_contract) + )), + ); + }); +} + +#[test] +fn test_service_contract_set_metadata_by_unauthorized_fails() { + new_test_ext().execute_with(|| { + create_service_consumer_contract(); + create_twin(charlie()); + + assert_noop!( + SmartContractModule::service_contract_set_metadata( + RuntimeOrigin::signed(charlie()), + 1, + b"some_metadata".to_vec(), + ), + Error::::TwinNotAuthorized + ); + }); +} + +#[test] +fn test_service_contract_set_metadata_already_approved_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_set_metadata( + RuntimeOrigin::signed(alice()), + 1, + b"some_metadata".to_vec(), + ), + Error::::ServiceContractModificationNotAllowed + ); + }); +} + +#[test] +fn test_service_contract_set_metadata_too_long_fails() { + new_test_ext().execute_with(|| { + create_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_set_metadata( + RuntimeOrigin::signed(alice()), + 1, + b"very_loooooooooooooooooooooooooooooooooooooooooooooooooong_metadata".to_vec(), + ), + Error::::ServiceContractMetadataTooLong + ); + }); +} + +#[test] +fn test_service_contract_set_fees_works() { + new_test_ext().execute_with(|| { + run_to_block(1, None); + create_service_consumer_contract(); + + assert_ok!(SmartContractModule::service_contract_set_fees( + RuntimeOrigin::signed(alice()), + 1, + BASE_FEE, + VARIABLE_FEE, + )); + + let mut service_contract = get_service_contract(); + service_contract.base_fee = BASE_FEE; + service_contract.variable_fee = VARIABLE_FEE; + assert_eq!( + service_contract, + SmartContractModule::service_contracts(1).unwrap(), + ); + + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule( + SmartContractEvent::ServiceContractFeesSet(service_contract) + )), + ); + }); +} + +#[test] +fn test_service_contract_set_fees_by_unauthorized_fails() { + new_test_ext().execute_with(|| { + create_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_set_fees( + RuntimeOrigin::signed(bob()), + 1, + BASE_FEE, + VARIABLE_FEE, + ), + Error::::TwinNotAuthorized + ); + }); +} + +#[test] +fn test_service_contract_set_fees_already_approved_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_set_fees( + RuntimeOrigin::signed(alice()), + 1, + BASE_FEE, + VARIABLE_FEE, + ), + Error::::ServiceContractModificationNotAllowed + ); + }); +} + +#[test] +fn test_service_contract_approve_works() { + new_test_ext().execute_with(|| { + run_to_block(1, None); + prepare_service_consumer_contract(); + + let mut service_contract = get_service_contract(); + service_contract.base_fee = BASE_FEE; + service_contract.variable_fee = VARIABLE_FEE; + service_contract.metadata = BoundedVec::try_from(b"some_metadata".to_vec()).unwrap(); + service_contract.state = types::ServiceContractState::AgreementReady; + assert_eq!( + service_contract, + SmartContractModule::service_contracts(1).unwrap(), + ); + + // Service approves + assert_ok!(SmartContractModule::service_contract_approve( + RuntimeOrigin::signed(alice()), + 1, + )); + + service_contract.accepted_by_service = true; + assert_eq!( + service_contract, + SmartContractModule::service_contracts(1).unwrap(), + ); + + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule(SmartContractEvent::< + TestRuntime, + >::ServiceContractApproved( + service_contract.clone() + ))), + ); + + // Consumer approves + assert_ok!(SmartContractModule::service_contract_approve( + RuntimeOrigin::signed(bob()), + 1, + )); + + service_contract.accepted_by_consumer = true; + service_contract.last_bill = get_timestamp_in_seconds_for_block(1); + service_contract.state = types::ServiceContractState::ApprovedByBoth; + assert_eq!( + service_contract, + SmartContractModule::service_contracts(1).unwrap(), + ); + + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule(SmartContractEvent::< + TestRuntime, + >::ServiceContractApproved( + service_contract + ))), + ); + }); +} + +#[test] +fn test_service_contract_approve_agreement_not_ready_fails() { + new_test_ext().execute_with(|| { + create_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_approve(RuntimeOrigin::signed(alice()), 1,), + Error::::ServiceContractApprovalNotAllowed + ); + }); +} + +#[test] +fn test_service_contract_approve_already_approved_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_approve(RuntimeOrigin::signed(alice()), 1,), + Error::::ServiceContractApprovalNotAllowed + ); + }); +} + +#[test] +fn test_service_contract_approve_by_unauthorized_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + create_twin(charlie()); + + assert_noop!( + SmartContractModule::service_contract_approve(RuntimeOrigin::signed(charlie()), 1,), + Error::::TwinNotAuthorized + ); + }); +} + +#[test] +fn test_service_contract_reject_works() { + new_test_ext().execute_with(|| { + run_to_block(1, None); + prepare_service_consumer_contract(); + + assert_ok!(SmartContractModule::service_contract_reject( + RuntimeOrigin::signed(alice()), + 1, + )); + + assert_eq!(SmartContractModule::service_contracts(1).is_none(), true); + + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule(SmartContractEvent::< + TestRuntime, + >::ServiceContractCanceled { + service_contract_id: 1, + cause: types::Cause::CanceledByUser, + })), + ); + }); +} + +#[test] +fn test_service_contract_reject_agreement_not_ready_fails() { + new_test_ext().execute_with(|| { + create_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_reject(RuntimeOrigin::signed(alice()), 1,), + Error::::ServiceContractRejectionNotAllowed + ); + }); +} + +#[test] +fn test_service_contract_reject_already_approved_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_reject(RuntimeOrigin::signed(alice()), 1,), + Error::::ServiceContractRejectionNotAllowed + ); + }); +} + +#[test] +fn test_service_contract_reject_by_unauthorized_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + create_twin(charlie()); + + assert_noop!( + SmartContractModule::service_contract_reject(RuntimeOrigin::signed(charlie()), 1,), + Error::::TwinNotAuthorized + ); + }); +} + +#[test] +fn test_service_contract_cancel_works() { + new_test_ext().execute_with(|| { + run_to_block(1, None); + create_service_consumer_contract(); + + assert_ok!(SmartContractModule::service_contract_cancel( + RuntimeOrigin::signed(alice()), + 1, + )); + + assert_eq!(SmartContractModule::service_contracts(1).is_none(), true); + + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule(SmartContractEvent::< + TestRuntime, + >::ServiceContractCanceled { + service_contract_id: 1, + cause: types::Cause::CanceledByUser, + })), + ); + }); +} + +#[test] +fn test_service_contract_cancel_by_unauthorized_fails() { + new_test_ext().execute_with(|| { + create_service_consumer_contract(); + create_twin(charlie()); + + assert_noop!( + SmartContractModule::service_contract_cancel(RuntimeOrigin::signed(charlie()), 1,), + Error::::TwinNotAuthorized + ); + }); +} + +#[test] +fn test_service_contract_bill_works() { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { + run_to_block(1, None); + prepare_service_consumer_contract(); + + let service_contract = SmartContractModule::service_contracts(1).unwrap(); + assert_eq!(service_contract.last_bill, 0); + + approve_service_consumer_contract(); + + let service_contract = SmartContractModule::service_contracts(1).unwrap(); + assert_eq!( + service_contract.last_bill, + get_timestamp_in_seconds_for_block(1) + ); + + let consumer_twin = TfgridModule::twins(2).unwrap(); + let consumer_balance = Balances::free_balance(&consumer_twin.account_id); + assert_eq!(consumer_balance, 2500000000); + + // Bill 20 min after contract approval + run_to_block(201, Some(&mut pool_state)); + assert_ok!(SmartContractModule::service_contract_bill( + RuntimeOrigin::signed(alice()), + 1, + VARIABLE_AMOUNT, + b"bill_metadata_1".to_vec(), + )); + + let service_contract = SmartContractModule::service_contracts(1).unwrap(); + assert_eq!( + service_contract.last_bill, + get_timestamp_in_seconds_for_block(201) + ); + + // Check consumer balance after first billing + let consumer_balance = Balances::free_balance(&consumer_twin.account_id); + let window = + get_timestamp_in_seconds_for_block(201) - get_timestamp_in_seconds_for_block(1); + let bill_1 = types::ServiceContractBill { + variable_amount: VARIABLE_AMOUNT, + window, + metadata: BoundedVec::try_from(b"bill_metadata_1".to_vec()).unwrap(), + }; + let billed_amount_1 = service_contract + .calculate_bill_cost_tft::(bill_1.clone()) + .unwrap(); + assert_eq!(2500000000 - consumer_balance, billed_amount_1); + + // Check event triggering + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule(SmartContractEvent::< + TestRuntime, + >::ServiceContractBilled { + service_contract, + bill: bill_1, + amount: billed_amount_1, + })), + ); + + // Bill a second time, 1h10min after first billing + run_to_block(901, Some(&mut pool_state)); + assert_ok!(SmartContractModule::service_contract_bill( + RuntimeOrigin::signed(alice()), + 1, + VARIABLE_AMOUNT, + b"bill_metadata_2".to_vec(), + )); + + let service_contract = SmartContractModule::service_contracts(1).unwrap(); + assert_eq!( + service_contract.last_bill, + get_timestamp_in_seconds_for_block(901) + ); + + // Check consumer balance after second billing + let consumer_balance = Balances::free_balance(&consumer_twin.account_id); + let bill_2 = types::ServiceContractBill { + variable_amount: VARIABLE_AMOUNT, + window: SECS_PER_HOUR, // force a 1h bill here + metadata: BoundedVec::try_from(b"bill_metadata_2".to_vec()).unwrap(), + }; + let billed_amount_2 = service_contract + .calculate_bill_cost_tft::(bill_2.clone()) + .unwrap(); + // Second billing was equivalent to a 1h + // billing even if window is greater than 1h + assert_eq!( + 2500000000 - consumer_balance - billed_amount_1, + billed_amount_2 + ); + + // Check event triggering + let our_events = System::events(); + assert_eq!(!our_events.is_empty(), true); + assert_eq!( + our_events.last().unwrap(), + &record(MockEvent::SmartContractModule(SmartContractEvent::< + TestRuntime, + >::ServiceContractBilled { + service_contract, + bill: bill_2, + amount: billed_amount_2, + })), + ); + }); +} + +#[test] +fn test_service_contract_bill_by_unauthorized_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_bill( + RuntimeOrigin::signed(bob()), + 1, + VARIABLE_AMOUNT, + b"bill_metadata".to_vec(), + ), + Error::::TwinNotAuthorized + ); + }); +} + +#[test] +fn test_service_contract_bill_not_approved_fails() { + new_test_ext().execute_with(|| { + prepare_service_consumer_contract(); + + assert_noop!( + SmartContractModule::service_contract_bill( + RuntimeOrigin::signed(alice()), + 1, + VARIABLE_AMOUNT, + b"bill_metadata".to_vec(), + ), + Error::::ServiceContractBillingNotApprovedByBoth + ); + }); +} + +#[test] +fn test_service_contract_bill_variable_amount_too_high_fails() { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { + run_to_block(1, None); + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + // Bill 1h after contract approval + run_to_block(601, Some(&mut pool_state)); + // set variable amount a bit higher than variable fee to trigger error + let variable_amount = VARIABLE_FEE + 1; + assert_noop!( + SmartContractModule::service_contract_bill( + RuntimeOrigin::signed(alice()), + 1, + variable_amount, + b"bill_metadata".to_vec(), + ), + Error::::ServiceContractBillingVariableAmountTooHigh + ); + }); +} + +#[test] +fn test_service_contract_bill_metadata_too_long_fails() { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { + run_to_block(1, None); + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + // Bill 1h after contract approval + run_to_block(601, Some(&mut pool_state)); + assert_noop!( + SmartContractModule::service_contract_bill( + RuntimeOrigin::signed(alice()), + 1, + VARIABLE_AMOUNT, + b"very_loooooooooooooooooooooooooooooooooooooooooooooooooong_metadata".to_vec(), + ), + Error::::ServiceContractBillMetadataTooLong + ); + }); +} + +#[test] +fn test_service_contract_bill_out_of_funds_fails() { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { + run_to_block(1, None); + prepare_service_consumer_contract(); + approve_service_consumer_contract(); + + // Drain consumer account + let consumer_twin = TfgridModule::twins(2).unwrap(); + let consumer_balance = Balances::free_balance(&consumer_twin.account_id); + Balances::transfer(RuntimeOrigin::signed(bob()), alice(), consumer_balance).unwrap(); + let consumer_balance = Balances::free_balance(&consumer_twin.account_id); + assert_eq!(consumer_balance, 0); + + // Bill 1h after contract approval + run_to_block(601, Some(&mut pool_state)); + assert_noop!( + SmartContractModule::service_contract_bill( + RuntimeOrigin::signed(alice()), + 1, + VARIABLE_AMOUNT, + b"bill_metadata".to_vec(), + ), + Error::::ServiceContractNotEnoughFundsToPayBill, + ); + }); +} + // MODULE FUNCTION TESTS // // ---------------------- // @@ -2189,6 +3066,45 @@ fn test_lock() { }) } +#[test] +fn test_change_billing_frequency_works() { + let (mut ext, mut pool_state) = new_test_ext_with_pool_state(0); + ext.execute_with(|| { + run_to_block(1, Some(&mut pool_state)); + let new_frequency = 900; + + assert_ok!(SmartContractModule::change_billing_frequency( + RawOrigin::Root.into(), + new_frequency + )); + + assert_eq!(SmartContractModule::billing_frequency(), new_frequency); + + let our_events = System::events(); + assert_eq!( + our_events.contains(&record(MockEvent::SmartContractModule( + SmartContractEvent::::BillingFrequencyChanged(new_frequency) + ))), + true + ); + }) +} + +#[test] +fn test_change_billing_frequency_fails_if_frequency_lower() { + new_test_ext().execute_with(|| { + let initial_frequency = SmartContractModule::billing_frequency(); + let new_frequency = initial_frequency - 1; + + assert_noop!( + SmartContractModule::change_billing_frequency(RawOrigin::Root.into(), new_frequency), + Error::::CanOnlyIncreaseFrequency + ); + + assert_eq!(initial_frequency, SmartContractModule::billing_frequency()); + }) +} + #[test] fn test_percent() { let cost: u64 = 1000; @@ -2213,10 +3129,10 @@ fn validate_distribution_rewards( total_amount_billed: u64, had_solution_provider: bool, ) { - println!("total locked balance {:?}", total_amount_billed); + info!("total locked balance {:?}", total_amount_billed); let staking_pool_account_balance = Balances::free_balance(&get_staking_pool_account()); - println!( + info!( "staking pool account balance, {:?}", staking_pool_account_balance ); @@ -2247,7 +3163,7 @@ fn validate_distribution_rewards( let solution_provider = SmartContractModule::solution_providers(1).unwrap(); let solution_provider_1_balance = Balances::free_balance(solution_provider.providers[0].who.clone()); - println!("solution provider b: {:?}", solution_provider_1_balance); + info!("solution provider b: {:?}", solution_provider_1_balance); assert_eq!( solution_provider_1_balance, Perbill::from_percent(10) * total_amount_billed @@ -2277,12 +3193,12 @@ fn push_nru_report_for_contract(contract_id: u64, block_number: u64) { consumption_reports.push(super::types::NruConsumption { contract_id, nru: 3 * gigabyte, - timestamp: 1628082000 + (6 * block_number), + timestamp: get_timestamp_in_seconds_for_block(block_number), window: 6 * block_number, }); assert_ok!(SmartContractModule::add_nru_reports( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), consumption_reports )); } @@ -2300,7 +3216,7 @@ fn push_contract_resources_used(contract_id: u64) { }); assert_ok!(SmartContractModule::report_contract_resources( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), resources )); } @@ -2313,27 +3229,19 @@ fn check_report_cost( ) { let our_events = System::events(); - let contract_bill_event = types::ContractBill { + let contract_bill = types::ContractBill { contract_id, - timestamp: 1628082000 + (6 * block_number), + timestamp: get_timestamp_in_seconds_for_block(block_number), discount_level, amount_billed: amount_billed as u128, }; assert_eq!( our_events.contains(&record(MockEvent::SmartContractModule( - SmartContractEvent::::ContractBilled(contract_bill_event) + SmartContractEvent::::ContractBilled(contract_bill) ))), true ); - // assert_eq!( - // our_events[index], - // record(MockEvent::SmartContractModule(SmartContractEvent::< - // TestRuntime, - // >::ContractBilled( - // contract_bill_event - // ))) - // ); } fn calculate_tft_cost(contract_id: u64, twin_id: u32, blocks: u64) -> (u64, types::DiscountLevel) { @@ -2355,11 +3263,11 @@ pub fn prepare_twins() { pub fn prepare_farm(source: AccountId, dedicated: bool) { let farm_name = "test_farm"; let mut pub_ips = Vec::new(); - pub_ips.push(pallet_tfgrid_types::PublicIpInput { + pub_ips.push(IP4 { ip: "185.206.122.33/24".as_bytes().to_vec().try_into().unwrap(), gw: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), }); - pub_ips.push(pallet_tfgrid_types::PublicIpInput { + pub_ips.push(IP4 { ip: "185.206.122.34/24".as_bytes().to_vec().try_into().unwrap(), gw: "185.206.122.1".as_bytes().to_vec().try_into().unwrap(), }); @@ -2405,7 +3313,7 @@ pub fn prepare_farm(source: AccountId, dedicated: bool) { .unwrap(); TfgridModule::create_farm( - Origin::signed(source), + RuntimeOrigin::signed(source), farm_name.as_bytes().to_vec().try_into().unwrap(), pub_ips.clone().try_into().unwrap(), ) @@ -2419,107 +3327,83 @@ pub fn prepare_farm(source: AccountId, dedicated: bool) { } pub fn prepare_farm_and_node() { - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); create_farming_policies(); - prepare_twins(); - prepare_farm(alice(), false); - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1024 * GIGABYTE, sru: 512 * GIGABYTE, cru: 8, mru: 16 * GIGABYTE, }; - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; + TfgridModule::create_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, resources, location, - country, - city, bounded_vec![], false, false, - "some_serial".as_bytes().to_vec(), + None, ) .unwrap(); } pub fn prepare_dedicated_farm_and_node() { - TFTPriceModule::set_prices(Origin::signed(bob()), 50, 101).unwrap(); + TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 50, 101).unwrap(); create_farming_policies(); - prepare_twins(); - prepare_farm(alice(), true); - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1024 * GIGABYTE, sru: 512 * GIGABYTE, cru: 8, mru: 16 * GIGABYTE, }; - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; + TfgridModule::create_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, resources, location, - country, - city, bounded_vec![], false, false, - "some_serial".as_bytes().to_vec(), + None, ) .unwrap(); } pub fn create_twin(origin: AccountId) { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - assert_ok!(TfgridModule::user_accept_tc( - Origin::signed(origin.clone()), - document.clone(), - hash.clone(), - )); - let ip = get_twin_ip(b"::1"); - assert_ok!(TfgridModule::create_twin( - Origin::signed(origin), - ip.clone().0 + RuntimeOrigin::signed(origin.clone()), + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), )); -} -fn run_to_block(n: u64) { - Timestamp::set_timestamp((1628082000 * 1000) + (6000 * n)); - while System::block_number() < n { - SmartContractModule::on_finalize(System::block_number()); - System::on_finalize(System::block_number()); - System::set_block_number(System::block_number() + 1); - System::on_initialize(System::block_number()); - SmartContractModule::on_initialize(System::block_number()); - } + let ip = get_twin_ip_input(b"::1"); + assert_ok!(TfgridModule::create_twin(RuntimeOrigin::signed(origin), ip)); } fn create_farming_policies() { @@ -2596,7 +3480,7 @@ fn prepare_solution_provider() { let providers = vec![provider]; assert_ok!(SmartContractModule::create_solution_provider( - Origin::signed(dave()), + RuntimeOrigin::signed(dave()), "some_description".as_bytes().to_vec(), "some_link".as_bytes().to_vec(), providers @@ -2609,7 +3493,7 @@ fn prepare_solution_provider() { )); } -fn record(event: Event) -> EventRecord { +fn record(event: RuntimeEvent) -> EventRecord { EventRecord { phase: Phase::Initialization, event, @@ -2617,8 +3501,9 @@ fn record(event: Event) -> EventRecord { } } -fn generate_deployment_hash() -> H256 { - H256::random() +fn generate_deployment_hash() -> HexHash { + let hash: [u8; 32] = H256::random().to_fixed_bytes(); + hash } fn get_deployment_data() -> crate::DeploymentDataInput { @@ -2627,3 +3512,64 @@ fn get_deployment_data() -> crate::DeploymentDataInput { ) .unwrap() } + +fn create_service_consumer_contract() { + create_twin(alice()); + create_twin(bob()); + + // create contract between service (Alice) and consumer (Bob) + assert_ok!(SmartContractModule::service_contract_create( + RuntimeOrigin::signed(alice()), + alice(), + bob(), + )); +} + +fn prepare_service_consumer_contract() { + create_service_consumer_contract(); + + assert_ok!(SmartContractModule::service_contract_set_metadata( + RuntimeOrigin::signed(alice()), + 1, + b"some_metadata".to_vec(), + )); + + assert_ok!(SmartContractModule::service_contract_set_fees( + RuntimeOrigin::signed(alice()), + 1, + BASE_FEE, + VARIABLE_FEE, + )); +} + +fn approve_service_consumer_contract() { + // Service approves + assert_ok!(SmartContractModule::service_contract_approve( + RuntimeOrigin::signed(alice()), + 1, + )); + // Consumer approves + assert_ok!(SmartContractModule::service_contract_approve( + RuntimeOrigin::signed(bob()), + 1, + )); +} + +fn get_service_contract() -> types::ServiceContract { + types::ServiceContract { + service_contract_id: 1, + service_twin_id: 1, //Alice + consumer_twin_id: 2, //Bob + base_fee: 0, + variable_fee: 0, + metadata: bounded_vec![], + accepted_by_service: false, + accepted_by_consumer: false, + last_bill: 0, + state: types::ServiceContractState::Created, + } +} + +fn get_timestamp_in_seconds_for_block(block_number: u64) -> u64 { + 1628082000 + (6 * block_number) +} diff --git a/substrate-node/pallets/pallet-smart-contract/src/types.rs b/substrate-node/pallets/pallet-smart-contract/src/types.rs index 59281177b..e7f2fb351 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/types.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/types.rs @@ -1,29 +1,28 @@ -use crate::pallet::{ - ContractPublicIP, DeploymentHash, MaxDeploymentDataLength, MaxNodeContractPublicIPs, -}; +use crate::pallet::{MaxDeploymentDataLength, MaxNodeContractPublicIPs}; use crate::Config; use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::{BoundedVec, RuntimeDebugNoBound}; +use frame_support::{pallet_prelude::ConstU32, BoundedVec, RuntimeDebugNoBound}; use scale_info::TypeInfo; use sp_std::prelude::*; use substrate_fixed::types::U64F64; -use tfchain_support::types::Resources; +use tfchain_support::{resources::Resources, types::PublicIP}; pub type BlockNumber = u64; /// Utility type for managing upgrades/migrations. -#[derive(Encode, Decode, Clone, Debug, PartialEq, TypeInfo, MaxEncodedLen)] +#[derive(Encode, Decode, Clone, Debug, PartialEq, PartialOrd, TypeInfo, MaxEncodedLen)] pub enum StorageVersion { V1, V2, V3, V4, V5, + V6, } impl Default for StorageVersion { fn default() -> StorageVersion { - StorageVersion::V3 + StorageVersion::V5 } } @@ -53,6 +52,9 @@ impl Contract { } } +// HexHash is hex encoded hash +pub type HexHash = [u8; 32]; + #[derive(Clone, Eq, PartialEq, RuntimeDebugNoBound, Encode, Decode, TypeInfo, MaxEncodedLen)] #[scale_info(skip_type_params(T))] #[codec(mel_bound())] @@ -60,10 +62,10 @@ pub struct NodeContract { pub node_id: u32, // Hash of the deployment, set by the user // Max 32 bytes - pub deployment_hash: DeploymentHash, + pub deployment_hash: HexHash, pub deployment_data: BoundedVec>, pub public_ips: u32, - pub public_ips_list: BoundedVec, MaxNodeContractPublicIPs>, + pub public_ips_list: BoundedVec>, } #[derive(Clone, Eq, PartialEq, RuntimeDebugNoBound, Encode, Decode, TypeInfo, MaxEncodedLen)] @@ -224,3 +226,38 @@ pub struct Provider { pub who: AccountId, pub take: u8, } + +pub const MAX_METADATA_LENGTH: u32 = 64; // limited to 64 bytes (2 public keys) +pub const MAX_BILL_METADATA_LENGTH: u32 = 50; // limited to 50 bytes for now + +#[derive(Clone, Eq, PartialEq, RuntimeDebugNoBound, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[scale_info(skip_type_params(T))] +#[codec(mel_bound())] +pub struct ServiceContract { + pub service_contract_id: u64, + pub service_twin_id: u32, + pub consumer_twin_id: u32, + pub base_fee: u64, + pub variable_fee: u64, + pub metadata: BoundedVec>, + pub accepted_by_service: bool, + pub accepted_by_consumer: bool, + pub last_bill: u64, + pub state: ServiceContractState, +} + +#[derive( + PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo, MaxEncodedLen, +)] +pub struct ServiceContractBill { + pub variable_amount: u64, // variable amount which is billed + pub window: u64, // amount of time (in seconds) covered since last bill + pub metadata: BoundedVec>, +} + +#[derive(Clone, Eq, PartialEq, RuntimeDebugNoBound, Encode, Decode, TypeInfo, MaxEncodedLen)] +pub enum ServiceContractState { + Created, + AgreementReady, + ApprovedByBoth, +} diff --git a/substrate-node/pallets/pallet-smart-contract/src/weights.rs b/substrate-node/pallets/pallet-smart-contract/src/weights.rs index 5fd989a44..3048d1fda 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/weights.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/weights.rs @@ -1,5 +1,6 @@ // This file is part of Substrate. +// Copyright (C) 2022 Threefold Tech // Copyright (C) 2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 @@ -17,65 +18,68 @@ //! Autogenerated weights for pallet_smart_contract //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2022-02-23, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Interpreted, CHAIN: Some("dev"), DB CACHE: 128 +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-12-16, STEPS: 50, REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: // ./target/release/tfchain // benchmark -// --chain=dev +// pallet +// --chain +// dev // --steps=50 // --repeat=20 // --pallet // pallet_smart_contract // --extrinsic // * -// --execution=wasm +// --execution +// wasm // --heap-pages=4096 -// --output=../pallets/pallet-smart-contract/src/weights.rs -// --raw +// --output=./pallets/pallet-smart-contract/src/weights.rs // --template // ./.maintain/frame-weight-template.hbs - #![allow(unused_parens)] #![allow(unused_imports)] -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use frame_support::{ + traits::Get, + weights::{constants::RocksDbWeight, Weight}, +}; use sp_std::marker::PhantomData; /// Weight functions needed for pallet_smart_contract. pub trait WeightInfo { - fn create_node_contract() -> Weight; - fn add_reports() -> Weight; + fn create_node_contract() -> Weight; + fn add_nru_reports() -> Weight; + fn bill_contract_for_block() -> Weight; } /// Weights for pallet_smart_contract using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn create_node_contract() -> Weight { - (926_396_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(8 as Weight)) - } - fn add_reports() -> Weight { - (832_738_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } + fn create_node_contract() -> Weight { + Weight::from_ref_time(926_396_000).saturating_add(T::DbWeight::get().reads_writes(8, 8)) + } + fn add_nru_reports() -> Weight { + Weight::from_ref_time(99_753_000).saturating_add(T::DbWeight::get().reads_writes(7, 1)) + } + fn bill_contract_for_block() -> Weight { + Weight::from_ref_time(131_686_000).saturating_add(T::DbWeight::get().reads_writes(14, 2)) + } } // For backwards compatibility and tests impl WeightInfo for () { - fn create_node_contract() -> Weight { - (926_396_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) - .saturating_add(RocksDbWeight::get().writes(8 as Weight)) - } - fn add_reports() -> Weight { - (832_738_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } -} \ No newline at end of file + fn create_node_contract() -> Weight { + Weight::from_ref_time(926_396_000).saturating_add(RocksDbWeight::get().reads_writes(8, 8)) + } + fn add_nru_reports() -> Weight { + Weight::from_ref_time(99_753_000).saturating_add(RocksDbWeight::get().reads_writes(7, 1)) + } + fn bill_contract_for_block() -> Weight { + Weight::from_ref_time(131_686_000).saturating_add(RocksDbWeight::get().reads_writes(14, 2)) + } +} diff --git a/substrate-node/pallets/pallet-smart-contract/third-party_service_contract.md b/substrate-node/pallets/pallet-smart-contract/third-party_service_contract.md new file mode 100644 index 000000000..01889170b --- /dev/null +++ b/substrate-node/pallets/pallet-smart-contract/third-party_service_contract.md @@ -0,0 +1,56 @@ +# Third party service contract + +Since we don't want to do work on the chain for every possible 3rd party service, we will keep this as generic as possible. While custom implementations for services might offer small advantages in the flow, the extra effort to develop and most importantly maintain these implementations is not worth it compared to a proper generic flow which would technically also be reusable. + +## Contract structure + +A contract will work simple client - server principle (i.e. the "buyer" and the "seller", a "consumer" of a service and one who "offers" the service). Both parties are identified by a twin id to fit in the current flow (we could use a generic address as well here). Contract is laid out as such + +- consumer twin id +- service twin id +- base fee, this is the fixed amount which will be billed hourly +- variable fee, this is the maximum amount which can be billed on top of the base fee (for variable consumption metrics, to be defined by the service) +- metadata, a field which just holds some bytes. The service can use this any way it likes (including having stuff set by the user). We limit this field to some size now, suggested 64 bytes (2 public keys generally) + +Additionally, we also keep track of some metadata, which will be: + +- accepted by consumer +- accepted by service +- last bill received (we keep track of this to make sure the service does not send overlapping bills) + +## Billing + +Once a contract is accepted by both the consumer and the service, the chain can start accepting "bill reports" from the service for the contract. Only the twin of the service can send these, as specified in the contract. The bill contains the following: + +- Variable amount which is billed. The chain checks that this is less than or equal to the variable amount as specified in the contract, if it is higher the bill is rejected for overcharging. Technically the service could send a report every second to drain the user. To protect against this, the max variable amount in the contract is interpreted as being "per hour", and the value set in the contract is divided by 3600, multiplied by window size, to find the actual maximum which can be billed by the contract. +- Window, this is the amount of time (in seconds) covered since last contract. The chain verifies that `current time - window >= contract.last_bill`, such that no bills overlap to avoid overcharging. Combined with the previous limit to variable amount this prevents the service from overcharging the user. +- Some optional metadata, this will again just be some bytes (the service decides how this can be interpreted). For now we'll limit this to 50 bytes or so. + +## Chain calls + +### Callable by anyone + +- `create_contract(consumer twin ID, service twin ID)`: Creates the contract and sets the id's. Base fee and variable fee are left at 0 + +### Callable by consumer or service + +- `set_metadata(data)`: Sets the custom metadata on the contract. This can be done by either the client of the service, depending on how it is interpreted (as specified by the service). For now, we will assume that setting metadata is a one off operation. As a result, if metadata is already present when this is called, an error is thrown (i.e. only the first call of this function can succeed). + +### Callable by service + +- `set_fees(base, variable)`: Sets the base fee and variable fee on the contract +- `reject_by_service()`: Rejects the contract, deleting it. +- `approve_by_service()`: Sets the `service_accepted` flag on the contract. After this, no more modifications to fees or metadata can be done + +### Callable by user + +- `reject_by_consumer()`: Rejects the contract, deleting it. +- `approve_by_consumer()`: Sets the `consumer_accepted` flag on the contract. After this, no more modifications to fees or metadata can be done + +## Flow + +We start of by creating a contract. This can technically be done by anyone, but in practice will likely end up being done by either the service or the consumer (depending on what the service expects). This will be followed by the service or consumer setting the metadata (again depending on how the service expects things to be), and the service setting a base fee + variable fee. Note that part of the communication can and should be off chain, the contract is only the finalized agreement. When the fees and metadata are set, both the consumer and service need to explicitly approve the contract, setting the appropriate flag on the contract. Note that as soon as either party accepted (i.e. either flag is set), the fees and metadata cannot be changed anymore. It is technically possible for consumers to accept a contract as soon as it is created, thereby not giving the service a chance to set the fees. Though this basically means the contract is invalid and the service should just outright reject it. + +Once the contract is accepted by both the consumer and the service, it can be billed (i.e. bills send before both flags are set must be rejected). Because a service should not charge the user if it doesn't work, we will require that bills be send every hour, by limiting the window size to 3600. Anything with a bigger window is rejected. This way if the service is down (for some longer period), it for sure can't bill for the time it was down. When the bill is received, the chain calculates `contract.base_fee * bill.window / 3600 + variable fee` (keeping in mind the constraint for variable fee as outlined above), and this amount is transferred from the consumer twin account to the service twin account. + +We will not implement a grace period for this right now, as the service should define on an individual basis how this is handled. If needed in the future this can of course change. diff --git a/substrate-node/pallets/pallet-tfgrid/Cargo.toml b/substrate-node/pallets/pallet-tfgrid/Cargo.toml index 25e24d81d..5a35962ca 100644 --- a/substrate-node/pallets/pallet-tfgrid/Cargo.toml +++ b/substrate-node/pallets/pallet-tfgrid/Cargo.toml @@ -17,30 +17,31 @@ version = '0.4.14' [dependencies] # Substrate packages +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } hex = { version = "0.4", default-features = false } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive", ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } tfchain-support = { path = "../../support", default-features = false } -valip = "0.3.0" +valip = "0.4.0" -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } [dev-dependencies] hex-literal = "0.3.1" -pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [features] default = ['std'] diff --git a/substrate-node/pallets/pallet-tfgrid/src/farm.rs b/substrate-node/pallets/pallet-tfgrid/src/farm.rs index 93afe4b93..a4d05c12b 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/farm.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/farm.rs @@ -1,10 +1,10 @@ -use sp_std::{marker::PhantomData, vec::Vec}; - use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::traits::Get; use frame_support::{ensure, sp_runtime::SaturatedConversion, BoundedVec, RuntimeDebug}; use scale_info::TypeInfo; +use sp_std::{marker::PhantomData, vec::Vec}; -use crate::{Config, Error}; +use crate::{Config, Error, FarmNameInput}; /// A Farm name (ASCI Characters). /// @@ -19,24 +19,23 @@ pub struct FarmName( pub const MIN_FARM_NAME_LENGTH: u32 = 3; -impl TryFrom> for FarmName { +impl TryFrom> for FarmName { type Error = Error; /// Fallible initialization from a provided byte vector if it is below the /// minimum or exceeds the maximum allowed length or contains invalid ASCII /// characters. - fn try_from(value: Vec) -> Result { + fn try_from(value: FarmNameInput) -> Result { ensure!( value.len() >= MIN_FARM_NAME_LENGTH.saturated_into(), Self::Error::FarmNameTooShort ); - let bounded_vec: BoundedVec = - BoundedVec::try_from(value).map_err(|_| Self::Error::FarmNameTooLong)?; ensure!( - validate_farm_name(&bounded_vec), - Self::Error::InvalidFarmName + value.len() <= T::MaxFarmNameLength::get() as usize, + Self::Error::FarmNameTooLong ); - Ok(Self(bounded_vec, PhantomData)) + ensure!(validate_farm_name(&value), Self::Error::InvalidFarmName); + Ok(Self(value, PhantomData)) } } diff --git a/substrate-node/pallets/pallet-tfgrid/src/farm_migration.rs b/substrate-node/pallets/pallet-tfgrid/src/farm_migration.rs deleted file mode 100644 index 796a4ebb4..000000000 --- a/substrate-node/pallets/pallet-tfgrid/src/farm_migration.rs +++ /dev/null @@ -1,88 +0,0 @@ -use super::Config; -use super::*; -use frame_support::{traits::Get, weights::Weight}; -use log::{debug, info}; - -#[cfg(feature = "try-runtime")] -use frame_support::traits::OnRuntimeUpgradeHelpersExt; -#[cfg(feature = "try-runtime")] -use sp_runtime::SaturatedConversion; - -pub mod v10 { - use super::*; - use crate::Config; - - use frame_support::{pallet_prelude::Weight, traits::OnRuntimeUpgrade}; - use sp_std::marker::PhantomData; - pub struct FixFarmingPolicy(PhantomData); - - impl OnRuntimeUpgrade for FixFarmingPolicy { - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result<(), &'static str> { - assert!(PalletVersion::::get() <= types::StorageVersion::V10Struct); - - // Store number of farms in temp storage - let farms_count: u64 = Farms::::iter_keys().count().saturated_into(); - Self::set_temp_storage(farms_count, "pre_farms_count"); - log::info!( - "🔎 FixFarmingPolicy pre migration: Number of existing farms {:?}", - farms_count - ); - - info!("👥 TFGrid pallet to V11 passes PRE migrate checks ✅",); - Ok(()) - } - - fn on_runtime_upgrade() -> Weight { - if PalletVersion::::get() == types::StorageVersion::V10Struct { - fix_farming_policy_migration_::() - } else { - info!(" >>> Unused migration"); - return 0; - } - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade() -> Result<(), &'static str> { - assert!(PalletVersion::::get() >= types::StorageVersion::V11Struct); - - // Check number of farms against pre-check result - let pre_farms_count = Self::get_temp_storage("pre_farms_count").unwrap_or(0u64); - assert_eq!( - Farms::::iter().count().saturated_into::(), - pre_farms_count, - "Number of farms migrated does not match" - ); - - info!( - "👥 TFGrid pallet migration to {:?} passes POST migrate checks ✅", - Pallet::::pallet_version() - ); - - Ok(()) - } - } -} - -pub fn fix_farming_policy_migration_() -> frame_support::weights::Weight { - info!(" >>> Migrating farm storage..."); - - let mut read_writes = 0; - - Farms::::translate::, _>(|k, f| { - let mut new_farm = f; - - new_farm.pricing_policy_id = 1; - debug!("migrated farm: {:?}", k); - - read_writes += 1; - Some(new_farm) - }); - - // Update pallet storage version - PalletVersion::::set(types::StorageVersion::V11Struct); - info!(" <<< Storage version upgraded"); - - // Return the weight consumed by the migration. - T::DbWeight::get().reads_writes(read_writes as Weight, read_writes as Weight) -} diff --git a/substrate-node/pallets/pallet-tfgrid/src/interface.rs b/substrate-node/pallets/pallet-tfgrid/src/interface.rs index 74854975c..d9cb50f44 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/interface.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/interface.rs @@ -1,14 +1,12 @@ -use sp_std::{marker::PhantomData, vec::Vec}; - +use crate::{Config, Error, InterfaceIpInput, InterfaceMacInput, InterfaceNameInput}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ ensure, sp_runtime::SaturatedConversion, traits::ConstU32, BoundedVec, RuntimeDebug, }; use scale_info::TypeInfo; +use sp_std::marker::PhantomData; use valip::{ip4::Ip as IPv4, ip6::Ip as IPv6, mac::Mac}; -use crate::{Config, Error}; - /// An Interface Name. #[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[scale_info(skip_type_params(T))] @@ -18,27 +16,29 @@ pub struct InterfaceName( PhantomData<(T, ConstU32)>, ); -pub const MIN_INTF_NAME_LENGHT: u32 = 3; +pub const MIN_INTF_NAME_LENGTH: u32 = 3; pub const MAX_INTF_NAME_LENGTH: u32 = 20; -impl TryFrom> for InterfaceName { +impl TryFrom for InterfaceName { type Error = Error; /// Fallible initialization from a provided byte vector if it is below the /// minimum or exceeds the maximum allowed length or contains invalid ASCII /// characters. - fn try_from(value: Vec) -> Result { + fn try_from(value: InterfaceNameInput) -> Result { + ensure!( + value.len() >= MIN_INTF_NAME_LENGTH.saturated_into(), + Self::Error::InterfaceNameTooShort + ); ensure!( - value.len() >= MIN_INTF_NAME_LENGHT.saturated_into(), - Self::Error::InterfaceNameToShort + value.len() <= MAX_INTF_NAME_LENGTH.saturated_into(), + Self::Error::InterfaceNameTooLong ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value.clone()).map_err(|_| Self::Error::InterfaceNameToLong)?; ensure!( validate_interface_name(&value), Self::Error::InvalidInterfaceName ); - Ok(Self(bounded_vec, PhantomData)) + Ok(Self(value, PhantomData)) } } @@ -74,24 +74,23 @@ pub struct InterfaceMac( pub const INTERFACE_MAC_LENGTH: u32 = 17; -impl TryFrom> for InterfaceMac { +impl TryFrom for InterfaceMac { type Error = Error; /// Fallible initialization from a provided byte vector if it is below the /// minimum or exceeds the maximum allowed length or contains invalid ASCII /// characters. - fn try_from(value: Vec) -> Result { + fn try_from(value: InterfaceMacInput) -> Result { ensure!( value.len() >= INTERFACE_MAC_LENGTH.saturated_into(), - Self::Error::InterfaceMacToShort + Self::Error::InterfaceMacTooShort ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::InterfaceMacToLong)?; ensure!( - Mac::parse(&bounded_vec).is_ok(), - Self::Error::InvalidMacAddress + value.len() <= INTERFACE_MAC_LENGTH.saturated_into(), + Self::Error::InterfaceMacTooLong ); - Ok(Self(bounded_vec, PhantomData)) + ensure!(Mac::parse(&value).is_ok(), Self::Error::InvalidMacAddress); + Ok(Self(value, PhantomData)) } } @@ -119,27 +118,29 @@ pub struct InterfaceIp( PhantomData<(T, ConstU32)>, ); -pub const MAX_INTERFACE_IP_LENGTH: u32 = 42; pub const MIN_INTERFACE_IP_LENGTH: u32 = 7; +pub const MAX_INTERFACE_IP_LENGTH: u32 = 42; -impl TryFrom> for InterfaceIp { +impl TryFrom for InterfaceIp { type Error = Error; /// Fallible initialization from a provided byte vector if it is below the /// minimum or exceeds the maximum allowed length or contains invalid ASCII /// characters. - fn try_from(value: Vec) -> Result { + fn try_from(value: InterfaceIpInput) -> Result { ensure!( value.len() >= MIN_INTERFACE_IP_LENGTH.saturated_into(), - Self::Error::InterfaceIpToShort + Self::Error::InterfaceIpTooShort + ); + ensure!( + value.len() <= MAX_INTERFACE_IP_LENGTH.saturated_into(), + Self::Error::InterfaceIpTooLong ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::InterfaceIpToLong)?; ensure!( - IPv4::parse(&bounded_vec).is_ok() || IPv6::parse(&bounded_vec).is_ok(), + IPv4::parse(&value).is_ok() || IPv6::parse(&value).is_ok(), Self::Error::InvalidInterfaceIP ); - Ok(Self(bounded_vec, PhantomData)) + Ok(Self(value, PhantomData)) } } diff --git a/substrate-node/pallets/pallet-tfgrid/src/lib.rs b/substrate-node/pallets/pallet-tfgrid/src/lib.rs index 1dcd80956..2306e008f 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/lib.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/lib.rs @@ -7,15 +7,17 @@ use sp_std::prelude::*; use codec::Encode; use frame_support::dispatch::DispatchErrorWithPostInfo; -use frame_support::{ensure, traits::ConstU32, traits::EnsureOrigin, BoundedVec}; +use frame_support::{ + dispatch::Pays, ensure, pallet_prelude::DispatchResultWithPostInfo, traits::EnsureOrigin, + BoundedVec, +}; use frame_system::{self as system, ensure_signed}; use hex::FromHex; use pallet_timestamp as timestamp; use sp_runtime::SaturatedConversion; -use tfchain_support::types::PublicIP; use tfchain_support::{ - resources, - types::{Interface, Node, PublicConfig, IP}, + resources::Resources, + types::{Interface, PublicIP}, }; // Re-export pallet items so that they can be accessed from the crate namespace. @@ -32,11 +34,11 @@ pub mod weights; pub mod types; pub mod farm; -pub mod farm_migration; pub mod interface; -pub mod nodes_migration; -pub mod pub_config; -pub mod pub_ip; +// pub mod ip; +pub mod migrations; +pub mod node; +pub mod terms_cond; pub mod twin; // Definition of the pallet logic, to be aggregated at runtime definition @@ -52,10 +54,12 @@ pub mod pallet { use pallet_timestamp as timestamp; use sp_std::{convert::TryInto, fmt::Debug, vec::Vec}; use tfchain_support::{ - traits::ChangeNode, + resources::Resources, + traits::{ChangeNode, PublicIpModifier}, types::{ - Farm, FarmCertification, FarmingPolicyLimit, Interface, Location, Node, - NodeCertification, PublicConfig, PublicIP, Resources, IP, + Farm, FarmCertification, FarmingPolicyLimit, Interface, Node, NodeCertification, + PublicConfig, PublicIP, IP4, MAX_DOMAIN_NAME_LENGTH, MAX_GW4_LENGTH, MAX_GW6_LENGTH, + MAX_IP4_LENGTH, MAX_IP6_LENGTH, }, }; @@ -80,19 +84,21 @@ pub mod pallet { // Concrete Farm Name type pub type FarmNameOf = ::FarmName; - // Input type for public ip - pub type PublicIpIpInput = BoundedVec>; - pub type PublicIpGatewayInput = BoundedVec>; - pub type FarmPublicIpInput = types::PublicIpInput; + // Input type for IP4 (IP & GW) + pub type Ip4Input = BoundedVec>; + pub type Gw4Input = BoundedVec>; - // Concrete type for Public IP type - pub type PublicIpOf = PublicIP<::PublicIP, ::GatewayIP>; + // Input type for IP6 (IP & GW) + pub type Ip6Input = BoundedVec>; + pub type Gw6Input = BoundedVec>; // Input type for public ip list - pub type PublicIpListInput = BoundedVec::MaxFarmPublicIps>; + pub type PublicIpListInput = BoundedVec::MaxFarmPublicIps>; + // Concrete type for public ip list type + pub type PublicIpListOf = BoundedVec>; // Farm information type - pub type FarmInfoOf = Farm<::FarmName, PublicIpOf>; + pub type FarmInfoOf = Farm<::FarmName>; #[pallet::storage] #[pallet::getter(fn farms)] @@ -111,49 +117,59 @@ pub mod pallet { pub type FarmPayoutV2AddressByFarmID = StorageMap<_, Blake2_128Concat, u32, Vec, ValueQuery>; - // Input type for public config - pub type PubConfigIP4Input = IP< - BoundedVec>, - BoundedVec>, - >; - pub type PubConfigIP6Input = IP< - BoundedVec>, - BoundedVec>, - >; - pub type PubConfigInput = PublicConfig< - PubConfigIP4Input, - Option, - Option>>, - >; - // Concrete public config type - pub type Ip4ConfigOf = IP<::IP4, ::GW4>; - pub type Ip6ConfigOf = IP<::IP6, ::GW6>; - pub type PubConfigOf = - PublicConfig, Option>, Option<::Domain>>; - + pub type DomainInput = BoundedVec>; // Input type for interfaces + pub type InterfaceNameInput = BoundedVec>; + pub type InterfaceMacInput = BoundedVec>; pub type InterfaceIpInput = BoundedVec>; pub type InterfaceIpsInput = BoundedVec::MaxInterfacesLength>; pub type InterfaceInput = BoundedVec< - Interface< - BoundedVec>, - BoundedVec>, - InterfaceIpsInput, - >, + Interface>, ::MaxInterfaceIpsLength, >; // Concrete type for interfaces - pub type InterfaceIp = ::InterfaceIP; - pub type InterfaceIpsOf = - BoundedVec<::InterfaceIP, ::MaxInterfaceIpsLength>; - pub type InterfaceOf = - Interface<::InterfaceName, ::InterfaceMac, InterfaceIpsOf>; + pub type InterfaceNameOf = ::InterfaceName; + pub type InterfaceMacOf = ::InterfaceMac; + pub type InterfaceIpOf = ::InterfaceIP; + pub type InterfaceIpsOf = BoundedVec, ::MaxInterfaceIpsLength>; + pub type InterfaceOf = Interface, InterfaceMacOf, InterfaceIpsOf>; + + // Input type for location + pub type CityNameInput = BoundedVec>; + pub type CountryNameInput = BoundedVec>; + pub type LatitudeInput = BoundedVec>; + pub type LongitudeInput = BoundedVec>; + pub type LocationInput = + types::LocationInput; + // Concrete type for location + pub type CityNameOf = ::CityName; + pub type CountryNameOf = ::CountryName; + pub type LocationOf = ::Location; + + // Input type for serial number + pub type SerialNumberInput = BoundedVec>; + // Concrete type for location + pub type SerialNumberOf = ::SerialNumber; + + // Input type for resources + pub type ResourcesInput = Resources; + + // Input type for terms and conditions + pub type DocumentLinkInput = BoundedVec>; + pub type DocumentHashInput = BoundedVec>; + pub type TermsAndConditionsInput = + types::TermsAndConditionsInput, DocumentLinkInput, DocumentHashInput>; + + // Concrete type for node + pub type TfgridNode = Node, InterfaceOf, SerialNumberOf>; + + // Concrete type for entity + pub type TfgridEntity = types::Entity, CityNameOf, CountryNameOf>; #[pallet::storage] #[pallet::getter(fn nodes)] - pub type Nodes = - StorageMap<_, Blake2_128Concat, u32, Node, InterfaceOf>, OptionQuery>; + pub type Nodes = StorageMap<_, Blake2_128Concat, u32, TfgridNode, OptionQuery>; #[pallet::storage] #[pallet::getter(fn node_by_twin_id)] @@ -162,7 +178,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn entities)] pub type Entities = - StorageMap<_, Blake2_128Concat, u32, types::Entity, OptionQuery>; + StorageMap<_, Blake2_128Concat, u32, TfgridEntity, OptionQuery>; #[pallet::storage] #[pallet::getter(fn entities_by_pubkey_id)] @@ -174,9 +190,9 @@ pub mod pallet { pub type EntityIdByName = StorageMap<_, Blake2_128Concat, Vec, u32, ValueQuery>; pub type TwinIndex = u32; - type AccountIdOf = ::AccountId; + pub type AccountIdOf = ::AccountId; type TwinInfoOf = types::Twin<::TwinIp, AccountIdOf>; - pub type TwinIpInput = BoundedVec>; + pub type TwinIpInput = BoundedVec>; pub type TwinIpOf = ::TwinIp; #[pallet::storage] @@ -203,15 +219,13 @@ pub mod pallet { pub type FarmingPoliciesMap = StorageMap<_, Blake2_128Concat, u32, types::FarmingPolicy, ValueQuery>; + // Concrete type for location + pub type TermsAndConditionsOf = ::TermsAndConditions; + #[pallet::storage] #[pallet::getter(fn users_terms_and_condition)] - pub type UsersTermsAndConditions = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - Vec>, - OptionQuery, - >; + pub type UsersTermsAndConditions = + StorageMap<_, Blake2_128Concat, T::AccountId, Vec>, OptionQuery>; #[pallet::storage] #[pallet::getter(fn allowed_node_certifiers)] @@ -255,133 +269,118 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config + pallet_timestamp::Config { - type Event: From> + IsType<::Event>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// Origin for restricted extrinsics /// Can be the root or another origin configured in the runtime - type RestrictedOrigin: EnsureOrigin; + type RestrictedOrigin: EnsureOrigin; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; - type NodeChanged: ChangeNode, super::InterfaceOf>; + type NodeChanged: ChangeNode< + super::LocationOf, + super::InterfaceOf, + super::SerialNumberOf, + >; - /// The type of a name. - type TwinIp: FullCodec - + Debug - + PartialEq - + Clone - + TypeInfo - + TryFrom, Error = Error> - + MaxEncodedLen; + type PublicIpModifier: PublicIpModifier; - /// The type of a name. - type FarmName: FullCodec + /// The type of terms and conditions. + type TermsAndConditions: FullCodec + Debug + PartialEq + Clone + TypeInfo - + TryFrom, Error = Error> - + Into> + + TryFrom, Error = Error> + MaxEncodedLen; - /// The type of a name. - type PublicIP: FullCodec - + Debug - + PartialEq - + Eq - + Clone - + TypeInfo - + TryFrom, Error = Error> - + MaxEncodedLen; - - /// The type of a name. - type GatewayIP: FullCodec + /// The type of a twin IP. + type TwinIp: FullCodec + Debug + PartialEq - + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; - /// The type of a name. - type IP4: FullCodec + /// The type of a farm name. + type FarmName: FullCodec + Debug + PartialEq - + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom, Error = Error> + + Into> + MaxEncodedLen; - /// The type of a name. - type GW4: FullCodec + /// The type of an interface name. + type InterfaceName: FullCodec + Debug + PartialEq + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; - /// The type of a name. - type IP6: FullCodec + /// The type of an interface mac address. + type InterfaceMac: FullCodec + Debug + PartialEq + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; - /// The type of a name. - type GW6: FullCodec + /// The type of an interface IP. + type InterfaceIP: FullCodec + Debug + PartialEq + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; - /// The type of a name. - type Domain: FullCodec + /// The type of a city name. + type CityName: FullCodec + Debug + + Default + PartialEq - + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; - /// The type of an interface name. - type InterfaceName: FullCodec + /// The type of a country name. + type CountryName: FullCodec + Debug + + Default + PartialEq - + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; - /// The type of an interface mac address. - type InterfaceMac: FullCodec + /// The type of a location. + type Location: FullCodec + Debug + + Default + PartialEq - + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; - /// The type of an interface IP. - type InterfaceIP: FullCodec + /// The type of a serial number. + type SerialNumber: FullCodec + Debug + + Default + PartialEq - + Eq + Clone + TypeInfo - + TryFrom, Error = Error> + + TryFrom> + MaxEncodedLen; #[pallet::constant] @@ -404,14 +403,14 @@ pub mod pallet { FarmUpdated(FarmInfoOf), FarmDeleted(u32), - NodeStored(Node, pallet::InterfaceOf>), - NodeUpdated(Node, pallet::InterfaceOf>), + NodeStored(TfgridNode), + NodeUpdated(TfgridNode), NodeDeleted(u32), NodeUptimeReported(u32, u64, u64), - NodePublicConfigStored(u32, Option>), + NodePublicConfigStored(u32, Option), - EntityStored(types::Entity), - EntityUpdated(types::Entity), + EntityStored(TfgridEntity), + EntityUpdated(TfgridEntity), EntityDeleted(u32), TwinStored(types::Twin), @@ -467,7 +466,7 @@ pub mod pallet { EntityWithSignatureAlreadyExists, CannotUpdateEntity, CannotDeleteEntity, - SignatureLenghtIsIncorrect, + SignatureLengthIsIncorrect, TwinExists, TwinNotExists, @@ -500,38 +499,70 @@ pub mod pallet { FarmNameTooShort, FarmNameTooLong, InvalidPublicIP, - PublicIPToShort, - PublicIPToLong, - GatewayIPToShort, - GatewayIPToLong, + PublicIPTooShort, + PublicIPTooLong, + GatewayIPTooShort, + GatewayIPTooLong, - IP4ToShort, - IP4ToLong, + IP4TooShort, + IP4TooLong, InvalidIP4, - GW4ToShort, - GW4ToLong, + GW4TooShort, + GW4TooLong, InvalidGW4, - IP6ToShort, - IP6ToLong, + IP6TooShort, + IP6TooLong, InvalidIP6, - GW6ToShort, - GW6ToLong, + GW6TooShort, + GW6TooLong, InvalidGW6, - DomainToShort, - DomainToLong, + DomainTooShort, + DomainTooLong, InvalidDomain, MethodIsDeprecated, - InterfaceNameToShort, - InterfaceNameToLong, + InterfaceNameTooShort, + InterfaceNameTooLong, InvalidInterfaceName, - InterfaceMacToShort, - InterfaceMacToLong, + InterfaceMacTooShort, + InterfaceMacTooLong, InvalidMacAddress, - InterfaceIpToShort, - InterfaceIpToLong, + InterfaceIpTooShort, + InterfaceIpTooLong, InvalidInterfaceIP, InvalidZosVersion, FarmingPolicyExpired, + + InvalidHRUInput, + InvalidSRUInput, + InvalidCRUInput, + InvalidMRUInput, + + LatitudeInputTooShort, + LatitudeInputTooLong, + InvalidLatitudeInput, + LongitudeInputTooShort, + LongitudeInputTooLong, + InvalidLongitudeInput, + CountryNameTooShort, + CountryNameTooLong, + InvalidCountryName, + CityNameTooShort, + CityNameTooLong, + InvalidCityName, + InvalidCountryCityPair, + + SerialNumberTooShort, + SerialNumberTooLong, + InvalidSerialNumber, + + DocumentLinkInputTooShort, + DocumentLinkInputTooLong, + InvalidDocumentLinkInput, + DocumentHashInputTooShort, + DocumentHashInputTooLong, + InvalidDocumentHashInput, + + InvalidPublicConfig, } #[pallet::genesis_config] @@ -702,7 +733,8 @@ pub mod pallet { #[pallet::call] impl Pallet { - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(0)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn set_storage_version( origin: OriginFor, version: types::StorageVersion, @@ -714,7 +746,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1))] + #[pallet::call_index(1)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] pub fn create_farm( origin: OriginFor, name: FarmNameInput, @@ -722,13 +755,9 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let address = ensure_signed(origin)?; - let farm_name = FarmNameOf::::try_from(name.clone().to_vec()) - .map_err(DispatchErrorWithPostInfo::from)?; + let mut id = FarmID::::get(); + id = id + 1; - ensure!( - !FarmIdByName::::contains_key(name.clone()), - Error::::FarmExists - ); let twin_id = TwinIdByAccountID::::get(&address).ok_or(Error::::TwinNotExists)?; let twin = Twins::::get(twin_id).ok_or(Error::::TwinNotExists)?; ensure!( @@ -736,8 +765,11 @@ pub mod pallet { Error::::CannotCreateFarmWrongTwin ); - let mut id = FarmID::::get(); - id = id + 1; + ensure!( + !FarmIdByName::::contains_key(name.clone()), + Error::::FarmExists + ); + let farm_name = Self::get_farm_name(name.clone())?; let public_ips_list = Self::get_public_ips(public_ips)?; @@ -754,7 +786,7 @@ pub mod pallet { }; Farms::::insert(id, &new_farm); - FarmIdByName::::insert(name.to_vec().clone(), id); + FarmIdByName::::insert(name.to_vec(), id); FarmID::::put(id); Self::deposit_event(Event::FarmStored(new_farm)); @@ -762,7 +794,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(3) + T::DbWeight::get().reads(2))] + #[pallet::call_index(2)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(3).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn update_farm( origin: OriginFor, id: u32, @@ -770,8 +803,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let address = ensure_signed(origin)?; - let new_farm_name = FarmNameOf::::try_from(name.to_vec()) - .map_err(DispatchErrorWithPostInfo::from)?; + let new_farm_name = Self::get_farm_name(name.clone())?; let twin_id = TwinIdByAccountID::::get(&address).ok_or(Error::::TwinNotExists)?; @@ -804,7 +836,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(10_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(2))] + #[pallet::call_index(3)] + #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn add_stellar_payout_v2address( origin: OriginFor, farm_id: u32, @@ -831,7 +864,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(4)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn set_farm_certification( origin: OriginFor, farm_id: u32, @@ -850,12 +884,13 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(2))] + #[pallet::call_index(5)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn add_farm_ip( origin: OriginFor, id: u32, - ip: PublicIpIpInput, - gateway: PublicIpGatewayInput, + ip: Ip4Input, + gw: Gw4Input, ) -> DispatchResultWithPostInfo { let address = ensure_signed(origin)?; @@ -867,15 +902,13 @@ pub mod pallet { Error::::CannotUpdateFarmWrongTwin ); - let parsed_ip = ::PublicIP::try_from(ip.into_inner()) - .map_err(DispatchErrorWithPostInfo::from)?; - - let parsed_gateway = ::GatewayIP::try_from(gateway.into_inner()) - .map_err(DispatchErrorWithPostInfo::from)?; + // Check if it's a valid IP4 + let ip4 = IP4 { ip, gw }; + ip4.is_valid().map_err(|_| Error::::InvalidPublicIP)?; let new_ip = PublicIP { - ip: parsed_ip, - gateway: parsed_gateway, + ip: ip4.ip, + gateway: ip4.gw, contract_id: 0, }; @@ -886,9 +919,10 @@ pub mod pallet { { Some(_) => return Err(Error::::IpExists.into()), None => { - stored_farm.public_ips.try_push(new_ip).or_else(|_| { - return Err(DispatchErrorWithPostInfo::from(Error::::InvalidPublicIP)); - })?; + stored_farm + .public_ips + .try_push(new_ip) + .map_err(|_| Error::::InvalidPublicIP)?; Farms::::insert(stored_farm.id, &stored_farm); Self::deposit_event(Event::FarmUpdated(stored_farm)); return Ok(().into()); @@ -896,11 +930,12 @@ pub mod pallet { }; } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(2))] + #[pallet::call_index(6)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn remove_farm_ip( origin: OriginFor, id: u32, - ip: PublicIpIpInput, + ip: Ip4Input, ) -> DispatchResultWithPostInfo { let address = ensure_signed(origin)?; @@ -912,13 +947,10 @@ pub mod pallet { Error::::CannotUpdateFarmWrongTwin ); - let parsed_ip = ::PublicIP::try_from(ip.into_inner()) - .map_err(DispatchErrorWithPostInfo::from)?; - match stored_farm .public_ips .iter() - .position(|pubip| pubip.ip == parsed_ip && pubip.contract_id == 0) + .position(|pubip| pubip.ip == ip && pubip.contract_id == 0) { Some(index) => { stored_farm.public_ips.remove(index); @@ -930,23 +962,23 @@ pub mod pallet { } } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2) + T::DbWeight::get().reads(2))] + #[pallet::call_index(7)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn delete_farm(_origin: OriginFor, _id: u32) -> DispatchResultWithPostInfo { Err(DispatchErrorWithPostInfo::from(Error::::MethodIsDeprecated).into()) } + #[pallet::call_index(8)] #[pallet::weight(::WeightInfo::create_node())] pub fn create_node( origin: OriginFor, farm_id: u32, - resources: Resources, - location: Location, - country: Vec, - city: Vec, + resources: ResourcesInput, + location: LocationInput, interfaces: InterfaceInput, secure_boot: bool, virtualized: bool, - serial_number: Vec, + serial_number: Option, ) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -963,11 +995,19 @@ pub mod pallet { Error::::NodeWithTwinIdExists ); - let node_interfaces = Self::get_interfaces(&interfaces)?; - let mut id = NodeID::::get(); id = id + 1; + let node_resources = Self::get_resources(resources)?; + let node_location = Self::get_location(location)?; + let node_interfaces = Self::get_interfaces(&interfaces)?; + + let node_serial_number = if let Some(serial_input) = serial_number { + Some(Self::get_serial_number(serial_input)?) + } else { + None + }; + let created = >::get().saturated_into::() / 1000; let mut new_node = Node { @@ -975,10 +1015,8 @@ pub mod pallet { id, farm_id, twin_id, - resources, - location, - country, - city, + resources: node_resources, + location: node_location, public_config: None, created, farming_policy_id: 0, @@ -986,7 +1024,7 @@ pub mod pallet { certification: NodeCertification::default(), secure_boot, virtualized, - serial_number, + serial_number: node_serial_number, connection_price: ConnectionPrice::::get(), }; @@ -1009,19 +1047,18 @@ pub mod pallet { Ok(().into()) } + #[pallet::call_index(9)] #[pallet::weight(::WeightInfo::update_node())] pub fn update_node( origin: OriginFor, node_id: u32, farm_id: u32, - resources: Resources, - location: Location, - country: Vec, - city: Vec, - interfaces: Vec>, + resources: ResourcesInput, + location: LocationInput, + interfaces: InterfaceInput, secure_boot: bool, virtualized: bool, - serial_number: Vec, + serial_number: Option, ) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1054,8 +1091,18 @@ pub mod pallet { NodesByFarmID::::insert(farm_id, nodes_by_farm); }; + let node_resources = Self::get_resources(resources)?; + let node_location = Self::get_location(location)?; + let node_interfaces = Self::get_interfaces(&interfaces)?; + + let node_serial_number = if let Some(serial_input) = serial_number { + Some(Self::get_serial_number(serial_input)?) + } else { + None + }; + // If the resources on a certified node changed, reset the certification level to DIY - if stored_node.resources != resources + if Resources::has_changed(&stored_node.resources, &node_resources, 1) && stored_node.certification == NodeCertification::Certified { stored_node.certification = NodeCertification::Diy; @@ -1066,14 +1113,12 @@ pub mod pallet { } stored_node.farm_id = farm_id; - stored_node.resources = resources; - stored_node.location = location; - stored_node.country = country; - stored_node.city = city; - stored_node.interfaces = interfaces; + stored_node.resources = node_resources; + stored_node.location = node_location; + stored_node.interfaces = node_interfaces; stored_node.secure_boot = secure_boot; stored_node.virtualized = virtualized; - stored_node.serial_number = serial_number; + stored_node.serial_number = node_serial_number; // override node in storage Nodes::::insert(stored_node.id, &stored_node); @@ -1085,7 +1130,8 @@ pub mod pallet { Ok(Pays::No.into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(10)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn set_node_certification( origin: OriginFor, node_id: u32, @@ -1122,6 +1168,7 @@ pub mod pallet { Ok(().into()) } + #[pallet::call_index(11)] #[pallet::weight(::WeightInfo::report_uptime())] pub fn report_uptime(origin: OriginFor, uptime: u64) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1144,12 +1191,13 @@ pub mod pallet { Ok(Pays::No.into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(3))] + #[pallet::call_index(12)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(3).ref_time())] pub fn add_node_public_config( origin: OriginFor, farm_id: u32, node_id: u32, - public_config: Option, + public_config: Option, ) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1171,9 +1219,11 @@ pub mod pallet { ensure!(node.farm_id == farm_id, Error::::NodeUpdateNotAuthorized); if let Some(config) = public_config { - let pub_config = Self::get_public_config(config)?; + config + .is_valid() + .map_err(|_| Error::::InvalidPublicConfig)?; // update the public config and save - node.public_config = Some(pub_config); + node.public_config = Some(config); } else { node.public_config = None; } @@ -1184,7 +1234,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(2))] + #[pallet::call_index(13)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn delete_node(origin: OriginFor, id: u32) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1210,19 +1261,17 @@ pub mod pallet { Self::deposit_event(Event::NodeDeleted(id)); - // Call node deleted - T::NodeChanged::node_deleted(&stored_node); - Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(4) + T::DbWeight::get().reads(3))] + #[pallet::call_index(14)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(4).ref_time() + T::DbWeight::get().reads(3).ref_time())] pub fn create_entity( origin: OriginFor, target: T::AccountId, name: Vec, - country: Vec, - city: Vec, + country: CountryNameInput, + city: CityNameInput, signature: Vec, ) -> DispatchResultWithPostInfo { let _ = ensure_signed(origin)?; @@ -1237,7 +1286,7 @@ pub mod pallet { ); ensure!( signature.len() == 128, - Error::::SignatureLenghtIsIncorrect + Error::::SignatureLengthIsIncorrect ); let decoded_signature_as_byteslice = <[u8; 64]>::from_hex(signature.clone()).expect("Decoding failed"); @@ -1254,12 +1303,12 @@ pub mod pallet { let mut id = EntityID::::get(); id = id + 1; - let entity = types::Entity:: { + let entity = TfgridEntity:: { version: TFGRID_ENTITY_VERSION, id, name: name.clone(), - country, - city, + country: Self::get_country_name(country)?, + city: Self::get_city_name(city)?, account_id: target.clone(), }; @@ -1273,12 +1322,13 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3) + T::DbWeight::get().reads(3))] + #[pallet::call_index(15)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3).ref_time() + T::DbWeight::get().reads(3).ref_time())] pub fn update_entity( origin: OriginFor, name: Vec, - country: Vec, - city: Vec, + country: CountryNameInput, + city: CityNameInput, ) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1306,8 +1356,8 @@ pub mod pallet { EntityIdByName::::remove(&stored_entity.name); stored_entity.name = name.clone(); - stored_entity.country = country; - stored_entity.city = city; + stored_entity.country = Self::get_country_name(country)?; + stored_entity.city = Self::get_city_name(city)?; // overwrite entity Entities::::insert(&stored_entity_id, &stored_entity); @@ -1321,7 +1371,8 @@ pub mod pallet { } // TODO: delete all object that have an entity id reference? - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3) + T::DbWeight::get().reads(2))] + #[pallet::call_index(16)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn delete_entity(origin: OriginFor) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1350,6 +1401,7 @@ pub mod pallet { Ok(().into()) } + #[pallet::call_index(17)] #[pallet::weight(::WeightInfo::create_twin())] pub fn create_twin(origin: OriginFor, ip: TwinIpInput) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1367,7 +1419,7 @@ pub mod pallet { let mut twin_id = TwinID::::get(); twin_id = twin_id + 1; - let twin_ip = Self::check_twin_ip(ip)?; + let twin_ip = Self::get_twin_ip(ip)?; let twin = types::Twin:: { version: TFGRID_TWIN_VERSION, @@ -1388,7 +1440,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(3))] + #[pallet::call_index(18)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(3).ref_time())] pub fn update_twin(origin: OriginFor, ip: TwinIpInput) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1403,7 +1456,7 @@ pub mod pallet { Error::::UnauthorizedToUpdateTwin ); - let twin_ip = Self::check_twin_ip(ip)?; + let twin_ip = Self::get_twin_ip(ip)?; twin.ip = twin_ip; @@ -1414,7 +1467,8 @@ pub mod pallet { } // Method for twins only - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(2))] + #[pallet::call_index(19)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn add_twin_entity( origin: OriginFor, twin_id: u32, @@ -1469,7 +1523,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(20)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn delete_twin_entity( origin: OriginFor, twin_id: u32, @@ -1504,7 +1559,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2) + T::DbWeight::get().reads(1))] + #[pallet::call_index(21)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn delete_twin(origin: OriginFor, twin_id: u32) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1525,7 +1581,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3) + T::DbWeight::get().reads(2))] + #[pallet::call_index(22)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn create_pricing_policy( origin: OriginFor, name: Vec, @@ -1572,7 +1629,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(4) + T::DbWeight::get().reads(2))] + #[pallet::call_index(23)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(4).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn update_pricing_policy( origin: OriginFor, id: u32, @@ -1626,7 +1684,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2) + T::DbWeight::get().reads(3))] + #[pallet::call_index(24)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2).ref_time() + T::DbWeight::get().reads(3).ref_time())] pub fn create_farming_policy( origin: OriginFor, name: Vec, @@ -1673,22 +1732,25 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(2))] + #[pallet::call_index(25)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn user_accept_tc( origin: OriginFor, - document_link: Vec, - document_hash: Vec, + document_link: DocumentLinkInput, + document_hash: DocumentHashInput, ) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; let timestamp = >::get().saturated_into::() / 1000; - let t_and_c = types::TermsAndConditions { + let input = TermsAndConditionsInput:: { account_id: account_id.clone(), timestamp, document_link, document_hash, }; + let t_and_c = Self::get_terms_and_conditions(input)?; + let mut users_terms_and_condition = UsersTermsAndConditions::::get(account_id.clone()).unwrap_or(vec![]); users_terms_and_condition.push(t_and_c); @@ -1697,7 +1759,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2) + T::DbWeight::get().reads(5))] + #[pallet::call_index(26)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(2).ref_time() + T::DbWeight::get().reads(5).ref_time())] pub fn delete_node_farm(origin: OriginFor, node_id: u32) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -1731,15 +1794,13 @@ pub mod pallet { Nodes::::remove(node_id); NodeIdByTwinID::::remove(node.twin_id); - // Call node deleted - T::NodeChanged::node_deleted(&node); - Self::deposit_event(Event::NodeDeleted(node_id)); Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3) + T::DbWeight::get().reads(2))] + #[pallet::call_index(27)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(3).ref_time() + T::DbWeight::get().reads(2).ref_time())] pub fn set_farm_dedicated( origin: OriginFor, farm_id: u32, @@ -1756,24 +1817,22 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(28)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn force_reset_farm_ip( origin: OriginFor, farm_id: u32, - ip: Vec, + ip: Ip4Input, ) -> DispatchResultWithPostInfo { T::RestrictedOrigin::ensure_origin(origin)?; ensure!(Farms::::contains_key(farm_id), Error::::FarmNotExists); let mut stored_farm = Farms::::get(farm_id).ok_or(Error::::FarmNotExists)?; - let parsed_ip = - ::PublicIP::try_from(ip).map_err(DispatchErrorWithPostInfo::from)?; - match stored_farm .public_ips .iter_mut() - .find(|pubip| pubip.ip == parsed_ip) + .find(|pubip| pubip.ip == ip) { Some(ip) => { ip.contract_id = 0; @@ -1788,7 +1847,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(29)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn set_connection_price( origin: OriginFor, price: u32, @@ -1802,7 +1862,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(30)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn add_node_certifier( origin: OriginFor, who: T::AccountId, @@ -1830,7 +1891,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(31)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn remove_node_certifier( origin: OriginFor, who: T::AccountId, @@ -1850,7 +1912,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(32)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn update_farming_policy( origin: OriginFor, id: u32, @@ -1892,7 +1955,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(33)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn attach_policy_to_farm( origin: OriginFor, farm_id: u32, @@ -1947,7 +2011,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(34)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn set_zos_version( origin: OriginFor, zos_version: Vec, @@ -1968,17 +2033,11 @@ pub mod pallet { } } -use frame_support::pallet_prelude::DispatchResultWithPostInfo; // Internal functions of the pallet impl Pallet { pub fn verify_signature(signature: [u8; 64], target: &T::AccountId, payload: &Vec) -> bool { - if Self::verify_ed_signature(signature, target, payload) { - return true; - } else if Self::verify_sr_signature(signature, target, payload) { - return true; - } - - false + Self::verify_ed_signature(signature, target, payload) + || Self::verify_sr_signature(signature, target, payload) } fn verify_ed_signature(signature: [u8; 64], target: &T::AccountId, payload: &Vec) -> bool { @@ -2014,7 +2073,7 @@ impl Pallet { } fn get_farming_policy( - node: &Node, pallet::InterfaceOf>, + node: &TfgridNode, ) -> Result, DispatchErrorWithPostInfo> { let mut farm = Farms::::get(node.farm_id).ok_or(Error::::FarmNotExists)?; @@ -2038,7 +2097,7 @@ impl Pallet { match limits.cu { Some(cu_limit) => { - let cu = resources::get_cu(node.resources); + let cu = node.resources.get_cu(); if cu > cu_limit { return Self::get_default_farming_policy(); } @@ -2049,7 +2108,7 @@ impl Pallet { match limits.su { Some(su_limit) => { - let su = resources::get_su(node.resources); + let su = node.resources.get_su(); if su > su_limit { return Self::get_default_farming_policy(); } @@ -2133,57 +2192,104 @@ impl Pallet { } } - fn check_twin_ip(ip: TwinIpInput) -> Result, DispatchErrorWithPostInfo> { - let ip = TwinIpOf::::try_from(ip.to_vec()).map_err(DispatchErrorWithPostInfo::from)?; + fn get_terms_and_conditions( + terms_cond: TermsAndConditionsInput, + ) -> Result, DispatchErrorWithPostInfo> { + let parsed_terms_cond = ::TermsAndConditions::try_from(terms_cond)?; + Ok(parsed_terms_cond) + } - Ok(ip) + fn get_twin_ip(ip: TwinIpInput) -> Result, DispatchErrorWithPostInfo> { + let ip_parsed = ::TwinIp::try_from(ip)?; + Ok(ip_parsed) } - fn get_public_config(config: pallet::PubConfigInput) -> Result, Error> { - let ipv4 = ::IP4::try_from(config.ip4.ip.into_inner())?; - let gw4 = ::GW4::try_from(config.ip4.gw.into_inner())?; + fn get_farm_name(name: FarmNameInput) -> Result, DispatchErrorWithPostInfo> { + let name_parsed = ::FarmName::try_from(name)?; + Ok(name_parsed) + } - let mut pub_config = PublicConfig { - ip4: IP { ip: ipv4, gw: gw4 }, - ip6: None, - domain: None, - }; + fn get_public_ips( + public_ips: PublicIpListInput, + ) -> Result { + let mut public_ips_list: PublicIpListOf = + vec![].try_into().map_err(|_| Error::::InvalidPublicIP)?; - if let Some(ipv6_config) = config.ip6 { - let ipv6 = ::IP6::try_from(ipv6_config.ip.into_inner())?; - let gw6 = ::GW6::try_from(ipv6_config.gw.into_inner())?; + for ip in public_ips { + let pub_ip = PublicIP { + ip: ip.ip, + gateway: ip.gw, + contract_id: 0, + }; - pub_config.ip6 = Some(IP { ip: ipv6, gw: gw6 }); - } + if public_ips_list.contains(&pub_ip) { + return Err(DispatchErrorWithPostInfo::from(Error::::IpExists)); + } - if let Some(domain) = config.domain { - let p_domain = ::Domain::try_from(domain.into_inner())?; - pub_config.domain = Some(p_domain) + public_ips_list + .try_push(pub_ip) + .map_err(|_| Error::::InvalidPublicIP)?; } - Ok(pub_config) + Ok(public_ips_list) + } + + pub fn get_resources( + resources: pallet::ResourcesInput, + ) -> Result { + ensure!(resources.validate_hru(), Error::::InvalidHRUInput); + ensure!(resources.validate_sru(), Error::::InvalidSRUInput); + ensure!(resources.validate_cru(), Error::::InvalidCRUInput); + ensure!(resources.validate_mru(), Error::::InvalidMRUInput); + + Ok(resources) + } + + fn get_interface_name( + if_name: InterfaceNameInput, + ) -> Result, DispatchErrorWithPostInfo> { + let if_name_parsed = ::InterfaceName::try_from(if_name)?; + Ok(if_name_parsed) + } + + fn get_interface_mac( + if_mac: InterfaceMacInput, + ) -> Result, DispatchErrorWithPostInfo> { + let if_mac_parsed = ::InterfaceMac::try_from(if_mac)?; + Ok(if_mac_parsed) + } + + fn get_interface_ip( + if_ip: InterfaceIpInput, + ) -> Result, DispatchErrorWithPostInfo> { + let if_ip_parsed = ::InterfaceIP::try_from(if_ip)?; + Ok(if_ip_parsed) } fn get_interfaces( - interfaces: &pallet::InterfaceInput, - ) -> Result>, Error> { + interfaces: &InterfaceInput, + ) -> Result>, DispatchErrorWithPostInfo> { let mut parsed_interfaces = Vec::new(); if interfaces.len() == 0 { return Ok(parsed_interfaces); } for intf in interfaces.iter() { - let intf_name = ::InterfaceName::try_from(intf.name.to_vec())?; - let intf_mac = ::InterfaceMac::try_from(intf.mac.to_vec())?; + let intf_name = Self::get_interface_name(intf.name.clone())?; + let intf_mac = Self::get_interface_mac(intf.mac.clone())?; let mut parsed_interfaces_ips: BoundedVec< - InterfaceIp, + InterfaceIpOf, ::MaxInterfaceIpsLength, - > = vec![].try_into().unwrap(); + > = vec![] + .try_into() + .map_err(|_| Error::::InvalidInterfaceIP)?; for ip in intf.ips.iter() { - let intf_ip = ::InterfaceIP::try_from(ip.to_vec())?; - let _ = parsed_interfaces_ips.try_push(intf_ip); + let intf_ip = Self::get_interface_ip(ip.clone())?; + parsed_interfaces_ips + .try_push(intf_ip) + .map_err(|_| Error::::InvalidInterfaceIP)?; } parsed_interfaces.push(Interface { @@ -2196,46 +2302,35 @@ impl Pallet { Ok(parsed_interfaces) } - fn get_public_ips( - public_ips: pallet::PublicIpListInput, - ) -> Result, ConstU32<256>>, Error> { - let mut public_ips_list: BoundedVec, ConstU32<256>> = - vec![].try_into().unwrap(); - - for ip in public_ips { - let public_ip_ip = ::PublicIP::try_from(ip.ip.into_inner())?; - let public_ip_gateway = ::GatewayIP::try_from(ip.gw.into_inner())?; + pub fn get_city_name(city: CityNameInput) -> Result, DispatchErrorWithPostInfo> { + let parsed_city = ::CityName::try_from(city)?; + Ok(parsed_city) + } - if public_ips_list.contains(&PublicIP { - ip: public_ip_ip.clone(), - gateway: public_ip_gateway.clone(), - contract_id: 0, - }) { - return Err(Error::::IpExists); - } + pub fn get_country_name( + country: CountryNameInput, + ) -> Result, DispatchErrorWithPostInfo> { + let parsed_country = ::CountryName::try_from(country)?; + Ok(parsed_country) + } - public_ips_list - .try_push(PublicIP { - ip: public_ip_ip, - gateway: public_ip_gateway, - contract_id: 0, - }) - .or_else(|_| { - return Err(DispatchErrorWithPostInfo::from(Error::::InvalidPublicIP)); - }) - .ok(); - } + pub fn get_location( + location: pallet::LocationInput, + ) -> Result, DispatchErrorWithPostInfo> { + let parsed_location = ::Location::try_from(location)?; + Ok(parsed_location) + } - Ok(public_ips_list) + fn get_serial_number( + serial_number: pallet::SerialNumberInput, + ) -> Result, DispatchErrorWithPostInfo> { + let parsed_serial_number = ::SerialNumber::try_from(serial_number)?; + Ok(parsed_serial_number) } } -impl tfchain_support::traits::Tfgrid> - for Pallet -{ - fn get_farm( - farm_id: u32, - ) -> Option>> { +impl tfchain_support::traits::Tfgrid for Pallet { + fn get_farm(farm_id: u32) -> Option> { Farms::::get(farm_id) } @@ -2257,4 +2352,4 @@ impl tfchain_support::traits::Tfgrid false, } } -} +} \ No newline at end of file diff --git a/substrate-node/pallets/pallet-tfgrid/src/migrations/mod.rs b/substrate-node/pallets/pallet-tfgrid/src/migrations/mod.rs new file mode 100644 index 000000000..ff3651387 --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/migrations/mod.rs @@ -0,0 +1,5 @@ +pub mod types; +pub mod v10; +pub mod v11; +pub mod v12; +pub mod v13; diff --git a/substrate-node/pallets/pallet-tfgrid/src/migrations/types.rs b/substrate-node/pallets/pallet-tfgrid/src/migrations/types.rs new file mode 100644 index 000000000..11c3ddabf --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/migrations/types.rs @@ -0,0 +1,87 @@ +pub mod v11 { + use codec::{Decode, Encode}; + use core::cmp::{Ord, PartialOrd}; + use scale_info::TypeInfo; + use sp_std::{prelude::*, vec::Vec}; + use tfchain_support::{ + resources::Resources, + types::{NodeCertification, PublicConfig}, + }; + + #[derive(Encode, Decode, Debug, Default, PartialEq, Eq, Clone, TypeInfo)] + pub struct Entity { + pub version: u32, + pub id: u32, + pub name: Vec, + pub account_id: AccountId, + pub country: Vec, + pub city: Vec, + } + + #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] + pub struct Location { + pub longitude: Vec, + pub latitude: Vec, + } + + #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] + pub struct Node { + pub version: u32, + pub id: u32, + pub farm_id: u32, + pub twin_id: u32, + pub resources: Resources, + pub location: Location, + pub country: Vec, + pub city: Vec, + pub public_config: Option, + pub created: u64, + pub farming_policy_id: u32, + pub interfaces: Vec, + pub certification: NodeCertification, + pub secure_boot: bool, + pub virtualized: bool, + pub serial_number: Vec, + pub connection_price: u32, + } +} + +pub mod v12 { + use codec::{Decode, Encode}; + use core::cmp::{Ord, PartialOrd}; + use scale_info::TypeInfo; + use sp_std::{prelude::*, vec::Vec}; + use tfchain_support::{ + resources::Resources, + types::{NodeCertification, PublicConfig}, + }; + + #[derive(Encode, Decode, Debug, Default, PartialEq, Eq, Clone, TypeInfo)] + pub struct Entity { + pub version: u32, + pub id: u32, + pub name: Vec, + pub account_id: AccountId, + pub country: Country, + pub city: City, + } + + #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] + pub struct Node { + pub version: u32, + pub id: u32, + pub farm_id: u32, + pub twin_id: u32, + pub resources: Resources, + pub location: Location, + pub public_config: Option, + pub created: u64, + pub farming_policy_id: u32, + pub interfaces: Vec, + pub certification: NodeCertification, + pub secure_boot: bool, + pub virtualized: bool, + pub serial_number: Option, + pub connection_price: u32, + } +} diff --git a/substrate-node/pallets/pallet-tfgrid/src/migrations/v10.rs b/substrate-node/pallets/pallet-tfgrid/src/migrations/v10.rs new file mode 100644 index 000000000..495caec5b --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/migrations/v10.rs @@ -0,0 +1,96 @@ +use crate::*; +use frame_support::{dispatch::Weight, traits::Get, traits::OnRuntimeUpgrade}; +use log::{debug, info}; +use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData}; + +#[cfg(feature = "try-runtime")] +use codec::Decode; +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +pub struct FixFarmNodeIndexMap(PhantomData); + +impl OnRuntimeUpgrade for FixFarmNodeIndexMap { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V9Struct); + + let nodes_count: u64 = Nodes::::iter().count() as u64; + log::info!( + "🔎 FixFarmingPolicy pre migration: Number of existing nodes {:?}", + nodes_count + ); + + info!("👥 TFGrid pallet to V10 passes PRE migrate checks ✅",); + Ok(nodes_count.encode()) + } + + fn on_runtime_upgrade() -> Weight { + if PalletVersion::::get() == types::StorageVersion::V9Struct { + add_farm_nodes_index::() + } else { + info!(" >>> Unused TFGrid pallet V10 migration"); + Weight::zero() + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(pre_nodes_count: Vec) -> Result<(), &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V10Struct); + + // Check number of nodes against pre-check result + let pre_nodes_count: u64 = Decode::decode(&mut pre_nodes_count.as_slice()) + .expect("the state parameter should be something that was generated by pre_upgrade"); + assert_eq!( + Nodes::::iter().count() as u64, + pre_nodes_count, + "Number of nodes migrated does not match" + ); + + info!( + "👥 TFGrid pallet migration to {:?} passes POST migrate checks ✅", + Pallet::::pallet_version() + ); + + Ok(()) + } +} + +pub fn add_farm_nodes_index() -> frame_support::weights::Weight { + info!(" >>> Migrating nodes storage..."); + + let _ = NodesByFarmID::::clear(0, None); + + let mut reads = 0; + let mut writes = 0; + + let mut farms_with_nodes: BTreeMap> = BTreeMap::new(); + for (_, node) in Nodes::::iter() { + // Add index of farm - list (nodes) + farms_with_nodes + .entry(node.farm_id) + .or_insert(vec![]) + .push(node.id); + + reads += 1; + } + + for (farm_id, nodes) in farms_with_nodes.iter() { + debug!( + "inserting nodes: {:?} with farm id: {:?}", + nodes.clone(), + farm_id + ); + NodesByFarmID::::insert(farm_id, nodes); + writes += 1; + } + + // Update pallet storage version + PalletVersion::::set(types::StorageVersion::V10Struct); + info!(" <<< Storage version upgraded"); + + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(reads, writes) +} diff --git a/substrate-node/pallets/pallet-tfgrid/src/migrations/v11.rs b/substrate-node/pallets/pallet-tfgrid/src/migrations/v11.rs new file mode 100644 index 000000000..d7ba68004 --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/migrations/v11.rs @@ -0,0 +1,82 @@ +use crate::*; +use frame_support::{traits::Get, traits::OnRuntimeUpgrade, weights::Weight}; +use log::{debug, info}; +use sp_std::marker::PhantomData; + +#[cfg(feature = "try-runtime")] +use codec::Decode; +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +pub struct FixFarmingPolicy(PhantomData); + +impl OnRuntimeUpgrade for FixFarmingPolicy { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V10Struct); + + let farms_count: u64 = Farms::::iter().count() as u64; + log::info!( + "🔎 FixFarmingPolicy pre migration: Number of existing farms {:?}", + farms_count + ); + + info!("👥 TFGrid pallet to V11 passes PRE migrate checks ✅",); + Ok(farms_count.encode()) + } + + fn on_runtime_upgrade() -> Weight { + if PalletVersion::::get() == types::StorageVersion::V10Struct { + fix_farming_policy_migration_::() + } else { + info!(" >>> Unused TFGrid pallet V11 migration"); + Weight::zero() + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(pre_farms_count: Vec) -> Result<(), &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V11Struct); + + // Check number of farms against pre-check result + let pre_farms_count: u64 = Decode::decode(&mut pre_farms_count.as_slice()) + .expect("the state parameter should be something that was generated by pre_upgrade"); + assert_eq!( + Farms::::iter().count() as u64, + pre_farms_count, + "Number of farms migrated does not match" + ); + + info!( + "👥 TFGrid pallet migration to {:?} passes POST migrate checks ✅", + Pallet::::pallet_version() + ); + + Ok(()) + } +} + +pub fn fix_farming_policy_migration_() -> frame_support::weights::Weight { + info!(" >>> Migrating farm storage..."); + + let mut read_writes = 0; + + Farms::::translate::, _>(|k, f| { + let mut new_farm = f; + + new_farm.pricing_policy_id = 1; + debug!("migrated farm: {:?}", k); + + read_writes += 1; + Some(new_farm) + }); + + // Update pallet storage version + PalletVersion::::set(types::StorageVersion::V11Struct); + info!(" <<< Storage version upgraded"); + + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(read_writes, read_writes) +} diff --git a/substrate-node/pallets/pallet-tfgrid/src/migrations/v12.rs b/substrate-node/pallets/pallet-tfgrid/src/migrations/v12.rs new file mode 100644 index 000000000..fd20e6fe1 --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/migrations/v12.rs @@ -0,0 +1,242 @@ +use crate::*; +use frame_support::{ + pallet_prelude::OptionQuery, storage_alias, traits::Get, traits::OnRuntimeUpgrade, + weights::Weight, Blake2_128Concat, BoundedVec, +}; +use log::{debug, info}; +use sp_std::marker::PhantomData; + +#[cfg(feature = "try-runtime")] +use codec::Decode; +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +// Storage alias from Node v12 +#[storage_alias] +pub type Nodes = StorageMap< + Pallet, + Blake2_128Concat, + u32, + super::types::v12::Node, InterfaceOf, SerialNumberOf>, + OptionQuery, +>; + +// Storage alias from Entity v12 +#[storage_alias] +pub type Entities = StorageMap< + Pallet, + Blake2_128Concat, + u32, + super::types::v12::Entity, CityNameOf, CountryNameOf>, + OptionQuery, +>; + +pub struct InputValidation(PhantomData); + +impl OnRuntimeUpgrade for InputValidation { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V11Struct); + + let nodes_count: u64 = Nodes::::iter().count() as u64; + log::info!( + "🔎 InputValidation pre migration: Number of existing nodes {:?}", + nodes_count + ); + + info!("👥 TFGrid pallet to V12 passes PRE migrate checks ✅",); + Ok(nodes_count.encode()) + } + + fn on_runtime_upgrade() -> Weight { + if PalletVersion::::get() == types::StorageVersion::V11Struct { + migrate_entities::() + migrate_nodes::() + update_pallet_storage_version::() + } else { + info!(" >>> Unused TFGrid pallet V12 migration"); + Weight::zero() + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(pre_nodes_count: Vec) -> Result<(), &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V12Struct); + + // Check number of nodes against pre-check result + let pre_nodes_count: u64 = Decode::decode(&mut pre_nodes_count.as_slice()) + .expect("the state parameter should be something that was generated by pre_upgrade"); + assert_eq!( + Nodes::::iter().count() as u64, + pre_nodes_count, + "Number of nodes migrated does not match" + ); + + info!( + "👥 TFGrid pallet migration to {:?} passes POST migrate checks ✅", + Pallet::::pallet_version() + ); + + Ok(()) + } +} + +fn migrate_entities() -> frame_support::weights::Weight { + info!(" >>> Migrating entities storage..."); + + let mut migrated_count = 0; + + // We transform the storage values from the old into the new format. + Entities::::translate::>, _>(|k, entity| { + let country = match get_country_name::(&entity) { + Ok(country_name) => country_name, + Err(e) => { + info!( + "failed to parse country name for entity: {:?}, error: {:?}", + k, e + ); + info!("set default country name for entity"); + ::CountryName::default() + } + }; + + let city = match get_city_name::(&entity) { + Ok(city_name) => city_name, + Err(e) => { + info!( + "failed to parse city name for entity: {:?}, error: {:?}", + k, e + ); + info!("set default city name for entity"); + ::CityName::default() + } + }; + + let new_entity = + super::types::v12::Entity::, CityNameOf, CountryNameOf> { + version: 2, // deprecated + id: entity.id, + name: entity.name, + account_id: entity.account_id, + country, + city, + }; + + migrated_count += 1; + + debug!("Entity: {:?} succesfully migrated", k); + Some(new_entity) + }); + + info!( + " <<< Entity storage updated! Migrated {} Entities ✅", + migrated_count + ); + + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(migrated_count + 1, migrated_count + 1) +} + +fn migrate_nodes() -> frame_support::weights::Weight { + info!(" >>> Migrating nodes storage..."); + + let mut migrated_count = 0; + + // We transform the storage values from the old into the new format. + Nodes::::translate::>, _>(|k, node| { + let location = match get_location::(&node) { + Ok(loc) => loc, + Err(e) => { + info!("failed to parse location for node: {:?}, error: {:?}", k, e); + info!("set default location for node"); + ::Location::default() + } + }; + + let serial_number = match get_serial_number::(&node) { + Ok(serial) => Some(serial), + Err(_) => None, + }; + + let new_node = super::types::v12::Node::, InterfaceOf, SerialNumberOf> { + version: TFGRID_NODE_VERSION, + id: node.id, + farm_id: node.farm_id, + twin_id: node.twin_id, + resources: node.resources, + location, + public_config: node.public_config, + created: node.created, + farming_policy_id: node.farming_policy_id, + interfaces: node.interfaces, + certification: node.certification, + secure_boot: node.secure_boot, + virtualized: node.virtualized, + serial_number, + connection_price: node.connection_price, + }; + + migrated_count += 1; + + debug!("Node: {:?} succesfully migrated", k); + Some(new_node) + }); + info!( + " <<< Node storage updated! Migrated {} nodes ✅", + migrated_count + ); + + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(migrated_count + 1, migrated_count + 1) +} + +fn update_pallet_storage_version() -> frame_support::weights::Weight { + PalletVersion::::set(types::StorageVersion::V12Struct); + info!(" <<< Storage version upgraded"); + + // Return the weight consumed by the migration. + T::DbWeight::get().writes(1) +} + +fn get_country_name( + node: &super::types::v11::Entity>, +) -> Result, Error> { + let country_name_input: CountryNameInput = + BoundedVec::try_from(node.country.clone()).map_err(|_| Error::::CountryNameTooLong)?; + + ::CountryName::try_from(country_name_input) +} + +fn get_city_name( + node: &super::types::v11::Entity>, +) -> Result, Error> { + let city_name_input: CityNameInput = + BoundedVec::try_from(node.city.clone()).map_err(|_| Error::::CityNameTooLong)?; + + ::CityName::try_from(city_name_input) +} + +fn get_location( + node: &super::types::v11::Node>, +) -> Result, Error> { + let location_input = LocationInput { + city: BoundedVec::try_from(node.city.clone()).map_err(|_| Error::::CityNameTooLong)?, + country: BoundedVec::try_from(node.country.clone()) + .map_err(|_| Error::::CountryNameTooLong)?, + latitude: BoundedVec::try_from(node.location.latitude.clone()) + .map_err(|_| Error::::LatitudeInputTooLong)?, + longitude: BoundedVec::try_from(node.location.longitude.clone()) + .map_err(|_| Error::::LongitudeInputTooLong)?, + }; + + ::Location::try_from(location_input) +} + +fn get_serial_number( + node: &super::types::v11::Node>, +) -> Result, Error> { + let serial_number_input: SerialNumberInput = BoundedVec::try_from(node.serial_number.clone()) + .map_err(|_| Error::::SerialNumberTooLong)?; + + ::SerialNumber::try_from(serial_number_input) +} diff --git a/substrate-node/pallets/pallet-tfgrid/src/migrations/v13.rs b/substrate-node/pallets/pallet-tfgrid/src/migrations/v13.rs new file mode 100644 index 000000000..748f1d100 --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/migrations/v13.rs @@ -0,0 +1,201 @@ +use crate::*; +use frame_support::{ + pallet_prelude::Weight, traits::ConstU32, traits::Get, traits::OnRuntimeUpgrade, BoundedVec, +}; +use log::{debug, info}; +use sp_std::{marker::PhantomData, vec}; +use tfchain_support::{ + traits::PublicIpModifier, + types::{Farm, Node, PublicIP, IP4}, +}; + +#[cfg(feature = "try-runtime")] +use codec::Decode; +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +pub struct FixPublicIP(PhantomData); + +impl OnRuntimeUpgrade for FixPublicIP { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() <= types::StorageVersion::V12Struct); + + let nodes_count: u64 = Nodes::::iter().count() as u64; + log::info!( + "🔎 FixPublicIP pre migration: Number of existing nodes {:?}", + nodes_count + ); + + info!("👥 TFGrid pallet to V13 passes PRE migrate checks ✅",); + Ok(nodes_count.encode()) + } + + fn on_runtime_upgrade() -> Weight { + if PalletVersion::::get() == types::StorageVersion::V12Struct { + migrate_nodes::() + migrate_farms::() + } else { + info!(" >>> Unused TFGrid pallet V13 migration"); + Weight::zero() + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(pre_nodes_count: Vec) -> Result<(), &'static str> { + info!("current pallet version: {:?}", PalletVersion::::get()); + assert!(PalletVersion::::get() >= types::StorageVersion::V13Struct); + + // Check number of nodes against pre-check result + let pre_nodes_count: u64 = Decode::decode(&mut pre_nodes_count.as_slice()) + .expect("the state parameter should be something that was generated by pre_upgrade"); + assert_eq!( + Nodes::::iter().count() as u64, + pre_nodes_count, + "Number of nodes migrated does not match" + ); + + info!( + "👥 FixPublicIP post migration: migration to {:?} passes POST migrate checks ✅", + PalletVersion::::get() + ); + + Ok(()) + } +} + +pub fn migrate_nodes() -> frame_support::weights::Weight { + info!( + " >>> Starting tfgrid pallet migration, pallet version: {:?}", + PalletVersion::::get() + ); + + let mut migrated_count = 0; + + Nodes::::translate::< + super::types::v12::Node, InterfaceOf, SerialNumberOf>, + _, + >(|k, n| { + // By default initialize the public config to None + let mut public_config = None; + if let Some(config) = n.public_config { + // If the config is valid, keep it, otherwise discard + match config.is_valid() { + Ok(_) => public_config = Some(config), + Err(_) => { + debug!("resetting pub config of node: {:?}", k); + public_config = None; + } + } + } + + let new_node = Node { + version: TFGRID_NODE_VERSION, + id: n.id, + farm_id: n.farm_id, + twin_id: n.twin_id, + resources: n.resources, + location: n.location, + public_config, + created: n.created, + farming_policy_id: n.farming_policy_id, + interfaces: n.interfaces, + certification: n.certification, + secure_boot: n.secure_boot, + virtualized: n.virtualized, + serial_number: n.serial_number, + connection_price: n.connection_price, + }; + debug!("Node: {:?} succesfully migrated", k); + migrated_count += 1; + Some(new_node) + }); + + info!( + " <<< Node storage updated! Migrated {} Nodes ✅", + migrated_count + ); + + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(migrated_count + 1, migrated_count + 1) +} + +pub fn migrate_farms() -> frame_support::weights::Weight { + info!(" >>> Migrating farms storage..."); + + let mut migrated_count = 0; + // We transform the storage values from the old into the new format. + Farms::::translate::, _>(|k, farm| { + let mut public_ips: BoundedVec> = vec![].try_into().unwrap(); + + match validate_public_ips::(&farm) { + Ok(ips) => { + public_ips = ips; + } + Err(e) => { + debug!( + "failed to parse public ips for farm: {:?}, error: {:?}", + k, e + ) + } + } + + let new_farm = Farm { + version: 4, + id: farm.id, + name: farm.name, + twin_id: farm.twin_id, + pricing_policy_id: farm.pricing_policy_id, + certification: farm.certification, + public_ips, + dedicated_farm: farm.dedicated_farm, + farming_policy_limits: farm.farming_policy_limits, + }; + + migrated_count += 1; + + debug!("Farm: {:?} succesfully migrated", k); + Some(new_farm) + }); + + info!( + " <<< Farm storage updated! Migrated {} Farms ✅", + migrated_count + ); + + // Update pallet storage version + PalletVersion::::set(types::StorageVersion::V13Struct); + info!(" <<< Storage version upgraded"); + + // Return the weight consumed by the migration. + T::DbWeight::get().reads_writes(migrated_count + 1, migrated_count + 1) +} + +fn validate_public_ips( + farm: &FarmInfoOf, +) -> Result>, Error> { + let mut parsed_public_ips: BoundedVec> = vec![].try_into().unwrap(); + + for pub_ip in farm.public_ips.clone().into_iter() { + let ip4 = IP4 { + ip: pub_ip.ip.clone(), + gw: pub_ip.gateway.clone(), + }; + + match ip4.is_valid() { + Ok(_) => { + let _ = parsed_public_ips.try_push(pub_ip); + } + Err(_) => { + debug!("resetting farm ip for farm {:?}", farm.id); + if pub_ip.contract_id != 0 { + T::PublicIpModifier::ip_removed(&pub_ip) + } + + continue; + } + } + } + + Ok(parsed_public_ips) +} diff --git a/substrate-node/pallets/pallet-tfgrid/src/mock.rs b/substrate-node/pallets/pallet-tfgrid/src/mock.rs index dea151f61..c27278d93 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/mock.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/mock.rs @@ -1,28 +1,28 @@ -use crate::mock::sp_api_hidden_includes_construct_runtime::hidden_include::traits::GenesisBuild; -use crate::{self as tfgridModule, Config}; -use frame_support::{construct_runtime, parameter_types, traits::ConstU32}; +use crate::{ + self as tfgridModule, + farm::FarmName, + interface::{InterfaceIp, InterfaceMac, InterfaceName}, + mock::sp_api_hidden_includes_construct_runtime::hidden_include::traits::GenesisBuild, + node::{CityName, CountryName, Location, SerialNumber}, + terms_cond::TermsAndConditions, + twin::TwinIp, + weights, CityNameInput, Config, CountryNameInput, DocumentHashInput, DocumentLinkInput, + DomainInput, FarmNameInput, Gw4Input, Gw6Input, InterfaceIpInput, InterfaceMacInput, + InterfaceNameInput, Ip4Input, Ip6Input, LatitudeInput, LongitudeInput, TwinIpInput, +}; +use frame_support::{construct_runtime, parameter_types, traits::ConstU32, BoundedVec}; use frame_system::EnsureRoot; +use sp_core::{ed25519, sr25519, Pair, Public, H256}; use sp_io::TestExternalities; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup}, + traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify}, + MultiSignature, }; -use tfchain_support::types::Node; - -use sp_core::{ed25519, sr25519, Pair, Public, H256}; - use sp_std::prelude::*; -use crate::farm::FarmName; -use crate::interface::{InterfaceIp, InterfaceMac, InterfaceName}; -use crate::pub_config::{Domain, GW4, GW6, IP4, IP6}; -use crate::pub_ip::{GatewayIP, PublicIP}; -use crate::twin::TwinIp; -use crate::weights; -use sp_runtime::traits::{IdentifyAccount, Verify}; -use sp_runtime::MultiSignature; - use hex; +use tfchain_support::types::PublicIP; pub type Signature = MultiSignature; @@ -49,8 +49,6 @@ construct_runtime!( parameter_types! { pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); pub const ExistentialDeposit: u64 = 1; } @@ -58,16 +56,16 @@ impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; - type Call = Call; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type DbWeight = (); type Version = (); @@ -81,18 +79,21 @@ impl frame_system::Config for TestRuntime { type MaxConsumers = ConstU32<16>; } -pub(crate) type PubConfig = crate::PubConfigOf; +pub(crate) type Serial = crate::SerialNumberOf; +pub(crate) type Loc = crate::LocationOf; pub(crate) type Interface = crate::InterfaceOf; +pub(crate) type TfgridNode = crate::TfgridNode; + pub struct NodeChanged; -impl tfchain_support::traits::ChangeNode for NodeChanged { - fn node_changed( - _old_node: Option<&Node>, - _new_node: &Node, - ) { - } +impl tfchain_support::traits::ChangeNode for NodeChanged { + fn node_changed(_old_node: Option<&TfgridNode>, _new_node: &TfgridNode) {} + fn node_deleted(_node: &TfgridNode) {} +} - fn node_deleted(_node: &tfchain_support::types::Node) {} +pub struct PublicIpModifier; +impl tfchain_support::traits::PublicIpModifier for PublicIpModifier { + fn ip_removed(_ip: &PublicIP) {} } parameter_types! { @@ -102,42 +103,40 @@ parameter_types! { pub const MaxFarmPublicIps: u32 = 512; } +pub(crate) type TestTermsAndConditions = TermsAndConditions; + pub(crate) type TestTwinIp = TwinIp; pub(crate) type TestFarmName = FarmName; -pub(crate) type TestPublicIP = PublicIP; -pub(crate) type TestGatewayIP = GatewayIP; - -pub(crate) type TestIP4 = IP4; -pub(crate) type TestGW4 = GW4; -pub(crate) type TestIP6 = IP6; -pub(crate) type TestGW6 = GW6; -pub(crate) type TestDomain = Domain; pub(crate) type TestInterfaceName = InterfaceName; pub(crate) type TestInterfaceMac = InterfaceMac; pub(crate) type TestInterfaceIp = InterfaceIp; +pub(crate) type TestCountryName = CountryName; +pub(crate) type TestCityName = CityName; +pub(crate) type TestLocation = Location; +pub(crate) type TestSerialNumber = SerialNumber; + impl Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type RestrictedOrigin = EnsureRoot; type WeightInfo = weights::SubstrateWeight; type NodeChanged = NodeChanged; + type PublicIpModifier = PublicIpModifier; + type TermsAndConditions = TestTermsAndConditions; type TwinIp = TestTwinIp; type FarmName = TestFarmName; type MaxFarmNameLength = MaxFarmNameLength; type MaxFarmPublicIps = MaxFarmPublicIps; - type PublicIP = TestPublicIP; - type GatewayIP = TestGatewayIP; - type IP4 = TestIP4; - type GW4 = TestGW4; - type IP6 = TestIP6; - type GW6 = TestGW6; - type Domain = TestDomain; type InterfaceName = TestInterfaceName; type InterfaceMac = TestInterfaceMac; type InterfaceIP = TestInterfaceIp; type MaxInterfacesLength = MaxInterfacesLength; type MaxInterfaceIpsLength = MaxInterfaceIpsLength; + type CountryName = TestCountryName; + type CityName = TestCityName; + type Location = TestLocation; + type SerialNumber = TestSerialNumber; } parameter_types! { @@ -152,7 +151,7 @@ impl pallet_balances::Config for TestRuntime { /// The type for recording an account's balance. type Balance = u64; /// The ubiquitous event type. - type Event = Event; + type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; @@ -174,9 +173,9 @@ parameter_types! { pub type CouncilCollective = pallet_collective::Instance1; impl pallet_collective::Config for TestRuntime { - type Origin = Origin; - type Proposal = Call; - type Event = Event; + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type MotionDuration = CouncilMotionDuration; type MaxProposals = CouncilMaxProposals; type MaxMembers = CouncilMaxMembers; @@ -185,7 +184,7 @@ impl pallet_collective::Config for TestRuntime { } impl pallet_membership::Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type AddOrigin = EnsureRoot; type RemoveOrigin = EnsureRoot; type SwapOrigin = EnsureRoot; @@ -222,7 +221,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { genesis.assimilate_storage(&mut t).unwrap(); let genesis = pallet_membership::GenesisConfig:: { - members: vec![alice()], + members: vec![alice()].try_into().unwrap(), phantom: Default::default(), }; genesis.assimilate_storage(&mut t).unwrap(); @@ -230,48 +229,76 @@ pub fn new_test_ext() -> sp_io::TestExternalities { t.into() } -pub(crate) fn get_twin_ip(twin_ip_input: &[u8]) -> TestTwinIp { - TwinIp::try_from(twin_ip_input.to_vec()).expect("Invalid twin ip input.") +pub(crate) fn get_document_link_input(document_link_input: &[u8]) -> DocumentLinkInput { + BoundedVec::try_from(document_link_input.to_vec()).expect("Invalid document link input.") +} + +pub(crate) fn get_document_hash_input(document_hash_input: &[u8]) -> DocumentHashInput { + BoundedVec::try_from(document_hash_input.to_vec()).expect("Invalid document hash input.") +} + +pub(crate) fn get_twin_ip_input(twin_ip_input: &[u8]) -> TwinIpInput { + BoundedVec::try_from(twin_ip_input.to_vec()).expect("Invalid twin ip input.") +} + +pub(crate) fn get_farm_name_input(farm_name_input: &[u8]) -> FarmNameInput { + BoundedVec::try_from(farm_name_input.to_vec()).expect("Invalid farm name input.") +} + +pub(crate) fn get_public_ip_ip_input(ip_input: &[u8]) -> Ip4Input { + BoundedVec::try_from(ip_input.to_vec()).expect("Invalid public ip (ip) input.") +} + +pub(crate) fn get_public_ip_gw_input(gw_input: &[u8]) -> Gw4Input { + BoundedVec::try_from(gw_input.to_vec()).expect("Invalid public ip (gw) input.") +} + +pub(crate) fn get_pub_config_ip4_input(ip4_input: &[u8]) -> Ip4Input { + BoundedVec::try_from(ip4_input.to_vec()).expect("Invalid ip4 input.") +} + +pub(crate) fn get_pub_config_gw4_input(gw4_input: &[u8]) -> Gw4Input { + BoundedVec::try_from(gw4_input.to_vec()).expect("Invalid gw4 input.") } -pub(crate) fn get_farm_name(farm_name_input: &[u8]) -> TestFarmName { - FarmName::try_from(farm_name_input.to_vec()).expect("Invalid farm input.") +pub(crate) fn get_pub_config_ip6_input(ip6_input: &[u8]) -> Ip6Input { + BoundedVec::try_from(ip6_input.to_vec()).expect("Invalid ip6 input.") } -pub(crate) fn get_pub_config_ip4(ip4: &[u8]) -> TestIP4 { - IP4::try_from(ip4.to_vec()).expect("Invalid ip4 input") +pub(crate) fn get_pub_config_gw6_input(gw6_input: &[u8]) -> Gw6Input { + BoundedVec::try_from(gw6_input.to_vec()).expect("Invalid gw6 input.") } -pub(crate) fn get_pub_config_gw4(gw4: &[u8]) -> TestGW4 { - GW4::try_from(gw4.to_vec()).expect("Invalid gw4 input") +pub(crate) fn get_pub_config_domain_input(domain_input: &[u8]) -> DomainInput { + BoundedVec::try_from(domain_input.to_vec()).expect("Invalid domain input.") } -pub(crate) fn get_pub_config_ip6(ip6: &[u8]) -> TestIP6 { - IP6::try_from(ip6.to_vec()).expect("Invalid ip6 input") +pub(crate) fn get_interface_name_input(if_name_input: &[u8]) -> InterfaceNameInput { + BoundedVec::try_from(if_name_input.to_vec()).expect("Invalid interface name input") } -pub(crate) fn get_pub_config_gw6(gw6: &[u8]) -> TestGW6 { - GW6::try_from(gw6.to_vec()).expect("Invalid gw6 input") +pub(crate) fn get_interface_mac_input(if_mac_input: &[u8]) -> InterfaceMacInput { + BoundedVec::try_from(if_mac_input.to_vec()).expect("Invalid interface mac input") } -pub(crate) fn get_public_ip_ip(ip: &[u8]) -> TestPublicIP { - PublicIP::try_from(ip.to_vec()).expect("Invalid public ip input") +pub(crate) fn get_interface_ip_input(if_ip_input: &[u8]) -> InterfaceIpInput { + BoundedVec::try_from(if_ip_input.to_vec()).expect("Invalid interface ip input") } -pub(crate) fn get_public_ip_gateway(gw: &[u8]) -> TestGatewayIP { - GatewayIP::try_from(gw.to_vec()).expect("Invalid gateway ip input") +pub(crate) fn get_city_name_input(city_input: &[u8]) -> CityNameInput { + BoundedVec::try_from(city_input.to_vec()).expect("Invalid city name input.") } -pub(crate) fn get_interface_name(name: &[u8]) -> TestInterfaceName { - InterfaceName::try_from(name.to_vec()).expect("Invalid interface name input") +pub(crate) fn get_country_name_input(country_input: &[u8]) -> CountryNameInput { + BoundedVec::try_from(country_input.to_vec()).expect("Invalid country name input.") } -pub(crate) fn get_interface_mac(mac: &[u8]) -> TestInterfaceMac { - InterfaceMac::try_from(mac.to_vec()).expect("Invalid interface mac input") +pub(crate) fn get_latitude_input(latitude_input: &[u8]) -> LatitudeInput { + BoundedVec::try_from(latitude_input.to_vec()).expect("Invalid latitude input.") } -pub(crate) fn get_interface_ip(ip: &[u8]) -> TestInterfaceIp { - InterfaceIp::try_from(ip.to_vec()).expect("Invalid interface ip input") +pub(crate) fn get_longitude_input(longitude_input: &[u8]) -> LongitudeInput { + BoundedVec::try_from(longitude_input.to_vec()).expect("Invalid longitude input.") } // industry dismiss casual gym gap music pave gasp sick owner dumb cost diff --git a/substrate-node/pallets/pallet-tfgrid/src/node.rs b/substrate-node/pallets/pallet-tfgrid/src/node.rs new file mode 100644 index 000000000..7563e0c00 --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/node.rs @@ -0,0 +1,411 @@ +use crate::{CityNameInput, Config, CountryNameInput, Error, LocationInput, SerialNumberInput}; +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::{ + ensure, sp_runtime::SaturatedConversion, traits::ConstU32, BoundedVec, RuntimeDebug, +}; +use scale_info::TypeInfo; +use sp_std::marker::PhantomData; + +// 1: Y +pub const MIN_CITY_NAME_LENGTH: u32 = 1; +// 85: Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch +pub const MAX_CITY_NAME_LENGTH: u32 = 58; +pub const DEFAULT_CITY_NAME: &[u8] = b"Unknown"; + +/// A city name in ASCI Characters. +#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[scale_info(skip_type_params(T))] +#[codec(mel_bound())] +pub struct CityName( + pub BoundedVec>, + PhantomData<(T, ConstU32)>, +); + +impl TryFrom for CityName { + type Error = Error; + + /// Fallible initialization from a provided byte vector if it is below the + /// minimum or exceeds the maximum allowed length or contains invalid ASCII + /// characters. + fn try_from(value: CityNameInput) -> Result { + ensure!( + value.len() >= MIN_CITY_NAME_LENGTH.saturated_into(), + Self::Error::CityNameTooShort + ); + ensure!( + value.len() <= MAX_CITY_NAME_LENGTH.saturated_into(), + Self::Error::CityNameTooLong + ); + ensure!(validate_city_name(&value), Self::Error::InvalidCityName); + + Ok(Self(value, PhantomData)) + } +} + +impl Default for CityName { + fn default() -> Self { + let city: BoundedVec> = + DEFAULT_CITY_NAME.to_vec().try_into().unwrap_or_default(); + + Self(city, PhantomData) + } +} + +// FIXME: did not find a way to automatically implement this. +impl PartialEq for CityName { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +// FIXME: did not find a way to automatically implement this. +impl Clone for CityName { + fn clone(&self) -> Self { + Self(self.0.clone(), self.1) + } +} + +pub fn validate_city_name(input: &[u8]) -> bool { + input == DEFAULT_CITY_NAME + || match core::str::from_utf8(input) { + Ok(val) => val + .chars() + .all(|c| c.is_alphabetic() || matches!(c, '-' | '.' | ' ')), + Err(_) => false, + } + // we convert to &str and then to chars to handle + // special alphabetic characters thanks to is_alphabetic() +} + +// 2: Allow country code like BE, FR, BR, ... +pub const MIN_COUNTRY_NAME_LENGTH: u32 = 2; +// 56: The United Kingdom of Great Britain and Northern Ireland +pub const MAX_COUNTRY_NAME_LENGTH: u32 = 56; +pub const DEFAULT_COUNTRY_NAME: &[u8] = b"Unknown"; + +/// A city name in ASCI Characters. +#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[scale_info(skip_type_params(T))] +#[codec(mel_bound())] +pub struct CountryName( + pub BoundedVec>, + PhantomData<(T, ConstU32)>, +); + +impl TryFrom for CountryName { + type Error = Error; + + /// Fallible initialization from a provided byte vector if it is below the + /// minimum or exceeds the maximum allowed length or contains invalid ASCII + /// characters. + fn try_from(value: CountryNameInput) -> Result { + ensure!( + value.len() >= MIN_COUNTRY_NAME_LENGTH.saturated_into(), + Self::Error::CountryNameTooShort + ); + ensure!( + value.len() <= MAX_COUNTRY_NAME_LENGTH.saturated_into(), + Self::Error::CountryNameTooLong + ); + ensure!( + validate_country_name(&value), + Self::Error::InvalidCountryName + ); + + Ok(Self(value, PhantomData)) + } +} + +impl Default for CountryName { + fn default() -> Self { + let country: BoundedVec> = + DEFAULT_COUNTRY_NAME.to_vec().try_into().unwrap_or_default(); + + Self(country, PhantomData) + } +} + +// FIXME: did not find a way to automatically implement this. +impl PartialEq for CountryName { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +// FIXME: did not find a way to automatically implement this. +impl Clone for CountryName { + fn clone(&self) -> Self { + Self(self.0.clone(), self.1) + } +} + +pub fn validate_country_name(input: &[u8]) -> bool { + input == DEFAULT_COUNTRY_NAME + || match core::str::from_utf8(input) { + Ok(val) => val + .chars() + .all(|c| c.is_alphabetic() || matches!(c, '-' | '.' | ' ')), + Err(_) => false, + } + // we convert to &str and then to chars to handle + // special alphabetic characters thanks to is_alphabetic() +} + +pub const MIN_LATITUDE_LENGTH: u32 = 1; +pub const MAX_LATITUDE_LENGTH: u32 = 50; +pub const DEFAULT_LATITUDE: &[u8] = b"Unknown"; + +pub const MIN_LONGITUDE_LENGTH: u32 = 1; +pub const MAX_LONGITUDE_LENGTH: u32 = 50; +pub const DEFAULT_LONGITUDE: &[u8] = b"Unknown"; + +/// A location that countains city, country and lat/long informations in ASCI Characters. +#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[scale_info(skip_type_params(T))] +#[codec(mel_bound())] +pub struct Location { + pub city: CityName, + pub country: CountryName, + pub latitude: BoundedVec>, + pub longitude: BoundedVec>, + _marker: PhantomData, +} + +impl TryFrom for Location { + type Error = Error; + + /// Fallible initialization from provided byte vectors + /// (city, country, latitude and longitude) if one is below the + /// minimum or exceeds the maximum allowed length. + /// For city and country check if byte vector contains invalid + /// ASCII characters. For lat/long check if byte vector can be + /// converted to float and is inside [-90; 90] range (for latitude) + /// or inside [-180; 180] range (for longitude) + fn try_from(value: LocationInput) -> Result { + // Check if [country][city] pair exists in data base + let city = CityName::::try_from(value.city)?; + let country = CountryName::::try_from(value.country)?; + + // latitude + ensure!( + value.latitude.len() >= MIN_LATITUDE_LENGTH.saturated_into(), + Self::Error::LatitudeInputTooShort + ); + ensure!( + value.latitude.len() <= MAX_LATITUDE_LENGTH.saturated_into(), + Self::Error::LatitudeInputTooLong + ); + ensure!( + validate_latitude_input(&value.latitude.to_vec()), + Self::Error::InvalidLatitudeInput + ); + + // longitude + ensure!( + value.longitude.len() >= MIN_LONGITUDE_LENGTH.saturated_into(), + Self::Error::LongitudeInputTooShort + ); + ensure!( + value.longitude.len() <= MAX_LONGITUDE_LENGTH.saturated_into(), + Self::Error::LongitudeInputTooLong + ); + ensure!( + validate_longitude_input(&value.longitude.to_vec()), + Self::Error::InvalidLongitudeInput + ); + + Ok(Self { + city, + country, + latitude: value.latitude, + longitude: value.longitude, + _marker: PhantomData, + }) + } +} + +impl Default for Location { + fn default() -> Self { + let city = CityName::default(); + let country = CountryName::default(); + let latitude: BoundedVec> = + DEFAULT_LATITUDE.to_vec().try_into().unwrap_or_default(); + let longitude: BoundedVec> = + DEFAULT_LONGITUDE.to_vec().try_into().unwrap_or_default(); + + Self { + city, + country, + latitude, + longitude, + _marker: PhantomData, + } + } +} + +// FIXME: did not find a way to automatically implement this. +impl PartialEq for Location { + fn eq(&self, other: &Self) -> bool { + self.city == other.city + && self.country == other.country + && self.latitude == other.latitude + && self.longitude == other.longitude + } +} + +// FIXME: did not find a way to automatically implement this. +impl Clone for Location { + fn clone(&self) -> Self { + Self { + city: self.city.clone(), + country: self.country.clone(), + latitude: self.latitude.clone(), + longitude: self.longitude.clone(), + _marker: PhantomData, + } + } +} + +pub fn validate_latitude_input(input: &[u8]) -> bool { + input == DEFAULT_LATITUDE + || match core::str::from_utf8(input) { + Ok(val) => { + if let Some(lat) = val.parse::().ok() { + lat >= -90.0 && lat <= 90.0 + } else { + false + } + } + Err(_) => false, + } +} + +pub fn validate_longitude_input(input: &[u8]) -> bool { + input == DEFAULT_LONGITUDE + || match core::str::from_utf8(input) { + Ok(val) => { + if let Some(long) = val.parse::().ok() { + long >= -180.0 && long <= 180.0 + } else { + false + } + } + Err(_) => false, + } +} + +pub const MIN_SERIAL_NUMBER_LENGTH: u32 = 10; +pub const MAX_SERIAL_NUMBER_LENGTH: u32 = 50; +pub const DEFAULT_SERIAL_NUMBER: &[u8] = b"Not Specified"; + +/// A serial number in ASCI Characters. +#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[scale_info(skip_type_params(T))] +#[codec(mel_bound())] +pub struct SerialNumber( + pub BoundedVec>, + PhantomData<(T, ConstU32)>, +); + +impl TryFrom for SerialNumber { + type Error = Error; + + /// Fallible initialization from a provided byte vector if it is below the + /// minimum or exceeds the maximum allowed length or contains invalid ASCII + /// characters. + fn try_from(value: SerialNumberInput) -> Result { + ensure!( + value.len() >= MIN_SERIAL_NUMBER_LENGTH.saturated_into(), + Self::Error::SerialNumberTooShort + ); + ensure!( + value.len() <= MAX_SERIAL_NUMBER_LENGTH.saturated_into(), + Self::Error::SerialNumberTooLong + ); + ensure!( + validate_serial_number(&value), + Self::Error::InvalidSerialNumber + ); + + Ok(Self(value, PhantomData)) + } +} + +impl Default for SerialNumber { + fn default() -> Self { + let serial: BoundedVec> = DEFAULT_SERIAL_NUMBER + .to_vec() + .try_into() + .unwrap_or_default(); + + Self(serial, PhantomData) + } +} + +// FIXME: did not find a way to automatically implement this. +impl PartialEq for SerialNumber { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +// FIXME: did not find a way to automatically implement this. +impl Clone for SerialNumber { + fn clone(&self) -> Self { + Self(self.0.clone(), self.1) + } +} + +pub fn validate_serial_number(input: &[u8]) -> bool { + input == DEFAULT_SERIAL_NUMBER + || input + .iter() + .all(|c| c.is_ascii_alphanumeric() || matches!(c, b'-' | b'_' | b'.')) +} + +#[test] +fn test_validate_city_name_works() { + assert_eq!(validate_city_name(b"Rio de Janeiro"), true); + assert_eq!(validate_city_name(b"Ghent"), true); + assert_eq!(validate_city_name(b"Cairo"), true); + assert_eq!( + validate_city_name(&vec![76, 105, 195, 168, 103, 101]), // b"Liège" + true + ); + + assert_eq!(validate_city_name(b"Los_Angeles"), false); +} + +#[test] +fn test_validate_country_name_works() { + assert_eq!(validate_country_name(b"Brazil"), true); + assert_eq!(validate_country_name(b"Belgium"), true); + assert_eq!(validate_country_name(b"Egypt"), true); + assert_eq!(validate_country_name(b"U.S.A"), true); + + assert_eq!(validate_country_name(b"Costa_Rica"), false); +} + +#[test] +fn test_validate_latitude_input_works() { + assert_eq!(validate_latitude_input(b"90.0"), true); + assert_eq!(validate_latitude_input(b"-90.0"), true); + assert_eq!(validate_latitude_input(b"0.0"), true); + + assert_eq!(validate_latitude_input(b"90.00001"), false); // 10e-5 sensitive + assert_eq!(validate_latitude_input(b"-90.00001"), false); // 10e-5 sensitive + assert_eq!(validate_longitude_input(b"30,35465"), false); + assert_eq!(validate_latitude_input(b"garbage data"), false); +} + +#[test] +fn test_validate_longitude_input_works() { + assert_eq!(validate_longitude_input(b"180.0"), true); + assert_eq!(validate_longitude_input(b"-180.0"), true); + assert_eq!(validate_longitude_input(b"0.0"), true); + + assert_eq!(validate_longitude_input(b"180.00001"), false); // 10e-5 sensitive + assert_eq!(validate_longitude_input(b"-180.00001"), false); // 10e-5 sensitive + assert_eq!(validate_longitude_input(b"30,35465"), false); + assert_eq!(validate_longitude_input(b"garbage data"), false); +} diff --git a/substrate-node/pallets/pallet-tfgrid/src/nodes_migration.rs b/substrate-node/pallets/pallet-tfgrid/src/nodes_migration.rs deleted file mode 100644 index 00f7bdcd2..000000000 --- a/substrate-node/pallets/pallet-tfgrid/src/nodes_migration.rs +++ /dev/null @@ -1,103 +0,0 @@ -use super::Config; -use super::*; -use frame_support::{traits::Get, weights::Weight}; -use log::{debug, info}; -use sp_std::collections::btree_map::BTreeMap; - -#[cfg(feature = "try-runtime")] -use frame_support::traits::OnRuntimeUpgradeHelpersExt; -#[cfg(feature = "try-runtime")] -use sp_runtime::SaturatedConversion; - -pub mod v9 { - use super::*; - use crate::Config; - - use frame_support::{pallet_prelude::Weight, traits::OnRuntimeUpgrade}; - use sp_std::marker::PhantomData; - pub struct FixFarmNodeIndexMap(PhantomData); - - impl OnRuntimeUpgrade for FixFarmNodeIndexMap { - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result<(), &'static str> { - assert!(PalletVersion::::get() == types::StorageVersion::V9Struct); - - // Store number of nodes in temp storage - let nodes_count: u64 = Nodes::::iter_keys().count().saturated_into(); - Self::set_temp_storage(nodes_count, "pre_nodes_count"); - log::info!( - "🔎 FixFarmingPolicy pre migration: Number of existing nodes {:?}", - nodes_count - ); - - info!("👥 TFGrid pallet to V10 passes PRE migrate checks ✅",); - Ok(()) - } - - fn on_runtime_upgrade() -> Weight { - if PalletVersion::::get() == types::StorageVersion::V9Struct { - add_farm_nodes_index::() - } else { - info!(" >>> Unused migration"); - return 0; - } - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade() -> Result<(), &'static str> { - assert!(PalletVersion::::get() >= types::StorageVersion::V10Struct); - - // Check number of nodes against pre-check result - let pre_nodes_count = Self::get_temp_storage("pre_nodes_count").unwrap_or(0u64); - assert_eq!( - Nodes::::iter().count().saturated_into::(), - pre_nodes_count, - "Number of nodes migrated does not match" - ); - - info!( - "👥 TFGrid pallet migration to {:?} passes POST migrate checks ✅", - Pallet::::pallet_version() - ); - - Ok(()) - } - } -} - -pub fn add_farm_nodes_index() -> frame_support::weights::Weight { - info!(" >>> Migrating nodes storage..."); - - NodesByFarmID::::remove_all(None); - - let mut reads = 0; - let mut writes = 0; - - let mut farms_with_nodes: BTreeMap> = BTreeMap::new(); - for (_, node) in Nodes::::iter() { - // Add index of farm - list (nodes) - farms_with_nodes - .entry(node.farm_id) - .or_insert(vec![]) - .push(node.id); - - reads += 1; - } - - for (farm_id, nodes) in farms_with_nodes.iter() { - debug!( - "inserting nodes: {:?} with farm id: {:?}", - nodes.clone(), - farm_id - ); - NodesByFarmID::::insert(farm_id, nodes); - writes += 1; - } - - // Update pallet storage version - PalletVersion::::set(types::StorageVersion::V10Struct); - info!(" <<< Storage version upgraded"); - - // Return the weight consumed by the migration. - T::DbWeight::get().reads_writes(reads as Weight, writes as Weight) -} diff --git a/substrate-node/pallets/pallet-tfgrid/src/pub_config.rs b/substrate-node/pallets/pallet-tfgrid/src/pub_config.rs deleted file mode 100644 index 76a9d8865..000000000 --- a/substrate-node/pallets/pallet-tfgrid/src/pub_config.rs +++ /dev/null @@ -1,248 +0,0 @@ -use sp_std::{marker::PhantomData, vec::Vec}; - -use crate::{Config, Error}; -use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::{ - ensure, sp_runtime::SaturatedConversion, traits::ConstU32, BoundedVec, RuntimeDebug, -}; -use scale_info::TypeInfo; -use valip::{ - ip4::{Ip as IPv4, CIDR as IPv4Cidr}, - ip6::{Ip as IPv6, CIDR as IPv6Cidr}, -}; - -/// A Public IP. -/// Needs to be valid format (ipv4 with cidr and in public range) -#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[scale_info(skip_type_params(T))] -#[codec(mel_bound())] -pub struct IP4( - pub BoundedVec>, - PhantomData<(T, ConstU32)>, -); - -pub const MIN_IP_LENGHT: u32 = 9; -pub const MAX_IP_LENGTH: u32 = 18; - -impl TryFrom> for IP4 { - type Error = Error; - - /// Fallible initialization from a provided byte vector if it is below the - /// minimum or exceeds the maximum allowed length or contains invalid ASCII - /// characters. - fn try_from(value: Vec) -> Result { - ensure!( - value.len() >= MIN_IP_LENGHT.saturated_into(), - Self::Error::IP4ToShort - ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::IP4ToLong)?; - ensure!( - IPv4Cidr::parse(&bounded_vec).is_ok(), - Self::Error::InvalidIP4 - ); - Ok(Self(bounded_vec, PhantomData)) - } -} - -// FIXME: did not find a way to automatically implement this. -impl PartialEq for IP4 { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -// FIXME: did not find a way to automatically implement this. -impl Clone for IP4 { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) - } -} - -/// A Public IP Gateway. -/// Needs to be valid format (ipv4 without cidr) -#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[scale_info(skip_type_params(T))] -#[codec(mel_bound())] -pub struct GW4( - pub BoundedVec>, - PhantomData<(T, ConstU32)>, -); - -pub const MIN_GATEWAY_LENGTH: u32 = 7; -pub const MAX_GATEWAY_LENGTH: u32 = 15; - -impl TryFrom> for GW4 { - type Error = Error; - - /// Fallible initialization from a provided byte vector if it is below the - /// minimum or exceeds the maximum allowed length or contains invalid ASCII - /// characters. - fn try_from(value: Vec) -> Result { - ensure!( - value.len() >= MIN_GATEWAY_LENGTH.saturated_into(), - Self::Error::GW4ToShort - ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::GW4ToLong)?; - ensure!(IPv4::parse(&bounded_vec).is_ok(), Self::Error::InvalidGW4); - Ok(Self(bounded_vec, PhantomData)) - } -} - -// FIXME: did not find a way to automatically implement this. -impl PartialEq for GW4 { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -// FIXME: did not find a way to automatically implement this. -impl Clone for GW4 { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) - } -} - -/// Public Config IP6. -/// Needs to be valid format (ipv6 with cidr and in public range) -#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[scale_info(skip_type_params(T))] -#[codec(mel_bound())] -pub struct IP6( - pub BoundedVec>, - PhantomData<(T, ConstU32)>, -); - -pub const MIN_IP6_LENGHT: u32 = 3; -pub const MAX_IP6_LENGTH: u32 = 43; - -impl TryFrom> for IP6 { - type Error = Error; - - /// Fallible initialization from a provided byte vector if it is below the - /// minimum or exceeds the maximum allowed length or contains invalid ASCII - /// characters. - fn try_from(value: Vec) -> Result { - ensure!( - value.len() >= MIN_IP6_LENGHT.saturated_into(), - Self::Error::IP6ToShort - ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::IP6ToLong)?; - ensure!( - IPv6Cidr::parse(&bounded_vec).is_ok(), - Self::Error::InvalidIP6 - ); - Ok(Self(bounded_vec, PhantomData)) - } -} - -// FIXME: did not find a way to automatically implement this. -impl PartialEq for IP6 { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -// FIXME: did not find a way to automatically implement this. -impl Clone for IP6 { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) - } -} - -/// A Public Config IP6 gateway -/// Needs to be valid format (ipv6 without CIDR) -#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[scale_info(skip_type_params(T))] -#[codec(mel_bound())] -pub struct GW6( - pub BoundedVec>, - PhantomData<(T, ConstU32)>, -); - -pub const MAX_GW6_LENGTH: u32 = 39; - -impl TryFrom> for GW6 { - type Error = Error; - - /// Fallible initialization from a provided byte vector if it is below the - /// minimum or exceeds the maximum allowed length or contains invalid ASCII - /// characters. - fn try_from(value: Vec) -> Result { - ensure!( - value.len() >= MIN_IP6_LENGHT.saturated_into(), - Self::Error::GW6ToShort - ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::GW6ToLong)?; - ensure!(IPv6::parse(&bounded_vec).is_ok(), Self::Error::InvalidGW6); - Ok(Self(bounded_vec, PhantomData)) - } -} - -// FIXME: did not find a way to automatically implement this. -impl PartialEq for GW6 { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -// FIXME: did not find a way to automatically implement this. -impl Clone for GW6 { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) - } -} - -/// A Public Config Domain -/// Needs to be valid format (ASCI Characters or numbers and dash). -#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[scale_info(skip_type_params(T))] -#[codec(mel_bound())] -pub struct Domain( - pub BoundedVec>, - PhantomData<(T, ConstU32)>, -); - -pub const MIN_DOMAIN_NAME_LENGTH: u32 = 4; -pub const MAX_DOMAIN_NAME_LENGTH: u32 = 128; - -impl TryFrom> for Domain { - type Error = Error; - - fn try_from(value: Vec) -> Result { - ensure!( - value.len() >= MIN_DOMAIN_NAME_LENGTH.saturated_into(), - Self::Error::DomainToShort - ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::DomainToLong)?; - ensure!( - validate_domain_name(&bounded_vec), - Self::Error::InvalidDomain - ); - Ok(Self(bounded_vec, PhantomData)) - } -} - -// FIXME: did not find a way to automatically implement this. -impl PartialEq for Domain { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -// FIXME: did not find a way to automatically implement this. -impl Clone for Domain { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) - } -} - -fn validate_domain_name(input: &[u8]) -> bool { - input - .iter() - .all(|c| matches!(c, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'.')) -} diff --git a/substrate-node/pallets/pallet-tfgrid/src/pub_ip.rs b/substrate-node/pallets/pallet-tfgrid/src/pub_ip.rs deleted file mode 100644 index c8a98409e..000000000 --- a/substrate-node/pallets/pallet-tfgrid/src/pub_ip.rs +++ /dev/null @@ -1,106 +0,0 @@ -use sp_std::{marker::PhantomData, vec::Vec}; - -use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::{ - ensure, sp_runtime::SaturatedConversion, traits::ConstU32, BoundedVec, RuntimeDebug, -}; -use scale_info::TypeInfo; -use valip::ip4::{Ip, CIDR}; - -use crate::{Config, Error}; - -/// A Public IP. -/// Needs to be valid format (ipv4 with cidr and in public range) -#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[scale_info(skip_type_params(T))] -#[codec(mel_bound())] -pub struct PublicIP( - pub BoundedVec>, - PhantomData<(T, ConstU32)>, -); - -pub const MIN_IP_LENGHT: u32 = 9; -pub const MAX_IP_LENGTH: u32 = 18; - -impl TryFrom> for PublicIP { - type Error = Error; - - /// Fallible initialization from a provided byte vector if it is below the - /// minimum or exceeds the maximum allowed length or contains invalid ASCII - /// characters. - fn try_from(value: Vec) -> Result { - ensure!( - value.len() >= MIN_IP_LENGHT.saturated_into(), - Self::Error::PublicIPToShort - ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::PublicIPToLong)?; - ensure!( - CIDR::parse(&bounded_vec).is_ok(), - Self::Error::InvalidPublicIP - ); - Ok(Self(bounded_vec, PhantomData)) - } -} - -// FIXME: did not find a way to automatically implement this. -impl PartialEq for PublicIP { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -// FIXME: did not find a way to automatically implement this. -impl Clone for PublicIP { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) - } -} - -/// A Public IP Gateway. -/// Needs to be valid format (ipv4 without cidr) -#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[scale_info(skip_type_params(T))] -#[codec(mel_bound())] -pub struct GatewayIP( - pub BoundedVec>, - PhantomData<(T, ConstU32)>, -); - -pub const MIN_GATEWAY_LENGTH: u32 = 7; -pub const MAX_GATEWAY_LENGTH: u32 = 15; - -impl TryFrom> for GatewayIP { - type Error = Error; - - /// Fallible initialization from a provided byte vector if it is below the - /// minimum or exceeds the maximum allowed length or contains invalid ASCII - /// characters. - fn try_from(value: Vec) -> Result { - ensure!( - value.len() >= MIN_GATEWAY_LENGTH.saturated_into(), - Self::Error::GatewayIPToShort - ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::GatewayIPToLong)?; - ensure!( - Ip::parse(&bounded_vec).is_ok(), - Self::Error::InvalidPublicIP - ); - Ok(Self(bounded_vec, PhantomData)) - } -} - -// FIXME: did not find a way to automatically implement this. -impl PartialEq for GatewayIP { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} - -// FIXME: did not find a way to automatically implement this. -impl Clone for GatewayIP { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) - } -} diff --git a/substrate-node/pallets/pallet-tfgrid/src/terms_cond.rs b/substrate-node/pallets/pallet-tfgrid/src/terms_cond.rs new file mode 100644 index 000000000..d01aa6ff5 --- /dev/null +++ b/substrate-node/pallets/pallet-tfgrid/src/terms_cond.rs @@ -0,0 +1,122 @@ +use crate::{Config, Error, TermsAndConditionsInput}; +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::{ + ensure, sp_runtime::SaturatedConversion, traits::ConstU32, BoundedVec, RuntimeDebug, +}; +use scale_info::TypeInfo; +use sp_std::marker::PhantomData; + +pub const MIN_DOCUMENT_LINK_LENGTH: u32 = 1; +pub const MAX_DOCUMENT_LINK_LENGTH: u32 = 2048; + +pub const MIN_DOCUMENT_HASH_LENGTH: u32 = 1; +pub const MAX_DOCUMENT_HASH_LENGTH: u32 = 50; + +/// Terms and conditions. +#[derive(Encode, Decode, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[scale_info(skip_type_params(T))] +#[codec(mel_bound())] +pub struct TermsAndConditions { + pub account_id: T::AccountId, + pub timestamp: u64, + pub document_link: BoundedVec>, + pub document_hash: BoundedVec>, + _marker: PhantomData, +} + +impl TryFrom> for TermsAndConditions { + type Error = Error; + + /// Fallible initialization from a provided tuple + /// (account id, timestamp, document link and document hash) + /// No check for account id and timestamp. + /// For document link and document hash check if byte vector + /// is below the minimum or exceeds the maximum allowed length. + /// Also check if byte vector only contains allowed ASCII characters. + fn try_from(value: TermsAndConditionsInput) -> Result { + ensure!( + value.document_link.len() >= MIN_DOCUMENT_LINK_LENGTH.saturated_into(), + Self::Error::DocumentLinkInputTooShort + ); + ensure!( + value.document_link.len() <= MAX_DOCUMENT_LINK_LENGTH.saturated_into(), + Self::Error::DocumentLinkInputTooLong + ); + ensure!( + validate_document_link_input(&value.document_link), + Self::Error::InvalidDocumentLinkInput + ); + + ensure!( + value.document_hash.len() >= MIN_DOCUMENT_HASH_LENGTH.saturated_into(), + Self::Error::DocumentHashInputTooShort + ); + ensure!( + value.document_hash.len() <= MAX_DOCUMENT_HASH_LENGTH.saturated_into(), + Self::Error::DocumentHashInputTooLong + ); + ensure!( + validate_document_hash_input(&value.document_hash), + Self::Error::InvalidDocumentHashInput + ); + + Ok(Self { + account_id: value.account_id, + timestamp: value.timestamp, + document_link: value.document_link, + document_hash: value.document_hash, + _marker: PhantomData, + }) + } +} + +// FIXME: did not find a way to automatically implement this. +impl PartialEq for TermsAndConditions { + fn eq(&self, other: &Self) -> bool { + self.account_id == other.account_id + && self.timestamp == other.timestamp + && self.document_link == other.document_link + && self.document_hash == other.document_hash + } +} + +// FIXME: did not find a way to automatically implement this. +impl Clone for TermsAndConditions { + fn clone(&self) -> Self { + Self { + account_id: self.account_id.clone(), + timestamp: self.timestamp.clone(), + document_link: self.document_link.clone(), + document_hash: self.document_hash.clone(), + _marker: PhantomData, + } + } +} + +fn validate_document_link_input(input: &[u8]) -> bool { + // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;= + input + .iter() + .all(|c| matches!(c, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' | b':' | b'/' | b'?' | b'#' | b'[' | b']' | b'@' | b'!' | b'$' | b'&' | b'\'' | b'(' | b')' | b'*' | b'+' | b',' | b';' | b'=')) +} + +fn validate_document_hash_input(input: &[u8]) -> bool { + // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_ + input + .iter() + .all(|c| matches!(c, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'_')) +} + +#[test] +fn test_validate_document_link_input_works() { + assert_eq!( + validate_document_link_input( + b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=" + ), + true + ); + assert_eq!( + validate_document_link_input(b"http://zos.tf/terms/v0.1"), + true + ); +} diff --git a/substrate-node/pallets/pallet-tfgrid/src/tests.rs b/substrate-node/pallets/pallet-tfgrid/src/tests.rs index f3c5fb59b..9bcea3a09 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/tests.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/tests.rs @@ -1,15 +1,14 @@ use super::Event as TfgridEvent; use crate::{ - mock::Event as MockEvent, mock::*, types::PublicIpInput, Error, InterfaceInput, - InterfaceIpsInput, PublicIpListInput, + mock::RuntimeEvent as MockEvent, mock::*, types::LocationInput, Error, InterfaceInput, + InterfaceIpsInput, PublicIpListInput, ResourcesInput, }; -use frame_support::{assert_noop, assert_ok, bounded_vec, BoundedVec}; +use frame_support::{assert_noop, assert_ok, bounded_vec}; use frame_system::{EventRecord, Phase, RawOrigin}; use sp_core::H256; -use tfchain_support::resources; use tfchain_support::types::{ - FarmCertification, FarmingPolicyLimit, Interface, Location, NodeCertification, PublicConfig, - Resources, IP, + FarmCertification, FarmingPolicyLimit, Interface, NodeCertification, PublicConfig, + PublicIpError, IP4, IP6, }; const GIGABYTE: u64 = 1024 * 1024 * 1024; @@ -32,16 +31,14 @@ fn test_update_entity_works() { ExternalityBuilder::build().execute_with(|| { create_entity(); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); // Change name to barfoo - let name = "barfoo".as_bytes().to_vec(); + let name = b"barfoo".to_vec(); assert_ok!(TfgridModule::update_entity( - Origin::signed(test_ed25519()), + RuntimeOrigin::signed(test_ed25519()), name, - country, - city + get_country_name_input(b"Belgium"), + get_city_name_input(b"Ghent"), )); }); } @@ -51,13 +48,16 @@ fn test_update_entity_fails_if_signed_by_someone_else() { ExternalityBuilder::build().execute_with(|| { create_entity(); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); // Change name to barfoo - let name = "barfoo".as_bytes().to_vec(); + let name = b"barfoo".to_vec(); assert_noop!( - TfgridModule::update_entity(Origin::signed(bob()), name, country, city), + TfgridModule::update_entity( + RuntimeOrigin::signed(bob()), + name, + get_country_name_input(b"Belgium"), + get_city_name_input(b"Ghent"), + ), Error::::EntityNotExists ); }); @@ -68,19 +68,20 @@ fn test_create_entity_double_fails() { ExternalityBuilder::build().execute_with(|| { create_entity(); - let name = "foobar".as_bytes().to_vec(); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); - let signature = sign_create_entity(name.clone(), country.clone(), city.clone()); + let name = b"foobar".to_vec(); + let country = get_country_name_input(b"Belgium"); + let city = get_city_name_input(b"Ghent"); + + let signature = sign_create_entity(name.clone(), country.to_vec(), city.to_vec()); assert_noop!( TfgridModule::create_entity( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), test_ed25519(), name, country, city, - signature + signature, ), Error::::EntityWithNameExists ); @@ -92,20 +93,20 @@ fn test_create_entity_double_fails_with_same_pubkey() { ExternalityBuilder::build().execute_with(|| { create_entity(); - let name = "barfoo".as_bytes().to_vec(); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); + let name = b"barfoo".to_vec(); + let country = get_country_name_input(b"Belgium"); + let city = get_city_name_input(b"Ghent"); - let signature = sign_create_entity(name.clone(), country.clone(), city.clone()); + let signature = sign_create_entity(name.clone(), country.to_vec(), city.to_vec()); assert_noop!( TfgridModule::create_entity( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), test_ed25519(), name, country, city, - signature + signature, ), Error::::EntityWithPubkeyExists ); @@ -117,7 +118,9 @@ fn test_delete_entity_works() { ExternalityBuilder::build().execute_with(|| { create_entity(); - assert_ok!(TfgridModule::delete_entity(Origin::signed(test_ed25519()))); + assert_ok!(TfgridModule::delete_entity(RuntimeOrigin::signed( + test_ed25519() + ))); }); } @@ -127,7 +130,7 @@ fn test_delete_entity_fails_if_signed_by_someone_else() { create_entity(); assert_noop!( - TfgridModule::delete_entity(Origin::signed(bob())), + TfgridModule::delete_entity(RuntimeOrigin::signed(bob())), Error::::EntityNotExists ); }); @@ -136,19 +139,16 @@ fn test_delete_entity_fails_if_signed_by_someone_else() { #[test] fn test_create_twin_works() { ExternalityBuilder::build().execute_with(|| { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - assert_ok!(TfgridModule::user_accept_tc( - Origin::signed(test_ed25519()), - document, - hash, + RuntimeOrigin::signed(test_ed25519()), + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), )); - let ip = get_twin_ip(b"::1"); + let ip = get_twin_ip_input(b"::1"); assert_ok!(TfgridModule::create_twin( - Origin::signed(test_ed25519()), - ip.clone().0 + RuntimeOrigin::signed(test_ed25519()), + ip, )); }); } @@ -156,23 +156,23 @@ fn test_create_twin_works() { #[test] fn test_delete_twin_works() { ExternalityBuilder::build().execute_with(|| { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - assert_ok!(TfgridModule::user_accept_tc( - Origin::signed(alice()), - document, - hash, + RuntimeOrigin::signed(alice()), + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), )); - let ip = get_twin_ip(b"::1"); + let ip = get_twin_ip_input(b"::1"); assert_ok!(TfgridModule::create_twin( - Origin::signed(alice()), - ip.clone().0 + RuntimeOrigin::signed(alice()), + ip )); let twin_id = 1; - assert_ok!(TfgridModule::delete_twin(Origin::signed(alice()), twin_id)); + assert_ok!(TfgridModule::delete_twin( + RuntimeOrigin::signed(alice()), + twin_id + )); }); } @@ -187,7 +187,10 @@ fn test_delete_node_works() { assert_eq!(nodes.len(), 1); assert_eq!(nodes[0], 1); - assert_ok!(TfgridModule::delete_node_farm(Origin::signed(alice()), 1)); + assert_ok!(TfgridModule::delete_node_farm( + RuntimeOrigin::signed(alice()), + 1 + )); let nodes = TfgridModule::nodes_by_farm_id(1); assert_eq!(nodes.len(), 0); @@ -203,7 +206,7 @@ fn test_delete_node_fails_if_not_authorized() { create_node(); assert_noop!( - TfgridModule::delete_node_farm(Origin::signed(bob()), 1), + TfgridModule::delete_node_farm(RuntimeOrigin::signed(bob()), 1), Error::::FarmerNotAuthorized ); }); @@ -223,7 +226,7 @@ fn test_add_entity_to_twin() { // Bob adds someone as entity to his twin assert_ok!(TfgridModule::add_twin_entity( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), twin_id, entity_id, signature @@ -244,7 +247,12 @@ fn test_add_entity_to_twin_fails_with_invalid_signature() { let entity_id = 1; assert_noop!( - TfgridModule::add_twin_entity(Origin::signed(bob()), twin_id, entity_id, signature), + TfgridModule::add_twin_entity( + RuntimeOrigin::signed(bob()), + twin_id, + entity_id, + signature + ), Error::::EntitySignatureDoesNotMatch ); }); @@ -265,14 +273,19 @@ fn test_add_entity_to_twin_fails_if_entity_is_added_twice() { let entity_id = 1; assert_ok!(TfgridModule::add_twin_entity( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), twin_id, entity_id, signature.clone() )); assert_noop!( - TfgridModule::add_twin_entity(Origin::signed(bob()), twin_id, entity_id, signature), + TfgridModule::add_twin_entity( + RuntimeOrigin::signed(bob()), + twin_id, + entity_id, + signature + ), Error::::EntityWithSignatureAlreadyExists ); }); @@ -283,9 +296,9 @@ fn test_create_twin_double_fails() { ExternalityBuilder::build().execute_with(|| { create_twin(); - let ip = get_twin_ip(b"::1"); + let ip = get_twin_ip_input(b"::1"); assert_noop!( - TfgridModule::create_twin(Origin::signed(alice()), ip.clone().0), + TfgridModule::create_twin(RuntimeOrigin::signed(alice()), ip), Error::::TwinWithPubkeyExists ); }); @@ -306,27 +319,27 @@ fn test_create_farm_invalid_name_fails() { create_entity(); create_twin(); - let farm_name = BoundedVec::try_from(b"test.farm".to_vec()).unwrap(); + let farm_name = get_farm_name_input(b"test.farm"); assert_noop!( - TfgridModule::create_farm(Origin::signed(alice()), farm_name, bounded_vec![]), + TfgridModule::create_farm(RuntimeOrigin::signed(alice()), farm_name, bounded_vec![]), Error::::InvalidFarmName ); - let farm_name = BoundedVec::try_from(b"test farm".to_vec()).unwrap(); + let farm_name = get_farm_name_input(b"test farm"); assert_noop!( - TfgridModule::create_farm(Origin::signed(alice()), farm_name, bounded_vec![]), + TfgridModule::create_farm(RuntimeOrigin::signed(alice()), farm_name, bounded_vec![]), Error::::InvalidFarmName ); - let farm_name = BoundedVec::try_from(b"".to_vec()).unwrap(); + let farm_name = get_farm_name_input(b""); assert_noop!( - TfgridModule::create_farm(Origin::signed(alice()), farm_name, bounded_vec![]), + TfgridModule::create_farm(RuntimeOrigin::signed(alice()), farm_name, bounded_vec![]), Error::::FarmNameTooShort ); - let farm_name = BoundedVec::try_from(b"12".to_vec()).unwrap(); + let farm_name = get_farm_name_input(b"12"); assert_noop!( - TfgridModule::create_farm(Origin::signed(alice()), farm_name, bounded_vec![]), + TfgridModule::create_farm(RuntimeOrigin::signed(alice()), farm_name, bounded_vec![]), Error::::FarmNameTooShort ); }); @@ -339,18 +352,19 @@ fn test_update_farm_name_works() { create_farm(); create_twin_bob(); - let farm_name = get_farm_name(b"bob_farm"); + + let farm_name = get_farm_name_input(b"bob_farm"); assert_ok!(TfgridModule::create_farm( - Origin::signed(bob()), - farm_name.0.clone(), + RuntimeOrigin::signed(bob()), + farm_name, bounded_vec![] )); - let farm_name = get_farm_name(b"bob_updated_farm"); + let farm_name = get_farm_name_input(b"bob_updated_farm"); assert_ok!(TfgridModule::update_farm( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 2, - farm_name.0.clone(), + farm_name, )); }); } @@ -360,25 +374,25 @@ fn test_update_farm_existing_name_fails() { ExternalityBuilder::build().execute_with(|| { create_twin(); - let farm_name = get_farm_name(b"alice_farm"); - + let farm_name = get_farm_name_input(b"alice_farm"); assert_ok!(TfgridModule::create_farm( - Origin::signed(alice()), - farm_name.0.clone(), + RuntimeOrigin::signed(alice()), + farm_name, bounded_vec![] )); create_twin_bob(); - let farm_name = get_farm_name(b"bob_farm"); + + let farm_name = get_farm_name_input(b"bob_farm"); assert_ok!(TfgridModule::create_farm( - Origin::signed(bob()), - farm_name.0.clone(), + RuntimeOrigin::signed(bob()), + farm_name, bounded_vec![] )); - let farm_name = get_farm_name(b"alice_farm"); + let farm_name = get_farm_name_input(b"alice_farm"); assert_noop!( - TfgridModule::update_farm(Origin::signed(bob()), 2, farm_name.0.clone()), + TfgridModule::update_farm(RuntimeOrigin::signed(bob()), 2, farm_name), Error::::InvalidFarmName ); }); @@ -390,23 +404,23 @@ fn test_create_farm_with_double_ip_fails() { create_entity(); create_twin(); - let farm_name = get_farm_name(b"test_farm"); + let farm_name = get_farm_name_input(b"test_farm"); let mut pub_ips: PublicIpListInput = bounded_vec![]; - let ip = get_public_ip_ip(&"185.206.122.33/24".as_bytes().to_vec()).0; - let gw = get_public_ip_gateway(&"185.206.122.1".as_bytes().to_vec()).0; + let ip = get_public_ip_ip_input(b"185.206.122.33/24"); + let gw = get_public_ip_gw_input(b"185.206.122.1"); pub_ips - .try_push(PublicIpInput { + .try_push(IP4 { ip: ip.clone(), gw: gw.clone(), }) .unwrap(); - pub_ips.try_push(PublicIpInput { ip, gw }).unwrap(); + pub_ips.try_push(IP4 { ip, gw }).unwrap(); assert_noop!( - TfgridModule::create_farm(Origin::signed(alice()), farm_name.0.clone(), pub_ips), + TfgridModule::create_farm(RuntimeOrigin::signed(alice()), farm_name, pub_ips), Error::::IpExists ); }); @@ -420,10 +434,10 @@ fn test_adding_ip_to_farm_works() { create_farm(); assert_ok!(TfgridModule::add_farm_ip( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, - get_public_ip_ip(&"185.206.122.125/16".as_bytes().to_vec()).0, - get_public_ip_gateway(&"185.206.122.1".as_bytes().to_vec()).0 + get_public_ip_ip_input(b"185.206.122.125/16"), + get_public_ip_gw_input(b"185.206.122.1"), )); }); } @@ -437,10 +451,10 @@ fn test_adding_misformatted_ip_to_farm_fails() { assert_noop!( TfgridModule::add_farm_ip( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, - "185.206.122.125".as_bytes().to_vec().try_into().unwrap(), - get_public_ip_gateway(&"185.206.122.1".as_bytes().to_vec()).0 + get_public_ip_ip_input(b"185.206.122.125"), + get_public_ip_gw_input(b"185.206.122.1"), ), Error::::InvalidPublicIP ); @@ -454,7 +468,7 @@ fn test_delete_farm_fails() { create_twin(); create_farm(); assert_noop!( - TfgridModule::delete_farm(Origin::signed(alice()), 1), + TfgridModule::delete_farm(RuntimeOrigin::signed(alice()), 1), Error::::MethodIsDeprecated ); }); @@ -468,18 +482,18 @@ fn test_adding_ip_duplicate_to_farm_fails() { create_farm(); assert_ok!(TfgridModule::add_farm_ip( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, - get_public_ip_ip(&"185.206.122.125/16".as_bytes().to_vec()).0, - get_public_ip_gateway(&"185.206.122.1".as_bytes().to_vec()).0 + get_public_ip_ip_input(b"185.206.122.125/16"), + get_public_ip_gw_input(b"185.206.122.1"), )); assert_noop!( TfgridModule::add_farm_ip( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, - get_public_ip_ip(&"185.206.122.125/16".as_bytes().to_vec()).0, - get_public_ip_gateway(&"185.206.122.1".as_bytes().to_vec()).0 + get_public_ip_ip_input(b"185.206.122.125/16"), + get_public_ip_gw_input(b"185.206.122.1"), ), Error::::IpExists ); @@ -534,10 +548,10 @@ fn test_update_twin_works() { ExternalityBuilder::build().execute_with(|| { create_twin(); - let ip = get_twin_ip(b"::1"); + let ip = get_twin_ip_input(b"::1"); assert_ok!(TfgridModule::update_twin( - Origin::signed(alice()), - ip.clone().0 + RuntimeOrigin::signed(alice()), + ip )); }); } @@ -545,24 +559,20 @@ fn test_update_twin_works() { #[test] fn test_update_twin_fails_if_signed_by_someone_else() { ExternalityBuilder::build().execute_with(|| { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - assert_ok!(TfgridModule::user_accept_tc( - Origin::signed(alice()), - document, - hash, + RuntimeOrigin::signed(alice()), + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), )); - let ip = get_twin_ip(b"::1"); + let ip = get_twin_ip_input(b"::1"); assert_ok!(TfgridModule::create_twin( - Origin::signed(alice()), - ip.clone().0 + RuntimeOrigin::signed(alice()), + ip.clone() )); - let ip = get_twin_ip(b"::1"); assert_noop!( - TfgridModule::update_twin(Origin::signed(bob()), ip.clone().0), + TfgridModule::update_twin(RuntimeOrigin::signed(bob()), ip), Error::::TwinNotExists ); }); @@ -575,12 +585,12 @@ fn test_create_farm_with_same_name_fails() { create_twin(); create_farm(); - let farm_name = get_farm_name(b"test_farm"); + let farm_name = get_farm_name_input(b"test_farm"); let pub_ips: PublicIpListInput = bounded_vec![]; assert_noop!( - TfgridModule::create_farm(Origin::signed(alice()), farm_name.0.clone(), pub_ips), + TfgridModule::create_farm(RuntimeOrigin::signed(alice()), farm_name, pub_ips), Error::::FarmExists ); }); @@ -595,14 +605,14 @@ fn test_farm_add_stellar_payout_address() { let addr = "some_address".as_bytes().to_vec(); assert_ok!(TfgridModule::add_stellar_payout_v2address( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, addr )); let addr2 = "some_other_address".as_bytes().to_vec(); assert_ok!(TfgridModule::add_stellar_payout_v2address( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, addr2 )); @@ -664,33 +674,31 @@ fn update_node_moved_from_farm_list_works() { assert_eq!(nodes.len(), 1); assert_eq!(nodes[0], 1); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); - - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1024 * GIGABYTE, sru: 512 * GIGABYTE, cru: 8, mru: 16 * GIGABYTE, }; + + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; + assert_ok!(TfgridModule::update_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 2, resources, location, - country, - city, - Vec::new().try_into().unwrap(), + bounded_vec![], true, true, - "some_serial".as_bytes().to_vec(), + None, )); // should be removed from farm 1 nodes @@ -718,7 +726,7 @@ fn update_certified_node_resources_loses_certification_works() { )); assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Certified )); @@ -727,21 +735,26 @@ fn update_certified_node_resources_loses_certification_works() { assert_eq!(node.certification, NodeCertification::Certified); // Change cores to 2 - let mut node_resources = node.resources; + let mut node_resources: ResourcesInput = node.resources; node_resources.cru = 2; + let node_location = LocationInput { + city: node.location.city.0, + country: node.location.country.0, + latitude: node.location.latitude, + longitude: node.location.longitude, + }; + assert_ok!(TfgridModule::update_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 1, node_resources, - node.location, - node.country, - node.city, - Vec::new().try_into().unwrap(), + node_location, + bounded_vec![], true, true, - "some_serial".as_bytes().to_vec(), + None, )); let our_events = System::events(); @@ -771,7 +784,7 @@ fn update_certified_node_same_resources_keeps_certification_works() { )); assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Certified )); @@ -779,19 +792,26 @@ fn update_certified_node_same_resources_keeps_certification_works() { let node = TfgridModule::nodes(1).unwrap(); assert_eq!(node.certification, NodeCertification::Certified); + let node_resources: ResourcesInput = node.resources; + + let node_location = LocationInput { + city: node.location.city.0, + country: node.location.country.0, + latitude: node.location.latitude, + longitude: node.location.longitude, + }; + // Don't change resources assert_ok!(TfgridModule::update_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 1, - node.resources, - node.location, - node.country, - node.city, - Vec::new().try_into().unwrap(), + node_resources, + node_location, + bounded_vec![], true, true, - "some_serial".as_bytes().to_vec(), + None, )); let node = TfgridModule::nodes(1).unwrap(); @@ -806,32 +826,28 @@ fn create_node_with_interfaces_works() { create_twin(); create_farm(); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); - - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1024 * GIGABYTE, sru: 512 * GIGABYTE, cru: 8, mru: 16 * GIGABYTE, }; - let mut interface_ips: InterfaceIpsInput = bounded_vec![]; - let intf_ip_1 = get_interface_ip(&"10.2.3.3".as_bytes().to_vec()); - interface_ips.try_push(intf_ip_1.0).unwrap(); + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; - let name = get_interface_name(&"zos".as_bytes().to_vec()).0; - let mac = get_interface_mac(&"00:00:5e:00:53:af".as_bytes().to_vec()).0; + let mut interface_ips: InterfaceIpsInput = bounded_vec![]; + let intf_ip = get_interface_ip_input(b"10.2.3.3"); + interface_ips.try_push(intf_ip).unwrap(); let interface = Interface { - name, - mac, + name: get_interface_name_input(b"zos"), + mac: get_interface_mac_input(b"00:00:5e:00:53:af"), ips: interface_ips, }; @@ -839,16 +855,14 @@ fn create_node_with_interfaces_works() { interfaces.try_push(interface).unwrap(); assert_ok!(TfgridModule::create_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, resources, location, - country, - city, interfaces, true, true, - "some_serial".as_bytes().to_vec() + None, )); }); } @@ -918,7 +932,7 @@ fn set_certification_type_node_allowed_certifier_works() { )); assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Certified )); @@ -926,7 +940,7 @@ fn set_certification_type_node_allowed_certifier_works() { assert_eq!(node.certification, NodeCertification::Certified); assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Diy )); @@ -945,7 +959,7 @@ fn set_certification_type_node_not_allowed_certifier_fails() { assert_noop!( TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Certified ), @@ -1007,7 +1021,10 @@ fn node_report_uptime_works() { create_node(); Timestamp::set_timestamp(1628082000); - assert_ok!(TfgridModule::report_uptime(Origin::signed(alice()), 500)); + assert_ok!(TfgridModule::report_uptime( + RuntimeOrigin::signed(alice()), + 500 + )); }); } @@ -1019,37 +1036,39 @@ fn node_add_public_config_works() { create_farm(); create_node(); - let ipv4 = get_pub_config_ip4(&"185.206.122.33/24".as_bytes().to_vec()); - let ipv6 = get_pub_config_ip6(&"2a10:b600:1::0cc4:7a30:65b5/64".as_bytes().to_vec()); - let gw4 = get_pub_config_gw4(&"185.206.122.1".as_bytes().to_vec()); - let gw6 = get_pub_config_gw6(&"2a10:b600:1::1".as_bytes().to_vec()); + let ipv4 = get_pub_config_ip4_input(b"185.206.122.33/24"); + let ipv6 = get_pub_config_ip6_input(b"2a10:b600:1::0cc4:7a30:65b5/64"); + let gw4 = get_pub_config_gw4_input(b"185.206.122.1"); + let gw6 = get_pub_config_gw6_input(b"2a10:b600:1::1"); + let domain = get_pub_config_domain_input(b"some-domain"); - let pub_config = PublicConfig { - ip4: IP { - ip: ipv4.clone().0, - gw: gw4.clone().0, + let pub_config_input = PublicConfig { + ip4: IP4 { + ip: ipv4.clone(), + gw: gw4.clone(), }, - ip6: Some(IP { - ip: ipv6.clone().0, - gw: gw6.clone().0, + ip6: Some(IP6 { + ip: ipv6.clone(), + gw: gw6.clone(), }), - domain: Some("some-domain".as_bytes().to_vec().try_into().unwrap()), + domain: Some(domain.clone()), }; assert_ok!(TfgridModule::add_node_public_config( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 1, - Some(pub_config.clone()) + Some(pub_config_input) )); let node = TfgridModule::nodes(1).unwrap(); + assert_eq!( node.public_config, Some(PublicConfig { - ip4: IP { ip: ipv4, gw: gw4 }, - ip6: Some(IP { ip: ipv6, gw: gw6 }), - domain: Some("some-domain".as_bytes().to_vec().try_into().unwrap()), + ip4: IP4 { ip: ipv4, gw: gw4 }, + ip6: Some(IP6 { ip: ipv6, gw: gw6 }), + domain: Some(domain), }) ); }); @@ -1063,30 +1082,30 @@ fn node_add_public_config_without_ipv6_and_domain_works() { create_farm(); create_node(); - let ipv4 = get_pub_config_ip4(&"185.206.122.33/24".as_bytes().to_vec()); - let gw4 = get_pub_config_gw4(&"185.206.122.1".as_bytes().to_vec()); + let ipv4 = get_pub_config_ip4_input(b"185.206.122.33/24"); + let gw4 = get_pub_config_gw4_input(b"185.206.122.1"); - let pub_config = PublicConfig { - ip4: IP { - ip: ipv4.clone().0, - gw: gw4.clone().0, + let pub_config_input = PublicConfig { + ip4: IP4 { + ip: ipv4.clone(), + gw: gw4.clone(), }, ip6: None, domain: None, }; assert_ok!(TfgridModule::add_node_public_config( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 1, - Some(pub_config.clone()) + Some(pub_config_input) )); let node = TfgridModule::nodes(1).unwrap(); assert_eq!( node.public_config, Some(PublicConfig { - ip4: IP { ip: ipv4, gw: gw4 }, + ip4: IP4 { ip: ipv4, gw: gw4 }, ip6: None, domain: None, }) @@ -1102,29 +1121,24 @@ fn node_add_public_config_fails_if_signature_incorrect() { create_farm(); create_node(); - let ipv4 = get_pub_config_ip4(&"185.206.122.33/24".as_bytes().to_vec()); - let ipv6 = get_pub_config_ip6(&"2a10:b600:1::0cc4:7a30:65b5/64".as_bytes().to_vec()); - let gw4 = get_pub_config_gw4(&"185.206.122.1".as_bytes().to_vec()); - let gw6 = get_pub_config_gw6(&"2a10:b600:1::1".as_bytes().to_vec()); - - let pub_config = PublicConfig { - ip4: IP { - ip: ipv4.clone().0, - gw: gw4.clone().0, + let pub_config_input = PublicConfig { + ip4: IP4 { + ip: get_pub_config_ip4_input(b"185.206.122.33/24"), + gw: get_pub_config_gw4_input(b"185.206.122.1"), }, - ip6: Some(IP { - ip: ipv6.clone().0, - gw: gw6.clone().0, + ip6: Some(IP6 { + ip: get_pub_config_ip6_input(b"2a10:b600:1::0cc4:7a30:65b5/64"), + gw: get_pub_config_gw6_input(b"2a10:b600:1::1"), }), - domain: Some("some-domain".as_bytes().to_vec().try_into().unwrap()), + domain: Some(get_pub_config_domain_input(b"some-domain")), }; assert_noop!( TfgridModule::add_node_public_config( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, 1, - Some(pub_config.clone()) + Some(pub_config_input) ), Error::::CannotUpdateFarmWrongTwin ); @@ -1139,42 +1153,44 @@ fn test_unsetting_node_public_config_works() { create_farm(); create_node(); - let ipv4 = get_pub_config_ip4(&"185.206.122.33/24".as_bytes().to_vec()); - let ipv6 = get_pub_config_ip6(&"2a10:b600:1::0cc4:7a30:65b5/64".as_bytes().to_vec()); - let gw4 = get_pub_config_gw4(&"185.206.122.1".as_bytes().to_vec()); - let gw6 = get_pub_config_gw6(&"2a10:b600:1::1".as_bytes().to_vec()); + let ipv4 = get_pub_config_ip4_input(b"185.206.122.33/24"); + let ipv6 = get_pub_config_ip6_input(b"2a10:b600:1::0cc4:7a30:65b5/64"); + let gw4 = get_pub_config_gw4_input(b"185.206.122.1"); + let gw6 = get_pub_config_gw6_input(b"2a10:b600:1::1"); + let domain = get_pub_config_domain_input(b"some-domain"); - let pub_config = PublicConfig { - ip4: IP { - ip: ipv4.clone().0, - gw: gw4.clone().0, + let pub_config_input = PublicConfig { + ip4: IP4 { + ip: ipv4.clone(), + gw: gw4.clone(), }, - ip6: Some(IP { - ip: ipv6.clone().0, - gw: gw6.clone().0, + ip6: Some(IP6 { + ip: ipv6.clone(), + gw: gw6.clone(), }), - domain: Some("some-domain".as_bytes().to_vec().try_into().unwrap()), + domain: Some(domain.clone()), }; assert_ok!(TfgridModule::add_node_public_config( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 1, - Some(pub_config.clone()) + Some(pub_config_input) )); let node = TfgridModule::nodes(1).unwrap(); + assert_eq!( node.public_config, Some(PublicConfig { - ip4: IP { ip: ipv4, gw: gw4 }, - ip6: Some(IP { ip: ipv6, gw: gw6 }), - domain: Some("some-domain".as_bytes().to_vec().try_into().unwrap()), + ip4: IP4 { ip: ipv4, gw: gw4 }, + ip6: Some(IP6 { ip: ipv6, gw: gw6 }), + domain: Some(domain), }) ); assert_ok!(TfgridModule::add_node_public_config( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 1, None @@ -1193,64 +1209,102 @@ fn test_node_public_config_falsy_values_fails() { create_farm(); create_node(); - // let ipv4 = get_pub_config_ip4(&"1.1.1.1".as_bytes().to_vec()); - let ipv6 = get_pub_config_ip6(&"2a10:b600:1::0cc4:7a30:65b5/64".as_bytes().to_vec()); - let gw4 = get_pub_config_gw4(&"185.206.122.1".as_bytes().to_vec()); - let gw6 = get_pub_config_gw6(&"2a10:b600:1::1".as_bytes().to_vec()); - - let pub_config = PublicConfig { - ip4: IP { - ip: "1.1.1.1".as_bytes().to_vec().try_into().unwrap(), - gw: gw4.clone().0, + let pub_config_input = PublicConfig { + ip4: IP4 { + ip: get_pub_config_ip4_input(b"1.1.1.1"), // Too short + gw: get_pub_config_gw4_input(b"185.206.122.1"), }, - ip6: Some(IP { - ip: ipv6.clone().0, - gw: gw6.clone().0, + ip6: Some(IP6 { + ip: get_pub_config_ip6_input(b"2a10:b600:1::0cc4:7a30:65b5/64"), + gw: get_pub_config_gw6_input(b"2a10:b600:1::1"), }), - domain: Some("some-domain".as_bytes().to_vec().try_into().unwrap()), + domain: Some(get_pub_config_domain_input(b"some-domain")), }; assert_noop!( TfgridModule::add_node_public_config( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, 1, - Some(pub_config.clone()) + Some(pub_config_input) ), - Error::::IP4ToShort + Error::::InvalidPublicConfig ); }); } #[test] -#[should_panic(expected = "InvalidIP4")] -fn test_validate_invalid_ip4_1() { +fn test_validate_pub_config_invalid_ip4() { ExternalityBuilder::build().execute_with(|| { - TestIP4::try_from("185.206.122.33".as_bytes().to_vec()).expect("fails"); - }); -} + let ipv4 = get_pub_config_ip4_input(b"185.206.122.33"); + let ipv6 = get_pub_config_ip6_input(b"2a10:b600:1::0cc4:7a30:65b5/64"); + let gw4 = get_pub_config_gw4_input(b"185.206.122.1"); + let gw6 = get_pub_config_gw6_input(b"2a10:b600:1::1"); + let domain = get_pub_config_domain_input(b"some-domain"); -#[test] -#[should_panic(expected = "IP4ToShort")] -fn test_validate_invalid_ip4_2() { - ExternalityBuilder::build().execute_with(|| { - TestIP4::try_from("185.206".as_bytes().to_vec()).expect("fails"); + let pub_conf = PublicConfig { + ip4: IP4 { + ip: ipv4.clone(), + gw: gw4.clone(), + }, + ip6: Some(IP6 { + ip: ipv6.clone(), + gw: gw6.clone(), + }), + domain: Some(domain.clone()), + }; + + assert_noop!(pub_conf.is_valid(), PublicIpError::InvalidIp4); }); } #[test] -#[should_panic(expected = "IP4ToLong")] -fn test_validate_invalid_ip4_3() { +fn test_validate_pub_config_invalid_gw4() { ExternalityBuilder::build().execute_with(|| { - TestIP4::try_from("185.206.12.12.1232123".as_bytes().to_vec()).expect("fails"); + let ipv4 = get_pub_config_ip4_input(b"185.206.122.33/24"); + let ipv6 = get_pub_config_ip6_input(b"2a10:b600:1::0cc4:7a30:65b5/64"); + let gw4 = get_pub_config_gw4_input(b"185.206.132.1"); + let gw6 = get_pub_config_gw6_input(b"2a10:b600:1::1"); + let domain = get_pub_config_domain_input(b"some-domain"); + + let pub_conf = PublicConfig { + ip4: IP4 { + ip: ipv4.clone(), + gw: gw4.clone(), + }, + ip6: Some(IP6 { + ip: ipv6.clone(), + gw: gw6.clone(), + }), + domain: Some(domain.clone()), + }; + + assert_noop!(pub_conf.is_valid(), PublicIpError::InvalidPublicIp); }); } #[test] -#[should_panic(expected = "InvalidIP4")] -fn test_validate_invalid_ip4_4() { +fn test_validate_pub_config_invalid_ip6() { ExternalityBuilder::build().execute_with(|| { - TestIP4::try_from("garbage data".as_bytes().to_vec()).expect("fails"); + let ipv4 = get_pub_config_ip4_input(b"185.206.122.33/24"); + let ipv6 = get_pub_config_ip6_input(b"2a10::0cc4:7a30:65b5/32"); + let gw4 = get_pub_config_gw4_input(b"185.206.122.1"); + let gw6 = get_pub_config_gw6_input(b"2a10:b600:1::1"); + let domain = get_pub_config_domain_input(b"some-domain"); + + let pub_conf = PublicConfig { + ip4: IP4 { + ip: ipv4.clone(), + gw: gw4.clone(), + }, + ip6: Some(IP6 { + ip: ipv6.clone(), + gw: gw6.clone(), + }), + domain: Some(domain.clone()), + }; + + assert_noop!(pub_conf.is_valid(), PublicIpError::InvalidPublicIp); }); } @@ -1262,36 +1316,31 @@ fn create_node_with_same_pubkey_fails() { create_farm(); create_node(); - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1, sru: 1, cru: 1, mru: 1, }; - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); - - let interfaces: InterfaceInput = bounded_vec![]; + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; assert_noop!( TfgridModule::create_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, resources, location, - country, - city, - interfaces, + bounded_vec![], true, true, - "some_serial".as_bytes().to_vec() + None, ), Error::::NodeWithTwinIdExists ); @@ -1627,7 +1676,7 @@ fn node_switches_farming_policy_when_marked_as_certified_works() { alice() )); assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Certified, )); @@ -1658,7 +1707,7 @@ fn node_switches_farming_policy_when_marked_as_certified_toggle_works() { alice() )); assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Certified, )); @@ -1671,7 +1720,7 @@ fn node_switches_farming_policy_when_marked_as_certified_toggle_works() { ); assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Diy, )); @@ -1709,7 +1758,7 @@ fn node_switches_farming_policy_when_marked_as_certified_and_gold_farm_works() { )); // Mark node as certified assert_ok!(TfgridModule::set_node_certification( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, NodeCertification::Certified, )); @@ -2015,170 +2064,155 @@ fn test_set_invalid_zos_version_fails() { } fn create_entity() { - let name = "foobar".as_bytes().to_vec(); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); + let name = b"foobar".to_vec(); + let country = get_country_name_input(b"Belgium"); + let city = get_city_name_input(b"Ghent"); - let signature = sign_create_entity(name.clone(), country.clone(), city.clone()); + let signature = sign_create_entity(name.clone(), country.to_vec(), city.to_vec()); assert_ok!(TfgridModule::create_entity( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), test_ed25519(), name, country, city, - signature.clone() + signature, )); } fn create_entity_sr() { - let name = "foobar".as_bytes().to_vec(); - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); + let name = b"foobar".to_vec(); + let country = get_country_name_input(b"Belgium"); + let city = get_city_name_input(b"Ghent"); - let signature = sign_create_entity_sr(name.clone(), country.clone(), city.clone()); + let signature = sign_create_entity_sr(name.clone(), country.to_vec(), city.to_vec()); assert_ok!(TfgridModule::create_entity( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), test_sr25519(), name, country, city, - signature.clone() + signature, )); } fn create_twin() { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - assert_ok!(TfgridModule::user_accept_tc( - Origin::signed(alice()), - document, - hash, + RuntimeOrigin::signed(alice()), + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), )); - let ip = get_twin_ip(b"::1"); + let ip = get_twin_ip_input(b"::1"); assert_ok!(TfgridModule::create_twin( - Origin::signed(alice()), - ip.clone().0 + RuntimeOrigin::signed(alice()), + ip )); } fn create_twin_bob() { - let document = "some_link".as_bytes().to_vec(); - let hash = "some_hash".as_bytes().to_vec(); - assert_ok!(TfgridModule::user_accept_tc( - Origin::signed(bob()), - document, - hash, + RuntimeOrigin::signed(bob()), + get_document_link_input(b"some_link"), + get_document_hash_input(b"some_hash"), )); - let ip = get_twin_ip(b"::1"); - assert_ok!(TfgridModule::create_twin( - Origin::signed(bob()), - ip.clone().0 - )); + let ip = get_twin_ip_input(b"::1"); + assert_ok!(TfgridModule::create_twin(RuntimeOrigin::signed(bob()), ip)); } fn create_farm() { - let farm_name = get_farm_name(b"test_farm"); + let farm_name = get_farm_name_input(b"test_farm"); let mut pub_ips: PublicIpListInput = bounded_vec![]; - let ip = get_public_ip_ip(&"185.206.122.33/24".as_bytes().to_vec()).0; - let gw = get_public_ip_gateway(&"185.206.122.1".as_bytes().to_vec()).0; + let ip = get_public_ip_ip_input(b"185.206.122.33/24"); + let gw = get_public_ip_gw_input(b"185.206.122.1"); - pub_ips.try_push(PublicIpInput { ip, gw }).unwrap(); + pub_ips.try_push(IP4 { ip, gw }).unwrap(); assert_ok!(TfgridModule::create_farm( - Origin::signed(alice()), - farm_name.0.clone(), - pub_ips.clone() + RuntimeOrigin::signed(alice()), + farm_name, + pub_ips, )); create_farming_policies() } fn create_farm2() { - let farm_name = get_farm_name(b"test_farm2"); + let farm_name = get_farm_name_input(b"test_farm2"); let mut pub_ips: PublicIpListInput = bounded_vec![]; - let ip = get_public_ip_ip(&"185.206.122.33/24".as_bytes().to_vec()).0; - let gw = get_public_ip_gateway(&"185.206.122.1".as_bytes().to_vec()).0; + let ip = get_public_ip_ip_input(b"185.206.122.33/24"); + let gw = get_public_ip_gw_input(b"185.206.122.1"); - pub_ips.try_push(PublicIpInput { ip, gw }).unwrap(); + pub_ips.try_push(IP4 { ip, gw }).unwrap(); assert_ok!(TfgridModule::create_farm( - Origin::signed(alice()), - farm_name.0.clone(), - pub_ips.clone() + RuntimeOrigin::signed(alice()), + farm_name, + pub_ips, )); create_farming_policies() } fn create_node() { - let country = "Belgium".as_bytes().to_vec(); - let city = "Ghent".as_bytes().to_vec(); - - // random location - let location = Location { - longitude: "12.233213231".as_bytes().to_vec(), - latitude: "32.323112123".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1024 * GIGABYTE, sru: 512 * GIGABYTE, cru: 8, mru: 16 * GIGABYTE, }; + // random location + let location = LocationInput { + city: get_city_name_input(b"Ghent"), + country: get_country_name_input(b"Belgium"), + latitude: get_latitude_input(b"12.233213231"), + longitude: get_longitude_input(b"32.323112123"), + }; + let interfaces: InterfaceInput = bounded_vec![]; assert_ok!(TfgridModule::create_node( - Origin::signed(alice()), + RuntimeOrigin::signed(alice()), 1, resources, location, - country, - city, interfaces, true, true, - "some_serial".as_bytes().to_vec() + None, )); } fn create_extra_node() { - let country = "Brazil".as_bytes().to_vec(); - let city = "Rio de Janeiro".as_bytes().to_vec(); - - // random location - let location = Location { - longitude: "43.1868".as_bytes().to_vec(), - latitude: "22.9694".as_bytes().to_vec(), - }; - - let resources = Resources { + let resources = ResourcesInput { hru: 1024 * GIGABYTE, sru: 512 * GIGABYTE, cru: 8, mru: 16 * GIGABYTE, }; + // random location + let location = LocationInput { + city: get_city_name_input(b"Rio de Janeiro"), + country: get_country_name_input(b"Brazil"), + latitude: get_latitude_input(b"43.1868"), + longitude: get_longitude_input(b"22.9694"), + }; + assert_ok!(TfgridModule::create_node( - Origin::signed(bob()), + RuntimeOrigin::signed(bob()), 1, resources, location, - country, - city, - Vec::new().try_into().unwrap(), + bounded_vec![], true, true, - "some_serial".as_bytes().to_vec() + None, )); } @@ -2282,7 +2316,7 @@ fn create_custom_farming_policies() { )); } -fn record(event: Event) -> EventRecord { +fn record(event: RuntimeEvent) -> EventRecord { EventRecord { phase: Phase::Initialization, event, @@ -2326,8 +2360,8 @@ fn test_attach_farming_policy_flow(farming_policy_id: u32) { // Provide enough CU and SU limits to avoid attaching default policy to node // For node: [CU = 20; SU = 2] - assert_eq!(resources::get_cu(node.resources) <= limit.cu.unwrap(), true); - assert_eq!(resources::get_su(node.resources) <= limit.su.unwrap(), true); + assert_eq!(node.resources.get_cu() <= limit.cu.unwrap(), true); + assert_eq!(node.resources.get_su() <= limit.su.unwrap(), true); // Link farming policy to farm assert_ok!(TfgridModule::attach_policy_to_farm( diff --git a/substrate-node/pallets/pallet-tfgrid/src/twin.rs b/substrate-node/pallets/pallet-tfgrid/src/twin.rs index 796e99ac6..a040628f2 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/twin.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/twin.rs @@ -1,10 +1,11 @@ -use sp_std::{marker::PhantomData, vec::Vec}; - +use crate::{Config, Error, TwinIpInput}; use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::{ensure, sp_runtime::SaturatedConversion, BoundedVec, RuntimeDebug, traits::ConstU32}; +use frame_support::{ + ensure, sp_runtime::SaturatedConversion, traits::ConstU32, BoundedVec, RuntimeDebug, +}; use scale_info::TypeInfo; -use crate::{Config, Error}; -use valip::{{ip6::Ip}}; +use sp_std::marker::PhantomData; +use valip::ip6::Ip; /// A Twin planetary IP (ipv6). /// @@ -13,27 +14,30 @@ use valip::{{ip6::Ip}}; #[scale_info(skip_type_params(T))] #[codec(mel_bound())] pub struct TwinIp( - pub BoundedVec>, - PhantomData<(T, ConstU32<39>)>, + pub BoundedVec>, + PhantomData<(T, ConstU32)>, ); -pub const MIN_IP_LENGHT: u32 = 3; +pub const MIN_IP_LENGTH: u32 = 3; +pub const MAX_IP_LENGTH: u32 = 39; -impl TryFrom> for TwinIp { +impl TryFrom for TwinIp { type Error = Error; /// Fallible initialization from a provided byte vector if it is below the /// minimum or exceeds the maximum allowed length or contains invalid ASCII /// characters. - fn try_from(value: Vec) -> Result { + fn try_from(value: TwinIpInput) -> Result { ensure!( - value.len() >= MIN_IP_LENGHT.saturated_into(), + value.len() >= MIN_IP_LENGTH.saturated_into(), Self::Error::TwinIpTooShort ); - let bounded_vec: BoundedVec> = - BoundedVec::try_from(value).map_err(|_| Self::Error::TwinIpTooLong)?; - ensure!(Ip::parse(&bounded_vec).is_ok(), Self::Error::InvalidTwinIp); - Ok(Self(bounded_vec, PhantomData)) + ensure!( + value.len() <= MAX_IP_LENGTH.saturated_into(), + Self::Error::TwinIpTooLong + ); + ensure!(Ip::parse(&value).is_ok(), Self::Error::InvalidTwinIp); + Ok(Self(value, PhantomData)) } } diff --git a/substrate-node/pallets/pallet-tfgrid/src/types.rs b/substrate-node/pallets/pallet-tfgrid/src/types.rs index 899748141..4255dba6b 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/types.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/types.rs @@ -18,22 +18,24 @@ pub enum StorageVersion { V9Struct, V10Struct, V11Struct, + V12Struct, + V13Struct, } impl Default for StorageVersion { fn default() -> StorageVersion { - StorageVersion::V11Struct + StorageVersion::V13Struct } } #[derive(Encode, Decode, Debug, Default, PartialEq, Eq, Clone, TypeInfo)] -pub struct Entity { +pub struct Entity { pub version: u32, pub id: u32, pub name: Vec, pub account_id: AccountId, - pub country: Vec, - pub city: Vec, + pub country: Country, + pub city: City, } //digital twin @@ -158,19 +160,13 @@ pub struct FarmingPolicy { pub farm_certification: FarmCertification, } -impl PartialOrd for FarmingPolicy -where - B: Ord, -{ +impl PartialOrd for FarmingPolicy { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for FarmingPolicy -where - B: Ord, -{ +impl Ord for FarmingPolicy { fn cmp(&self, other: &Self) -> Ordering { match self.farm_certification.cmp(&other.farm_certification) { Ordering::Equal => self.node_certification.cmp(&other.node_certification), @@ -180,15 +176,17 @@ where } #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] -pub struct TermsAndConditions { +pub struct TermsAndConditionsInput { pub account_id: AccountId, pub timestamp: u64, - pub document_link: Vec, - pub document_hash: Vec, + pub document_link: DocLink, + pub document_hash: DocHash, } #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] -pub struct PublicIpInput { - pub ip: IP, - pub gw: GW, +pub struct LocationInput { + pub city: City, + pub country: Country, + pub latitude: Latitude, + pub longitude: Longitude, } diff --git a/substrate-node/pallets/pallet-tfgrid/src/weights.rs b/substrate-node/pallets/pallet-tfgrid/src/weights.rs index 3c71c83a6..3ed35beec 100644 --- a/substrate-node/pallets/pallet-tfgrid/src/weights.rs +++ b/substrate-node/pallets/pallet-tfgrid/src/weights.rs @@ -40,75 +40,77 @@ // --template // ./.maintain/frame-weight-template.hbs - #![allow(unused_parens)] #![allow(unused_imports)] -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use frame_support::{ + traits::Get, + weights::{constants::RocksDbWeight, Weight}, +}; + use sp_std::marker::PhantomData; /// Weight functions needed for pallet_tfgrid. pub trait WeightInfo { - fn create_twin() -> Weight; - fn create_farm() -> Weight; - fn create_node() -> Weight; - fn update_node() -> Weight; - fn report_uptime() -> Weight; + fn create_twin() -> Weight; + fn create_farm() -> Weight; + fn create_node() -> Weight; + fn update_node() -> Weight; + fn report_uptime() -> Weight; } /// Weights for pallet_tfgrid using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn create_twin() -> Weight { - (301_555_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn create_farm() -> Weight { - (433_860_000 as Weight) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn create_node() -> Weight { - (535_924_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn update_node() -> Weight { - (478_710_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn report_uptime() -> Weight { - (247_084_000 as Weight) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } + fn create_twin() -> Weight { + Weight::from_ref_time(301_555_000 as u64) + .saturating_add(T::DbWeight::get().reads(3 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } + fn create_farm() -> Weight { + Weight::from_ref_time(433_860_000 as u64) + .saturating_add(T::DbWeight::get().reads(4 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } + fn create_node() -> Weight { + Weight::from_ref_time(535_924_000 as u64) + .saturating_add(T::DbWeight::get().reads(6 as u64)) + .saturating_add(T::DbWeight::get().writes(3 as u64)) + } + fn update_node() -> Weight { + Weight::from_ref_time(478_710_000 as u64) + .saturating_add(T::DbWeight::get().reads(3 as u64)) + .saturating_add(T::DbWeight::get().writes(1 as u64)) + } + fn report_uptime() -> Weight { + Weight::from_ref_time(247_084_000 as u64).saturating_add(T::DbWeight::get().reads(4 as u64)) + } } // For backwards compatibility and tests impl WeightInfo for () { - fn create_twin() -> Weight { - (301_555_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn create_farm() -> Weight { - (433_860_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn create_node() -> Weight { - (535_924_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn update_node() -> Weight { - (478_710_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - fn report_uptime() -> Weight { - (247_084_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } -} \ No newline at end of file + fn create_twin() -> Weight { + Weight::from_ref_time(301_555_000 as u64) + .saturating_add(RocksDbWeight::get().reads(3 as u64)) + .saturating_add(RocksDbWeight::get().writes(3 as u64)) + } + fn create_farm() -> Weight { + Weight::from_ref_time(433_860_000 as u64) + .saturating_add(RocksDbWeight::get().reads(4 as u64)) + .saturating_add(RocksDbWeight::get().writes(3 as u64)) + } + fn create_node() -> Weight { + Weight::from_ref_time(535_924_000 as u64) + .saturating_add(RocksDbWeight::get().reads(6 as u64)) + .saturating_add(RocksDbWeight::get().writes(3 as u64)) + } + fn update_node() -> Weight { + Weight::from_ref_time(478_710_000 as u64) + .saturating_add(RocksDbWeight::get().reads(3 as u64)) + .saturating_add(RocksDbWeight::get().writes(1 as u64)) + } + fn report_uptime() -> Weight { + Weight::from_ref_time(247_084_000 as u64) + .saturating_add(RocksDbWeight::get().reads(4 as u64)) + } +} diff --git a/substrate-node/pallets/pallet-tft-price/Cargo.toml b/substrate-node/pallets/pallet-tft-price/Cargo.toml index aaee6dcd0..c913f394e 100644 --- a/substrate-node/pallets/pallet-tft-price/Cargo.toml +++ b/substrate-node/pallets/pallet-tft-price/Cargo.toml @@ -25,13 +25,19 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } substrate-fixed = { git = 'https://github.com/encointer/substrate-fixed.git', rev = "b33d186888c60f38adafcfc0ec3a21aab263aef1" } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", optional = true } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", optional = true } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } + +[dev-dependencies] +tfchain-support = { path = "../../support", default-features = false } +substrate-validator-set = { path = '../substrate-validator-set' } [features] default = ['std'] @@ -47,5 +53,10 @@ std = [ 'sp-keystore', 'serde/std', 'log/std', - 'scale-info/std' + 'scale-info/std', + 'pallet-authorship/std', + 'pallet-session/std' +] +try-runtime = [ + "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-tft-price/src/lib.rs b/substrate-node/pallets/pallet-tft-price/src/lib.rs index 9bf3d2d2c..cb4e9c309 100644 --- a/substrate-node/pallets/pallet-tft-price/src/lib.rs +++ b/substrate-node/pallets/pallet-tft-price/src/lib.rs @@ -3,11 +3,11 @@ /// Edit this file to define custom logic or remove it if it is not needed. /// Learn more about FRAME and the core library of Substrate FRAME pallets: /// https://substrate.dev/docs/en/knowledgebase/runtime/frame -use frame_support::{dispatch::DispatchResultWithPostInfo, weights::Pays}; -use frame_system::offchain::{SendSignedTransaction, Signer}; +use frame_support::dispatch::{DispatchResultWithPostInfo, Pays}; +use frame_system::offchain::{SendSignedTransaction, SignMessage, Signer}; use log; use sp_runtime::offchain::{http, Duration}; -use sp_runtime::traits::SaturatedConversion; +use sp_runtime::traits::{Convert, SaturatedConversion}; use sp_std::{boxed::Box, vec::Vec}; mod ringbuffer; use ringbuffer::{RingBufferTrait, RingBufferTransient}; @@ -16,7 +16,7 @@ use serde_json::Value; use sp_core::crypto::KeyTypeId; use substrate_fixed::types::U32F32; -pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"tft!"); +pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"aura"); const SRC_CODE: &str = "USDC"; const SRC_ISSUER: &str = "GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN"; @@ -77,14 +77,19 @@ pub mod pallet { } #[pallet::config] - pub trait Config: frame_system::Config + CreateSignedTransaction> { - type Event: From> + IsType<::Event>; + pub trait Config: + frame_system::Config + + CreateSignedTransaction> + + pallet_authorship::Config + + pallet_session::Config + { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; // Add other types and constants required to configure this pallet. type AuthorityId: AppCrypto; type Call: From>; /// Origin for restricted extrinsics /// Can be the root or another origin configured in the runtime - type RestrictedOrigin: EnsureOrigin; + type RestrictedOrigin: EnsureOrigin; } #[pallet::event] @@ -105,6 +110,8 @@ pub mod pallet { AccountUnauthorizedToSetPrice, MaxPriceBelowMinPriceError, MinPriceAboveMaxPriceError, + IsNotAnAuthority, + WrongAuthority, } #[pallet::pallet] @@ -132,10 +139,6 @@ pub mod pallet { #[pallet::getter(fn range)] pub type BufferRange = StorageValue<_, (BufferIndex, BufferIndex), ValueQuery>; - #[pallet::storage] - #[pallet::getter(fn allowed_origin)] - pub type AllowedOrigin = StorageValue<_, T::AccountId, OptionQuery>; - #[pallet::storage] #[pallet::getter(fn min_tft_price)] pub type MinTftPrice = StorageValue<_, u32, ValueQuery>; @@ -146,34 +149,25 @@ pub mod pallet { #[pallet::call] impl Pallet { - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(0)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn set_prices( origin: OriginFor, price: u32, block_number: T::BlockNumber, ) -> DispatchResultWithPostInfo { let address = ensure_signed(origin)?; - if let Some(allowed_origin) = AllowedOrigin::::get() { - ensure!( - allowed_origin == address, - Error::::AccountUnauthorizedToSetPrice - ); - Self::calculate_and_set_price(price, block_number)?; - } - Ok(().into()) - } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1))] - pub fn set_allowed_origin( - origin: OriginFor, - target: T::AccountId, - ) -> DispatchResultWithPostInfo { - T::RestrictedOrigin::ensure_origin(origin)?; - AllowedOrigin::::set(Some(target)); - Ok(().into()) + ensure!( + Self::is_validator(address), + Error::::AccountUnauthorizedToSetPrice + ); + + Self::calculate_and_set_price(price, block_number) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(2)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn set_min_tft_price(origin: OriginFor, price: u32) -> DispatchResultWithPostInfo { T::RestrictedOrigin::ensure_origin(origin)?; ensure!( @@ -184,7 +178,8 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1) + T::DbWeight::get().reads(1))] + #[pallet::call_index(3)] + #[pallet::weight(100_000_000 + T::DbWeight::get().writes(1).ref_time() + T::DbWeight::get().reads(1).ref_time())] pub fn set_max_tft_price(origin: OriginFor, price: u32) -> DispatchResultWithPostInfo { T::RestrictedOrigin::ensure_origin(origin)?; ensure!( @@ -208,18 +203,18 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { - pub allowed_origin: Option, pub min_tft_price: u32, pub max_tft_price: u32, + pub _data: PhantomData, } #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { Self { - allowed_origin: None, min_tft_price: 10, max_tft_price: 1000, + _data: PhantomData, } } } @@ -227,7 +222,6 @@ pub mod pallet { #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - AllowedOrigin::::set(self.allowed_origin.clone()); MinTftPrice::::put(self.min_tft_price); MaxTftPrice::::put(self.max_tft_price); } @@ -325,6 +319,14 @@ impl Pallet { } fn offchain_signed_tx(block_number: T::BlockNumber) -> Result<(), Error> { + let signer = Signer::::AuthorityId>::any_account(); + + // Only allow the author of the next block to trigger the billing + match Self::is_next_block_author(&signer) { + Ok(_) => (), + Err(_) => return Ok(()), + } + let last_block_set: T::BlockNumber = LastBlockSet::::get(); // Fetch the price every 1 minutes if block_number.saturated_into::() - last_block_set.saturated_into::() < 10 { @@ -338,8 +340,6 @@ impl Pallet { } }; - let signer = Signer::::any_account(); - let result = signer.send_signed_transaction(|_acct| Call::set_prices { price, block_number, @@ -405,4 +405,52 @@ impl Pallet { .round() .to_num::() } + + // Validates if the given signer is the next block author based on the validators in session + // This can be used if an extrinsic should be refunded by the author in the same block + // It also requires that the keytype inserted for the offchain workers is the validator key + fn is_next_block_author( + signer: &Signer::AuthorityId>, + ) -> Result<(), Error> { + let author = >::author(); + let validators = >::validators(); + + // Sign some arbitrary data in order to get the AccountId, maybe there is another way to do this? + let signed_message = signer.sign_message(&[0]); + if let Some(signed_message_data) = signed_message { + if let Some(block_author) = author { + let validator = + ::ValidatorIdOf::convert(block_author.clone()) + .ok_or(Error::::IsNotAnAuthority)?; + + let validator_count = validators.len(); + let author_index = (validators.iter().position(|a| a == &validator).unwrap_or(0) + + 1) + % validator_count; + + let signer_validator_account = + ::ValidatorIdOf::convert( + signed_message_data.0.id.clone(), + ) + .ok_or(Error::::IsNotAnAuthority)?; + + if signer_validator_account != validators[author_index] { + return Err(Error::::WrongAuthority); + } + } + } + + Ok(().into()) + } + + fn is_validator(account: T::AccountId) -> bool { + let validators = >::validators(); + + validators.iter().any(|validator| { + match ::ValidatorIdOf::convert(account.clone()) { + Some(signer) => &signer == validator, + None => false, + } + }) + } } diff --git a/substrate-node/pallets/pallet-tft-price/src/mock.rs b/substrate-node/pallets/pallet-tft-price/src/mock.rs index 2ce7216f8..564bf4759 100644 --- a/substrate-node/pallets/pallet-tft-price/src/mock.rs +++ b/substrate-node/pallets/pallet-tft-price/src/mock.rs @@ -5,26 +5,69 @@ use crate::{self as pallet_tft_price}; use codec::alloc::sync::Arc; use frame_support::traits::GenesisBuild; use frame_support::{construct_runtime, parameter_types, traits::ConstU32}; +use frame_system::mocking; use frame_system::EnsureRoot; -use frame_system::{limits, mocking}; use sp_core::{ + crypto::key_types::DUMMY, offchain::{testing, OffchainDbExt, TransactionPoolExt}, sr25519, H256, }; use sp_io::TestExternalities; use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStore}; use sp_runtime::{ - testing::{Header, TestXt}, - traits::{BlakeTwo256, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup, Verify}, + impl_opaque_keys, + testing::{Header, UintAuthorityId}, + traits::{ + BlakeTwo256, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup, OpaqueKeys, Verify, + }, + MultiSignature, }; +use sp_std::marker::PhantomData; +use std::cell::RefCell; +use tfchain_support::constants::time::MINUTES; -type Extrinsic = TestXt; -type UncheckedExtrinsic = mocking::MockUncheckedExtrinsic; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = mocking::MockBlock; -use sp_runtime::MultiSignature; pub type Signature = MultiSignature; pub type AccountId = <::Signer as IdentifyAccount>::AccountId; +impl_opaque_keys! { + pub struct MockSessionKeys { + pub dummy: UintAuthorityId, + } +} + +impl From for MockSessionKeys { + fn from(dummy: UintAuthorityId) -> Self { + Self { dummy } + } +} + +pub const KEY_ID_A: KeyTypeId = KeyTypeId([4; 4]); +pub const KEY_ID_B: KeyTypeId = KeyTypeId([9; 4]); + +#[derive(Debug, Clone, codec::Encode, codec::Decode, PartialEq, Eq)] +pub struct PreUpgradeMockSessionKeys { + pub a: [u8; 32], + pub b: [u8; 64], +} + +impl OpaqueKeys for PreUpgradeMockSessionKeys { + type KeyTypeIdProviders = (); + + fn key_ids() -> &'static [KeyTypeId] { + &[KEY_ID_A, KEY_ID_B] + } + + fn get_raw(&self, i: KeyTypeId) -> &[u8] { + match i { + i if i == KEY_ID_A => &self.a[..], + i if i == KEY_ID_B => &self.b[..], + _ => &[], + } + } +} + // For testing the module, we construct a mock runtime. construct_runtime!( pub enum TestRuntime where @@ -34,28 +77,30 @@ construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, TFTPriceModule: pallet_tft_price::{Pallet, Call, Storage, Config, Event}, + Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent}, + ValidatorSet: substrate_validator_set::{Pallet, Call, Storage, Event, Config}, + Session: pallet_session::{Pallet, Call, Storage, Event, Config}, } ); parameter_types! { pub const BlockHashCount: u64 = 250; - pub BlockWeights: limits::BlockWeights = limits::BlockWeights::simple_max(1024); } impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; - type Call = Call; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type DbWeight = (); type Version = (); @@ -75,11 +120,88 @@ parameter_types! { impl Config for TestRuntime { type AuthorityId = pallet_tft_price::AuthId; - type Call = Call; - type Event = Event; + type Call = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type RestrictedOrigin = EnsureRoot; } +parameter_types! { + pub const UncleGenerations: u32 = 0; +} + +impl pallet_authorship::Config for TestRuntime { + type FindAuthor = (); + type UncleGenerations = UncleGenerations; + type FilterUncle = (); + type EventHandler = (); +} + +parameter_types! { + pub const Period: u32 = 60 * MINUTES; + pub const Offset: u32 = 0; +} + +thread_local! { + pub static VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); + pub static NEXT_VALIDATORS: RefCell> = RefCell::new(vec![1, 2, 3]); + pub static AUTHORITIES: RefCell> = + RefCell::new(vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); + pub static FORCE_SESSION_END: RefCell = RefCell::new(false); + pub static SESSION_LENGTH: RefCell = RefCell::new(2); + pub static SESSION_CHANGED: RefCell = RefCell::new(false); + pub static DISABLED: RefCell = RefCell::new(false); + pub static BEFORE_SESSION_END_CALLED: RefCell = RefCell::new(false); +} + +use pallet_session::SessionHandler; +use sp_runtime::RuntimeAppPublic; +pub struct TestSessionHandler; +impl SessionHandler for TestSessionHandler { + const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[UintAuthorityId::ID]; + fn on_genesis_session(_validators: &[(AccountId, T)]) {} + fn on_new_session( + changed: bool, + validators: &[(AccountId, T)], + _queued_validators: &[(AccountId, T)], + ) { + SESSION_CHANGED.with(|l| *l.borrow_mut() = changed); + AUTHORITIES.with(|l| { + *l.borrow_mut() = validators + .iter() + .map(|(_, id)| id.get::(DUMMY).unwrap_or_default()) + .collect() + }); + } + fn on_disabled(_validator_index: u32) { + DISABLED.with(|l| *l.borrow_mut() = true) + } + fn on_before_session_ending() { + BEFORE_SESSION_END_CALLED.with(|b| *b.borrow_mut() = true); + } +} + +parameter_types! { + pub const MinAuthorities: u32 = 2; +} + +impl substrate_validator_set::Config for TestRuntime { + type AddRemoveOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type MinAuthorities = MinAuthorities; +} + +impl pallet_session::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = ::AccountId; + type ValidatorIdOf = substrate_validator_set::ValidatorOf; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionManager = (); + type SessionHandler = TestSessionHandler; + type Keys = MockSessionKeys; + type WeightInfo = (); +} + impl frame_system::offchain::SigningTypes for TestRuntime { type Public = ::Signer; type Signature = Signature; @@ -87,23 +209,26 @@ impl frame_system::offchain::SigningTypes for TestRuntime { impl frame_system::offchain::SendTransactionTypes for TestRuntime where - Call: From, + RuntimeCall: From, { - type OverarchingCall = Call; - type Extrinsic = Extrinsic; + type OverarchingCall = RuntimeCall; + type Extrinsic = UncheckedExtrinsic; } impl frame_system::offchain::CreateSignedTransaction for TestRuntime where - Call: From, + RuntimeCall: From, { fn create_transaction>( - call: Call, + call: RuntimeCall, _public: ::Signer, - _account: AccountId, - nonce: u64, - ) -> Option<(Call, ::SignaturePayload)> { - Some((call, (nonce, ()))) + account: AccountId, + _nonce: u64, + ) -> Option<( + RuntimeCall, + ::SignaturePayload, + )> { + Some((call, (account, (), ()))) } } @@ -117,12 +242,6 @@ fn get_from_seed(seed: &str) -> ::Public .public() } -fn get_from_seed_string(seed: &str) -> ::Public { - TPublic::Pair::from_string(&format!("{}", seed), None) - .expect("static values are valid; qed") - .public() -} - /// Helper function to generate an account ID from seed fn get_account_id_from_seed(seed: &str) -> AccountId where @@ -131,17 +250,8 @@ where AccountPublic::from(get_from_seed::(seed)).into_account() } -fn get_account_id_from_seed_string(seed: &str) -> AccountId -where - AccountPublic: From<::Public>, -{ - AccountPublic::from(get_from_seed_string::(seed)).into_account() -} - -pub fn allowed_account() -> AccountId { - get_account_id_from_seed_string::( - "expire stage crawl shell boss any story swamp skull yellow bamboo copy", - ) +pub fn alice() -> AccountId { + get_account_id_from_seed::("Alice") } pub fn bob() -> AccountId { @@ -166,10 +276,15 @@ impl ExternalityBuilder { .build_storage::() .unwrap(); + let session_genesis = pallet_session::GenesisConfig:: { + keys: vec![(alice(), alice(), MockSessionKeys::from(UintAuthorityId(1)))], + }; + session_genesis.assimilate_storage(&mut storage).unwrap(); + let genesis = pallet_tft_price::GenesisConfig:: { - allowed_origin: Some(allowed_account()), min_tft_price: 10, max_tft_price: 1000, + _data: PhantomData, }; genesis.assimilate_storage(&mut storage).unwrap(); diff --git a/substrate-node/pallets/pallet-tft-price/src/tests.rs b/substrate-node/pallets/pallet-tft-price/src/tests.rs index 31e9d36c3..58121e8c0 100644 --- a/substrate-node/pallets/pallet-tft-price/src/tests.rs +++ b/substrate-node/pallets/pallet-tft-price/src/tests.rs @@ -1,33 +1,9 @@ use super::Event as TftPriceEvent; -use crate::{mock::Event as MockEvent, mock::*, Error}; +use crate::{mock::RuntimeEvent as MockEvent, mock::*, Error}; use frame_support::{assert_noop, assert_ok, error::BadOrigin}; use frame_system::{EventRecord, Phase, RawOrigin}; use sp_core::H256; -#[test] -fn test_set_allowed_origin_works() { - let mut t = ExternalityBuilder::build(); - t.execute_with(|| { - assert_ok!(TFTPriceModule::set_allowed_origin( - RawOrigin::Root.into(), - bob(), - )); - - assert_eq!(TFTPriceModule::allowed_origin(), Some(bob())); - }) -} - -#[test] -fn test_set_allowed_origin_by_wrong_origin_fails() { - let mut t = ExternalityBuilder::build(); - t.execute_with(|| { - assert_noop!( - TFTPriceModule::set_allowed_origin(Origin::signed(bob()), bob()), - BadOrigin, - ); - }) -} - #[test] fn test_calc_avg_rounding_works() { let mut t = ExternalityBuilder::build(); @@ -54,11 +30,10 @@ fn test_calc_avg_rounding_works() { fn test_set_prices_works() { let mut t = ExternalityBuilder::build(); t.execute_with(|| { - let acct = allowed_account(); for i in 1..1441 { let target_block = i * 100; // we set the price every 100 blocks run_to_block(target_block); - match TFTPriceModule::set_prices(Origin::signed(acct.clone()), 500, target_block) { + match TFTPriceModule::set_prices(RuntimeOrigin::signed(alice()), 500, target_block) { Ok(_) => (), Err(_) => panic!("Couldn't set tft_price"), } @@ -76,8 +51,11 @@ fn test_set_prices_works() { fn test_set_price_works() { let mut t = ExternalityBuilder::build(); t.execute_with(|| { - let acct = allowed_account(); - assert_ok!(TFTPriceModule::set_prices(Origin::signed(acct), 500, 1)); + assert_ok!(TFTPriceModule::set_prices( + RuntimeOrigin::signed(alice()), + 500, + 1 + )); assert_eq!(TFTPriceModule::tft_price(), 500); assert_eq!(TFTPriceModule::average_tft_price(), 500); @@ -88,8 +66,11 @@ fn test_set_price_works() { fn test_set_price_below_min_price_works() { let mut t = ExternalityBuilder::build(); t.execute_with(|| { - let acct = allowed_account(); - assert_ok!(TFTPriceModule::set_prices(Origin::signed(acct), 5, 1)); + assert_ok!(TFTPriceModule::set_prices( + RuntimeOrigin::signed(alice()), + 5, + 1 + )); let our_events = System::events(); assert_eq!( @@ -111,8 +92,11 @@ fn test_set_price_below_min_price_works() { fn test_set_price_above_max_price_works() { let mut t = ExternalityBuilder::build(); t.execute_with(|| { - let acct = allowed_account(); - assert_ok!(TFTPriceModule::set_prices(Origin::signed(acct), 2000, 1)); + assert_ok!(TFTPriceModule::set_prices( + RuntimeOrigin::signed(alice()), + 2000, + 1 + )); let our_events = System::events(); assert_eq!( @@ -131,11 +115,11 @@ fn test_set_price_above_max_price_works() { } #[test] -fn test_set_price_wrong_origin_fails() { +fn test_set_price_not_validator_fails() { let mut t = ExternalityBuilder::build(); t.execute_with(|| { assert_noop!( - TFTPriceModule::set_prices(Origin::signed(bob()), 500, 1), + TFTPriceModule::set_prices(RuntimeOrigin::signed(bob()), 500, 1), Error::::AccountUnauthorizedToSetPrice ); }) @@ -193,7 +177,7 @@ fn test_set_min_tft_price_wrong_origin_fails() { let mut t = ExternalityBuilder::build(); t.execute_with(|| { assert_noop!( - TFTPriceModule::set_min_tft_price(Origin::signed(bob()), 20), + TFTPriceModule::set_min_tft_price(RuntimeOrigin::signed(bob()), 20), BadOrigin, ); }) @@ -228,7 +212,7 @@ fn test_set_max_tft_price_wrong_origin_fails() { let mut t = ExternalityBuilder::build(); t.execute_with(|| { assert_noop!( - TFTPriceModule::set_max_tft_price(Origin::signed(bob()), 2000), + TFTPriceModule::set_max_tft_price(RuntimeOrigin::signed(bob()), 2000), BadOrigin, ); }) @@ -245,7 +229,7 @@ fn test_set_max_tft_price_too_low_fails() { }) } -fn record(event: Event) -> EventRecord { +fn record(event: RuntimeEvent) -> EventRecord { EventRecord { phase: Phase::Initialization, event, diff --git a/substrate-node/pallets/pallet-validator/Cargo.toml b/substrate-node/pallets/pallet-validator/Cargo.toml index f38a56879..acf69b6cb 100644 --- a/substrate-node/pallets/pallet-validator/Cargo.toml +++ b/substrate-node/pallets/pallet-validator/Cargo.toml @@ -10,17 +10,17 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [dependencies.substrate-validator-set] default-features = false @@ -40,4 +40,7 @@ std = [ 'pallet-session/std', 'sp-io/std', 'scale-info/std' +] +try-runtime = [ + "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/pallet-validator/src/lib.rs b/substrate-node/pallets/pallet-validator/src/lib.rs index 3cd85e25d..45d8bbbda 100644 --- a/substrate-node/pallets/pallet-validator/src/lib.rs +++ b/substrate-node/pallets/pallet-validator/src/lib.rs @@ -36,9 +36,9 @@ pub mod pallet { + pallet_membership::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event - type Event: From> + IsType<::Event>; + type RuntimeEvent: From> + IsType<::RuntimeEvent>; type Currency: Currency; - type CouncilOrigin: EnsureOrigin<::Origin>; + type CouncilOrigin: EnsureOrigin; } #[pallet::pallet] @@ -115,6 +115,7 @@ pub mod pallet { /// Tf Connect ID: the threefold connect ID of the person who wants to become a validator /// Info: some public info about the validator (website link, blog link, ..) /// A user can only have 1 validator request at a time + #[pallet::call_index(0)] #[pallet::weight(100_000_000)] pub fn create_validator_request( origin: OriginFor, @@ -153,6 +154,7 @@ pub mod pallet { /// Will activate the Validator node account on consensus level /// A user can only call this if his request to be a validator is approved by the council /// Should be called when his node is synced and ready to start validating + #[pallet::call_index(1)] #[pallet::weight(100_000_000)] pub fn activate_validator_node(origin: OriginFor) -> DispatchResultWithPostInfo { let address = ensure_signed(origin)?; @@ -188,6 +190,7 @@ pub mod pallet { /// In case the Validator wishes to change his validator node account /// he can call this method with the new node validator account /// this new account will be added as a new consensus validator if he is validating already + #[pallet::call_index(2)] #[pallet::weight(100_000_000)] pub fn change_validator_node_account( origin: OriginFor, @@ -228,6 +231,7 @@ pub mod pallet { /// Bond an account to a validator account /// Just proves that the stash account is indeed under control of the validator account + #[pallet::call_index(3)] #[pallet::weight(100_000_000)] pub fn bond( origin: OriginFor, @@ -251,26 +255,28 @@ pub mod pallet { /// Approve validator (council) /// Approves a validator to be added as a council member and /// to participate in consensus + #[pallet::call_index(4)] #[pallet::weight(100_000_000)] pub fn approve_validator( origin: OriginFor, - validator_account: T::AccountId, + validator_account: ::Source, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - Self::is_council_member(who)?; + Self::is_council_member(&who)?; - let mut validator = >::get(&validator_account) + let v = T::Lookup::lookup(validator_account.clone())?; + let mut validator = >::get(&v) .ok_or(DispatchError::from(Error::::ValidatorNotFound))?; // Set state to approved validator.state = types::ValidatorRequestState::Approved; - >::insert(validator_account.clone(), &validator); + >::insert(v.clone(), &validator); // Add the validator as a council member pallet_membership::Pallet::::add_member( frame_system::RawOrigin::Root.into(), - validator_account.clone(), + validator_account, )?; Self::deposit_event(Event::ValidatorRequestApproved(validator)); @@ -284,28 +290,31 @@ pub mod pallet { /// 2. Storage /// 3. Consensus /// Can only be called by the user or the council + #[pallet::call_index(5)] #[pallet::weight(100_000_000)] pub fn remove_validator( origin: OriginFor, - validator: T::AccountId, + validator_account: ::Source, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin.clone())?; - if !(who == validator || Self::is_council_member(who).is_ok()) { + let v = T::Lookup::lookup(validator_account.clone())?; + + if !(v == who || Self::is_council_member(&who).is_ok()) { Err(Error::::BadOrigin)? } - let _ = >::get(&validator) + let _ = >::get(&v) .ok_or(DispatchError::from(Error::::ValidatorNotFound))?; // Remove the validator as a council member pallet_membership::Pallet::::remove_member( frame_system::RawOrigin::Root.into(), - validator.clone(), + validator_account, )?; // Remove the entry from the storage map - >::remove(validator); + >::remove(v); // let node_validators = substrate_validator_set::Validators::::get(); @@ -332,7 +341,7 @@ pub mod pallet { } impl Pallet { - fn is_council_member(who: T::AccountId) -> DispatchResultWithPostInfo { + fn is_council_member(who: &T::AccountId) -> DispatchResultWithPostInfo { let council_members = pallet_membership::Pallet::::members(); @@ -340,4 +349,4 @@ impl Pallet { Ok(().into()) } -} +} \ No newline at end of file diff --git a/substrate-node/pallets/pallet-validator/src/mock.rs b/substrate-node/pallets/pallet-validator/src/mock.rs index b718cd280..8a6cc087b 100644 --- a/substrate-node/pallets/pallet-validator/src/mock.rs +++ b/substrate-node/pallets/pallet-validator/src/mock.rs @@ -1,7 +1,7 @@ use super::*; use crate as pallet_validator; use core::cell::RefCell; -use frame_support::{construct_runtime, parameter_types, traits::ConstU32}; +use frame_support::{bounded_vec, construct_runtime, parameter_types, traits::ConstU32}; use frame_system::EnsureRoot; use pallet_session::{SessionHandler, ShouldEndSession}; use sp_core::{crypto::key_types::DUMMY, H256}; @@ -32,7 +32,7 @@ construct_runtime!( ); impl pallet_validator::Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type CouncilOrigin = EnsureRoot; type Currency = (); } @@ -45,16 +45,16 @@ impl frame_system::Config for TestRuntime { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; - type Call = Call; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type DbWeight = (); type Version = (); @@ -73,7 +73,7 @@ parameter_types! { } impl substrate_validator_set::Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type AddRemoveOrigin = EnsureRoot; type MinAuthorities = MinAuthorities; } @@ -141,7 +141,7 @@ impl pallet_session::Config for TestRuntime { type SessionHandler = TestSessionHandler; type Keys = MockSessionKeys; type WeightInfo = (); - type Event = Event; + type RuntimeEvent = RuntimeEvent; } pub type BlockNumber = u32; @@ -153,9 +153,9 @@ parameter_types! { pub type CouncilCollective = pallet_collective::Instance1; impl pallet_collective::Config for TestRuntime { - type Origin = Origin; - type Proposal = Call; - type Event = Event; + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type MotionDuration = CouncilMotionDuration; type MaxProposals = CouncilMaxProposals; type MaxMembers = CouncilMaxMembers; @@ -164,7 +164,7 @@ impl pallet_collective::Config for TestRuntime { } impl pallet_membership::Config for TestRuntime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type AddOrigin = EnsureRoot; type RemoveOrigin = EnsureRoot; type SwapOrigin = EnsureRoot; @@ -185,7 +185,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { genesis.assimilate_storage(&mut t).unwrap(); let genesis = pallet_membership::GenesisConfig:: { - members: vec![1, 2, 3], // [1, 2, 3] accounts are council members + members: bounded_vec![1, 2, 3], // [1, 2, 3] accounts are council members phantom: Default::default(), }; genesis.assimilate_storage(&mut t).unwrap(); diff --git a/substrate-node/pallets/pallet-validator/src/tests.rs b/substrate-node/pallets/pallet-validator/src/tests.rs index 25e96a0f5..e64df6fc5 100644 --- a/substrate-node/pallets/pallet-validator/src/tests.rs +++ b/substrate-node/pallets/pallet-validator/src/tests.rs @@ -1,5 +1,5 @@ use super::Event as ValidatorEvent; -use crate::{mock::Event as MockEvent, mock::*, Error}; +use crate::{mock::RuntimeEvent as MockEvent, mock::*, Error}; use frame_support::{assert_noop, assert_ok}; use frame_system::{EventRecord, Phase}; use sp_core::H256; @@ -34,7 +34,7 @@ fn test_create_validator_request_duplicate_fails() { assert_noop!( ValidatorModule::create_validator_request( - Origin::signed(10), // same origin + RuntimeOrigin::signed(10), // same origin 13, 14, b"other_description".to_vec(), @@ -73,7 +73,7 @@ fn test_approve_validator_works() { fn test_approve_validator_by_unauthorized_fails() { new_test_ext().execute_with(|| { assert_noop!( - ValidatorModule::approve_validator(Origin::signed(10), 10,), + ValidatorModule::approve_validator(RuntimeOrigin::signed(10), 10,), Error::::NotCouncilMember, ); }); @@ -83,7 +83,7 @@ fn test_approve_validator_by_unauthorized_fails() { fn test_approve_validator_not_found_fails() { new_test_ext().execute_with(|| { assert_noop!( - ValidatorModule::approve_validator(Origin::signed(1), 10,), + ValidatorModule::approve_validator(RuntimeOrigin::signed(1), 10,), Error::::ValidatorNotFound, ); }); @@ -94,7 +94,9 @@ fn test_activate_validator_node_works() { new_test_ext().execute_with(|| { create_validator_and_approve(); - assert_ok!(ValidatorModule::activate_validator_node(Origin::signed(10),)); + assert_ok!(ValidatorModule::activate_validator_node( + RuntimeOrigin::signed(10), + )); let validator_validating = get_validator(crate::types::ValidatorRequestState::Validating); @@ -118,7 +120,7 @@ fn test_activate_validator_node_works() { fn test_activate_validator_not_found_fails() { new_test_ext().execute_with(|| { assert_noop!( - ValidatorModule::activate_validator_node(Origin::signed(10),), + ValidatorModule::activate_validator_node(RuntimeOrigin::signed(10),), Error::::ValidatorNotFound, ); }); @@ -130,7 +132,7 @@ fn test_activate_validator_not_approved_fails() { create_validator(); assert_noop!( - ValidatorModule::activate_validator_node(Origin::signed(10),), + ValidatorModule::activate_validator_node(RuntimeOrigin::signed(10),), Error::::ValidatorNotApproved, ); }); @@ -141,10 +143,12 @@ fn test_activate_validator_already_validating_fails() { new_test_ext().execute_with(|| { create_validator_and_approve(); - assert_ok!(ValidatorModule::activate_validator_node(Origin::signed(10),)); + assert_ok!(ValidatorModule::activate_validator_node( + RuntimeOrigin::signed(10), + )); assert_noop!( - ValidatorModule::activate_validator_node(Origin::signed(10),), + ValidatorModule::activate_validator_node(RuntimeOrigin::signed(10),), Error::::ValidatorValidatingAlready, ); }); @@ -156,7 +160,7 @@ fn test_change_validator_node_account_works() { create_validator_and_approve(); assert_ok!(ValidatorModule::change_validator_node_account( - Origin::signed(10), + RuntimeOrigin::signed(10), 13, )); @@ -175,10 +179,12 @@ fn test_change_validator_node_account_validating_works() { new_test_ext().execute_with(|| { create_validator_and_approve(); - assert_ok!(ValidatorModule::activate_validator_node(Origin::signed(10),)); + assert_ok!(ValidatorModule::activate_validator_node( + RuntimeOrigin::signed(10), + )); assert_ok!(ValidatorModule::change_validator_node_account( - Origin::signed(10), + RuntimeOrigin::signed(10), 13, )); @@ -212,7 +218,7 @@ fn test_change_validator_node_account_validating_works() { fn test_change_validator_node_account_not_found_fails() { new_test_ext().execute_with(|| { assert_noop!( - ValidatorModule::change_validator_node_account(Origin::signed(10), 13,), + ValidatorModule::change_validator_node_account(RuntimeOrigin::signed(10), 13,), Error::::ValidatorNotFound, ); }); @@ -221,7 +227,7 @@ fn test_change_validator_node_account_not_found_fails() { #[test] fn test_bond_works() { new_test_ext().execute_with(|| { - assert_ok!(ValidatorModule::bond(Origin::signed(12), 10,)); + assert_ok!(ValidatorModule::bond(RuntimeOrigin::signed(12), 10,)); assert_eq!(ValidatorModule::bonded(12), Some(10),); @@ -239,10 +245,10 @@ fn test_bond_works() { #[test] fn test_bond_already_bounded_fails() { new_test_ext().execute_with(|| { - assert_ok!(ValidatorModule::bond(Origin::signed(12), 10,)); + assert_ok!(ValidatorModule::bond(RuntimeOrigin::signed(12), 10,)); assert_noop!( - ValidatorModule::bond(Origin::signed(12), 10,), + ValidatorModule::bond(RuntimeOrigin::signed(12), 10,), Error::::AlreadyBonded, ); }); @@ -253,7 +259,10 @@ fn test_remove_validator_works() { new_test_ext().execute_with(|| { create_validator_and_approve(); - assert_ok!(ValidatorModule::remove_validator(Origin::signed(1), 10,)); + assert_ok!(ValidatorModule::remove_validator( + RuntimeOrigin::signed(1), + 10, + )); assert_eq!(ValidatorModule::validator_requests(10), None,); }); @@ -264,7 +273,10 @@ fn test_remove_validator_by_himself_works() { new_test_ext().execute_with(|| { create_validator_and_approve(); - assert_ok!(ValidatorModule::remove_validator(Origin::signed(10), 10,)); + assert_ok!(ValidatorModule::remove_validator( + RuntimeOrigin::signed(10), + 10, + )); assert_eq!(ValidatorModule::validator_requests(10), None,); }); @@ -274,7 +286,7 @@ fn test_remove_validator_by_himself_works() { fn test_remove_validator_by_unauthorized_fails() { new_test_ext().execute_with(|| { assert_noop!( - ValidatorModule::remove_validator(Origin::signed(4), 10,), + ValidatorModule::remove_validator(RuntimeOrigin::signed(4), 10,), Error::::BadOrigin, ); }); @@ -284,13 +296,13 @@ fn test_remove_validator_by_unauthorized_fails() { fn test_remove_validator_not_found_fails() { new_test_ext().execute_with(|| { assert_noop!( - ValidatorModule::remove_validator(Origin::signed(1), 10,), + ValidatorModule::remove_validator(RuntimeOrigin::signed(1), 10,), Error::::ValidatorNotFound, ); }); } -fn record(event: Event) -> EventRecord { +fn record(event: RuntimeEvent) -> EventRecord { EventRecord { phase: Phase::Initialization, event, @@ -311,7 +323,7 @@ fn get_validator(state: crate::types::ValidatorRequestState) -> crate::types::Va fn create_validator() { assert_ok!(ValidatorModule::create_validator_request( - Origin::signed(10), + RuntimeOrigin::signed(10), 11, 12, b"description".to_vec(), @@ -323,5 +335,8 @@ fn create_validator() { fn create_validator_and_approve() { create_validator(); - assert_ok!(ValidatorModule::approve_validator(Origin::signed(1), 10,)); + assert_ok!(ValidatorModule::approve_validator( + RuntimeOrigin::signed(1), + 10, + )); } diff --git a/substrate-node/pallets/substrate-validator-set/Cargo.toml b/substrate-node/pallets/substrate-validator-set/Cargo.toml index 1f717eab0..90a2ff467 100644 --- a/substrate-node/pallets/substrate-validator-set/Cargo.toml +++ b/substrate-node/pallets/substrate-validator-set/Cargo.toml @@ -12,21 +12,21 @@ scale-info = { version = "2.1.1", default-features = false, features = ["derive" serde = { features = ['derive'], optional = true, version = '1.0.101'} -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [dependencies.log] default-features = false version = '0.4.14' [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } [features] default = ['std'] @@ -42,4 +42,7 @@ std = [ 'sp-io/std', 'scale-info/std', 'log/std' +] +try-runtime = [ + "frame-support/try-runtime", ] \ No newline at end of file diff --git a/substrate-node/pallets/substrate-validator-set/diff.patch b/substrate-node/pallets/substrate-validator-set/diff.patch index a2b29270d..773e36f12 100644 --- a/substrate-node/pallets/substrate-validator-set/diff.patch +++ b/substrate-node/pallets/substrate-validator-set/diff.patch @@ -8,7 +8,7 @@ index 4f65d9c..67a3cb7 100644 type Event: From> + IsType<::Event>; - - /// Origin for adding or removing a validator. -- type ExternalOrigin: EnsureOrigin; +- type ExternalOrigin: EnsureOrigin; } #[pallet::pallet] diff --git a/substrate-node/pallets/substrate-validator-set/src/lib.rs b/substrate-node/pallets/substrate-validator-set/src/lib.rs index 8fd9e6b6b..b828820ba 100644 --- a/substrate-node/pallets/substrate-validator-set/src/lib.rs +++ b/substrate-node/pallets/substrate-validator-set/src/lib.rs @@ -17,320 +17,343 @@ mod mock; mod tests; use frame_support::{ - ensure, - pallet_prelude::*, - traits::{EstimateNextSessionRotation, Get, ValidatorSet, ValidatorSetWithIdentification}, + ensure, + pallet_prelude::*, + traits::{EstimateNextSessionRotation, Get, ValidatorSet, ValidatorSetWithIdentification}, }; use log; pub use pallet::*; use sp_runtime::traits::{Convert, Zero}; use sp_staking::offence::{Offence, OffenceError, ReportOffence}; -use sp_std::{collections::btree_set::BTreeSet, prelude::*}; use sp_std::convert::TryInto; +use sp_std::{collections::btree_set::BTreeSet, prelude::*}; pub const LOG_TARGET: &'static str = "runtime::validator-set"; #[frame_support::pallet] pub mod pallet { - use super::*; - use frame_system::pallet_prelude::*; - - /// Configure the pallet by specifying the parameters and types on which it - /// depends. - #[pallet::config] - pub trait Config: frame_system::Config + pallet_session::Config { - /// The Event type. - type Event: From> + IsType<::Event>; - - /// Origin for adding or removing a validator. - type AddRemoveOrigin: EnsureOrigin; - - /// Minimum number of validators to leave in the validator set during - /// auto removal. - type MinAuthorities: Get; - } - - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] - pub struct Pallet(_); - - #[pallet::storage] - #[pallet::getter(fn validators)] - pub type Validators = StorageValue<_, Vec, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn approved_validators)] - pub type ApprovedValidators = StorageValue<_, Vec, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn validators_to_remove)] - pub type OfflineValidators = StorageValue<_, Vec, ValueQuery>; - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - /// New validator addition initiated. Effective in ~2 sessions. - ValidatorAdditionInitiated(T::AccountId), - - /// Validator removal initiated. Effective in ~2 sessions. - ValidatorRemovalInitiated(T::AccountId), - } - - // Errors inform users that something went wrong. - #[pallet::error] - pub enum Error { - /// Target (post-removal) validator count is below the minimum. - TooLowValidatorCount, - /// Validator is already in the validator set. - Duplicate, - /// Validator is not approved for re-addition. - ValidatorNotApproved, - /// Only the validator can add itself back after coming online. - BadOrigin, - } - - #[pallet::hooks] - impl Hooks> for Pallet {} - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub initial_validators: Vec, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - Self { initial_validators: Default::default() } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - Pallet::::initialize_validators(&self.initial_validators); - } - } - - #[pallet::call] - impl Pallet { - /// Add a new validator. - /// - /// New validator's session keys should be set in Session pallet before - /// calling this. - /// - /// The origin can be configured using the `AddRemoveOrigin` type in the - /// host runtime. Can also be set to sudo/root. - #[pallet::weight(0)] - pub fn add_validator(origin: OriginFor, validator_id: T::AccountId) -> DispatchResult { - T::AddRemoveOrigin::ensure_origin(origin)?; - - Self::do_add_validator(validator_id.clone())?; - Self::approve_validator(validator_id)?; - - Ok(()) - } - - /// Remove a validator. - /// - /// The origin can be configured using the `AddRemoveOrigin` type in the - /// host runtime. Can also be set to sudo/root. - #[pallet::weight(0)] - pub fn remove_validator( - origin: OriginFor, - validator_id: T::AccountId, - ) -> DispatchResult { - T::AddRemoveOrigin::ensure_origin(origin)?; - - Self::do_remove_validator(validator_id.clone())?; - Self::unapprove_validator(validator_id)?; - - Ok(()) - } - - /// Add an approved validator again when it comes back online. - /// - /// For this call, the dispatch origin must be the validator itself. - #[pallet::weight(0)] - pub fn add_validator_again( - origin: OriginFor, - validator_id: T::AccountId, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - ensure!(who == validator_id, Error::::BadOrigin); - - let approved_set: BTreeSet<_> = >::get().into_iter().collect(); - ensure!(approved_set.contains(&validator_id), Error::::ValidatorNotApproved); - - Self::do_add_validator(validator_id)?; - - Ok(()) - } - } + use super::*; + use frame_system::pallet_prelude::*; + + /// Configure the pallet by specifying the parameters and types on which it + /// depends. + #[pallet::config] + pub trait Config: frame_system::Config + pallet_session::Config { + /// The Event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Origin for adding or removing a validator. + type AddRemoveOrigin: EnsureOrigin; + + /// Minimum number of validators to leave in the validator set during + /// auto removal. + type MinAuthorities: Get; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::storage] + #[pallet::getter(fn validators)] + pub type Validators = StorageValue<_, Vec, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn approved_validators)] + pub type ApprovedValidators = StorageValue<_, Vec, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn validators_to_remove)] + pub type OfflineValidators = StorageValue<_, Vec, ValueQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// New validator addition initiated. Effective in ~2 sessions. + ValidatorAdditionInitiated(T::AccountId), + + /// Validator removal initiated. Effective in ~2 sessions. + ValidatorRemovalInitiated(T::AccountId), + } + + // Errors inform users that something went wrong. + #[pallet::error] + pub enum Error { + /// Target (post-removal) validator count is below the minimum. + TooLowValidatorCount, + /// Validator is already in the validator set. + Duplicate, + /// Validator is not approved for re-addition. + ValidatorNotApproved, + /// Only the validator can add itself back after coming online. + BadOrigin, + } + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub initial_validators: Vec, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self { + initial_validators: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + Pallet::::initialize_validators(&self.initial_validators); + } + } + + #[pallet::call] + impl Pallet { + /// Add a new validator. + /// + /// New validator's session keys should be set in Session pallet before + /// calling this. + /// + /// The origin can be configured using the `AddRemoveOrigin` type in the + /// host runtime. Can also be set to sudo/root. + #[pallet::call_index(0)] + #[pallet::weight(0)] + pub fn add_validator(origin: OriginFor, validator_id: T::AccountId) -> DispatchResult { + T::AddRemoveOrigin::ensure_origin(origin)?; + + Self::do_add_validator(validator_id.clone())?; + Self::approve_validator(validator_id)?; + + Ok(()) + } + + /// Remove a validator. + /// + /// The origin can be configured using the `AddRemoveOrigin` type in the + /// host runtime. Can also be set to sudo/root. + #[pallet::call_index(1)] + #[pallet::weight(0)] + pub fn remove_validator( + origin: OriginFor, + validator_id: T::AccountId, + ) -> DispatchResult { + T::AddRemoveOrigin::ensure_origin(origin)?; + + Self::do_remove_validator(validator_id.clone())?; + Self::unapprove_validator(validator_id)?; + + Ok(()) + } + + /// Add an approved validator again when it comes back online. + /// + /// For this call, the dispatch origin must be the validator itself. + #[pallet::call_index(2)] + #[pallet::weight(0)] + pub fn add_validator_again( + origin: OriginFor, + validator_id: T::AccountId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + ensure!(who == validator_id, Error::::BadOrigin); + + let approved_set: BTreeSet<_> = >::get().into_iter().collect(); + ensure!( + approved_set.contains(&validator_id), + Error::::ValidatorNotApproved + ); + + Self::do_add_validator(validator_id)?; + + Ok(()) + } + } } impl Pallet { - fn initialize_validators(validators: &[T::AccountId]) { - assert!(validators.len() as u32 >= T::MinAuthorities::get(), "Initial set of validators must be at least T::MinAuthorities"); - assert!(>::get().is_empty(), "Validators are already initialized!"); - - >::put(validators); - >::put(validators); - } - - fn do_add_validator(validator_id: T::AccountId) -> DispatchResult { - let validator_set: BTreeSet<_> = >::get().into_iter().collect(); - ensure!(!validator_set.contains(&validator_id), Error::::Duplicate); - >::mutate(|v| v.push(validator_id.clone())); - - Self::deposit_event(Event::ValidatorAdditionInitiated(validator_id.clone())); - log::debug!(target: LOG_TARGET, "Validator addition initiated."); - - Ok(()) - } - - fn do_remove_validator(validator_id: T::AccountId) -> DispatchResult { - let mut validators = >::get(); - - // Ensuring that the post removal, target validator count doesn't go - // below the minimum. - ensure!( - validators.len().saturating_sub(1) as u32 >= T::MinAuthorities::get(), - Error::::TooLowValidatorCount - ); - - validators.retain(|v| *v != validator_id); - - >::put(validators); - - Self::deposit_event(Event::ValidatorRemovalInitiated(validator_id.clone())); - log::debug!(target: LOG_TARGET, "Validator removal initiated."); - - Ok(()) - } - - fn approve_validator(validator_id: T::AccountId) -> DispatchResult { - let approved_set: BTreeSet<_> = >::get().into_iter().collect(); - ensure!(!approved_set.contains(&validator_id), Error::::Duplicate); - >::mutate(|v| v.push(validator_id.clone())); - Ok(()) - } - - fn unapprove_validator(validator_id: T::AccountId) -> DispatchResult { - let mut approved_set = >::get(); - approved_set.retain(|v| *v != validator_id); - Ok(()) - } - - // Adds offline validators to a local cache for removal at new session. - fn mark_for_removal(validator_id: T::AccountId) { - >::mutate(|v| v.push(validator_id)); - log::debug!(target: LOG_TARGET, "Offline validator marked for auto removal."); - } - - // Removes offline validators from the validator set and clears the offline - // cache. It is called in the session change hook and removes the validators - // who were reported offline during the session that is ending. We do not - // check for `MinAuthorities` here, because the offline validators will not - // produce blocks and will have the same overall effect on the runtime. - fn remove_offline_validators() { - let validators_to_remove: BTreeSet<_> = >::get().into_iter().collect(); - - // Delete from active validator set. - >::mutate(|vs| vs.retain(|v| !validators_to_remove.contains(v))); - log::debug!( - target: LOG_TARGET, - "Initiated removal of {:?} offline validators.", - validators_to_remove.len() - ); - - // Clear the offline validator list to avoid repeated deletion. - >::put(Vec::::new()); - } + fn initialize_validators(validators: &[T::AccountId]) { + assert!( + validators.len() as u32 >= T::MinAuthorities::get(), + "Initial set of validators must be at least T::MinAuthorities" + ); + assert!( + >::get().is_empty(), + "Validators are already initialized!" + ); + + >::put(validators); + >::put(validators); + } + + fn do_add_validator(validator_id: T::AccountId) -> DispatchResult { + let validator_set: BTreeSet<_> = >::get().into_iter().collect(); + ensure!( + !validator_set.contains(&validator_id), + Error::::Duplicate + ); + >::mutate(|v| v.push(validator_id.clone())); + + Self::deposit_event(Event::ValidatorAdditionInitiated(validator_id.clone())); + log::debug!(target: LOG_TARGET, "Validator addition initiated."); + + Ok(()) + } + + fn do_remove_validator(validator_id: T::AccountId) -> DispatchResult { + let mut validators = >::get(); + + // Ensuring that the post removal, target validator count doesn't go + // below the minimum. + ensure!( + validators.len().saturating_sub(1) as u32 >= T::MinAuthorities::get(), + Error::::TooLowValidatorCount + ); + + validators.retain(|v| *v != validator_id); + + >::put(validators); + + Self::deposit_event(Event::ValidatorRemovalInitiated(validator_id.clone())); + log::debug!(target: LOG_TARGET, "Validator removal initiated."); + + Ok(()) + } + + fn approve_validator(validator_id: T::AccountId) -> DispatchResult { + let approved_set: BTreeSet<_> = >::get().into_iter().collect(); + ensure!(!approved_set.contains(&validator_id), Error::::Duplicate); + >::mutate(|v| v.push(validator_id.clone())); + Ok(()) + } + + fn unapprove_validator(validator_id: T::AccountId) -> DispatchResult { + let mut approved_set = >::get(); + approved_set.retain(|v| *v != validator_id); + Ok(()) + } + + // Adds offline validators to a local cache for removal at new session. + fn mark_for_removal(validator_id: T::AccountId) { + >::mutate(|v| v.push(validator_id)); + log::debug!( + target: LOG_TARGET, + "Offline validator marked for auto removal." + ); + } + + // Removes offline validators from the validator set and clears the offline + // cache. It is called in the session change hook and removes the validators + // who were reported offline during the session that is ending. We do not + // check for `MinAuthorities` here, because the offline validators will not + // produce blocks and will have the same overall effect on the runtime. + fn remove_offline_validators() { + let validators_to_remove: BTreeSet<_> = >::get().into_iter().collect(); + + // Delete from active validator set. + >::mutate(|vs| vs.retain(|v| !validators_to_remove.contains(v))); + log::debug!( + target: LOG_TARGET, + "Initiated removal of {:?} offline validators.", + validators_to_remove.len() + ); + + // Clear the offline validator list to avoid repeated deletion. + >::put(Vec::::new()); + } } // Provides the new set of validators to the session module when session is // being rotated. impl pallet_session::SessionManager for Pallet { - // Plan a new session and provide new validator set. - fn new_session(_new_index: u32) -> Option> { - // Remove any offline validators. This will only work when the runtime - // also has the im-online pallet. - Self::remove_offline_validators(); + // Plan a new session and provide new validator set. + fn new_session(_new_index: u32) -> Option> { + // Remove any offline validators. This will only work when the runtime + // also has the im-online pallet. + Self::remove_offline_validators(); - log::debug!(target: LOG_TARGET, "New session called; updated validator set provided."); + log::debug!( + target: LOG_TARGET, + "New session called; updated validator set provided." + ); - Some(Self::validators()) - } + Some(Self::validators()) + } - fn end_session(_end_index: u32) {} + fn end_session(_end_index: u32) {} - fn start_session(_start_index: u32) {} + fn start_session(_start_index: u32) {} } impl EstimateNextSessionRotation for Pallet { - fn average_session_length() -> T::BlockNumber { - Zero::zero() - } - - fn estimate_current_session_progress( - _now: T::BlockNumber, - ) -> (Option, frame_support::dispatch::Weight) { - (None, Zero::zero()) - } - - fn estimate_next_session_rotation( - _now: T::BlockNumber, - ) -> (Option, frame_support::dispatch::Weight) { - (None, Zero::zero()) - } + fn average_session_length() -> T::BlockNumber { + Zero::zero() + } + + fn estimate_current_session_progress( + _now: T::BlockNumber, + ) -> (Option, frame_support::dispatch::Weight) { + (None, Zero::zero()) + } + + fn estimate_next_session_rotation( + _now: T::BlockNumber, + ) -> (Option, frame_support::dispatch::Weight) { + (None, Zero::zero()) + } } // Implementation of Convert trait for mapping ValidatorId with AccountId. pub struct ValidatorOf(sp_std::marker::PhantomData); impl Convert> for ValidatorOf { - fn convert(account: T::ValidatorId) -> Option { - Some(account) - } + fn convert(account: T::ValidatorId) -> Option { + Some(account) + } } impl ValidatorSet for Pallet { - type ValidatorId = T::ValidatorId; - type ValidatorIdOf = T::ValidatorIdOf; + type ValidatorId = T::ValidatorId; + type ValidatorIdOf = T::ValidatorIdOf; - fn session_index() -> sp_staking::SessionIndex { - pallet_session::Pallet::::current_index() - } + fn session_index() -> sp_staking::SessionIndex { + pallet_session::Pallet::::current_index() + } - fn validators() -> Vec { - pallet_session::Pallet::::validators() - } + fn validators() -> Vec { + pallet_session::Pallet::::validators() + } } impl ValidatorSetWithIdentification for Pallet { - type Identification = T::ValidatorId; - type IdentificationOf = ValidatorOf; + type Identification = T::ValidatorId; + type IdentificationOf = ValidatorOf; } // Offence reporting and unresponsiveness management. impl> - ReportOffence for Pallet + ReportOffence for Pallet { - fn report_offence(_reporters: Vec, offence: O) -> Result<(), OffenceError> { - let offenders = offence.offenders(); - - for (v, _) in offenders.into_iter() { - Self::mark_for_removal(v); - } - - Ok(()) - } - - fn is_known_offence( - _offenders: &[(T::AccountId, T::AccountId)], - _time_slot: &O::TimeSlot, - ) -> bool { - false - } + fn report_offence(_reporters: Vec, offence: O) -> Result<(), OffenceError> { + let offenders = offence.offenders(); + + for (v, _) in offenders.into_iter() { + Self::mark_for_removal(v); + } + + Ok(()) + } + + fn is_known_offence( + _offenders: &[(T::AccountId, T::AccountId)], + _time_slot: &O::TimeSlot, + ) -> bool { + false + } } \ No newline at end of file diff --git a/substrate-node/pallets/substrate-validator-set/src/mock.rs b/substrate-node/pallets/substrate-validator-set/src/mock.rs index bb4b9115d..3d97ec74d 100644 --- a/substrate-node/pallets/substrate-validator-set/src/mock.rs +++ b/substrate-node/pallets/substrate-validator-set/src/mock.rs @@ -155,26 +155,24 @@ pub fn new_test_ext() -> sp_io::TestExternalities { parameter_types! { pub const MinimumPeriod: u64 = 5; pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); - type DbWeight = (); - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; type Index = u64; + type RuntimeCall = RuntimeCall; type BlockNumber = u64; - type Call = Call; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; + type DbWeight = (); type Version = (); type PalletInfo = PalletInfo; type AccountData = (); @@ -192,7 +190,7 @@ parameter_types! { impl validator_set::Config for Test { type AddRemoveOrigin = EnsureRoot; - type Event = Event; + type RuntimeEvent = RuntimeEvent; type MinAuthorities = MinAuthorities; } @@ -205,5 +203,5 @@ impl pallet_session::Config for Test { type SessionHandler = TestSessionHandler; type Keys = MockSessionKeys; type WeightInfo = (); - type Event = Event; + type RuntimeEvent = RuntimeEvent; } diff --git a/substrate-node/pallets/substrate-validator-set/src/tests.rs b/substrate-node/pallets/substrate-validator-set/src/tests.rs index c23a69cad..76f205c21 100644 --- a/substrate-node/pallets/substrate-validator-set/src/tests.rs +++ b/substrate-node/pallets/substrate-validator-set/src/tests.rs @@ -3,57 +3,68 @@ #![cfg(test)] use super::*; -use crate::mock::{authorities, new_test_ext, Origin, Session, Test, ValidatorSet}; +use crate::mock::*; +use crate::mock::{authorities, new_test_ext, Session, Test, ValidatorSet}; use frame_support::{assert_noop, assert_ok, pallet_prelude::*}; +use frame_system::RawOrigin; use sp_runtime::testing::UintAuthorityId; #[test] fn simple_setup_should_work() { - new_test_ext().execute_with(|| { - assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); - assert_eq!(ValidatorSet::validators(), vec![1u64, 2u64, 3u64]); - assert_eq!(Session::validators(), vec![1, 2, 3]); - }); + new_test_ext().execute_with(|| { + assert_eq!( + authorities(), + vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)] + ); + assert_eq!(ValidatorSet::validators(), vec![1u64, 2u64, 3u64]); + assert_eq!(Session::validators(), vec![1, 2, 3]); + }); } #[test] fn add_validator_updates_validators_list() { - new_test_ext().execute_with(|| { - assert_ok!(ValidatorSet::add_validator(Origin::root(), 4)); - assert_eq!(ValidatorSet::validators(), vec![1u64, 2u64, 3u64, 4u64]) - }); + new_test_ext().execute_with(|| { + assert_ok!(ValidatorSet::add_validator(RawOrigin::Root.into(), 4)); + assert_eq!(ValidatorSet::validators(), vec![1u64, 2u64, 3u64, 4u64]) + }); } #[test] fn remove_validator_updates_validators_list() { - new_test_ext().execute_with(|| { - assert_ok!(ValidatorSet::remove_validator(Origin::root(), 2)); - assert_eq!(ValidatorSet::validators(), vec![1u64, 3u64]); - }); + new_test_ext().execute_with(|| { + assert_ok!(ValidatorSet::remove_validator(RawOrigin::Root.into(), 2)); + assert_eq!(ValidatorSet::validators(), vec![1u64, 3u64]); + }); } #[test] fn add_validator_fails_with_invalid_origin() { - new_test_ext().execute_with(|| { - assert_noop!(ValidatorSet::add_validator(Origin::signed(1), 4), DispatchError::BadOrigin); - }); + new_test_ext().execute_with(|| { + assert_noop!( + ValidatorSet::add_validator(RuntimeOrigin::signed(1), 4), + DispatchError::BadOrigin + ); + }); } #[test] fn remove_validator_fails_with_invalid_origin() { - new_test_ext().execute_with(|| { - assert_noop!( - ValidatorSet::remove_validator(Origin::signed(1), 4), - DispatchError::BadOrigin - ); - }); + new_test_ext().execute_with(|| { + assert_noop!( + ValidatorSet::remove_validator(RuntimeOrigin::signed(1), 4), + DispatchError::BadOrigin + ); + }); } #[test] fn duplicate_check() { - new_test_ext().execute_with(|| { - assert_ok!(ValidatorSet::add_validator(Origin::root(), 4)); - assert_eq!(ValidatorSet::validators(), vec![1u64, 2u64, 3u64, 4u64]); - assert_noop!(ValidatorSet::add_validator(Origin::root(), 4), Error::::Duplicate); - }); -} \ No newline at end of file + new_test_ext().execute_with(|| { + assert_ok!(ValidatorSet::add_validator(RawOrigin::Root.into(), 4)); + assert_eq!(ValidatorSet::validators(), vec![1u64, 2u64, 3u64, 4u64]); + assert_noop!( + ValidatorSet::add_validator(RawOrigin::Root.into(), 4), + Error::::Duplicate + ); + }); +} diff --git a/substrate-node/pallets/test_offchain_worker.py b/substrate-node/pallets/test_offchain_worker.py new file mode 100644 index 000000000..f4b69ae26 --- /dev/null +++ b/substrate-node/pallets/test_offchain_worker.py @@ -0,0 +1,119 @@ +from random import randbytes +from substrateinterface import SubstrateInterface, Keypair, KeypairType + +GIGABYTE = 1024*1024*1024 + +substrate = SubstrateInterface( + url="ws://127.0.0.1:9945", + ss58_format=42, + type_registry_preset='polkadot' +) + +key_alice = Keypair.create_from_uri("//Alice") + +alice_insert_key_params = ["tft!", "//Alice", key_alice.public_key.hex()] +substrate.rpc_request("author_insertKey", alice_insert_key_params) + +alice_insert_key_params = ["smct", "//Alice", key_alice.public_key.hex()] +substrate.rpc_request("author_insertKey", alice_insert_key_params) + + +call_user_accept_tc = substrate.compose_call("TfgridModule", + "user_accept_tc", + { + "document_link": "garbage", + "document_hash": "garbage" + } + ) +call_user_accept_tc_signed = substrate.create_signed_extrinsic(call_user_accept_tc, key_alice) + +response = substrate.submit_extrinsic(call_user_accept_tc_signed, wait_for_finalization=True) +if response.error_message: + print(response.error_message) + + + +call_create_twin = substrate.compose_call("TfgridModule", + "create_twin", + { + "ip": "::1" + }) +call_create_twin_signed = substrate.create_signed_extrinsic(call_create_twin, key_alice) +response = substrate.submit_extrinsic(call_create_twin_signed, wait_for_finalization=True) +if response.error_message: + print(response.error_message) + + + +call_create_farm = substrate.compose_call("TfgridModule", + "create_farm", + { + "name": "myfarm", + "public_ips": [] + }) +call_create_farm_signed = substrate.create_signed_extrinsic(call_create_farm, key_alice) +response = substrate.submit_extrinsic(call_create_farm_signed, wait_for_finalization=True) +if response.error_message: + print(response.error_message) + + + +call_create_node = substrate.compose_call("TfgridModule", + "create_node", + { + "farm_id": "1", + "resources": { + "hru": 1024 * GIGABYTE, + "sru": 512 * GIGABYTE, + "cru": 8, + "mru": 16 * GIGABYTE}, + "location": { + "longitude": "garbage", + "latitude": "garbage" + }, + "country": "Belgium", + "city": "Ghent", + "interfaces": [], + "secure_boot": False, + "virtualized": False, + "serial_number": "garbage" + }) +call_create_node_signed = substrate.create_signed_extrinsic(call_create_node, key_alice) +response = substrate.submit_extrinsic(call_create_node_signed, wait_for_finalization=True) +if response.error_message: + print(response.error_message) + + +call_create_contract = substrate.compose_call("SmartContractModule", + "create_node_contract", + { + "node_id": 1, + "deployment_data": randbytes(32), + "deployment_hash": randbytes(32), + "public_ips": 0, + "solution_provider_id": None + }) +call_create_contract_signed = substrate.create_signed_extrinsic(call_create_contract, key_alice) +response = substrate.submit_extrinsic(call_create_contract_signed, wait_for_finalization=True) +if response.error_message: + print(response.error_message) + +call_create_contract = substrate.compose_call("SmartContractModule", + "report_contract_resources", + { + "contract_resources": [ + { + "contract_id": 1, + "used": { + "hru": 0, + "sru": 20 * GIGABYTE, + "cru": 2, + "mru": 4 * GIGABYTE + } + } + ] + }) +call_create_contract_signed = substrate.create_signed_extrinsic(call_create_contract, key_alice) +response = substrate.submit_extrinsic(call_create_contract_signed, wait_for_finalization=True) +if response.error_message: + print(response.error_message) \ No newline at end of file diff --git a/substrate-node/pallets/test_offchain_worker_setup.py b/substrate-node/pallets/test_offchain_worker_setup.py new file mode 100644 index 000000000..f23311675 --- /dev/null +++ b/substrate-node/pallets/test_offchain_worker_setup.py @@ -0,0 +1,19 @@ +from re import sub +from substrateinterface import SubstrateInterface, Keypair, KeypairType + +GIGABYTE = 1024*1024*1024 + +substrate = SubstrateInterface( + url="ws://127.0.0.1:9946", + ss58_format=42, + type_registry_preset='polkadot' +) + +key_bob = Keypair.create_from_uri("//Bob") + +bob_insert_key_params = ["tft!", "//Bob", key_bob.public_key.hex()] +substrate.rpc_request("author_insertKey", bob_insert_key_params) + +bob_insert_key_params = ["smct", "//Bob", key_bob.public_key.hex()] +substrate.rpc_request("author_insertKey", bob_insert_key_params) + diff --git a/substrate-node/runtime/Cargo.toml b/substrate-node/runtime/Cargo.toml index 27daf3381..e8eb73513 100644 --- a/substrate-node/runtime/Cargo.toml +++ b/substrate-node/runtime/Cargo.toml @@ -5,13 +5,13 @@ homepage = 'https://substrate.dev' license = 'Unlicense' name = 'tfchain-runtime' repository = 'https://github.com/substrate-developer-hub/substrate-node-template/' -version = '2.1.3' +version = '2.2.0' [package.metadata.docs.rs] targets = ['x86_64-unknown-linux-gnu'] [build-dependencies] -substrate-wasm-builder = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.36" } [dependencies.pallet-tfgrid] default-features = false @@ -33,8 +33,9 @@ path = "../pallets/pallet-kvstore" default-features = false git = "https://github.com/threefoldtech/tfchain_tft_bridge" package = "pallet-tft-bridge" -version = "2.4.0" -#path = "../../../tfchain_tft/pallet-tft-bridge" +branch = "feat_upgrade_polkadot-0.9.36" +#version = "2.4.0" +#path = "../../../tfchain_tft_bridge/pallet-tft-bridge" [dependencies.pallet-tft-price] default-features = false @@ -67,41 +68,41 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } - -pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-executive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, features = ['historical'] } -pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -pallet-utility = {git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.24"} - -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } -frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } -try-runtime-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } -frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } + +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, features = ['historical'] } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = {git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +pallet-utility = {git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.36"} + +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } +try-runtime-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false, optional = true } hex-literal = { version = "0.3.1", optional = true } tfchain-support = { path = "../support", default-features = false } @@ -110,19 +111,21 @@ tfchain-support = { path = "../support", default-features = false } default = ['std'] runtime-benchmarks = [ 'hex-literal', - 'frame-benchmarking', + "frame-benchmarking/runtime-benchmarks", 'frame-support/runtime-benchmarks', 'frame-system-benchmarking', 'frame-system/runtime-benchmarks', - 'pallet-balances/runtime-benchmarks', 'pallet-timestamp/runtime-benchmarks', 'sp-runtime/runtime-benchmarks', - 'pallet-collective/runtime-benchmarks', 'pallet-tfgrid/runtime-benchmarks', + 'pallet-balances/runtime-benchmarks', + 'pallet-collective/runtime-benchmarks', + 'pallet-smart-contract/runtime-benchmarks', ] try-runtime = [ "frame-executive/try-runtime", "frame-try-runtime", + "frame-support/try-runtime", "frame-system/try-runtime", "pallet-aura/try-runtime", "pallet-balances/try-runtime", @@ -132,7 +135,21 @@ try-runtime = [ "pallet-timestamp/try-runtime", "pallet-transaction-payment/try-runtime", "pallet-smart-contract/try-runtime", - "pallet-tfgrid/try-runtime" + "pallet-tfgrid/try-runtime", + "validatorset/try-runtime", + "pallet-session/try-runtime", + "pallet-authorship/try-runtime", + "pallet-tft-bridge/try-runtime", + "pallet-tft-price/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-burning/try-runtime", + "pallet-kvstore/try-runtime", + "pallet-collective/try-runtime", + "pallet-membership/try-runtime", + "pallet-runtime-upgrade/try-runtime", + "pallet-validator/try-runtime", + "pallet-dao/try-runtime", + "pallet-utility/try-runtime", ] std = [ 'codec/std', @@ -179,4 +196,4 @@ std = [ 'tfchain-support/std', 'log/std', 'pallet-utility/std', -] \ No newline at end of file +] diff --git a/substrate-node/runtime/src/constants.rs b/substrate-node/runtime/src/constants.rs index 663311f44..6d28f700b 100644 --- a/substrate-node/runtime/src/constants.rs +++ b/substrate-node/runtime/src/constants.rs @@ -28,22 +28,6 @@ pub mod currency { } } -/// Time and blocks. -pub mod time { - use crate::BlockNumber; - pub const MILLISECS_PER_BLOCK: u64 = 6000; - pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 1 * HOURS; - - // These time units are defined in number of blocks. - pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); - pub const HOURS: BlockNumber = MINUTES * 60; - pub const DAYS: BlockNumber = HOURS * 24; - - // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. - pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); -} - /// Fee-related. pub mod fee { use crate::Balance; @@ -73,7 +57,7 @@ pub mod fee { fn polynomial() -> WeightToFeeCoefficients { // in Westend, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: let p = super::currency::CENTS; - let q = 10 * Balance::from(ExtrinsicBaseWeight::get()); + let q = 10 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); smallvec![WeightToFeeCoefficient { degree: 1, negative: false, @@ -88,28 +72,9 @@ pub mod fee { mod tests { use super::currency::{CENTS, MILLICENTS}; use super::fee::WeightToFeeStruct; - use crate::MaximumBlockWeight; use frame_support::weights::constants::ExtrinsicBaseWeight; use frame_support::weights::WeightToFee; - #[test] - // This function tests that the fee for `MaximumBlockWeight` of weight is correct - fn full_block_fee_is_correct() { - // A full block should cost 23.3112 DOLLARS - log::info!("MaxBlockWeight: {:?}", MaximumBlockWeight::get()); - log::info!("BaseWeight: {:?}", ExtrinsicBaseWeight::get()); - // we multiply by 100 to avoid loss of precision after division and devide by 100 at the end - let precision = 100; - let max_block_weight: u128 = (MaximumBlockWeight::get() as u128) * precision; - let ext_base_weight: u128 = ExtrinsicBaseWeight::get() as u128; - let x = WeightToFeeStruct::weight_to_fee(&MaximumBlockWeight::get()); - let cost_extrinsic:u128 = WeightToFeeStruct::weight_to_fee(&ExtrinsicBaseWeight::get()); - let y:u128 = (cost_extrinsic * (max_block_weight/ext_base_weight)) / precision; - // Difference should be less then the cost of an extrinsic devided by 2 as we can execute Z amount of extrinsics and Z was calculated by deviding - // the max amount of weight per block by the weight of one extrinsic. That operation results in a loss of precision (from float to integer). - assert!(x.max(y) - x.min(y) < cost_extrinsic / 2); - } - #[test] // This function tests that the fee for `ExtrinsicBaseWeight` of weight is correct fn extrinsic_base_fee_is_correct() { diff --git a/substrate-node/runtime/src/impls.rs b/substrate-node/runtime/src/impls.rs index 2674af41e..5cebf4eb0 100644 --- a/substrate-node/runtime/src/impls.rs +++ b/substrate-node/runtime/src/impls.rs @@ -9,7 +9,7 @@ where R: pallet_balances::Config, ::AccountId: From, ::AccountId: Into, - ::Event: From>, + ::RuntimeEvent: From>, { fn on_nonzero_unbalanced(amount: NegativeImbalance) { if let Some(author) = Authorship::author() { diff --git a/substrate-node/runtime/src/lib.rs b/substrate-node/runtime/src/lib.rs index 0e722ee77..9c8042315 100644 --- a/substrate-node/runtime/src/lib.rs +++ b/substrate-node/runtime/src/lib.rs @@ -26,14 +26,20 @@ use sp_std::{cmp::Ordering, prelude::*}; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use tfchain_support::{traits::ChangeNode, types::Node}; +use tfchain_support::{ + constants::time::*, + traits::{ChangeNode, PublicIpModifier}, + types::PublicIP, +}; // A few exports that help ease life for downstream crates. pub use frame_support::{ construct_runtime, parameter_types, - traits::{ConstU8, EnsureOneOf, FindAuthor, KeyOwnerProofSystem, PrivilegeCmp, Randomness}, + traits::{ConstU8, EitherOfDiverse, FindAuthor, KeyOwnerProofSystem, PrivilegeCmp, Randomness}, weights::{ - constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + constants::{ + BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND, + }, ConstantMultiplier, IdentityFee, Weight, }, StorageValue, @@ -139,28 +145,13 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("substrate-threefold"), impl_name: create_runtime_str!("substrate-threefold"), authoring_version: 1, - spec_version: 116, + spec_version: 123, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 2, state_version: 0, }; -/// This determines the average expected block time that we are targeting. -/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. -/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked -/// up by `pallet_aura` to implement `fn slot_duration()`. -/// -/// Change this to adjust the block time. -pub const MILLISECS_PER_BLOCK: u64 = 6000; - -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -// Time is measured by number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { @@ -176,14 +167,16 @@ parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const BlockHashCount: BlockNumber = 2400; /// We allow for 2 seconds of compute with a 6 second average block time. - pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights - ::with_sensible_defaults(2 * WEIGHT_PER_SECOND, NORMAL_DISPATCH_RATIO); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::with_sensible_defaults( + Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX), + NORMAL_DISPATCH_RATIO, + ); pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); pub const SS58Prefix: u8 = 42; - pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; - pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; pub const MaxScheduledPerBlock: u32 = 50; pub const NoPreimagePostponement: Option = Some(10); } @@ -200,7 +193,7 @@ impl frame_system::Config for Runtime { /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; + type RuntimeCall = RuntimeCall; /// The lookup mechanism to get account ID from whatever is passed in dispatchers. type Lookup = AccountIdLookup; /// The index type for storing how many extrinsics an account has signed. @@ -214,9 +207,9 @@ impl frame_system::Config for Runtime { /// The header type. type Header = generic::Header; /// The ubiquitous event type. - type Event = Event; + type RuntimeEvent = RuntimeEvent; /// The ubiquitous origin type. - type Origin = Origin; + type RuntimeOrigin = RuntimeOrigin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; /// The weight of database operations that the runtime can invoke. @@ -253,8 +246,7 @@ impl pallet_aura::Config for Runtime { } impl pallet_grandpa::Config for Runtime { - type Event = Event; - type Call = Call; + type RuntimeEvent = RuntimeEvent; type KeyOwnerProofSystem = (); @@ -297,7 +289,7 @@ impl pallet_balances::Config for Runtime { /// The type for recording an account's balance. type Balance = Balance; /// The ubiquitous event type. - type Event = Event; + type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; @@ -309,6 +301,7 @@ parameter_types! { } impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter>; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = WeightToFeeStruct; @@ -317,27 +310,35 @@ impl pallet_transaction_payment::Config for Runtime { } impl pallet_sudo::Config for Runtime { - type Event = Event; - type Call = Call; + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; } -pub type PubConfig = pallet_tfgrid::pallet::PubConfigOf; +pub type Serial = pallet_tfgrid::pallet::SerialNumberOf; +pub type Loc = pallet_tfgrid::pallet::LocationOf; pub type Interface = pallet_tfgrid::pallet::InterfaceOf; + +pub type TfgridNode = pallet_tfgrid::pallet::TfgridNode; + pub struct NodeChanged; -impl ChangeNode for NodeChanged { - fn node_changed( - old_node: Option<&Node>, - new_node: &Node, - ) { +impl ChangeNode for NodeChanged { + fn node_changed(old_node: Option<&TfgridNode>, new_node: &TfgridNode) { Dao::node_changed(old_node, new_node) } - fn node_deleted(node: &Node) { + fn node_deleted(node: &TfgridNode) { SmartContractModule::node_deleted(node); Dao::node_deleted(node); } } +pub struct PublicIpModifierType; +impl PublicIpModifier for PublicIpModifierType { + fn ip_removed(ip: &PublicIP) { + SmartContractModule::ip_removed(ip); + } +} + parameter_types! { pub const MaxFarmNameLength: u32 = 40; pub const MaxInterfaceIpsLength: u32 = 10; @@ -346,31 +347,31 @@ parameter_types! { } impl pallet_tfgrid::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type RestrictedOrigin = EnsureRootOrCouncilApproval; type WeightInfo = pallet_tfgrid::weights::SubstrateWeight; type NodeChanged = NodeChanged; + type PublicIpModifier = SmartContractModule; + type TermsAndConditions = pallet_tfgrid::terms_cond::TermsAndConditions; type TwinIp = pallet_tfgrid::twin::TwinIp; type MaxFarmNameLength = MaxFarmNameLength; type MaxFarmPublicIps = MaxFarmPublicIps; type FarmName = pallet_tfgrid::farm::FarmName; - type PublicIP = pallet_tfgrid::pub_ip::PublicIP; - type GatewayIP = pallet_tfgrid::pub_ip::GatewayIP; - type IP4 = pallet_tfgrid::pub_config::IP4; - type GW4 = pallet_tfgrid::pub_config::GW4; - type IP6 = pallet_tfgrid::pub_config::IP6; - type GW6 = pallet_tfgrid::pub_config::GW6; - type Domain = pallet_tfgrid::pub_config::Domain; type MaxInterfacesLength = MaxInterfacesLength; type InterfaceName = pallet_tfgrid::interface::InterfaceName; type InterfaceMac = pallet_tfgrid::interface::InterfaceMac; type InterfaceIP = pallet_tfgrid::interface::InterfaceIp; type MaxInterfaceIpsLength = MaxInterfaceIpsLength; + type CountryName = pallet_tfgrid::node::CountryName; + type CityName = pallet_tfgrid::node::CityName; + type Location = pallet_tfgrid::node::Location; + type SerialNumber = pallet_tfgrid::node::SerialNumber; } parameter_types! { pub StakingPoolAccount: AccountId = get_staking_pool_account(); pub BillingFrequency: u64 = 600; + pub BillingReferencePeriod: u64 = SECS_PER_HOUR; pub GracePeriod: u64 = (14 * DAYS).into(); pub DistributionFrequency: u16 = 24; pub RetryInterval: u32 = 20; @@ -387,14 +388,18 @@ pub fn get_staking_pool_account() -> AccountId { } impl pallet_smart_contract::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type Currency = Balances; type StakingPoolAccount = StakingPoolAccount; type BillingFrequency = BillingFrequency; + type BillingReferencePeriod = BillingReferencePeriod; type DistributionFrequency = DistributionFrequency; type GracePeriod = GracePeriod; type WeightInfo = pallet_smart_contract::weights::SubstrateWeight; type NodeChanged = NodeChanged; + type PublicIpModifier = PublicIpModifierType; + type AuthorityId = pallet_smart_contract::crypto::AuthId; + type Call = RuntimeCall; type MaxNameContractNameLength = MaxNameContractNameLength; type NameContractName = pallet_smart_contract::name_contract::NameContractName; type RestrictedOrigin = EnsureRootOrCouncilApproval; @@ -404,7 +409,7 @@ impl pallet_smart_contract::Config for Runtime { } impl pallet_tft_bridge::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type Currency = Balances; type Burn = (); type RestrictedOrigin = EnsureRootOrCouncilApproval; @@ -412,24 +417,24 @@ impl pallet_tft_bridge::Config for Runtime { } impl pallet_burning::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type Currency = Balances; type Burn = (); } impl pallet_kvstore::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; } impl pallet_tft_price::Config for Runtime { type AuthorityId = pallet_tft_price::AuthId; - type Call = Call; - type Event = Event; + type Call = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type RestrictedOrigin = EnsureRootOrCouncilApproval; } impl pallet_validator::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type CouncilOrigin = EnsureRootOrCouncilApproval; type Currency = Balances; } @@ -439,7 +444,7 @@ parameter_types! { } impl validatorset::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type AddRemoveOrigin = EnsureRootOrCouncilApproval; type MinAuthorities = MinAuthorities; } @@ -450,9 +455,9 @@ parameter_types! { } impl pallet_dao::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type CouncilOrigin = EnsureRootOrCouncilApproval; - type Proposal = Call; + type Proposal = RuntimeCall; type MotionDuration = DaoMotionDuration; type Tfgrid = TfgridModule; type NodeChanged = NodeChanged; @@ -495,22 +500,22 @@ impl pallet_session::Config for Runtime { type SessionHandler = ::KeyTypeIdProviders; type Keys = opaque::SessionKeys; type WeightInfo = (); - type Event = Event; + type RuntimeEvent = RuntimeEvent; // type DisabledValidatorsThreshold = (); } -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; impl frame_system::offchain::CreateSignedTransaction for Runtime where - Call: From, + RuntimeCall: From, { fn create_transaction>( - call: Call, + call: RuntimeCall, public: ::Signer, account: AccountId, index: Index, ) -> Option<( - Call, + RuntimeCall, ::SignaturePayload, )> { let period = BlockHashCount::get() as u64; @@ -554,9 +559,9 @@ impl frame_system::offchain::SigningTypes for Runtime { impl frame_system::offchain::SendTransactionTypes for Runtime where - Call: From, + RuntimeCall: From, { - type OverarchingCall = Call; + type OverarchingCall = RuntimeCall; type Extrinsic = UncheckedExtrinsic; } @@ -584,17 +589,16 @@ impl PrivilegeCmp for OriginPrivilegeCmp { } impl pallet_scheduler::Config for Runtime { - type Event = Event; - type Origin = Origin; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; type PalletsOrigin = OriginCaller; - type Call = Call; + type RuntimeCall = RuntimeCall; type MaximumWeight = MaximumSchedulerWeight; type ScheduleOrigin = frame_system::EnsureRoot; type MaxScheduledPerBlock = MaxScheduledPerBlock; type WeightInfo = (); type OriginPrivilegeCmp = OriginPrivilegeCmp; - type PreimageProvider = (); - type NoPreimagePostponement = NoPreimagePostponement; + type Preimages = (); } parameter_types! { @@ -605,9 +609,9 @@ parameter_types! { type CouncilCollective = pallet_collective::Instance1; impl pallet_collective::Config for Runtime { - type Origin = Origin; - type Proposal = Call; - type Event = Event; + type RuntimeOrigin = RuntimeOrigin; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type MotionDuration = CouncilMotionDuration; type MaxProposals = CouncilMaxProposals; type MaxMembers = CouncilMaxMembers; @@ -616,7 +620,7 @@ impl pallet_collective::Config for Runtime { } impl pallet_membership::Config for Runtime { - type Event = Event; + type RuntimeEvent = RuntimeEvent; type AddOrigin = EnsureRootOrCouncilApproval; type RemoveOrigin = EnsureRootOrCouncilApproval; type SwapOrigin = EnsureRootOrCouncilApproval; @@ -642,7 +646,7 @@ impl ChangeMembers for MembershipChangedGroup { } } -type EnsureRootOrCouncilApproval = EnsureOneOf< +type EnsureRootOrCouncilApproval = EitherOfDiverse< EnsureRoot, pallet_collective::EnsureProportionAtLeast, >; @@ -682,8 +686,8 @@ impl pallet_authorship::Config for Runtime { impl pallet_randomness_collective_flip::Config for Runtime {} impl pallet_utility::Config for Runtime { - type Event = Event; - type Call = Call; + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; type WeightInfo = pallet_utility::weights::SubstrateWeight; } @@ -703,7 +707,7 @@ construct_runtime!( Session: pallet_session::{Pallet, Call, Storage, Event, Config}, Aura: pallet_aura::{Pallet, Config}, Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, Sudo: pallet_sudo::{Pallet, Call, Config, Storage, Event}, Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent}, TfgridModule: pallet_tfgrid::{Pallet, Call, Storage, Event, Config}, @@ -744,9 +748,10 @@ pub type SignedExtra = ( pallet_transaction_payment::ChargeTransactionPayment, ); /// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; +pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -754,12 +759,40 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPalletsWithSystem, - ( - pallet_tfgrid::nodes_migration::v9::FixFarmNodeIndexMap, - pallet_tfgrid::farm_migration::v10::FixFarmingPolicy, - ), + Migrations, >; +// All migrations executed on runtime upgrade as a nested tuple of types implementing +// `OnRuntimeUpgrade`. +type Migrations = ( + pallet_smart_contract::migrations::v6::ContractMigrationV5, + pallet_tfgrid::migrations::v10::FixFarmNodeIndexMap, + pallet_tfgrid::migrations::v11::FixFarmingPolicy, + pallet_tfgrid::migrations::v12::InputValidation, + pallet_tfgrid::migrations::v13::FixPublicIP, +); + +// follows Substrate's non destructive way of eliminating otherwise required +// repetion: https://github.com/paritytech/substrate/pull/10592 +#[cfg(feature = "runtime-benchmarks")] +#[macro_use] +extern crate frame_benchmarking; + +#[cfg(feature = "runtime-benchmarks")] +mod benches { + define_benchmarks!( + // KILT + [pallet_smart_contract, SmartContractModule] + // Substrate + [frame_benchmarking::baseline, Baseline::] + [frame_system, SystemBench::] + // [pallet_session, Session] + [pallet_balances, Balances] + [pallet_collective, Council] + [pallet_timestamp, Timestamp] + ); +} + impl_runtime_apis! { impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { @@ -801,10 +834,6 @@ impl_runtime_apis! { ) -> sp_inherents::CheckInherentsResult { data.check_extrinsics(&block) } - - // fn random_seed() -> ::Hash { - // RandomnessCollectiveFlip::random_seed().0 - // } } impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { @@ -899,13 +928,33 @@ impl_runtime_apis! { #[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 frame_benchmarking::baseline::Pallet as Baseline; + + 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::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; + use frame_benchmarking::{Benchmarking, BenchmarkBatch, TrackedStorageKey}; + use frame_system_benchmarking::Pallet as SystemBench; + use frame_benchmarking::baseline::Pallet as Baseline; - use frame_system_benchmarking::Module as SystemBench; impl frame_system_benchmarking::Config for Runtime {} + impl frame_benchmarking::baseline::Config for Runtime {} let whitelist: Vec = vec![ // Block Number @@ -928,12 +977,7 @@ impl_runtime_apis! { let mut batches = Vec::::new(); let params = (&config, &whitelist); - add_benchmark!(params, batches, frame_system, SystemBench::); - add_benchmark!(params, batches, pallet_balances, Balances); - add_benchmark!(params, batches, pallet_timestamp, Timestamp); - add_benchmark!(params, batches, pallet_tfgrid, TfgridModule); - add_benchmark!(params, batches, pallet_smart_contract, SmartContractModule); - add_benchmark!(params, batches, pallet_dao, Dao); + add_benchmarks!(params, batches); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) @@ -942,19 +986,23 @@ impl_runtime_apis! { #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { - fn on_runtime_upgrade() -> (frame_support::weights::Weight, frame_support::weights::Weight) { - log::info!("try-runtime::on_runtime_upgrade."); + fn on_runtime_upgrade(checks: bool) -> (Weight, Weight) { // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to // have a backtrace here. If any of the pre/post migration checks fail, we shall stop // right here and right now. - let weight = Executive::try_runtime_upgrade().map_err(|err|{ - log::error!("try-runtime::on_runtime_upgrade failed with: {:?}", err); - err - }).unwrap(); + let weight = Executive::try_runtime_upgrade(checks).unwrap(); (weight, BlockWeights::get().max_block) } - fn execute_block_no_check(block: Block) -> frame_support::weights::Weight { - Executive::execute_block_no_check(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).expect("execute-block failed") } } } diff --git a/substrate-node/support/Cargo.toml b/substrate-node/support/Cargo.toml index d0abf98bc..2082ebc11 100644 --- a/substrate-node/support/Cargo.toml +++ b/substrate-node/support/Cargo.toml @@ -11,10 +11,11 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = "derive", ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.36", default-features = false } +valip = "0.4.0" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/substrate-node/support/src/constants.rs b/substrate-node/support/src/constants.rs index 42aa0b462..709165c04 100644 --- a/substrate-node/support/src/constants.rs +++ b/substrate-node/support/src/constants.rs @@ -1,12 +1,19 @@ pub type BlockNumber = u32; /// Time and blocks. pub mod time { + /// This determines the average expected block time that we are targeting. + /// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. + /// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked + /// up by `pallet_aura` to implement `fn slot_duration()`. + /// + /// Change this to adjust the block time. pub const MILLISECS_PER_BLOCK: u64 = 6000; pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + pub const SECS_PER_HOUR: u64 = 3600; pub const EPOCH_DURATION_IN_BLOCKS: super::BlockNumber = 1 * HOURS; // These time units are defined in number of blocks. pub const MINUTES: super::BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as super::BlockNumber); pub const HOURS: super::BlockNumber = MINUTES * 60; pub const DAYS: super::BlockNumber = HOURS * 24; -} \ No newline at end of file +} diff --git a/substrate-node/support/src/resources.rs b/substrate-node/support/src/resources.rs index 63602faee..4f04292b7 100644 --- a/substrate-node/support/src/resources.rs +++ b/substrate-node/support/src/resources.rs @@ -1,27 +1,105 @@ -pub use super::types::Resources; +use codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use sp_runtime::Percent; + +/// A resources capacity that countains HRU, SRU, CRU and MRU in integer values. +#[derive( + PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo, MaxEncodedLen, +)] +pub struct Resources { + pub hru: u64, + pub sru: u64, + pub cru: u64, + pub mru: u64, +} pub const ONE_THOUSAND: u128 = 1_000; -pub const GIB: u128 = 1024 * 1024 * 1024; +pub const GIGABYTE: u128 = 1024 * 1024 * 1024; + +impl Resources { + pub fn add(mut self, other: &Resources) -> Resources { + self.cru += other.cru; + self.sru += other.sru; + self.hru += other.hru; + self.mru += other.mru; + self + } -pub fn get_cu(resources: Resources) -> u64 { - let cu = calc_cu(resources); - let calculated_cu = 2 * (cu as u128 / GIB / ONE_THOUSAND); - calculated_cu as u64 -} + pub fn validate_hru(&self) -> bool { + // No HRU minimun requirement + true + } -pub fn calc_cu(resources: Resources) -> u64 { - let cu_cru = resources.cru as u128 * 2 * GIB * ONE_THOUSAND; - let cu_mru = ((resources.mru as u128).checked_sub(1).unwrap_or(0) * GIB) * ONE_THOUSAND / 4; - let cu_sru = resources.sru as u128 * ONE_THOUSAND / 50; - cu_cru.min(cu_mru.min(cu_sru)) as u64 -} + pub fn validate_sru(&self) -> bool { + // SRU minimum of 100 GB + self.sru as u128 >= 100 * GIGABYTE + } + + pub fn validate_cru(&self) -> bool { + // CRU minimum of 1 vCPU + self.cru >= 1 + } + + pub fn validate_mru(&self) -> bool { + // MRU minimum of 2GB + self.mru as u128 >= 2 * GIGABYTE + } + + pub fn get_cu(&self) -> u64 { + let cu = self.calc_cu(); + let calculated_cu = 2 * (cu as u128 / GIGABYTE / ONE_THOUSAND); + calculated_cu as u64 + } + + fn calc_cu(&self) -> u64 { + let cru_min = self.cru as u128 * 2 * GIGABYTE * ONE_THOUSAND; + let mru_min = + ((self.mru as u128).checked_sub(1).unwrap_or(0) * GIGABYTE) * ONE_THOUSAND / 4; + let sru_min = self.sru as u128 * ONE_THOUSAND / 50; + + if cru_min < mru_min && cru_min < sru_min { + cru_min as u64 + } else if mru_min < cru_min && mru_min < sru_min { + mru_min as u64 + } else if sru_min < cru_min && sru_min < mru_min { + sru_min as u64 + } else { + 0 + } + } + + pub fn get_su(&self) -> u64 { + let su = self.hru as u128 * ONE_THOUSAND / 1200 + self.sru as u128 * ONE_THOUSAND / 250; + let calculated_su = su / GIGABYTE; + let result = calculated_su as u128 / ONE_THOUSAND; + result as u64 + } + + pub fn get_node_weight(&self) -> u64 { + let cu = self.get_cu(); + let su = self.get_su(); + cu * 2 + su + } + + pub fn has_changed( + resources_before: &Resources, + resources_after: &Resources, + tolerance: u8, + ) -> bool { + let wiggle = |a: u64, b: u64| -> bool { + let p = Percent::from_percent(tolerance) * a; + let diff = (a as i64 - b as i64).abs() as u64; + if diff > p { + return true; + } + return false; + }; -pub fn get_su(resources: Resources) -> u64 { - let su = - resources.hru as u128 * ONE_THOUSAND / 1200 + resources.sru as u128 * ONE_THOUSAND / 250; - let calculated_su = su / GIB; - let result = calculated_su as u128 / ONE_THOUSAND; - result as u64 + return wiggle(resources_before.cru, resources_after.cru) + || wiggle(resources_before.sru, resources_after.sru) + || wiggle(resources_before.hru, resources_after.hru) + || wiggle(resources_before.mru, resources_after.mru); + } } #[cfg(test)] @@ -37,46 +115,46 @@ mod test { sru: 0, }; - let cu = get_cu(resources); + let cu = resources.get_cu(); assert_eq!(cu, 0); } #[test] fn test_calc_cu() { let resources = Resources { - hru: 4 * GIB as u64 * 1024, + hru: 4 * GIGABYTE as u64 * 1024, cru: 64, - mru: 64 * GIB as u64 * 1024, - sru: 12 * GIB as u64 * 1024, + mru: 64 * GIGABYTE as u64 * 1024, + sru: 12 * GIGABYTE as u64 * 1024, }; - let cu = get_cu(resources); + let cu = resources.get_cu(); assert_eq!(cu, 256); } #[test] fn test_calc_cu_2() { let resources = Resources { - hru: 4 * GIB as u64 * 1024, + hru: 4 * GIGABYTE as u64 * 1024, cru: 4, mru: 8, - sru: 12 * GIB as u64 * 1024, + sru: 12 * GIGABYTE as u64 * 1024, }; - let cu = get_cu(resources); + let cu = resources.get_cu(); assert_eq!(cu, 2); } #[test] fn test_calc_su() { let resources = Resources { - hru: 4 * GIB as u64 * 1024, + hru: 4 * GIGABYTE as u64 * 1024, cru: 64, mru: 64, - sru: 12 * GIB as u64 * 1024, + sru: 12 * GIGABYTE as u64 * 1024, }; - let su = get_su(resources); + let su = resources.get_su(); assert_eq!(su, 52); } @@ -86,10 +164,10 @@ mod test { hru: 0, cru: 64, mru: 64, - sru: 12 * GIB as u64 * 1024, + sru: 12 * GIGABYTE as u64 * 1024, }; - let su = get_su(resources); + let su = resources.get_su(); assert_eq!(su, 49); } @@ -102,20 +180,71 @@ mod test { sru: 0, }; - let su = get_su(resources); + let su = resources.get_su(); assert_eq!(su, 0); } #[test] fn test_calc_su_4() { let resources = Resources { - hru: 4 * GIB as u64 * 1024, + hru: 4 * GIGABYTE as u64 * 1024, cru: 64, mru: 64, sru: 0, }; - let su = get_su(resources); + let su = resources.get_su(); assert_eq!(su, 3); } + + #[test] + fn test_resources_diff() { + let resources = Resources { + hru: 4 * GIGABYTE as u64 * 1024, + cru: 64, + mru: 64 * GIGABYTE as u64, + sru: 0, + }; + + let new_resources = Resources { + hru: 4 * GIGABYTE as u64 * 1024, + cru: 64, + mru: 64 * GIGABYTE as u64, + sru: 0, + }; + + assert_eq!(Resources::has_changed(&resources, &new_resources, 1), false); + + let resources = Resources { + hru: 4 * GIGABYTE as u64 * 1024, + cru: 64, + mru: 64 * GIGABYTE as u64, + sru: 0, + }; + + let new_resources = Resources { + hru: 4 * GIGABYTE as u64 * 1024, + cru: 64, + mru: 40 * GIGABYTE as u64, + sru: 0, + }; + + assert_eq!(Resources::has_changed(&resources, &new_resources, 1), true); + + let resources = Resources { + hru: 4 * GIGABYTE as u64 * 1024, + cru: 64, + mru: 64 * GIGABYTE as u64, + sru: 1000 * GIGABYTE as u64, + }; + + let new_resources = Resources { + hru: 4 * GIGABYTE as u64 * 1024, + cru: 64, + mru: 64 * GIGABYTE as u64, + sru: 989 * GIGABYTE as u64, + }; + + assert_eq!(Resources::has_changed(&resources, &new_resources, 1), true); + } } diff --git a/substrate-node/support/src/traits.rs b/substrate-node/support/src/traits.rs index ff7a3cd70..fd5938263 100644 --- a/substrate-node/support/src/traits.rs +++ b/substrate-node/support/src/traits.rs @@ -1,10 +1,19 @@ -pub trait Tfgrid { - fn get_farm(farm_id: u32) -> Option>; + +use crate::types::PublicIP; +pub trait Tfgrid { + fn get_farm(farm_id: u32) -> Option>; fn is_farm_owner(farm_id: u32, who: AccountId) -> bool; fn is_twin_owner(twin_id: u32, who: AccountId) -> bool; } -pub trait ChangeNode { - fn node_changed(node: Option<&super::types::Node>, new_node: &super::types::Node); - fn node_deleted(node: &super::types::Node); -} \ No newline at end of file +pub trait ChangeNode { + fn node_changed( + node: Option<&super::types::Node>, + new_node: &super::types::Node, + ); + fn node_deleted(node: &super::types::Node); +} + +pub trait PublicIpModifier { + fn ip_removed(ip: &PublicIP); +} diff --git a/substrate-node/support/src/types.rs b/substrate-node/support/src/types.rs index a7fb09309..3e8a63437 100644 --- a/substrate-node/support/src/types.rs +++ b/substrate-node/support/src/types.rs @@ -1,13 +1,22 @@ +use super::resources::Resources; use codec::{Decode, Encode, MaxEncodedLen}; use core::cmp::{Ord, Ordering, PartialOrd}; use frame_support::{traits::ConstU32, BoundedVec}; use scale_info::TypeInfo; use sp_std::prelude::*; +use valip::ip4::{Ip as IPv4, CIDR as IPv4Cidr}; +use valip::ip6::{Ip as IPv6, CIDR as IPv6Cidr}; + +pub const MAX_IP4_LENGTH: u32 = 18; +pub const MAX_GW4_LENGTH: u32 = 15; +pub const MAX_IP6_LENGTH: u32 = 43; +pub const MAX_GW6_LENGTH: u32 = 39; +pub const MAX_DOMAIN_NAME_LENGTH: u32 = 128; #[derive( PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo, MaxEncodedLen, )] -pub struct Farm { +pub struct Farm { pub version: u32, pub id: u32, pub name: Name, @@ -22,9 +31,9 @@ pub struct Farm { #[derive( PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo, MaxEncodedLen, )] -pub struct PublicIP { - pub ip: Ip, - pub gateway: Gateway, +pub struct PublicIP { + pub ip: BoundedVec>, + pub gateway: BoundedVec>, pub contract_id: u64, } @@ -69,24 +78,22 @@ pub struct FarmingPolicyLimit { } #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] -pub struct Node { +pub struct Node { pub version: u32, pub id: u32, pub farm_id: u32, pub twin_id: u32, pub resources: Resources, pub location: Location, - pub country: Vec, - pub city: Vec, // optional public config - pub public_config: Option, + pub public_config: Option, pub created: u64, pub farming_policy_id: u32, pub interfaces: Vec, pub certification: NodeCertification, pub secure_boot: bool, pub virtualized: bool, - pub serial_number: Vec, + pub serial_number: Option, pub connection_price: u32, } @@ -98,54 +105,95 @@ pub struct Interface { } #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] -pub struct PublicConfig { +pub struct PublicConfig { pub ip4: IP4, - pub ip6: IP6, - pub domain: Domain, + pub ip6: Option, + pub domain: Option>>, } #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] -pub struct IP { - pub ip: IpAddr, - pub gw: Gw, +pub struct IP4 { + pub ip: BoundedVec>, + pub gw: BoundedVec>, +} + +#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] +pub enum PublicIpError { + InvalidIp4, + InvalidGw4, + InvalidIp6, + InvalidGw6, + InvalidPublicIp, + InvalidDomain, +} + +impl IP4 { + pub fn is_valid(&self) -> Result<(), PublicIpError> { + let gw4 = IPv4::parse(&self.gw).map_err(|_| PublicIpError::InvalidGw4)?; + let ip4 = IPv4Cidr::parse(&self.ip).map_err(|_| PublicIpError::InvalidIp4)?; + + if gw4.is_public() + && gw4.is_unicast() + && ip4.is_public() + && ip4.is_unicast() + && ip4.contains(gw4) + { + Ok(()) + } else { + Err(PublicIpError::InvalidPublicIp) + } + } } -#[derive( - PartialEq, - Eq, - PartialOrd, - Ord, - Clone, - Encode, - Decode, - Default, - Debug, - TypeInfo, - Copy, - MaxEncodedLen, -)] -pub struct Resources { - pub hru: u64, - pub sru: u64, - pub cru: u64, - pub mru: u64, -} - -impl Resources { - pub fn add(mut self, other: &Resources) -> Resources { - self.cru += other.cru; - self.sru += other.sru; - self.hru += other.hru; - self.mru += other.mru; - self +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] +pub struct IP6 { + pub ip: BoundedVec>, + pub gw: BoundedVec>, +} + +impl IP6 { + pub fn is_valid(&self) -> Result<(), PublicIpError> { + let gw6 = IPv6::parse(&self.gw).map_err(|_| PublicIpError::InvalidGw6)?; + let ipv6 = IPv6Cidr::parse(&self.ip).map_err(|_| PublicIpError::InvalidIp6)?; + + if gw6.is_public() + && gw6.is_unicast() + && ipv6.is_public() + && ipv6.is_unicast() + && ipv6.contains(gw6) + { + Ok(()) + } else { + Err(PublicIpError::InvalidPublicIp) + } } } -// Store Location long and lat as string -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo)] -pub struct Location { - pub longitude: Vec, - pub latitude: Vec, +impl PublicConfig { + pub fn is_valid(&self) -> Result<(), PublicIpError> { + // Validate domain + if let Some(domain) = &self.domain { + if !is_valid_domain(&domain) { + return Err(PublicIpError::InvalidDomain); + } + } + + // Validate ip4 config + self.ip4.is_valid()?; + + // If ip6 config, validate + if let Some(ip6) = &self.ip6 { + Ok(ip6.is_valid()?) + } else { + Ok(()) + } + } +} + +fn is_valid_domain(input: &[u8]) -> bool { + input + .iter() + .all(|c| matches!(c, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'-' | b'.')) } #[derive(PartialEq, Eq, Clone, Encode, Decode, Debug, TypeInfo, Copy)] diff --git a/substrate-node/tests/SubstrateNetwork.py b/substrate-node/tests/SubstrateNetwork.py index a5f64465c..57fc919ef 100644 --- a/substrate-node/tests/SubstrateNetwork.py +++ b/substrate-node/tests/SubstrateNetwork.py @@ -46,16 +46,12 @@ def wait_till_node_ready(log_file: str, timeout_in_seconds=TIMEOUT_STARTUP_IN_SE if RE_NODE_STARTED.search(line): return -def setup_offchain_workers(port: int, worker_tft: str = "Alice", worker_smct: str = "Bob"): +def setup_offchain_workers(port: int, worker_account: str = "Alice"): logging.info("Setting up offchain workers") substrate = SubstrateInterface(url=f"ws://127.0.0.1:{port}", ss58_format=42, type_registry_preset='polkadot') insert_key_params = [ - "tft!", f"//{worker_tft}", PREDEFINED_KEYS[worker_tft].public_key.hex()] - substrate.rpc_request("author_insertKey", insert_key_params) - - insert_key_params = [ - "smct", f"//{worker_smct}", PREDEFINED_KEYS[worker_smct].public_key.hex()] + "tft!", f"//{worker_account}", PREDEFINED_KEYS[worker_account].public_key.hex()] substrate.rpc_request("author_insertKey", insert_key_params) def execute_command(cmd: list, log_file: str | None = None): @@ -128,7 +124,7 @@ def setup_multi_node_network(self, log_name: str = "", amt: int = 2): self._nodes["alice"] = run_node(log_file_alice, "/tmp/alice", "alice", port, ws_port, rpc_port, node_key="0000000000000000000000000000000000000000000000000000000000000001") wait_till_node_ready(log_file_alice) - setup_offchain_workers(ws_port) + setup_offchain_workers(ws_port, "Alice") log_file = "" for x in range(1, amt): @@ -140,7 +136,7 @@ def setup_multi_node_network(self, log_name: str = "", amt: int = 2): self._nodes[name] = run_node(log_file, f"/tmp/{name}", name, port, ws_port, rpc_port, node_key=None, bootnodes="/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp") wait_till_node_ready(log_file) - setup_offchain_workers(ws_port) + setup_offchain_workers(ws_port, "Bob") logging.info("Network is up and running.") diff --git a/substrate-node/tests/TfChainClient.py b/substrate-node/tests/TfChainClient.py index 046b4d15a..2b05994ef 100644 --- a/substrate-node/tests/TfChainClient.py +++ b/substrate-node/tests/TfChainClient.py @@ -277,7 +277,7 @@ def add_farm_ip(self, id: int = 1, ip: str = "", gateway: str = "", port: int = { "id": id, "ip": ip, - "gateway": gateway + "gw": gateway }) expected_events = [{ "module_id": "TfgridModule", diff --git a/substrate-node/tests/integration_tests.robot b/substrate-node/tests/integration_tests.robot index 2da7d4012..024293647 100644 --- a/substrate-node/tests/integration_tests.robot +++ b/substrate-node/tests/integration_tests.robot @@ -287,7 +287,7 @@ Test Add Public Config On Node: Failure InvalidIP4 Setup Network And Create Node - Run Keyword And Expect Error *'InvalidIP4'* + Run Keyword And Expect Error *'InvalidPublicConfig'* ... Add Node Public Config farm_id=${1} node_id=${1} ipv4=185.206.122.33 gw4=185.206.122.1 domain=some-domain Tear Down Multi Node Network @@ -298,7 +298,7 @@ Test Add Public Config On Node: Failure InvalidIP6 Setup Network And Create Node - Run Keyword And Expect Error *'InvalidIP6'* + Run Keyword And Expect Error *'InvalidPublicConfig'* ... Add Node Public Config farm_id=${1} node_id=${1} ipv4=185.206.122.33/24 gw4=185.206.122.1 ipv6=2a10:b600:1::0cc4:7a30:65b5 gw6=2a10:b600:1::1 domain=some-domain Tear Down Multi Node Network @@ -308,7 +308,7 @@ Test Add Public Config On Node: Failure InvalidDomain Setup Multi Node Network log_name=test_add_pub_config_node_failure_invaliddomain Setup Network And Create Node - Run Keyword And Expect Error *'InvalidDomain'* + Run Keyword And Expect Error *'InvalidPublicConfig'* ... Add Node Public Config farm_id=${1} node_id=${1} ipv4=185.206.122.33/24 gw4=185.206.122.1 ipv6=2a10:b600:1::0cc4:7a30:65b5/64 gw6=2a10:b600:1::1 domain=some_invalid_domain Tear Down Multi Node Network