From 40eca7cb942d8db6965864b07130630fa0f54870 Mon Sep 17 00:00:00 2001 From: borispovod Date: Thu, 10 Feb 2022 20:49:51 +0300 Subject: [PATCH 01/13] update to polkadot v0.9.16 --- Cargo.lock | 2776 ++++++++++++---------- README.md | 4 +- docker-compose.yml | 2 +- node/Cargo.toml | 100 +- pallets/author-mapping/Cargo.toml | 22 +- pallets/author-mapping/src/lib.rs | 92 +- pallets/author-mapping/src/migrations.rs | 10 +- pallets/author-mapping/src/mock.rs | 28 +- pallets/author-mapping/src/tests.rs | 86 +- pallets/currencies/Cargo.toml | 25 +- pallets/currencies/src/lib.rs | 8 +- pallets/currencies/src/mock.rs | 11 +- pallets/groupsign/Cargo.toml | 14 +- pallets/parachain-staking/Cargo.toml | 20 +- pallets/parachain-staking/src/lib.rs | 31 +- pallets/sp-mvm/Cargo.toml | 26 +- pallets/sp-mvm/rpc/Cargo.toml | 12 +- pallets/sp-mvm/rpc/runtime/Cargo.toml | 11 +- pallets/sp-mvm/src/balance.rs | 9 +- pallets/sp-mvm/src/lib.rs | 1 + pallets/transaction-pause/Cargo.toml | 40 +- pallets/transaction-pause/src/lib.rs | 1 + pallets/transaction-pause/src/mock.rs | 3 +- primitives/Cargo.toml | 6 +- primitives/src/currency.rs | 4 +- runtime/Cargo.toml | 110 +- 26 files changed, 1853 insertions(+), 1599 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5d5edfa..48cbcd3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,22 +12,13 @@ dependencies = [ "regex", ] -[[package]] -name = "addr2line" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" -dependencies = [ - "gimli 0.25.0", -] - [[package]] name = "addr2line" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ - "gimli 0.26.1", + "gimli", ] [[package]] @@ -258,7 +249,7 @@ dependencies = [ "parking", "polling", "slab", - "socket2 0.4.3", + "socket2 0.4.4", "waker-fn", "winapi 0.3.9", ] @@ -329,9 +320,9 @@ dependencies = [ [[package]] name = "async-std-resolver" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed4e2c3da14d8ad45acb1e3191db7a918e9505b6f155b218e70a7c9a1a48c638" +checksum = "dbf3e776afdf3a2477ef4854b85ba0dff3bd85792f685fb3c68948b4d304e4f0" dependencies = [ "async-std", "async-trait", @@ -412,17 +403,17 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6" +checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" dependencies = [ - "addr2line 0.17.0", + "addr2line", "cc", "cfg-if 1.0.0", "libc", @@ -491,14 +482,15 @@ dependencies = [ [[package]] name = "beefy-gadget" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-primitives", "fnv", - "futures 0.3.19", + "futures 0.3.21", "log", "parity-scale-codec", "parking_lot 0.11.2", + "sc-chain-spec", "sc-client-api", "sc-keystore", "sc-network", @@ -508,8 +500,8 @@ dependencies = [ "sp-application-crypto", "sp-arithmetic", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "sp-runtime", "substrate-prometheus-endpoint", "thiserror", @@ -519,40 +511,44 @@ dependencies = [ [[package]] name = "beefy-gadget-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-gadget", "beefy-primitives", - "futures 0.3.19", + "derive_more", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", "jsonrpc-derive 18.0.0", "jsonrpc-pubsub 18.0.0", "log", "parity-scale-codec", + "parking_lot 0.11.2", "sc-rpc", + "sc-utils", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", + "thiserror", ] [[package]] name = "beefy-merkle-tree" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" [[package]] name = "beefy-primitives" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", "sp-api", "sp-application-crypto", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -687,6 +683,15 @@ dependencies = [ "generic-array 0.14.5", ] +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array 0.14.5", +] + [[package]] name = "block-padding" version = "0.1.5" @@ -726,9 +731,9 @@ dependencies = [ [[package]] name = "bounded-vec" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afdd1dffefe5fc66262a524b91087c43b16e478b2e3dc49eb11b0e2fd6b6ec90" +checksum = "b47cca82fca99417fe405f09d93bb8fff90bdd03d13c631f18096ee123b4281c" dependencies = [ "thiserror", ] @@ -736,35 +741,35 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "finality-grandpa", "frame-support", "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-finality-grandpa", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "bp-message-dispatch" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-runtime", "frame-support", "parity-scale-codec", "scale-info", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "bp-messages" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-runtime", @@ -774,13 +779,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-runtime", @@ -789,31 +794,16 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-version", ] -[[package]] -name = "bp-rialto" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" -dependencies = [ - "bp-messages", - "bp-runtime", - "frame-support", - "frame-system", - "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", -] - [[package]] name = "bp-rococo" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -823,32 +813,32 @@ dependencies = [ "smallvec 1.8.0", "sp-api", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-version", ] [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "hash-db", "num-traits", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", + "sp-trie 4.0.0", ] [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "ed25519-dalek", @@ -857,13 +847,13 @@ dependencies = [ "sp-application-crypto", "sp-finality-grandpa", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "bp-wococo" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -872,13 +862,13 @@ dependencies = [ "parity-scale-codec", "sp-api", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "bridge-runtime-common" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-messages", @@ -891,11 +881,11 @@ dependencies = [ "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", + "sp-trie 4.0.0", ] [[package]] @@ -1010,7 +1000,7 @@ checksum = "ba2ae6de944143141f6155a473a6b02f66c7c3f9f47316f802f80204ebfe6e12" dependencies = [ "camino", "cargo-platform", - "semver 1.0.4", + "semver 1.0.5", "serde", "serde_json", ] @@ -1128,9 +1118,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa66045b9cb23c2e9c1520732030608b02ee07e5cfaa5a521ec15ded7fa24c90" +checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" dependencies = [ "glob", "libc", @@ -1204,9 +1194,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -1247,24 +1237,24 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc0cb7df82c8cf8f2e6a8dd394a0932a71369c160cc9b027dca414fced242513" +checksum = "9516ba6b2ba47b4cbf63b713f75b432fafa0a0e0464ec8381ec76e6efe931ab3" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4463c15fa42eee909e61e5eac4866b7c6d22d0d8c621e57a0c5380753bfa8c" +checksum = "489e5d0081f7edff6be12d71282a8bf387b5df64d5592454b75d662397f2d642" dependencies = [ "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-entity", - "gimli 0.25.0", + "gimli", "log", "regalloc", "smallvec 1.8.0", @@ -1273,34 +1263,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793f6a94a053a55404ea16e1700202a88101672b8cd6b4df63e13cde950852bf" +checksum = "d36ee1140371bb0f69100e734b30400157a4adf7b86148dee8b0a438763ead48" dependencies = [ "cranelift-codegen-shared", - "cranelift-entity", ] [[package]] name = "cranelift-codegen-shared" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44aa1846df275bce5eb30379d65964c7afc63c05a117076e62a119c25fe174be" +checksum = "981da52d8f746af1feb96290c83977ff8d41071a7499e991d8abae0d4869f564" [[package]] name = "cranelift-entity" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3a45d8d6318bf8fc518154d9298eab2a8154ec068a8885ff113f6db8d69bb3a" +checksum = "a2906740053dd3bcf95ce53df0fd9b5649c68ae4bd9adada92b406f059eae461" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e07339bd461766deb7605169de039e01954768ff730fa1254e149001884a8525" +checksum = "b7cb156de1097f567d46bf57a0cd720a72c3e15e1a2bd8b1041ba2fc894471b7" dependencies = [ "cranelift-codegen", "log", @@ -1310,9 +1299,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e2fca76ff57e0532936a71e3fc267eae6a19a86656716479c66e7f912e3d7b" +checksum = "166028ca0343a6ee7bddac0e70084e142b23f99c701bd6f6ea9123afac1a7a46" dependencies = [ "cranelift-codegen", "libc", @@ -1321,9 +1310,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.78.0" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f46fec547a1f8a32c54ea61c28be4f4ad234ad95342b718a9a9adcaadb0c778" +checksum = "5012a1cde0c8b3898770b711490d803018ae9bec2d60674ba0e5b2058a874f80" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1337,9 +1326,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if 1.0.0", ] @@ -1367,9 +1356,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -1380,9 +1369,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" dependencies = [ "cfg-if 1.0.0", "lazy_static", @@ -1394,6 +1383,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-common" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" +dependencies = [ + "generic-array 0.14.5", +] + [[package]] name = "crypto-mac" version = "0.8.0" @@ -1456,7 +1454,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "sc-cli", "sc-service", @@ -1466,12 +1464,13 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", "cumulus-primitives-core", - "futures 0.3.19", + "cumulus-relay-chain-interface", + "futures 0.3.21", "parity-scale-codec", "parking_lot 0.10.2", "polkadot-node-primitives", @@ -1481,7 +1480,7 @@ dependencies = [ "sc-client-api", "sp-api", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", "tracing", ] @@ -1489,11 +1488,12 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "async-trait", + "cumulus-relay-chain-interface", "dyn-clone", - "futures 0.3.19", + "futures 0.3.21", "parity-scale-codec", "polkadot-primitives", "sc-client-api", @@ -1502,28 +1502,28 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-runtime", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-trie 4.0.0", "tracing", ] [[package]] name = "cumulus-client-consensus-relay-chain" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "async-trait", "cumulus-client-consensus-common", "cumulus-primitives-core", - "futures 0.3.19", + "cumulus-relay-chain-interface", + "futures 0.3.21", "parking_lot 0.10.2", - "polkadot-client", "sc-client-api", "sc-consensus", "sp-api", "sp-block-builder", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", "sp-runtime", "substrate-prometheus-endpoint", @@ -1533,14 +1533,15 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ + "async-trait", + "cumulus-relay-chain-interface", "derive_more", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "parity-scale-codec", - "parking_lot 0.10.2", - "polkadot-client", + "parking_lot 0.11.2", "polkadot-node-primitives", "polkadot-parachain", "polkadot-primitives", @@ -1548,19 +1549,21 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", + "sp-state-machine 0.10.0", "tracing", ] [[package]] name = "cumulus-client-pov-recovery" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", - "futures 0.3.19", - "futures-timer 3.0.2", + "cumulus-relay-chain-interface", + "futures 0.3.21", + "futures-timer", "parity-scale-codec", "polkadot-node-primitives", "polkadot-node-subsystem", @@ -1579,17 +1582,17 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-client-collator", "cumulus-client-consensus-common", "cumulus-client-pov-recovery", "cumulus-primitives-core", + "cumulus-relay-chain-interface", "parity-scale-codec", "parking_lot 0.10.2", "polkadot-overseer", "polkadot-primitives", - "polkadot-service", "sc-chain-spec", "sc-client-api", "sc-consensus", @@ -1600,7 +1603,7 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", "tracing", ] @@ -1608,7 +1611,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1616,9 +1619,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] @@ -1626,7 +1629,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-pallet-parachain-system-proc-macro", "cumulus-primitives-core", @@ -1634,20 +1637,21 @@ dependencies = [ "environmental", "frame-support", "frame-system", + "impl-trait-for-tuples", "log", "pallet-balances", "parity-scale-codec", "polkadot-parachain", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", + "sp-trie 4.0.0", "sp-version", "xcm", ] @@ -1655,7 +1659,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -1666,7 +1670,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1674,16 +1678,16 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", ] [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1693,7 +1697,7 @@ dependencies = [ "rand_chacha 0.3.1", "scale-info", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] @@ -1701,57 +1705,57 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "frame-support", - "impl-trait-for-tuples", "parity-scale-codec", "polkadot-core-primitives", "polkadot-parachain", "polkadot-primitives", "sp-api", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-trie 4.0.0", ] [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "async-trait", "cumulus-primitives-core", + "cumulus-relay-chain-interface", "cumulus-test-relay-sproof-builder", "parity-scale-codec", - "polkadot-client", "sc-client-api", "scale-info", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", + "sp-storage 4.0.0", + "sp-trie 4.0.0", "tracing", ] [[package]] name = "cumulus-primitives-timestamp" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", "sp-inherents", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-timestamp", ] [[package]] name = "cumulus-primitives-utility" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1760,22 +1764,43 @@ dependencies = [ "polkadot-parachain", "polkadot-primitives", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-trie 4.0.0", "xcm", ] +[[package]] +name = "cumulus-relay-chain-interface" +version = "0.1.0" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" +dependencies = [ + "async-trait", + "cumulus-primitives-core", + "derive_more", + "futures 0.3.21", + "parking_lot 0.11.2", + "polkadot-overseer", + "sc-client-api", + "sc-service", + "sp-api", + "sp-blockchain", + "sp-core 4.1.0-dev", + "sp-runtime", + "sp-state-machine 0.10.0", + "thiserror", +] + [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", "polkadot-primitives", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", ] [[package]] @@ -1928,6 +1953,16 @@ dependencies = [ "generic-array 0.14.5", ] +[[package]] +name = "digest" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", +] + [[package]] name = "directories" version = "4.0.1" @@ -2116,19 +2151,6 @@ dependencies = [ "syn", ] -[[package]] -name = "env_logger" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime 1.3.0", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.9.0" @@ -2136,7 +2158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ "atty", - "humantime 2.1.0", + "humantime", "log", "regex", "termcolor", @@ -2231,7 +2253,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", ] [[package]] @@ -2304,11 +2326,11 @@ dependencies = [ [[package]] name = "file-per-thread-logger" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fdbe0d94371f9ce939b555dd342d0686cc4c0cadbcd4b61d70af5ff97eb4126" +checksum = "21e16290574b39ee41c71aeb90ae960c504ebaf1e2a1c87bd52aa56ed6e1a02f" dependencies = [ - "env_logger 0.7.1", + "env_logger", "log", ] @@ -2319,8 +2341,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8ac3ff5224ef91f3c97e03eb1de2db82743427e91aaa5ac635f454f0b164f5a" dependencies = [ "either", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "log", "num-traits", "parity-scale-codec", @@ -2374,7 +2396,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", ] @@ -2392,7 +2414,7 @@ dependencies = [ [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -2402,17 +2424,18 @@ dependencies = [ "paste", "scale-info", "sp-api", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-application-crypto", + "sp-io 4.0.0", "sp-runtime", - "sp-runtime-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-runtime-interface 4.1.0-dev", + "sp-std 4.0.0", + "sp-storage 4.0.0", ] [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "Inflector", "chrono", @@ -2427,18 +2450,18 @@ dependencies = [ "sc-executor", "sc-service", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", + "sp-keystore 0.10.0", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", "structopt", ] [[package]] name = "frame-election-provider-support" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -2446,23 +2469,23 @@ dependencies = [ "scale-info", "sp-arithmetic", "sp-npos-elections", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-tracing 4.0.0", ] [[package]] @@ -2480,7 +2503,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "bitflags", "frame-metadata", @@ -2494,22 +2517,22 @@ dependencies = [ "serde", "smallvec 1.8.0", "sp-arithmetic", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-core-hashing-proc-macro", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", "sp-staking", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", + "sp-tracing 4.0.0", "tt-call", ] [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "Inflector", "frame-support-procedural-tools", @@ -2521,7 +2544,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 1.1.0", @@ -2533,7 +2556,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro2", "quote", @@ -2543,39 +2566,39 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "log", "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-version", ] [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "sp-api", @@ -2584,12 +2607,12 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "sp-api", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -2650,9 +2673,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -2665,9 +2688,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -2675,15 +2698,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -2693,9 +2716,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-lite" @@ -2714,9 +2737,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ "proc-macro2", "quote", @@ -2736,21 +2759,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" - -[[package]] -name = "futures-timer" -version = "2.0.2" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-timer" @@ -2760,9 +2777,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures 0.1.31", "futures-channel", @@ -2783,7 +2800,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" dependencies = [ - "typenum 1.15.0", + "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2792,7 +2809,7 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ - "typenum 1.15.0", + "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "version_check", ] @@ -2834,21 +2851,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" dependencies = [ "fallible-iterator", "indexmap 1.8.0", "stable_deref_trait", ] -[[package]] -name = "gimli" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" - [[package]] name = "glob" version = "0.3.0" @@ -2870,15 +2881,14 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f16c88aa13d2656ef20d1c042086b8767bbe2bdb62526894275a1b062161b2e" +checksum = "4d12a7f4e95cfe710f1d624fb1210b7d961a5fb05c4fd942f4feab06e61f590e" dependencies = [ "futures-channel", "futures-core", "js-sys", "wasm-bindgen", - "web-sys", ] [[package]] @@ -2890,11 +2900,11 @@ dependencies = [ "getrandom 0.2.4", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", + "sp-keystore 0.10.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -2963,6 +2973,15 @@ dependencies = [ "ahash 0.7.6", ] +[[package]] +name = "hashbrown" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" +dependencies = [ + "ahash 0.7.6", +] + [[package]] name = "heck" version = "0.3.3" @@ -3065,9 +3084,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" [[package]] name = "httpdate" @@ -3075,15 +3094,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error 1.2.3", -] - [[package]] name = "humantime" version = "2.1.0" @@ -3107,7 +3117,7 @@ dependencies = [ "httpdate", "itoa 0.4.8", "pin-project-lite 0.2.8", - "socket2 0.4.3", + "socket2 0.4.4", "tokio", "tower-service", "tracing", @@ -3181,7 +3191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae8ab7f67bad3240049cb24fb9cb0b4c2c6af4c245840917fbbdededeee91179" dependencies = [ "async-io", - "futures 0.3.19", + "futures 0.3.21", "futures-lite", "if-addrs", "ipnet", @@ -3219,9 +3229,9 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5dacb10c5b3bb92d46ba347505a9041e676bb20ad220101326bffb0c93031ee" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", @@ -3273,23 +3283,12 @@ dependencies = [ "num-traits", ] -[[package]] -name = "intervalier" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275" -dependencies = [ - "futures 0.3.19", - "futures-timer 2.0.2", -] - [[package]] name = "io-lifetimes" -version = "0.3.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "278e90d6f8a6c76a8334b336e306efa3c5f2b604048cbfd486d6f49878e3af14" +checksum = "f6ef6787e7f0faedc040f95716bdd0e62bcfcf4ba93da053b62dea2691c13864" dependencies = [ - "rustc_version 0.4.0", "winapi 0.3.9", ] @@ -3388,7 +3387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a" dependencies = [ "derive_more", - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-pubsub 18.0.0", "log", @@ -3429,7 +3428,7 @@ version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "futures-executor", "futures-util", "log", @@ -3453,7 +3452,7 @@ version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-client-transports 18.0.0", ] @@ -3487,7 +3486,7 @@ version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1dea6e07251d9ce6a552abfb5d7ad6bc290a4596c8dcc3d795fae2bbdc1f3ff" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "hyper", "jsonrpc-core 18.0.0", "jsonrpc-server-utils", @@ -3503,7 +3502,7 @@ version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-server-utils", "log", @@ -3544,7 +3543,7 @@ version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "lazy_static", "log", @@ -3560,7 +3559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4" dependencies = [ "bytes 1.1.0", - "futures 0.3.19", + "futures 0.3.21", "globset", "jsonrpc-core 18.0.0", "lazy_static", @@ -3577,7 +3576,7 @@ version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f892c7d766369475ab7b0669f417906302d7c0fb521285c0a0c92e52e7c8e946" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-server-utils", "log", @@ -3650,7 +3649,7 @@ dependencies = [ "arrayvec 0.7.2", "async-trait", "fnv", - "futures 0.3.19", + "futures 0.3.21", "http", "jsonrpsee-types", "log", @@ -3683,8 +3682,8 @@ dependencies = [ [[package]] name = "kusama-runtime" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -3697,6 +3696,7 @@ dependencies = [ "frame-system-rpc-runtime-api", "frame-try-runtime", "hex-literal", + "kusama-runtime-constants", "log", "pallet-authority-discovery", "pallet-authorship", @@ -3719,6 +3719,7 @@ dependencies = [ "pallet-nicks", "pallet-offences", "pallet-offences-benchmarking", + "pallet-preimage", "pallet-proxy", "pallet-recovery", "pallet-scheduler", @@ -3749,15 +3750,15 @@ dependencies = [ "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-transaction-pool", "sp-version", "static_assertions", @@ -3767,6 +3768,18 @@ dependencies = [ "xcm-executor", ] +[[package]] +name = "kusama-runtime-constants" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec 1.8.0", + "sp-runtime", +] + [[package]] name = "kv-log-macro" version = "1.0.7" @@ -3829,9 +3842,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0005d08a8f7b65fb8073cb697aa0b12b631ed251ce73d862ce50eeb52ce3b50" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "libloading" @@ -3855,9 +3868,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" [[package]] name = "libp2p" @@ -3867,7 +3880,7 @@ checksum = "3bec54343492ba5940a6c555e512c6721139835d28c59bc22febece72dfd0d9d" dependencies = [ "atomic", "bytes 1.1.0", - "futures 0.3.19", + "futures 0.3.21", "lazy_static", "libp2p-core", "libp2p-deflate", @@ -3902,17 +3915,18 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.30.0" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef22d9bba1e8bcb7ec300073e6802943fe8abb8190431842262b5f1c30abba1" +checksum = "86aad7d54df283db817becded03e611137698a6509d4237a96881976a162340c" dependencies = [ "asn1_der", "bs58", "ed25519-dalek", "either", "fnv", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", + "instant", "lazy_static", "libsecp256k1 0.7.0", "log", @@ -3941,7 +3955,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51a800adb195f33de63f4b17b63fe64cfc23bf2c6a0d3d0d5321328664e65197" dependencies = [ "flate2", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", ] @@ -3952,7 +3966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb8f89d15cb6e3c5bc22afff7513b11bab7856f2872d3cfba86f7f63a06bc498" dependencies = [ "async-std-resolver", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "log", "smallvec 1.8.0", @@ -3967,7 +3981,7 @@ checksum = "aab3d7210901ea51b7bae2b581aa34521797af8c4ec738c980bda4a06434067f" dependencies = [ "cuckoofilter", "fnv", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "libp2p-swarm", "log", @@ -3988,7 +4002,7 @@ dependencies = [ "byteorder", "bytes 1.1.0", "fnv", - "futures 0.3.19", + "futures 0.3.21", "hex_fmt", "libp2p-core", "libp2p-swarm", @@ -4009,7 +4023,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cca1275574183f288ff8b72d535d5ffa5ea9292ef7829af8b47dcb197c7b0dcd" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "libp2p-swarm", "log", @@ -4031,7 +4045,7 @@ dependencies = [ "bytes 1.1.0", "either", "fnv", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "libp2p-swarm", "log", @@ -4055,7 +4069,7 @@ dependencies = [ "async-io", "data-encoding", "dns-parser", - "futures 0.3.19", + "futures 0.3.21", "if-watch", "lazy_static", "libp2p-core", @@ -4063,7 +4077,7 @@ dependencies = [ "log", "rand 0.8.4", "smallvec 1.8.0", - "socket2 0.4.3", + "socket2 0.4.4", "void", ] @@ -4089,7 +4103,7 @@ checksum = "7f2cd64ef597f40e14bfce0497f50ecb63dd6d201c61796daeb4227078834fbf" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.1.0", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "log", "nohash-hasher", @@ -4107,7 +4121,7 @@ checksum = "a8772c7a99088221bb7ca9c5c0574bf55046a7ab4c319f3619b275f28c8fb87a" dependencies = [ "bytes 1.1.0", "curve25519-dalek 3.2.0", - "futures 0.3.19", + "futures 0.3.21", "lazy_static", "libp2p-core", "log", @@ -4127,7 +4141,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80ef7b0ec5cf06530d9eb6cf59ae49d46a2c45663bde31c25a12f682664adbcf" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "libp2p-swarm", "log", @@ -4144,7 +4158,7 @@ checksum = "5fba1a6ff33e4a274c89a3b1d78b9f34f32af13265cc5c46c16938262d4e945a" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.1.0", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "log", "prost", @@ -4159,7 +4173,7 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f1a458bbda880107b5b36fcb9b5a1ef0c329685da0e203ed692a8ebe64cc92c" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "log", "pin-project 1.0.10", "rand 0.7.3", @@ -4175,8 +4189,8 @@ checksum = "2852b61c90fa8ce3c8fcc2aba76e6cefc20d648f9df29157d6b3a916278ef3e3" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.1.0", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "libp2p-core", "libp2p-swarm", "log", @@ -4198,7 +4212,7 @@ checksum = "14a6d2b9e7677eff61dc3d2854876aaf3976d84a01ef6664b610c77a0c9407c5" dependencies = [ "asynchronous-codec 0.6.0", "bimap", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "libp2p-swarm", "log", @@ -4220,7 +4234,7 @@ checksum = "a877a4ced6d46bf84677e1974e8cf61fb434af73b2e96fb48d6cb6223a4634d8" dependencies = [ "async-trait", "bytes 1.1.0", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "libp2p-swarm", "log", @@ -4238,7 +4252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f5184a508f223bc100a12665517773fb8730e9f36fc09eefb670bf01b107ae9" dependencies = [ "either", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "log", "rand 0.7.3", @@ -4264,14 +4278,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7399c5b6361ef525d41c11fcf51635724f832baf5819b30d3d873eabb4fbae4b" dependencies = [ "async-io", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "if-watch", "ipnet", "libc", "libp2p-core", "log", - "socket2 0.4.3", + "socket2 0.4.4", ] [[package]] @@ -4281,7 +4295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8b7563e46218165dfd60f64b96f7ce84590d75f53ecbdc74a7dd01450dc5973" dependencies = [ "async-std", - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "log", ] @@ -4292,7 +4306,7 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1008a302b73c5020251f9708c653f5ed08368e530e247cc9cd2f109ff30042cf" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "js-sys", "libp2p-core", "parity-send-wrapper", @@ -4307,7 +4321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22e12df82d1ed64969371a9e65ea92b91064658604cc2576c2757f18ead9a1cf" dependencies = [ "either", - "futures 0.3.19", + "futures 0.3.21", "futures-rustls", "libp2p-core", "log", @@ -4324,7 +4338,7 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e7362abb8867d7187e7e93df17f460d554c997fc5c8ac57dc1259057f6889af" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "libp2p-core", "parking_lot 0.11.2", "thiserror", @@ -4359,7 +4373,7 @@ dependencies = [ "rand 0.7.3", "serde", "sha2 0.9.9", - "typenum 1.15.0", + "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4378,7 +4392,7 @@ dependencies = [ "rand 0.8.4", "serde", "sha2 0.9.9", - "typenum 1.15.0", + "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4477,9 +4491,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.0.28" +version = "0.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "687387ff42ec7ea4f2149035a5675fedb675d26f98db90a1846ac63d3addb5f5" +checksum = "a261afc61b7a5e323933b402ca6a1765183687c614789b1e4db7762ed4230bca" [[package]] name = "lock_api" @@ -4492,9 +4506,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" dependencies = [ "scopeguard", ] @@ -4624,9 +4638,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3179b85e1fd8b14447cbebadb75e45a1002f541b925f0bfec366d56a81c56d" +checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f" dependencies = [ "libc", ] @@ -4651,6 +4665,17 @@ dependencies = [ "parity-util-mem", ] +[[package]] +name = "memory-db" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d505169b746dacf02f7d14d8c80b34edfd8212159c63d23c977739a0d960c626" +dependencies = [ + "hash-db", + "hashbrown 0.11.2", + "parity-util-mem", +] + [[package]] name = "memory-lru" version = "0.1.0" @@ -4680,12 +4705,12 @@ dependencies = [ [[package]] name = "metered-channel" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "thiserror", "tracing", ] @@ -4696,7 +4721,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd2c2cc134e57461f0898b0e921f0a7819b5e3f3a4335b9aa390ce81a5f36fb9" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "rand 0.8.4", "thrift", ] @@ -4802,10 +4827,10 @@ dependencies = [ "primitives", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -4984,7 +5009,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56a336acba8bc87c8876f6425407dbbe6c417bf478b22015f8fb0994ef3bc0ab" dependencies = [ "bytes 1.1.0", - "futures 0.3.19", + "futures 0.3.21", "log", "pin-project 1.0.10", "smallvec 1.8.0", @@ -5012,7 +5037,7 @@ dependencies = [ "move-vm-types", "parity-scale-codec", "parity-scale-codec-derive", - "sp-io 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-io 4.0.0-dev", "stdlib", ] @@ -5031,7 +5056,7 @@ dependencies = [ "rand 0.8.4", "rand_distr", "simba", - "typenum 1.15.0", + "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5067,14 +5092,15 @@ dependencies = [ [[package]] name = "nimbus-consensus" -version = "0.1.0" -source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.13#e4b6e1aa61ba83ba1909f901a1936916840b6774" +version = "0.9.0" +source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.16#fe112c616306445bfe408865a629f27ad5980b9e" dependencies = [ "async-trait", "cumulus-client-consensus-common", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", - "futures 0.3.19", + "cumulus-relay-chain-interface", + "futures 0.3.21", "log", "nimbus-primitives", "parity-scale-codec", @@ -5082,24 +5108,24 @@ dependencies = [ "polkadot-client", "sc-client-api", "sc-consensus", + "sc-consensus-manual-seal", "sp-api", "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", "substrate-prometheus-endpoint", "tracing", ] [[package]] name = "nimbus-primitives" -version = "0.1.0" -source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.13#e4b6e1aa61ba83ba1909f901a1936916840b6774" +version = "0.9.0" +source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.16#fe112c616306445bfe408865a629f27ad5980b9e" dependencies = [ "async-trait", "frame-support", @@ -5110,7 +5136,7 @@ dependencies = [ "sp-application-crypto", "sp-inherents", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -5288,7 +5314,7 @@ dependencies = [ [[package]] name = "orml-currencies" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "frame-support", "frame-system", @@ -5296,15 +5322,15 @@ dependencies = [ "orml-utilities", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "orml-tokens" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "frame-support", "frame-system", @@ -5313,13 +5339,13 @@ dependencies = [ "scale-info", "serde", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "orml-traits" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -5328,64 +5354,64 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", ] [[package]] name = "orml-unknown-tokens" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "frame-support", "frame-system", "orml-xcm-support", "parity-scale-codec", "scale-info", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", ] [[package]] name = "orml-utilities" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "frame-support", "parity-scale-codec", "scale-info", "serde", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "orml-xcm" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "frame-support", "frame-system", "pallet-xcm", "parity-scale-codec", "scale-info", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", ] [[package]] name = "orml-xcm-support" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "frame-support", "orml-traits", "parity-scale-codec", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] @@ -5393,7 +5419,7 @@ dependencies = [ [[package]] name = "orml-xtokens" version = "0.4.1-dev" -source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5#88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=213f743af2d6d2c94f235613d7e7ff21b093297c#213f743af2d6d2c94f235613d7e7ff21b093297c" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -5403,9 +5429,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] @@ -5421,8 +5447,8 @@ dependencies = [ [[package]] name = "pallet-author-inherent" -version = "0.1.0" -source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.13#e4b6e1aa61ba83ba1909f901a1936916840b6774" +version = "0.9.0" +source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.16#fe112c616306445bfe408865a629f27ad5980b9e" dependencies = [ "frame-support", "frame-system", @@ -5435,12 +5461,12 @@ dependencies = [ "sp-authorship", "sp-inherents", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-author-mapping" -version = "2.0.4" +version = "2.0.5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5451,16 +5477,16 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-author-slot-filter" -version = "0.1.0" -source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.13#e4b6e1aa61ba83ba1909f901a1936916840b6774" +version = "0.9.0" +source = "git+https://github.com/pontem-network/nimbus?branch=polkadot-v0.9.16#fe112c616306445bfe408865a629f27ad5980b9e" dependencies = [ "frame-support", "frame-system", @@ -5469,15 +5495,15 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -5487,13 +5513,13 @@ dependencies = [ "sp-application-crypto", "sp-authority-discovery", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -5502,13 +5528,13 @@ dependencies = [ "scale-info", "sp-authorship", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-babe" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5522,17 +5548,17 @@ dependencies = [ "sp-application-crypto", "sp-consensus-babe", "sp-consensus-vrf", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-bags-list" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5542,17 +5568,17 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-tracing 4.0.0", ] [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5561,13 +5587,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-beefy" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-primitives", "frame-support", @@ -5577,13 +5603,13 @@ dependencies = [ "scale-info", "serde", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-beefy-mmr" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-merkle-tree", "beefy-primitives", @@ -5599,16 +5625,16 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-bounties" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5617,16 +5643,16 @@ dependencies = [ "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-bridge-dispatch" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-runtime", @@ -5635,15 +5661,15 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "bp-runtime", @@ -5658,19 +5684,18 @@ dependencies = [ "serde", "sp-finality-grandpa", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-trie 4.0.0", ] [[package]] name = "pallet-bridge-messages" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-message-dispatch", "bp-messages", - "bp-rialto", "bp-runtime", "frame-support", "frame-system", @@ -5679,15 +5704,15 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-collective" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5695,16 +5720,16 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-democracy" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5712,15 +5737,15 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5731,20 +5756,20 @@ dependencies = [ "rand 0.7.3", "scale-info", "sp-arithmetic", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-npos-elections", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "static_assertions", - "strum", - "strum_macros", + "strum 0.22.0", + "strum_macros 0.23.1", ] [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5752,17 +5777,17 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-npos-elections", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-gilt" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5771,13 +5796,13 @@ dependencies = [ "scale-info", "sp-arithmetic", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5788,19 +5813,19 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-application-crypto", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-finality-grandpa", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-identity" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5808,15 +5833,15 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-im-online" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5826,34 +5851,34 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-application-crypto", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-indices" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-keyring", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-membership" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5861,16 +5886,16 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-mmr" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ckb-merkle-mountain-range", "frame-benchmarking", @@ -5879,16 +5904,16 @@ dependencies = [ "pallet-mmr-primitives", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-mmr-primitives" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -5896,15 +5921,15 @@ dependencies = [ "parity-scale-codec", "serde", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-mmr-rpc" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", @@ -5914,43 +5939,43 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", ] [[package]] name = "pallet-multisig" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-nicks" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-offences" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -5961,13 +5986,13 @@ dependencies = [ "serde", "sp-runtime", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5984,28 +6009,44 @@ dependencies = [ "scale-info", "sp-runtime", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", +] + +[[package]] +name = "pallet-preimage" +version = "4.0.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", + "sp-runtime", + "sp-std 4.0.0", ] [[package]] name = "pallet-proxy" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-randomness-collective-flip" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6013,27 +6054,27 @@ dependencies = [ "safe-mix", "scale-info", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-recovery" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6041,15 +6082,15 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6058,19 +6099,19 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-trie 4.0.0", ] [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6080,13 +6121,13 @@ dependencies = [ "rand 0.7.3", "sp-runtime", "sp-session", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-society" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6094,13 +6135,13 @@ dependencies = [ "rand_chacha 0.2.2", "scale-info", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-staking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6114,16 +6155,16 @@ dependencies = [ "scale-info", "serde", "sp-application-crypto", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-staking-reward-curve" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -6134,7 +6175,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "sp-arithmetic", @@ -6143,21 +6184,21 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6166,16 +6207,16 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-timestamp", ] [[package]] name = "pallet-tips" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6185,16 +6226,16 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6202,16 +6243,16 @@ dependencies = [ "scale-info", "serde", "smallvec 1.8.0", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", @@ -6220,7 +6261,7 @@ dependencies = [ "parity-scale-codec", "sp-api", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-rpc", "sp-runtime", ] @@ -6228,7 +6269,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -6239,7 +6280,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6250,29 +6291,29 @@ dependencies = [ "scale-info", "serde", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-vesting" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6281,13 +6322,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "pallet-xcm" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -6295,17 +6336,17 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] [[package]] name = "pallet-xcm-benchmarks" -version = "0.9.8" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -6314,7 +6355,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] @@ -6322,7 +6363,7 @@ dependencies = [ [[package]] name = "parachain-info" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.13#05cc5f0e2acacc18796f45ffa3c7b4626fd1046d" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -6346,18 +6387,18 @@ dependencies = [ "scale-info", "serde", "similar-asserts", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "substrate-fixed", ] [[package]] name = "parity-db" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a95abf24f1097c6e3181abbbbfc3630b3b5e681470940f719b69acb4911c7f" +checksum = "68de01cff53da5574397233383dd7f5c15ee958c348245765ea8cb09f2571e6b" dependencies = [ "blake2-rfc", "crc32fast", @@ -6410,7 +6451,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "libc", "log", "rand 0.7.3", @@ -6514,7 +6555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", - "lock_api 0.4.5", + "lock_api 0.4.6", "parking_lot_core 0.8.5", ] @@ -6738,10 +6779,10 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "polkadot-approval-distribution" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "polkadot-node-network-protocol", "polkadot-node-primitives", "polkadot-node-subsystem", @@ -6752,10 +6793,10 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "polkadot-node-network-protocol", "polkadot-node-subsystem", "polkadot-node-subsystem-util", @@ -6765,11 +6806,11 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", - "futures 0.3.19", + "futures 0.3.21", "lru 0.7.2", "parity-scale-codec", "polkadot-erasure-coding", @@ -6779,18 +6820,18 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-primitives", "rand 0.8.4", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "thiserror", "tracing", ] [[package]] name = "polkadot-availability-recovery" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "lru 0.7.2", "parity-scale-codec", "polkadot-erasure-coding", @@ -6807,18 +6848,21 @@ dependencies = [ [[package]] name = "polkadot-cli" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking-cli", - "futures 0.3.19", + "futures 0.3.21", "log", "polkadot-node-core-pvf", + "polkadot-node-metrics", + "polkadot-performance-test", "polkadot-service", "sc-cli", "sc-service", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sc-tracing", + "sp-core 4.1.0-dev", + "sp-trie 4.0.0", "structopt", "substrate-build-script-utils", "thiserror", @@ -6827,8 +6871,8 @@ dependencies = [ [[package]] name = "polkadot-client" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "frame-benchmarking", @@ -6852,27 +6896,27 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-storage 4.0.0", "sp-transaction-pool", "westend-runtime", ] [[package]] name = "polkadot-collator-protocol" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "derive_more", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "polkadot-node-network-protocol", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "sp-runtime", "thiserror", "tracing", @@ -6880,24 +6924,24 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "parity-util-mem", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "polkadot-dispute-distribution" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", - "futures 0.3.19", + "futures 0.3.21", "lru 0.7.2", "parity-scale-codec", "polkadot-erasure-coding", @@ -6908,32 +6952,32 @@ dependencies = [ "polkadot-primitives", "sc-network", "sp-application-crypto", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "thiserror", "tracing", ] [[package]] name = "polkadot-erasure-coding" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", "polkadot-primitives", "reed-solomon-novelpoly", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-trie 4.0.0", "thiserror", ] [[package]] name = "polkadot-gossip-support" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "polkadot-node-network-protocol", "polkadot-node-subsystem", "polkadot-node-subsystem-util", @@ -6942,18 +6986,18 @@ dependencies = [ "rand_chacha 0.3.1", "sc-network", "sp-application-crypto", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "tracing", ] [[package]] name = "polkadot-network-bridge" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", - "futures 0.3.19", + "futures 0.3.21", "parity-scale-codec", "parking_lot 0.11.2", "polkadot-node-network-protocol", @@ -6968,17 +7012,17 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "parity-scale-codec", "polkadot-erasure-coding", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-maybe-compressed-blob", "thiserror", "tracing", @@ -6986,13 +7030,13 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "derive_more", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "kvdb", "lru 0.7.2", "merlin", @@ -7014,12 +7058,12 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "kvdb", "parity-scale-codec", "polkadot-erasure-coding", @@ -7034,32 +7078,32 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", - "futures 0.3.19", + "futures 0.3.21", "polkadot-erasure-coding", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", "polkadot-statement-table", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "thiserror", "tracing", ] [[package]] name = "polkadot-node-core-bitfield-signing" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "thiserror", "tracing", "wasm-timer", @@ -7067,11 +7111,11 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", - "futures 0.3.19", + "futures 0.3.21", "parity-scale-codec", "polkadot-node-core-pvf", "polkadot-node-primitives", @@ -7085,10 +7129,10 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", @@ -7100,11 +7144,11 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "kvdb", "parity-scale-codec", "polkadot-node-primitives", @@ -7117,13 +7161,12 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "bitvec", - "derive_more", - "futures 0.3.19", + "futures 0.3.21", "kvdb", + "lru 0.7.2", "parity-scale-codec", "polkadot-node-primitives", "polkadot-node-subsystem", @@ -7134,27 +7177,14 @@ dependencies = [ "tracing", ] -[[package]] -name = "polkadot-node-core-dispute-participation" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" -dependencies = [ - "futures 0.3.19", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-primitives", - "thiserror", - "tracing", -] - [[package]] name = "polkadot-node-core-parachains-inherent" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "polkadot-node-subsystem", "polkadot-primitives", "sp-blockchain", @@ -7166,31 +7196,32 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", + "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", + "rand 0.8.4", "thiserror", "tracing", ] [[package]] name = "polkadot-node-core-pvf" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "assert_matches", "async-process", "async-std", - "futures 0.3.19", - "futures-timer 3.0.2", - "libc", + "futures 0.3.21", + "futures-timer", "parity-scale-codec", "pin-project 1.0.10", "polkadot-core-primitives", @@ -7201,21 +7232,37 @@ dependencies = [ "sc-executor-common", "sc-executor-wasmtime", "slotmap", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", + "sp-io 4.0.0", "sp-maybe-compressed-blob", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-tracing 4.0.0", + "sp-wasm-interface 4.1.0-dev", + "tracing", +] + +[[package]] +name = "polkadot-node-core-pvf-checker" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +dependencies = [ + "futures 0.3.21", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-node-subsystem-util", + "polkadot-overseer", + "polkadot-primitives", + "sp-keystore 0.10.0", + "thiserror", "tracing", ] [[package]] name = "polkadot-node-core-runtime-api" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "memory-lru", "parity-util-mem", "polkadot-node-subsystem", @@ -7224,14 +7271,14 @@ dependencies = [ "sp-api", "sp-authority-discovery", "sp-consensus-babe", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "tracing", ] [[package]] name = "polkadot-node-jaeger" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-std", "lazy_static", @@ -7242,46 +7289,54 @@ dependencies = [ "polkadot-node-primitives", "polkadot-primitives", "sc-network", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "thiserror", ] [[package]] name = "polkadot-node-metrics" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", - "futures-timer 3.0.2", + "bs58", + "futures 0.3.21", + "futures-timer", + "log", "metered-channel", + "parity-scale-codec", + "polkadot-primitives", + "sc-cli", + "sc-service", + "sc-tracing", "substrate-prometheus-endpoint", + "tracing", ] [[package]] name = "polkadot-node-network-protocol" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", - "futures 0.3.19", + "futures 0.3.21", "parity-scale-codec", "polkadot-node-jaeger", "polkadot-node-primitives", "polkadot-primitives", "sc-authority-discovery", "sc-network", - "strum", + "strum 0.23.0", "thiserror", ] [[package]] name = "polkadot-node-primitives" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bounded-vec", - "futures 0.3.19", + "futures 0.3.21", "parity-scale-codec", "polkadot-parachain", "polkadot-primitives", @@ -7290,8 +7345,8 @@ dependencies = [ "sp-application-crypto", "sp-consensus-babe", "sp-consensus-vrf", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "sp-maybe-compressed-blob", "thiserror", "zstd", @@ -7299,8 +7354,8 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "polkadot-node-jaeger", "polkadot-node-subsystem-types", @@ -7309,11 +7364,11 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", - "futures 0.3.19", + "futures 0.3.21", "polkadot-node-jaeger", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -7328,12 +7383,12 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", - "futures 0.3.19", + "futures 0.3.21", "itertools", "lru 0.7.2", "metered-channel", @@ -7342,24 +7397,25 @@ dependencies = [ "polkadot-node-jaeger", "polkadot-node-metrics", "polkadot-node-network-protocol", + "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-overseer", "polkadot-primitives", "rand 0.8.4", "sp-application-crypto", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "thiserror", "tracing", ] [[package]] name = "polkadot-overseer" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "lru 0.7.2", "parity-util-mem", "parking_lot 0.11.2", @@ -7376,12 +7432,12 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "metered-channel", "pin-project 1.0.10", "polkadot-node-network-protocol", @@ -7393,8 +7449,8 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen-proc-macro" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -7404,8 +7460,8 @@ dependencies = [ [[package]] name = "polkadot-parachain" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "frame-support", @@ -7414,15 +7470,30 @@ dependencies = [ "polkadot-core-primitives", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", +] + +[[package]] +name = "polkadot-performance-test" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +dependencies = [ + "env_logger", + "kusama-runtime", + "log", + "polkadot-erasure-coding", + "polkadot-node-core-pvf", + "polkadot-node-primitives", + "quote", + "thiserror", ] [[package]] name = "polkadot-primitives" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "frame-system", @@ -7438,21 +7509,21 @@ dependencies = [ "sp-arithmetic", "sp-authority-discovery", "sp-consensus-slots", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", + "sp-keystore 0.10.0", "sp-runtime", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-trie 4.0.0", "sp-version", ] [[package]] name = "polkadot-rpc" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-gadget", "beefy-gadget-rpc", @@ -7475,15 +7546,15 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-runtime", "substrate-frame-rpc-system", ] [[package]] name = "polkadot-runtime" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7517,6 +7588,7 @@ dependencies = [ "pallet-nicks", "pallet-offences", "pallet-offences-benchmarking", + "pallet-preimage", "pallet-proxy", "pallet-scheduler", "pallet-session", @@ -7534,6 +7606,7 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "polkadot-runtime-common", + "polkadot-runtime-constants", "polkadot-runtime-parachains", "rustc-hex", "scale-info", @@ -7544,15 +7617,15 @@ dependencies = [ "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-transaction-pool", "sp-version", "static_assertions", @@ -7564,8 +7637,8 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7597,22 +7670,46 @@ dependencies = [ "serde_derive", "slot-range-helper", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-npos-elections", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "static_assertions", "xcm", ] +[[package]] +name = "polkadot-runtime-constants" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec 1.8.0", + "sp-runtime", +] + +[[package]] +name = "polkadot-runtime-metrics" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +dependencies = [ + "bs58", + "parity-scale-codec", + "polkadot-primitives", + "sp-std 4.0.0", + "sp-tracing 4.0.0", +] + [[package]] name = "polkadot-runtime-parachains" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitflags", "bitvec", @@ -7631,36 +7728,38 @@ dependencies = [ "pallet-vesting", "parity-scale-codec", "polkadot-primitives", + "polkadot-runtime-metrics", "rand 0.8.4", "rand_chacha 0.3.1", "rustc-hex", "scale-info", "serde", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", + "sp-keystore 0.10.0", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] [[package]] name = "polkadot-service" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "beefy-gadget", "beefy-primitives", "frame-system-rpc-runtime-api", - "futures 0.3.19", + "futures 0.3.21", "hex-literal", "kusama-runtime", + "kusama-runtime-constants", "kvdb", "kvdb-rocksdb", "lru 0.7.2", @@ -7687,9 +7786,9 @@ dependencies = [ "polkadot-node-core-chain-api", "polkadot-node-core-chain-selection", "polkadot-node-core-dispute-coordinator", - "polkadot-node-core-dispute-participation", "polkadot-node-core-parachains-inherent", "polkadot-node-core-provisioner", + "polkadot-node-core-pvf-checker", "polkadot-node-core-runtime-api", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -7700,6 +7799,7 @@ dependencies = [ "polkadot-primitives", "polkadot-rpc", "polkadot-runtime", + "polkadot-runtime-constants", "polkadot-runtime-parachains", "polkadot-statement-distribution", "rococo-runtime", @@ -7729,33 +7829,34 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-finality-grandpa", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", + "sp-keystore 0.10.0", "sp-offchain", "sp-runtime", "sp-session", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-storage 4.0.0", "sp-timestamp", "sp-transaction-pool", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-trie 4.0.0", "substrate-prometheus-endpoint", "thiserror", "tracing", "westend-runtime", + "westend-runtime-constants", ] [[package]] name = "polkadot-statement-distribution" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "arrayvec 0.5.2", "derive_more", - "futures 0.3.19", + "futures 0.3.21", "indexmap 1.8.0", "parity-scale-codec", "polkadot-node-network-protocol", @@ -7763,7 +7864,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-staking", "thiserror", "tracing", @@ -7771,12 +7872,12 @@ dependencies = [ [[package]] name = "polkadot-statement-table" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-primitives", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", ] [[package]] @@ -7830,7 +7931,7 @@ dependencies = [ "cumulus-primitives-parachain-inherent", "frame-benchmarking", "frame-benchmarking-cli", - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "log", "mvm", @@ -7867,10 +7968,10 @@ dependencies = [ "sp-block-builder", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-finality-grandpa", "sp-inherents", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-mvm-rpc", "sp-mvm-rpc-runtime", "sp-offchain", @@ -7898,7 +7999,7 @@ dependencies = [ "cumulus-primitives-core", "cumulus-primitives-timestamp", "cumulus-primitives-utility", - "env_logger 0.9.0", + "env_logger", "frame-benchmarking", "frame-executive", "frame-support", @@ -7944,15 +8045,15 @@ dependencies = [ "smallvec 1.8.0", "sp-api", "sp-block-builder", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-mvm", "sp-mvm-rpc-runtime", "sp-offchain", "sp-runtime", "sp-session", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", @@ -8004,9 +8105,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -8137,17 +8238,6 @@ dependencies = [ "cc", ] -[[package]] -name = "pwasm-utils" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "880b3384fb00b8f6ecccd5d358b93bd2201900ae3daad213791d1864f6441f5c" -dependencies = [ - "byteorder", - "log", - "parity-wasm 0.42.2", -] - [[package]] name = "quick-error" version = "1.2.3" @@ -8378,9 +8468,9 @@ dependencies = [ [[package]] name = "regalloc" -version = "0.0.32" +version = "0.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6304468554ed921da3d32c355ea107b8d13d7b8996c3adfb7aab48d3bc321f4" +checksum = "7d808cff91dfca7b239d40b972ba628add94892b1d9e19a842aedc5cfae8ab1a" dependencies = [ "log", "rustc-hash", @@ -8428,16 +8518,16 @@ dependencies = [ [[package]] name = "remote-externalities" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "env_logger 0.9.0", + "env_logger", "jsonrpsee", "log", "parity-scale-codec", "serde", "serde_json", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", "sp-version", ] @@ -8463,9 +8553,9 @@ dependencies = [ [[package]] name = "retain_mut" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11000e6ba5020e53e7cc26f73b91ae7d5496b4977851479edb66b694c0675c21" +checksum = "51dd4445360338dab5116712bee1388dc727991d51969558a8882ab552e6db30" [[package]] name = "ring" @@ -8504,8 +8594,8 @@ dependencies = [ [[package]] name = "rococo-runtime" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bp-messages", @@ -8552,6 +8642,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-parachains", + "rococo-runtime-constants", "scale-info", "serde", "serde_derive", @@ -8560,14 +8651,14 @@ dependencies = [ "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-offchain", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", @@ -8577,30 +8668,25 @@ dependencies = [ ] [[package]] -name = "rpassword" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" +name = "rococo-runtime-constants" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "libc", - "winapi 0.3.9", + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec 1.8.0", + "sp-runtime", ] [[package]] -name = "rsix" -version = "0.23.9" +name = "rpassword" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f64c5788d5aab8b75441499d99576a24eb09f76fb267b36fec7e3d970c66431" +checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" dependencies = [ - "bitflags", - "cc", - "errno", - "io-lifetimes", - "itoa 0.4.8", "libc", - "linux-raw-sys", - "once_cell", - "rustc_version 0.4.0", + "winapi 0.3.9", ] [[package]] @@ -8645,7 +8731,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.4", + "semver 1.0.5", +] + +[[package]] +name = "rustix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2dcfc2778a90e38f56a708bfc90572422e11d6c7ee233d053d1f782cf9df6d2" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "winapi 0.3.9", ] [[package]] @@ -8673,13 +8773,19 @@ dependencies = [ "security-framework", ] +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + [[package]] name = "rw-stream-sink" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "pin-project 0.4.29", "static_assertions", ] @@ -8720,23 +8826,23 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-wasm-interface 4.1.0-dev", "thiserror", ] [[package]] name = "sc-authority-discovery" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "ip_network", "libp2p", "log", @@ -8749,8 +8855,8 @@ dependencies = [ "sp-api", "sp-authority-discovery", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "sp-runtime", "substrate-prometheus-endpoint", ] @@ -8758,10 +8864,10 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "log", "parity-scale-codec", "sc-block-builder", @@ -8772,7 +8878,7 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", "sp-runtime", "substrate-prometheus-endpoint", @@ -8781,40 +8887,40 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "sc-client-api", "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", ] [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-trait-for-tuples", - "memmap2 0.5.2", + "memmap2 0.5.3", "parity-scale-codec", "sc-chain-spec-derive", "sc-network", "sc-telemetry", "serde", "serde_json", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", ] [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -8825,11 +8931,11 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "chrono", "fdlimit", - "futures 0.3.19", + "futures 0.3.21", "hex", "libp2p", "log", @@ -8848,10 +8954,10 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-keyring", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-panic-handler 4.0.0-dev", + "sp-keystore 0.10.0", + "sp-panic-handler 4.0.0", "sp-runtime", "sp-version", "structopt", @@ -8863,10 +8969,10 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "fnv", - "futures 0.3.19", + "futures 0.3.21", "hash-db", "log", "parity-scale-codec", @@ -8877,21 +8983,21 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-database", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-externalities 0.10.0", + "sp-keystore 0.10.0", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-storage 4.0.0", + "sp-trie 4.0.0", "substrate-prometheus-endpoint", ] [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", "kvdb", @@ -8906,21 +9012,21 @@ dependencies = [ "sc-state-db", "sp-arithmetic", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-database", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-trie 4.0.0", ] [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "libp2p", "log", "parking_lot 0.11.2", @@ -8930,22 +9036,51 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", "substrate-prometheus-endpoint", "thiserror", ] +[[package]] +name = "sc-consensus-aura" +version = "0.10.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +dependencies = [ + "async-trait", + "derive_more", + "futures 0.3.21", + "log", + "parity-scale-codec", + "sc-block-builder", + "sc-client-api", + "sc-consensus", + "sc-consensus-slots", + "sc-telemetry", + "sp-api", + "sp-application-crypto", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-aura", + "sp-consensus-slots", + "sp-core 4.1.0-dev", + "sp-inherents", + "sp-keystore 0.10.0", + "sp-runtime", + "substrate-prometheus-endpoint", +] + [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", "fork-tree", - "futures 0.3.19", + "futures 0.3.21", "log", "merlin", "num-bigint", @@ -8971,10 +9106,10 @@ dependencies = [ "sp-consensus-babe", "sp-consensus-slots", "sp-consensus-vrf", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", + "sp-keystore 0.10.0", "sp-runtime", "sp-version", "substrate-prometheus-endpoint", @@ -8983,10 +9118,10 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", "jsonrpc-derive 18.0.0", @@ -8999,15 +9134,15 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "sp-runtime", ] [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "fork-tree", "parity-scale-codec", @@ -9020,12 +9155,12 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "assert_matches", "async-trait", "derive_more", - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", "jsonrpc-derive 18.0.0", @@ -9033,6 +9168,7 @@ dependencies = [ "parity-scale-codec", "sc-client-api", "sc-consensus", + "sc-consensus-aura", "sc-consensus-babe", "sc-consensus-epochs", "sc-transaction-pool", @@ -9041,11 +9177,12 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", + "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-slots", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-runtime", "sp-timestamp", "substrate-prometheus-endpoint", @@ -9054,25 +9191,24 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "log", "parity-scale-codec", "sc-client-api", "sc-consensus", "sc-telemetry", - "sp-api", "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", "sp-timestamp", "thiserror", ] @@ -9080,7 +9216,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "sc-client-api", "sp-authorship", @@ -9091,68 +9227,69 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "lazy_static", "libsecp256k1 0.7.0", "log", + "lru 0.6.6", "parity-scale-codec", "parking_lot 0.11.2", "sc-executor-common", "sc-executor-wasmi", "sc-executor-wasmtime", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-core-hashing-proc-macro", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-panic-handler 4.0.0-dev", - "sp-runtime-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-externalities 0.10.0", + "sp-io 4.0.0", + "sp-panic-handler 4.0.0", + "sp-runtime-interface 4.1.0-dev", "sp-tasks", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-trie 4.0.0", "sp-version", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-wasm-interface 4.1.0-dev", "wasmi", ] [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", "environmental", "parity-scale-codec", - "pwasm-utils", "sc-allocator", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-maybe-compressed-blob", "sp-serializer", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-wasm-interface 4.1.0-dev", "thiserror", + "wasm-instrument", "wasmi", ] [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "parity-scale-codec", "sc-allocator", "sc-executor-common", "scoped-tls", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-runtime-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-runtime-interface 4.1.0-dev", + "sp-wasm-interface 4.1.0-dev", "wasmi", ] [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "cfg-if 1.0.0", "libc", @@ -9161,29 +9298,30 @@ dependencies = [ "parity-wasm 0.42.2", "sc-allocator", "sc-executor-common", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-runtime-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-runtime-interface 4.1.0-dev", + "sp-wasm-interface 4.1.0-dev", "wasmtime", ] [[package]] name = "sc-finality-grandpa" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", "dyn-clone", "finality-grandpa", "fork-tree", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "log", "parity-scale-codec", "parking_lot 0.11.2", "rand 0.8.4", "sc-block-builder", + "sc-chain-spec", "sc-client-api", "sc-consensus", "sc-keystore", @@ -9197,9 +9335,9 @@ dependencies = [ "sp-arithmetic", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-finality-grandpa", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-runtime", "substrate-prometheus-endpoint", ] @@ -9207,11 +9345,11 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", "finality-grandpa", - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", "jsonrpc-derive 18.0.0", @@ -9224,18 +9362,18 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", ] [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ansi_term", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "log", "parity-util-mem", "sc-client-api", @@ -9248,7 +9386,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", @@ -9256,14 +9394,14 @@ dependencies = [ "parking_lot 0.11.2", "serde_json", "sp-application-crypto", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", ] [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-std", "async-trait", @@ -9275,8 +9413,8 @@ dependencies = [ "either", "fnv", "fork-tree", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "hex", "ip_network", "libp2p", @@ -9301,7 +9439,7 @@ dependencies = [ "sp-arithmetic", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-finality-grandpa", "sp-runtime", "substrate-prometheus-endpoint", @@ -9314,10 +9452,10 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "libp2p", "log", "lru 0.7.2", @@ -9330,12 +9468,12 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "bytes 1.1.0", "fnv", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "hex", "hyper", "hyper-rustls", @@ -9348,7 +9486,7 @@ dependencies = [ "sc-network", "sc-utils", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-offchain", "sp-runtime", "threadpool", @@ -9358,9 +9496,9 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "libp2p", "log", "sc-utils", @@ -9371,7 +9509,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -9380,9 +9518,9 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "hash-db", "jsonrpc-core 18.0.0", "jsonrpc-pubsub 18.0.0", @@ -9399,8 +9537,8 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "sp-offchain", "sp-rpc", "sp-runtime", @@ -9411,9 +9549,9 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", "jsonrpc-derive 18.0.0", @@ -9425,10 +9563,10 @@ dependencies = [ "sc-transaction-pool-api", "serde", "serde_json", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-rpc", "sp-runtime", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-tracing 4.0.0", "sp-version", "thiserror", ] @@ -9436,9 +9574,9 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-http-server", "jsonrpc-ipc-server", @@ -9453,13 +9591,13 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "directories", "exit-future", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "hash-db", "jsonrpc-core 18.0.0", "jsonrpc-pubsub 18.0.0", @@ -9493,18 +9631,18 @@ dependencies = [ "sp-block-builder", "sp-blockchain", "sp-consensus", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", "sp-inherents", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-runtime", "sp-session", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-storage 4.0.0", + "sp-tracing 4.0.0", "sp-transaction-pool", "sp-transaction-storage-proof", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-trie 4.0.0", "sp-version", "substrate-prometheus-endpoint", "tempfile", @@ -9517,7 +9655,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "parity-scale-codec", @@ -9525,13 +9663,13 @@ dependencies = [ "parity-util-mem-derive", "parking_lot 0.11.2", "sc-client-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", ] [[package]] name = "sc-sync-state-rpc" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", @@ -9553,10 +9691,10 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "chrono", - "futures 0.3.19", + "futures 0.3.21", "libp2p", "log", "parking_lot 0.11.2", @@ -9571,7 +9709,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ansi_term", "atty", @@ -9589,10 +9727,10 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-rpc", "sp-runtime", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-tracing 4.0.0", "thiserror", "tracing", "tracing-log", @@ -9602,7 +9740,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -9613,10 +9751,10 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", - "intervalier", + "futures 0.3.21", + "futures-timer", "linked-hash-map", "log", "parity-scale-codec", @@ -9629,9 +9767,9 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-tracing 4.0.0", "sp-transaction-pool", "substrate-prometheus-endpoint", "thiserror", @@ -9640,10 +9778,10 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", - "futures 0.3.19", + "futures 0.3.21", "log", "serde", "sp-blockchain", @@ -9654,11 +9792,12 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "lazy_static", + "parking_lot 0.11.2", "prometheus", ] @@ -9758,9 +9897,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d09d3c15d814eda1d6a836f2f2b56a6abc1446c8a34351cb3180d3db92ffe4ce" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" dependencies = [ "bitflags", "core-foundation", @@ -9771,9 +9910,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90dd10c41c6bfc633da6e0c659bd25d31e0791e5974ac42970267d59eba87f7" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" dependencies = [ "core-foundation-sys", "libc", @@ -9808,9 +9947,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" dependencies = [ "serde", ] @@ -9920,6 +10059,17 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures 0.2.1", + "digest 0.10.2", +] + [[package]] name = "sha3" version = "0.9.1" @@ -10021,14 +10171,14 @@ dependencies = [ [[package]] name = "slot-range-helper" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "enumn", "parity-scale-codec", "paste", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -10092,9 +10242,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f82496b90c36d70af5fcd482edaa2e0bd16fade569de1330405fecbbdac736b" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", "winapi 0.3.9", @@ -10109,7 +10259,7 @@ dependencies = [ "base64 0.13.0", "bytes 1.1.0", "flate2", - "futures 0.3.19", + "futures 0.3.21", "httparse", "log", "rand 0.8.4", @@ -10119,16 +10269,16 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", "log", "parity-scale-codec", "sp-api-proc-macro", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", "sp-version", "thiserror", ] @@ -10136,7 +10286,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "blake2-rfc", "proc-macro-crate 1.1.0", @@ -10147,75 +10297,75 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", + "sp-std 4.0.0", ] [[package]] name = "sp-arithmetic" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "integer-sqrt", "num-traits", "parity-scale-codec", "scale-info", "serde", - "sp-debug-derive 4.0.0-dev", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-debug-derive 4.0.0", + "sp-std 4.0.0", "static_assertions", ] [[package]] name = "sp-authority-discovery" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", "sp-api", "sp-application-crypto", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "sp-authorship" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "parity-scale-codec", "sp-inherents", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "sp-api", "sp-inherents", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "log", "lru 0.7.2", "parity-scale-codec", @@ -10224,33 +10374,51 @@ dependencies = [ "sp-consensus", "sp-database", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", "thiserror", ] [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", - "futures 0.3.19", - "futures-timer 3.0.2", + "futures 0.3.21", + "futures-timer", "log", "parity-scale-codec", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", "sp-version", "thiserror", ] +[[package]] +name = "sp-consensus-aura" +version = "0.10.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +dependencies = [ + "async-trait", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-application-crypto", + "sp-consensus", + "sp-consensus-slots", + "sp-inherents", + "sp-runtime", + "sp-std 4.0.0", + "sp-timestamp", +] + [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "merlin", @@ -10262,18 +10430,18 @@ dependencies = [ "sp-consensus", "sp-consensus-slots", "sp-consensus-vrf", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-keystore 0.10.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-timestamp", ] [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -10285,13 +10453,13 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "schnorrkel", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -10304,7 +10472,7 @@ dependencies = [ "byteorder", "dyn-clonable", "ed25519-dalek", - "futures 0.3.19", + "futures 0.3.21", "hash-db", "hash256-std-hasher", "hex", @@ -10326,10 +10494,10 @@ dependencies = [ "serde", "sha2 0.9.9", "sp-debug-derive 3.0.0", - "sp-externalities 0.10.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-runtime-interface 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-storage 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-externalities 0.10.0-dev", + "sp-runtime-interface 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", "substrate-bip39", "thiserror", "tiny-bip39", @@ -10341,8 +10509,8 @@ dependencies = [ [[package]] name = "sp-core" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.1.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "base58 0.2.0", "bitflags", @@ -10350,7 +10518,7 @@ dependencies = [ "byteorder", "dyn-clonable", "ed25519-dalek", - "futures 0.3.19", + "futures 0.3.21", "hash-db", "hash256-std-hasher", "hex", @@ -10370,13 +10538,13 @@ dependencies = [ "schnorrkel", "secrecy 0.8.0", "serde", - "sha2 0.9.9", + "sha2 0.10.1", "sp-core-hashing", - "sp-debug-derive 4.0.0-dev", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-runtime-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-debug-derive 4.0.0", + "sp-externalities 0.10.0", + "sp-runtime-interface 4.1.0-dev", + "sp-std 4.0.0", + "sp-storage 4.0.0", "ss58-registry", "substrate-bip39", "thiserror", @@ -10389,13 +10557,13 @@ dependencies = [ [[package]] name = "sp-core-hashing" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "blake2-rfc", "byteorder", - "sha2 0.9.9", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sha2 0.10.1", + "sp-std 4.0.0", "tiny-keccak", "twox-hash", ] @@ -10403,7 +10571,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro2", "quote", @@ -10414,7 +10582,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "kvdb", "parking_lot 0.11.2", @@ -10432,8 +10600,8 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro2", "quote", @@ -10447,25 +10615,25 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57 dependencies = [ "environmental", "parity-scale-codec", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-storage 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", ] [[package]] name = "sp-externalities" -version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "0.10.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "environmental", "parity-scale-codec", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-storage 4.0.0", ] [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "finality-grandpa", "log", @@ -10474,23 +10642,23 @@ dependencies = [ "serde", "sp-api", "sp-application-crypto", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-keystore 0.10.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "impl-trait-for-tuples", "parity-scale-codec", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "thiserror", ] @@ -10499,58 +10667,58 @@ name = "sp-io" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57346f6b24875f8935280dba51fa8ab0a9ba1e39" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "hash-db", "libsecp256k1 0.6.0", "log", "parity-scale-codec", "parking_lot 0.11.2", - "sp-core 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-externalities 0.10.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-keystore 0.10.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-runtime-interface 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-state-machine 0.10.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-tracing 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-trie 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-wasm-interface 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", + "sp-keystore 0.10.0-dev", + "sp-runtime-interface 4.0.0-dev", + "sp-state-machine 0.10.0-dev", + "sp-std 4.0.0-dev", + "sp-tracing 4.0.0-dev", + "sp-trie 4.0.0-dev", + "sp-wasm-interface 4.0.0-dev", "tracing", "tracing-core", ] [[package]] name = "sp-io" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "hash-db", "libsecp256k1 0.7.0", "log", "parity-scale-codec", "parking_lot 0.11.2", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-runtime-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", + "sp-keystore 0.10.0", + "sp-runtime-interface 4.1.0-dev", + "sp-state-machine 0.10.0", + "sp-std 4.0.0", + "sp-tracing 4.0.0", + "sp-trie 4.0.0", + "sp-wasm-interface 4.1.0-dev", "tracing", "tracing-core", ] [[package]] name = "sp-keyring" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.1.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "lazy_static", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", - "strum", + "strum 0.22.0", ] [[package]] @@ -10560,36 +10728,36 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57 dependencies = [ "async-trait", "derive_more", - "futures 0.3.19", + "futures 0.3.21", "merlin", "parity-scale-codec", "parking_lot 0.11.2", "schnorrkel", - "sp-core 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-externalities 0.10.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", ] [[package]] name = "sp-keystore" -version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "0.10.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", - "futures 0.3.19", + "futures 0.3.21", "merlin", "parity-scale-codec", "parking_lot 0.11.2", "schnorrkel", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", ] [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "zstd", ] @@ -10604,7 +10772,7 @@ dependencies = [ "bcs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "bcs 0.1.3 (git+https://github.com/pontem-network/sp-move-vm.git?rev=c8ac6f91c7ec95e62afa3ee9ef9884eec113511c)", "constants", - "env_logger 0.9.0", + "env_logger", "frame-benchmarking", "frame-support", "frame-system", @@ -10627,10 +10795,10 @@ dependencies = [ "primitives", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "test-log", ] @@ -10662,28 +10830,28 @@ dependencies = [ "sp-api", "sp-mvm", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "sp-npos-elections" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", "serde", "sp-arithmetic", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-npos-elections-solution-type", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "sp-npos-elections-solution-type" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -10694,10 +10862,10 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", ] @@ -10711,8 +10879,8 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "backtrace", "lazy_static", @@ -10722,17 +10890,17 @@ dependencies = [ [[package]] name = "sp-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "rustc-hash", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", ] [[package]] name = "sp-runtime" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.1.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "either", "hash256-std-hasher", @@ -10746,9 +10914,9 @@ dependencies = [ "serde", "sp-application-crypto", "sp-arithmetic", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", + "sp-std 4.0.0", ] [[package]] @@ -10759,29 +10927,29 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "primitive-types 0.10.1", - "sp-externalities 0.10.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-runtime-interface-proc-macro 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-storage 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-tracing 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-wasm-interface 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-externalities 0.10.0-dev", + "sp-runtime-interface-proc-macro 4.0.0-dev", + "sp-std 4.0.0-dev", + "sp-storage 4.0.0-dev", + "sp-tracing 4.0.0-dev", + "sp-wasm-interface 4.0.0-dev", "static_assertions", ] [[package]] name = "sp-runtime-interface" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.1.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "primitive-types 0.10.1", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-runtime-interface-proc-macro 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-storage 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-tracing 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-wasm-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-externalities 0.10.0", + "sp-runtime-interface-proc-macro 4.0.0", + "sp-std 4.0.0", + "sp-storage 4.0.0", + "sp-tracing 4.0.0", + "sp-wasm-interface 4.1.0-dev", "static_assertions", ] @@ -10799,8 +10967,8 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "Inflector", "proc-macro-crate 1.1.0", @@ -10812,7 +10980,7 @@ dependencies = [ [[package]] name = "sp-serializer" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "serde", "serde_json", @@ -10821,26 +10989,26 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -10855,21 +11023,21 @@ dependencies = [ "parking_lot 0.11.2", "rand 0.7.3", "smallvec 1.8.0", - "sp-core 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-externalities 0.10.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-core 4.0.0-dev", + "sp-externalities 0.10.0-dev", "sp-panic-handler 3.0.0", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-trie 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-std 4.0.0-dev", + "sp-trie 4.0.0-dev", "thiserror", "tracing", - "trie-db", - "trie-root", + "trie-db 0.22.6", + "trie-root 0.16.0", ] [[package]] name = "sp-state-machine" -version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "0.10.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", "log", @@ -10878,15 +11046,15 @@ dependencies = [ "parking_lot 0.11.2", "rand 0.7.3", "smallvec 1.8.0", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-panic-handler 4.0.0-dev", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", + "sp-panic-handler 4.0.0", + "sp-std 4.0.0", + "sp-trie 4.0.0", "thiserror", "tracing", - "trie-db", - "trie-root", + "trie-db 0.23.1", + "trie-root 0.17.0", ] [[package]] @@ -10896,8 +11064,8 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57 [[package]] name = "sp-std" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" [[package]] name = "sp-storage" @@ -10909,48 +11077,48 @@ dependencies = [ "ref-cast", "serde", "sp-debug-derive 3.0.0", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-std 4.0.0-dev", ] [[package]] name = "sp-storage" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 4.0.0-dev", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-debug-derive 4.0.0", + "sp-std 4.0.0", ] [[package]] name = "sp-tasks" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-runtime-interface 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", + "sp-io 4.0.0", + "sp-runtime-interface 4.1.0-dev", + "sp-std 4.0.0", ] [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", - "futures-timer 3.0.2", + "futures-timer", "log", "parity-scale-codec", "sp-api", "sp-inherents", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "thiserror", ] @@ -10966,7 +11134,7 @@ dependencies = [ "serde", "serde_json", "slog", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-std 4.0.0-dev", "tracing", "tracing-core", "tracing-subscriber", @@ -10974,11 +11142,11 @@ dependencies = [ [[package]] name = "sp-tracing" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "tracing", "tracing-core", "tracing-subscriber", @@ -10987,7 +11155,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "sp-api", "sp-runtime", @@ -10996,17 +11164,17 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "log", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-trie 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", + "sp-trie 4.0.0", ] [[package]] @@ -11015,42 +11183,43 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57346f6b24875f8935280dba51fa8ab0a9ba1e39" dependencies = [ "hash-db", - "memory-db", + "memory-db 0.27.0", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", - "trie-db", - "trie-root", + "sp-core 4.0.0-dev", + "sp-std 4.0.0-dev", + "trie-db 0.22.6", + "trie-root 0.16.0", ] [[package]] name = "sp-trie" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.0.0" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", - "memory-db", + "memory-db 0.28.0", "parity-scale-codec", "scale-info", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "trie-db", - "trie-root", + "sp-core 4.1.0-dev", + "sp-std 4.0.0", + "trie-db 0.23.1", + "trie-root 0.17.0", ] [[package]] name = "sp-version" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-serde", "parity-scale-codec", "parity-wasm 0.42.2", "scale-info", "serde", + "sp-core-hashing-proc-macro", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-version-proc-macro", "thiserror", ] @@ -11058,7 +11227,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -11073,19 +11242,21 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57 dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11)", + "sp-std 4.0.0-dev", "wasmi", ] [[package]] name = "sp-wasm-interface" -version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +version = "4.1.0-dev" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-trait-for-tuples", + "log", "parity-scale-codec", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "wasmi", + "wasmtime", ] [[package]] @@ -11206,7 +11377,16 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7ac893c7d471c8a21f31cfe213ec4f6d9afeed25537c772e08ef3f005f8729e" dependencies = [ - "strum_macros", + "strum_macros 0.22.0", +] + +[[package]] +name = "strum" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" +dependencies = [ + "strum_macros 0.23.1", ] [[package]] @@ -11221,6 +11401,19 @@ dependencies = [ "syn", ] +[[package]] +name = "strum_macros" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "substrate-bip39" version = "0.4.4" @@ -11237,28 +11430,28 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "platforms", ] [[package]] name = "substrate-fixed" -version = "0.5.7" -source = "git+https://github.com/encointer/substrate-fixed#2f353acee3c7cf7a386863a89fc6cb805048561f" +version = "0.5.8" +source = "git+https://github.com/encointer/substrate-fixed#5984ba9b9433d5007597c7f03f65ea5bf6d08601" dependencies = [ "parity-scale-codec", "scale-info", - "typenum 1.14.0", + "typenum 1.15.0 (git+https://github.com/encointer/typenum?tag=v1.15.0)", ] [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-system-rpc-runtime-api", - "futures 0.3.19", + "futures 0.3.21", "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", "jsonrpc-derive 18.0.0", @@ -11270,14 +11463,14 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-runtime", ] [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-std", "derive_more", @@ -11291,7 +11484,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ansi_term", "build-helper", @@ -11340,9 +11533,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff" +checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1" [[package]] name = "tempfile" @@ -11504,9 +11697,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.15.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" dependencies = [ "bytes 1.1.0", "libc", @@ -11585,9 +11778,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" dependencies = [ "cfg-if 1.0.0", "pin-project-lite 0.2.8", @@ -11597,9 +11790,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +checksum = "8276d9a4a3a558d7b7ad5303ad50b53d58264641b82914b7ada36bd762e7a716" dependencies = [ "proc-macro2", "quote", @@ -11608,11 +11801,12 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" dependencies = [ "lazy_static", + "valuable", ] [[package]] @@ -11638,9 +11832,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" dependencies = [ "serde", "tracing-core", @@ -11684,10 +11878,10 @@ dependencies = [ "primitives", "scale-info", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", ] [[package]] @@ -11703,6 +11897,19 @@ dependencies = [ "smallvec 1.8.0", ] +[[package]] +name = "trie-db" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32d034c0d3db64b43c31de38e945f15b40cd4ca6d2dcfc26d4798ce8de4ab83" +dependencies = [ + "hash-db", + "hashbrown 0.12.0", + "log", + "rustc-hex", + "smallvec 1.8.0", +] + [[package]] name = "trie-root" version = "0.16.0" @@ -11712,11 +11919,20 @@ dependencies = [ "hash-db", ] +[[package]] +name = "trie-root" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a36c5ca3911ed3c9a5416ee6c679042064b93fc637ded67e25f92e68d783891" +dependencies = [ + "hash-db", +] + [[package]] name = "trust-dns-proto" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0d7f5db438199a6e2609debe3f69f808d074e0a2888ee0bccb45fe234d03f4" +checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" dependencies = [ "async-trait", "cfg-if 1.0.0", @@ -11738,9 +11954,9 @@ dependencies = [ [[package]] name = "trust-dns-resolver" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ad17b608a64bd0735e67bde16b0636f8aa8591f831a25d18443ed00a699770" +checksum = "ecae383baad9995efaa34ce8e57d12c3f305e545887472a492b838f4b5cfb77a" dependencies = [ "cfg-if 1.0.0", "futures-util", @@ -11764,7 +11980,7 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13#afb74de23dfe2994e7ce38c0870efb9734e966f7" +source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpsee", "log", @@ -11775,14 +11991,15 @@ dependencies = [ "sc-executor", "sc-service", "serde", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-externalities 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-keystore 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-externalities 0.10.0", + "sp-io 4.0.0", + "sp-keystore 0.10.0", "sp-runtime", - "sp-state-machine 0.10.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-state-machine 0.10.0", "sp-version", "structopt", + "zstd", ] [[package]] @@ -11804,17 +12021,18 @@ dependencies = [ [[package]] name = "typenum" -version = "1.14.0" -source = "git+https://github.com/encointer/typenum#ec35bb80fcfb495de2e1f6966381c3f85e8a6509" -dependencies = [ - "scale-info", -] +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "typenum" version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +source = "git+https://github.com/encointer/typenum?tag=v1.15.0#14e21b6532ad2adf893fbe329b78deb7ae7dfad0" +dependencies = [ + "parity-scale-codec", + "scale-info", +] [[package]] name = "ucd-trie" @@ -11824,9 +12042,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "uint" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" dependencies = [ "byteorder", "crunchy", @@ -11860,9 +12078,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-width" @@ -11945,6 +12163,12 @@ dependencies = [ "percent-encoding 2.1.0", ] +[[package]] +name = "valuable" +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.8" @@ -12105,13 +12329,22 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "wasm-instrument" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "962e5b0401bbb6c887f54e69b8c496ea36f704df65db73e81fd5ff8dc3e63a9f" +dependencies = [ + "parity-wasm 0.42.2", +] + [[package]] name = "wasm-timer" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "js-sys", "parking_lot 0.11.2", "pin-utils", @@ -12152,9 +12385,9 @@ checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc" [[package]] name = "wasmtime" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311d06b0c49346d1fbf48a17052e844036b95a7753c1afb34e8c0af3f6b5bb13" +checksum = "414be1bc5ca12e755ffd3ff7acc3a6d1979922f8237fc34068b2156cebcc3270" dependencies = [ "anyhow", "backtrace", @@ -12184,9 +12417,9 @@ dependencies = [ [[package]] name = "wasmtime-cache" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147930a4995137dc096e5b17a573b446799be2bbaea433e821ce6a80abe2c5" +checksum = "8b9b4cd1949206fda9241faf8c460a7d797aa1692594d3dd6bc1cbfa57ee20d0" dependencies = [ "anyhow", "base64 0.13.0", @@ -12194,7 +12427,7 @@ dependencies = [ "directories-next", "file-per-thread-logger", "log", - "rsix", + "rustix", "serde", "sha2 0.9.9", "toml", @@ -12204,9 +12437,9 @@ dependencies = [ [[package]] name = "wasmtime-cranelift" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3083a47e1ede38aac06a1d9831640d673f9aeda0b82a64e4ce002f3432e2e7" +checksum = "a4693d33725773615a4c9957e4aa731af57b27dca579702d1d8ed5750760f1a9" dependencies = [ "anyhow", "cranelift-codegen", @@ -12214,7 +12447,7 @@ dependencies = [ "cranelift-frontend", "cranelift-native", "cranelift-wasm", - "gimli 0.25.0", + "gimli", "log", "more-asserts", "object", @@ -12226,14 +12459,13 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c2d194b655321053bc4111a1aa4ead552655c8a17d17264bc97766e70073510" +checksum = "5b17e47116a078b9770e6fb86cff8b9a660826623cebcfff251b047c8d8993ef" dependencies = [ "anyhow", - "cfg-if 1.0.0", "cranelift-entity", - "gimli 0.25.0", + "gimli", "indexmap 1.8.0", "log", "more-asserts", @@ -12247,24 +12479,21 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864ac8dfe4ce310ac59f16fdbd560c257389cb009ee5d030ac6e30523b023d11" +checksum = "60ea5b380bdf92e32911400375aeefb900ac9d3f8e350bb6ba555a39315f2ee7" dependencies = [ - "addr2line 0.16.0", + "addr2line", "anyhow", "bincode", "cfg-if 1.0.0", - "gimli 0.25.0", - "log", - "more-asserts", + "gimli", "object", "region", - "rsix", + "rustix", "serde", "target-lexicon", "thiserror", - "wasmparser", "wasmtime-environ", "wasmtime-runtime", "winapi 0.3.9", @@ -12272,9 +12501,9 @@ dependencies = [ [[package]] name = "wasmtime-runtime" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab97da813a26b98c9abfd3b0c2d99e42f6b78b749c0646344e2e262d212d8c8b" +checksum = "abc7cd79937edd6e238b337608ebbcaf9c086a8457f01dfd598324f7fa56d81a" dependencies = [ "anyhow", "backtrace", @@ -12289,7 +12518,7 @@ dependencies = [ "more-asserts", "rand 0.8.4", "region", - "rsix", + "rustix", "thiserror", "wasmtime-environ", "winapi 0.3.9", @@ -12297,9 +12526,9 @@ dependencies = [ [[package]] name = "wasmtime-types" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff94409cc3557bfbbcce6b14520ccd6bd3727e965c0fe68d63ef2c185bf379c6" +checksum = "d9e5e51a461a2cf2b69e1fc48f325b17d78a8582816e18479e8ead58844b23f8" dependencies = [ "cranelift-entity", "serde", @@ -12347,8 +12576,8 @@ dependencies = [ [[package]] name = "westend-runtime" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -12381,6 +12610,7 @@ dependencies = [ "pallet-nicks", "pallet-offences", "pallet-offences-benchmarking", + "pallet-preimage", "pallet-proxy", "pallet-recovery", "pallet-scheduler", @@ -12412,23 +12642,36 @@ dependencies = [ "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", "sp-inherents", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-session", "sp-staking", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", + "westend-runtime-constants", "xcm", "xcm-builder", "xcm-executor", ] +[[package]] +name = "westend-runtime-constants" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec 1.8.0", + "sp-runtime", +] + [[package]] name = "which" version = "4.2.4" @@ -12527,8 +12770,8 @@ dependencies = [ [[package]] name = "xcm" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derivative", "impl-trait-for-tuples", @@ -12540,8 +12783,8 @@ dependencies = [ [[package]] name = "xcm-builder" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -12551,9 +12794,9 @@ dependencies = [ "polkadot-parachain", "scale-info", "sp-arithmetic", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", "xcm-executor", ] @@ -12561,7 +12804,7 @@ dependencies = [ [[package]] name = "xcm-emulator" version = "0.1.0" -source = "git+https://github.com/pontem-network/xcm-simulator?branch=polkadot-v0.9.13#0e6af33b4da4766bb098d06b00ef85a26c06b24f" +source = "git+https://github.com/pontem-network/xcm-simulator?branch=polkadot-v0.9.16#d4a700a345789d21423879caad4eb8107eda44e9" dependencies = [ "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -12576,16 +12819,16 @@ dependencies = [ "paste", "polkadot-primitives", "polkadot-runtime-parachains", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-io 4.0.0", + "sp-std 4.0.0", "xcm", "xcm-executor", ] [[package]] name = "xcm-executor" -version = "0.9.13" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +version = "0.9.16" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -12593,18 +12836,19 @@ dependencies = [ "log", "parity-scale-codec", "sp-arithmetic", - "sp-core 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", - "sp-io 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-core 4.1.0-dev", + "sp-io 4.0.0", "sp-runtime", - "sp-std 4.0.0-dev (git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.13)", + "sp-std 4.0.0", "xcm", ] [[package]] name = "xcm-procedural" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.13#7d8f00b90cd6d87780123b3e08ca120cfb0c6e50" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ + "Inflector", "proc-macro2", "quote", "syn", @@ -12616,7 +12860,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7d9028f208dd5e63c614be69f115c1b53cacc1111437d4c765185856666c107" dependencies = [ - "futures 0.3.19", + "futures 0.3.21", "log", "nohash-hasher", "parking_lot 0.11.2", @@ -12626,9 +12870,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db" +checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" dependencies = [ "zeroize_derive", ] diff --git a/README.md b/README.md index 230d7924..b814a6c2 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ There are several options to launch Pontem local parachain: Install [polkadot-launch](https://github.com/paritytech/polkadot-launch). -**Note:** you must have polkadot node `v0.9.13` compiled and built placed in `../polkadot/target/release/`. +**Note:** you must have polkadot node `v0.9.16` compiled and built placed in `../polkadot/target/release/`. To use different localion you can modify `./launch-config.json`. Create keystore path for Pontem: @@ -105,7 +105,7 @@ Build Polkadot: git clone https://github.com/paritytech/polkadot.git cd polkadot git fetch origin -git checkout release-v0.9.13 +git checkout release-v0.9.16 cargo build --release ``` diff --git a/docker-compose.yml b/docker-compose.yml index dfe666b8..816061f0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: dockerfile: launch.Dockerfile args: PONTEM_VERSION: v0.4.1 - POLKADOT_VERSION: v0.9.13 + POLKADOT_VERSION: v0.9.16 NODE_VERSION: 16 ports: - "9944:9944" # Alice relaychain diff --git a/node/Cargo.toml b/node/Cargo.toml index 091e23e0..4131d35a 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -17,7 +17,7 @@ path = 'src/main.rs' targets = ['x86_64-unknown-linux-gnu'] [build-dependencies] -substrate-build-script-utils = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +substrate-build-script-utils = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } stdlib-fetch = { path = "../utils/stdlib-fetch" } [dependencies] @@ -26,68 +26,68 @@ futures = { version = "0.3.1", features = ["compat"] } jsonrpc-core = '18.0' serde_json = '1.0' structopt = '0.3.8' -codec = { package = 'parity-scale-codec', version = '2.3.0' } +codec = { package = 'parity-scale-codec', version = '2.3.1' } log = "0.4" serde = { version = "1.0", features = ["derive"] } # Substrate dependencies -frame-benchmarking = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-benchmarking-cli = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-transaction-payment-rpc = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -substrate-frame-rpc-system = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -substrate-prometheus-endpoint = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +frame-benchmarking = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-benchmarking-cli = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-transaction-payment-rpc = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +substrate-frame-rpc-system = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +substrate-prometheus-endpoint = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Substarte Client Dependencies -sc-basic-authorship = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-cli = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13', features = ['wasmtime'] } -sc-client-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-consensus = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-executor = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13', features = ['wasmtime'] } -sc-finality-grandpa = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-keystore = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-rpc = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-rpc-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-service = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13', features = ['wasmtime'] } -sc-telemetry = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-transaction-pool = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-tracing = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-chain-spec = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-network = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-transaction-pool-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sc-consensus-manual-seal = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sc-basic-authorship = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-cli = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } +sc-client-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-consensus = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-executor = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } +sc-finality-grandpa = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-keystore = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-rpc = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-rpc-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-service = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } +sc-telemetry = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-transaction-pool = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-tracing = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-chain-spec = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-network = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-transaction-pool-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-consensus-manual-seal = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Substrate Primitive Dependencies -sp-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-block-builder = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-blockchain = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-consensus = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-core = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-finality-grandpa = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-inherents = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-runtime = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-transaction-pool = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-timestamp = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-session = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-offchain = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-keystore = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-block-builder = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-blockchain = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-consensus = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-finality-grandpa = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-inherents = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-transaction-pool = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-timestamp = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-session = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-offchain = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-keystore = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Nimbus dependencies -nimbus-primitives = { git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.13' } -nimbus-consensus = { git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.13' } +nimbus-primitives = { git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.16' } +nimbus-consensus = { git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.16' } # Cumulus dependencies -cumulus-client-consensus-relay-chain = { git = "https://github.com/paritytech/cumulus", branch = 'polkadot-v0.9.13' } -cumulus-client-consensus-common = { git = "https://github.com/paritytech/cumulus", branch = 'polkadot-v0.9.13' } -cumulus-client-network = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-client-service = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-client-cli = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-primitives-core = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-primitives-parachain-inherent = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } +cumulus-client-consensus-relay-chain = { git = "https://github.com/paritytech/cumulus", branch = 'polkadot-v0.9.16' } +cumulus-client-consensus-common = { git = "https://github.com/paritytech/cumulus", branch = 'polkadot-v0.9.16' } +cumulus-client-network = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-client-service = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-client-cli = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-primitives-core = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-primitives-parachain-inherent = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } # Polkadot dependencies -polkadot-primitives = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -polkadot-service = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -polkadot-parachain = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } +polkadot-primitives = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +polkadot-service = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +polkadot-parachain = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } # Local dependencies pontem-runtime = { path = '../runtime' } @@ -105,7 +105,7 @@ constants = { path = '../constants' } # # ** Don't enable relay chains you don't need, as this is a **very** heavy build for no reason** # More info: https://github.com/paritytech/polkadot/pull/3189 -polkadot-cli = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13', features = ["kusama-native"] } +polkadot-cli = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16', features = ["kusama-native"] } [dependencies.move-vm] package = "mvm" diff --git a/pallets/author-mapping/Cargo.toml b/pallets/author-mapping/Cargo.toml index 69e329b7..39271ffb 100644 --- a/pallets/author-mapping/Cargo.toml +++ b/pallets/author-mapping/Cargo.toml @@ -1,26 +1,26 @@ [package] name = "pallet-author-mapping" -version = "2.0.4" +version = "2.0.5" authors = ["PureStake"] edition = "2021" description = "Maps AuthorIds to AccountIds Useful for associating consensus authors with in-runtime accounts" [dependencies] log = { version = "0.4", default-features = false } -nimbus-primitives = { git = "https://github.com/pontem-network/nimbus", branch = "polkadot-v0.9.13", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -parity-scale-codec = { version = "2.0.0", default-features = false, features=["derive"] } +nimbus-primitives = { git = "https://github.com/pontem-network/nimbus", branch = "polkadot-v0.9.16", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +parity-scale-codec = { version = "2.3.1", default-features = false, features=["derive"] } serde = { version = "1.0.101", optional=true } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false, optional = true } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false, optional = true } scale-info = { version = "1.0", default-features = false, features = ["derive"] } [dev-dependencies] -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } [features] default = ["std"] diff --git a/pallets/author-mapping/src/lib.rs b/pallets/author-mapping/src/lib.rs index 3c8ffd20..cd074261 100644 --- a/pallets/author-mapping/src/lib.rs +++ b/pallets/author-mapping/src/lib.rs @@ -17,7 +17,7 @@ //! Maps Author Ids as used in nimbus consensus layer to account ids as used i nthe runtime. //! This should likely be moved to nimbus eventually. //! -//! This pallet maps AuthorId => AccountId which is most useful when using propositional style +//! This pallet maps NimbusId => AccountId which is most useful when using propositional style //! queries. This mapping will likely need to go the other way if using exhaustive authority sets. //! That could either be a seperate pallet, or this pallet could implement a two-way mapping. But //! for now it it one-way @@ -45,7 +45,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_support::traits::{Currency, ReservableCurrency}; use frame_system::pallet_prelude::*; - use nimbus_primitives::AccountLookup; + use nimbus_primitives::{AccountLookup, NimbusId}; pub type BalanceOf = <::DepositCurrency as Currency< ::AccountId, @@ -58,6 +58,7 @@ pub mod pallet { } #[pallet::pallet] + #[pallet::without_storage_info] pub struct Pallet(PhantomData); /// Configuration trait of this pallet. We tightly couple to Parachain Staking in order to @@ -67,11 +68,9 @@ pub mod pallet { pub trait Config: frame_system::Config { /// Overarching event type type Event: From> + IsType<::Event>; - /// The type of authority id that will be used at the consensus layer. - type AuthorId: Member + Parameter + MaybeSerializeDeserialize + Default; /// Currency in which the security deposit will be taken. type DepositCurrency: Currency + ReservableCurrency; - /// The amount that should be taken as a security deposit when registering an AuthorId. + /// The amount that should be taken as a security deposit when registering an NimbusId. type DepositAmount: Get<>::Balance>; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; @@ -86,32 +85,32 @@ pub mod pallet { NotYourAssociation, /// This account cannot set an author because it cannon afford the security deposit CannotAffordSecurityDeposit, - /// The AuthorId in question is already associated and cannot be overwritten + /// The NimbusId in question is already associated and cannot be overwritten AlreadyAssociated, } #[pallet::event] #[pallet::generate_deposit(pub(crate) fn deposit_event)] pub enum Event { - /// An AuthorId has been registered and mapped to an AccountId. - AuthorRegistered(T::AuthorId, T::AccountId), - /// An AuthorId has been de-registered, and its AccountId mapping removed. - AuthorDeRegistered(T::AuthorId), - /// An AuthorId has been registered, replacing a previous registration and its mapping. - AuthorRotated(T::AuthorId, T::AccountId), - /// An AuthorId has been forcibly deregistered after not being rotated or cleaned up. + /// An NimbusId has been registered and mapped to an AccountId. + AuthorRegistered(NimbusId, T::AccountId), + /// An NimbusId has been de-registered, and its AccountId mapping removed. + AuthorDeRegistered(NimbusId), + /// An NimbusId has been registered, replacing a previous registration and its mapping. + AuthorRotated(NimbusId, T::AccountId), + /// An NimbusId has been forcibly deregistered after not being rotated or cleaned up. /// The reporteing account has been rewarded accordingly. - DefunctAuthorBusted(T::AuthorId, T::AccountId), + DefunctAuthorBusted(NimbusId, T::AccountId), } #[pallet::call] impl Pallet { - /// Register your AuthorId onchain so blocks you author are associated with your account. + /// Register your NimbusId onchain so blocks you author are associated with your account. /// /// Users who have been (or will soon be) elected active collators in staking, /// should submit this extrinsic to have their blocks accepted and earn rewards. #[pallet::weight(::WeightInfo::add_association())] - pub fn add_association(origin: OriginFor, author_id: T::AuthorId) -> DispatchResult { + pub fn add_association(origin: OriginFor, author_id: NimbusId) -> DispatchResult { let account_id = ensure_signed(origin)?; ensure!( @@ -126,15 +125,15 @@ pub mod pallet { Ok(()) } - /// Change your AuthorId. + /// Change your Mapping. /// /// This is useful for normal key rotation or for when switching from one physical collator /// machine to another. No new security deposit is required. #[pallet::weight(::WeightInfo::update_association())] pub fn update_association( origin: OriginFor, - old_author_id: T::AuthorId, - new_author_id: T::AuthorId, + old_author_id: NimbusId, + new_author_id: NimbusId, ) -> DispatchResult { let account_id = ensure_signed(origin)?; @@ -145,23 +144,27 @@ pub mod pallet { account_id == stored_info.account, Error::::NotYourAssociation ); + ensure!( + MappingWithDeposit::::get(&new_author_id).is_none(), + Error::::AlreadyAssociated + ); - MappingWithDeposit::::insert(&new_author_id, &stored_info); MappingWithDeposit::::remove(&old_author_id); + MappingWithDeposit::::insert(&new_author_id, &stored_info); >::deposit_event(Event::AuthorRotated(new_author_id, stored_info.account)); Ok(()) } - /// Clear your AuthorId. + /// Clear your Mapping. /// /// This is useful when you are no longer an author and would like to re-claim your security /// deposit. #[pallet::weight(::WeightInfo::clear_association())] pub fn clear_association( origin: OriginFor, - author_id: T::AuthorId, + author_id: NimbusId, ) -> DispatchResultWithPostInfo { let account_id = ensure_signed(origin)?; @@ -181,42 +184,11 @@ pub mod pallet { Ok(().into()) } - - //TODO maybe in the future we will add some more incentivization for key cleanup and also - // proper key rotation - // /// The portion of the security deposit that goes to the the account who reports it - // /// occupying space after it should have been cleaned or rotated. - // pub const NARC_REWARD: Percent = Percent::from_percent(5); - - // /// The period of time after which an AuthorId can be reported as defunct. - // /// This value should be roughly the recommended key rotation period. - // pub const NARC_GRACE_PERIOD: u32 = 2_000; - // - // /// Narc on another account for having a useless association and collect a bounty. - // /// - // /// This incentivizes good citizenship in the form of cleaning up others' defunct - // /// associations. When you clean up another account's association, you will receive X - // /// percent of their security deposit. - // /// - // /// No association can be cleaned up within the initial grace period which allows collators - // /// some time to get their associations onchain before they become active, and to clean up - // /// after they are no longer active. - // /// - // /// This also _forces_ collators to rotate their keys regularly because failing to will - // /// make their mappings ripe for narcing. If an active collator gets its association reaped - // /// they will lose out on their block rewards (and in the future potentially be slashed). - // #[pallet::weight(0)] - // pub fn narc_defunct_association( - // origin: OriginFor, - // author_id: T::AuthorId, - // ) -> DispatchResult { - // todo!() - // } } impl Pallet { pub fn enact_registration( - author_id: &T::AuthorId, + author_id: &NimbusId, account_id: &T::AccountId, ) -> DispatchResult { let deposit = T::DepositAmount::get(); @@ -237,12 +209,12 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn account_and_deposit_of)] - /// We maintain a mapping from the AuthorIds used in the consensus layer + /// We maintain a mapping from the NimbusIds used in the consensus layer /// to the AccountIds runtime (including this staking pallet). pub type MappingWithDeposit = StorageMap< _, Blake2_128Concat, - T::AuthorId, + NimbusId, RegistrationInfo>, OptionQuery, >; @@ -251,7 +223,7 @@ pub mod pallet { /// Genesis config for author mapping pallet pub struct GenesisConfig { /// The associations that should exist at chain genesis - pub mappings: Vec<(T::AuthorId, T::AccountId)>, + pub mappings: Vec<(NimbusId, T::AccountId)>, } #[cfg(feature = "std")] @@ -272,8 +244,8 @@ pub mod pallet { } } - impl AccountLookup for Pallet { - fn lookup_account(author: &T::AuthorId) -> Option { + impl AccountLookup for Pallet { + fn lookup_account(author: &NimbusId) -> Option { Self::account_id_of(author) } } @@ -281,7 +253,7 @@ pub mod pallet { impl Pallet { /// A helper function to lookup the account id associated with the given author id. This is /// the primary lookup that this pallet is responsible for. - pub fn account_id_of(author_id: &T::AuthorId) -> Option { + pub fn account_id_of(author_id: &NimbusId) -> Option { Self::account_and_deposit_of(author_id).map(|info| info.account) } } diff --git a/pallets/author-mapping/src/migrations.rs b/pallets/author-mapping/src/migrations.rs index b0f64727..7b71cb19 100644 --- a/pallets/author-mapping/src/migrations.rs +++ b/pallets/author-mapping/src/migrations.rs @@ -26,6 +26,8 @@ use frame_support::{ use sp_std::convert::TryInto; //TODO sometimes this is unused, sometimes its necessary use sp_std::vec::Vec; +use nimbus_primitives::NimbusId; + /// Migrates the AuthorMapping's storage map fro mthe insecure Twox64 hasher to the secure /// BlakeTwo hasher. @@ -39,7 +41,7 @@ impl OnRuntimeUpgrade for TwoXToBlake { // Read all the data into memory. // https://crates.parity.io/frame_support/storage/migration/fn.storage_key_iter.html let stored_data: Vec<_> = storage_key_iter::< - T::AuthorId, + NimbusId, RegistrationInfo>, Twox64Concat, >(pallet_prefix, storage_item_prefix) @@ -56,7 +58,7 @@ impl OnRuntimeUpgrade for TwoXToBlake { // Assert that old storage is empty assert!(storage_key_iter::< - T::AuthorId, + NimbusId, RegistrationInfo>, Twox64Concat, >(pallet_prefix, storage_item_prefix) @@ -106,7 +108,7 @@ impl OnRuntimeUpgrade for TwoXToBlake { // Read an example pair from old storage and set it aside in temp storage if mapping_count > 0 { let example_pair = storage_key_iter::< - T::AuthorId, + NimbusId, RegistrationInfo>, Twox64Concat, >(pallet_prefix, storage_item_prefix) @@ -132,7 +134,7 @@ impl OnRuntimeUpgrade for TwoXToBlake { // Check that our example pair is still well-mapped after the migration if new_mapping_count > 0 { let (account, original_info): ( - T::AuthorId, + NimbusId, RegistrationInfo>, ) = Self::get_temp_storage("example_pair").expect("qed"); let migrated_info = MappingWithDeposit::::get(account).expect("qed"); diff --git a/pallets/author-mapping/src/mock.rs b/pallets/author-mapping/src/mock.rs index 79d61d1e..f98c6710 100644 --- a/pallets/author-mapping/src/mock.rs +++ b/pallets/author-mapping/src/mock.rs @@ -18,20 +18,21 @@ use crate as pallet_author_mapping; use frame_support::{ construct_runtime, parameter_types, - traits::{Everything, GenesisBuild}, + traits::{Everything, GenesisBuild, ConstU32}, weights::Weight, }; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -use sp_core::H256; +use sp_core::{H256, ByteArray}; use sp_io; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, Perbill, RuntimeDebug, }; +use nimbus_primitives::NimbusId; #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)] @@ -39,13 +40,20 @@ pub enum TestAuthor { Alice, Bob, Charlie, - Dave, - Eve, } impl Default for TestAuthor { - fn default() -> TestAuthor { - TestAuthor::Alice - } + fn default() -> TestAuthor { + TestAuthor::Alice + } +} +impl Into for TestAuthor { + fn into(self) -> NimbusId { + match self { + Self::Alice => NimbusId::from_slice(&[0u8; 32]).unwrap(), + Self::Bob => NimbusId::from_slice(&[1u8; 32]).unwrap(), + Self::Charlie => NimbusId::from_slice(&[2u8; 32]).unwrap(), + } + } } pub type AccountId = u64; pub type Balance = u128; @@ -97,6 +105,7 @@ impl frame_system::Config for Runtime { type BlockLength = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<12>; } parameter_types! { pub const ExistentialDeposit: u128 = 1; @@ -118,7 +127,6 @@ parameter_types! { } impl pallet_author_mapping::Config for Runtime { type Event = Event; - type AuthorId = TestAuthor; type DepositCurrency = Balances; type DepositAmount = DepositAmount; type WeightInfo = (); @@ -130,7 +138,7 @@ pub(crate) struct ExtBuilder { /// Accounts endowed with balances balances: Vec<(AccountId, Balance)>, /// AuthorId -> AccoutId mappings - mappings: Vec<(TestAuthor, AccountId)>, + mappings: Vec<(NimbusId, AccountId)>, } impl Default for ExtBuilder { @@ -148,7 +156,7 @@ impl ExtBuilder { self } - pub(crate) fn with_mappings(mut self, mappings: Vec<(TestAuthor, AccountId)>) -> Self { + pub(crate) fn with_mappings(mut self, mappings: Vec<(NimbusId, AccountId)>) -> Self { self.mappings = mappings; self } diff --git a/pallets/author-mapping/src/tests.rs b/pallets/author-mapping/src/tests.rs index b521fbe4..7dd5de6d 100644 --- a/pallets/author-mapping/src/tests.rs +++ b/pallets/author-mapping/src/tests.rs @@ -26,14 +26,14 @@ use frame_support::{assert_noop, assert_ok}; fn genesis_builder_works() { ExtBuilder::default() .with_balances(vec![(1, 1000)]) - .with_mappings(vec![(TestAuthor::Alice, 1)]) + .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) .build() .execute_with(|| { assert!(System::events().is_empty()); assert_eq!(Balances::free_balance(&1), 900); assert_eq!(Balances::reserved_balance(&1), 100); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice), Some(1)); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob), None); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), Some(1)); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), None); }) } @@ -45,16 +45,16 @@ fn eligible_account_can_register() { .execute_with(|| { assert_ok!(AuthorMapping::add_association( Origin::signed(2), - TestAuthor::Bob + TestAuthor::Bob.into() )); assert_eq!(Balances::free_balance(&2), 900); assert_eq!(Balances::reserved_balance(&2), 100); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob), Some(2)); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), Some(2)); assert_eq!( last_event(), - MetaEvent::AuthorMapping(Event::AuthorRegistered(TestAuthor::Bob, 2)) + MetaEvent::AuthorMapping(Event::AuthorRegistered(TestAuthor::Bob.into(), 2)) ); }) } @@ -66,12 +66,12 @@ fn cannot_register_without_deposit() { .build() .execute_with(|| { assert_noop!( - AuthorMapping::add_association(Origin::signed(2), TestAuthor::Alice), + AuthorMapping::add_association(Origin::signed(2), TestAuthor::Alice.into()), Error::::CannotAffordSecurityDeposit ); assert_eq!(Balances::free_balance(&2), 10); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice), None); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), None); }) } @@ -84,35 +84,35 @@ fn double_registration_costs_twice_as_much() { // Register once as Bob assert_ok!(AuthorMapping::add_association( Origin::signed(2), - TestAuthor::Bob + TestAuthor::Bob.into() )); assert_eq!(Balances::free_balance(&2), 900); assert_eq!(Balances::reserved_balance(&2), 100); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob), Some(2)); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), Some(2)); assert_eq!( last_event(), - MetaEvent::AuthorMapping(Event::AuthorRegistered(TestAuthor::Bob, 2)) + MetaEvent::AuthorMapping(Event::AuthorRegistered(TestAuthor::Bob.into(), 2)) ); // Register again as Alice assert_ok!(AuthorMapping::add_association( Origin::signed(2), - TestAuthor::Alice + TestAuthor::Alice.into() )); assert_eq!(Balances::free_balance(&2), 800); assert_eq!(Balances::reserved_balance(&2), 200); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice), Some(2)); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), Some(2)); assert_eq!( last_event(), - MetaEvent::AuthorMapping(Event::AuthorRegistered(TestAuthor::Alice, 2)) + MetaEvent::AuthorMapping(Event::AuthorRegistered(TestAuthor::Alice.into(), 2)) ); // Should still be registered as Bob as well - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob), Some(2)); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), Some(2)); }) } @@ -120,21 +120,21 @@ fn double_registration_costs_twice_as_much() { fn registered_account_can_clear() { ExtBuilder::default() .with_balances(vec![(1, 1000)]) - .with_mappings(vec![(TestAuthor::Alice, 1)]) + .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) .build() .execute_with(|| { assert_ok!(AuthorMapping::clear_association( Origin::signed(1), - TestAuthor::Alice + TestAuthor::Alice.into() )); assert_eq!(Balances::free_balance(&1), 1000); assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice), None); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), None); assert_eq!( last_event(), - MetaEvent::AuthorMapping(Event::AuthorDeRegistered(TestAuthor::Alice)) + MetaEvent::AuthorMapping(Event::AuthorDeRegistered(TestAuthor::Alice.into())) ); }) } @@ -143,7 +143,7 @@ fn registered_account_can_clear() { fn unregistered_author_cannot_be_cleared() { ExtBuilder::default().build().execute_with(|| { assert_noop!( - AuthorMapping::clear_association(Origin::signed(1), TestAuthor::Alice), + AuthorMapping::clear_association(Origin::signed(1), TestAuthor::Alice.into()), Error::::AssociationNotFound ); }) @@ -153,11 +153,11 @@ fn unregistered_author_cannot_be_cleared() { fn registered_author_cannot_be_cleared_by_non_owner() { ExtBuilder::default() .with_balances(vec![(1, 1000)]) - .with_mappings(vec![(TestAuthor::Alice, 1)]) + .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) .build() .execute_with(|| { assert_noop!( - AuthorMapping::clear_association(Origin::signed(2), TestAuthor::Alice), + AuthorMapping::clear_association(Origin::signed(2), TestAuthor::Alice.into()), Error::::NotYourAssociation ); }) @@ -167,11 +167,11 @@ fn registered_author_cannot_be_cleared_by_non_owner() { fn registered_author_cannot_be_overwritten() { ExtBuilder::default() .with_balances(vec![(1, 1000)]) - .with_mappings(vec![(TestAuthor::Alice, 1)]) + .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) .build() .execute_with(|| { assert_noop!( - AuthorMapping::add_association(Origin::signed(2), TestAuthor::Alice), + AuthorMapping::add_association(Origin::signed(2), TestAuthor::Alice.into()), Error::::AlreadyAssociated ); }) @@ -181,17 +181,17 @@ fn registered_author_cannot_be_overwritten() { fn registered_can_rotate() { ExtBuilder::default() .with_balances(vec![(2, 1000)]) - .with_mappings(vec![(TestAuthor::Bob, 2)]) + .with_mappings(vec![(TestAuthor::Bob.into(), 2)]) .build() .execute_with(|| { assert_ok!(AuthorMapping::update_association( Origin::signed(2), - TestAuthor::Bob, - TestAuthor::Charlie + TestAuthor::Bob.into(), + TestAuthor::Charlie.into() )); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob), None); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Charlie), Some(2)); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), None); + assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Charlie.into()), Some(2)); // Should still only ahve paid a single security deposit assert_eq!(Balances::free_balance(&2), 900); @@ -205,8 +205,8 @@ fn unregistered_author_cannot_be_rotated() { assert_noop!( AuthorMapping::update_association( Origin::signed(2), - TestAuthor::Alice, - TestAuthor::Bob + TestAuthor::Alice.into(), + TestAuthor::Bob.into() ), Error::::AssociationNotFound ); @@ -217,20 +217,38 @@ fn unregistered_author_cannot_be_rotated() { fn registered_author_cannot_be_rotated_by_non_owner() { ExtBuilder::default() .with_balances(vec![(1, 1000)]) - .with_mappings(vec![(TestAuthor::Alice, 1)]) + .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) .build() .execute_with(|| { assert_noop!( AuthorMapping::update_association( Origin::signed(2), - TestAuthor::Alice, - TestAuthor::Bob + TestAuthor::Alice.into(), + TestAuthor::Bob.into() ), Error::::NotYourAssociation ); }) } +#[test] +fn rotating_to_the_same_author_id_leaves_registration_in_tact() { + ExtBuilder::default() + .with_balances(vec![(1, 1000)]) + .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) + .build() + .execute_with(|| { + assert_noop!( + AuthorMapping::update_association( + Origin::signed(1), + TestAuthor::Alice.into(), + TestAuthor::Alice.into() + ), + Error::::AlreadyAssociated + ); + }) +} + //TODO Test ideas in case we bring back the narc extrinsic // unstaked account can be narced after period // unstaked account cannot be narced before period diff --git a/pallets/currencies/Cargo.toml b/pallets/currencies/Cargo.toml index f8a5f467..c637a605 100644 --- a/pallets/currencies/Cargo.toml +++ b/pallets/currencies/Cargo.toml @@ -8,26 +8,26 @@ edition = "2021" serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "2.3.1", default-features = false } scale-info = { version = "1.0", default-features = false, features = ["derive"] } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } # Orml dependencies -orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-utilities = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } +orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-utilities = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } # Local dependencies primitives = { default-features = false, path = "../../primitives" } [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } +orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } [features] default = ["std"] @@ -44,5 +44,6 @@ std = [ "orml-traits/std", "orml-utilities/std", "primitives/std", + "orml-tokens/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/currencies/src/lib.rs b/pallets/currencies/src/lib.rs index 2bd505c7..e762ead6 100644 --- a/pallets/currencies/src/lib.rs +++ b/pallets/currencies/src/lib.rs @@ -22,7 +22,7 @@ #![allow(clippy::unused_unit)] #![allow(clippy::upper_case_acronyms)] -use codec::{Codec, FullCodec}; +use codec::{Codec, FullCodec, MaxEncodedLen}; use frame_support::{ pallet_prelude::*, traits::{ @@ -83,7 +83,8 @@ pub mod module { + Copy + MaybeSerializeDeserialize + Debug - + scale_info::TypeInfo; + + scale_info::TypeInfo + + MaxEncodedLen; type MultiCurrency: TransferAll + MultiCurrencyExtended + MultiLockableCurrency @@ -859,7 +860,8 @@ where + Copy + MaybeSerializeDeserialize + Debug - + Default, + + Default + + MaxEncodedLen, Currency: PalletCurrency, T: Config, { diff --git a/pallets/currencies/src/mock.rs b/pallets/currencies/src/mock.rs index 16a9efe1..21bafb18 100644 --- a/pallets/currencies/src/mock.rs +++ b/pallets/currencies/src/mock.rs @@ -22,12 +22,12 @@ use frame_support::{ ord_parameter_types, parameter_types, - traits::{Everything, GenesisBuild, Nothing}, + traits::{Everything, GenesisBuild, Nothing, ConstU32}, PalletId, }; use orml_traits::parameter_type_with_key; use sp_core::{H256, crypto::Ss58Codec}; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use sp_runtime::{ testing::Header, @@ -43,7 +43,7 @@ use serde::{Deserialize, Serialize}; use scale_info::TypeInfo; // Currencies id. -#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, TypeInfo)] +#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum CurrencyId { // Relaychain's currency. @@ -88,6 +88,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<12>; } type Balance = u128; @@ -178,8 +179,8 @@ pub type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, diff --git a/pallets/groupsign/Cargo.toml b/pallets/groupsign/Cargo.toml index 793214a3..4eb02ab8 100644 --- a/pallets/groupsign/Cargo.toml +++ b/pallets/groupsign/Cargo.toml @@ -14,17 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { default-features = false , package = "parity-scale-codec", version = "2.3.1" } scale-info = { default-features = false, version = "1.0", features = ["derive"] } -frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } getrandom = { version = "0.2.3", optional = true } [dev-dependencies] -sp-keystore = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-keystore = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } [features] default = ['std'] diff --git a/pallets/parachain-staking/Cargo.toml b/pallets/parachain-staking/Cargo.toml index 9f93a48d..f28fcb8d 100644 --- a/pallets/parachain-staking/Cargo.toml +++ b/pallets/parachain-staking/Cargo.toml @@ -6,23 +6,23 @@ edition = "2021" description = "parachain staking pallet for collator selection and reward distribution" [dependencies] -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false, optional = true } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } log = "0.4" -nimbus-primitives = { git = "https://github.com/pontem-network/nimbus", branch = "polkadot-v0.9.13", default-features = false } -parity-scale-codec = { version = "2.2", default-features = false, features = ["derive"] } +nimbus-primitives = { git = "https://github.com/pontem-network/nimbus", branch = "polkadot-v0.9.16", default-features = false } +parity-scale-codec = { version = "2.3.1", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } substrate-fixed = { default-features = false, git = "https://github.com/encointer/substrate-fixed" } scale-info = { version = "1.0", default-features = false, features = ["derive"] } [dev-dependencies] -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13"} +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16"} similar-asserts = "1.1.0" -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } [features] default = ["std"] diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index b4c72cfb..11f3dfbf 100644 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -79,9 +79,10 @@ pub mod pallet { /// Pallet for parachain staking #[pallet::pallet] + #[pallet::without_storage_info] pub struct Pallet(PhantomData); - #[derive(Default, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct Bond { pub owner: AccountId, pub amount: Balance, @@ -133,7 +134,7 @@ pub mod pallet { } } - #[derive(Default, Encode, Decode, RuntimeDebug, TypeInfo)] + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] /// Snapshot of collator state at the start of the round for which they are selected pub struct CollatorSnapshot { pub bond: Balance, @@ -642,16 +643,8 @@ pub mod pallet { /// Percent of inflation set aside for parachain bond account pub percent: Percent, } - impl Default for ParachainBondConfig { - fn default() -> ParachainBondConfig { - ParachainBondConfig { - account: A::default(), - percent: Percent::zero(), - } - } - } - #[derive(Encode, Decode, RuntimeDebug, Default, TypeInfo)] + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] /// Store and process all delayed exits by collators and nominators pub struct ExitQ { /// Candidate exit set @@ -664,6 +657,14 @@ pub mod pallet { pub nominator_schedule: Vec<(AccountId, Option, RoundIndex)>, } + impl Default for ExitQ { + fn default() -> ExitQ { + ExitQ { + ..Default::default() + } + } + } + impl ExitQ { /// Schedule to leave the set of candidates and return all ongoing nominations pub fn schedule_candidate_exit( @@ -1088,7 +1089,7 @@ pub mod pallet { // Set parachain bond config to default config >::put(ParachainBondConfig { // must be set soon; if not => due inflation will be sent to collators/nominators - account: T::AccountId::default(), + account: T::AccountId::new([0; 32]), percent: T::DefaultParachainBondReservePercent::get(), }); // Set total selected candidates to minimum config @@ -1169,9 +1170,11 @@ pub mod pallet { account: old, percent, } = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); + if let Some(old_account) = old { + ensure!(old_account != new, Error::::NoWritingSameValue); + } >::put(ParachainBondConfig { - account: new.clone(), + account: Some(new), percent, }); Self::deposit_event(Event::ParachainBondAccountSet(old, new)); diff --git a/pallets/sp-mvm/Cargo.toml b/pallets/sp-mvm/Cargo.toml index e0610150..4a3069bc 100644 --- a/pallets/sp-mvm/Cargo.toml +++ b/pallets/sp-mvm/Cargo.toml @@ -45,22 +45,22 @@ serde = { version = "1.0", optional = true } once_cell = { default-features = false, version = "1.5.2" } # substrate: scale-info = { version = "1.0", default-features = false, features = ["derive"] } -frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -timestamp = { default-features = false, package = "pallet-timestamp", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -balances = { default-features = false, package = "pallet-balances", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +timestamp = { default-features = false, package = "pallet-timestamp", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +balances = { default-features = false, package = "pallet-balances", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # logging, `sp_runtime::print`: -sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } groupsign = { path = "../groupsign", default-features = false } -sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } getrandom = { version = "0.2.3", optional = true } # Orml -orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } +orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } # serde is for lcs/bcs only # used for benchmarking (runtime, std, no-std) @@ -76,13 +76,13 @@ optional = true [dev-dependencies] # serde is for lcs/bcs and construct_runtime # used for tests (std) only -pallet-vesting = { default-features = false, package = "pallet-vesting", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +pallet-vesting = { default-features = false, package = "pallet-vesting", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } primitives = { path = "../../primitives" } assets = { path = "../../assets" } constants = { path = "../../constants" } module-currencies = { path = "../currencies" } -orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-currencies = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } +orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-currencies = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } serde = { package = "serde", version = "1.0.119" } bcs = { package = "bcs", version = "0.1" } env_logger = "0.9.0" diff --git a/pallets/sp-mvm/rpc/Cargo.toml b/pallets/sp-mvm/rpc/Cargo.toml index 3a21c622..3ed78d55 100644 --- a/pallets/sp-mvm/rpc/Cargo.toml +++ b/pallets/sp-mvm/rpc/Cargo.toml @@ -13,13 +13,13 @@ targets = ["x86_64-unknown-linux-gnu"] jsonrpc-core = "18.0" jsonrpc-core-client = "18.0" jsonrpc-derive = "18.0" -sp-rpc = { version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-runtime = { version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-api = { version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-support = { version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-blockchain = { version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-rpc = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-api = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-support = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-blockchain = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } sp-mvm-rpc-runtime = { version = "0.2.2", path = "./runtime" } -codec = { package = "parity-scale-codec", version = "2.3.0" } +codec = { package = "parity-scale-codec", version = "2.3.1" } serde = { version = "1.0.119", features = [ "derive" ] } # / 1.0.101 fc-rpc-core = { version = "1.0.0" } diff --git a/pallets/sp-mvm/rpc/runtime/Cargo.toml b/pallets/sp-mvm/rpc/runtime/Cargo.toml index ffd6ba6b..5f3c18d7 100644 --- a/pallets/sp-mvm/rpc/runtime/Cargo.toml +++ b/pallets/sp-mvm/rpc/runtime/Cargo.toml @@ -10,13 +10,12 @@ version = "0.2.2" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { default-features = false, version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-api = { default-features = false, version = '4.0.0-dev', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-support = { default-features = false, version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-api = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } sp-mvm = { default-features = false, path = "../../" } -sp-runtime = { default-features = false, version = "4.0.0-dev", git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -# TODO: update parity-scale-codec to 2.2.0 -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } +sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +codec = { package = "parity-scale-codec", version = "2.3.1", default-features = false } [features] default = ["std"] diff --git a/pallets/sp-mvm/src/balance.rs b/pallets/sp-mvm/src/balance.rs index 348f284d..d017f873 100644 --- a/pallets/sp-mvm/src/balance.rs +++ b/pallets/sp-mvm/src/balance.rs @@ -11,7 +11,6 @@ //! * get_balance - get current balance of account. //! * add - add tokens to account. //! * sub - reduce account balance on amount. - use core::convert::TryFrom; use core::convert::TryInto; use move_vm::io::traits::{Balance as VmBalance, BalanceAccess}; @@ -47,7 +46,7 @@ pub struct BalancesAdapter { _phantom: core::marker::PhantomData<(AccountId, Currencies, CurrencyId)>, } -impl +impl BalancesAdapter { /// Create new instance of Balance Adapter. @@ -74,7 +73,7 @@ impl /// It's a trait required to Move VM and allows for poxy balances between Substrate and VM. /// Using deposit/withdraw to PalletId we are solving total issuance issue. impl< - AccountId: Encode + Decode + Default, + AccountId: Encode + Decode, Currencies: MultiCurrency + fungibles::Inspect, CurrencyId: FullCodec @@ -247,7 +246,7 @@ pub mod boxed { } impl< - AccountId: Encode + Decode + Sized + Default + 'static, + AccountId: Encode + Decode + Sized + 'static, Currencies: MultiCurrency + fungibles::Inspect + 'static, @@ -286,7 +285,7 @@ pub mod boxed { } impl< - AccountId: Encode + Decode + Sized + Default + 'static, + AccountId: Encode + Decode + Sized + 'static, Currencies: orml_traits::MultiCurrency + fungibles::Inspect + 'static, diff --git a/pallets/sp-mvm/src/lib.rs b/pallets/sp-mvm/src/lib.rs index 6273eba3..013621d0 100644 --- a/pallets/sp-mvm/src/lib.rs +++ b/pallets/sp-mvm/src/lib.rs @@ -136,6 +136,7 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub trait Store)] + #[pallet::without_storage_info] pub struct Pallet(_); // The pallet's runtime storage items. diff --git a/pallets/transaction-pause/Cargo.toml b/pallets/transaction-pause/Cargo.toml index 5be23446..89c1bb23 100644 --- a/pallets/transaction-pause/Cargo.toml +++ b/pallets/transaction-pause/Cargo.toml @@ -9,32 +9,28 @@ edition = "2021" serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "2.3.1", default-features = false } scale-info = { version = "1.0", default-features = false, features = ["derive"] } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false, optional = true } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } primitives = { default-features = false, path = "../../primitives" } # Orml dependencies -orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-utilities = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } - +orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-utilities = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } [dev-dependencies] -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13"} -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13"} -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } -orml-traits = { git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-utilities = { git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } - - -primitives = { path = "../../primitives" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16"} +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16"} +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } +orml-traits = { git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-utilities = { git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } [features] default = ["std"] @@ -46,4 +42,10 @@ std = [ "sp-runtime/std", "sp-std/std", "scale-info/std", + "primitives/std", + "orml-traits/std", + "orml-utilities/std", + "sp-io/std", + "sp-core/std", + "codec/std", ] diff --git a/pallets/transaction-pause/src/lib.rs b/pallets/transaction-pause/src/lib.rs index 227d52ba..7ef410f1 100644 --- a/pallets/transaction-pause/src/lib.rs +++ b/pallets/transaction-pause/src/lib.rs @@ -57,6 +57,7 @@ pub mod module { StorageMap<_, Twox64Concat, (Vec, Vec), (), OptionQuery>; #[pallet::pallet] + #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::hooks] diff --git a/pallets/transaction-pause/src/mock.rs b/pallets/transaction-pause/src/mock.rs index cb9c5bfc..728e0568 100644 --- a/pallets/transaction-pause/src/mock.rs +++ b/pallets/transaction-pause/src/mock.rs @@ -3,7 +3,7 @@ use super::*; use frame_support::{ construct_runtime, ord_parameter_types, parameter_types, - traits::{Everything, Nothing}, + traits::{Everything, Nothing, ConstU32}, }; use frame_system::{EnsureSignedBy}; use orml_traits::parameter_type_with_key; @@ -47,6 +47,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<12>; } parameter_types! { diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index d91edfce..76eefa05 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -11,9 +11,9 @@ version = '3.0.0' serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "2.3.1", default-features = false, features = ["max-encoded-len"] } scale-info = { version = "1.0", default-features = false, features = ["derive"] } -sp-std = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-core = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-runtime = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +sp-std = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } [features] default = ["std"] diff --git a/primitives/src/currency.rs b/primitives/src/currency.rs index 34bde0dd..fc3f524c 100644 --- a/primitives/src/currency.rs +++ b/primitives/src/currency.rs @@ -4,7 +4,7 @@ use sp_std::convert::TryFrom; use sp_std::vec::Vec; use sp_std::cmp::PartialEq; use sp_std::default::Default; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; #[cfg(feature = "std")] @@ -157,7 +157,7 @@ pub const NATIVE_SYM: &'static [u8] = { #[cfg(not(feature = "pont"))] def_currencies! { /// Currencies id. - #[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, TypeInfo)] + #[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum CurrencyId { /// Our native currency. diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 6ce8540e..0b5f4414 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -11,7 +11,7 @@ version = '3.0.0' targets = ['x86_64-unknown-linux-gnu'] [build-dependencies] -substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13" } +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } [dependencies.codec] default-features = false @@ -26,64 +26,64 @@ smallvec = "1.6" # Substrate dependencies scale-info = { version = "1.0", default-features = false, features = ["derive"] } -frame-benchmarking = { default-features = false, optional = true, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-executive = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-support = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-system = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-system-benchmarking = { default-features = false, optional = true, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -frame-system-rpc-runtime-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-balances = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-randomness-collective-flip = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-sudo = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-timestamp = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-transaction-payment = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-vesting = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-treasury = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-democracy = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-scheduler = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +frame-benchmarking = { default-features = false, optional = true, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-executive = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-support = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system-benchmarking = { default-features = false, optional = true, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system-rpc-runtime-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-balances = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-randomness-collective-flip = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-sudo = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-timestamp = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-transaction-payment = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-vesting = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-treasury = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-democracy = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-scheduler = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Substrate Primitives dependencies -sp-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-block-builder = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-core = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-inherents = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-offchain = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-runtime = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-session = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-std = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-transaction-pool = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -sp-version = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-multisig = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } -pallet-xcm = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -xcm = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -xcm-builder = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -xcm-executor = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -polkadot-parachain = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -polkadot-primitives = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } +sp-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-block-builder = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-inherents = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-offchain = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-session = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-std = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-transaction-pool = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-version = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-multisig = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-xcm = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +xcm = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +xcm-builder = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +xcm-executor = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +polkadot-parachain = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +polkadot-primitives = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } # Nimbus dependencies -nimbus-primitives = { default-features = false, git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.13' } -pallet-author-inherent = { default-features = false, git = 'https://github.com/pontem-network/nimbus', branch = 'polkadot-v0.9.13' } -pallet-author-slot-filter = { default-features = false, git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.13' } +nimbus-primitives = { default-features = false, git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.16' } +pallet-author-inherent = { default-features = false, git = 'https://github.com/pontem-network/nimbus', branch = 'polkadot-v0.9.16' } +pallet-author-slot-filter = { default-features = false, git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.16' } # Cumulus Dependencies -parachain-info = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-pallet-parachain-system = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-pallet-xcm = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-pallet-xcmp-queue = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-pallet-dmp-queue = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-primitives-utility = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-primitives-core = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } -cumulus-primitives-timestamp = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.13' } +parachain-info = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-pallet-parachain-system = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-pallet-xcm = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-pallet-xcmp-queue = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-pallet-dmp-queue = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-primitives-utility = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-primitives-core = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-primitives-timestamp = { default-features = false, git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } # xtokens -orml-xtokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-xcm = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-xcm-support = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } -orml-unknown-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '88f1b4b1ac6ea0621d188dfa7e64fd2915dd81d5' } +orml-xtokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-xcm = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-traits = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-xcm-support = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } +orml-unknown-tokens = { default-features = false, git = 'https://github.com/open-web3-stack/open-runtime-module-library', rev = '213f743af2d6d2c94f235613d7e7ff21b093297c' } # local dependencies sp-mvm = { path = '../pallets/sp-mvm', default-features = false } @@ -97,10 +97,10 @@ groupsign = { path = "../pallets/groupsign", default-features = false } transaction-pause = { path = "../pallets/transaction-pause", default-features = false } [dev-dependencies] -xcm-emulator = { git = 'https://github.com/pontem-network/xcm-simulator', branch = 'polkadot-v0.9.13' } -polkadot-runtime-parachains = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -kusama-runtime = { git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.13' } -sp-io = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.13' } +xcm-emulator = { git = 'https://github.com/pontem-network/xcm-simulator', branch = 'polkadot-v0.9.16' } +polkadot-runtime-parachains = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +kusama-runtime = { git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +sp-io = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } assets = { path = '../assets', default-features = false } env_logger = "0.9.0" test-log = "0.2.8" From c14c781e48496f82fe480edc081ed2ba79fa84b2 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 00:04:51 +0300 Subject: [PATCH 02/13] new parachain staking, test fixes --- Cargo.lock | 92 +- pallets/groupsign/src/mock.rs | 5 +- pallets/parachain-staking/migrations.md | 14 + pallets/parachain-staking/src/benchmarks.rs | 2011 ++-- pallets/parachain-staking/src/inflation.rs | 300 +- pallets/parachain-staking/src/lib.rs | 5154 ++++++---- pallets/parachain-staking/src/mock.rs | 753 +- pallets/parachain-staking/src/set.rs | 100 +- pallets/parachain-staking/src/tests.rs | 9561 ++++++++++++------- pallets/parachain-staking/src/weights.rs | 661 +- 10 files changed, 11645 insertions(+), 7006 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48cbcd3d..9d291b95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1569,7 +1569,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-overseer", "polkadot-primitives", - "rand 0.8.4", + "rand 0.8.5", "sc-client-api", "sc-consensus", "sp-api", @@ -2357,7 +2357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" dependencies = [ "byteorder", - "rand 0.8.4", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -3102,9 +3102,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.16" +version = "0.14.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" +checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd" dependencies = [ "bytes 1.1.0", "futures-channel", @@ -3115,7 +3115,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 0.4.8", + "itoa 1.0.1", "pin-project-lite 0.2.8", "socket2 0.4.4", "tokio", @@ -3842,9 +3842,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" [[package]] name = "libloading" @@ -3937,7 +3937,7 @@ dependencies = [ "pin-project 1.0.10", "prost", "prost-build", - "rand 0.8.4", + "rand 0.8.5", "ring", "rw-stream-sink", "sha2 0.9.9", @@ -4075,7 +4075,7 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "rand 0.8.4", + "rand 0.8.5", "smallvec 1.8.0", "socket2 0.4.4", "void", @@ -4127,7 +4127,7 @@ dependencies = [ "log", "prost", "prost-build", - "rand 0.8.4", + "rand 0.8.5", "sha2 0.9.9", "snow", "static_assertions", @@ -4218,7 +4218,7 @@ dependencies = [ "log", "prost", "prost-build", - "rand 0.8.4", + "rand 0.8.5", "sha2 0.9.9", "thiserror", "unsigned-varint 0.7.1", @@ -4389,7 +4389,7 @@ dependencies = [ "libsecp256k1-core 0.3.0", "libsecp256k1-gen-ecmult 0.3.0", "libsecp256k1-gen-genmult 0.3.0", - "rand 0.8.4", + "rand 0.8.5", "serde", "sha2 0.9.9", "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4722,7 +4722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd2c2cc134e57461f0898b0e921f0a7819b5e3f3a4335b9aa390ce81a5f36fb9" dependencies = [ "futures 0.3.21", - "rand 0.8.4", + "rand 0.8.5", "thrift", ] @@ -5053,7 +5053,7 @@ dependencies = [ "num-complex", "num-rational 0.4.0", "num-traits", - "rand 0.8.4", + "rand 0.8.5", "rand_distr", "simba", "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5076,7 +5076,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a8690bf09abf659851e58cd666c3d37ac6af07c2bd7a9e332cfba471715775" dependencies = [ - "rand 0.8.4", + "rand 0.8.5", ] [[package]] @@ -5164,9 +5164,9 @@ dependencies = [ [[package]] name = "ntapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" dependencies = [ "winapi 0.3.9", ] @@ -6409,7 +6409,7 @@ dependencies = [ "lz4", "memmap2 0.2.3", "parking_lot 0.11.2", - "rand 0.8.4", + "rand 0.8.5", "snap", ] @@ -6819,7 +6819,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.4", + "rand 0.8.5", "sp-core 4.1.0-dev", "sp-keystore 0.10.0", "thiserror", @@ -6840,7 +6840,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.4", + "rand 0.8.5", "sc-network", "thiserror", "tracing", @@ -6982,7 +6982,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.4", + "rand 0.8.5", "rand_chacha 0.3.1", "sc-network", "sp-application-crypto", @@ -7206,7 +7206,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.4", + "rand 0.8.5", "thiserror", "tracing", ] @@ -7227,7 +7227,7 @@ dependencies = [ "polkadot-core-primitives", "polkadot-node-subsystem-util", "polkadot-parachain", - "rand 0.8.4", + "rand 0.8.5", "sc-executor", "sc-executor-common", "sc-executor-wasmtime", @@ -7401,7 +7401,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-overseer", "polkadot-primitives", - "rand 0.8.4", + "rand 0.8.5", "sp-application-crypto", "sp-core 4.1.0-dev", "sp-keystore 0.10.0", @@ -7729,7 +7729,7 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "polkadot-runtime-metrics", - "rand 0.8.4", + "rand 0.8.5", "rand_chacha 0.3.1", "rustc-hex", "scale-info", @@ -8286,20 +8286,19 @@ dependencies = [ "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc 0.2.0", + "rand_hc", "rand_pcg", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", "rand_core 0.6.3", - "rand_hc 0.3.1", ] [[package]] @@ -8347,7 +8346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand 0.8.4", + "rand 0.8.5", ] [[package]] @@ -8359,15 +8358,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - [[package]] name = "rand_pcg" version = "0.2.1" @@ -9319,7 +9309,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.11.2", - "rand 0.8.4", + "rand 0.8.5", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -10000,9 +9990,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa 1.0.1", "ryu", @@ -10220,7 +10210,7 @@ dependencies = [ "aes-gcm", "blake2", "chacha20poly1305", - "rand 0.8.4", + "rand 0.8.5", "rand_core 0.6.3", "ring", "rustc_version 0.3.3", @@ -10262,7 +10252,7 @@ dependencies = [ "futures 0.3.21", "httparse", "log", - "rand 0.8.4", + "rand 0.8.5", "sha-1 0.9.8", ] @@ -11267,9 +11257,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "ss58-registry" -version = "1.12.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8319f44e20b42e5c11b88b1ad4130c35fe2974665a007b08b02322070177136a" +checksum = "d8cb4b9ce18beb6cb16ecad62d936245cef5212ddc8e094d7417a75e8d0e85f5" dependencies = [ "Inflector", "proc-macro2", @@ -11326,7 +11316,7 @@ dependencies = [ "lazy_static", "nalgebra", "num-traits", - "rand 0.8.4", + "rand 0.8.5", ] [[package]] @@ -11945,7 +11935,7 @@ dependencies = [ "ipnet", "lazy_static", "log", - "rand 0.8.4", + "rand 0.8.5", "smallvec 1.8.0", "thiserror", "tinyvec", @@ -12015,7 +12005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0" dependencies = [ "cfg-if 1.0.0", - "rand 0.8.4", + "rand 0.8.5", "static_assertions", ] @@ -12516,7 +12506,7 @@ dependencies = [ "mach", "memoffset", "more-asserts", - "rand 0.8.4", + "rand 0.8.5", "region", "rustix", "thiserror", @@ -12864,7 +12854,7 @@ dependencies = [ "log", "nohash-hasher", "parking_lot 0.11.2", - "rand 0.8.4", + "rand 0.8.5", "static_assertions", ] diff --git a/pallets/groupsign/src/mock.rs b/pallets/groupsign/src/mock.rs index 987d5f1e..41e27792 100644 --- a/pallets/groupsign/src/mock.rs +++ b/pallets/groupsign/src/mock.rs @@ -1,6 +1,6 @@ use crate::{self as groupsign, weights::PontemWeights}; use codec::{Decode, Encode}; -use frame_support::parameter_types; +use frame_support::{parameter_types, traits::ConstU32}; use frame_system as system; use scale_info::TypeInfo; use sp_core::{H256, sr25519}; @@ -54,6 +54,7 @@ impl system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<12>; } impl groupsign::Config for Test { @@ -67,7 +68,7 @@ impl groupsign::Config for Test { type Signature = AnySignature; } -#[derive(Eq, PartialEq, Clone, Default, Encode, Decode, TypeInfo, Debug)] +#[derive(Eq, PartialEq, Clone, Encode, Decode, TypeInfo, Debug)] pub struct AnySignature(sr25519::Signature); impl Verify for AnySignature { diff --git a/pallets/parachain-staking/migrations.md b/pallets/parachain-staking/migrations.md index 62b05a35..184693fa 100644 --- a/pallets/parachain-staking/migrations.md +++ b/pallets/parachain-staking/migrations.md @@ -1,5 +1,19 @@ # Migration History +## Increase max delegations per candidate + +- [Migration PR `#1096`](https://github.com/PureStake/moonbeam/pull/1096) +- [Migratio bugfix `#1112`](https://github.com/PureStake/moonbeam/pull/1112) + +## Manual Exits and Patch Lack of Delay for bond\_{more, less} + +- [Migration PR `#810`](https://github.com/PureStake/moonbeam/pull/810) +- [Migration Removal PR `#?`]() + +## Purge Stale Storage + +- [Migration PR `#970`](https://github.com/PureStake/moonbeam/pull/970) + ## Delay nominator exits by changing NominatorState and ExitQueue - [Migration PR `#610`](https://github.com/PureStake/moonbeam/pull/610) diff --git a/pallets/parachain-staking/src/benchmarks.rs b/pallets/parachain-staking/src/benchmarks.rs index 7575fc4b..6e0da6fa 100644 --- a/pallets/parachain-staking/src/benchmarks.rs +++ b/pallets/parachain-staking/src/benchmarks.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2021 PureStake Inc. +// Copyright 2019-2022 PureStake Inc. // This file is part of Moonbeam. // Moonbeam is free software: you can redistribute it and/or modify @@ -17,7 +17,10 @@ #![cfg(feature = "runtime-benchmarks")] //! Benchmarking -use crate::{BalanceOf, Call, Config, Pallet, Range}; +use crate::{ + BalanceOf, Call, CandidateBondLessRequest, Config, DelegationChange, DelegationRequest, Pallet, + Range, +}; use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite}; use frame_support::traits::{Currency, Get, OnFinalize, OnInitialize, ReservableCurrency}; use frame_system::RawOrigin; @@ -25,720 +28,1338 @@ use nimbus_primitives::EventHandler; use sp_runtime::{Perbill, Percent}; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; -/// Default balance amount is minimum collator stake -fn default_balance() -> BalanceOf { - <::MinCollatorStk as Get>>::get() +/// Minimum collator candidate stake +fn min_candidate_stk() -> BalanceOf { + <::MinCollatorStk as Get>>::get() +} + +/// Minimum delegator stake +fn min_delegator_stk() -> BalanceOf { + <::MinDelegatorStk as Get>>::get() } /// Create a funded user. +/// Extra + min_candidate_stk is total minted funds +/// Returns tuple (id, balance) fn create_funded_user( - string: &'static str, - n: u32, - extra: BalanceOf, -) -> T::AccountId { - const SEED: u32 = 0; - let user = account(string, n, SEED); - let default_balance = default_balance::(); - let total = default_balance + extra; - T::Currency::make_free_balance_be(&user, total); - T::Currency::issue(total); - user + string: &'static str, + n: u32, + extra: BalanceOf, +) -> (T::AccountId, BalanceOf) { + const SEED: u32 = 0; + let user = account(string, n, SEED); + let min_candidate_stk = min_candidate_stk::(); + let total = min_candidate_stk + extra; + T::Currency::make_free_balance_be(&user, total); + T::Currency::issue(total); + (user, total) } -/// Create a funded nominator. Base balance is MinCollatorStk == default_balance -/// but the amount for the nomination is MinNominatorStk << MinCollatorStk => the rest + extra -/// is free balance for the returned account. -fn create_funded_nominator( - string: &'static str, - n: u32, - extra: BalanceOf, - collator: T::AccountId, - collator_nominator_count: u32, +/// Create a funded delegator. +fn create_funded_delegator( + string: &'static str, + n: u32, + extra: BalanceOf, + collator: T::AccountId, + min_bond: bool, + collator_delegator_count: u32, ) -> Result { - let user = create_funded_user::(string, n, extra); - Pallet::::nominate( - RawOrigin::Signed(user.clone()).into(), - collator, - <::MinNominatorStk as Get>>::get(), - collator_nominator_count, - 0u32, // first nomination for all calls - )?; - Ok(user) + let (user, total) = create_funded_user::(string, n, extra); + let bond = if min_bond { + min_delegator_stk::() + } else { + total + }; + Pallet::::delegate( + RawOrigin::Signed(user.clone()).into(), + collator, + bond, + collator_delegator_count, + 0u32, // first delegation for all calls + )?; + Ok(user) } -/// Create a funded collator. Base amount is MinCollatorStk == default_balance but the -/// last parameter `extra` represents how much additional balance is minted to the collator. +/// Create a funded collator. fn create_funded_collator( - string: &'static str, - n: u32, - extra: BalanceOf, - candidate_count: u32, + string: &'static str, + n: u32, + extra: BalanceOf, + min_bond: bool, + candidate_count: u32, ) -> Result { - let user = create_funded_user::(string, n, extra); - Pallet::::join_candidates( - RawOrigin::Signed(user.clone()).into(), - default_balance::(), - candidate_count, - )?; - Ok(user) + let (user, total) = create_funded_user::(string, n, extra); + let bond = if min_bond { + min_candidate_stk::() + } else { + total + }; + Pallet::::join_candidates( + RawOrigin::Signed(user.clone()).into(), + bond, + candidate_count, + )?; + Ok(user) +} + +/// Run to end block and author +fn roll_to_and_author(round_delay: u32, author: T::AccountId) { + let total_rounds = round_delay + 1u32; + let round_length: T::BlockNumber = Pallet::::round().length.into(); + let mut now = >::block_number() + 1u32.into(); + let end = Pallet::::round().first + (round_length * total_rounds.into()); + while now < end { + Pallet::::note_author(author.clone()); + >::on_finalize(>::block_number()); + >::set_block_number( + >::block_number() + 1u32.into(), + ); + >::on_initialize(>::block_number()); + Pallet::::on_initialize(>::block_number()); + now += 1u32.into(); + } } const USER_SEED: u32 = 999666; benchmarks! { - // MONETARY ORIGIN DISPATCHABLES - - set_staking_expectations { - let stake_range: Range> = Range { - min: 100u32.into(), - ideal: 200u32.into(), - max: 300u32.into(), - }; - }: _(RawOrigin::Root, stake_range) - verify { - assert_eq!(Pallet::::inflation_config().expect, stake_range); - } - - set_inflation { - let inflation_range: Range = Range { - min: Perbill::from_perthousand(1), - ideal: Perbill::from_perthousand(2), - max: Perbill::from_perthousand(3), - }; - - }: _(RawOrigin::Root, inflation_range) - verify { - assert_eq!(Pallet::::inflation_config().annual, inflation_range); - } - - set_parachain_bond_account { - let parachain_bond_account: T::AccountId = account("TEST", 0u32, USER_SEED); - }: _(RawOrigin::Root, parachain_bond_account.clone()) - verify { - assert_eq!(Pallet::::parachain_bond_info().account, parachain_bond_account); - } - - set_parachain_bond_reserve_percent { - }: _(RawOrigin::Root, Percent::from_percent(33)) - verify { - assert_eq!(Pallet::::parachain_bond_info().percent, Percent::from_percent(33)); - } - - // ROOT DISPATCHABLES - - set_total_selected {}: _(RawOrigin::Root, 100u32) - verify { - assert_eq!(Pallet::::total_selected(), 100u32); - } - - set_collator_commission {}: _(RawOrigin::Root, Perbill::from_percent(33)) - verify { - assert_eq!(Pallet::::collator_commission(), Perbill::from_percent(33)); - } - - set_blocks_per_round {}: _(RawOrigin::Root, 1200u32) - verify { - assert_eq!(Pallet::::round().length, 1200u32); - } - - // USER DISPATCHABLES - - join_candidates { - let x in 3..1_000; - // Worst Case Complexity is insertion into an ordered list so \exists full list before call - let mut candidate_count = 1u32; - for i in 2..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - candidate_count - )?; - candidate_count += 1u32; - } - let caller: T::AccountId = create_funded_user::("caller", USER_SEED, 0u32.into()); - }: _(RawOrigin::Signed(caller.clone()), default_balance::(), candidate_count) - verify { - assert!(Pallet::::is_candidate(&caller)); - } - - // This call schedules the collator's exit and removes them from the candidate pool - // -> it retains the self-bond and nominator bonds - leave_candidates { - let x in 3..1_000; - // Worst Case Complexity is removal from an ordered list so \exists full list before call - let mut candidate_count = 1u32; - for i in 2..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - candidate_count - )?; - candidate_count += 1u32; - } - let caller: T::AccountId = create_funded_collator::( - "caller", - USER_SEED, - 0u32.into(), - candidate_count, - )?; - candidate_count += 1u32; - }: _(RawOrigin::Signed(caller.clone()), candidate_count) - verify { - assert!(Pallet::::collator_state2(&caller).unwrap().is_leaving()); - } - - go_offline { - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - 1u32 - )?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert!(!Pallet::::collator_state2(&caller).unwrap().is_active()); - } - - go_online { - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - 1u32 - )?; - Pallet::::go_offline(RawOrigin::Signed(caller.clone()).into())?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert!(Pallet::::collator_state2(&caller).unwrap().is_active()); - } - - candidate_bond_more { - let balance = default_balance::(); - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - balance, - 1u32, - )?; - }: _(RawOrigin::Signed(caller.clone()), balance) - verify { - let expected_bond = balance * 2u32.into(); - assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); - } - - candidate_bond_less { - let balance = default_balance::(); - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - balance, - 1u32, - )?; - Pallet::::candidate_bond_more(RawOrigin::Signed(caller.clone()).into(), balance)?; - }: _(RawOrigin::Signed(caller.clone()), balance) - verify { - assert_eq!(T::Currency::reserved_balance(&caller), balance); - } - - nominate { - let max_nominations = <::MaxCollatorsPerNominator as Get>::get(); - let max_nominators = <::MaxNominatorsPerCollator as Get>::get(); - let x in 3..<::MaxCollatorsPerNominator as Get>::get(); - let y in 2..<::MaxNominatorsPerCollator as Get>::get(); - // Worst Case is full of nominations before calling `nominate` - let mut collators: Vec = Vec::new(); - // Initialize MaxCollatorsPerNominator collator candidates - for i in 2..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - collators.len() as u32 + 1u32, - )?; - collators.push(collator.clone()); - } - let bond = <::MinNominatorStk as Get>>::get(); - let extra = if (bond * (collators.len() as u32 + 1u32).into()) > default_balance::() { - (bond * (collators.len() as u32 + 1u32).into()) - default_balance::() - } else { - 0u32.into() - }; - let caller: T::AccountId = create_funded_user::("caller", USER_SEED, extra.into()); - // Nomination count - let mut nom_nom_count = 0u32; - // Nominate MaxCollatorsPerNominators collator candidates - for col in collators.clone() { - Pallet::::nominate( - RawOrigin::Signed(caller.clone()).into(), col, bond, 0u32, nom_nom_count - )?; - nom_nom_count += 1u32; - } - // Last collator to be nominated - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - collators.len() as u32 + 1u32, - )?; - // Worst Case Complexity is insertion into an almost full collator - let mut col_nom_count = 0u32; - for i in 1..y { - let seed = USER_SEED + i; - let nominator = create_funded_nominator::( - "nominator", - seed, - 0u32.into(), - collator.clone(), - col_nom_count, - )?; - col_nom_count += 1u32; - } - }: _(RawOrigin::Signed(caller.clone()), collator, bond, col_nom_count, nom_nom_count) - verify { - assert!(Pallet::::is_nominator(&caller)); - } - - leave_nominators { - let x in 2..<::MaxCollatorsPerNominator as Get>::get(); - // Worst Case is full of nominations before exit - let mut collators: Vec = Vec::new(); - // Initialize MaxCollatorsPerNominator collator candidates - for i in 1..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - collators.len() as u32 + 1u32 - )?; - collators.push(collator.clone()); - } - let bond = <::MinNominatorStk as Get>>::get(); - let need = bond * (collators.len() as u32).into(); - let default_minted = default_balance::(); - let need: BalanceOf = if need > default_minted { - need - default_minted - } else { - 0u32.into() - }; - // Fund the nominator - let caller: T::AccountId = create_funded_user::("caller", USER_SEED, need); - let nomination_count = collators.len() as u32; - // Nomination count - let mut nom_count = 0u32; - // Nominate MaxCollatorsPerNominators collator candidates - for col in collators { - Pallet::::nominate( - RawOrigin::Signed(caller.clone()).into(), - col, - bond, - 0u32, - nom_count - )?; - nom_count += 1u32; - } - }: _(RawOrigin::Signed(caller.clone()), nomination_count) - verify { - assert!(Pallet::::nominator_state2(&caller).unwrap().is_leaving()); - } - - revoke_nomination { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - 1u32 - )?; - let caller: T::AccountId = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinNominatorStk as Get>>::get(); - Pallet::::nominate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - }: _(RawOrigin::Signed(caller.clone()), collator.clone()) - verify { - assert_eq!( - Pallet::::nominator_state2(&caller).unwrap().revocations.0[0], - collator - ); - } - - nominator_bond_more { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - 1u32 - )?; - let caller: T::AccountId = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinNominatorStk as Get>>::get(); - Pallet::::nominate( - RawOrigin::Signed(caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - }: _(RawOrigin::Signed(caller.clone()), collator, bond) - verify { - let expected_bond = bond * 2u32.into(); - assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); - } - - nominator_bond_less { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - 1u32 - )?; - let caller: T::AccountId = create_funded_user::("caller", USER_SEED, 0u32.into()); - let total = default_balance::(); - Pallet::::nominate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - total, - 0u32, - 0u32 - )?; - let bond_less = <::MinNominatorStk as Get>>::get(); - }: _(RawOrigin::Signed(caller.clone()), collator, bond_less) - verify { - let expected = total - bond_less; - assert_eq!(T::Currency::reserved_balance(&caller), expected); - } - - // ON_INITIALIZE - - active_on_initialize { - // TOTAL SELECTED COLLATORS PER ROUND - let x in 1..28; - // NOMINATIONS - let y in 0..(<::MaxNominatorsPerCollator as Get>::get() * 28); - let max_nominators_per_collator = - <::MaxNominatorsPerCollator as Get>::get(); - let max_nominations = x * max_nominators_per_collator; - // y should depend on x but cannot directly, we overwrite y here if necessary to bound it - let total_nominations: u32 = if max_nominations < y { max_nominations } else { y }; - // INITIALIZE RUNTIME STATE - let high_inflation: Range = Range { - min: Perbill::one(), - ideal: Perbill::one(), - max: Perbill::one(), - }; - Pallet::::set_inflation(RawOrigin::Root.into(), high_inflation.clone())?; - Pallet::::set_total_selected(RawOrigin::Root.into(), 28u32)?; - // INITIALIZE COLLATOR STATE - let mut collators: Vec = Vec::new(); - let mut collator_count = 1u32; - for i in 0..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - default_balance::() * 1_000_000u32.into(), - collator_count - )?; - collators.push(collator); - collator_count += 1u32; - } - // STORE starting balances for all collators - let collator_starting_balances: Vec<( - T::AccountId, - <::Currency as Currency>::Balance - )> = collators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); - // INITIALIZE NOMINATIONS - let mut col_nom_count: BTreeMap = BTreeMap::new(); - collators.iter().for_each(|x| { - col_nom_count.insert(x.clone(), 0u32); - }); - let mut nominators: Vec = Vec::new(); - let mut remaining_nominations = if total_nominations > max_nominators_per_collator { - for j in 1..(max_nominators_per_collator + 1) { - let seed = USER_SEED + j; - let nominator = create_funded_nominator::( - "nominator", - seed, - default_balance::() * 1_000_000u32.into(), - collators[0].clone(), - nominators.len() as u32, - )?; - nominators.push(nominator); - } - total_nominations - max_nominators_per_collator - } else { - for j in 1..(total_nominations + 1) { - let seed = USER_SEED + j; - let nominator = create_funded_nominator::( - "nominator", - seed, - default_balance::() * 1_000_000u32.into(), - collators[0].clone(), - nominators.len() as u32, - )?; - nominators.push(nominator); - } - 0u32 - }; - col_nom_count.insert(collators[0].clone(), nominators.len() as u32); - // FILL remaining nominations - if remaining_nominations > 0 { - for (col, n_count) in col_nom_count.iter_mut() { - if n_count < &mut (nominators.len() as u32) { - // assumes nominators.len() <= MaxNominatorsPerCollator - let mut open_spots = nominators.len() as u32 - *n_count; - while open_spots > 0 && remaining_nominations > 0 { - let caller = nominators[open_spots as usize - 1usize].clone(); - if let Ok(_) = Pallet::::nominate(RawOrigin::Signed( - caller.clone()).into(), - col.clone(), - <::MinNominatorStk as Get>>::get(), - *n_count, - collators.len() as u32, // overestimate - ) { - *n_count += 1; - remaining_nominations -= 1; - } - open_spots -= 1; - } - } - if remaining_nominations == 0 { - break; - } - } - } - // STORE starting balances for all nominators - let nominator_starting_balances: Vec<( - T::AccountId, - <::Currency as Currency>::Balance - )> = nominators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); - // PREPARE RUN_TO_BLOCK LOOP - let before_running_round_index = Pallet::::round().current; - let round_length: T::BlockNumber = Pallet::::round().length.into(); - let reward_delay = <::RewardPaymentDelay as Get>::get() + 2u32; - let mut now = >::block_number() + 1u32.into(); - let mut counter = 0usize; - let end = Pallet::::round().first + (round_length * reward_delay.into()); - // SET collators as authors for blocks from now - end - while now < end { - let author = collators[counter % collators.len()].clone(); - Pallet::::note_author(author); - >::on_finalize(>::block_number()); - >::set_block_number( - >::block_number() + 1u32.into() - ); - >::on_initialize(>::block_number()); - Pallet::::on_initialize(>::block_number()); - now += 1u32.into(); - counter += 1usize; - } - Pallet::::note_author(collators[counter % collators.len()].clone()); - >::on_finalize(>::block_number()); - >::set_block_number( - >::block_number() + 1u32.into() - ); - >::on_initialize(>::block_number()); - }: { Pallet::::on_initialize(>::block_number()); } - verify { - // Collators have been paid - for (col, initial) in collator_starting_balances { - assert!(T::Currency::free_balance(&col) > initial); - } - // Nominators have been paid - for (col, initial) in nominator_starting_balances { - assert!(T::Currency::free_balance(&col) > initial); - } - // Round transitions - assert_eq!(Pallet::::round().current, before_running_round_index + reward_delay); - } - - passive_on_initialize { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - 1u32 - )?; - let start = >::block_number(); - Pallet::::note_author(collator.clone()); - >::on_finalize(start); - >::set_block_number( - start + 1u32.into() - ); - let end = >::block_number(); - >::on_initialize(end); - }: { Pallet::::on_initialize(end); } - verify { - // Round transitions - assert_eq!(start + 1u32.into(), end); - } + // HOTFIX BENCHMARK + hotfix_remove_delegation_requests { + let x in 2..<::MaxTopDelegationsPerCandidate as Get>::get() + + <::MaxBottomDelegationsPerCandidate as Get>::get(); + let mut delegators: Vec = Vec::new(); + let collator = create_funded_collator::( + "candidate", + 100, + 0u32.into(), + true, + 1u32 + )?; + let mut col_del_count = 0u32; + for i in 1..x { + let seed = USER_SEED + i; + let delegator = create_funded_delegator::( + "delegator", + seed, + 0u32.into(), + collator.clone(), + true, + col_del_count, + )?; + delegators.push(delegator); + col_del_count += 1u32; + } + }: _(RawOrigin::Root, delegators) + verify { } + + hotfix_update_candidate_pool_value { + let x in 5..200; + let mut candidates: Vec = Vec::new(); + for i in 1..x { + let account = create_funded_collator::( + "candidate", + i + 100, + 0u32.into(), + true, + i + )?; + candidates.push(account); + } + }: _(RawOrigin::Root, candidates) + verify { } + + // MONETARY ORIGIN DISPATCHABLES + + set_staking_expectations { + let stake_range: Range> = Range { + min: 100u32.into(), + ideal: 200u32.into(), + max: 300u32.into(), + }; + }: _(RawOrigin::Root, stake_range) + verify { + assert_eq!(Pallet::::inflation_config().expect, stake_range); + } + + set_inflation { + let inflation_range: Range = Range { + min: Perbill::from_perthousand(1), + ideal: Perbill::from_perthousand(2), + max: Perbill::from_perthousand(3), + }; + + }: _(RawOrigin::Root, inflation_range) + verify { + assert_eq!(Pallet::::inflation_config().annual, inflation_range); + } + + set_parachain_bond_account { + let parachain_bond_account: T::AccountId = account("TEST", 0u32, USER_SEED); + }: _(RawOrigin::Root, parachain_bond_account.clone()) + verify { + assert_eq!(Pallet::::parachain_bond_info().account, parachain_bond_account); + } + + set_parachain_bond_reserve_percent { + }: _(RawOrigin::Root, Percent::from_percent(33)) + verify { + assert_eq!(Pallet::::parachain_bond_info().percent, Percent::from_percent(33)); + } + + // ROOT DISPATCHABLES + + set_total_selected { + Pallet::::set_blocks_per_round(RawOrigin::Root.into(), 100u32)?; + }: _(RawOrigin::Root, 100u32) + verify { + assert_eq!(Pallet::::total_selected(), 100u32); + } + + set_collator_commission {}: _(RawOrigin::Root, Perbill::from_percent(33)) + verify { + assert_eq!(Pallet::::collator_commission(), Perbill::from_percent(33)); + } + + set_blocks_per_round {}: _(RawOrigin::Root, 1200u32) + verify { + assert_eq!(Pallet::::round().length, 1200u32); + } + + // USER DISPATCHABLES + + join_candidates { + let x in 3..1_000; + // Worst Case Complexity is insertion into an ordered list so \exists full list before call + let mut candidate_count = 1u32; + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + candidate_count + )?; + candidate_count += 1u32; + } + let (caller, min_candidate_stk) = create_funded_user::("caller", USER_SEED, 0u32.into()); + }: _(RawOrigin::Signed(caller.clone()), min_candidate_stk, candidate_count) + verify { + assert!(Pallet::::is_candidate(&caller)); + } + + // This call schedules the collator's exit and removes them from the candidate pool + // -> it retains the self-bond and delegator bonds + schedule_leave_candidates { + let x in 3..1_000; + // Worst Case Complexity is removal from an ordered list so \exists full list before call + let mut candidate_count = 1u32; + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + candidate_count + )?; + candidate_count += 1u32; + } + let caller: T::AccountId = create_funded_collator::( + "caller", + USER_SEED, + 0u32.into(), + true, + candidate_count, + )?; + candidate_count += 1u32; + }: _(RawOrigin::Signed(caller.clone()), candidate_count) + verify { + assert!(Pallet::::candidate_info(&caller).unwrap().is_leaving()); + } + + execute_leave_candidates { + // x is total number of delegations for the candidate + let x in 2..(<::MaxTopDelegationsPerCandidate as Get>::get() + + <::MaxBottomDelegationsPerCandidate as Get>::get()); + let candidate: T::AccountId = create_funded_collator::( + "unique_caller", + USER_SEED - 100, + 0u32.into(), + true, + 1u32, + )?; + // 2nd delegation required for all delegators to ensure DelegatorState updated not removed + let second_candidate: T::AccountId = create_funded_collator::( + "unique__caller", + USER_SEED - 99, + 0u32.into(), + true, + 2u32, + )?; + let mut delegators: Vec = Vec::new(); + let mut col_del_count = 0u32; + for i in 1..x { + let seed = USER_SEED + i; + let delegator = create_funded_delegator::( + "delegator", + seed, + min_delegator_stk::(), + candidate.clone(), + true, + col_del_count, + )?; + Pallet::::delegate( + RawOrigin::Signed(delegator.clone()).into(), + second_candidate.clone(), + min_delegator_stk::(), + col_del_count, + 1u32, + )?; + Pallet::::schedule_revoke_delegation( + RawOrigin::Signed(delegator.clone()).into(), + candidate.clone() + )?; + delegators.push(delegator); + col_del_count += 1u32; + } + Pallet::::schedule_leave_candidates( + RawOrigin::Signed(candidate.clone()).into(), + 3u32 + )?; + roll_to_and_author::(2, candidate.clone()); + }: _(RawOrigin::Signed(candidate.clone()), candidate.clone(), col_del_count) + verify { + assert!(Pallet::::candidate_info(&candidate).is_none()); + assert!(Pallet::::candidate_info(&second_candidate).is_some()); + for delegator in delegators { + assert!(Pallet::::is_delegator(&delegator)); + } + } + + cancel_leave_candidates { + let x in 3..1_000; + // Worst Case Complexity is removal from an ordered list so \exists full list before call + let mut candidate_count = 1u32; + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + candidate_count + )?; + candidate_count += 1u32; + } + let caller: T::AccountId = create_funded_collator::( + "caller", + USER_SEED, + 0u32.into(), + true, + candidate_count, + )?; + candidate_count += 1u32; + Pallet::::schedule_leave_candidates( + RawOrigin::Signed(caller.clone()).into(), + candidate_count + )?; + candidate_count -= 1u32; + }: _(RawOrigin::Signed(caller.clone()), candidate_count) + verify { + assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); + } + + go_offline { + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(!Pallet::::candidate_info(&caller).unwrap().is_active()); + } + + go_online { + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + Pallet::::go_offline(RawOrigin::Signed(caller.clone()).into())?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); + } + + candidate_bond_more { + let more = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + more, + true, + 1u32, + )?; + }: _(RawOrigin::Signed(caller.clone()), more) + verify { + let expected_bond = more * 2u32.into(); + assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); + } + + schedule_candidate_bond_less { + let min_candidate_stk = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + min_candidate_stk, + false, + 1u32, + )?; + }: _(RawOrigin::Signed(caller.clone()), min_candidate_stk) + verify { + let state = Pallet::::candidate_info(&caller).expect("request bonded less so exists"); + assert_eq!( + state.request, + Some(CandidateBondLessRequest { + amount: min_candidate_stk, + when_executable: 3, + }) + ); + } + + execute_candidate_bond_less { + let min_candidate_stk = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + min_candidate_stk, + false, + 1u32, + )?; + Pallet::::schedule_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + min_candidate_stk + )?; + roll_to_and_author::(2, caller.clone()); + }: { + Pallet::::execute_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + caller.clone() + )?; + } verify { + assert_eq!(T::Currency::reserved_balance(&caller), min_candidate_stk); + } + + cancel_candidate_bond_less { + let min_candidate_stk = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + min_candidate_stk, + false, + 1u32, + )?; + Pallet::::schedule_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + min_candidate_stk + )?; + }: { + Pallet::::cancel_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + )?; + } verify { + assert!( + Pallet::::candidate_info(&caller).unwrap().request.is_none() + ); + } + + delegate { + let x in 3..<::MaxDelegationsPerDelegator as Get>::get(); + let y in 2..<::MaxTopDelegationsPerCandidate as Get>::get(); + // Worst Case is full of delegations before calling `delegate` + let mut collators: Vec = Vec::new(); + // Initialize MaxDelegationsPerDelegator collator candidates + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + collators.len() as u32 + 1u32, + )?; + collators.push(collator.clone()); + } + let bond = <::MinDelegatorStk as Get>>::get(); + let extra = if (bond * (collators.len() as u32 + 1u32).into()) > min_candidate_stk::() { + (bond * (collators.len() as u32 + 1u32).into()) - min_candidate_stk::() + } else { + 0u32.into() + }; + let (caller, _) = create_funded_user::("caller", USER_SEED, extra.into()); + // Delegation count + let mut del_del_count = 0u32; + // Nominate MaxDelegationsPerDelegators collator candidates + for col in collators.clone() { + Pallet::::delegate( + RawOrigin::Signed(caller.clone()).into(), col, bond, 0u32, del_del_count + )?; + del_del_count += 1u32; + } + // Last collator to be delegated + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + collators.len() as u32 + 1u32, + )?; + // Worst Case Complexity is insertion into an almost full collator + let mut col_del_count = 0u32; + for i in 1..y { + let seed = USER_SEED + i; + let _ = create_funded_delegator::( + "delegator", + seed, + 0u32.into(), + collator.clone(), + true, + col_del_count, + )?; + col_del_count += 1u32; + } + }: _(RawOrigin::Signed(caller.clone()), collator, bond, col_del_count, del_del_count) + verify { + assert!(Pallet::::is_delegator(&caller)); + } + + schedule_leave_delegators { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(Pallet::::delegator_state(&caller).unwrap().is_leaving()); + } + + execute_leave_delegators { + let x in 2..<::MaxDelegationsPerDelegator as Get>::get(); + // Worst Case is full of delegations before execute exit + let mut collators: Vec = Vec::new(); + // Initialize MaxDelegationsPerDelegator collator candidates + for i in 1..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + collators.len() as u32 + 1u32 + )?; + collators.push(collator.clone()); + } + let bond = <::MinDelegatorStk as Get>>::get(); + let need = bond * (collators.len() as u32).into(); + let default_minted = min_candidate_stk::(); + let need: BalanceOf = if need > default_minted { + need - default_minted + } else { + 0u32.into() + }; + // Fund the delegator + let (caller, _) = create_funded_user::("caller", USER_SEED, need); + // Delegation count + let mut delegation_count = 0u32; + let author = collators[0].clone(); + // Nominate MaxDelegationsPerDelegators collator candidates + for col in collators { + Pallet::::delegate( + RawOrigin::Signed(caller.clone()).into(), + col, + bond, + 0u32, + delegation_count + )?; + delegation_count += 1u32; + } + Pallet::::schedule_leave_delegators(RawOrigin::Signed(caller.clone()).into())?; + roll_to_and_author::(2, author); + }: _(RawOrigin::Signed(caller.clone()), caller.clone(), delegation_count) + verify { + assert!(Pallet::::delegator_state(&caller).is_none()); + } + + cancel_leave_delegators { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + Pallet::::schedule_leave_delegators(RawOrigin::Signed(caller.clone()).into())?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(Pallet::::delegator_state(&caller).unwrap().is_active()); + } + + schedule_revoke_delegation { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + }: _(RawOrigin::Signed(caller.clone()), collator.clone()) + verify { + assert_eq!( + Pallet::::delegator_state(&caller).unwrap().requests().get(&collator), + Some(&DelegationRequest { + collator, + amount: bond, + when_executable: 3, + action: DelegationChange::Revoke + }) + ); + } + + delegator_bond_more { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate( + RawOrigin::Signed(caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + }: _(RawOrigin::Signed(caller.clone()), collator.clone(), bond) + verify { + let expected_bond = bond * 2u32.into(); + assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); + } + + schedule_delegator_bond_less { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + total, + 0u32, + 0u32 + )?; + let bond_less = <::MinDelegatorStk as Get>>::get(); + }: _(RawOrigin::Signed(caller.clone()), collator.clone(), bond_less) + verify { + let state = Pallet::::delegator_state(&caller) + .expect("just request bonded less so exists"); + assert_eq!( + state.requests().get(&collator), + Some(&DelegationRequest { + collator, + amount: 5u32.into(), + when_executable: 3, + action: DelegationChange::Decrease + }) + ); + } + + execute_revoke_delegation { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + Pallet::::schedule_revoke_delegation(RawOrigin::Signed( + caller.clone()).into(), + collator.clone() + )?; + roll_to_and_author::(2, collator.clone()); + }: { + Pallet::::execute_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + caller.clone(), + collator.clone() + )?; + } verify { + assert!( + !Pallet::::is_delegator(&caller) + ); + } + + execute_delegator_bond_less { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + total, + 0u32, + 0u32 + )?; + let bond_less = <::MinDelegatorStk as Get>>::get(); + Pallet::::schedule_delegator_bond_less( + RawOrigin::Signed(caller.clone()).into(), + collator.clone(), + bond_less + )?; + roll_to_and_author::(2, collator.clone()); + }: { + Pallet::::execute_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + caller.clone(), + collator.clone() + )?; + } verify { + let expected = total - bond_less; + assert_eq!(T::Currency::reserved_balance(&caller), expected); + } + + cancel_revoke_delegation { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + Pallet::::schedule_revoke_delegation( + RawOrigin::Signed(caller.clone()).into(), + collator.clone() + )?; + }: { + Pallet::::cancel_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + collator.clone() + )?; + } verify { + assert!( + Pallet::::delegator_state(&caller).unwrap().requests().get(&collator).is_none() + ); + } + + cancel_delegator_bond_less { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + total, + 0u32, + 0u32 + )?; + let bond_less = <::MinDelegatorStk as Get>>::get(); + Pallet::::schedule_delegator_bond_less( + RawOrigin::Signed(caller.clone()).into(), + collator.clone(), + bond_less + )?; + roll_to_and_author::(2, collator.clone()); + }: { + Pallet::::cancel_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + collator.clone() + )?; + } verify { + assert!( + Pallet::::delegator_state(&caller) + .unwrap() + .requests() + .get(&collator) + .is_none() + ); + } + + // ON_INITIALIZE + + round_transition_on_initialize { + // TOTAL SELECTED COLLATORS PER ROUND + let x in 1..28; + // DELEGATIONS + let y in 0..(<::MaxTopDelegationsPerCandidate as Get>::get() * 28); + let max_delegators_per_collator = + <::MaxTopDelegationsPerCandidate as Get>::get(); + let max_delegations = x * max_delegators_per_collator; + // y should depend on x but cannot directly, we overwrite y here if necessary to bound it + let total_delegations: u32 = if max_delegations < y { max_delegations } else { y }; + // INITIALIZE RUNTIME STATE + let high_inflation: Range = Range { + min: Perbill::one(), + ideal: Perbill::one(), + max: Perbill::one(), + }; + Pallet::::set_inflation(RawOrigin::Root.into(), high_inflation.clone())?; + Pallet::::set_total_selected(RawOrigin::Root.into(), 28u32)?; + // INITIALIZE COLLATOR STATE + let mut collators: Vec = Vec::new(); + let mut collator_count = 1u32; + for i in 0..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + min_candidate_stk::() * 1_000_000u32.into(), + true, + collator_count + )?; + collators.push(collator); + collator_count += 1u32; + } + // STORE starting balances for all collators + let collator_starting_balances: Vec<( + T::AccountId, + <::Currency as Currency>::Balance + )> = collators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); + // INITIALIZE DELEGATIONS + let mut col_del_count: BTreeMap = BTreeMap::new(); + collators.iter().for_each(|x| { + col_del_count.insert(x.clone(), 0u32); + }); + let mut delegators: Vec = Vec::new(); + let mut remaining_delegations = if total_delegations > max_delegators_per_collator { + for j in 1..(max_delegators_per_collator + 1) { + let seed = USER_SEED + j; + let delegator = create_funded_delegator::( + "delegator", + seed, + min_candidate_stk::() * 1_000_000u32.into(), + collators[0].clone(), + true, + delegators.len() as u32, + )?; + delegators.push(delegator); + } + total_delegations - max_delegators_per_collator + } else { + for j in 1..(total_delegations + 1) { + let seed = USER_SEED + j; + let delegator = create_funded_delegator::( + "delegator", + seed, + min_candidate_stk::() * 1_000_000u32.into(), + collators[0].clone(), + true, + delegators.len() as u32, + )?; + delegators.push(delegator); + } + 0u32 + }; + col_del_count.insert(collators[0].clone(), delegators.len() as u32); + // FILL remaining delegations + if remaining_delegations > 0 { + for (col, n_count) in col_del_count.iter_mut() { + if n_count < &mut (delegators.len() as u32) { + // assumes delegators.len() <= MaxTopDelegationsPerCandidate + let mut open_spots = delegators.len() as u32 - *n_count; + while open_spots > 0 && remaining_delegations > 0 { + let caller = delegators[open_spots as usize - 1usize].clone(); + if let Ok(_) = Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + col.clone(), + <::MinDelegatorStk as Get>>::get(), + *n_count, + collators.len() as u32, // overestimate + ) { + *n_count += 1; + remaining_delegations -= 1; + } + open_spots -= 1; + } + } + if remaining_delegations == 0 { + break; + } + } + } + // STORE starting balances for all delegators + let delegator_starting_balances: Vec<( + T::AccountId, + <::Currency as Currency>::Balance + )> = delegators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); + // PREPARE RUN_TO_BLOCK LOOP + let before_running_round_index = Pallet::::round().current; + let round_length: T::BlockNumber = Pallet::::round().length.into(); + let reward_delay = <::RewardPaymentDelay as Get>::get() + 2u32; + let mut now = >::block_number() + 1u32.into(); + let mut counter = 0usize; + let end = Pallet::::round().first + (round_length * reward_delay.into()); + // SET collators as authors for blocks from now - end + while now < end { + let author = collators[counter % collators.len()].clone(); + Pallet::::note_author(author); + >::on_finalize(>::block_number()); + >::set_block_number( + >::block_number() + 1u32.into() + ); + >::on_initialize(>::block_number()); + Pallet::::on_initialize(>::block_number()); + now += 1u32.into(); + counter += 1usize; + } + Pallet::::note_author(collators[counter % collators.len()].clone()); + >::on_finalize(>::block_number()); + >::set_block_number( + >::block_number() + 1u32.into() + ); + >::on_initialize(>::block_number()); + }: { Pallet::::on_initialize(>::block_number()); } + verify { + // Collators have been paid + for (col, initial) in collator_starting_balances { + assert!(T::Currency::free_balance(&col) > initial); + } + // Nominators have been paid + for (col, initial) in delegator_starting_balances { + assert!(T::Currency::free_balance(&col) > initial); + } + // Round transitions + assert_eq!(Pallet::::round().current, before_running_round_index + reward_delay); + } + + pay_one_collator_reward { + // y controls number of delegators + // TODO: mock.rs sets MaxTopDelegationsPerCandidate to 4, which is too low for this test to be + // meaningful. we use a higher value here, which works so long as we don't invoke any of + // pallet_staking's logic which uses MaxTopDelegationsPerCandidate as a constraint. this is + // brittle, to say the least... + let y in 0..2000; + + // must come after 'let foo in 0..` statements for macro + use crate::{ + DelayedPayout, DelayedPayouts, AtStake, CollatorSnapshot, Bond, Points, + AwardedPts, + }; + + let before_running_round_index = Pallet::::round().current; + let initial_stake_amount = min_candidate_stk::() * 1_000_000u32.into(); + + let mut total_staked = 0u32.into(); + + // initialize our single collator + let sole_collator = create_funded_collator::( + "collator", + 0, + initial_stake_amount, + true, + 1u32, + )?; + total_staked += initial_stake_amount; + + // generate funded collator accounts + let mut delegators: Vec = Vec::new(); + for i in 0..y { + let seed = USER_SEED + i; + let delegator = create_funded_delegator::( + "delegator", + seed, + initial_stake_amount, + sole_collator.clone(), + true, + delegators.len() as u32, + )?; + delegators.push(delegator); + total_staked += initial_stake_amount; + } + + // rather than roll through rounds in order to initialize the storage we want, we set it + // directly and then call pay_one_collator_reward directly. + + let round_for_payout = 5; + >::insert(&round_for_payout, DelayedPayout { + // NOTE: round_issuance is not correct here, but it doesn't seem to cause problems + round_issuance: 1000u32.into(), + total_staking_reward: total_staked, + collator_commission: Perbill::from_rational(1u32, 100u32), + }); + + let mut delegations: Vec>> = Vec::new(); + for delegator in &delegators { + delegations.push(Bond { + owner: delegator.clone(), + amount: 100u32.into(), + }); + } + + >::insert(round_for_payout, &sole_collator, CollatorSnapshot { + bond: 1_000u32.into(), + delegations, + total: 1_000_000u32.into(), + }); + + >::insert(round_for_payout, 100); + >::insert(round_for_payout, &sole_collator, 20); + + }: { + let round_for_payout = 5; + // TODO: this is an extra read right here (we should whitelist it?) + let payout_info = Pallet::::delayed_payouts(round_for_payout).expect("payout expected"); + let result = Pallet::::pay_one_collator_reward(round_for_payout, payout_info); + assert!(result.0.is_some()); // TODO: how to keep this in scope so it can be done in verify block? + } + verify { + // collator should have been paid + assert!( + T::Currency::free_balance(&sole_collator) > initial_stake_amount, + "collator should have been paid in pay_one_collator_reward" + ); + // nominators should have been paid + for delegator in &delegators { + assert!( + T::Currency::free_balance(&delegator) > initial_stake_amount, + "delegator should have been paid in pay_one_collator_reward" + ); + } + } + + base_on_initialize { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let start = >::block_number(); + Pallet::::note_author(collator.clone()); + >::on_finalize(start); + >::set_block_number( + start + 1u32.into() + ); + let end = >::block_number(); + >::on_initialize(end); + }: { Pallet::::on_initialize(end); } + verify { + // Round transitions + assert_eq!(start + 1u32.into(), end); + } } #[cfg(test)] mod tests { - use crate::benchmarks::*; - use crate::mock::Test; - use frame_support::assert_ok; - use sp_io::TestExternalities; - - pub fn new_test_ext() -> TestExternalities { - let t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - TestExternalities::new(t) - } - - #[test] - fn bench_set_staking_expectations() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_set_staking_expectations::()); - }); - } - - #[test] - fn bench_set_inflation() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_set_inflation::()); - }); - } - - #[test] - fn bench_set_parachain_bond_account() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_set_parachain_bond_account::()); - }); - } - - #[test] - fn bench_set_parachain_bond_reserve_percent() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_set_parachain_bond_reserve_percent::()); - }); - } - - #[test] - fn bench_set_total_selected() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_set_total_selected::()); - }); - } - - #[test] - fn bench_set_collator_commission() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_set_collator_commission::()); - }); - } - - #[test] - fn bench_set_blocks_per_round() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_set_blocks_per_round::()); - }); - } - - #[test] - fn bench_join_candidates() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_join_candidates::()); - }); - } - - #[test] - fn bench_leave_candidates() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_leave_candidates::()); - }); - } - - #[test] - fn bench_go_offline() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_go_offline::()); - }); - } - - #[test] - fn bench_go_online() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_go_online::()); - }); - } - - #[test] - fn bench_candidate_bond_more() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_candidate_bond_more::()); - }); - } - - #[test] - fn bench_candidate_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_candidate_bond_less::()); - }); - } - - #[test] - fn bench_nominate() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_nominate::()); - }); - } - - #[test] - fn bench_leave_nominators() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_leave_nominators::()); - }); - } - - #[test] - fn bench_revoke_nomination() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_revoke_nomination::()); - }); - } - - #[test] - fn bench_nominator_bond_more() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_nominator_bond_more::()); - }); - } - - #[test] - fn bench_nominator_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_nominator_bond_less::()); - }); - } - - #[test] - fn bench_active_on_initialize() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_active_on_initialize::()); - }); - } - - #[test] - fn bench_passive_on_initialize() { - new_test_ext().execute_with(|| { - assert_ok!(test_benchmark_passive_on_initialize::()); - }); - } + use crate::benchmarks::*; + use crate::mock::Test; + use frame_support::assert_ok; + use sp_io::TestExternalities; + + pub fn new_test_ext() -> TestExternalities { + let t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + TestExternalities::new(t) + } + + #[test] + fn bench_hotfix_remove_delegation_requests() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_hotfix_remove_delegation_requests()); + }); + } + + #[test] + fn bench_hotfix_update_candidate_pool_value() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_hotfix_update_candidate_pool_value()); + }); + } + + #[test] + fn bench_set_staking_expectations() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_staking_expectations()); + }); + } + + #[test] + fn bench_set_inflation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_inflation()); + }); + } + + #[test] + fn bench_set_parachain_bond_account() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_parachain_bond_account()); + }); + } + + #[test] + fn bench_set_parachain_bond_reserve_percent() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_parachain_bond_reserve_percent()); + }); + } + + #[test] + fn bench_set_total_selected() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_total_selected()); + }); + } + + #[test] + fn bench_set_collator_commission() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_collator_commission()); + }); + } + + #[test] + fn bench_set_blocks_per_round() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_blocks_per_round()); + }); + } + + #[test] + fn bench_join_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_join_candidates()); + }); + } + + #[test] + fn bench_schedule_leave_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_leave_candidates()); + }); + } + + #[test] + fn bench_execute_leave_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_leave_candidates()); + }); + } + + #[test] + fn bench_cancel_leave_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_leave_candidates()); + }); + } + + #[test] + fn bench_go_offline() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_go_offline()); + }); + } + + #[test] + fn bench_go_online() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_go_online()); + }); + } + + #[test] + fn bench_candidate_bond_more() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_candidate_bond_more()); + }); + } + + #[test] + fn bench_schedule_candidate_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_candidate_bond_less()); + }); + } + + #[test] + fn bench_execute_candidate_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_candidate_bond_less()); + }); + } + + #[test] + fn bench_cancel_candidate_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_candidate_bond_less()); + }); + } + + #[test] + fn bench_delegate() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_delegate()); + }); + } + + #[test] + fn bench_schedule_leave_delegators() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_leave_delegators()); + }); + } + + #[test] + fn bench_execute_leave_delegators() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_leave_delegators()); + }); + } + + #[test] + fn bench_cancel_leave_delegators() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_leave_delegators()); + }); + } + + #[test] + fn bench_schedule_revoke_delegation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_revoke_delegation()); + }); + } + + #[test] + fn bench_delegator_bond_more() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_delegator_bond_more()); + }); + } + + #[test] + fn bench_schedule_delegator_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_delegator_bond_less()); + }); + } + + #[test] + fn bench_execute_revoke_delegation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_revoke_delegation()); + }); + } + + #[test] + fn bench_execute_delegator_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_delegator_bond_less()); + }); + } + + #[test] + fn bench_cancel_revoke_delegation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_revoke_delegation()); + }); + } + + #[test] + fn bench_cancel_delegator_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_delegator_bond_less()); + }); + } + + #[test] + fn bench_round_transition_on_initialize() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_round_transition_on_initialize()); + }); + } + + #[test] + fn bench_base_on_initialize() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_base_on_initialize()); + }); + } } impl_benchmark_test_suite!( - Pallet, - crate::benchmarks::tests::new_test_ext(), - crate::mock::Test + Pallet, + crate::benchmarks::tests::new_test_ext(), + crate::mock::Test ); diff --git a/pallets/parachain-staking/src/inflation.rs b/pallets/parachain-staking/src/inflation.rs index 23f7fcd6..f2181565 100644 --- a/pallets/parachain-staking/src/inflation.rs +++ b/pallets/parachain-staking/src/inflation.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2021 PureStake Inc. +// Copyright 2019-2022 PureStake Inc. // This file is part of Moonbeam. // Moonbeam is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ //! Helper methods for computing issuance based on inflation use crate::pallet::{BalanceOf, Config, Pallet}; use frame_support::traits::Currency; -use parity_scale_codec::{Decode, Encode}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; @@ -28,185 +28,187 @@ use substrate_fixed::types::{I32F32, I64F64}; const SECONDS_PER_YEAR: u32 = 31557600; const SECONDS_PER_BLOCK: u32 = 12; -const BLOCKS_PER_YEAR: u32 = SECONDS_PER_YEAR / SECONDS_PER_BLOCK; +pub const BLOCKS_PER_YEAR: u32 = SECONDS_PER_YEAR / SECONDS_PER_BLOCK; fn rounds_per_year() -> u32 { - let blocks_per_round = >::round().length; - BLOCKS_PER_YEAR / blocks_per_round + let blocks_per_round = >::round().length; + BLOCKS_PER_YEAR / blocks_per_round } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, Default, RuntimeDebug, TypeInfo)] +#[derive( + Eq, PartialEq, Clone, Copy, Encode, Decode, Default, RuntimeDebug, MaxEncodedLen, TypeInfo, +)] pub struct Range { - pub min: T, - pub ideal: T, - pub max: T, + pub min: T, + pub ideal: T, + pub max: T, } impl Range { - pub fn is_valid(&self) -> bool { - self.max >= self.ideal && self.ideal >= self.min - } + pub fn is_valid(&self) -> bool { + self.max >= self.ideal && self.ideal >= self.min + } } impl From for Range { - fn from(other: T) -> Range { - Range { - min: other, - ideal: other, - max: other, - } - } + fn from(other: T) -> Range { + Range { + min: other, + ideal: other, + max: other, + } + } } /// Convert an annual inflation to a round inflation -/// round = 1 - (1+annual)^(1/rounds_per_year) -fn perbill_annual_to_perbill_round( - annual: Range, - rounds_per_year: u32, +/// round = (1+annual)^(1/rounds_per_year) - 1 +pub fn perbill_annual_to_perbill_round( + annual: Range, + rounds_per_year: u32, ) -> Range { - let exponent = I32F32::from_num(1) / I32F32::from_num(rounds_per_year); - let annual_to_round = |annual: Perbill| -> Perbill { - let x = I32F32::from_num(annual.deconstruct()) / I32F32::from_num(Perbill::ACCURACY); - let y: I64F64 = floatpow(I32F32::from_num(1) + x, exponent) - .expect("Cannot overflow since rounds_per_year is u32 so worst case 0; QED"); - Perbill::from_parts( - ((y - I64F64::from_num(1)) * I64F64::from_num(Perbill::ACCURACY)) - .ceil() - .to_num::(), - ) - }; - Range { - min: annual_to_round(annual.min), - ideal: annual_to_round(annual.ideal), - max: annual_to_round(annual.max), - } + let exponent = I32F32::from_num(1) / I32F32::from_num(rounds_per_year); + let annual_to_round = |annual: Perbill| -> Perbill { + let x = I32F32::from_num(annual.deconstruct()) / I32F32::from_num(Perbill::ACCURACY); + let y: I64F64 = floatpow(I32F32::from_num(1) + x, exponent) + .expect("Cannot overflow since rounds_per_year is u32 so worst case 0; QED"); + Perbill::from_parts( + ((y - I64F64::from_num(1)) * I64F64::from_num(Perbill::ACCURACY)) + .ceil() + .to_num::(), + ) + }; + Range { + min: annual_to_round(annual.min), + ideal: annual_to_round(annual.ideal), + max: annual_to_round(annual.max), + } } /// Convert annual inflation rate range to round inflation range pub fn annual_to_round(annual: Range) -> Range { - let periods = rounds_per_year::(); - perbill_annual_to_perbill_round(annual, periods) + let periods = rounds_per_year::(); + perbill_annual_to_perbill_round(annual, periods) } /// Compute round issuance range from round inflation range and current total issuance pub fn round_issuance_range(round: Range) -> Range> { - let circulating = T::Currency::total_issuance(); - Range { - min: round.min * circulating, - ideal: round.ideal * circulating, - max: round.max * circulating, - } + let circulating = T::Currency::total_issuance(); + Range { + min: round.min * circulating, + ideal: round.ideal * circulating, + max: round.max * circulating, + } } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Eq, PartialEq, Clone, Encode, Decode, Default, RuntimeDebug, TypeInfo)] pub struct InflationInfo { - /// Staking expectations - pub expect: Range, - /// Annual inflation range - pub annual: Range, - /// Round inflation range - pub round: Range, + /// Staking expectations + pub expect: Range, + /// Annual inflation range + pub annual: Range, + /// Round inflation range + pub round: Range, } impl InflationInfo { - pub fn new( - annual: Range, - expect: Range, - ) -> InflationInfo { - InflationInfo { - expect, - annual, - round: annual_to_round::(annual), - } - } - /// Set round inflation range according to input annual inflation range - pub fn set_round_from_annual(&mut self, new: Range) { - self.round = annual_to_round::(new); - } - /// Reset round inflation rate based on changes to round length - pub fn reset_round(&mut self, new_length: u32) { - let periods = BLOCKS_PER_YEAR / new_length; - self.round = perbill_annual_to_perbill_round(self.annual, periods); - } - /// Set staking expectations - pub fn set_expectations(&mut self, expect: Range) { - self.expect = expect; - } + pub fn new( + annual: Range, + expect: Range, + ) -> InflationInfo { + InflationInfo { + expect, + annual, + round: annual_to_round::(annual), + } + } + /// Set round inflation range according to input annual inflation range + pub fn set_round_from_annual(&mut self, new: Range) { + self.round = annual_to_round::(new); + } + /// Reset round inflation rate based on changes to round length + pub fn reset_round(&mut self, new_length: u32) { + let periods = BLOCKS_PER_YEAR / new_length; + self.round = perbill_annual_to_perbill_round(self.annual, periods); + } + /// Set staking expectations + pub fn set_expectations(&mut self, expect: Range) { + self.expect = expect; + } } #[cfg(test)] mod tests { - use super::*; - fn mock_annual_to_round(annual: Range, rounds_per_year: u32) -> Range { - perbill_annual_to_perbill_round(annual, rounds_per_year) - } - fn mock_round_issuance_range( - // Total circulating before minting - circulating: u128, - // Round inflation range - round: Range, - ) -> Range { - Range { - min: round.min * circulating, - ideal: round.ideal * circulating, - max: round.max * circulating, - } - } - #[test] - fn simple_issuance_conversion() { - // 5% inflation for 10_000_0000 = 500,000 minted over the year - // let's assume there are 10 periods in a year - // => mint 500_000 over 10 periods => 50_000 minted per period - let expected_round_issuance_range: Range = Range { - min: 48_909, - ideal: 48_909, - max: 48_909, - }; - let schedule = Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5), - }; - assert_eq!( - expected_round_issuance_range, - mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) - ); - } - #[test] - fn range_issuance_conversion() { - // 3-5% inflation for 10_000_0000 = 300_000-500,000 minted over the year - // let's assume there are 10 periods in a year - // => mint 300_000-500_000 over 10 periods => 30_000-50_000 minted per period - let expected_round_issuance_range: Range = Range { - min: 29_603, - ideal: 39298, - max: 48_909, - }; - let schedule = Range { - min: Perbill::from_percent(3), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(5), - }; - assert_eq!( - expected_round_issuance_range, - mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) - ); - } - #[test] - fn expected_parameterization() { - let expected_round_schedule: Range = Range { - min: 45, - ideal: 56, - max: 56, - }; - let schedule = Range { - min: Perbill::from_percent(4), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5), - }; - assert_eq!( - expected_round_schedule, - mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 8766)) - ); - } + use super::*; + fn mock_annual_to_round(annual: Range, rounds_per_year: u32) -> Range { + perbill_annual_to_perbill_round(annual, rounds_per_year) + } + fn mock_round_issuance_range( + // Total circulating before minting + circulating: u128, + // Round inflation range + round: Range, + ) -> Range { + Range { + min: round.min * circulating, + ideal: round.ideal * circulating, + max: round.max * circulating, + } + } + #[test] + fn simple_issuance_conversion() { + // 5% inflation for 10_000_0000 = 500,000 minted over the year + // let's assume there are 10 periods in a year + // => mint 500_000 over 10 periods => 50_000 minted per period + let expected_round_issuance_range: Range = Range { + min: 48_909, + ideal: 48_909, + max: 48_909, + }; + let schedule = Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5), + }; + assert_eq!( + expected_round_issuance_range, + mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) + ); + } + #[test] + fn range_issuance_conversion() { + // 3-5% inflation for 10_000_0000 = 300_000-500,000 minted over the year + // let's assume there are 10 periods in a year + // => mint 300_000-500_000 over 10 periods => 30_000-50_000 minted per period + let expected_round_issuance_range: Range = Range { + min: 29_603, + ideal: 39298, + max: 48_909, + }; + let schedule = Range { + min: Perbill::from_percent(3), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(5), + }; + assert_eq!( + expected_round_issuance_range, + mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) + ); + } + #[test] + fn expected_parameterization() { + let expected_round_schedule: Range = Range { + min: 45, + ideal: 56, + max: 56, + }; + let schedule = Range { + min: Perbill::from_percent(4), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5), + }; + assert_eq!( + expected_round_schedule, + mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 8766)) + ); + } } diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index 11f3dfbf..6583d688 100644 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2021 PureStake Inc. +// Copyright 2019-2022 PureStake Inc. // This file is part of Moonbeam. // Moonbeam is free software: you can redistribute it and/or modify @@ -17,1973 +17,3253 @@ //! # Parachain Staking //! Minimal staking pallet that implements collator selection by total backed stake. //! The main difference between this pallet and `frame/pallet-staking` is that this pallet -//! uses direct delegation. Nominators choose exactly who they nominate and with what stake. -//! This is different from `frame/pallet-staking` where you approval vote and then run Phragmen. +//! uses direct delegation. Delegators choose exactly who they delegate and with what stake. +//! This is different from `frame/pallet-staking` where delegators approval vote and run Phragmen. //! //! ### Rules //! There is a new round every `>::get().length` blocks. //! //! At the start of every round, -//! * issuance is distributed to collators (and their nominators) for block authoring +//! * issuance is calculated for collators (and their delegators) for block authoring //! `T::RewardPaymentDelay` rounds ago -//! * queued collator and nominator exits are executed //! * a new set of collators is chosen from the candidates //! -//! To join the set of candidates, call `join_candidates` with `bond >= MinCollatorCandidateStk`. +//! Immediately following a round change, payments are made once-per-block until all payments have +//! been made. In each such block, one collator is chosen for a rewards payment and is paid along +//! with each of its top `T::MaxTopDelegationsPerCandidate` delegators. //! -//! To leave the set of candidates, call `leave_candidates`. If the call succeeds, +//! To join the set of candidates, call `join_candidates` with `bond >= MinCandidateStk`. +//! To leave the set of candidates, call `schedule_leave_candidates`. If the call succeeds, //! the collator is removed from the pool of candidates so they cannot be selected for future -//! collator sets, but they are not unstaked until `T::LeaveCandidatesDelay` rounds later. -//! The exit request is stored in the `ExitQueue` and processed `T::LeaveCandidatesDelay` rounds -//! later to unstake the collator and all of its nominations. +//! collator sets, but they are not unbonded until their exit request is executed. Any signed +//! account may trigger the exit `T::LeaveCandidatesDelay` rounds after the round in which the +//! original request was made. //! -//! To join the set of nominators, call `nominate` and pass in an account that is -//! already a collator candidate and `bond >= MinNominatorStk`. Each nominator can nominate up to -//! `T::MaxCollatorsPerNominator` collator candidates by calling `nominate`. +//! To join the set of delegators, call `delegate` and pass in an account that is +//! already a collator candidate and `bond >= MinDelegatorStk`. Each delegator can delegate up to +//! `T::MaxDelegationsPerDelegator` collator candidates by calling `delegate`. //! -//! To revoke a nomination, call `revoke_nomination` with the collator candidate's account. -//! To leave the set of nominators and revoke all nominations, call `leave_nominators`. +//! To revoke a delegation, call `revoke_delegation` with the collator candidate's account. +//! To leave the set of delegators and revoke all delegations, call `leave_delegators`. #![cfg_attr(not(feature = "std"), no_std)] #[cfg(any(test, feature = "runtime-benchmarks"))] mod benchmarks; -mod inflation; +pub mod inflation; +pub mod migrations; #[cfg(test)] mod mock; mod set; #[cfg(test)] mod tests; - pub mod weights; -use weights::WeightInfo; use frame_support::pallet; pub use inflation::{InflationInfo, Range}; +use weights::WeightInfo; pub use pallet::*; #[pallet] pub mod pallet { - use crate::{set::OrderedSet, InflationInfo, Range, WeightInfo}; - use frame_support::pallet_prelude::*; - use frame_support::traits::{Currency, Get, Imbalance, ReservableCurrency}; - use frame_system::pallet_prelude::*; - use parity_scale_codec::{Decode, Encode}; - use scale_info::TypeInfo; - use sp_runtime::{ - traits::{AtLeast32BitUnsigned, Saturating, Zero}, - Perbill, Percent, RuntimeDebug, - }; - use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; - - /// Pallet for parachain staking - #[pallet::pallet] - #[pallet::without_storage_info] - pub struct Pallet(PhantomData); - - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] - pub struct Bond { - pub owner: AccountId, - pub amount: Balance, - } - - impl Bond { - fn from_owner(owner: A) -> Self { - Bond { - owner, - amount: B::default(), - } - } - } - - impl Eq for Bond {} - - impl Ord for Bond { - fn cmp(&self, other: &Self) -> Ordering { - self.owner.cmp(&other.owner) - } - } - - impl PartialOrd for Bond { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - - impl PartialEq for Bond { - fn eq(&self, other: &Self) -> bool { - self.owner == other.owner - } - } - - #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// The activity status of the collator - pub enum CollatorStatus { - /// Committed to be online and producing valid blocks (not equivocating) - Active, - /// Temporarily inactive and excused for inactivity - Idle, - /// Bonded until the inner round - Leaving(RoundIndex), - } - - impl Default for CollatorStatus { - fn default() -> CollatorStatus { - CollatorStatus::Active - } - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] - /// Snapshot of collator state at the start of the round for which they are selected - pub struct CollatorSnapshot { - pub bond: Balance, - pub nominators: Vec>, - pub total: Balance, - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] - /// Collator state with commission fee, bonded stake, and nominations - pub struct Collator2 { - /// The account of this collator - pub id: AccountId, - /// This collator's self stake. - pub bond: Balance, - /// Set of all nominator AccountIds (to prevent >1 nomination per AccountId) - pub nominators: OrderedSet, - /// Top T::MaxNominatorsPerCollator::get() nominators, ordered greatest to least - pub top_nominators: Vec>, - /// Bottom nominators (unbounded), ordered least to greatest - pub bottom_nominators: Vec>, - /// Sum of top nominations + self.bond - pub total_counted: Balance, - /// Sum of all nominations + self.bond = (total_counted + uncounted) - pub total_backing: Balance, - /// Current status of the collator - pub state: CollatorStatus, - } - - /// Convey relevant information describing if a nominator was added to the top or bottom - /// Nominations added to the top yield a new total - #[derive(Clone, Copy, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] - pub enum NominatorAdded { - AddedToTop { new_total: B }, - AddedToBottom, - } - - impl< - A: Ord + Clone, - B: AtLeast32BitUnsigned + Ord + Copy + sp_std::ops::AddAssign + sp_std::ops::SubAssign, - > Collator2 - { - pub fn new(id: A, bond: B) -> Self { - Collator2 { - id, - bond, - nominators: OrderedSet::new(), - top_nominators: Vec::new(), - bottom_nominators: Vec::new(), - total_counted: bond, - total_backing: bond, - state: CollatorStatus::default(), // default active - } - } - pub fn is_active(&self) -> bool { - self.state == CollatorStatus::Active - } - pub fn is_leaving(&self) -> bool { - matches!(self.state, CollatorStatus::Leaving(_)) - } - pub fn bond_more(&mut self, more: B) { - self.bond += more; - self.total_counted += more; - self.total_backing += more; - } - // Return None if less >= self.bond => collator must leave instead of bond less - pub fn bond_less(&mut self, less: B) -> Option { - if self.bond > less { - self.bond -= less; - self.total_counted -= less; - self.total_backing -= less; - Some(self.bond) - } else { - None - } - } - /// Infallible sorted insertion - /// caller must verify !self.nominators.contains(nominator.owner) before call - pub fn add_top_nominator(&mut self, nominator: Bond) { - match self - .top_nominators - .binary_search_by(|x| nominator.amount.cmp(&x.amount)) - { - Ok(i) => self.top_nominators.insert(i, nominator), - Err(i) => self.top_nominators.insert(i, nominator), - } - } - /// Infallible sorted insertion - /// caller must verify !self.nominators.contains(nominator.owner) before call - pub fn add_bottom_nominator(&mut self, nominator: Bond) { - match self - .bottom_nominators - .binary_search_by(|x| x.amount.cmp(&nominator.amount)) - { - Ok(i) => self.bottom_nominators.insert(i, nominator), - Err(i) => self.bottom_nominators.insert(i, nominator), - } - } - /// Sort top nominators from greatest to least - pub fn sort_top_nominators(&mut self) { - self.top_nominators - .sort_unstable_by(|a, b| b.amount.cmp(&a.amount)); - } - /// Sort bottom nominators from least to greatest - pub fn sort_bottom_nominators(&mut self) { - self.bottom_nominators - .sort_unstable_by(|a, b| a.amount.cmp(&b.amount)); - } - /// Bond a new account as a nominator, and make a first nomination. If successful, - /// the return value indicates whether the nomination is top for the candidate. - pub fn add_nominator( - &mut self, - acc: A, - amount: B, - ) -> Result, DispatchError> { - ensure!( - self.nominators.insert(acc.clone()), - Error::::NominatorExists - ); - self.total_backing += amount; - if (self.top_nominators.len() as u32) < T::MaxNominatorsPerCollator::get() { - self.add_top_nominator(Bond { owner: acc, amount }); - self.total_counted += amount; - Ok(NominatorAdded::AddedToTop { - new_total: self.total_counted, - }) - } else { - // >pop requires push to reset in case isn't pushed to bottom - let last_nomination_in_top = self - .top_nominators - .pop() - .expect("self.top_nominators.len() >= T::Max exists >= 1 element in top"); - if amount > last_nomination_in_top.amount { - // update total_counted with positive difference - self.total_counted += amount - last_nomination_in_top.amount; - // last nomination already popped from top_nominators - // insert new nominator into top_nominators - self.add_top_nominator(Bond { owner: acc, amount }); - self.add_bottom_nominator(last_nomination_in_top); - Ok(NominatorAdded::AddedToTop { - new_total: self.total_counted, - }) - } else { - // >required push to previously popped last nomination into top_nominators - self.top_nominators.push(last_nomination_in_top); - self.add_bottom_nominator(Bond { owner: acc, amount }); - Ok(NominatorAdded::AddedToBottom) - } - } - } - /// Return Ok((if_total_counted_changed, nominator's stake)) - pub fn rm_nominator( - &mut self, - nominator: A, - ) -> Result<(bool, B), DispatchError> { - ensure!( - self.nominators.remove(&nominator), - Error::::NominatorDNEInNominatorSet - ); - let mut nominator_stake: Option = None; - self.top_nominators = self - .top_nominators - .clone() - .into_iter() - .filter_map(|nom| { - if nom.owner != nominator { - Some(nom) - } else { - nominator_stake = Some(nom.amount); - None - } - }) - .collect(); - // item removed from the top => highest bottom is popped from bottom and pushed to top - if let Some(s) = nominator_stake { - // last element has largest amount as per ordering - if let Some(last) = self.bottom_nominators.pop() { - self.total_counted -= s - last.amount; - self.add_top_nominator(last); - } else { - // no item in bottom nominators so no item from bottom to pop and push up - self.total_counted -= s; - } - self.total_backing -= s; - return Ok((true, s)); - } - // else (no item removed from the top) - self.bottom_nominators = self - .bottom_nominators - .clone() - .into_iter() - .filter_map(|nom| { - if nom.owner != nominator { - Some(nom) - } else { - nominator_stake = Some(nom.amount); - None - } - }) - .collect(); - // if err, no item with account exists in top || bottom - let stake = nominator_stake.ok_or(Error::::NominatorDNEinTopNorBottom)?; - self.total_backing -= stake; - Ok((false, stake)) - } - /// Return true if in_top after call - /// Caller must verify before call that account is a nominator - pub fn inc_nominator(&mut self, nominator: A, more: B) -> bool { - let mut in_top = false; - for x in &mut self.top_nominators { - if x.owner == nominator { - x.amount += more; - self.total_counted += more; - self.total_backing += more; - in_top = true; - break; - } - } - // if nominator was increased in top nominators - if in_top { - self.sort_top_nominators(); - return true; - } - // else nominator to increase must exist in bottom - // >pop requires push later on to reset in case it isn't used - let lowest_top = self - .top_nominators - .pop() - .expect("any bottom nominators => exists T::Max top nominators"); - let mut move_2_top = false; - for x in &mut self.bottom_nominators { - if x.owner == nominator { - x.amount += more; - self.total_backing += more; - move_2_top = x.amount > lowest_top.amount; - break; - } - } - if move_2_top { - self.sort_bottom_nominators(); - let highest_bottom = self.bottom_nominators.pop().expect("updated => exists"); - self.total_counted += highest_bottom.amount - lowest_top.amount; - self.add_top_nominator(highest_bottom); - self.add_bottom_nominator(lowest_top); - true - } else { - // >required push to reset top_nominators from earlier pop - self.top_nominators.push(lowest_top); - self.sort_bottom_nominators(); - false - } - } - /// Return true if in_top after call - pub fn dec_nominator(&mut self, nominator: A, less: B) -> bool { - let mut in_top = false; - let mut new_lowest_top: Option> = None; - for x in &mut self.top_nominators { - if x.owner == nominator { - x.amount -= less; - // if there is at least 1 nominator in bottom nominators, compare it to check - // if it should be swapped with lowest top nomination and put in top - // >pop requires push later on to reset in case it isn't used - if let Some(highest_bottom) = self.bottom_nominators.pop() { - if highest_bottom.amount > x.amount { - new_lowest_top = Some(highest_bottom); - } else { - // >required push to reset self.bottom_nominators - self.bottom_nominators.push(highest_bottom); - } - } - in_top = true; - break; - } - } - if in_top { - self.sort_top_nominators(); - if let Some(highest_bottom) = new_lowest_top { - // pop last in top to swap it with top bottom - let lowest_top = self - .top_nominators - .pop() - .expect("must have >1 item to update, assign in_top = true"); - self.total_counted -= lowest_top.amount + less; - self.total_counted += highest_bottom.amount; - self.total_backing -= less; - self.add_top_nominator(highest_bottom); - self.add_bottom_nominator(lowest_top); - return false; - } else { - // no existing bottom nominators so update both counters the same magnitude - self.total_counted -= less; - self.total_backing -= less; - return true; - } - } - for x in &mut self.bottom_nominators { - if x.owner == nominator { - x.amount -= less; - self.total_backing -= less; - break; - } - } - self.sort_bottom_nominators(); - false - } - pub fn go_offline(&mut self) { - self.state = CollatorStatus::Idle; - } - pub fn go_online(&mut self) { - self.state = CollatorStatus::Active; - } - pub fn leave(&mut self, when: RoundIndex) { - self.state = CollatorStatus::Leaving(when); - } - } - - impl From> for CollatorSnapshot { - fn from(other: Collator2) -> CollatorSnapshot { - CollatorSnapshot { - bond: other.bond, - nominators: other.top_nominators, - total: other.total_counted, - } - } - } - - #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] - pub enum NominatorStatus { - /// Active with no scheduled exit - Active, - /// Schedule exit to revoke all ongoing nominations - Leaving(RoundIndex), - } - - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Nominator state - pub struct Nominator2 { - /// All current nominations - pub nominations: OrderedSet>, - /// Nominations scheduled to be revoked - pub revocations: OrderedSet, - /// Total balance locked for this nominator - pub total: Balance, - /// Total number of revocations scheduled to be executed - pub scheduled_revocations_count: u32, - /// Total amount to be unbonded once revocations are executed - pub scheduled_revocations_total: Balance, - /// Status for this nominator - pub status: NominatorStatus, - } - - impl< - AccountId: Ord + Clone, - Balance: Copy - + sp_std::ops::AddAssign - + sp_std::ops::Add - + sp_std::ops::SubAssign - + PartialOrd - + Zero, - > Nominator2 - { - pub fn new(collator: AccountId, amount: Balance) -> Self { - Nominator2 { - nominations: OrderedSet::from(vec![Bond { - owner: collator, - amount, - }]), - revocations: OrderedSet::new(), - total: amount, - scheduled_revocations_count: 0u32, - scheduled_revocations_total: Zero::zero(), - status: NominatorStatus::Active, - } - } - pub fn is_active(&self) -> bool { - matches!(self.status, NominatorStatus::Active) - } - pub fn is_leaving(&self) -> bool { - matches!(self.status, NominatorStatus::Leaving(_)) - } - /// Set nominator status to exit - pub fn leave(&mut self, when: RoundIndex) { - self.status = NominatorStatus::Leaving(when) - } - pub fn add_nomination(&mut self, bond: Bond) -> bool { - let amt = bond.amount; - if self.nominations.insert(bond) { - self.total += amt; - true - } else { - false - } - } - // Return Some(remaining balance), must be more than MinNominatorStk - // Return None if nomination not found - pub fn rm_nomination(&mut self, collator: AccountId) -> Option { - let mut amt: Option = None; - let nominations = self - .nominations - .0 - .iter() - .filter_map(|x| { - if x.owner == collator { - amt = Some(x.amount); - None - } else { - Some(x.clone()) - } - }) - .collect(); - if let Some(balance) = amt { - self.nominations = OrderedSet::from(nominations); - self.total -= balance; - Some(self.total) - } else { - None - } - } - // Return false if nomination not found - pub fn inc_nomination(&mut self, collator: AccountId, more: Balance) -> bool { - for x in &mut self.nominations.0 { - if x.owner == collator { - x.amount += more; - self.total += more; - return true; - } - } - false - } - // Return Some(Some(balance)) if successful - // Return None if nomination not found - // Return Some(None) if less >= nomination_total - pub fn dec_nomination( - &mut self, - collator: AccountId, - less: Balance, - ) -> Option> { - for x in &mut self.nominations.0 { - if x.owner == collator { - if x.amount > less { - x.amount -= less; - self.total -= less; - return Some(Some(x.amount)); - } else { - // must rm entire nomination if x.amount <= less - return Some(None); - } - } - } - None - } - } - - #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// The current round index and transition information - pub struct RoundInfo { - /// Current round index - pub current: RoundIndex, - /// The first block of the current round - pub first: BlockNumber, - /// The length of the current round in number of blocks - pub length: u32, - } - impl< - B: Copy - + sp_std::ops::Add - + sp_std::ops::Sub - + From - + PartialOrd, - > RoundInfo - { - pub fn new(current: RoundIndex, first: B, length: u32) -> RoundInfo { - RoundInfo { - current, - first, - length, - } - } - /// Check if the round should be updated - pub fn should_update(&self, now: B) -> bool { - now - self.first >= self.length.into() - } - /// New round - pub fn update(&mut self, now: B) { - self.current += 1u32; - self.first = now; - } - } - impl< - B: Copy - + sp_std::ops::Add - + sp_std::ops::Sub - + From - + PartialOrd, - > Default for RoundInfo - { - fn default() -> RoundInfo { - RoundInfo::new(1u32, 1u32.into(), 20u32) - } - } - - #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Reserve information { account, percent_of_inflation } - pub struct ParachainBondConfig { - /// Account which receives funds intended for parachain bond - pub account: AccountId, - /// Percent of inflation set aside for parachain bond account - pub percent: Percent, - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] - /// Store and process all delayed exits by collators and nominators - pub struct ExitQ { - /// Candidate exit set - pub candidates: OrderedSet, - /// Nominator exit set (does not include nominators that made `revoke` requests) - pub nominators_leaving: OrderedSet, - /// [Candidate, Round to Exit] - pub candidate_schedule: Vec<(AccountId, RoundIndex)>, - /// [Nominator, Some(ValidatorId) || None => All Nominations, Round To Exit] - pub nominator_schedule: Vec<(AccountId, Option, RoundIndex)>, - } - - impl Default for ExitQ { - fn default() -> ExitQ { - ExitQ { - ..Default::default() - } - } - } - - impl ExitQ { - /// Schedule to leave the set of candidates and return all ongoing nominations - pub fn schedule_candidate_exit( - &mut self, - candidate: A, - exit_round: RoundIndex, - ) -> DispatchResult { - ensure!( - self.candidates.insert(candidate.clone()), - Error::::CandidateAlreadyLeaving - ); - self.candidate_schedule.push((candidate, exit_round)); - Ok(()) - } - /// Schedule to leave the set of nominators and revoke all ongoing nominations - pub fn schedule_nominator_exit( - &mut self, - nominator: A, - exit_round: RoundIndex, - ) -> DispatchResult { - ensure!( - self.nominators_leaving.insert(nominator.clone()), - Error::::NominatorAlreadyLeaving - ); - self.nominator_schedule.push((nominator, None, exit_round)); - Ok(()) - } - /// Schedule to revoke a single nomination - pub fn schedule_nomination_revocation( - &mut self, - nominator: A, - collator: A, - exit_round: RoundIndex, - ) -> DispatchResult { - self.nominator_schedule - .push((nominator, Some(collator), exit_round)); - Ok(()) - } - } - - type RoundIndex = u32; - type RewardPoint = u32; - pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - - /// Configuration trait of this pallet. - #[pallet::config] - pub trait Config: frame_system::Config { - /// Overarching event type - type Event: From> + IsType<::Event>; - /// The currency type - type Currency: Currency + ReservableCurrency; - /// The origin for monetary governance - type MonetaryGovernanceOrigin: EnsureOrigin; - /// Minimum number of blocks per round - #[pallet::constant] - type MinBlocksPerRound: Get; - /// Default number of blocks per round at genesis - #[pallet::constant] - type DefaultBlocksPerRound: Get; - /// Number of rounds that collators remain bonded before exit request is executed - #[pallet::constant] - type LeaveCandidatesDelay: Get; - /// Number of rounds that nominators remain bonded before exit request is executed - #[pallet::constant] - type LeaveNominatorsDelay: Get; - /// Number of rounds that nominations remain bonded before revocation request is executed - #[pallet::constant] - type RevokeNominationDelay: Get; - /// Number of rounds after which block authors are rewarded - #[pallet::constant] - type RewardPaymentDelay: Get; - /// Minimum number of selected candidates every round - #[pallet::constant] - type MinSelectedCandidates: Get; - /// Maximum nominators counted per collator - #[pallet::constant] - type MaxNominatorsPerCollator: Get; - /// Maximum collators per nominator - #[pallet::constant] - type MaxCollatorsPerNominator: Get; - /// Default commission due to collators, set at genesis - #[pallet::constant] - type DefaultCollatorCommission: Get; - /// Default percent of inflation set aside for parachain bond account - #[pallet::constant] - type DefaultParachainBondReservePercent: Get; - /// Minimum stake required for any account to be in `SelectedCandidates` for the round - #[pallet::constant] - type MinCollatorStk: Get>; - /// Minimum stake required for any account to be a collator candidate - #[pallet::constant] - type MinCollatorCandidateStk: Get>; - /// Minimum stake for any registered on-chain account to nominate - #[pallet::constant] - type MinNomination: Get>; - /// Minimum stake for any registered on-chain account to become a nominator - #[pallet::constant] - type MinNominatorStk: Get>; - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; - } - - #[pallet::error] - pub enum Error { - NominatorDNE, - NominatorDNEinTopNorBottom, - NominatorDNEInNominatorSet, - CandidateDNE, - NominationDNE, - NominatorExists, - CandidateExists, - ValBondBelowMin, - NomBondBelowMin, - NominationBelowMin, - AlreadyOffline, - AlreadyActive, - NominatorAlreadyLeaving, - NominationAlreadyRevoked, - CandidateAlreadyLeaving, - CannotActBecauseLeaving, - CannotActBecauseRevoking, - ExceedMaxCollatorsPerNom, - AlreadyNominatedCollator, - InvalidSchedule, - CannotSetBelowMin, - NoWritingSameValue, - TooLowCandidateCountWeightHintJoinCandidates, - TooLowCollatorCandidateCountToLeaveCandidates, - TooLowNominationCountToNominate, - TooLowCollatorNominationCountToNominate, - TooLowNominationCountToLeaveNominators, - } - - #[pallet::event] - #[pallet::generate_deposit(pub(crate) fn deposit_event)] - pub enum Event { - /// Starting Block, Round, Number of Collators Selected, Total Balance - NewRound(T::BlockNumber, RoundIndex, u32, BalanceOf), - /// Account, Amount Locked, New Total Amt Locked - JoinedCollatorCandidates(T::AccountId, BalanceOf, BalanceOf), - /// Round, Collator Account, Total Exposed Amount (includes all nominations) - CollatorChosen(RoundIndex, T::AccountId, BalanceOf), - /// Collator Account, Old Bond, New Bond - CollatorBondedMore(T::AccountId, BalanceOf, BalanceOf), - /// Collator Account, Old Bond, New Bond - CollatorBondedLess(T::AccountId, BalanceOf, BalanceOf), - CollatorWentOffline(RoundIndex, T::AccountId), - CollatorBackOnline(RoundIndex, T::AccountId), - /// Round, Collator Account, Scheduled Exit - CollatorScheduledExit(RoundIndex, T::AccountId, RoundIndex), - /// Account, Amount Unlocked, New Total Amt Locked - CollatorLeft(T::AccountId, BalanceOf, BalanceOf), - // Nominator, Collator, Amount, If in top nominations for collator after increase - NominationIncreased(T::AccountId, T::AccountId, BalanceOf, bool), - // Nominator, Collator, Amount, If in top nominations for collator after decrease - NominationDecreased(T::AccountId, T::AccountId, BalanceOf, bool), - /// Round, Nominator, Scheduled Exit - NominatorExitScheduled(RoundIndex, T::AccountId, RoundIndex), - /// Round, Nominator, Collator, Scheduled Exit - NominationRevocationScheduled(RoundIndex, T::AccountId, T::AccountId, RoundIndex), - /// Nominator, Amount Unstaked - NominatorLeft(T::AccountId, BalanceOf), - /// Nominator, Amount Locked, Collator, Nominator Position with New Total Counted if in Top - Nomination( - T::AccountId, - BalanceOf, - T::AccountId, - NominatorAdded>, - ), - /// Nominator, Collator, Amount Unstaked, New Total Amt Staked for Collator - NominatorLeftCollator(T::AccountId, T::AccountId, BalanceOf, BalanceOf), - /// Paid the account (nominator or collator) the balance as liquid rewards - Rewarded(T::AccountId, BalanceOf), - /// Transferred to account which holds funds reserved for parachain bond - ReservedForParachainBond(T::AccountId, BalanceOf), - /// Account (re)set for parachain bond treasury [old, new] - ParachainBondAccountSet(T::AccountId, T::AccountId), - /// Percent of inflation reserved for parachain bond (re)set [old, new] - ParachainBondReservePercentSet(Percent, Percent), - /// Annual inflation input (first 3) was used to derive new per-round inflation (last 3) - InflationSet(Perbill, Perbill, Perbill, Perbill, Perbill, Perbill), - /// Staking expectations set - StakeExpectationsSet(BalanceOf, BalanceOf, BalanceOf), - /// Set total selected candidates to this value [old, new] - TotalSelectedSet(u32, u32), - /// Set collator commission to this value [old, new] - CollatorCommissionSet(Perbill, Perbill), - /// Set blocks per round [current_round, first_block, old, new, new_per_round_inflation] - BlocksPerRoundSet( - RoundIndex, - T::BlockNumber, - u32, - u32, - Perbill, - Perbill, - Perbill, - ), - } - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(n: T::BlockNumber) -> Weight { - let mut round = >::get(); - if round.should_update(n) { - // mutate round - round.update(n); - // pay all stakers for T::RewardPaymentDelay rounds ago - Self::pay_stakers(round.current); - // execute all delayed collator exits - Self::execute_collator_exits(round.current); - // execute all delayed nominator exits - Self::execute_nominator_exits(round.current); - // select top collator candidates for next round - let (collator_count, nomination_count, total_staked) = - Self::select_top_candidates(round.current); - // start next round - >::put(round); - // snapshot total stake - >::insert(round.current, >::get()); - Self::deposit_event(Event::NewRound( - round.first, - round.current, - collator_count, - total_staked, - )); - T::WeightInfo::active_on_initialize(collator_count, nomination_count) - } else { - T::WeightInfo::passive_on_initialize() - } - } - } - - #[pallet::storage] - #[pallet::getter(fn collator_commission)] - /// Commission percent taken off of rewards for all collators - type CollatorCommission = StorageValue<_, Perbill, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn total_selected)] - /// The total candidates selected every round - type TotalSelected = StorageValue<_, u32, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn parachain_bond_info)] - /// Parachain bond config info { account, percent_of_inflation } - type ParachainBondInfo = - StorageValue<_, ParachainBondConfig, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn round)] - /// Current round index and next round scheduled transition - type Round = StorageValue<_, RoundInfo, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn nominator_state2)] - /// Get nominator state associated with an account if account is nominating else None - type NominatorState2 = StorageMap< - _, - Twox64Concat, - T::AccountId, - Nominator2>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn collator_state2)] - /// Get collator state associated with an account if account is collating else None - pub(crate) type CollatorState2 = StorageMap< - _, - Twox64Concat, - T::AccountId, - Collator2>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn selected_candidates)] - /// The collator candidates selected for the current round - type SelectedCandidates = StorageValue<_, Vec, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn total)] - /// Total capital locked by this staking pallet - type Total = StorageValue<_, BalanceOf, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn candidate_pool)] - /// The pool of collator candidates, each with their total backing stake - type CandidatePool = - StorageValue<_, OrderedSet>>, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn exit_queue2)] - /// A queue of collators and nominators awaiting exit - type ExitQueue2 = StorageValue<_, ExitQ, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn at_stake)] - /// Snapshot of collator nomination stake at the start of the round - pub type AtStake = StorageDoubleMap< - _, - Twox64Concat, - RoundIndex, - Twox64Concat, - T::AccountId, - CollatorSnapshot>, - ValueQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn staked)] - /// Total backing stake for selected candidates in the round - pub type Staked = - StorageMap<_, Twox64Concat, RoundIndex, BalanceOf, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn inflation_config)] - /// Inflation configuration - pub type InflationConfig = - StorageValue<_, InflationInfo>, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn points)] - /// Total points awarded to collators for block production in the round - pub type Points = StorageMap<_, Twox64Concat, RoundIndex, RewardPoint, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn awarded_pts)] - /// Points for each collator per round - pub type AwardedPts = StorageDoubleMap< - _, - Twox64Concat, - RoundIndex, - Twox64Concat, - T::AccountId, - RewardPoint, - ValueQuery, - >; - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub candidates: Vec<(T::AccountId, BalanceOf)>, - pub nominations: Vec<(T::AccountId, T::AccountId, BalanceOf)>, - pub inflation_config: InflationInfo>, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - Self { - candidates: vec![], - nominations: vec![], - ..Default::default() - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - >::put(self.inflation_config.clone()); - let mut candidate_count = 0u32; - // Initialize the candidates - for &(ref candidate, balance) in &self.candidates { - assert!( - T::Currency::free_balance(&candidate) >= balance, - "Account does not have enough balance to bond as a candidate." - ); - candidate_count += 1u32; - if let Err(error) = >::join_candidates( - T::Origin::from(Some(candidate.clone()).into()), - balance, - candidate_count, - ) { - log::warn!("Join candidates failed in genesis with error {:?}", error); - } else { - candidate_count += 1u32; - } - } - let mut col_nominator_count: BTreeMap = BTreeMap::new(); - let mut nom_nominator_count: BTreeMap = BTreeMap::new(); - // Initialize the nominations - for &(ref nominator, ref target, balance) in &self.nominations { - assert!( - T::Currency::free_balance(&nominator) >= balance, - "Account does not have enough balance to place nomination." - ); - let cn_count = if let Some(x) = col_nominator_count.get(&target) { - *x - } else { - 0u32 - }; - let nn_count = if let Some(x) = nom_nominator_count.get(&nominator) { - *x - } else { - 0u32 - }; - if let Err(error) = >::nominate( - T::Origin::from(Some(nominator.clone()).into()), - target.clone(), - balance, - cn_count, - nn_count, - ) { - log::warn!("Join nominators failed in genesis with error {:?}", error); - } else { - if let Some(x) = col_nominator_count.get_mut(&target) { - *x += 1u32; - } else { - col_nominator_count.insert(target.clone(), 1u32); - }; - if let Some(x) = nom_nominator_count.get_mut(&nominator) { - *x += 1u32; - } else { - nom_nominator_count.insert(nominator.clone(), 1u32); - }; - } - } - // Set collator commission to default config - >::put(T::DefaultCollatorCommission::get()); - // Set parachain bond config to default config - >::put(ParachainBondConfig { - // must be set soon; if not => due inflation will be sent to collators/nominators - account: T::AccountId::new([0; 32]), - percent: T::DefaultParachainBondReservePercent::get(), - }); - // Set total selected candidates to minimum config - >::put(T::MinSelectedCandidates::get()); - // Choose top TotalSelected collator candidates - let (v_count, _, total_staked) = >::select_top_candidates(1u32); - // Start Round 1 at Block 0 - let round: RoundInfo = - RoundInfo::new(1u32, 0u32.into(), T::DefaultBlocksPerRound::get()); - >::put(round); - // Snapshot total stake - >::insert(1u32, >::get()); - >::deposit_event(Event::NewRound( - T::BlockNumber::zero(), - 1u32, - v_count, - total_staked, - )); - } - } - - #[pallet::call] - impl Pallet { - /// Set the expectations for total staked. These expectations determine the issuance for - /// the round according to logic in `fn compute_issuance` - #[pallet::weight(::WeightInfo::set_staking_expectations())] - pub fn set_staking_expectations( - origin: OriginFor, - expectations: Range>, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - ensure!(expectations.is_valid(), Error::::InvalidSchedule); - let mut config = >::get(); - ensure!( - config.expect != expectations, - Error::::NoWritingSameValue - ); - config.set_expectations(expectations); - Self::deposit_event(Event::StakeExpectationsSet( - config.expect.min, - config.expect.ideal, - config.expect.max, - )); - >::put(config); - Ok(().into()) - } - /// Set the annual inflation rate to derive per-round inflation - #[pallet::weight(::WeightInfo::set_inflation())] - pub fn set_inflation( - origin: OriginFor, - schedule: Range, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - ensure!(schedule.is_valid(), Error::::InvalidSchedule); - let mut config = >::get(); - ensure!(config.annual != schedule, Error::::NoWritingSameValue); - config.annual = schedule; - config.set_round_from_annual::(schedule); - Self::deposit_event(Event::InflationSet( - config.annual.min, - config.annual.ideal, - config.annual.max, - config.round.min, - config.round.ideal, - config.round.max, - )); - >::put(config); - Ok(().into()) - } - /// Set the account that will hold funds set aside for parachain bond - #[pallet::weight(::WeightInfo::set_parachain_bond_account())] - pub fn set_parachain_bond_account( - origin: OriginFor, - new: T::AccountId, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - let ParachainBondConfig { - account: old, - percent, - } = >::get(); - if let Some(old_account) = old { - ensure!(old_account != new, Error::::NoWritingSameValue); - } - >::put(ParachainBondConfig { - account: Some(new), - percent, - }); - Self::deposit_event(Event::ParachainBondAccountSet(old, new)); - Ok(().into()) - } - /// Set the percent of inflation set aside for parachain bond - #[pallet::weight(::WeightInfo::set_parachain_bond_reserve_percent())] - pub fn set_parachain_bond_reserve_percent( - origin: OriginFor, - new: Percent, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - let ParachainBondConfig { - account, - percent: old, - } = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); - >::put(ParachainBondConfig { - account, - percent: new, - }); - Self::deposit_event(Event::ParachainBondReservePercentSet(old, new)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_total_selected())] - /// Set the total number of collator candidates selected per round - /// - changes are not applied until the start of the next round - pub fn set_total_selected(origin: OriginFor, new: u32) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - ensure!( - new >= T::MinSelectedCandidates::get(), - Error::::CannotSetBelowMin - ); - let old = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); - >::put(new); - Self::deposit_event(Event::TotalSelectedSet(old, new)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_collator_commission())] - /// Set the commission for all collators - pub fn set_collator_commission( - origin: OriginFor, - new: Perbill, - ) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - let old = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); - >::put(new); - Self::deposit_event(Event::CollatorCommissionSet(old, new)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_blocks_per_round())] - /// Set blocks per round - /// - if called with `new` less than length of current round, will transition immediately - /// in the next block - /// - also updates per-round inflation config - pub fn set_blocks_per_round( - origin: OriginFor, - new: u32, - ) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - ensure!( - new >= T::MinBlocksPerRound::get(), - Error::::CannotSetBelowMin - ); - let mut round = >::get(); - let (now, first, old) = (round.current, round.first, round.length); - ensure!(old != new, Error::::NoWritingSameValue); - round.length = new; - // update per-round inflation given new rounds per year - let mut inflation_config = >::get(); - inflation_config.reset_round(new); - >::put(round); - Self::deposit_event(Event::BlocksPerRoundSet( - now, - first, - old, - new, - inflation_config.round.min, - inflation_config.round.ideal, - inflation_config.round.max, - )); - >::put(inflation_config); - Ok(().into()) - } - /// Join the set of collator candidates - #[pallet::weight(::WeightInfo::join_candidates(*candidate_count))] - pub fn join_candidates( - origin: OriginFor, - bond: BalanceOf, - candidate_count: u32, - ) -> DispatchResultWithPostInfo { - let acc = ensure_signed(origin)?; - ensure!(!Self::is_candidate(&acc), Error::::CandidateExists); - ensure!(!Self::is_nominator(&acc), Error::::NominatorExists); - ensure!( - bond >= T::MinCollatorCandidateStk::get(), - Error::::ValBondBelowMin - ); - let mut candidates = >::get(); - let old_count = candidates.0.len() as u32; - ensure!( - candidate_count >= old_count, - Error::::TooLowCandidateCountWeightHintJoinCandidates - ); - ensure!( - candidates.insert(Bond { - owner: acc.clone(), - amount: bond - }), - Error::::CandidateExists - ); - T::Currency::reserve(&acc, bond)?; - let candidate = Collator2::new(acc.clone(), bond); - >::insert(&acc, candidate); - >::put(candidates); - let new_total = >::get().saturating_add(bond); - >::put(new_total); - Self::deposit_event(Event::JoinedCollatorCandidates(acc, bond, new_total)); - Ok(().into()) - } - /// Request to leave the set of candidates. If successful, the account is immediately - /// removed from the candidate pool to prevent selection as a collator, but unbonding is - /// executed with a delay of `T::LeaveCandidates` rounds. - #[pallet::weight(::WeightInfo::leave_candidates(*candidate_count))] - pub fn leave_candidates( - origin: OriginFor, - candidate_count: u32, - ) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = - >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(!state.is_leaving(), Error::::CandidateAlreadyLeaving); - let mut exits = >::get(); - let now = >::get().current; - let when = now + T::LeaveCandidatesDelay::get(); - exits.schedule_candidate_exit::(collator.clone(), when)?; - state.leave(when); - let mut candidates = >::get(); - ensure!( - candidate_count >= candidates.0.len() as u32, - Error::::TooLowCollatorCandidateCountToLeaveCandidates - ); - if candidates.remove(&Bond::from_owner(collator.clone())) { - >::put(candidates); - } - >::put(exits); - >::insert(&collator, state); - Self::deposit_event(Event::CollatorScheduledExit(now, collator, when)); - Ok(().into()) - } - /// Temporarily leave the set of collator candidates without unbonding - #[pallet::weight(::WeightInfo::go_offline())] - pub fn go_offline(origin: OriginFor) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = - >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(state.is_active(), Error::::AlreadyOffline); - state.go_offline(); - let mut candidates = >::get(); - if candidates.remove(&Bond::from_owner(collator.clone())) { - >::put(candidates); - } - >::insert(&collator, state); - Self::deposit_event(Event::CollatorWentOffline( - >::get().current, - collator, - )); - Ok(().into()) - } - /// Rejoin the set of collator candidates if previously had called `go_offline` - #[pallet::weight(::WeightInfo::go_online())] - pub fn go_online(origin: OriginFor) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = - >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(!state.is_active(), Error::::AlreadyActive); - ensure!(!state.is_leaving(), Error::::CannotActBecauseLeaving); - state.go_online(); - let mut candidates = >::get(); - ensure!( - candidates.insert(Bond { - owner: collator.clone(), - amount: state.total_counted - }), - Error::::AlreadyActive - ); - >::put(candidates); - >::insert(&collator, state); - Self::deposit_event(Event::CollatorBackOnline( - >::get().current, - collator, - )); - Ok(().into()) - } - /// Bond more for collator candidates - #[pallet::weight(::WeightInfo::candidate_bond_more())] - pub fn candidate_bond_more( - origin: OriginFor, - more: BalanceOf, - ) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = - >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(!state.is_leaving(), Error::::CannotActBecauseLeaving); - T::Currency::reserve(&collator, more)?; - let before = state.bond; - state.bond_more(more); - let after = state.bond; - if state.is_active() { - Self::update_active(collator.clone(), state.total_counted); - } - >::insert(&collator, state); - let new_total = >::get().saturating_add(more); - >::put(new_total); - Self::deposit_event(Event::CollatorBondedMore(collator, before, after)); - Ok(().into()) - } - /// Bond less for collator candidates - #[pallet::weight(::WeightInfo::candidate_bond_less())] - pub fn candidate_bond_less( - origin: OriginFor, - less: BalanceOf, - ) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = - >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(!state.is_leaving(), Error::::CannotActBecauseLeaving); - let before = state.bond; - let after = state.bond_less(less).ok_or(Error::::ValBondBelowMin)?; - ensure!( - after >= T::MinCollatorCandidateStk::get(), - Error::::ValBondBelowMin - ); - T::Currency::unreserve(&collator, less); - if state.is_active() { - Self::update_active(collator.clone(), state.total_counted); - } - >::insert(&collator, state); - let new_total_staked = >::get().saturating_sub(less); - >::put(new_total_staked); - Self::deposit_event(Event::CollatorBondedLess(collator, before, after)); - Ok(().into()) - } - /// If caller is not a nominator, then join the set of nominators - /// If caller is a nominator, then makes nomination to change their nomination state - #[pallet::weight( - ::WeightInfo::nominate( - *collator_nominator_count, - *nomination_count + use crate::{set::OrderedSet, InflationInfo, Range, WeightInfo}; + use frame_support::pallet_prelude::*; + use frame_support::traits::{Currency, Get, Imbalance, ReservableCurrency}; + use frame_system::pallet_prelude::*; + use parity_scale_codec::{Decode, Encode}; + use scale_info::TypeInfo; + use sp_runtime::{ + traits::{AtLeast32BitUnsigned, Saturating, Zero}, + Perbill, Percent, RuntimeDebug, + }; + use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; + + /// Pallet for parachain staking + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(PhantomData); + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + pub struct Bond { + pub owner: AccountId, + pub amount: Balance, + } + + impl Default for Bond { + fn default() -> Bond { + Bond { + owner: A::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + amount: B::default(), + } + } + } + + impl Bond { + fn from_owner(owner: A) -> Self { + Bond { + owner, + amount: B::default(), + } + } + } + + impl Eq for Bond {} + + impl Ord for Bond { + fn cmp(&self, other: &Self) -> Ordering { + self.owner.cmp(&other.owner) + } + } + + impl PartialOrd for Bond { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + + impl PartialEq for Bond { + fn eq(&self, other: &Self) -> bool { + self.owner == other.owner + } + } + + #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// The activity status of the collator + pub enum CollatorStatus { + /// Committed to be online and producing valid blocks (not equivocating) + Active, + /// Temporarily inactive and excused for inactivity + Idle, + /// Bonded until the inner round + Leaving(RoundIndex), + } + + impl Default for CollatorStatus { + fn default() -> CollatorStatus { + CollatorStatus::Active + } + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// Snapshot of collator state at the start of the round for which they are selected + pub struct CollatorSnapshot { + pub bond: Balance, + pub delegations: Vec>, + pub total: Balance, + } + + impl Default for CollatorSnapshot { + fn default() -> CollatorSnapshot { + CollatorSnapshot { + bond: B::default(), + delegations: Vec::new(), + total: B::default(), + } + } + } + + #[derive(Default, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Info needed to make delayed payments to stakers after round end + pub struct DelayedPayout { + /// Total round reward (result of compute_issuance() at round end) + pub round_issuance: Balance, + /// The total inflation paid this round to stakers (e.g. less parachain bond fund) + pub total_staking_reward: Balance, + /// Snapshot of collator commission rate at the end of the round + pub collator_commission: Perbill, + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// DEPRECATED + /// Collator state with commission fee, bonded stake, and delegations + pub struct Collator2 { + /// The account of this collator + pub id: AccountId, + /// This collator's self stake. + pub bond: Balance, + /// Set of all nominator AccountIds (to prevent >1 nomination per AccountId) + pub nominators: OrderedSet, + /// Top T::MaxDelegatorsPerCollator::get() nominators, ordered greatest to least + pub top_nominators: Vec>, + /// Bottom nominators (unbounded), ordered least to greatest + pub bottom_nominators: Vec>, + /// Sum of top delegations + self.bond + pub total_counted: Balance, + /// Sum of all delegations + self.bond = (total_counted + uncounted) + pub total_backing: Balance, + /// Current status of the collator + pub state: CollatorStatus, + } + + impl From> for CollatorCandidate { + fn from(other: Collator2) -> CollatorCandidate { + CollatorCandidate { + id: other.id, + bond: other.bond, + delegators: other.nominators, + top_delegations: other.top_nominators, + bottom_delegations: other.bottom_nominators, + total_counted: other.total_counted, + total_backing: other.total_backing, + request: None, + state: other.state, + } + } + } + + #[derive(PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Request scheduled to change the collator candidate self-bond + pub struct CandidateBondLessRequest { + pub amount: Balance, + pub when_executable: RoundIndex, + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// DEPRECATED, replaced by `CandidateMetadata` and two storage instances of `Delegations` + /// Collator candidate state with self bond + delegations + pub struct CollatorCandidate { + /// The account of this collator + pub id: AccountId, + /// This collator's self stake. + pub bond: Balance, + /// Set of all delegator AccountIds (to prevent >1 delegation per AccountId) + pub delegators: OrderedSet, + /// Top T::MaxDelegatorsPerCollator::get() delegations, ordered greatest to least + pub top_delegations: Vec>, + /// Bottom delegations (unbounded), ordered least to greatest + pub bottom_delegations: Vec>, + /// Sum of top delegations + self.bond + pub total_counted: Balance, + /// Sum of all delegations + self.bond = (total_counted + uncounted) + pub total_backing: Balance, + /// Maximum 1 pending request to decrease candidate self bond at any given time + pub request: Option>, + /// Current status of the collator + pub state: CollatorStatus, + } + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Type for top and bottom delegation storage item + pub struct Delegations { + pub delegations: Vec>, + pub total: Balance, + } + + impl Default for Delegations { + fn default() -> Delegations { + Delegations { + delegations: Vec::new(), + total: B::default(), + } + } + } + + impl + Delegations + { + pub fn sort_greatest_to_least(&mut self) { + self.delegations.sort_by(|a, b| b.amount.cmp(&a.amount)); + } + /// Insert sorted greatest to least and increase .total accordingly + /// Insertion respects first come first serve so new delegations are pushed after existing + /// delegations if the amount is the same + pub fn insert_sorted_greatest_to_least(&mut self, delegation: Bond) { + self.total = self.total.saturating_add(delegation.amount); + // if delegations nonempty && last_element == delegation.amount => push input and return + if !self.delegations.is_empty() { + // if last_element == delegation.amount => push the delegation and return early + if self.delegations[self.delegations.len() - 1].amount == delegation.amount { + self.delegations.push(delegation); + // early return + return; + } + } + // else binary search insertion + match self + .delegations + .binary_search_by(|x| delegation.amount.cmp(&x.amount)) + { + // sorted insertion on sorted vec + // enforces first come first serve for equal bond amounts + Ok(i) => { + let mut new_index = i + 1; + while new_index <= (self.delegations.len() - 1) { + if self.delegations[new_index].amount == delegation.amount { + new_index += 1; + } else { + self.delegations.insert(new_index, delegation); + return; + } + } + self.delegations.push(delegation) + } + Err(i) => self.delegations.insert(i, delegation), + } + } + /// Return the capacity status for top delegations + pub fn top_capacity(&self) -> CapacityStatus { + match &self.delegations { + x if x.len() as u32 >= T::MaxTopDelegationsPerCandidate::get() => { + CapacityStatus::Full + } + x if x.is_empty() => CapacityStatus::Empty, + _ => CapacityStatus::Partial, + } + } + /// Return the capacity status for bottom delegations + pub fn bottom_capacity(&self) -> CapacityStatus { + match &self.delegations { + x if x.len() as u32 >= T::MaxBottomDelegationsPerCandidate::get() => { + CapacityStatus::Full + } + x if x.is_empty() => CapacityStatus::Empty, + _ => CapacityStatus::Partial, + } + } + /// Return last delegation amount without popping the delegation + pub fn lowest_delegation_amount(&self) -> Balance { + self.delegations + .last() + .map(|x| x.amount) + .unwrap_or(Balance::zero()) + } + /// Return highest delegation amount + pub fn highest_delegation_amount(&self) -> Balance { + self.delegations + .first() + .map(|x| x.amount) + .unwrap_or(Balance::zero()) + } + } + + #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Capacity status for top or bottom delegations + pub enum CapacityStatus { + /// Reached capacity + Full, + /// Empty aka contains no delegations + Empty, + /// Partially full (nonempty and not full) + Partial, + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// All candidate info except the top and bottom delegations + pub struct CandidateMetadata { + /// This candidate's self bond amount + pub bond: Balance, + /// Total number of delegations to this candidate + pub delegation_count: u32, + /// Self bond + sum of top delegations + pub total_counted: Balance, + /// The smallest top delegation amount + pub lowest_top_delegation_amount: Balance, + /// The highest bottom delegation amount + pub highest_bottom_delegation_amount: Balance, + /// The smallest bottom delegation amount + pub lowest_bottom_delegation_amount: Balance, + /// Capacity status for top delegations + pub top_capacity: CapacityStatus, + /// Capacity status for bottom delegations + pub bottom_capacity: CapacityStatus, + /// Maximum 1 pending request to decrease candidate self bond at any given time + pub request: Option>, + /// Current status of the collator + pub status: CollatorStatus, + } + + impl< + Balance: Copy + + Zero + + PartialOrd + + sp_std::ops::AddAssign + + sp_std::ops::SubAssign + + sp_std::ops::Sub + + sp_std::fmt::Debug, + > CandidateMetadata + { + pub fn new(bond: Balance) -> Self { + CandidateMetadata { + bond, + delegation_count: 0u32, + total_counted: bond, + lowest_top_delegation_amount: Zero::zero(), + highest_bottom_delegation_amount: Zero::zero(), + lowest_bottom_delegation_amount: Zero::zero(), + top_capacity: CapacityStatus::Empty, + bottom_capacity: CapacityStatus::Empty, + request: None, + status: CollatorStatus::Active, + } + } + pub fn is_active(&self) -> bool { + matches!(self.status, CollatorStatus::Active) + } + pub fn is_leaving(&self) -> bool { + matches!(self.status, CollatorStatus::Leaving(_)) + } + pub fn schedule_leave( + &mut self, + ) -> Result<(RoundIndex, RoundIndex), DispatchError> { + ensure!(!self.is_leaving(), Error::::CandidateAlreadyLeaving); + let now = >::get().current; + let when = now + T::LeaveCandidatesDelay::get(); + self.status = CollatorStatus::Leaving(when); + Ok((now, when)) + } + pub fn can_leave(&self) -> DispatchResult { + if let CollatorStatus::Leaving(when) = self.status { + ensure!( + >::get().current >= when, + Error::::CandidateCannotLeaveYet + ); + Ok(()) + } else { + Err(Error::::CandidateNotLeaving.into()) + } + } + pub fn go_offline(&mut self) { + self.status = CollatorStatus::Idle; + } + pub fn go_online(&mut self) { + self.status = CollatorStatus::Active; + } + pub fn bond_more(&mut self, who: T::AccountId, more: Balance) -> DispatchResult + where + BalanceOf: From, + { + T::Currency::reserve(&who, more.into())?; + let new_total = >::get().saturating_add(more.into()); + >::put(new_total); + self.bond += more; + self.total_counted += more; + >::deposit_event(Event::CandidateBondedMore( + who.clone(), + more.into(), + self.bond.into(), + )); + Ok(()) + } + /// Schedule executable decrease of collator candidate self bond + /// Returns the round at which the collator can execute the pending request + pub fn schedule_bond_less( + &mut self, + less: Balance, + ) -> Result + where + BalanceOf: Into, + { + // ensure no pending request + ensure!( + self.request.is_none(), + Error::::PendingCandidateRequestAlreadyExists + ); + // ensure bond above min after decrease + ensure!(self.bond > less, Error::::CandidateBondBelowMin); + ensure!( + self.bond - less >= T::MinCandidateStk::get().into(), + Error::::CandidateBondBelowMin + ); + let when_executable = >::get().current + T::CandidateBondLessDelay::get(); + self.request = Some(CandidateBondLessRequest { + amount: less, + when_executable, + }); + Ok(when_executable) + } + /// Execute pending request to decrease the collator self bond + /// Returns the event to be emitted + pub fn execute_bond_less(&mut self, who: T::AccountId) -> DispatchResult + where + BalanceOf: From, + { + let request = self + .request + .ok_or(Error::::PendingCandidateRequestsDNE)?; + ensure!( + request.when_executable <= >::get().current, + Error::::PendingCandidateRequestNotDueYet + ); + T::Currency::unreserve(&who, request.amount.into()); + let new_total_staked = >::get().saturating_sub(request.amount.into()); + >::put(new_total_staked); + // Arithmetic assumptions are self.bond > less && self.bond - less > CollatorMinBond + // (assumptions enforced by `schedule_bond_less`; if storage corrupts, must re-verify) + self.bond -= request.amount; + self.total_counted -= request.amount; + let event = Event::CandidateBondedLess( + who.clone().into(), + request.amount.into(), + self.bond.into(), + ); + // reset s.t. no pending request + self.request = None; + // update candidate pool value because it must change if self bond changes + if self.is_active() { + Pallet::::update_active(who.into(), self.total_counted.into()); + } + Pallet::::deposit_event(event); + Ok(()) + } + /// Cancel candidate bond less request + pub fn cancel_bond_less(&mut self, who: T::AccountId) -> DispatchResult + where + BalanceOf: From, + { + let request = self + .request + .ok_or(Error::::PendingCandidateRequestsDNE)?; + let event = Event::CancelledCandidateBondLess( + who.clone().into(), + request.amount.into(), + request.when_executable, + ); + self.request = None; + Pallet::::deposit_event(event); + Ok(()) + } + /// Reset top delegations metadata + pub fn reset_top_data( + &mut self, + top_delegations: &Delegations>, + ) where + BalanceOf: Into, + { + self.lowest_top_delegation_amount = top_delegations.lowest_delegation_amount().into(); + self.top_capacity = top_delegations.top_capacity::(); + self.total_counted = self.bond + top_delegations.total.into(); + } + /// Reset bottom delegations metadata + pub fn reset_bottom_data( + &mut self, + bottom_delegations: &Delegations>, + ) where + BalanceOf: Into, + { + self.lowest_bottom_delegation_amount = + bottom_delegations.lowest_delegation_amount().into(); + self.highest_bottom_delegation_amount = + bottom_delegations.highest_delegation_amount().into(); + self.bottom_capacity = bottom_delegations.bottom_capacity::(); + } + /// Add delegation + /// Returns whether delegator was added and an optional negative total counted remainder + /// for if a bottom delegation was kicked + /// MUST ensure no delegation exists for this candidate in the `DelegatorState` before call + pub fn add_delegation( + &mut self, + candidate: &T::AccountId, + delegation: Bond>, + ) -> Result<(DelegatorAdded, Option), DispatchError> + where + BalanceOf: Into, + { + let mut less_total_staked = None; + let delegator_added = match self.top_capacity { + CapacityStatus::Full => { + // top is full, insert into top iff the lowest_top < amount + if self.lowest_top_delegation_amount < delegation.amount.into() { + // bumps lowest top to the bottom inside this function call + less_total_staked = self.add_top_delegation::(candidate, delegation); + DelegatorAdded::AddedToTop { + new_total: self.total_counted, + } + } else { + // if bottom is full, only insert if greater than lowest bottom (which will + // be bumped out) + if matches!(self.bottom_capacity, CapacityStatus::Full) { + ensure!( + delegation.amount.into() > self.lowest_bottom_delegation_amount, + Error::::CannotDelegateLessThanLowestBottomWhenBottomIsFull + ); + // need to subtract from total staked + less_total_staked = Some(self.lowest_bottom_delegation_amount); + } + // insert into bottom + self.add_bottom_delegation::(false, candidate, delegation); + DelegatorAdded::AddedToBottom + } + } + // top is either empty or partially full + _ => { + self.add_top_delegation::(candidate, delegation); + DelegatorAdded::AddedToTop { + new_total: self.total_counted, + } + } + }; + Ok((delegator_added, less_total_staked)) + } + /// Add delegation to top delegation + /// Returns Option + /// Only call if lowest top delegation is less than delegation.amount || !top_full + pub fn add_top_delegation( + &mut self, + candidate: &T::AccountId, + delegation: Bond>, + ) -> Option + where + BalanceOf: Into, + { + let mut less_total_staked = None; + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo existence => TopDelegations existence"); + let max_top_delegations_per_candidate = T::MaxTopDelegationsPerCandidate::get(); + if top_delegations.delegations.len() as u32 == max_top_delegations_per_candidate { + // pop lowest top delegation + let new_bottom_delegation = top_delegations.delegations.pop().expect(""); + top_delegations.total = top_delegations + .total + .saturating_sub(new_bottom_delegation.amount); + if matches!(self.bottom_capacity, CapacityStatus::Full) { + less_total_staked = Some(self.lowest_bottom_delegation_amount); + } + self.add_bottom_delegation::(true, candidate, new_bottom_delegation); + } + // insert into top + top_delegations.insert_sorted_greatest_to_least(delegation); + // update candidate info + self.reset_top_data::(&top_delegations); + if less_total_staked.is_none() { + // only increment delegation count if we are not kicking a bottom delegation + self.delegation_count += 1u32; + } + >::insert(&candidate, top_delegations); + less_total_staked + } + /// Add delegation to bottom delegations + /// Check before call that if capacity is full, inserted delegation is higher than lowest + /// bottom delegation (and if so, need to adjust the total storage item) + /// CALLER MUST ensure(lowest_bottom_to_be_kicked.amount < delegation.amount) + pub fn add_bottom_delegation( + &mut self, + bumped_from_top: bool, + candidate: &T::AccountId, + delegation: Bond>, + ) where + BalanceOf: Into, + { + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo existence => BottomDelegations existence"); + // if bottom is full, kick the lowest bottom (which is expected to be lower than input + // as per check) + let increase_delegation_count = if bottom_delegations.delegations.len() as u32 + == T::MaxBottomDelegationsPerCandidate::get() + { + let lowest_bottom_to_be_kicked = bottom_delegations + .delegations + .pop() + .expect("if at full capacity (>0), then >0 bottom delegations exist; qed"); + // EXPECT lowest_bottom_to_be_kicked.amount < delegation.amount enforced by caller + // if lowest_bottom_to_be_kicked.amount == delegation.amount, we will still kick + // the lowest bottom to enforce first come first served + bottom_delegations.total = bottom_delegations + .total + .saturating_sub(lowest_bottom_to_be_kicked.amount); + // update delegator state + // unreserve kicked bottom + T::Currency::unreserve( + &lowest_bottom_to_be_kicked.owner, + lowest_bottom_to_be_kicked.amount, + ); + // total staked is updated via propagation of lowest bottom delegation amount prior + // to call + let mut delegator_state = + >::get(&lowest_bottom_to_be_kicked.owner) + .expect("Delegation existence => DelegatorState existence"); + let leaving = delegator_state.delegations.0.len() == 1usize; + delegator_state.rm_delegation(candidate); + Pallet::::deposit_event(Event::DelegationKicked( + lowest_bottom_to_be_kicked.owner.clone(), + candidate.clone(), + lowest_bottom_to_be_kicked.amount, + )); + if leaving { + >::remove(&lowest_bottom_to_be_kicked.owner); + Pallet::::deposit_event(Event::DelegatorLeft( + lowest_bottom_to_be_kicked.owner, + lowest_bottom_to_be_kicked.amount, + )); + } else { + >::insert(&lowest_bottom_to_be_kicked.owner, delegator_state); + } + false + } else { + !bumped_from_top + }; + // only increase delegation count if new bottom delegation (1) doesn't come from top && + // (2) doesn't pop the lowest delegation from the bottom + if increase_delegation_count { + self.delegation_count += 1u32; + } + bottom_delegations.insert_sorted_greatest_to_least(delegation); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + } + /// Remove delegation + /// Removes from top if amount is above lowest top or top is not full + /// Return Ok(if_total_counted_changed) + pub fn rm_delegation_if_exists( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + amount: Balance, + ) -> Result + where + BalanceOf: Into + From, + { + let amount_geq_lowest_top = amount >= self.lowest_top_delegation_amount; + let top_is_not_full = !matches!(self.top_capacity, CapacityStatus::Full); + let lowest_top_eq_highest_bottom = + self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; + let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); + if top_is_not_full || (amount_geq_lowest_top && !lowest_top_eq_highest_bottom) { + self.rm_top_delegation::(candidate, delegator) + } else if amount_geq_lowest_top && lowest_top_eq_highest_bottom { + let result = self.rm_top_delegation::(candidate, delegator.clone()); + if result == Err(delegation_dne_err) { + // worst case removal + self.rm_bottom_delegation::(candidate, delegator) + } else { + result + } + } else { + self.rm_bottom_delegation::(candidate, delegator) + } + } + /// Remove top delegation, bumps top bottom delegation if exists + pub fn rm_top_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + ) -> Result + where + BalanceOf: Into, + { + let old_total_counted = self.total_counted; + // remove top delegation + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo exists => TopDelegations exists"); + let mut actual_amount_option: Option> = None; + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + actual_amount_option = Some(d.amount); + None + } + }) + .collect(); + let actual_amount = actual_amount_option.ok_or(Error::::DelegationDNE)?; + top_delegations.total -= actual_amount; + // if bottom nonempty => bump top bottom to top + if !matches!(self.bottom_capacity, CapacityStatus::Empty) { + let mut bottom_delegations = >::get(candidate) + .expect("bottom is nonempty as just checked"); + // expect already stored greatest to least by bond amount + let highest_bottom_delegation = bottom_delegations.delegations.remove(0); + bottom_delegations.total = bottom_delegations + .total + .saturating_sub(highest_bottom_delegation.amount); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + // insert highest bottom into top delegations + top_delegations.insert_sorted_greatest_to_least(highest_bottom_delegation); + } + // update candidate info + self.reset_top_data::(&top_delegations); + self.delegation_count -= 1u32; + >::insert(candidate, top_delegations); + // return whether total counted changed + Ok(old_total_counted == self.total_counted) + } + /// Remove bottom delegation + /// Returns if_total_counted_changed: bool + pub fn rm_bottom_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + ) -> Result + where + BalanceOf: Into, + { + // remove bottom delegation + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo exists => BottomDelegations exists"); + let mut actual_amount_option: Option> = None; + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + actual_amount_option = Some(d.amount); + None + } + }) + .collect(); + let actual_amount = actual_amount_option.ok_or(Error::::DelegationDNE)?; + bottom_delegations.total = bottom_delegations.total.saturating_sub(actual_amount); + // update candidate info + self.reset_bottom_data::(&bottom_delegations); + self.delegation_count = self.delegation_count.saturating_sub(1u32); + >::insert(candidate, bottom_delegations); + Ok(false) + } + /// Increase delegation amount + pub fn increase_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: BalanceOf, + more: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let lowest_top_eq_highest_bottom = + self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; + let bond_geq_lowest_top = bond.into() >= self.lowest_top_delegation_amount; + let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); + if bond_geq_lowest_top && !lowest_top_eq_highest_bottom { + // definitely in top + self.increase_top_delegation::(candidate, delegator.clone(), more) + } else if bond_geq_lowest_top && lowest_top_eq_highest_bottom { + // update top but if error then update bottom (because could be in bottom because + // lowest_top_eq_highest_bottom) + let result = self.increase_top_delegation::(candidate, delegator.clone(), more); + if result == Err(delegation_dne_err) { + self.increase_bottom_delegation::(candidate, delegator, bond, more) + } else { + result + } + } else { + self.increase_bottom_delegation::(candidate, delegator, bond, more) + } + } + /// Increase top delegation + pub fn increase_top_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + more: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo exists => TopDelegations exists"); + let mut in_top = false; + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + in_top = true; + let new_amount = d.amount.saturating_add(more); + Bond { + owner: d.owner, + amount: new_amount, + } + } + }) + .collect(); + ensure!(in_top, Error::::DelegationDNE); + top_delegations.sort_greatest_to_least(); + self.reset_top_data::(&top_delegations); + >::insert(candidate, top_delegations); + Ok(true) + } + /// Increase bottom delegation + pub fn increase_bottom_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: BalanceOf, + more: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let mut bottom_delegations = + >::get(candidate).ok_or(Error::::CandidateDNE)?; + let mut delegation_option: Option>> = None; + let in_top_after = + if (bond.saturating_add(more)).into() > self.lowest_top_delegation_amount { + // bump it from bottom + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + delegation_option = Some(Bond { + owner: d.owner, + amount: d.amount.saturating_add(more), + }); + None + } + }) + .collect(); + let delegation = delegation_option.ok_or(Error::::DelegationDNE)?; + bottom_delegations.total = bottom_delegations.total.saturating_sub(bond); + // add it to top + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo existence => TopDelegations existence"); + // if top is full, pop lowest top + if matches!(top_delegations.top_capacity::(), CapacityStatus::Full) { + // pop lowest top delegation + let new_bottom_delegation = top_delegations + .delegations + .pop() + .expect("Top capacity full => Exists at least 1 top delegation"); + top_delegations.total = top_delegations + .total + .saturating_sub(new_bottom_delegation.amount); + bottom_delegations.insert_sorted_greatest_to_least(new_bottom_delegation); + } + // insert into top + top_delegations.insert_sorted_greatest_to_least(delegation); + self.reset_top_data::(&top_delegations); + >::insert(candidate, top_delegations); + true + } else { + let mut in_bottom = false; + // just increase the delegation + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + in_bottom = true; + Bond { + owner: d.owner, + amount: d.amount.saturating_add(more), + } + } + }) + .collect(); + ensure!(in_bottom, Error::::DelegationDNE); + bottom_delegations.sort_greatest_to_least(); + false + }; + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + Ok(in_top_after) + } + /// Decrease delegation + pub fn decrease_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: Balance, + less: BalanceOf, + ) -> Result + where + BalanceOf: Into + From, + { + let lowest_top_eq_highest_bottom = + self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; + let bond_geq_lowest_top = bond >= self.lowest_top_delegation_amount; + let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); + if bond_geq_lowest_top && !lowest_top_eq_highest_bottom { + // definitely in top + self.decrease_top_delegation::(candidate, delegator.clone(), bond.into(), less) + } else if bond_geq_lowest_top && lowest_top_eq_highest_bottom { + // update top but if error then update bottom (because could be in bottom because + // lowest_top_eq_highest_bottom) + let result = self.decrease_top_delegation::( + candidate, + delegator.clone(), + bond.into(), + less, + ); + if result == Err(delegation_dne_err) { + self.decrease_bottom_delegation::(candidate, delegator, less) + } else { + result + } + } else { + self.decrease_bottom_delegation::(candidate, delegator, less) + } + } + /// Decrease top delegation + pub fn decrease_top_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: BalanceOf, + less: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + // The delegation after the `decrease-delegation` will be strictly less than the + // highest bottom delegation + let bond_after_less_than_highest_bottom = + bond.saturating_sub(less).into() < self.highest_bottom_delegation_amount; + // The top delegations is full and the bottom delegations has at least one delegation + let full_top_and_nonempty_bottom = matches!(self.top_capacity, CapacityStatus::Full) + && !matches!(self.bottom_capacity, CapacityStatus::Empty); + let mut top_delegations = + >::get(candidate).ok_or(Error::::CandidateDNE)?; + let in_top_after = if bond_after_less_than_highest_bottom + && full_top_and_nonempty_bottom + { + let mut delegation_option: Option>> = None; + // take delegation from top + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + top_delegations.total = top_delegations.total.saturating_sub(d.amount); + delegation_option = Some(Bond { + owner: d.owner, + amount: d.amount.saturating_sub(less), + }); + None + } + }) + .collect(); + let delegation = delegation_option.ok_or(Error::::DelegationDNE)?; + // pop highest bottom by reverse and popping + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo existence => BottomDelegations existence"); + let highest_bottom_delegation = bottom_delegations.delegations.remove(0); + bottom_delegations.total = bottom_delegations + .total + .saturating_sub(highest_bottom_delegation.amount); + // insert highest bottom into top + top_delegations.insert_sorted_greatest_to_least(highest_bottom_delegation); + // insert previous top into bottom + bottom_delegations.insert_sorted_greatest_to_least(delegation); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + false + } else { + // keep it in the top + let mut is_in_top = false; + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + is_in_top = true; + Bond { + owner: d.owner, + amount: d.amount.saturating_sub(less), + } + } + }) + .collect(); + ensure!(is_in_top, Error::::DelegationDNE); + top_delegations.total = top_delegations.total.saturating_sub(less); + top_delegations.sort_greatest_to_least(); + true + }; + self.reset_top_data::(&top_delegations); + >::insert(candidate, top_delegations); + Ok(in_top_after) + } + /// Decrease bottom delegation + pub fn decrease_bottom_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + less: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo exists => BottomDelegations exists"); + let mut in_bottom = false; + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + in_bottom = true; + Bond { + owner: d.owner, + amount: d.amount.saturating_sub(less), + } + } + }) + .collect(); + ensure!(in_bottom, Error::::DelegationDNE); + bottom_delegations.sort_greatest_to_least(); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + Ok(false) + } + } + + // Temporary manual implementation for migration testing purposes + impl PartialEq for CollatorCandidate { + fn eq(&self, other: &Self) -> bool { + let must_be_true = self.id == other.id + && self.bond == other.bond + && self.total_counted == other.total_counted + && self.total_backing == other.total_backing + && self.request == other.request + && self.state == other.state; + if !must_be_true { + return false; + } + for (x, y) in self.delegators.0.iter().zip(other.delegators.0.iter()) { + if x != y { + return false; + } + } + for ( + Bond { + owner: o1, + amount: a1, + }, + Bond { + owner: o2, + amount: a2, + }, + ) in self + .top_delegations + .iter() + .zip(other.top_delegations.iter()) + { + if o1 != o2 || a1 != a2 { + return false; + } + } + for ( + Bond { + owner: o1, + amount: a1, + }, + Bond { + owner: o2, + amount: a2, + }, + ) in self + .bottom_delegations + .iter() + .zip(other.bottom_delegations.iter()) + { + if o1 != o2 || a1 != a2 { + return false; + } + } + true + } + } + + /// Convey relevant information describing if a delegator was added to the top or bottom + /// Delegations added to the top yield a new total + #[derive(Clone, Copy, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + pub enum DelegatorAdded { + AddedToTop { new_total: B }, + AddedToBottom, + } + + impl< + A: Ord + Clone + sp_std::fmt::Debug, + B: AtLeast32BitUnsigned + + Ord + + Copy + + sp_std::ops::AddAssign + + sp_std::ops::SubAssign + + sp_std::fmt::Debug, + > CollatorCandidate + { + pub fn is_active(&self) -> bool { + self.state == CollatorStatus::Active + } + } + + impl From> for CollatorSnapshot { + fn from(other: CollatorCandidate) -> CollatorSnapshot { + CollatorSnapshot { + bond: other.bond, + delegations: other.top_delegations, + total: other.total_counted, + } + } + } + + #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + pub enum DelegatorStatus { + /// Active with no scheduled exit + Active, + /// Schedule exit to revoke all ongoing delegations + Leaving(RoundIndex), + } + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Delegator state + pub struct Delegator { + /// Delegator account + pub id: AccountId, + /// All current delegations + pub delegations: OrderedSet>, + /// Total balance locked for this delegator + pub total: Balance, + /// Requests to change delegations, relevant iff active + pub requests: PendingDelegationRequests, + /// Status for this delegator + pub status: DelegatorStatus, + } + + // Temporary manual implementation for migration testing purposes + impl PartialEq for Delegator { + fn eq(&self, other: &Self) -> bool { + let must_be_true = self.id == other.id + && self.total == other.total + && self.requests == other.requests + && self.status == other.status; + if !must_be_true { + return false; + } + for ( + Bond { + owner: o1, + amount: a1, + }, + Bond { + owner: o2, + amount: a2, + }, + ) in self.delegations.0.iter().zip(other.delegations.0.iter()) + { + if o1 != o2 || a1 != a2 { + return false; + } + } + true + } + } + + impl< + AccountId: Ord + Clone, + Balance: Copy + + sp_std::ops::AddAssign + + sp_std::ops::Add + + sp_std::ops::SubAssign + + sp_std::ops::Sub + + Ord + + Zero + + Default, + > Delegator + { + pub fn new(id: AccountId, collator: AccountId, amount: Balance) -> Self { + Delegator { + id, + delegations: OrderedSet::from(vec![Bond { + owner: collator, + amount, + }]), + total: amount, + requests: PendingDelegationRequests::new(), + status: DelegatorStatus::Active, + } + } + pub fn requests(&self) -> BTreeMap> { + self.requests.requests.clone() + } + pub fn is_active(&self) -> bool { + matches!(self.status, DelegatorStatus::Active) + } + pub fn is_leaving(&self) -> bool { + matches!(self.status, DelegatorStatus::Leaving(_)) + } + /// Can only leave if the current round is less than or equal to scheduled execution round + /// - returns None if not in leaving state + pub fn can_execute_leave(&self, delegation_weight_hint: u32) -> DispatchResult { + ensure!( + delegation_weight_hint >= (self.delegations.0.len() as u32), + Error::::TooLowDelegationCountToLeaveDelegators + ); + if let DelegatorStatus::Leaving(when) = self.status { + ensure!( + >::get().current >= when, + Error::::DelegatorCannotLeaveYet + ); + Ok(()) + } else { + Err(Error::::DelegatorNotLeaving.into()) + } + } + /// Set status to leaving + pub(crate) fn set_leaving(&mut self, when: RoundIndex) { + self.status = DelegatorStatus::Leaving(when); + } + /// Schedule status to exit + pub fn schedule_leave(&mut self) -> (RoundIndex, RoundIndex) { + let now = >::get().current; + let when = now + T::LeaveDelegatorsDelay::get(); + self.set_leaving(when); + (now, when) + } + /// Set delegator status to active + pub fn cancel_leave(&mut self) { + self.status = DelegatorStatus::Active + } + pub fn add_delegation(&mut self, bond: Bond) -> bool { + let amt = bond.amount; + if self.delegations.insert(bond) { + self.total += amt; + true + } else { + false + } + } + // Return Some(remaining balance), must be more than MinDelegatorStk + // Return None if delegation not found + pub fn rm_delegation(&mut self, collator: &AccountId) -> Option { + let mut amt: Option = None; + let delegations = self + .delegations + .0 + .iter() + .filter_map(|x| { + if &x.owner == collator { + amt = Some(x.amount); + None + } else { + Some(x.clone()) + } + }) + .collect(); + if let Some(balance) = amt { + self.delegations = OrderedSet::from(delegations); + self.total -= balance; + Some(self.total) + } else { + None + } + } + pub fn increase_delegation( + &mut self, + candidate: AccountId, + amount: Balance, + ) -> DispatchResult + where + BalanceOf: From, + T::AccountId: From, + Delegator>: From>, + { + let delegator_id: T::AccountId = self.id.clone().into(); + let candidate_id: T::AccountId = candidate.clone().into(); + let balance_amt: BalanceOf = amount.into(); + // increase delegation + for x in &mut self.delegations.0 { + if x.owner == candidate { + let before_amount: BalanceOf = x.amount.into(); + x.amount += amount; + self.total += amount; + // update collator state delegation + let mut collator_state = + >::get(&candidate_id).ok_or(Error::::CandidateDNE)?; + T::Currency::reserve(&self.id.clone().into(), balance_amt)?; + let before = collator_state.total_counted; + let in_top = collator_state.increase_delegation::( + &candidate_id, + delegator_id.clone(), + before_amount, + balance_amt, + )?; + let after = collator_state.total_counted; + if collator_state.is_active() && (before != after) { + Pallet::::update_active(candidate_id.clone(), after); + } + >::insert(&candidate_id, collator_state); + let new_total_staked = >::get().saturating_add(balance_amt); + >::put(new_total_staked); + let nom_st: Delegator> = self.clone().into(); + >::insert(&delegator_id, nom_st); + Pallet::::deposit_event(Event::DelegationIncreased( + delegator_id, + candidate_id, + balance_amt, + in_top, + )); + return Ok(()); + } + } + Err(Error::::DelegationDNE.into()) + } + /// Schedule decrease delegation + pub fn schedule_decrease_delegation( + &mut self, + collator: AccountId, + less: Balance, + ) -> Result + where + BalanceOf: Into + From, + { + // get delegation amount + let Bond { amount, .. } = self + .delegations + .0 + .iter() + .find(|b| b.owner == collator) + .ok_or(Error::::DelegationDNE)?; + ensure!(*amount > less, Error::::DelegatorBondBelowMin); + let expected_amt: BalanceOf = (*amount - less).into(); + ensure!( + expected_amt >= T::MinDelegation::get(), + Error::::DelegationBelowMin + ); + // Net Total is total after pending orders are executed + let net_total = self.total - self.requests.less_total; + // Net Total is always >= MinDelegatorStk + let max_subtracted_amount = net_total - T::MinDelegatorStk::get().into(); + ensure!( + less <= max_subtracted_amount, + Error::::DelegatorBondBelowMin + ); + let when = >::get().current + T::DelegationBondLessDelay::get(); + self.requests.bond_less::(collator, less, when)?; + Ok(when) + } + /// Temporary function to migrate revocations + pub fn hotfix_set_revoke(&mut self, collator: AccountId, when: RoundIndex) { + // get delegation amount + let maybe_bond = self.delegations.0.iter().find(|b| b.owner == collator); + if let Some(Bond { amount, .. }) = maybe_bond { + // add revocation to pending requests + if let Err(e) = self.requests.revoke::(collator, *amount, when) { + log::warn!("Migrate revocation request failed with error: {:?}", e); + } + } else { + log::warn!("Migrate revocation request failed because delegation DNE"); + } + } + /// Schedule revocation for the given collator + pub fn schedule_revoke( + &mut self, + collator: AccountId, + ) -> Result<(RoundIndex, RoundIndex), DispatchError> + where + BalanceOf: Into, + { + // get delegation amount + let Bond { amount, .. } = self + .delegations + .0 + .iter() + .find(|b| b.owner == collator) + .ok_or(Error::::DelegationDNE)?; + let now = >::get().current; + let when = now + T::RevokeDelegationDelay::get(); + // add revocation to pending requests + self.requests.revoke::(collator, *amount, when)?; + Ok((now, when)) + } + /// Execute pending delegation change request + pub fn execute_pending_request(&mut self, candidate: AccountId) -> DispatchResult + where + BalanceOf: From + Into, + T::AccountId: From, + Delegator>: From>, + { + let now = >::get().current; + let DelegationRequest { + amount, + action, + when_executable, + .. + } = self + .requests + .requests + .remove(&candidate) + .ok_or(Error::::PendingDelegationRequestDNE)?; + ensure!( + when_executable <= now, + Error::::PendingDelegationRequestNotDueYet + ); + let (balance_amt, candidate_id, delegator_id): ( + BalanceOf, + T::AccountId, + T::AccountId, + ) = ( + amount.into(), + candidate.clone().into(), + self.id.clone().into(), + ); + match action { + DelegationChange::Revoke => { + // revoking last delegation => leaving set of delegators + let leaving = if self.delegations.0.len() == 1usize { + true + } else { + ensure!( + self.total - T::MinDelegatorStk::get().into() >= amount, + Error::::DelegatorBondBelowMin + ); + false + }; + // remove from pending requests + self.requests.less_total -= amount; + self.requests.revocations_count -= 1u32; + // remove delegation from delegator state + self.rm_delegation(&candidate); + // remove delegation from collator state delegations + Pallet::::delegator_leaves_candidate( + candidate_id.clone(), + delegator_id.clone(), + balance_amt, + )?; + Pallet::::deposit_event(Event::DelegationRevoked( + delegator_id.clone(), + candidate_id, + balance_amt, + )); + if leaving { + >::remove(&delegator_id); + Pallet::::deposit_event(Event::DelegatorLeft(delegator_id, balance_amt)); + } else { + let nom_st: Delegator> = self.clone().into(); + >::insert(&delegator_id, nom_st); + } + Ok(()) + } + DelegationChange::Decrease => { + // remove from pending requests + self.requests.less_total -= amount; + // decrease delegation + for x in &mut self.delegations.0 { + if x.owner == candidate { + if x.amount > amount { + let amount_before: BalanceOf = x.amount.into(); + x.amount -= amount; + self.total -= amount; + let new_total: BalanceOf = self.total.into(); + ensure!( + new_total >= T::MinDelegation::get(), + Error::::DelegationBelowMin + ); + ensure!( + new_total >= T::MinDelegatorStk::get(), + Error::::DelegatorBondBelowMin + ); + let mut collator = >::get(&candidate_id) + .ok_or(Error::::CandidateDNE)?; + T::Currency::unreserve(&delegator_id, balance_amt); + let before = collator.total_counted; + // need to go into decrease_delegation + let in_top = collator.decrease_delegation::( + &candidate_id, + delegator_id.clone(), + amount_before, + balance_amt, + )?; + let after = collator.total_counted; + if collator.is_active() && (before != after) { + Pallet::::update_active(candidate_id.clone(), after); + } + >::insert(&candidate_id, collator); + let new_total_staked = + >::get().saturating_sub(balance_amt); + >::put(new_total_staked); + let nom_st: Delegator> = + self.clone().into(); + >::insert(&delegator_id, nom_st); + Pallet::::deposit_event(Event::DelegationDecreased( + delegator_id, + candidate_id, + balance_amt, + in_top, + )); + return Ok(()); + } else { + // must rm entire delegation if x.amount <= less or cancel request + return Err(Error::::DelegationBelowMin.into()); + } + } + } + Err(Error::::DelegationDNE.into()) + } + } + } + /// Cancel pending delegation change request + pub fn cancel_pending_request( + &mut self, + candidate: AccountId, + ) -> Result, DispatchError> { + let order = self + .requests + .requests + .remove(&candidate) + .ok_or(Error::::PendingDelegationRequestDNE)?; + match order.action { + DelegationChange::Revoke => { + self.requests.revocations_count -= 1u32; + self.requests.less_total -= order.amount; + } + DelegationChange::Decrease => { + self.requests.less_total -= order.amount; + } + } + Ok(order) + } + } + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Changes requested by the delegator + /// - limit of 1 ongoing change per delegation + pub enum DelegationChange { + Revoke, + Decrease, + } + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + pub struct DelegationRequest { + pub collator: AccountId, + pub amount: Balance, + pub when_executable: RoundIndex, + pub action: DelegationChange, + } + + #[derive(Clone, Encode, PartialEq, Decode, RuntimeDebug, TypeInfo)] + /// Pending requests to mutate delegations for each delegator + pub struct PendingDelegationRequests { + /// Number of pending revocations (necessary for determining whether revoke is exit) + pub revocations_count: u32, + /// Map from collator -> Request (enforces at most 1 pending request per delegation) + pub requests: BTreeMap>, + /// Sum of pending revocation amounts + bond less amounts + pub less_total: Balance, + } + + impl Default for PendingDelegationRequests { + fn default() -> PendingDelegationRequests { + PendingDelegationRequests { + revocations_count: 0u32, + requests: BTreeMap::new(), + less_total: B::zero(), + } + } + } + + impl< + A: Ord + Clone, + B: Zero + + Ord + + Copy + + Clone + + sp_std::ops::AddAssign + + sp_std::ops::Add + + sp_std::ops::SubAssign + + sp_std::ops::Sub, + > PendingDelegationRequests + { + /// New default (empty) pending requests + pub fn new() -> PendingDelegationRequests { + PendingDelegationRequests::default() + } + /// Add bond less order to pending requests, only succeeds if returns true + /// - limit is the maximum amount allowed that can be subtracted from the delegation + /// before it would be below the minimum delegation amount + pub fn bond_less( + &mut self, + collator: A, + amount: B, + when_executable: RoundIndex, + ) -> DispatchResult { + ensure!( + self.requests.get(&collator).is_none(), + Error::::PendingDelegationRequestAlreadyExists + ); + self.requests.insert( + collator.clone(), + DelegationRequest { + collator, + amount, + when_executable, + action: DelegationChange::Decrease, + }, + ); + self.less_total += amount; + Ok(()) + } + /// Add revoke order to pending requests + /// - limit is the maximum amount allowed that can be subtracted from the delegation + /// before it would be below the minimum delegation amount + pub fn revoke( + &mut self, + collator: A, + amount: B, + when_executable: RoundIndex, + ) -> DispatchResult { + ensure!( + self.requests.get(&collator).is_none(), + Error::::PendingDelegationRequestAlreadyExists + ); + self.requests.insert( + collator.clone(), + DelegationRequest { + collator, + amount, + when_executable, + action: DelegationChange::Revoke, + }, + ); + self.revocations_count += 1u32; + self.less_total += amount; + Ok(()) + } + } + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + /// DEPRECATED in favor of Delegator + /// Nominator state + pub struct Nominator2 { + /// All current delegations + pub delegations: OrderedSet>, + /// Delegations scheduled to be revoked + pub revocations: OrderedSet, + /// Total balance locked for this nominator + pub total: Balance, + /// Total number of revocations scheduled to be executed + pub scheduled_revocations_count: u32, + /// Total amount to be unbonded once revocations are executed + pub scheduled_revocations_total: Balance, + /// Status for this nominator + pub status: DelegatorStatus, + } + + // /// Temporary function to migrate state + // pub(crate) fn migrate_nominator_to_delegator_state( + // id: T::AccountId, + // nominator: Nominator2>, + // ) -> Delegator> { + // Delegator { + // id, + // delegations: nominator.delegations, + // total: nominator.total, + // requests: PendingDelegationRequests::new(), + // status: nominator.status, + // } + // } + + #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// The current round index and transition information + pub struct RoundInfo { + /// Current round index + pub current: RoundIndex, + /// The first block of the current round + pub first: BlockNumber, + /// The length of the current round in number of blocks + pub length: u32, + } + impl< + B: Copy + + sp_std::ops::Add + + sp_std::ops::Sub + + From + + PartialOrd, + > RoundInfo + { + pub fn new(current: RoundIndex, first: B, length: u32) -> RoundInfo { + RoundInfo { + current, + first, + length, + } + } + /// Check if the round should be updated + pub fn should_update(&self, now: B) -> bool { + now - self.first >= self.length.into() + } + /// New round + pub fn update(&mut self, now: B) { + self.current += 1u32; + self.first = now; + } + } + impl< + B: Copy + + sp_std::ops::Add + + sp_std::ops::Sub + + From + + PartialOrd, + > Default for RoundInfo + { + fn default() -> RoundInfo { + RoundInfo::new(1u32, 1u32.into(), 20u32) + } + } + + #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Reserve information { account, percent_of_inflation } + pub struct ParachainBondConfig { + /// Account which receives funds intended for parachain bond + pub account: AccountId, + /// Percent of inflation set aside for parachain bond account + pub percent: Percent, + } + impl Default for ParachainBondConfig { + fn default() -> ParachainBondConfig { + ParachainBondConfig { + account: A::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + percent: Percent::zero(), + } + } + } + + pub(crate) type RoundIndex = u32; + type RewardPoint = u32; + pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + + /// Configuration trait of this pallet. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Overarching event type + type Event: From> + IsType<::Event>; + /// The currency type + type Currency: Currency + ReservableCurrency; + /// The origin for monetary governance + type MonetaryGovernanceOrigin: EnsureOrigin; + /// Minimum number of blocks per round + #[pallet::constant] + type MinBlocksPerRound: Get; + /// Default number of blocks per round at genesis + #[pallet::constant] + type DefaultBlocksPerRound: Get; + /// Number of rounds that candidates remain bonded before exit request is executable + #[pallet::constant] + type LeaveCandidatesDelay: Get; + /// Number of rounds candidate requests to decrease self-bond must wait to be executable + #[pallet::constant] + type CandidateBondLessDelay: Get; + /// Number of rounds that delegators remain bonded before exit request is executable + #[pallet::constant] + type LeaveDelegatorsDelay: Get; + /// Number of rounds that delegations remain bonded before revocation request is executable + #[pallet::constant] + type RevokeDelegationDelay: Get; + /// Number of rounds that delegation less requests must wait before executable + #[pallet::constant] + type DelegationBondLessDelay: Get; + /// Number of rounds after which block authors are rewarded + #[pallet::constant] + type RewardPaymentDelay: Get; + /// Minimum number of selected candidates every round + #[pallet::constant] + type MinSelectedCandidates: Get; + /// Maximum top delegations counted per candidate + #[pallet::constant] + type MaxTopDelegationsPerCandidate: Get; + /// Maximum bottom delegations (not counted) per candidate + #[pallet::constant] + type MaxBottomDelegationsPerCandidate: Get; + /// Maximum delegations per delegator + #[pallet::constant] + type MaxDelegationsPerDelegator: Get; + /// Default commission due to collators, is `CollatorCommission` storage value in genesis + #[pallet::constant] + type DefaultCollatorCommission: Get; + /// Default percent of inflation set aside for parachain bond account + #[pallet::constant] + type DefaultParachainBondReservePercent: Get; + /// Minimum stake required for any candidate to be in `SelectedCandidates` for the round + #[pallet::constant] + type MinCollatorStk: Get>; + /// Minimum stake required for any account to be a collator candidate + #[pallet::constant] + type MinCandidateStk: Get>; + /// Minimum stake for any registered on-chain account to delegate + #[pallet::constant] + type MinDelegation: Get>; + /// Minimum stake for any registered on-chain account to be a delegator + #[pallet::constant] + type MinDelegatorStk: Get>; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::error] + pub enum Error { + DelegatorDNE, + DelegatorDNEinTopNorBottom, + DelegatorDNEInDelegatorSet, + CandidateDNE, + DelegationDNE, + DelegatorExists, + CandidateExists, + CandidateBondBelowMin, + InsufficientBalance, + DelegatorBondBelowMin, + DelegationBelowMin, + AlreadyOffline, + AlreadyActive, + DelegatorAlreadyLeaving, + DelegatorNotLeaving, + DelegatorCannotLeaveYet, + CannotDelegateIfLeaving, + CandidateAlreadyLeaving, + CandidateNotLeaving, + CandidateCannotLeaveYet, + CannotGoOnlineIfLeaving, + ExceedMaxDelegationsPerDelegator, + AlreadyDelegatedCandidate, + InvalidSchedule, + CannotSetBelowMin, + RoundLengthMustBeAtLeastTotalSelectedCollators, + NoWritingSameValue, + TooLowCandidateCountWeightHintJoinCandidates, + TooLowCandidateCountWeightHintCancelLeaveCandidates, + TooLowCandidateCountToLeaveCandidates, + TooLowDelegationCountToDelegate, + TooLowCandidateDelegationCountToDelegate, + TooLowCandidateDelegationCountToLeaveCandidates, + TooLowDelegationCountToLeaveDelegators, + PendingCandidateRequestsDNE, + PendingCandidateRequestAlreadyExists, + PendingCandidateRequestNotDueYet, + PendingDelegationRequestDNE, + PendingDelegationRequestAlreadyExists, + PendingDelegationRequestNotDueYet, + CannotDelegateLessThanLowestBottomWhenBottomIsFull, + } + + #[pallet::event] + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event { + /// Starting Block, Round, Number of Collators Selected, Total Balance + NewRound(T::BlockNumber, RoundIndex, u32, BalanceOf), + /// Account, Amount Locked, New Total Amt Locked + JoinedCollatorCandidates(T::AccountId, BalanceOf, BalanceOf), + /// Round, Collator Account, Total Exposed Amount (includes all delegations) + CollatorChosen(RoundIndex, T::AccountId, BalanceOf), + /// Candidate, Amount To Decrease, Round at which request can be executed by caller + CandidateBondLessRequested(T::AccountId, BalanceOf, RoundIndex), + /// Candidate, Amount, New Bond Total + CandidateBondedMore(T::AccountId, BalanceOf, BalanceOf), + /// Candidate, Amount, New Bond + CandidateBondedLess(T::AccountId, BalanceOf, BalanceOf), + /// Candidate + CandidateWentOffline(T::AccountId), + /// Candidate + CandidateBackOnline(T::AccountId), + /// Round At Which Exit Is Allowed, Candidate, Scheduled Exit + CandidateScheduledExit(RoundIndex, T::AccountId, RoundIndex), + /// Candidate + CancelledCandidateExit(T::AccountId), + /// Candidate, Amount, Round at which could be executed + CancelledCandidateBondLess(T::AccountId, BalanceOf, RoundIndex), + /// Ex-Candidate, Amount Unlocked, New Total Amt Locked + CandidateLeft(T::AccountId, BalanceOf, BalanceOf), + /// Delegator, Candidate, Amount to be decreased, Round at which can be executed + DelegationDecreaseScheduled(T::AccountId, T::AccountId, BalanceOf, RoundIndex), + // Delegator, Candidate, Amount, If in top delegations for candidate after increase + DelegationIncreased(T::AccountId, T::AccountId, BalanceOf, bool), + // Delegator, Candidate, Amount, If in top delegations for candidate after decrease + DelegationDecreased(T::AccountId, T::AccountId, BalanceOf, bool), + /// Round, Delegator, Scheduled Exit + DelegatorExitScheduled(RoundIndex, T::AccountId, RoundIndex), + /// Round, Delegator, Candidate, Scheduled Exit + DelegationRevocationScheduled(RoundIndex, T::AccountId, T::AccountId, RoundIndex), + /// Delegator, Amount Unstaked + DelegatorLeft(T::AccountId, BalanceOf), + /// Delegator, Candidate, Amount Unstaked + DelegationRevoked(T::AccountId, T::AccountId, BalanceOf), + /// Delegator, Candidate, Amount Unstaked + DelegationKicked(T::AccountId, T::AccountId, BalanceOf), + /// Delegator + DelegatorExitCancelled(T::AccountId), + /// Delegator, Cancelled Request + CancelledDelegationRequest(T::AccountId, DelegationRequest>), + /// Delegator, Amount Locked, Candidate, Delegator Position with New Total Counted if in Top + Delegation( + T::AccountId, + BalanceOf, + T::AccountId, + DelegatorAdded>, + ), + /// Delegator, Candidate, Amount Unstaked, New Total Amt Staked for Candidate + DelegatorLeftCandidate(T::AccountId, T::AccountId, BalanceOf, BalanceOf), + /// Paid the account (delegator or collator) the balance as liquid rewards + Rewarded(T::AccountId, BalanceOf), + /// Transferred to account which holds funds reserved for parachain bond + ReservedForParachainBond(T::AccountId, BalanceOf), + /// Account (re)set for parachain bond treasury [old, new] + ParachainBondAccountSet(T::AccountId, T::AccountId), + /// Percent of inflation reserved for parachain bond (re)set [old, new] + ParachainBondReservePercentSet(Percent, Percent), + /// Annual inflation input (first 3) was used to derive new per-round inflation (last 3) + InflationSet(Perbill, Perbill, Perbill, Perbill, Perbill, Perbill), + /// Staking expectations set + StakeExpectationsSet(BalanceOf, BalanceOf, BalanceOf), + /// Set total selected candidates to this value [old, new] + TotalSelectedSet(u32, u32), + /// Set collator commission to this value [old, new] + CollatorCommissionSet(Perbill, Perbill), + /// Set blocks per round [current_round, first_block, old, new, new_per_round_inflation] + BlocksPerRoundSet( + RoundIndex, + T::BlockNumber, + u32, + u32, + Perbill, + Perbill, + Perbill, + ), + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: T::BlockNumber) -> Weight { + let mut weight = T::WeightInfo::base_on_initialize(); + + let mut round = >::get(); + if round.should_update(n) { + // mutate round + round.update(n); + // pay all stakers for T::RewardPaymentDelay rounds ago + Self::prepare_staking_payouts(round.current); + // select top collator candidates for next round + let (collator_count, delegation_count, total_staked) = + Self::select_top_candidates(round.current); + // start next round + >::put(round); + // snapshot total stake + >::insert(round.current, >::get()); + Self::deposit_event(Event::NewRound( + round.first, + round.current, + collator_count, + total_staked, + )); + weight += + T::WeightInfo::round_transition_on_initialize(collator_count, delegation_count); + } + + weight += Self::handle_delayed_payouts(round.current); + + weight + } + } + + #[pallet::storage] + #[pallet::getter(fn collator_commission)] + /// Commission percent taken off of rewards for all collators + type CollatorCommission = StorageValue<_, Perbill, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn total_selected)] + /// The total candidates selected every round + type TotalSelected = StorageValue<_, u32, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn parachain_bond_info)] + /// Parachain bond config info { account, percent_of_inflation } + type ParachainBondInfo = + StorageValue<_, ParachainBondConfig, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn round)] + /// Current round index and next round scheduled transition + pub(crate) type Round = StorageValue<_, RoundInfo, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn nominator_state2)] + /// DEPRECATED in favor of DelegatorState + /// Get nominator state associated with an account if account is nominating else None + pub(crate) type NominatorState2 = StorageMap< + _, + Twox64Concat, + T::AccountId, + Nominator2>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn delegator_state)] + /// Get delegator state associated with an account if account is delegating else None + pub(crate) type DelegatorState = StorageMap< + _, + Twox64Concat, + T::AccountId, + Delegator>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn candidate_state)] + /// DEPRECATED + /// Get collator candidate state associated with an account if account is a candidate else None + pub(crate) type CandidateState = StorageMap< + _, + Twox64Concat, + T::AccountId, + CollatorCandidate>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn candidate_info)] + /// Get collator candidate info associated with an account if account is candidate else None + pub(crate) type CandidateInfo = + StorageMap<_, Twox64Concat, T::AccountId, CandidateMetadata>, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn top_delegations)] + /// Top delegations for collator candidate + pub(crate) type TopDelegations = StorageMap< + _, + Twox64Concat, + T::AccountId, + Delegations>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn bottom_delegations)] + /// Bottom delegations for collator candidate + pub(crate) type BottomDelegations = StorageMap< + _, + Twox64Concat, + T::AccountId, + Delegations>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn collator_state2)] + /// DEPRECATED in favor of CandidateState + /// Get collator state associated with an account if account is collating else None + pub(crate) type CollatorState2 = StorageMap< + _, + Twox64Concat, + T::AccountId, + Collator2>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn selected_candidates)] + /// The collator candidates selected for the current round + type SelectedCandidates = StorageValue<_, Vec, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn total)] + /// Total capital locked by this staking pallet + pub(crate) type Total = StorageValue<_, BalanceOf, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn candidate_pool)] + /// The pool of collator candidates, each with their total backing stake + pub(crate) type CandidatePool = + StorageValue<_, OrderedSet>>, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn at_stake)] + /// Snapshot of collator delegation stake at the start of the round + pub type AtStake = StorageDoubleMap< + _, + Twox64Concat, + RoundIndex, + Twox64Concat, + T::AccountId, + CollatorSnapshot>, + ValueQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn delayed_payouts)] + /// Delayed payouts + pub type DelayedPayouts = + StorageMap<_, Twox64Concat, RoundIndex, DelayedPayout>, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn staked)] + /// Total counted stake for selected candidates in the round + pub type Staked = StorageMap<_, Twox64Concat, RoundIndex, BalanceOf, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn inflation_config)] + /// Inflation configuration + pub type InflationConfig = StorageValue<_, InflationInfo>, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn points)] + /// Total points awarded to collators for block production in the round + pub type Points = StorageMap<_, Twox64Concat, RoundIndex, RewardPoint, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn awarded_pts)] + /// Points for each collator per round + pub type AwardedPts = StorageDoubleMap< + _, + Twox64Concat, + RoundIndex, + Twox64Concat, + T::AccountId, + RewardPoint, + ValueQuery, + >; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub candidates: Vec<(T::AccountId, BalanceOf)>, + /// Vec of tuples of the format (delegator AccountId, collator AccountId, delegation Amount) + pub delegations: Vec<(T::AccountId, T::AccountId, BalanceOf)>, + pub inflation_config: InflationInfo>, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self { + candidates: vec![], + delegations: vec![], + ..Default::default() + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + >::put(self.inflation_config.clone()); + let mut candidate_count = 0u32; + // Initialize the candidates + for &(ref candidate, balance) in &self.candidates { + assert!( + T::Currency::free_balance(candidate) >= balance, + "Account does not have enough balance to bond as a candidate." + ); + candidate_count += 1u32; + if let Err(error) = >::join_candidates( + T::Origin::from(Some(candidate.clone()).into()), + balance, + candidate_count, + ) { + log::warn!("Join candidates failed in genesis with error {:?}", error); + } else { + candidate_count += 1u32; + } + } + let mut col_delegator_count: BTreeMap = BTreeMap::new(); + let mut del_delegation_count: BTreeMap = BTreeMap::new(); + // Initialize the delegations + for &(ref delegator, ref target, balance) in &self.delegations { + assert!( + T::Currency::free_balance(delegator) >= balance, + "Account does not have enough balance to place delegation." + ); + let cd_count = if let Some(x) = col_delegator_count.get(target) { + *x + } else { + 0u32 + }; + let dd_count = if let Some(x) = del_delegation_count.get(delegator) { + *x + } else { + 0u32 + }; + if let Err(error) = >::delegate( + T::Origin::from(Some(delegator.clone()).into()), + target.clone(), + balance, + cd_count, + dd_count, + ) { + log::warn!("Delegate failed in genesis with error {:?}", error); + } else { + if let Some(x) = col_delegator_count.get_mut(target) { + *x += 1u32; + } else { + col_delegator_count.insert(target.clone(), 1u32); + }; + if let Some(x) = del_delegation_count.get_mut(delegator) { + *x += 1u32; + } else { + del_delegation_count.insert(delegator.clone(), 1u32); + }; + } + } + // Set collator commission to default config + >::put(T::DefaultCollatorCommission::get()); + // Set parachain bond config to default config + >::put(ParachainBondConfig { + // must be set soon; if not => due inflation will be sent to collators/delegators + account: T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + percent: T::DefaultParachainBondReservePercent::get(), + }); + // Set total selected candidates to minimum config + >::put(T::MinSelectedCandidates::get()); + // Choose top TotalSelected collator candidates + let (v_count, _, total_staked) = >::select_top_candidates(1u32); + // Start Round 1 at Block 0 + let round: RoundInfo = + RoundInfo::new(1u32, 0u32.into(), T::DefaultBlocksPerRound::get()); + >::put(round); + // Snapshot total stake + >::insert(1u32, >::get()); + >::deposit_event(Event::NewRound( + T::BlockNumber::zero(), + 1u32, + v_count, + total_staked, + )); + } + } + + #[pallet::call] + impl Pallet { + #[pallet::weight( + ::WeightInfo::hotfix_remove_delegation_requests(delegators.len() as u32) + )] + /// Hotfix patch to remove all delegation requests not removed during a candidate exit + pub fn hotfix_remove_delegation_requests( + origin: OriginFor, + delegators: Vec, + ) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + for delegator in delegators { + if let Some(mut state) = >::get(&delegator) { + // go through all requests and remove ones without corresponding delegation + for (candidate, request) in state.requests.requests.clone().into_iter() { + if state + .delegations + .0 + .iter() + .find(|x| x.owner == candidate) + .is_none() + { + state.requests.requests.remove(&candidate); + state.requests.less_total = + state.requests.less_total.saturating_sub(request.amount); + if matches!(request.action, DelegationChange::Revoke) { + state.requests.revocations_count -= 1u32; + } + } + } + >::insert(&delegator, state); + } // else delegator is not a delegator so no update needed + } + Ok(().into()) + } + #[pallet::weight( + ::WeightInfo::hotfix_update_candidate_pool_value(candidates.len() as u32) + )] + /// Hotfix patch to correct and update CandidatePool value for candidates that have + /// called candidate_bond_more when it did not update the CandidatePool value + pub fn hotfix_update_candidate_pool_value( + origin: OriginFor, + candidates: Vec, + ) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + for candidate in candidates { + if let Some(state) = >::get(&candidate) { + Self::update_active(candidate, state.total_counted); + } // else candidate is not a candidate so no update needed + } + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_staking_expectations())] + /// Set the expectations for total staked. These expectations determine the issuance for + /// the round according to logic in `fn compute_issuance` + pub fn set_staking_expectations( + origin: OriginFor, + expectations: Range>, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + ensure!(expectations.is_valid(), Error::::InvalidSchedule); + let mut config = >::get(); + ensure!( + config.expect != expectations, + Error::::NoWritingSameValue + ); + config.set_expectations(expectations); + Self::deposit_event(Event::StakeExpectationsSet( + config.expect.min, + config.expect.ideal, + config.expect.max, + )); + >::put(config); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_inflation())] + /// Set the annual inflation rate to derive per-round inflation + pub fn set_inflation( + origin: OriginFor, + schedule: Range, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + ensure!(schedule.is_valid(), Error::::InvalidSchedule); + let mut config = >::get(); + ensure!(config.annual != schedule, Error::::NoWritingSameValue); + config.annual = schedule; + config.set_round_from_annual::(schedule); + Self::deposit_event(Event::InflationSet( + config.annual.min, + config.annual.ideal, + config.annual.max, + config.round.min, + config.round.ideal, + config.round.max, + )); + >::put(config); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_parachain_bond_account())] + /// Set the account that will hold funds set aside for parachain bond + pub fn set_parachain_bond_account( + origin: OriginFor, + new: T::AccountId, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + let ParachainBondConfig { + account: old, + percent, + } = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + >::put(ParachainBondConfig { + account: new.clone(), + percent, + }); + Self::deposit_event(Event::ParachainBondAccountSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_parachain_bond_reserve_percent())] + /// Set the percent of inflation set aside for parachain bond + pub fn set_parachain_bond_reserve_percent( + origin: OriginFor, + new: Percent, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + let ParachainBondConfig { + account, + percent: old, + } = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + >::put(ParachainBondConfig { + account, + percent: new, + }); + Self::deposit_event(Event::ParachainBondReservePercentSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_total_selected())] + /// Set the total number of collator candidates selected per round + /// - changes are not applied until the start of the next round + pub fn set_total_selected(origin: OriginFor, new: u32) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + ensure!( + new >= T::MinSelectedCandidates::get(), + Error::::CannotSetBelowMin + ); + let old = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + ensure!( + new <= >::get().length, + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + >::put(new); + Self::deposit_event(Event::TotalSelectedSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_collator_commission())] + /// Set the commission for all collators + pub fn set_collator_commission( + origin: OriginFor, + new: Perbill, + ) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + let old = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + >::put(new); + Self::deposit_event(Event::CollatorCommissionSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_blocks_per_round())] + /// Set blocks per round + /// - if called with `new` less than length of current round, will transition immediately + /// in the next block + /// - also updates per-round inflation config + pub fn set_blocks_per_round(origin: OriginFor, new: u32) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + ensure!( + new >= T::MinBlocksPerRound::get(), + Error::::CannotSetBelowMin + ); + let mut round = >::get(); + let (now, first, old) = (round.current, round.first, round.length); + ensure!(old != new, Error::::NoWritingSameValue); + ensure!( + new >= >::get(), + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + round.length = new; + // update per-round inflation given new rounds per year + let mut inflation_config = >::get(); + inflation_config.reset_round(new); + >::put(round); + Self::deposit_event(Event::BlocksPerRoundSet( + now, + first, + old, + new, + inflation_config.round.min, + inflation_config.round.ideal, + inflation_config.round.max, + )); + >::put(inflation_config); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::join_candidates(*candidate_count))] + /// Join the set of collator candidates + pub fn join_candidates( + origin: OriginFor, + bond: BalanceOf, + candidate_count: u32, + ) -> DispatchResultWithPostInfo { + let acc = ensure_signed(origin)?; + ensure!(!Self::is_candidate(&acc), Error::::CandidateExists); + ensure!(!Self::is_delegator(&acc), Error::::DelegatorExists); + ensure!( + bond >= T::MinCandidateStk::get(), + Error::::CandidateBondBelowMin + ); + let mut candidates = >::get(); + let old_count = candidates.0.len() as u32; + ensure!( + candidate_count >= old_count, + Error::::TooLowCandidateCountWeightHintJoinCandidates + ); + ensure!( + candidates.insert(Bond { + owner: acc.clone(), + amount: bond + }), + Error::::CandidateExists + ); + T::Currency::reserve(&acc, bond)?; + let candidate = CandidateMetadata::new(bond); + >::insert(&acc, candidate); + let empty_delegations: Delegations> = Default::default(); + // insert empty top delegations + >::insert(&acc, empty_delegations.clone()); + // insert empty bottom delegations + >::insert(&acc, empty_delegations); + >::put(candidates); + let new_total = >::get().saturating_add(bond); + >::put(new_total); + Self::deposit_event(Event::JoinedCollatorCandidates(acc, bond, new_total)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_leave_candidates(*candidate_count))] + /// Request to leave the set of candidates. If successful, the account is immediately + /// removed from the candidate pool to prevent selection as a collator. + pub fn schedule_leave_candidates( + origin: OriginFor, + candidate_count: u32, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + let (now, when) = state.schedule_leave::()?; + let mut candidates = >::get(); + ensure!( + candidate_count >= candidates.0.len() as u32, + Error::::TooLowCandidateCountToLeaveCandidates + ); + if candidates.remove(&Bond::from_owner(collator.clone())) { + >::put(candidates); + } + >::insert(&collator, state); + Self::deposit_event(Event::CandidateScheduledExit(now, collator, when)); + Ok(().into()) + } + #[pallet::weight( + ::WeightInfo::execute_leave_candidates(*candidate_delegation_count) + )] + /// Execute leave candidates request + pub fn execute_leave_candidates( + origin: OriginFor, + candidate: T::AccountId, + candidate_delegation_count: u32, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + let state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; + ensure!( + state.delegation_count <= candidate_delegation_count, + Error::::TooLowCandidateDelegationCountToLeaveCandidates + ); + state.can_leave::()?; + let return_stake = |bond: Bond>| { + T::Currency::unreserve(&bond.owner, bond.amount); + // remove delegation from delegator state + let mut delegator = DelegatorState::::get(&bond.owner).expect( + "Collator state and delegator state are consistent. + Collator state has a record of this delegation. Therefore, + Delegator state also has a record. qed.", + ); + if let Some(remaining) = delegator.rm_delegation(&candidate) { + if remaining.is_zero() { + >::remove(&bond.owner); + } else { + if let Some(request) = delegator.requests.requests.remove(&candidate) { + delegator.requests.less_total = + delegator.requests.less_total.saturating_sub(request.amount); + if matches!(request.action, DelegationChange::Revoke) { + delegator.requests.revocations_count -= 1u32; + } + } + >::insert(&bond.owner, delegator); + } + } + }; + // total backing stake is at least the candidate self bond + let mut total_backing = state.bond; + // return all top delegations + let top_delegations = + >::take(&candidate).expect("CandidateInfo existence checked"); + for bond in top_delegations.delegations { + return_stake(bond); + } + total_backing += top_delegations.total; + // return all bottom delegations + let bottom_delegations = + >::take(&candidate).expect("CandidateInfo existence checked"); + for bond in bottom_delegations.delegations { + return_stake(bond); + } + total_backing += bottom_delegations.total; + // return stake to collator + T::Currency::unreserve(&candidate, state.bond); + >::remove(&candidate); + >::remove(&candidate); + >::remove(&candidate); + let new_total_staked = >::get().saturating_sub(total_backing); + >::put(new_total_staked); + Self::deposit_event(Event::CandidateLeft( + candidate, + total_backing, + new_total_staked, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_leave_candidates(*candidate_count))] + /// Cancel open request to leave candidates + /// - only callable by collator account + /// - result upon successful call is the candidate is active in the candidate pool + pub fn cancel_leave_candidates( + origin: OriginFor, + candidate_count: u32, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + ensure!(state.is_leaving(), Error::::CandidateNotLeaving); + state.go_online(); + let mut candidates = >::get(); + ensure!( + candidates.0.len() as u32 <= candidate_count, + Error::::TooLowCandidateCountWeightHintCancelLeaveCandidates + ); + ensure!( + candidates.insert(Bond { + owner: collator.clone(), + amount: state.total_counted + }), + Error::::AlreadyActive + ); + >::put(candidates); + >::insert(&collator, state); + Self::deposit_event(Event::CancelledCandidateExit(collator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::go_offline())] + /// Temporarily leave the set of collator candidates without unbonding + pub fn go_offline(origin: OriginFor) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + ensure!(state.is_active(), Error::::AlreadyOffline); + state.go_offline(); + let mut candidates = >::get(); + if candidates.remove(&Bond::from_owner(collator.clone())) { + >::put(candidates); + } + >::insert(&collator, state); + Self::deposit_event(Event::CandidateWentOffline(collator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::go_online())] + /// Rejoin the set of collator candidates if previously had called `go_offline` + pub fn go_online(origin: OriginFor) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + ensure!(!state.is_active(), Error::::AlreadyActive); + ensure!(!state.is_leaving(), Error::::CannotGoOnlineIfLeaving); + state.go_online(); + let mut candidates = >::get(); + ensure!( + candidates.insert(Bond { + owner: collator.clone(), + amount: state.total_counted + }), + Error::::AlreadyActive + ); + >::put(candidates); + >::insert(&collator, state); + Self::deposit_event(Event::CandidateBackOnline(collator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::candidate_bond_more())] + /// Increase collator candidate self bond by `more` + pub fn candidate_bond_more( + origin: OriginFor, + more: BalanceOf, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + state.bond_more::(collator.clone(), more)?; + let (is_active, total_counted) = (state.is_active(), state.total_counted); + >::insert(&collator, state); + if is_active { + Self::update_active(collator, total_counted); + } + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_candidate_bond_less())] + /// Request by collator candidate to decrease self bond by `less` + pub fn schedule_candidate_bond_less( + origin: OriginFor, + less: BalanceOf, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + let when = state.schedule_bond_less::(less)?; + >::insert(&collator, state); + Self::deposit_event(Event::CandidateBondLessRequested(collator, less, when)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::execute_candidate_bond_less())] + /// Execute pending request to adjust the collator candidate self bond + pub fn execute_candidate_bond_less( + origin: OriginFor, + candidate: T::AccountId, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; // we may want to reward this if caller != candidate + let mut state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; + state.execute_bond_less::(candidate.clone())?; + >::insert(&candidate, state); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_candidate_bond_less())] + /// Cancel pending request to adjust the collator candidate self bond + pub fn cancel_candidate_bond_less(origin: OriginFor) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + state.cancel_bond_less::(collator.clone())?; + >::insert(&collator, state); + Ok(().into()) + } + #[pallet::weight( + ::WeightInfo::delegate( + *candidate_delegation_count, + *delegation_count ) )] - pub fn nominate( - origin: OriginFor, - collator: T::AccountId, - amount: BalanceOf, - collator_nominator_count: u32, - nomination_count: u32, - ) -> DispatchResultWithPostInfo { - let acc = ensure_signed(origin)?; - let nominator = if let Some(mut state) = >::get(&acc) { - ensure!(state.is_active(), Error::::CannotActBecauseLeaving); - // nomination after first - ensure!( - amount >= T::MinNomination::get(), - Error::::NominationBelowMin - ); - ensure!( - nomination_count >= state.nominations.0.len() as u32, - Error::::TooLowNominationCountToNominate - ); - ensure!( - (state.nominations.0.len() as u32) < T::MaxCollatorsPerNominator::get(), - Error::::ExceedMaxCollatorsPerNom - ); - // ensure that nominator is not in the exit_queue - ensure!( - state.add_nomination(Bond { - owner: collator.clone(), - amount - }), - Error::::AlreadyNominatedCollator - ); - state - } else { - // first nomination - ensure!( - amount >= T::MinNominatorStk::get(), - Error::::NomBondBelowMin - ); - ensure!(!Self::is_candidate(&acc), Error::::CandidateExists); - Nominator2::new(collator.clone(), amount) - }; - let mut state = - >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!( - collator_nominator_count >= state.nominators.0.len() as u32, - Error::::TooLowCollatorNominationCountToNominate - ); - let nominator_position = state.add_nominator::(acc.clone(), amount)?; - T::Currency::reserve(&acc, amount)?; - if let NominatorAdded::AddedToTop { new_total } = nominator_position { - if state.is_active() { - Self::update_active(collator.clone(), new_total); - } - } - let new_total_locked = >::get() + amount; - >::put(new_total_locked); - >::insert(&collator, state); - >::insert(&acc, nominator); - Self::deposit_event(Event::Nomination(acc, amount, collator, nominator_position)); - Ok(().into()) - } - /// Request to leave the set of nominators. If successful, the nominator is scheduled - /// to exit - #[pallet::weight(::WeightInfo::leave_nominators(*nomination_count))] - pub fn leave_nominators( - origin: OriginFor, - nomination_count: u32, - ) -> DispatchResultWithPostInfo { - let acc = ensure_signed(origin)?; - let mut state = >::get(&acc).ok_or(Error::::NominatorDNE)?; - ensure!(!state.is_leaving(), Error::::NominatorAlreadyLeaving); - ensure!( - nomination_count >= (state.nominations.0.len() as u32), - Error::::TooLowNominationCountToLeaveNominators - ); - let mut exits = >::get(); - let now = >::get().current; - let when = now + T::LeaveNominatorsDelay::get(); - exits.schedule_nominator_exit::(acc.clone(), when)?; - state.leave(when); - state.scheduled_revocations_total = state.total; - state.scheduled_revocations_count = state.nominations.0.len() as u32; - >::put(exits); - >::insert(&acc, state); - Self::deposit_event(Event::NominatorExitScheduled(now, acc, when)); - Ok(().into()) - } - /// Request to revoke an existing nomination. If successful, the nomination is scheduled - /// to exit - #[pallet::weight(::WeightInfo::revoke_nomination())] - pub fn revoke_nomination( - origin: OriginFor, - collator: T::AccountId, - ) -> DispatchResultWithPostInfo { - let nominator = ensure_signed(origin)?; - let mut state = - >::get(&nominator).ok_or(Error::::NominatorDNE)?; - ensure!(state.is_active(), Error::::CannotActBecauseLeaving); - ensure!( - state.revocations.insert(collator.clone()), - Error::::NominationAlreadyRevoked - ); - let mut nomination_amount: Option> = None; - for Bond { owner, amount } in state.nominations.0.iter() { - if owner == &collator { - nomination_amount = Some(*amount); - break; - } - } - // Ensure that the collator exists in the nominations - let amount = nomination_amount.ok_or(Error::::NominationDNE)?; - let remaining = state.total - state.scheduled_revocations_total - amount; - let leaving = - if state.nominations.0.len() as u32 - state.scheduled_revocations_count < 2 { - true - } else { - ensure!( - remaining >= T::MinNominatorStk::get(), - Error::::NomBondBelowMin - ); - false - }; - let mut exits = >::get(); - let now = >::get().current; - let when = now + T::RevokeNominationDelay::get(); - if leaving { - // schedule to leave the set of nominators if this is the only nomination - exits.schedule_nominator_exit::(nominator.clone(), when)?; - state.leave(when); - state.scheduled_revocations_total = state.total; - state.scheduled_revocations_count = state.nominations.0.len() as u32; - >::put(exits); - >::insert(&nominator, state); - Self::deposit_event(Event::NominatorExitScheduled(now, nominator, when)); - } else { - // schedule to revoke this nomination - exits.schedule_nomination_revocation::( - nominator.clone(), - collator.clone(), - when, - )?; - state.scheduled_revocations_total += amount; - state.scheduled_revocations_count += 1u32; - >::put(exits); - >::insert(&nominator, state); - Self::deposit_event(Event::NominationRevocationScheduled( - now, nominator, collator, when, - )); - } - Ok(().into()) - } - /// Bond more for nominators with respect to a specific collator candidate - #[pallet::weight(::WeightInfo::nominator_bond_more())] - pub fn nominator_bond_more( - origin: OriginFor, - candidate: T::AccountId, - more: BalanceOf, - ) -> DispatchResultWithPostInfo { - let nominator = ensure_signed(origin)?; - let mut state = - >::get(&nominator).ok_or(Error::::NominatorDNE)?; - ensure!(state.is_active(), Error::::CannotActBecauseLeaving); - ensure!( - !state.revocations.contains(&candidate), - Error::::CannotActBecauseRevoking - ); - let mut collator = - >::get(&candidate).ok_or(Error::::CandidateDNE)?; - ensure!( - state.inc_nomination(candidate.clone(), more), - Error::::NominationDNE - ); - T::Currency::reserve(&nominator, more)?; - let before = collator.total_counted; - let in_top = collator.inc_nominator(nominator.clone(), more); - let after = collator.total_counted; - if collator.is_active() && (before != after) { - Self::update_active(candidate.clone(), after); - } - >::insert(&candidate, collator); - >::insert(&nominator, state); - let new_total_staked = >::get().saturating_add(more); - >::put(new_total_staked); - Self::deposit_event(Event::NominationIncreased( - nominator, candidate, more, in_top, - )); - Ok(().into()) - } - /// Bond less for nominators with respect to a specific nominator candidate - #[pallet::weight(::WeightInfo::nominator_bond_less())] - pub fn nominator_bond_less( - origin: OriginFor, - candidate: T::AccountId, - less: BalanceOf, - ) -> DispatchResultWithPostInfo { - let nominator = ensure_signed(origin)?; - let mut state = - >::get(&nominator).ok_or(Error::::NominatorDNE)?; - ensure!(state.is_active(), Error::::CannotActBecauseLeaving); - ensure!( - !state.revocations.contains(&candidate), - Error::::CannotActBecauseRevoking - ); - let mut collator = - >::get(&candidate).ok_or(Error::::CandidateDNE)?; - let remaining = state - .dec_nomination(candidate.clone(), less) - .ok_or(Error::::NominationDNE)? - .ok_or(Error::::NomBondBelowMin)?; - ensure!( - remaining >= T::MinNomination::get(), - Error::::NominationBelowMin - ); - ensure!( - state.total >= T::MinNominatorStk::get(), - Error::::NomBondBelowMin - ); - T::Currency::unreserve(&nominator, less); - let before = collator.total_counted; - let in_top = collator.dec_nominator(nominator.clone(), less); - let after = collator.total_counted; - if collator.is_active() && (before != after) { - Self::update_active(candidate.clone(), after); - } - >::insert(&candidate, collator); - >::insert(&nominator, state); - let new_total_staked = >::get().saturating_sub(less); - >::put(new_total_staked); - Self::deposit_event(Event::NominationDecreased( - nominator, candidate, less, in_top, - )); - Ok(().into()) - } - } - - impl Pallet { - pub fn is_nominator(acc: &T::AccountId) -> bool { - >::get(acc).is_some() - } - pub fn is_candidate(acc: &T::AccountId) -> bool { - >::get(acc).is_some() - } - pub fn is_selected_candidate(acc: &T::AccountId) -> bool { - >::get().binary_search(acc).is_ok() - } - // ensure candidate is active before calling - fn update_active(candidate: T::AccountId, total: BalanceOf) { - let mut candidates = >::get(); - candidates.remove(&Bond::from_owner(candidate.clone())); - candidates.insert(Bond { - owner: candidate, - amount: total, - }); - >::put(candidates); - } - // Calculate round issuance based on total staked for the given round - fn compute_issuance(staked: BalanceOf) -> BalanceOf { - let config = >::get(); - let round_issuance = crate::inflation::round_issuance_range::(config.round); - // TODO: consider interpolation instead of bounded range - if staked < config.expect.min { - round_issuance.min - } else if staked > config.expect.max { - round_issuance.max - } else { - round_issuance.ideal - } - } - pub(crate) fn nominator_leaves_collator( - nominator: T::AccountId, - collator: T::AccountId, - ) -> DispatchResultWithPostInfo { - let mut state = - >::get(&collator).ok_or(Error::::CandidateDNE)?; - let (total_changed, nominator_stake) = state.rm_nominator::(nominator.clone())?; - T::Currency::unreserve(&nominator, nominator_stake); - if state.is_active() && total_changed { - Self::update_active(collator.clone(), state.total_counted); - } - let new_total_locked = >::get() - nominator_stake; - >::put(new_total_locked); - let new_total = state.total_counted; - >::insert(&collator, state); - Self::deposit_event(Event::NominatorLeftCollator( - nominator, - collator, - nominator_stake, - new_total, - )); - Ok(().into()) - } - fn pay_stakers(next: RoundIndex) { - // payout is next - duration rounds ago => next - duration > 0 else return early - let duration = T::RewardPaymentDelay::get(); - if next <= duration { - return; - } - let round_to_payout = next - duration; - let total = >::get(round_to_payout); - if total.is_zero() { - return; - } - let total_staked = >::get(round_to_payout); - let total_issuance = Self::compute_issuance(total_staked); - let mut left_issuance = total_issuance; - // reserve portion of issuance for parachain bond account - let bond_config = >::get(); - let parachain_bond_reserve = bond_config.percent * total_issuance; - if let Ok(imb) = - T::Currency::deposit_into_existing(&bond_config.account, parachain_bond_reserve) - { - // update round issuance iff transfer succeeds - left_issuance -= imb.peek(); - Self::deposit_event(Event::ReservedForParachainBond( - bond_config.account, - imb.peek(), - )); - } - let mint = |amt: BalanceOf, to: T::AccountId| { - if let Ok(imb) = T::Currency::deposit_into_existing(&to, amt) { - Self::deposit_event(Event::Rewarded(to.clone(), imb.peek())); - } - }; - // only pay out rewards at the end to transfer only total amount due - let mut due_rewards: BTreeMap> = BTreeMap::new(); - let mut increase_due_rewards = |amt: BalanceOf, to: T::AccountId| { - if let Some(already_due) = due_rewards.get(&to) { - let amount = amt.saturating_add(*already_due); - due_rewards.insert(to, amount); - } else { - due_rewards.insert(to, amt); - } - }; - let collator_fee = >::get(); - let collator_issuance = collator_fee * total_issuance; - for (val, pts) in >::drain_prefix(round_to_payout) { - let pct_due = Perbill::from_rational(pts, total); - let mut amt_due = pct_due * left_issuance; - // Take the snapshot of block author and nominations - let state = >::take(round_to_payout, &val); - if state.nominators.is_empty() { - // solo collator with no nominators - mint(amt_due, val.clone()); - } else { - // pay collator first; commission + due_portion - let val_pct = Perbill::from_rational(state.bond, state.total); - let commission = pct_due * collator_issuance; - amt_due -= commission; - let val_due = (val_pct * amt_due) + commission; - mint(val_due, val.clone()); - // pay nominators due portion - for Bond { owner, amount } in state.nominators { - let percent = Perbill::from_rational(amount, state.total); - let due = percent * amt_due; - increase_due_rewards(due, owner); - } - } - } - for (nominator, total_due) in due_rewards { - mint(total_due, nominator); - } - } - /// Executes all collator exits scheduled for when <= now - fn execute_collator_exits(now: RoundIndex) { - let mut exit_queue = >::get(); - let remaining_exits = exit_queue - .candidate_schedule - .clone() - .into_iter() - .filter_map(|(who, when)| { - if when > now { - Some((who, when)) - } else { - if !exit_queue.candidates.remove(&who) { - log::warn!( - "Candidates set removal failed, CollatorState had inconsistency!", - ); - } - if let Some(state) = >::get(&who) { - // return stake to nominator - let return_stake = |bond: Bond>| { - T::Currency::unreserve(&bond.owner, bond.amount); - // remove nomination from nominator state - let mut nominator = NominatorState2::::get(&bond.owner) - .expect( - "Collator state and nominator state are consistent. - Collator state has a record of this nomination. Therefore, - Nominator state also has a record. qed.", - ); - if let Some(remaining) = nominator.rm_nomination(who.clone()) { - if remaining.is_zero() { - >::remove(&bond.owner); - } else { - >::insert(&bond.owner, nominator); - } - } - }; - // return all top nominations - for bond in state.top_nominators { - return_stake(bond); - } - // return all bottom nominations - for bond in state.bottom_nominators { - return_stake(bond); - } - // return stake to collator - T::Currency::unreserve(&state.id, state.bond); - >::remove(&who); - let new_total_staked = - >::get().saturating_sub(state.total_backing); - >::put(new_total_staked); - Self::deposit_event(Event::CollatorLeft( - who, - state.total_backing, - new_total_staked, - )); - } - None - } - }) - .collect::>(); - exit_queue.candidate_schedule = remaining_exits; - >::put(exit_queue); - } - /// Executes all nominator exits for when <= now - fn execute_nominator_exits(now: RoundIndex) { - let mut exit_queue = >::get(); - let remaining_exits = exit_queue - .nominator_schedule - .clone() - .into_iter() - .filter_map(|(nominator, maybe_collator, when)| { - if when > now { - Some((nominator, maybe_collator, when)) - } else { - if let Some(collator) = maybe_collator { - // single revocation needs to be executed - if let Some(mut state) = >::get(&nominator) { - let pre_total = state.total; - if let Some(remaining) = state.rm_nomination(collator.clone()) { - let amount = pre_total - remaining; - state.scheduled_revocations_total -= amount; - state.scheduled_revocations_count -= 1u32; - state.revocations.remove(&collator); - let _ = Self::nominator_leaves_collator( - nominator.clone(), - collator, - ); - >::insert(&nominator, state); - } - } else { - log::warn!( - "Nominator State for Nominator {:?} Not Found During Revocation - of Support for Collator {:?}", - nominator, - collator, - ); - } - } else { - if !exit_queue.nominators_leaving.remove(&nominator) { - log::warn!( - "Nominators set removal failed, - NominatorState had inconsistency!", - ); - } - if let Some(state) = >::get(&nominator) { - for bond in state.nominations.0 { - if let Err(error) = Self::nominator_leaves_collator( - nominator.clone(), - bond.owner.clone(), - ) { - log::warn!( - "Nominator leaves collator failed with error: {:?}", - error - ); - } - } - >::remove(&nominator); - Self::deposit_event(Event::NominatorLeft(nominator, state.total)); - } else { - log::warn!( - "Nominator State Not Found During Exit for Nominator {:?}", - nominator - ); - } - } - None - } - }) - .collect::, RoundIndex)>>(); - exit_queue.nominator_schedule = remaining_exits; - >::put(exit_queue); - } - /// Compute the top `TotalSelected` candidates in the CandidatePool and return - /// a vec of their AccountIds (in the order of selection) - pub fn compute_top_candidates() -> Vec { - let mut candidates = >::get().0; - // order candidates by stake (least to greatest so requires `rev()`) - candidates.sort_unstable_by(|a, b| a.amount.partial_cmp(&b.amount).unwrap()); - let top_n = >::get() as usize; - // choose the top TotalSelected qualified candidates, ordered by stake - let mut collators = candidates - .into_iter() - .rev() - .take(top_n) - .filter(|x| x.amount >= T::MinCollatorStk::get()) - .map(|x| x.owner) - .collect::>(); - collators.sort(); - collators - } - /// Best as in most cumulatively supported in terms of stake - /// Returns [collator_count, nomination_count, total staked] - fn select_top_candidates(next: RoundIndex) -> (u32, u32, BalanceOf) { - let (mut collator_count, mut nomination_count, mut total) = - (0u32, 0u32, BalanceOf::::zero()); - // choose the top TotalSelected qualified candidates, ordered by stake - let collators = Self::compute_top_candidates(); - // snapshot exposure for round for weighting reward distribution - for account in collators.iter() { - let state = >::get(&account) - .expect("all members of CandidateQ must be candidates"); - collator_count += 1u32; - nomination_count += state.nominators.0.len() as u32; - let amount = state.total_counted; - total += amount; - let exposure: CollatorSnapshot> = state.into(); - >::insert(next, account, exposure); - Self::deposit_event(Event::CollatorChosen(next, account.clone(), amount)); - } - // insert canonical collator set - >::put(collators); - (collator_count, nomination_count, total) - } - } - - /// Add reward points to block authors: - /// * 20 points to the block producer for producing a block in the chain - impl nimbus_primitives::EventHandler for Pallet { - fn note_author(author: T::AccountId) { - let now = >::get().current; - let score_plus_20 = >::get(now, &author) + 20; - >::insert(now, author, score_plus_20); - >::mutate(now, |x| *x += 20); - } - } - - impl nimbus_primitives::CanAuthor for Pallet { - fn can_author(account: &T::AccountId, _slot: &u32) -> bool { - Self::is_selected_candidate(account) - } - } - - impl Get> for Pallet { - fn get() -> Vec { - Self::selected_candidates() - } - } + /// If caller is not a delegator and not a collator, then join the set of delegators + /// If caller is a delegator, then makes delegation to change their delegation state + pub fn delegate( + origin: OriginFor, + candidate: T::AccountId, + amount: BalanceOf, + // will_be_in_top: bool // weight hint + // look into returning weight in DispatchResult + candidate_delegation_count: u32, + delegation_count: u32, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + // check that caller can reserve the amount before any changes to storage + ensure!( + T::Currency::can_reserve(&delegator, amount), + Error::::InsufficientBalance + ); + let delegator_state = if let Some(mut state) = >::get(&delegator) { + ensure!(state.is_active(), Error::::CannotDelegateIfLeaving); + // delegation after first + ensure!( + amount >= T::MinDelegation::get(), + Error::::DelegationBelowMin + ); + ensure!( + delegation_count >= state.delegations.0.len() as u32, + Error::::TooLowDelegationCountToDelegate + ); + ensure!( + (state.delegations.0.len() as u32) < T::MaxDelegationsPerDelegator::get(), + Error::::ExceedMaxDelegationsPerDelegator + ); + ensure!( + state.add_delegation(Bond { + owner: candidate.clone(), + amount + }), + Error::::AlreadyDelegatedCandidate + ); + state + } else { + // first delegation + ensure!( + amount >= T::MinDelegatorStk::get(), + Error::::DelegatorBondBelowMin + ); + ensure!(!Self::is_candidate(&delegator), Error::::CandidateExists); + Delegator::new(delegator.clone(), candidate.clone(), amount) + }; + let mut state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; + ensure!( + candidate_delegation_count >= state.delegation_count, + Error::::TooLowCandidateDelegationCountToDelegate + ); + let (delegator_position, less_total_staked) = state.add_delegation::( + &candidate, + Bond { + owner: delegator.clone(), + amount, + }, + )?; + T::Currency::reserve(&delegator, amount) + .expect("verified can reserve at top of this extrinsic body"); + if let DelegatorAdded::AddedToTop { new_total } = delegator_position { + if state.is_active() { + Self::update_active(candidate.clone(), new_total); + } + } + // only is_some if kicked the lowest bottom as a consequence of this new delegation + let net_total_increase = if let Some(less) = less_total_staked { + amount - less + } else { + amount + }; + let new_total_locked = >::get() + net_total_increase; + >::put(new_total_locked); + >::insert(&candidate, state); + >::insert(&delegator, delegator_state); + Self::deposit_event(Event::Delegation( + delegator, + amount, + candidate, + delegator_position, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_leave_delegators())] + /// Request to leave the set of delegators. If successful, the caller is scheduled + /// to be allowed to exit. Success forbids future delegator actions until the request is + /// invoked or cancelled. + pub fn schedule_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { + let acc = ensure_signed(origin)?; + let mut state = >::get(&acc).ok_or(Error::::DelegatorDNE)?; + ensure!(!state.is_leaving(), Error::::DelegatorAlreadyLeaving); + let (now, when) = state.schedule_leave::(); + >::insert(&acc, state); + Self::deposit_event(Event::DelegatorExitScheduled(now, acc, when)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::execute_leave_delegators(*delegation_count))] + /// Execute the right to exit the set of delegators and revoke all ongoing delegations. + pub fn execute_leave_delegators( + origin: OriginFor, + delegator: T::AccountId, + delegation_count: u32, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + let state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + state.can_execute_leave::(delegation_count)?; + for bond in state.delegations.0 { + if let Err(error) = Self::delegator_leaves_candidate( + bond.owner.clone(), + delegator.clone(), + bond.amount, + ) { + log::warn!( + "STORAGE CORRUPTED \nDelegator leaving collator failed with error: {:?}", + error + ); + } + } + >::remove(&delegator); + Self::deposit_event(Event::DelegatorLeft(delegator, state.total)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_leave_delegators())] + /// Cancel a pending request to exit the set of delegators. Success clears the pending exit + /// request (thereby resetting the delay upon another `leave_delegators` call). + pub fn cancel_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + // ensure delegator state exists + let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + // ensure state is leaving + ensure!(state.is_leaving(), Error::::DelegatorDNE); + // cancel exit request + state.cancel_leave(); + >::insert(&delegator, state); + Self::deposit_event(Event::DelegatorExitCancelled(delegator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_revoke_delegation())] + /// Request to revoke an existing delegation. If successful, the delegation is scheduled + /// to be allowed to be revoked via the `execute_delegation_request` extrinsic. + pub fn schedule_revoke_delegation( + origin: OriginFor, + collator: T::AccountId, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + let (now, when) = state.schedule_revoke::(collator.clone())?; + >::insert(&delegator, state); + Self::deposit_event(Event::DelegationRevocationScheduled( + now, delegator, collator, when, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::delegator_bond_more())] + /// Bond more for delegators wrt a specific collator candidate. + pub fn delegator_bond_more( + origin: OriginFor, + candidate: T::AccountId, + more: BalanceOf, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + state.increase_delegation::(candidate.clone(), more)?; + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_delegator_bond_less())] + /// Request bond less for delegators wrt a specific collator candidate. + pub fn schedule_delegator_bond_less( + origin: OriginFor, + candidate: T::AccountId, + less: BalanceOf, + ) -> DispatchResultWithPostInfo { + let caller = ensure_signed(origin)?; + let mut state = >::get(&caller).ok_or(Error::::DelegatorDNE)?; + let when = state.schedule_decrease_delegation::(candidate.clone(), less)?; + >::insert(&caller, state); + Self::deposit_event(Event::DelegationDecreaseScheduled( + caller, candidate, less, when, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::execute_delegator_bond_less())] + /// Execute pending request to change an existing delegation + pub fn execute_delegation_request( + origin: OriginFor, + delegator: T::AccountId, + candidate: T::AccountId, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; // we may want to reward caller if caller != delegator + let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + state.execute_pending_request::(candidate)?; + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_delegator_bond_less())] + /// Cancel request to change an existing delegation. + pub fn cancel_delegation_request( + origin: OriginFor, + candidate: T::AccountId, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + let request = state.cancel_pending_request::(candidate)?; + >::insert(&delegator, state); + Self::deposit_event(Event::CancelledDelegationRequest(delegator, request)); + Ok(().into()) + } + } + + impl Pallet { + pub fn is_delegator(acc: &T::AccountId) -> bool { + >::get(acc).is_some() + } + pub fn is_candidate(acc: &T::AccountId) -> bool { + >::get(acc).is_some() + } + pub fn is_selected_candidate(acc: &T::AccountId) -> bool { + >::get().binary_search(acc).is_ok() + } + /// Caller must ensure candidate is active before calling + pub(crate) fn update_active(candidate: T::AccountId, total: BalanceOf) { + let mut candidates = >::get(); + candidates.remove(&Bond::from_owner(candidate.clone())); + candidates.insert(Bond { + owner: candidate, + amount: total, + }); + >::put(candidates); + } + /// Compute round issuance based on total staked for the given round + fn compute_issuance(staked: BalanceOf) -> BalanceOf { + let config = >::get(); + let round_issuance = crate::inflation::round_issuance_range::(config.round); + // TODO: consider interpolation instead of bounded range + if staked < config.expect.min { + round_issuance.min + } else if staked > config.expect.max { + round_issuance.max + } else { + round_issuance.ideal + } + } + /// Remove delegation from candidate state + /// Amount input should be retrieved from delegator and it informs the storage lookups + fn delegator_leaves_candidate( + candidate: T::AccountId, + delegator: T::AccountId, + amount: BalanceOf, + ) -> DispatchResult { + let mut state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; + let total_changed = + state.rm_delegation_if_exists::(&candidate, delegator.clone(), amount)?; + T::Currency::unreserve(&delegator, amount); + if state.is_active() && total_changed { + Self::update_active(candidate.clone(), state.total_counted); + } + let new_total_locked = >::get().saturating_sub(amount); + >::put(new_total_locked); + let new_total = state.total_counted; + >::insert(&candidate, state); + Self::deposit_event(Event::DelegatorLeftCandidate( + delegator, candidate, amount, new_total, + )); + Ok(()) + } + fn prepare_staking_payouts(now: RoundIndex) { + // payout is now - delay rounds ago => now - delay > 0 else return early + let delay = T::RewardPaymentDelay::get(); + if now <= delay { + return; + } + let round_to_payout = now - delay; + let total_points = >::get(round_to_payout); + if total_points.is_zero() { + return; + } + let total_staked = >::take(round_to_payout); + let total_issuance = Self::compute_issuance(total_staked); + let mut left_issuance = total_issuance; + // reserve portion of issuance for parachain bond account + let bond_config = >::get(); + let parachain_bond_reserve = bond_config.percent * total_issuance; + if let Ok(imb) = + T::Currency::deposit_into_existing(&bond_config.account, parachain_bond_reserve) + { + // update round issuance iff transfer succeeds + left_issuance -= imb.peek(); + Self::deposit_event(Event::ReservedForParachainBond( + bond_config.account, + imb.peek(), + )); + } + + let payout = DelayedPayout { + round_issuance: total_issuance, + total_staking_reward: left_issuance, + collator_commission: >::get(), + }; + + >::insert(round_to_payout, payout); + } + + /// Wrapper around pay_one_collator_reward which handles the following logic: + /// * whether or not a payout needs to be made + /// * cleaning up when payouts are done + /// * returns the weight consumed by pay_one_collator_reward if applicable + fn handle_delayed_payouts(now: RoundIndex) -> Weight { + let delay = T::RewardPaymentDelay::get(); + + // don't underflow uint + if now < delay { + return 0u64.into(); + } + + let paid_for_round = now - delay; + + if let Some(payout_info) = >::get(paid_for_round) { + let result = Self::pay_one_collator_reward(paid_for_round, payout_info); + if result.0.is_none() { + // result.0 indicates whether or not a payout was made + // clean up storage items that we no longer need + >::remove(paid_for_round); + >::remove(paid_for_round); + } + result.1 // weight consumed by pay_one_collator_reward + } else { + 0u64.into() + } + } + + /// Payout a single collator from the given round. + /// + /// Returns an optional tuple of (Collator's AccountId, total paid) + /// or None if there were no more payouts to be made for the round. + pub(crate) fn pay_one_collator_reward( + paid_for_round: RoundIndex, + payout_info: DelayedPayout>, + ) -> (Option<(T::AccountId, BalanceOf)>, Weight) { + // TODO: it would probably be optimal to roll Points into the DelayedPayouts storage + // item so that we do fewer reads each block + let total_points = >::get(paid_for_round); + if total_points.is_zero() { + // TODO: this case is obnoxious... it's a value query, so it could mean one of two + // different logic errors: + // 1. we removed it before we should have + // 2. we called pay_one_collator_reward when we were actually done with deferred + // payouts + log::warn!("pay_one_collator_reward called with no > for the round!"); + return (None, 0u64.into()); + } + + let mint = |amt: BalanceOf, to: T::AccountId| { + if let Ok(amount_transferred) = T::Currency::deposit_into_existing(&to, amt) { + Self::deposit_event(Event::Rewarded(to.clone(), amount_transferred.peek())); + } + }; + + let collator_fee = payout_info.collator_commission; + let collator_issuance = collator_fee * payout_info.round_issuance; + + if let Some((collator, pts)) = + >::iter_prefix(paid_for_round).drain().next() + { + let pct_due = Perbill::from_rational(pts, total_points); + let total_paid = pct_due * payout_info.total_staking_reward; + let mut amt_due = total_paid; + // Take the snapshot of block author and delegations + let state = >::take(paid_for_round, &collator); + let num_delegators = state.delegations.len(); + if state.delegations.is_empty() { + // solo collator with no delegators + mint(amt_due, collator.clone()); + } else { + // pay collator first; commission + due_portion + let collator_pct = Perbill::from_rational(state.bond, state.total); + let commission = pct_due * collator_issuance; + amt_due -= commission; + let collator_reward = (collator_pct * amt_due) + commission; + mint(collator_reward, collator.clone()); + // pay delegators due portion + for Bond { owner, amount } in state.delegations { + let percent = Perbill::from_rational(amount, state.total); + let due = percent * amt_due; + mint(due, owner.clone()); + } + } + + ( + Some((collator, total_paid)), + T::WeightInfo::pay_one_collator_reward(num_delegators as u32), + ) + } else { + // Note that we don't clean up storage here; it is cleaned up in + // handle_delayed_payouts() + (None, 0u64.into()) + } + } + + /// Compute the top `TotalSelected` candidates in the CandidatePool and return + /// a vec of their AccountIds (in the order of selection) + pub fn compute_top_candidates() -> Vec { + let mut candidates = >::get().0; + // order candidates by stake (least to greatest so requires `rev()`) + candidates.sort_by(|a, b| a.amount.partial_cmp(&b.amount).unwrap()); + let top_n = >::get() as usize; + // choose the top TotalSelected qualified candidates, ordered by stake + let mut collators = candidates + .into_iter() + .rev() + .take(top_n) + .filter(|x| x.amount >= T::MinCollatorStk::get()) + .map(|x| x.owner) + .collect::>(); + collators.sort(); + collators + } + /// Best as in most cumulatively supported in terms of stake + /// Returns [collator_count, delegation_count, total staked] + fn select_top_candidates(now: RoundIndex) -> (u32, u32, BalanceOf) { + let (mut collator_count, mut delegation_count, mut total) = + (0u32, 0u32, BalanceOf::::zero()); + // choose the top TotalSelected qualified candidates, ordered by stake + let collators = Self::compute_top_candidates(); + // snapshot exposure for round for weighting reward distribution + for account in collators.iter() { + let state = >::get(account) + .expect("all members of CandidateQ must be candidates"); + let top_delegations = >::get(account) + .expect("all members of CandidateQ must be candidates"); + collator_count += 1u32; + delegation_count += state.delegation_count; + total += state.total_counted; + let snapshot_total = state.total_counted; + let snapshot = CollatorSnapshot { + bond: state.bond, + delegations: top_delegations.delegations, + total: state.total_counted, + }; + >::insert(now, account, snapshot); + Self::deposit_event(Event::CollatorChosen(now, account.clone(), snapshot_total)); + } + // insert canonical collator set + >::put(collators); + (collator_count, delegation_count, total) + } + } + + /// Add reward points to block authors: + /// * 20 points to the block producer for producing a block in the chain + impl nimbus_primitives::EventHandler for Pallet { + fn note_author(author: T::AccountId) { + let now = >::get().current; + let score_plus_20 = >::get(now, &author) + 20; + >::insert(now, author, score_plus_20); + >::mutate(now, |x| *x += 20); + } + } + + impl nimbus_primitives::CanAuthor for Pallet { + fn can_author(account: &T::AccountId, _slot: &u32) -> bool { + Self::is_selected_candidate(account) + } + } + + impl Get> for Pallet { + fn get() -> Vec { + Self::selected_candidates() + } + } } diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index fc436c54..5c1b2a54 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2021 PureStake Inc. +// Copyright 2019-2022 PureStake Inc. // This file is part of Moonbeam. // Moonbeam is free software: you can redistribute it and/or modify @@ -15,19 +15,19 @@ // along with Moonbeam. If not, see . //! Test utilities -use crate as stake; +use crate as parachain_staking; use crate::{pallet, AwardedPts, Config, InflationInfo, Points, Range}; use frame_support::{ - construct_runtime, parameter_types, - traits::{Everything, GenesisBuild, OnFinalize, OnInitialize}, - weights::Weight, + construct_runtime, parameter_types, + traits::{Everything, GenesisBuild, OnFinalize, OnInitialize}, + weights::Weight, }; use sp_core::H256; use sp_io; use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, - Perbill, Percent, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + Perbill, Percent, }; pub type AccountId = u64; @@ -39,307 +39,514 @@ type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Stake: stake::{Pallet, Call, Storage, Config, Event}, - } + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParachainStaking: parachain_staking::{Pallet, Call, Storage, Config, Event}, + } ); parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const SS58Prefix: u8 = 105; + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const SS58Prefix: u8 = 42; } impl frame_system::Config for Test { - type BaseCallFilter = Everything; - type DbWeight = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = BlockNumber; - type Call = Call; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type BlockHashCount = BlockHashCount; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type BlockWeights = (); - type BlockLength = (); - type SS58Prefix = SS58Prefix; - type OnSetCode = (); + type BaseCallFilter = Everything; + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type BlockWeights = (); + type BlockLength = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { - pub const ExistentialDeposit: u128 = 1; + pub const ExistentialDeposit: u128 = 1; } impl pallet_balances::Config for Test { - type MaxReserves = (); - type ReserveIdentifier = [u8; 4]; - type MaxLocks = (); - type Balance = Balance; - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); } parameter_types! { - pub const MinBlocksPerRound: u32 = 3; - pub const DefaultBlocksPerRound: u32 = 5; - pub const LeaveCandidatesDelay: u32 = 2; - pub const LeaveNominatorsDelay: u32 = 2; - pub const RevokeNominationDelay: u32 = 2; - pub const RewardPaymentDelay: u32 = 2; - pub const MinSelectedCandidates: u32 = 5; - pub const MaxNominatorsPerCollator: u32 = 4; - pub const MaxCollatorsPerNominator: u32 = 4; - pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(20); - pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30); - pub const MinCollatorStk: u128 = 10; - pub const MinNominatorStk: u128 = 5; - pub const MinNomination: u128 = 3; + pub const MinBlocksPerRound: u32 = 3; + pub const DefaultBlocksPerRound: u32 = 5; + pub const LeaveCandidatesDelay: u32 = 2; + pub const CandidateBondLessDelay: u32 = 2; + pub const LeaveDelegatorsDelay: u32 = 2; + pub const RevokeDelegationDelay: u32 = 2; + pub const DelegationBondLessDelay: u32 = 2; + pub const RewardPaymentDelay: u32 = 2; + pub const MinSelectedCandidates: u32 = 5; + pub const MaxTopDelegationsPerCandidate: u32 = 4; + pub const MaxBottomDelegationsPerCandidate: u32 = 4; + pub const MaxDelegationsPerDelegator: u32 = 4; + pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(20); + pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30); + pub const MinCollatorStk: u128 = 10; + pub const MinDelegatorStk: u128 = 5; + pub const MinDelegation: u128 = 3; } impl Config for Test { - type Event = Event; - type Currency = Balances; - type MonetaryGovernanceOrigin = frame_system::EnsureRoot; - type MinBlocksPerRound = MinBlocksPerRound; - type DefaultBlocksPerRound = DefaultBlocksPerRound; - type LeaveCandidatesDelay = LeaveCandidatesDelay; - type LeaveNominatorsDelay = LeaveNominatorsDelay; - type RevokeNominationDelay = RevokeNominationDelay; - type RewardPaymentDelay = RewardPaymentDelay; - type MinSelectedCandidates = MinSelectedCandidates; - type MaxNominatorsPerCollator = MaxNominatorsPerCollator; - type MaxCollatorsPerNominator = MaxCollatorsPerNominator; - type DefaultCollatorCommission = DefaultCollatorCommission; - type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; - type MinCollatorStk = MinCollatorStk; - type MinCollatorCandidateStk = MinCollatorStk; - type MinNominatorStk = MinNominatorStk; - type MinNomination = MinNomination; - type WeightInfo = (); + type Event = Event; + type Currency = Balances; + type MonetaryGovernanceOrigin = frame_system::EnsureRoot; + type MinBlocksPerRound = MinBlocksPerRound; + type DefaultBlocksPerRound = DefaultBlocksPerRound; + type LeaveCandidatesDelay = LeaveCandidatesDelay; + type CandidateBondLessDelay = CandidateBondLessDelay; + type LeaveDelegatorsDelay = LeaveDelegatorsDelay; + type RevokeDelegationDelay = RevokeDelegationDelay; + type DelegationBondLessDelay = DelegationBondLessDelay; + type RewardPaymentDelay = RewardPaymentDelay; + type MinSelectedCandidates = MinSelectedCandidates; + type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; + type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; + type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; + type DefaultCollatorCommission = DefaultCollatorCommission; + type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; + type MinCollatorStk = MinCollatorStk; + type MinCandidateStk = MinCollatorStk; + type MinDelegatorStk = MinDelegatorStk; + type MinDelegation = MinDelegation; + type WeightInfo = (); } pub(crate) struct ExtBuilder { - // endowed accounts with balances - balances: Vec<(AccountId, Balance)>, - // [collator, amount] - collators: Vec<(AccountId, Balance)>, - // [nominator, collator, nomination_amount] - nominations: Vec<(AccountId, AccountId, Balance)>, - // inflation config - inflation: InflationInfo, + // endowed accounts with balances + balances: Vec<(AccountId, Balance)>, + // [collator, amount] + collators: Vec<(AccountId, Balance)>, + // [delegator, collator, delegation_amount] + delegations: Vec<(AccountId, AccountId, Balance)>, + // inflation config + inflation: InflationInfo, } impl Default for ExtBuilder { - fn default() -> ExtBuilder { - ExtBuilder { - balances: vec![], - nominations: vec![], - collators: vec![], - inflation: InflationInfo { - expect: Range { - min: 700, - ideal: 700, - max: 700, - }, - // not used - annual: Range { - min: Perbill::from_percent(50), - ideal: Perbill::from_percent(50), - max: Perbill::from_percent(50), - }, - // unrealistically high parameterization, only for testing - round: Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5), - }, - }, - } - } + fn default() -> ExtBuilder { + ExtBuilder { + balances: vec![], + delegations: vec![], + collators: vec![], + inflation: InflationInfo { + expect: Range { + min: 700, + ideal: 700, + max: 700, + }, + // not used + annual: Range { + min: Perbill::from_percent(50), + ideal: Perbill::from_percent(50), + max: Perbill::from_percent(50), + }, + // unrealistically high parameterization, only for testing + round: Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5), + }, + }, + } + } } impl ExtBuilder { - pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self { - self.balances = balances; - self - } - - pub(crate) fn with_candidates(mut self, collators: Vec<(AccountId, Balance)>) -> Self { - self.collators = collators; - self - } - - pub(crate) fn with_nominations( - mut self, - nominations: Vec<(AccountId, AccountId, Balance)>, - ) -> Self { - self.nominations = nominations; - self - } - - #[allow(dead_code)] - pub(crate) fn with_inflation(mut self, inflation: InflationInfo) -> Self { - self.inflation = inflation; - self - } - - pub(crate) fn build(self) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .expect("Frame system builds valid default genesis config"); - - pallet_balances::GenesisConfig:: { - balances: self.balances, - } - .assimilate_storage(&mut t) - .expect("Pallet balances storage can be assimilated"); - stake::GenesisConfig:: { - candidates: self.collators, - nominations: self.nominations, - inflation_config: self.inflation, - } - .assimilate_storage(&mut t) - .expect("Parachain Staking's storage can be assimilated"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } + pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self { + self.balances = balances; + self + } + + pub(crate) fn with_candidates(mut self, collators: Vec<(AccountId, Balance)>) -> Self { + self.collators = collators; + self + } + + pub(crate) fn with_delegations( + mut self, + delegations: Vec<(AccountId, AccountId, Balance)>, + ) -> Self { + self.delegations = delegations; + self + } + + #[allow(dead_code)] + pub(crate) fn with_inflation(mut self, inflation: InflationInfo) -> Self { + self.inflation = inflation; + self + } + + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: self.balances, + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + parachain_staking::GenesisConfig:: { + candidates: self.collators, + delegations: self.delegations, + inflation_config: self.inflation, + } + .assimilate_storage(&mut t) + .expect("Parachain Staking's storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} + +/// Rolls forward one block. Returns the new block number. +pub(crate) fn roll_one_block() -> u64 { + ParachainStaking::on_finalize(System::block_number()); + Balances::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()); + Balances::on_initialize(System::block_number()); + ParachainStaking::on_initialize(System::block_number()); + System::block_number() +} + +/// Rolls to the desired block. Returns the number of blocks played. +pub(crate) fn roll_to(n: u64) -> u64 { + let mut num_blocks = 0; + let mut block = System::block_number(); + while block < n { + block = roll_one_block(); + num_blocks += 1; + } + num_blocks } -pub(crate) fn roll_to(n: u64) { - while System::block_number() < n { - Stake::on_finalize(System::block_number()); - Balances::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()); - Balances::on_initialize(System::block_number()); - Stake::on_initialize(System::block_number()); - } +/// Rolls block-by-block to the beginning of the specified round. +/// This will complete the block in which the round change occurs. +/// Returns the number of blocks played. +pub(crate) fn roll_to_round_begin(round: u64) -> u64 { + let block = (round - 1) * DefaultBlocksPerRound::get() as u64; + roll_to(block) +} + +/// Rolls block-by-block to the end of the specified round. +/// The block following will be the one in which the specified round change occurs. +pub(crate) fn roll_to_round_end(round: u64) -> u64 { + let block = round * DefaultBlocksPerRound::get() as u64 - 1; + roll_to(block) } pub(crate) fn last_event() -> Event { - System::events().pop().expect("Event expected").event + System::events().pop().expect("Event expected").event } pub(crate) fn events() -> Vec> { - System::events() - .into_iter() - .map(|r| r.event) - .filter_map(|e| { - if let Event::Stake(inner) = e { - Some(inner) - } else { - None - } - }) - .collect::>() + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + if let Event::ParachainStaking(inner) = e { + Some(inner) + } else { + None + } + }) + .collect::>() +} + +/// Assert input equal to the last event emitted +#[macro_export] +macro_rules! assert_last_event { + ($event:expr) => { + match &$event { + e => assert_eq!(*e, crate::mock::last_event()), + } + }; +} + +/// Compares the system events with passed in events +/// Prints highlighted diff iff assert_eq fails +#[macro_export] +macro_rules! assert_eq_events { + ($events:expr) => { + match &$events { + e => similar_asserts::assert_eq!(*e, crate::mock::events()), + } + }; +} + +/// Compares the last N system events with passed in events, where N is the length of events passed +/// in. +/// +/// Prints highlighted diff iff assert_eq fails. +/// The last events from frame_system will be taken in order to match the number passed to this +/// macro. If there are insufficient events from frame_system, they will still be compared; the +/// output may or may not be helpful. +/// +/// Examples: +/// If frame_system has events [A, B, C, D, E] and events [C, D, E] are passed in, the result would +/// be a successful match ([C, D, E] == [C, D, E]). +/// +/// If frame_system has events [A, B, C, D] and events [B, C] are passed in, the result would be an +/// error and a hopefully-useful diff will be printed between [C, D] and [B, C]. +/// +/// Note that events are filtered to only match parachain-staking (see events()). +#[macro_export] +macro_rules! assert_eq_last_events { + ($events:expr) => { + assert_tail_eq!($events, crate::mock::events()); + }; +} + +/// Assert that one array is equal to the tail of the other. A more generic and testable version of +/// assert_eq_last_events. +#[macro_export] +macro_rules! assert_tail_eq { + ($tail:expr, $arr:expr) => { + if $tail.len() != 0 { + // 0-length always passes + + if $tail.len() > $arr.len() { + similar_asserts::assert_eq!($tail, $arr); // will fail + } + + let len_diff = $arr.len() - $tail.len(); + similar_asserts::assert_eq!($tail, $arr[len_diff..]); + } + }; +} + +/// Panics if an event is not found in the system log of events +#[macro_export] +macro_rules! assert_event_emitted { + ($event:expr) => { + match &$event { + e => { + assert!( + crate::mock::events().iter().find(|x| *x == e).is_some(), + "Event {:?} was not found in events: \n {:?}", + e, + crate::mock::events() + ); + } + } + }; +} + +/// Panics if an event is found in the system log of events +#[macro_export] +macro_rules! assert_event_not_emitted { + ($event:expr) => { + match &$event { + e => { + assert!( + crate::mock::events().iter().find(|x| *x == e).is_none(), + "Event {:?} was found in events: \n {:?}", + e, + crate::mock::events() + ); + } + } + }; } // Same storage changes as EventHandler::note_author impl pub(crate) fn set_author(round: u32, acc: u64, pts: u32) { - >::mutate(round, |p| *p += pts); - >::mutate(round, acc, |p| *p += pts); + >::mutate(round, |p| *p += pts); + >::mutate(round, acc, |p| *p += pts); } #[test] fn geneses() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 300), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 9), - (9, 4), - ]) - .with_candidates(vec![(1, 500), (2, 200)]) - .with_nominations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) - .build() - .execute_with(|| { - assert!(System::events().is_empty()); - // collators - assert_eq!(Balances::reserved_balance(&1), 500); - assert_eq!(Balances::free_balance(&1), 500); - assert!(Stake::is_candidate(&1)); - assert_eq!(Balances::reserved_balance(&2), 200); - assert_eq!(Balances::free_balance(&2), 100); - assert!(Stake::is_candidate(&2)); - // nominators - for x in 3..7 { - assert!(Stake::is_nominator(&x)); - assert_eq!(Balances::free_balance(&x), 0); - assert_eq!(Balances::reserved_balance(&x), 100); - } - // uninvolved - for x in 7..10 { - assert!(!Stake::is_nominator(&x)); - } - assert_eq!(Balances::free_balance(&7), 100); - assert_eq!(Balances::reserved_balance(&7), 0); - assert_eq!(Balances::free_balance(&8), 9); - assert_eq!(Balances::reserved_balance(&8), 0); - assert_eq!(Balances::free_balance(&9), 4); - assert_eq!(Balances::reserved_balance(&9), 0); - }); - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_nominations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - assert!(System::events().is_empty()); - // collators - for x in 1..5 { - assert!(Stake::is_candidate(&x)); - assert_eq!(Balances::free_balance(&x), 80); - assert_eq!(Balances::reserved_balance(&x), 20); - } - assert!(Stake::is_candidate(&5)); - assert_eq!(Balances::free_balance(&5), 90); - assert_eq!(Balances::reserved_balance(&5), 10); - // nominators - for x in 6..11 { - assert!(Stake::is_nominator(&x)); - assert_eq!(Balances::free_balance(&x), 90); - assert_eq!(Balances::reserved_balance(&x), 10); - } - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 300), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 9), + (9, 4), + ]) + .with_candidates(vec![(1, 500), (2, 200)]) + .with_delegations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) + .build() + .execute_with(|| { + assert!(System::events().is_empty()); + // collators + assert_eq!(Balances::reserved_balance(&1), 500); + assert_eq!(Balances::free_balance(&1), 500); + assert!(ParachainStaking::is_candidate(&1)); + assert_eq!(Balances::reserved_balance(&2), 200); + assert_eq!(Balances::free_balance(&2), 100); + assert!(ParachainStaking::is_candidate(&2)); + // delegators + for x in 3..7 { + assert!(ParachainStaking::is_delegator(&x)); + assert_eq!(Balances::free_balance(&x), 0); + assert_eq!(Balances::reserved_balance(&x), 100); + } + // uninvolved + for x in 7..10 { + assert!(!ParachainStaking::is_delegator(&x)); + } + assert_eq!(Balances::free_balance(&7), 100); + assert_eq!(Balances::reserved_balance(&7), 0); + assert_eq!(Balances::free_balance(&8), 9); + assert_eq!(Balances::reserved_balance(&8), 0); + assert_eq!(Balances::free_balance(&9), 4); + assert_eq!(Balances::reserved_balance(&9), 0); + }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + assert!(System::events().is_empty()); + // collators + for x in 1..5 { + assert!(ParachainStaking::is_candidate(&x)); + assert_eq!(Balances::free_balance(&x), 80); + assert_eq!(Balances::reserved_balance(&x), 20); + } + assert!(ParachainStaking::is_candidate(&5)); + assert_eq!(Balances::free_balance(&5), 90); + assert_eq!(Balances::reserved_balance(&5), 10); + // delegators + for x in 6..11 { + assert!(ParachainStaking::is_delegator(&x)); + assert_eq!(Balances::free_balance(&x), 90); + assert_eq!(Balances::reserved_balance(&x), 10); + } + }); +} + +#[test] +fn roll_to_round_begin_works() { + ExtBuilder::default().build().execute_with(|| { + // these tests assume blocks-per-round of 5, as established by DefaultBlocksPerRound + assert_eq!(System::block_number(), 1); // we start on block 1 + + let num_blocks = roll_to_round_begin(1); + assert_eq!(System::block_number(), 1); // no-op, we're already on this round + assert_eq!(num_blocks, 0); + + let num_blocks = roll_to_round_begin(2); + assert_eq!(System::block_number(), 5); + assert_eq!(num_blocks, 4); + + let num_blocks = roll_to_round_begin(3); + assert_eq!(System::block_number(), 10); + assert_eq!(num_blocks, 5); + }); +} + +#[test] +fn roll_to_round_end_works() { + ExtBuilder::default().build().execute_with(|| { + // these tests assume blocks-per-round of 5, as established by DefaultBlocksPerRound + assert_eq!(System::block_number(), 1); // we start on block 1 + + let num_blocks = roll_to_round_end(1); + assert_eq!(System::block_number(), 4); + assert_eq!(num_blocks, 3); + + let num_blocks = roll_to_round_end(2); + assert_eq!(System::block_number(), 9); + assert_eq!(num_blocks, 5); + + let num_blocks = roll_to_round_end(3); + assert_eq!(System::block_number(), 14); + assert_eq!(num_blocks, 5); + }); +} + +#[test] +fn assert_tail_eq_works() { + assert_tail_eq!(vec![1, 2], vec![0, 1, 2]); + + assert_tail_eq!(vec![1], vec![1]); + + assert_tail_eq!( + vec![0u32; 0], // 0 length array + vec![0u32; 1] // 1-length array + ); + + assert_tail_eq!(vec![0u32, 0], vec![0u32, 0]); +} + +#[test] +#[should_panic] +fn assert_tail_eq_panics_on_non_equal_tail() { + assert_tail_eq!(vec![2, 2], vec![0, 1, 2]); +} + +#[test] +#[should_panic] +fn assert_tail_eq_panics_on_empty_arr() { + assert_tail_eq!(vec![2, 2], vec![0u32; 0]); +} + +#[test] +#[should_panic] +fn assert_tail_eq_panics_on_longer_tail() { + assert_tail_eq!(vec![1, 2, 3], vec![1, 2]); +} + +#[test] +#[should_panic] +fn assert_tail_eq_panics_on_unequal_elements_same_length_array() { + assert_tail_eq!(vec![1, 2, 3], vec![0, 1, 2]); } diff --git a/pallets/parachain-staking/src/set.rs b/pallets/parachain-staking/src/set.rs index 860d6d62..8e4e2964 100644 --- a/pallets/parachain-staking/src/set.rs +++ b/pallets/parachain-staking/src/set.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2021 PureStake Inc. +// Copyright 2019-2022 PureStake Inc. // This file is part of Moonbeam. // Moonbeam is free software: you can redistribute it and/or modify @@ -28,62 +28,62 @@ use sp_std::prelude::*; pub struct OrderedSet(pub Vec); impl OrderedSet { - /// Create a new empty set - pub fn new() -> Self { - Self(Vec::new()) - } + /// Create a new empty set + pub fn new() -> Self { + Self(Vec::new()) + } - /// Create a set from a `Vec`. - /// `v` will be sorted and dedup first. - pub fn from(mut v: Vec) -> Self { - v.sort(); - v.dedup(); - Self::from_sorted_set(v) - } + /// Create a set from a `Vec`. + /// `v` will be sorted and dedup first. + pub fn from(mut v: Vec) -> Self { + v.sort(); + v.dedup(); + Self::from_sorted_set(v) + } - /// Create a set from a `Vec`. - /// Assume `v` is sorted and contain unique elements. - pub fn from_sorted_set(v: Vec) -> Self { - Self(v) - } + /// Create a set from a `Vec`. + /// Assume `v` is sorted and contain unique elements. + pub fn from_sorted_set(v: Vec) -> Self { + Self(v) + } - /// Insert an element. - /// Return true if insertion happened. - pub fn insert(&mut self, value: T) -> bool { - match self.0.binary_search(&value) { - Ok(_) => false, - Err(loc) => { - self.0.insert(loc, value); - true - } - } - } + /// Insert an element. + /// Return true if insertion happened. + pub fn insert(&mut self, value: T) -> bool { + match self.0.binary_search(&value) { + Ok(_) => false, + Err(loc) => { + self.0.insert(loc, value); + true + } + } + } - /// Remove an element. - /// Return true if removal happened. - pub fn remove(&mut self, value: &T) -> bool { - match self.0.binary_search(&value) { - Ok(loc) => { - self.0.remove(loc); - true - } - Err(_) => false, - } - } + /// Remove an element. + /// Return true if removal happened. + pub fn remove(&mut self, value: &T) -> bool { + match self.0.binary_search(value) { + Ok(loc) => { + self.0.remove(loc); + true + } + Err(_) => false, + } + } - /// Return if the set contains `value` - pub fn contains(&self, value: &T) -> bool { - self.0.binary_search(&value).is_ok() - } + /// Return if the set contains `value` + pub fn contains(&self, value: &T) -> bool { + self.0.binary_search(value).is_ok() + } - /// Clear the set - pub fn clear(&mut self) { - self.0.clear(); - } + /// Clear the set + pub fn clear(&mut self) { + self.0.clear(); + } } impl From> for OrderedSet { - fn from(v: Vec) -> Self { - Self::from(v) - } + fn from(v: Vec) -> Self { + Self::from(v) + } } diff --git a/pallets/parachain-staking/src/tests.rs b/pallets/parachain-staking/src/tests.rs index 895a8ebf..a67fefbc 100644 --- a/pallets/parachain-staking/src/tests.rs +++ b/pallets/parachain-staking/src/tests.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2021 PureStake Inc. +// Copyright 2019-2022 PureStake Inc. // This file is part of Moonbeam. // Moonbeam is free software: you can redistribute it and/or modify @@ -22,511 +22,595 @@ //! 3. Public (Collator, Nominator) //! 4. Miscellaneous Property-Based Tests use crate::mock::{ - events, last_event, roll_to, set_author, Balances, Event as MetaEvent, ExtBuilder, Origin, - Stake, Test, + roll_one_block, roll_to, roll_to_round_begin, roll_to_round_end, set_author, Balances, + Event as MetaEvent, ExtBuilder, Origin, ParachainStaking, Test, }; -use crate::{Bond, CollatorStatus, Error, Event, NominatorAdded, Range}; -use frame_support::{assert_noop, assert_ok}; +use crate::{ + assert_eq_events, assert_eq_last_events, assert_event_emitted, assert_event_not_emitted, + assert_last_event, assert_tail_eq, pallet::CapacityStatus, set::OrderedSet, BalanceOf, Bond, + BottomDelegations, CandidateInfo, CandidatePool, CandidateState, CollatorCandidate, + CollatorStatus, Config, DelegationChange, DelegationRequest, Delegator, DelegatorAdded, + DelegatorState, DelegatorStatus, Error, Event, PendingDelegationRequests, Range, + TopDelegations, Total, +}; +use frame_support::{assert_noop, assert_ok, traits::ReservableCurrency}; use sp_runtime::{traits::Zero, DispatchError, Perbill, Percent}; - -/// Prints the diff iff assert_eq fails, should only be used for debugging purposes -#[macro_export] -macro_rules! asserts_eq { - ($left:expr, $right:expr) => { - match (&$left, &$right) { - (left_val, right_val) => { - similar_asserts::assert_eq!(*left_val, *right_val); - } - } - }; -} +use sp_std::collections::btree_map::BTreeMap; // ~~ ROOT ~~ #[test] fn invalid_root_origin_fails() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_total_selected(Origin::signed(45), 6u32), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - Stake::set_collator_commission(Origin::signed(45), Perbill::from_percent(5)), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - Stake::set_blocks_per_round(Origin::signed(45), 3u32), - sp_runtime::DispatchError::BadOrigin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_total_selected(Origin::signed(45), 6u32), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_collator_commission(Origin::signed(45), Perbill::from_percent(5)), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::signed(45), 3u32), + sp_runtime::DispatchError::BadOrigin + ); + }); } // SET TOTAL SELECTED #[test] fn set_total_selected_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Stake::set_total_selected(Origin::root(), 6u32)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::TotalSelectedSet(5u32, 6u32,)) - ); - }); + ExtBuilder::default().build().execute_with(|| { + // before we can bump total_selected we must bump the blocks per round + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 6u32)); + assert_last_event!(MetaEvent::ParachainStaking(Event::TotalSelectedSet( + 5u32, 6u32 + ))); + }); +} + +#[test] +fn set_total_selected_fails_if_above_blocks_per_round() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::round().length, 5); // test relies on this + assert_noop!( + ParachainStaking::set_total_selected(Origin::root(), 6u32), + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + }); +} + +#[test] +fn set_total_selected_passes_if_equal_to_blocks_per_round() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 10u32)); + }); +} + +#[test] +fn set_total_selected_passes_if_below_blocks_per_round() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 9u32)); + }); +} + +#[test] +fn set_blocks_per_round_fails_if_below_total_selected() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 20u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 15u32)); + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::root(), 14u32), + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + }); +} + +#[test] +fn set_blocks_per_round_passes_if_equal_to_total_selected() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 9u32)); + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 9u32)); + }); +} + +#[test] +fn set_blocks_per_round_passes_if_above_total_selected() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::round().length, 5); // test relies on this + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + }); } #[test] fn set_total_selected_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Stake::total_selected(), 5u32); - assert_ok!(Stake::set_total_selected(Origin::root(), 6u32)); - assert_eq!(Stake::total_selected(), 6u32); - }); + ExtBuilder::default().build().execute_with(|| { + // round length must be >= total_selected, so update that first + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + + assert_eq!(ParachainStaking::total_selected(), 5u32); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 6u32)); + assert_eq!(ParachainStaking::total_selected(), 6u32); + }); } #[test] fn cannot_set_total_selected_to_current_total_selected() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_total_selected(Origin::root(), 5u32), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_total_selected(Origin::root(), 5u32), + Error::::NoWritingSameValue + ); + }); } #[test] fn cannot_set_total_selected_below_module_min() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_total_selected(Origin::root(), 4u32), - Error::::CannotSetBelowMin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_total_selected(Origin::root(), 4u32), + Error::::CannotSetBelowMin + ); + }); } // SET COLLATOR COMMISSION #[test] fn set_collator_commission_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Stake::set_collator_commission( - Origin::root(), - Perbill::from_percent(5) - )); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorCommissionSet( - Perbill::from_percent(20), - Perbill::from_percent(5), - )) - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_collator_commission( + Origin::root(), + Perbill::from_percent(5) + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CollatorCommissionSet( + Perbill::from_percent(20), + Perbill::from_percent(5), + ))); + }); } #[test] fn set_collator_commission_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Stake::collator_commission(), Perbill::from_percent(20)); - assert_ok!(Stake::set_collator_commission( - Origin::root(), - Perbill::from_percent(5) - )); - assert_eq!(Stake::collator_commission(), Perbill::from_percent(5)); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + ParachainStaking::collator_commission(), + Perbill::from_percent(20) + ); + assert_ok!(ParachainStaking::set_collator_commission( + Origin::root(), + Perbill::from_percent(5) + )); + assert_eq!( + ParachainStaking::collator_commission(), + Perbill::from_percent(5) + ); + }); } #[test] fn cannot_set_collator_commission_to_current_collator_commission() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_collator_commission(Origin::root(), Perbill::from_percent(20)), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_collator_commission(Origin::root(), Perbill::from_percent(20)), + Error::::NoWritingSameValue + ); + }); } // SET BLOCKS PER ROUND #[test] fn set_blocks_per_round_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Stake::set_blocks_per_round(Origin::root(), 3u32)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::BlocksPerRoundSet( - 1, - 0, - 5, - 3, - Perbill::from_parts(463), - Perbill::from_parts(463), - Perbill::from_parts(463) - )) - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + assert_last_event!(MetaEvent::ParachainStaking(Event::BlocksPerRoundSet( + 1, + 0, + 5, + 6, + Perbill::from_parts(926), + Perbill::from_parts(926), + Perbill::from_parts(926), + ))); + }); } #[test] fn set_blocks_per_round_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Stake::round().length, 5); - assert_ok!(Stake::set_blocks_per_round(Origin::root(), 3u32)); - assert_eq!(Stake::round().length, 3); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::round().length, 5); + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + assert_eq!(ParachainStaking::round().length, 6); + }); } #[test] fn cannot_set_blocks_per_round_below_module_min() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_blocks_per_round(Origin::root(), 2u32), - Error::::CannotSetBelowMin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::root(), 2u32), + Error::::CannotSetBelowMin + ); + }); } #[test] fn cannot_set_blocks_per_round_to_current_blocks_per_round() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_blocks_per_round(Origin::root(), 5u32), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::root(), 5u32), + Error::::NoWritingSameValue + ); + }); } #[test] fn round_immediately_jumps_if_current_duration_exceeds_new_blocks_per_round() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - // default round every 5 blocks - roll_to(8); - assert_eq!(last_event(), MetaEvent::Stake(Event::NewRound(5, 2, 1, 20))); - assert_ok!(Stake::set_blocks_per_round(Origin::root(), 3u32)); - roll_to(9); - assert_eq!(last_event(), MetaEvent::Stake(Event::NewRound(9, 3, 1, 20))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + // we can't lower the blocks per round because it must be above the number of collators, + // and we can't lower the number of collators because it must be above + // MinSelectedCandidates. so we first raise blocks per round, then lower it. + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + + roll_to(17); + assert_last_event!(MetaEvent::ParachainStaking(Event::NewRound(10, 2, 1, 20))); + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 5u32)); + roll_to(18); + assert_last_event!(MetaEvent::ParachainStaking(Event::NewRound(18, 3, 1, 20))); + }); } // ~~ MONETARY GOVERNANCE ~~ #[test] fn invalid_monetary_origin_fails() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_staking_expectations( - Origin::signed(45), - Range { - min: 3u32.into(), - ideal: 4u32.into(), - max: 5u32.into() - } - ), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - Stake::set_inflation( - Origin::signed(45), - Range { - min: Perbill::from_percent(3), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(5) - } - ), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - Stake::set_inflation( - Origin::signed(45), - Range { - min: Perbill::from_percent(3), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(5) - } - ), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - Stake::set_parachain_bond_account(Origin::signed(45), 11), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - Stake::set_parachain_bond_reserve_percent( - Origin::signed(45), - Percent::from_percent(2) - ), - sp_runtime::DispatchError::BadOrigin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_staking_expectations( + Origin::signed(45), + Range { + min: 3u32.into(), + ideal: 4u32.into(), + max: 5u32.into() + } + ), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_inflation( + Origin::signed(45), + Range { + min: Perbill::from_percent(3), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(5) + } + ), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_inflation( + Origin::signed(45), + Range { + min: Perbill::from_percent(3), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(5) + } + ), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_parachain_bond_account(Origin::signed(45), 11), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_parachain_bond_reserve_percent( + Origin::signed(45), + Percent::from_percent(2) + ), + sp_runtime::DispatchError::BadOrigin + ); + }); } // SET STAKING EXPECTATIONS #[test] fn set_staking_event_emits_event_correctly() { - ExtBuilder::default().build().execute_with(|| { - // valid call succeeds - assert_ok!(Stake::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128, - } - )); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::StakeExpectationsSet(3u128, 4u128, 5u128)) - ); - }); + ExtBuilder::default().build().execute_with(|| { + // valid call succeeds + assert_ok!(ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128, + } + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::StakeExpectationsSet( + 3u128, 4u128, 5u128, + ))); + }); } #[test] fn set_staking_updates_storage_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - Stake::inflation_config().expect, - Range { - min: 700, - ideal: 700, - max: 700 - } - ); - assert_ok!(Stake::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128, - } - )); - assert_eq!( - Stake::inflation_config().expect, - Range { - min: 3u128, - ideal: 4u128, - max: 5u128 - } - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + ParachainStaking::inflation_config().expect, + Range { + min: 700, + ideal: 700, + max: 700 + } + ); + assert_ok!(ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128, + } + )); + assert_eq!( + ParachainStaking::inflation_config().expect, + Range { + min: 3u128, + ideal: 4u128, + max: 5u128 + } + ); + }); } #[test] fn cannot_set_invalid_staking_expectations() { - ExtBuilder::default().build().execute_with(|| { - // invalid call fails - assert_noop!( - Stake::set_staking_expectations( - Origin::root(), - Range { - min: 5u128, - ideal: 4u128, - max: 3u128 - } - ), - Error::::InvalidSchedule - ); - }); + ExtBuilder::default().build().execute_with(|| { + // invalid call fails + assert_noop!( + ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 5u128, + ideal: 4u128, + max: 3u128 + } + ), + Error::::InvalidSchedule + ); + }); } #[test] fn cannot_set_same_staking_expectations() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Stake::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128 - } - )); - assert_noop!( - Stake::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128 - } - ), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128 + } + )); + assert_noop!( + ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128 + } + ), + Error::::NoWritingSameValue + ); + }); } // SET INFLATION #[test] fn set_inflation_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - let (min, ideal, max): (Perbill, Perbill, Perbill) = ( - Perbill::from_percent(3), - Perbill::from_percent(4), - Perbill::from_percent(5), - ); - assert_ok!(Stake::set_inflation( - Origin::root(), - Range { min, ideal, max } - )); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::InflationSet( - min, - ideal, - max, - Perbill::from_parts(57), - Perbill::from_parts(75), - Perbill::from_parts(93) - )) - ); - }); + ExtBuilder::default().build().execute_with(|| { + let (min, ideal, max): (Perbill, Perbill, Perbill) = ( + Perbill::from_percent(3), + Perbill::from_percent(4), + Perbill::from_percent(5), + ); + assert_ok!(ParachainStaking::set_inflation( + Origin::root(), + Range { min, ideal, max } + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::InflationSet( + min, + ideal, + max, + Perbill::from_parts(57), + Perbill::from_parts(75), + Perbill::from_parts(93), + ))); + }); } #[test] fn set_inflation_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - let (min, ideal, max): (Perbill, Perbill, Perbill) = ( - Perbill::from_percent(3), - Perbill::from_percent(4), - Perbill::from_percent(5), - ); - assert_eq!( - Stake::inflation_config().annual, - Range { - min: Perbill::from_percent(50), - ideal: Perbill::from_percent(50), - max: Perbill::from_percent(50) - } - ); - assert_eq!( - Stake::inflation_config().round, - Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5) - } - ); - assert_ok!(Stake::set_inflation( - Origin::root(), - Range { min, ideal, max } - ),); - assert_eq!(Stake::inflation_config().annual, Range { min, ideal, max }); - assert_eq!( - Stake::inflation_config().round, - Range { - min: Perbill::from_parts(57), - ideal: Perbill::from_parts(75), - max: Perbill::from_parts(93) - } - ); - }); + ExtBuilder::default().build().execute_with(|| { + let (min, ideal, max): (Perbill, Perbill, Perbill) = ( + Perbill::from_percent(3), + Perbill::from_percent(4), + Perbill::from_percent(5), + ); + assert_eq!( + ParachainStaking::inflation_config().annual, + Range { + min: Perbill::from_percent(50), + ideal: Perbill::from_percent(50), + max: Perbill::from_percent(50) + } + ); + assert_eq!( + ParachainStaking::inflation_config().round, + Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5) + } + ); + assert_ok!(ParachainStaking::set_inflation( + Origin::root(), + Range { min, ideal, max } + ),); + assert_eq!( + ParachainStaking::inflation_config().annual, + Range { min, ideal, max } + ); + assert_eq!( + ParachainStaking::inflation_config().round, + Range { + min: Perbill::from_parts(57), + ideal: Perbill::from_parts(75), + max: Perbill::from_parts(93) + } + ); + }); } #[test] fn cannot_set_invalid_inflation() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_inflation( - Origin::root(), - Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(3) - } - ), - Error::::InvalidSchedule - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_inflation( + Origin::root(), + Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(3) + } + ), + Error::::InvalidSchedule + ); + }); } #[test] fn cannot_set_same_inflation() { - ExtBuilder::default().build().execute_with(|| { - let (min, ideal, max): (Perbill, Perbill, Perbill) = ( - Perbill::from_percent(3), - Perbill::from_percent(4), - Perbill::from_percent(5), - ); - assert_ok!(Stake::set_inflation( - Origin::root(), - Range { min, ideal, max } - ),); - assert_noop!( - Stake::set_inflation(Origin::root(), Range { min, ideal, max }), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + let (min, ideal, max): (Perbill, Perbill, Perbill) = ( + Perbill::from_percent(3), + Perbill::from_percent(4), + Perbill::from_percent(5), + ); + assert_ok!(ParachainStaking::set_inflation( + Origin::root(), + Range { min, ideal, max } + ),); + assert_noop!( + ParachainStaking::set_inflation(Origin::root(), Range { min, ideal, max }), + Error::::NoWritingSameValue + ); + }); } // SET PARACHAIN BOND ACCOUNT #[test] fn set_parachain_bond_account_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Stake::set_parachain_bond_account(Origin::root(), 11)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::ParachainBondAccountSet(0, 11)) - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_parachain_bond_account( + Origin::root(), + 11 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::ParachainBondAccountSet( + 0, 11 + ))); + }); } #[test] fn set_parachain_bond_account_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Stake::parachain_bond_info().account, 0); - assert_ok!(Stake::set_parachain_bond_account(Origin::root(), 11)); - assert_eq!(Stake::parachain_bond_info().account, 11); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::parachain_bond_info().account, 0); + assert_ok!(ParachainStaking::set_parachain_bond_account( + Origin::root(), + 11 + )); + assert_eq!(ParachainStaking::parachain_bond_info().account, 11); + }); } // SET PARACHAIN BOND RESERVE PERCENT #[test] fn set_parachain_bond_reserve_percent_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Stake::set_parachain_bond_reserve_percent( - Origin::root(), - Percent::from_percent(50) - )); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::ParachainBondReservePercentSet( - Percent::from_percent(30), - Percent::from_percent(50) - )) - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(50) + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::ParachainBondReservePercentSet( + Percent::from_percent(30), + Percent::from_percent(50), + ) + )); + }); } #[test] fn set_parachain_bond_reserve_percent_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - Stake::parachain_bond_info().percent, - Percent::from_percent(30) - ); - assert_ok!(Stake::set_parachain_bond_reserve_percent( - Origin::root(), - Percent::from_percent(50) - )); - assert_eq!( - Stake::parachain_bond_info().percent, - Percent::from_percent(50) - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + ParachainStaking::parachain_bond_info().percent, + Percent::from_percent(30) + ); + assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(50) + )); + assert_eq!( + ParachainStaking::parachain_bond_info().percent, + Percent::from_percent(50) + ); + }); } #[test] fn cannot_set_same_parachain_bond_reserve_percent() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::set_parachain_bond_reserve_percent(Origin::root(), Percent::from_percent(30)), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(30) + ), + Error::::NoWritingSameValue + ); + }); } // ~~ PUBLIC ~~ @@ -535,3371 +619,5668 @@ fn cannot_set_same_parachain_bond_reserve_percent() { #[test] fn join_candidates_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::join_candidates(Origin::signed(1), 10u128, 0u32)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::JoinedCollatorCandidates(1, 10u128, 10u128)) - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::JoinedCollatorCandidates(1, 10u128, 10u128,) + )); + }); } #[test] fn join_candidates_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(Balances::free_balance(&1), 10); - assert_ok!(Stake::join_candidates(Origin::signed(1), 10u128, 0u32)); - assert_eq!(Balances::reserved_balance(&1), 10); - assert_eq!(Balances::free_balance(&1), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(&1), 10); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + assert_eq!(Balances::reserved_balance(&1), 10); + assert_eq!(Balances::free_balance(&1), 0); + }); } #[test] fn join_candidates_increases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::total(), 0); - assert_ok!(Stake::join_candidates(Origin::signed(1), 10u128, 0u32)); - assert_eq!(Stake::total(), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 0); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + assert_eq!(ParachainStaking::total(), 10); + }); } #[test] fn join_candidates_creates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert!(Stake::collator_state2(1).is_none()); - assert_ok!(Stake::join_candidates(Origin::signed(1), 10u128, 0u32)); - let candidate_state = Stake::collator_state2(1).expect("just joined => exists"); - assert_eq!(candidate_state.bond, 10u128); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::candidate_info(1).is_none()); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + let candidate_state = + ParachainStaking::candidate_info(1).expect("just joined => exists"); + assert_eq!(candidate_state.bond, 10u128); + }); } #[test] fn join_candidates_adds_to_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert!(Stake::candidate_pool().0.is_empty()); - assert_ok!(Stake::join_candidates(Origin::signed(1), 10u128, 0u32)); - let candidate_pool = Stake::candidate_pool(); - assert_eq!( - candidate_pool.0[0], - Bond { - owner: 1, - amount: 10u128 - } - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + let candidate_pool = ParachainStaking::candidate_pool(); + assert_eq!(candidate_pool.0[0].owner, 1); + assert_eq!(candidate_pool.0[0].amount, 10); + }); } #[test] fn cannot_join_candidates_if_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 1000)]) - .with_candidates(vec![(1, 500)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::join_candidates(Origin::signed(1), 11u128, 100u32), - Error::::CandidateExists - ); - }); -} - -#[test] -fn cannot_join_candidates_if_nominator() { - ExtBuilder::default() - .with_balances(vec![(1, 50), (2, 20)]) - .with_candidates(vec![(1, 50)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::join_candidates(Origin::signed(2), 10u128, 1u32), - Error::::NominatorExists - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 1000)]) + .with_candidates(vec![(1, 500)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(1), 11u128, 100u32), + Error::::CandidateExists + ); + }); +} + +#[test] +fn cannot_join_candidates_if_delegator() { + ExtBuilder::default() + .with_balances(vec![(1, 50), (2, 20)]) + .with_candidates(vec![(1, 50)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(2), 10u128, 1u32), + Error::::DelegatorExists + ); + }); } #[test] fn cannot_join_candidates_without_min_bond() { - ExtBuilder::default() - .with_balances(vec![(1, 1000)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::join_candidates(Origin::signed(1), 9u128, 100u32), - Error::::ValBondBelowMin - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 1000)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(1), 9u128, 100u32), + Error::::CandidateBondBelowMin + ); + }); } #[test] fn cannot_join_candidates_with_more_than_available_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 500)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::join_candidates(Origin::signed(1), 501u128, 100u32), - DispatchError::Module { - index: 1, - error: 2, - message: Some("InsufficientBalance") - } - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 500)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(1), 501u128, 100u32), + DispatchError::Module { + index: 1, + error: 2, + message: Some("InsufficientBalance") + } + ); + }); } #[test] fn insufficient_join_candidates_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - for i in 0..5 { - assert_noop!( - Stake::join_candidates(Origin::signed(6), 20, i), - Error::::TooLowCandidateCountWeightHintJoinCandidates - ); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + for i in 0..5 { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(6), 20, i), + Error::::TooLowCandidateCountWeightHintJoinCandidates + ); + } + }); } #[test] fn sufficient_join_candidates_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (2, 20), - (3, 20), - (4, 20), - (5, 20), - (6, 20), - (7, 20), - (8, 20), - (9, 20), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - let mut count = 5u32; - for i in 6..10 { - assert_ok!(Stake::join_candidates(Origin::signed(i), 20, count)); - count += 1u32; - } - }); -} - -// LEAVE CANDIDATES + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (2, 20), + (3, 20), + (4, 20), + (5, 20), + (6, 20), + (7, 20), + (8, 20), + (9, 20), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + let mut count = 5u32; + for i in 6..10 { + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(i), + 20, + count + )); + count += 1u32; + } + }); +} + +// SCHEDULE LEAVE CANDIDATES #[test] fn leave_candidates_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1u32)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorScheduledExit(1, 1, 3)) - ); - }); -} - -#[test] -fn leave_candidates_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_eq!(Balances::reserved_balance(&1), 10); - assert_eq!(Balances::free_balance(&1), 0); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1u32)); - roll_to(30); - assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(Balances::free_balance(&1), 10); - }); -} - -#[test] -fn leave_candidates_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_eq!(Stake::total(), 10); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1u32)); - roll_to(30); - assert_eq!(Stake::total(), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( + 1, 1, 3 + ))); + }); } #[test] fn leave_candidates_removes_candidate_from_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::candidate_pool().0.len(), 1); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1u32)); - assert!(Stake::candidate_pool().0.is_empty()); - }); -} - -#[test] -fn leave_candidates_removes_candidate_state_after_exit() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1u32)); - // candidate state is not immediately removed - let candidate_state = Stake::collator_state2(1).expect("just left => still exists"); - assert_eq!(candidate_state.bond, 10u128); - roll_to(30); - assert!(Stake::collator_state2(1).is_none()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert!(ParachainStaking::candidate_pool().0.is_empty()); + }); } #[test] fn cannot_leave_candidates_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::leave_candidates(Origin::signed(1), 1u32), - Error::::CandidateDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_leave_candidates(Origin::signed(1), 1u32), + Error::::CandidateDNE + ); + }); } #[test] fn cannot_leave_candidates_if_already_leaving_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1u32)); - assert_noop!( - Stake::leave_candidates(Origin::signed(1), 1u32), - Error::::CandidateAlreadyLeaving - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_noop!( + ParachainStaking::schedule_leave_candidates(Origin::signed(1), 1u32), + Error::::CandidateAlreadyLeaving + ); + }); } #[test] fn insufficient_leave_candidates_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - for i in 1..6 { - assert_noop!( - Stake::leave_candidates(Origin::signed(i), 4u32), - Error::::TooLowCollatorCandidateCountToLeaveCandidates - ); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + for i in 1..6 { + assert_noop!( + ParachainStaking::schedule_leave_candidates(Origin::signed(i), 4u32), + Error::::TooLowCandidateCountToLeaveCandidates + ); + } + }); } #[test] fn sufficient_leave_candidates_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - let mut count = 5u32; - for i in 1..6 { - assert_ok!(Stake::leave_candidates(Origin::signed(i), count)); - count -= 1u32; - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + let mut count = 5u32; + for i in 1..6 { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(i), + count + )); + count -= 1u32; + } + }); +} + +// EXECUTE LEAVE CANDIDATES + +#[test] +fn execute_leave_candidates_emits_event() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateLeft(1, 10, 0))); + }); +} + +#[test] +fn execute_leave_candidates_callable_by_any_signed() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 1, + 0 + )); + }); +} + +#[test] +fn execute_leave_candidates_requires_correct_weight_hint() { + ExtBuilder::default() + .with_balances(vec![(1, 10), (2, 10), (3, 10), (4, 10)]) + .with_candidates(vec![(1, 10)]) + .with_delegations(vec![(2, 1, 10), (3, 1, 10), (4, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + for i in 0..3 { + assert_noop!( + ParachainStaking::execute_leave_candidates(Origin::signed(1), 1, i), + Error::::TooLowCandidateDelegationCountToLeaveCandidates + ); + } + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 1, + 3 + )); + }); +} + +#[test] +fn execute_leave_candidates_unreserves_balance() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 10); + assert_eq!(Balances::free_balance(&1), 0); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(&1), 10); + }); +} + +#[test] +fn execute_leave_candidates_decreases_total_staked() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 10); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_eq!(ParachainStaking::total(), 0); + }); +} + +#[test] +fn execute_leave_candidates_removes_candidate_state() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + // candidate state is not immediately removed + let candidate_state = + ParachainStaking::candidate_info(1).expect("just left => still exists"); + assert_eq!(candidate_state.bond, 10u128); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert!(ParachainStaking::candidate_state(1).is_none()); + }); +} + +#[test] +fn cannot_execute_leave_candidates_before_delay() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_noop!( + ParachainStaking::execute_leave_candidates(Origin::signed(3), 1, 0), + Error::::CandidateCannotLeaveYet + ); + roll_to(9); + assert_noop!( + ParachainStaking::execute_leave_candidates(Origin::signed(3), 1, 0), + Error::::CandidateCannotLeaveYet + ); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(3), + 1, + 0 + )); + }); +} + +// CANCEL LEAVE CANDIDATES + +#[test] +fn cancel_leave_candidates_emits_event() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_ok!(ParachainStaking::cancel_leave_candidates( + Origin::signed(1), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CancelledCandidateExit( + 1 + ))); + }); +} + +#[test] +fn cancel_leave_candidates_updates_candidate_state() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_ok!(ParachainStaking::cancel_leave_candidates( + Origin::signed(1), + 1 + )); + let candidate = + ParachainStaking::candidate_info(&1).expect("just cancelled leave so exists"); + assert!(candidate.is_active()); + }); +} + +#[test] +fn cancel_leave_candidates_adds_to_candidate_pool() { + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_ok!(ParachainStaking::cancel_leave_candidates( + Origin::signed(1), + 1 + )); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 10); + }); } // GO OFFLINE #[test] fn go_offline_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::go_offline(Origin::signed(1))); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorWentOffline(1, 1)) - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateWentOffline(1))); + }); } #[test] fn go_offline_removes_candidate_from_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_eq!(Stake::candidate_pool().0.len(), 1); - assert_ok!(Stake::go_offline(Origin::signed(1))); - assert!(Stake::candidate_pool().0.is_empty()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert!(ParachainStaking::candidate_pool().0.is_empty()); + }); } #[test] fn go_offline_updates_candidate_state_to_idle() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - let candidate_state = Stake::collator_state2(1).expect("is active candidate"); - assert_eq!(candidate_state.state, CollatorStatus::Active); - assert_ok!(Stake::go_offline(Origin::signed(1))); - let candidate_state = Stake::collator_state2(1).expect("is candidate, just offline"); - assert_eq!(candidate_state.state, CollatorStatus::Idle); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let candidate_state = ParachainStaking::candidate_info(1).expect("is active candidate"); + assert_eq!(candidate_state.status, CollatorStatus::Active); + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + let candidate_state = + ParachainStaking::candidate_info(1).expect("is candidate, just offline"); + assert_eq!(candidate_state.status, CollatorStatus::Idle); + }); } #[test] fn cannot_go_offline_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::go_offline(Origin::signed(3)), - Error::::CandidateDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::go_offline(Origin::signed(3)), + Error::::CandidateDNE + ); + }); } #[test] fn cannot_go_offline_if_already_offline() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::go_offline(Origin::signed(1))); - assert_noop!( - Stake::go_offline(Origin::signed(1)), - Error::::AlreadyOffline - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert_noop!( + ParachainStaking::go_offline(Origin::signed(1)), + Error::::AlreadyOffline + ); + }); } // GO ONLINE #[test] fn go_online_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::go_offline(Origin::signed(1))); - assert_ok!(Stake::go_online(Origin::signed(1))); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorBackOnline(1, 1)) - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert_ok!(ParachainStaking::go_online(Origin::signed(1))); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBackOnline(1))); + }); } #[test] fn go_online_adds_to_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::go_offline(Origin::signed(1))); - assert!(Stake::candidate_pool().0.is_empty()); - assert_ok!(Stake::go_online(Origin::signed(1))); - assert_eq!( - Stake::candidate_pool().0[0], - Bond { - owner: 1, - amount: 20 - } - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert_ok!(ParachainStaking::go_online(Origin::signed(1))); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + }); } #[test] fn go_online_storage_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::go_offline(Origin::signed(1))); - let candidate_state = Stake::collator_state2(1).expect("offline still exists"); - assert_eq!(candidate_state.state, CollatorStatus::Idle); - assert_ok!(Stake::go_online(Origin::signed(1))); - let candidate_state = Stake::collator_state2(1).expect("online so exists"); - assert_eq!(candidate_state.state, CollatorStatus::Active); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + let candidate_state = + ParachainStaking::candidate_info(1).expect("offline still exists"); + assert_eq!(candidate_state.status, CollatorStatus::Idle); + assert_ok!(ParachainStaking::go_online(Origin::signed(1))); + let candidate_state = ParachainStaking::candidate_info(1).expect("online so exists"); + assert_eq!(candidate_state.status, CollatorStatus::Active); + }); } #[test] fn cannot_go_online_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::go_online(Origin::signed(3)), - Error::::CandidateDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::go_online(Origin::signed(3)), + Error::::CandidateDNE + ); + }); } #[test] fn cannot_go_online_if_already_online() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::go_online(Origin::signed(1)), - Error::::AlreadyActive - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::go_online(Origin::signed(1)), + Error::::AlreadyActive + ); + }); +} + +#[test] +fn cannot_go_online_if_leaving() { + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_noop!( + ParachainStaking::go_online(Origin::signed(1)), + Error::::CannotGoOnlineIfLeaving + ); + }); } // CANDIDATE BOND MORE #[test] -fn candidate_bond_more_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::candidate_bond_more(Origin::signed(1), 30)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorBondedMore(1, 20, 50)) - ); - }); +fn candidate_bond_more_emits_correct_event() { + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBondedMore( + 1, 30, 50 + ))); + }); } #[test] fn candidate_bond_more_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&1), 20); - assert_eq!(Balances::free_balance(&1), 30); - assert_ok!(Stake::candidate_bond_more(Origin::signed(1), 30)); - assert_eq!(Balances::reserved_balance(&1), 50); - assert_eq!(Balances::free_balance(&1), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 20); + assert_eq!(Balances::free_balance(&1), 30); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + assert_eq!(Balances::reserved_balance(&1), 50); + assert_eq!(Balances::free_balance(&1), 0); + }); } #[test] fn candidate_bond_more_increases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - let mut total = Stake::total(); - assert_ok!(Stake::candidate_bond_more(Origin::signed(1), 30)); - total += 30; - assert_eq!(Stake::total(), total); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let mut total = ParachainStaking::total(); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + total += 30; + assert_eq!(ParachainStaking::total(), total); + }); } #[test] fn candidate_bond_more_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - let candidate_state = Stake::collator_state2(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 20); - assert_ok!(Stake::candidate_bond_more(Origin::signed(1), 30)); - let candidate_state = Stake::collator_state2(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 50); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 20); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 50); + }); } #[test] fn candidate_bond_more_updates_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_eq!( - Stake::candidate_pool().0[0], - Bond { - owner: 1, - amount: 20 - } - ); - assert_ok!(Stake::candidate_bond_more(Origin::signed(1), 30)); - assert_eq!( - Stake::candidate_pool().0[0], - Bond { - owner: 1, - amount: 50 - } - ); - }); -} - -#[test] -fn cannot_candidate_bond_more_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::candidate_bond_more(Origin::signed(6), 50), - Error::::CandidateDNE - ); - }); -} - -#[test] -fn cannot_candidate_bond_more_if_insufficient_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::candidate_bond_more(Origin::signed(1), 1), - DispatchError::Module { - index: 1, - error: 2, - message: Some("InsufficientBalance") - } - ); - }); -} - -#[test] -fn cannot_candidate_bond_more_if_leaving_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1)); - assert_noop!( - Stake::candidate_bond_more(Origin::signed(1), 30), - Error::::CannotActBecauseLeaving - ); - }); -} - -#[test] -fn cannot_candidate_bond_more_if_exited_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - roll_to(4); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1)); - roll_to(30); - assert_noop!( - Stake::candidate_bond_more(Origin::signed(1), 30), - Error::::CandidateDNE - ); - }); -} - -// CANDIDATE BOND LESS - -#[test] -fn candidate_bond_less_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(Stake::candidate_bond_less(Origin::signed(1), 10)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorBondedLess(1, 30, 20)) - ); - }); -} - -#[test] -fn candidate_bond_less_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&1), 30); - assert_eq!(Balances::free_balance(&1), 0); - assert_ok!(Stake::candidate_bond_less(Origin::signed(1), 10)); - assert_eq!(Balances::reserved_balance(&1), 20); - assert_eq!(Balances::free_balance(&1), 10); - }); -} - -#[test] -fn candidate_bond_less_decreases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - let mut total = Stake::total(); - assert_ok!(Stake::candidate_bond_less(Origin::signed(1), 10)); - total -= 10; - assert_eq!(Stake::total(), total); - }); -} - -#[test] -fn candidate_bond_less_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - let candidate_state = Stake::collator_state2(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 30); - assert_ok!(Stake::candidate_bond_less(Origin::signed(1), 10)); - let candidate_state = Stake::collator_state2(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 20); - }); -} - -#[test] -fn candidate_bond_less_updates_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_eq!( - Stake::candidate_pool().0[0], - Bond { - owner: 1, - amount: 30 - } - ); - assert_ok!(Stake::candidate_bond_less(Origin::signed(1), 10)); - assert_eq!( - Stake::candidate_pool().0[0], - Bond { - owner: 1, - amount: 20 - } - ); - }); -} - -#[test] -fn cannot_candidate_bond_less_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::candidate_bond_less(Origin::signed(6), 50), - Error::::CandidateDNE - ); - }); -} - -#[test] -fn cannot_candidate_bond_less_if_new_total_below_min_candidate_stk() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::candidate_bond_less(Origin::signed(1), 21), - Error::::ValBondBelowMin - ); - }); -} - -#[test] -fn cannot_candidate_bond_less_if_leaving_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1)); - assert_noop!( - Stake::candidate_bond_less(Origin::signed(1), 10), - Error::::CannotActBecauseLeaving - ); - }); -} - -#[test] -fn cannot_candidate_bond_less_if_exited_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - roll_to(4); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1)); - roll_to(30); - assert_noop!( - Stake::candidate_bond_less(Origin::signed(1), 10), - Error::::CandidateDNE - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 50); + }); +} + +// SCHEDULE CANDIDATE BOND LESS + +#[test] +fn schedule_candidate_bond_less_event_emits_correctly() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CandidateBondLessRequested(1, 10, 3,) + )); + }); +} + +#[test] +fn cannot_schedule_candidate_bond_less_if_request_exists() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 5 + )); + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 5), + Error::::PendingCandidateRequestAlreadyExists + ); + }); +} + +#[test] +fn cannot_schedule_candidate_bond_less_if_not_candidate() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(6), 50), + Error::::CandidateDNE + ); + }); +} + +#[test] +fn cannot_schedule_candidate_bond_less_if_new_total_below_min_candidate_stk() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 21), + Error::::CandidateBondBelowMin + ); + }); +} + +#[test] +fn can_schedule_candidate_bond_less_if_leaving_candidates() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + }); +} + +#[test] +fn cannot_schedule_candidate_bond_less_if_exited_candidates() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 10), + Error::::CandidateDNE + ); + }); +} + +// 2. EXECUTE BOND LESS REQUEST + +#[test] +fn execute_candidate_bond_less_emits_correct_event() { + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 50)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 30 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBondedLess( + 1, 30, 20 + ))); + }); +} + +#[test] +fn execute_candidate_bond_less_unreserves_balance() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 30); + assert_eq!(Balances::free_balance(&1), 0); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + assert_eq!(Balances::reserved_balance(&1), 20); + assert_eq!(Balances::free_balance(&1), 10); + }); +} + +#[test] +fn execute_candidate_bond_less_decreases_total() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + let mut total = ParachainStaking::total(); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + total -= 10; + assert_eq!(ParachainStaking::total(), total); + }); +} + +#[test] +fn execute_candidate_bond_less_updates_candidate_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 30); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 20); + }); +} + +#[test] +fn execute_candidate_bond_less_updates_candidate_pool() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 30); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + }); +} + +// CANCEL CANDIDATE BOND LESS REQUEST + +#[test] +fn cancel_candidate_bond_less_emits_event() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_ok!(ParachainStaking::cancel_candidate_bond_less( + Origin::signed(1) + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CancelledCandidateBondLess(1, 10, 3,) + )); + }); +} + +#[test] +fn cancel_candidate_bond_less_updates_candidate_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_ok!(ParachainStaking::cancel_candidate_bond_less( + Origin::signed(1) + )); + assert!(ParachainStaking::candidate_info(&1) + .unwrap() + .request + .is_none()); + }); +} + +#[test] +fn only_candidate_can_cancel_candidate_bond_less_request() { + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_noop!( + ParachainStaking::cancel_candidate_bond_less(Origin::signed(2)), + Error::::CandidateDNE + ); + }); } // NOMINATE #[test] -fn nominate_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(Stake::nominate(Origin::signed(2), 1, 10, 0, 0)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::Nomination( - 2, - 10, - 1, - NominatorAdded::AddedToTop { new_total: 40 } - )), - ); - }); -} - -#[test] -fn nominate_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - assert_ok!(Stake::nominate(Origin::signed(2), 1, 10, 0, 0)); - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - }); -} - -#[test] -fn nominate_updates_nominator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert!(Stake::nominator_state2(2).is_none()); - assert_ok!(Stake::nominate(Origin::signed(2), 1, 10, 0, 0)); - let nominator_state = Stake::nominator_state2(2).expect("just nominated => exists"); - assert_eq!(nominator_state.total, 10); - assert_eq!( - nominator_state.nominations.0[0], - Bond { - owner: 1, - amount: 10 - } - ); - }); -} - -#[test] -fn nominate_updates_collator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - let candidate_state = Stake::collator_state2(1).expect("registered in genesis"); - assert_eq!(candidate_state.total_backing, 30); - assert_eq!(candidate_state.total_counted, 30); - assert!(candidate_state.top_nominators.is_empty()); - assert_ok!(Stake::nominate(Origin::signed(2), 1, 10, 0, 0)); - let candidate_state = Stake::collator_state2(1).expect("just nominated => exists"); - assert_eq!(candidate_state.total_backing, 40); - assert_eq!(candidate_state.total_counted, 40); - assert_eq!( - candidate_state.top_nominators[0], - Bond { - owner: 2, - amount: 10 - } - ); - }); -} - -#[test] -fn can_nominate_immediately_after_other_join_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20)]) - .build() - .execute_with(|| { - assert_ok!(Stake::join_candidates(Origin::signed(1), 20, 0)); - assert_ok!(Stake::nominate(Origin::signed(2), 1, 20, 0, 0)); - }); -} - -#[test] -fn can_nominate_if_revoking() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 30), (3, 20), (4, 20)]) - .with_candidates(vec![(1, 20), (3, 20), (4, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_ok!(Stake::nominate(Origin::signed(2), 4, 10, 0, 2)); - }); -} - -#[test] -fn cannot_nominate_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20)]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - assert_noop!( - Stake::nominate(Origin::signed(2), 1, 10, 0, 0), - Error::::CannotActBecauseLeaving - ); - }); -} - -#[test] -fn cannot_nominate_if_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20)]) - .with_candidates(vec![(1, 20), (2, 20)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominate(Origin::signed(2), 1, 10, 0, 0), - Error::::CandidateExists - ); - }); -} - -#[test] -fn cannot_nominate_if_already_nominated() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 30)]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![(2, 1, 20)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominate(Origin::signed(2), 1, 10, 1, 1), - Error::::AlreadyNominatedCollator - ); - }); -} - -#[test] -fn cannot_nominate_more_than_max_nominations() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 50), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10), (2, 5, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominate(Origin::signed(2), 6, 10, 0, 4), - Error::::ExceedMaxCollatorsPerNom, - ); - }); -} - -#[test] -fn sufficient_nominate_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (2, 20), - (3, 20), - (4, 20), - (5, 20), - (6, 20), - (7, 20), - (8, 20), - (9, 20), - (10, 20), - ]) - .with_candidates(vec![(1, 20), (2, 20)]) - .with_nominations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - let mut count = 4u32; - for i in 7..11 { - assert_ok!(Stake::nominate(Origin::signed(i), 1, 10, count, 0u32)); - count += 1u32; - } - let mut count = 0u32; - for i in 3..11 { - assert_ok!(Stake::nominate(Origin::signed(i), 2, 10, count, 1u32)); - count += 1u32; - } - }); -} - -#[test] -fn insufficient_nominate_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (2, 20), - (3, 20), - (4, 20), - (5, 20), - (6, 20), - (7, 20), - (8, 20), - (9, 20), - (10, 20), - ]) - .with_candidates(vec![(1, 20), (2, 20)]) - .with_nominations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - let mut count = 3u32; - for i in 7..11 { - assert_noop!( - Stake::nominate(Origin::signed(i), 1, 10, count, 0u32), - Error::::TooLowCollatorNominationCountToNominate - ); - } - // to set up for next error test - count = 4u32; - for i in 7..11 { - assert_ok!(Stake::nominate(Origin::signed(i), 1, 10, count, 0u32)); - count += 1u32; - } - count = 0u32; - for i in 3..11 { - assert_noop!( - Stake::nominate(Origin::signed(i), 2, 10, count, 0u32), - Error::::TooLowNominationCountToNominate - ); - count += 1u32; - } - }); -} - -// LEAVE_NOMINATORS - -#[test] -fn leave_nominators_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominatorExitScheduled(1, 2, 3)) - ); - roll_to(10); - assert!(events().contains(&Event::NominatorLeft(2, 10))); - }); -} - -#[test] -fn leave_nominators_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - roll_to(10); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - }); -} - -#[test] -fn leave_nominators_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_eq!(Stake::total(), 40); - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - roll_to(10); - assert_eq!(Stake::total(), 30); - }); -} - -#[test] -fn leave_nominators_removes_nominator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert!(Stake::nominator_state2(2).is_some()); - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - roll_to(10); - assert!(Stake::nominator_state2(2).is_none()); - }); -} - -#[test] -fn leave_nominators_removes_nominations_from_collator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 100), (2, 20), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(2, 20), (3, 20), (4, 20), (5, 20)]) - .with_nominations(vec![(1, 2, 10), (1, 3, 10), (1, 4, 10), (1, 5, 10)]) - .build() - .execute_with(|| { - roll_to(1); - for i in 2..6 { - let candidate_state = - Stake::collator_state2(i).expect("initialized in ext builder"); - assert_eq!( - candidate_state.top_nominators[0], - Bond { - owner: 1, - amount: 10 - } - ); - assert_eq!(candidate_state.nominators.0[0], 1); - assert_eq!(candidate_state.total_backing, 30); - } - assert_eq!( - Stake::nominator_state2(1).unwrap().nominations.0.len(), - 4usize - ); - assert_ok!(Stake::leave_nominators(Origin::signed(1), 10)); - roll_to(10); - for i in 2..6 { - let candidate_state = - Stake::collator_state2(i).expect("initialized in ext builder"); - assert!(candidate_state.top_nominators.is_empty()); - assert!(candidate_state.nominators.0.is_empty()); - assert_eq!(candidate_state.total_backing, 20); - } - }); -} - -#[test] -fn cannot_leave_nominators_if_leaving_through_revoking_last_nomination() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 3)); - assert_noop!( - Stake::leave_nominators(Origin::signed(2), 2), - Error::::NominatorAlreadyLeaving - ); - }); -} - -#[test] -fn cannot_leave_nominators_if_already_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - assert_noop!( - Stake::leave_nominators(Origin::signed(2), 1), - Error::::NominatorAlreadyLeaving - ); - }); -} - -#[test] -fn cannot_leave_nominators_if_not_nominator() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::leave_nominators(Origin::signed(2), 1), - Error::::NominatorDNE - ); - }); -} - -#[test] -fn insufficient_leave_nominators_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - for i in 3..7 { - assert_noop!( - Stake::leave_nominators(Origin::signed(i), 0u32), - Error::::TooLowNominationCountToLeaveNominators - ); - } - }); -} - -#[test] -fn sufficient_leave_nominators_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - for i in 3..7 { - assert_ok!(Stake::leave_nominators(Origin::signed(i), 1u32),); - } - }); -} - -// REVOKE_NOMINATION - -#[test] -fn revoke_nomination_event_emits_exit_scheduled_if_no_nominations_left() { - // last nomination is revocation - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominatorExitScheduled(1, 2, 3)) - ); - roll_to(10); - assert!(events().contains(&Event::NominatorLeftCollator(2, 1, 10, 30))); - assert!(events().contains(&Event::NominatorLeft(2, 10))); - }); -} - -#[test] -fn revoke_nomination_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominationRevocationScheduled(1, 2, 1, 3)) - ); - roll_to(10); - assert!(events().contains(&Event::NominatorLeftCollator(2, 1, 10, 30))); - }); -} - -#[test] -fn revoke_nomination_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - roll_to(10); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - }); -} - -#[test] -fn revoke_nomination_adds_revocation_to_nominator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert!(Stake::nominator_state2(2) - .expect("exists") - .revocations - .0 - .is_empty()); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - Stake::nominator_state2(2).expect("exists").revocations.0[0], - 1 - ); - }); -} - -#[test] -fn revoke_nomination_removes_revocation_from_nominator_state_upon_execution() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - roll_to(10); - assert!(Stake::nominator_state2(2) - .expect("exists") - .revocations - .0 - .is_empty()); - }); -} - -#[test] -fn revoke_nomination_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_eq!(Stake::total(), 40); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - roll_to(10); - assert_eq!(Stake::total(), 30); - }); -} - -#[test] -fn revoke_nomination_for_last_nomination_removes_nominator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert!(Stake::nominator_state2(2).is_some()); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - roll_to(10); - assert!(Stake::nominator_state2(2).is_none()); - }); -} - -#[test] -fn revoke_nomination_removes_nomination_from_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_eq!( - Stake::collator_state2(1) - .expect("exists") - .nominators - .0 - .len(), - 1usize - ); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - roll_to(10); - assert!(Stake::collator_state2(1) - .expect("exists") - .nominators - .0 - .is_empty()); - }); -} - -#[test] -fn can_revoke_nomination_if_revoking_another_nomination() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 3)); - }); -} - -#[test] -fn cannot_revoke_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_nominators(Origin::signed(2), 2)); - assert_noop!( - Stake::revoke_nomination(Origin::signed(2), 3), - Error::::CannotActBecauseLeaving - ); - }); -} - -#[test] -fn cannot_revoke_nomination_if_not_nominator() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::revoke_nomination(Origin::signed(2), 1), - Error::::NominatorDNE - ); - }); -} - -#[test] -fn cannot_revoke_nomination_that_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::revoke_nomination(Origin::signed(2), 3), - Error::::NominationDNE - ); - }); -} - -#[test] -fn cannot_revoke_nomination_leaving_nominator_below_min_nominator_stake() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 8), (3, 20)]) - .with_candidates(vec![(1, 20), (3, 20)]) - .with_nominations(vec![(2, 1, 5), (2, 3, 3)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::revoke_nomination(Origin::signed(2), 1), - Error::::NomBondBelowMin - ); - }); -} - -#[test] -fn revoke_nomination_after_leave_candidates_executes_during_leave_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1)); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominatorExitScheduled(1, 2, 3)) - ); - roll_to(10); - assert!(!Stake::is_nominator(&2)); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - }); -} - -#[test] -fn revoke_nomination_before_leave_candidates_executes_during_leave_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominatorExitScheduled(1, 2, 3)) - ); - assert_ok!(Stake::leave_candidates(Origin::signed(1), 1)); - roll_to(10); - assert!(!Stake::is_nominator(&2)); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - }); -} - -#[test] -fn nominator_bond_more_after_revoke_nomination_does_not_effect_exit() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 30), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominationRevocationScheduled(1, 2, 1, 3)) - ); - assert_noop!( - Stake::nominator_bond_more(Origin::signed(2), 1, 10), - Error::::CannotActBecauseRevoking - ); - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 3, 10)); - roll_to(10); - assert!(Stake::is_nominator(&2)); - assert_eq!(Balances::reserved_balance(&2), 20); - assert_eq!(Balances::free_balance(&2), 10); - }); -} - -#[test] -fn nominator_bond_less_after_revoke_nomination_does_not_effect_exit() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 30), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominationRevocationScheduled(1, 2, 1, 3)) - ); - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 1, 2), - Error::::CannotActBecauseRevoking - ); - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 3, 2)); - roll_to(10); - assert!(Stake::is_nominator(&2)); - assert_eq!(Balances::reserved_balance(&2), 8); - assert_eq!(Balances::free_balance(&2), 22); - }); -} - -// NOMINATOR BOND MORE - -#[test] -fn nominator_bond_more_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 1, 5)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominationIncreased(2, 1, 5, true)) - ); - }); -} - -#[test] -fn nominator_bond_more_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 5); - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 1, 5)); - assert_eq!(Balances::reserved_balance(&2), 15); - assert_eq!(Balances::free_balance(&2), 0); - }); -} - -#[test] -fn nominator_bond_more_increases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::total(), 40); - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 1, 5)); - assert_eq!(Stake::total(), 45); - }); -} - -#[test] -fn nominator_bond_more_updates_nominator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::nominator_state2(2).expect("exists").total, 10); - assert_eq!( - Stake::nominator_state2(2).expect("exists").nominations.0[0], - Bond { - owner: 1, - amount: 10 - } - ); - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 1, 5)); - assert_eq!(Stake::nominator_state2(2).expect("exists").total, 15); - assert_eq!( - Stake::nominator_state2(2).expect("exists").nominations.0[0], - Bond { - owner: 1, - amount: 15 - } - ); - }); -} - -#[test] -fn nominator_bond_more_updates_candidate_state_top_nominators() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!( - Stake::collator_state2(1).expect("exists").top_nominators[0], - Bond { - owner: 2, - amount: 10 - } - ); - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 1, 5)); - assert_eq!( - Stake::collator_state2(1).expect("exists").top_nominators[0], - Bond { - owner: 2, - amount: 15 - } - ); - }); -} - -#[test] -fn nominator_bond_more_updates_candidate_state_bottom_nominators() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![ - (2, 1, 10), - (3, 1, 20), - (4, 1, 20), - (5, 1, 20), - (6, 1, 20), - ]) - .build() - .execute_with(|| { - assert_eq!( - Stake::collator_state2(1).expect("exists").bottom_nominators[0], - Bond { - owner: 2, - amount: 10 - } - ); - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 1, 5)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominationIncreased(2, 1, 5, false)) - ); - assert_eq!( - Stake::collator_state2(1).expect("exists").bottom_nominators[0], - Bond { - owner: 2, - amount: 15 - } - ); - }); -} - -#[test] -fn nominator_bond_more_increases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::total(), 40); - assert_ok!(Stake::nominator_bond_more(Origin::signed(2), 1, 5)); - assert_eq!(Stake::total(), 45); - }); -} - -#[test] -fn cannot_nominator_bond_more_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - assert_noop!( - Stake::nominator_bond_more(Origin::signed(2), 1, 5), - Error::::CannotActBecauseLeaving - ); - }); -} - -#[test] -fn cannot_nominator_bond_more_if_revoking() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 25), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_noop!( - Stake::nominator_bond_more(Origin::signed(2), 1, 5), - Error::::CannotActBecauseRevoking - ); - }); -} - -#[test] -fn cannot_nominator_bond_more_if_not_nominator() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::nominator_bond_more(Origin::signed(2), 1, 5), - Error::::NominatorDNE - ); - }); -} - -#[test] -fn cannot_nominator_bond_more_if_candidate_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_more(Origin::signed(2), 3, 5), - Error::::CandidateDNE - ); - }); -} - -#[test] -fn cannot_nominator_bond_more_if_nomination_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_more(Origin::signed(2), 3, 5), - Error::::NominationDNE - ); - }); -} - -#[test] -fn cannot_nominator_bond_more_if_insufficient_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_more(Origin::signed(2), 1, 5), - DispatchError::Module { - index: 1, - error: 2, - message: Some("InsufficientBalance") - } - ); - }); -} - -// NOMINATOR BOND LESS - -#[test] -fn nominator_bond_less_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 1, 5)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::NominationDecreased(2, 1, 5, true)) - ); - }); -} - -#[test] -fn nominator_bond_less_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 1, 5)); - assert_eq!(Balances::reserved_balance(&2), 5); - assert_eq!(Balances::free_balance(&2), 5); - }); -} - -#[test] -fn nominator_bond_less_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::total(), 40); - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 1, 5)); - assert_eq!(Stake::total(), 35); - }); -} - -#[test] -fn nominator_bond_less_updates_nominator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::nominator_state2(2).expect("exists").total, 10); - assert_eq!( - Stake::nominator_state2(2).expect("exists").nominations.0[0], - Bond { - owner: 1, - amount: 10 - } - ); - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 1, 5)); - assert_eq!(Stake::nominator_state2(2).expect("exists").total, 5); - assert_eq!( - Stake::nominator_state2(2).expect("exists").nominations.0[0], - Bond { - owner: 1, - amount: 5 - } - ); - }); -} - -#[test] -fn nominator_bond_less_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!( - Stake::collator_state2(1).expect("exists").top_nominators[0], - Bond { - owner: 2, - amount: 10 - } - ); - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 1, 5)); - assert_eq!( - Stake::collator_state2(1).expect("exists").top_nominators[0], - Bond { - owner: 2, - amount: 5 - } - ); - }); -} - -#[test] -fn nominator_bond_less_decreases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Stake::total(), 40); - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 1, 5)); - assert_eq!(Stake::total(), 35); - }); -} - -#[test] -fn cannot_nominator_bond_less_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::leave_nominators(Origin::signed(2), 1)); - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 1, 1), - Error::::CannotActBecauseLeaving - ); - }); -} - -#[test] -fn cannot_nominator_bond_less_if_revoking() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 25), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 1, 1), - Error::::CannotActBecauseRevoking - ); - }); -} - -#[test] -fn cannot_nominator_bond_less_if_not_nominator() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 1, 5), - Error::::NominatorDNE - ); - }); -} - -#[test] -fn cannot_nominator_bond_less_if_candidate_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 3, 5), - Error::::CandidateDNE - ); - }); -} - -#[test] -fn cannot_nominator_bond_less_if_nomination_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 3, 5), - Error::::NominationDNE - ); - }); -} - -#[test] -fn cannot_nominator_bond_less_below_min_collator_stk() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 1, 6), - Error::::NomBondBelowMin - ); - }); -} - -#[test] -fn cannot_nominator_bond_less_more_than_total_nomination() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_nominations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 1, 11), - Error::::NomBondBelowMin - ); - }); -} - -#[test] -fn cannot_nominator_bond_less_below_min_nomination() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_noop!( - Stake::nominator_bond_less(Origin::signed(2), 1, 8), - Error::::NominationBelowMin - ); - }); -} - -#[test] -fn nominator_bond_less_updates_just_bottom_nominations() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![ - (2, 1, 10), - (3, 1, 11), - (4, 1, 12), - (5, 1, 14), - (6, 1, 15), - ]) - .build() - .execute_with(|| { - let pre_call_collator_state = - Stake::collator_state2(&1).expect("nominated by all so exists"); - assert_ok!(Stake::nominator_bond_less(Origin::signed(2), 1, 2)); - let post_call_collator_state = - Stake::collator_state2(&1).expect("nominated by all so exists"); - let mut not_equal = false; - for Bond { owner, amount } in pre_call_collator_state.bottom_nominators { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_collator_state.bottom_nominators - { - if &owner == post_owner { - if &amount != post_amount { - not_equal = true; - break; - } - } - } - } - assert!(not_equal); - let mut equal = true; - for Bond { owner, amount } in pre_call_collator_state.top_nominators { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_collator_state.top_nominators - { - if &owner == post_owner { - if &amount != post_amount { - equal = false; - break; - } - } - } - } - assert!(equal); - assert_eq!( - pre_call_collator_state.total_backing - 2, - post_call_collator_state.total_backing - ); - assert_eq!( - pre_call_collator_state.total_counted, - post_call_collator_state.total_counted - ); - }); -} - -#[test] -fn nominator_bond_less_does_not_delete_bottom_nominations() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![ - (2, 1, 10), - (3, 1, 11), - (4, 1, 12), - (5, 1, 14), - (6, 1, 15), - ]) - .build() - .execute_with(|| { - let pre_call_collator_state = - Stake::collator_state2(&1).expect("nominated by all so exists"); - assert_ok!(Stake::nominator_bond_less(Origin::signed(6), 1, 4)); - let post_call_collator_state = - Stake::collator_state2(&1).expect("nominated by all so exists"); - let mut equal = true; - for Bond { owner, amount } in pre_call_collator_state.bottom_nominators { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_collator_state.bottom_nominators - { - if &owner == post_owner { - if &amount != post_amount { - equal = false; - break; - } - } - } - } - assert!(equal); - let mut not_equal = false; - for Bond { owner, amount } in pre_call_collator_state.top_nominators { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_collator_state.top_nominators - { - if &owner == post_owner { - if &amount != post_amount { - not_equal = true; - break; - } - } - } - } - assert!(not_equal); - assert_eq!( - pre_call_collator_state.total_backing - 4, - post_call_collator_state.total_backing - ); - assert_eq!( - pre_call_collator_state.total_counted - 4, - post_call_collator_state.total_counted - ); - }); +fn delegate_event_emits_correctly() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + assert_last_event!(MetaEvent::ParachainStaking(Event::Delegation( + 2, + 10, + 1, + DelegatorAdded::AddedToTop { new_total: 40 }, + ))); + }); +} + +#[test] +fn delegate_reserves_balance() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + }); +} + +#[test] +fn delegate_updates_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2).is_none()); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + let delegator_state = + ParachainStaking::delegator_state(2).expect("just delegated => exists"); + assert_eq!(delegator_state.total, 10); + assert_eq!(delegator_state.delegations.0[0].owner, 1); + assert_eq!(delegator_state.delegations.0[0].amount, 10); + }); +} + +#[test] +fn delegate_updates_collator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + let candidate_state = + ParachainStaking::candidate_info(1).expect("registered in genesis"); + assert_eq!(candidate_state.total_counted, 30); + let top_delegations = + ParachainStaking::top_delegations(1).expect("registered in genesis"); + assert!(top_delegations.delegations.is_empty()); + assert!(top_delegations.total.is_zero()); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + let candidate_state = + ParachainStaking::candidate_info(1).expect("just delegated => exists"); + assert_eq!(candidate_state.total_counted, 40); + let top_delegations = + ParachainStaking::top_delegations(1).expect("just delegated => exists"); + assert_eq!(top_delegations.delegations[0].owner, 2); + assert_eq!(top_delegations.delegations[0].amount, 10); + assert_eq!(top_delegations.total, 10); + }); +} + +#[test] +fn can_delegate_immediately_after_other_join_candidates() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::join_candidates(Origin::signed(1), 20, 0)); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 20, 0, 0)); + }); +} + +#[test] +fn can_delegate_if_revoking() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 30), (3, 20), (4, 20)]) + .with_candidates(vec![(1, 20), (3, 20), (4, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 4, 10, 0, 2)); + }); +} + +#[test] +fn cannot_delegate_if_leaving() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 20), (3, 20)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 3, 10, 0, 1), + Error::::CannotDelegateIfLeaving + ); + }); +} + +#[test] +fn cannot_delegate_if_candidate() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 30)]) + .with_candidates(vec![(1, 20), (2, 20)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0), + Error::::CandidateExists + ); + }); +} + +#[test] +fn cannot_delegate_if_already_delegated() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 30)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(2, 1, 20)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 1, 10, 1, 1), + Error::::AlreadyDelegatedCandidate + ); + }); +} + +#[test] +fn cannot_delegate_more_than_max_delegations() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 50), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10), (2, 5, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 6, 10, 0, 4), + Error::::ExceedMaxDelegationsPerDelegator, + ); + }); +} + +#[test] +fn sufficient_delegate_weight_hint_succeeds() { + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (2, 20), + (3, 20), + (4, 20), + (5, 20), + (6, 20), + (7, 20), + (8, 20), + (9, 20), + (10, 20), + ]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + let mut count = 4u32; + for i in 7..11 { + assert_ok!(ParachainStaking::delegate( + Origin::signed(i), + 1, + 10, + count, + 0u32 + )); + count += 1u32; + } + let mut count = 0u32; + for i in 3..11 { + assert_ok!(ParachainStaking::delegate( + Origin::signed(i), + 2, + 10, + count, + 1u32 + )); + count += 1u32; + } + }); +} + +#[test] +fn insufficient_delegate_weight_hint_fails() { + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (2, 20), + (3, 20), + (4, 20), + (5, 20), + (6, 20), + (7, 20), + (8, 20), + (9, 20), + (10, 20), + ]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + let mut count = 3u32; + for i in 7..11 { + assert_noop!( + ParachainStaking::delegate(Origin::signed(i), 1, 10, count, 0u32), + Error::::TooLowCandidateDelegationCountToDelegate + ); + } + // to set up for next error test + count = 4u32; + for i in 7..11 { + assert_ok!(ParachainStaking::delegate( + Origin::signed(i), + 1, + 10, + count, + 0u32 + )); + count += 1u32; + } + count = 0u32; + for i in 3..11 { + assert_noop!( + ParachainStaking::delegate(Origin::signed(i), 2, 10, count, 0u32), + Error::::TooLowDelegationCountToDelegate + ); + count += 1u32; + } + }); +} + +// SCHEDULE LEAVE DELEGATORS + +#[test] +fn schedule_leave_delegators_event_emits_correctly() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegatorExitScheduled( + 1, 2, 3 + ))); + }); +} + +#[test] +fn cannot_schedule_leave_delegators_if_already_leaving() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(2)), + Error::::DelegatorAlreadyLeaving + ); + }); +} + +#[test] +fn cannot_schedule_leave_delegators_if_not_delegator() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(2)), + Error::::DelegatorDNE + ); + }); +} + +// EXECUTE LEAVE DELEGATORS + +#[test] +fn execute_leave_delegators_event_emits_correctly() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeft(2, 10)); + }); +} + +#[test] +fn execute_leave_delegators_unreserves_balance() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + }); +} + +#[test] +fn execute_leave_delegators_decreases_total_staked() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 30); + }); +} + +#[test] +fn execute_leave_delegators_removes_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2).is_some()); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::delegator_state(2).is_none()); + }); +} + +#[test] +fn execute_leave_delegators_removes_delegations_from_collator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 100), (2, 20), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(2, 20), (3, 20), (4, 20), (5, 20)]) + .with_delegations(vec![(1, 2, 10), (1, 3, 10), (1, 4, 10), (1, 5, 10)]) + .build() + .execute_with(|| { + for i in 2..6 { + let candidate_state = + ParachainStaking::candidate_info(i).expect("initialized in ext builder"); + assert_eq!(candidate_state.total_counted, 30); + let top_delegations = + ParachainStaking::top_delegations(i).expect("initialized in ext builder"); + assert_eq!(top_delegations.delegations[0].owner, 1); + assert_eq!(top_delegations.delegations[0].amount, 10); + assert_eq!(top_delegations.total, 10); + } + assert_eq!( + ParachainStaking::delegator_state(1) + .unwrap() + .delegations + .0 + .len(), + 4usize + ); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 1 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(1), + 1, + 10 + )); + for i in 2..6 { + let candidate_state = + ParachainStaking::candidate_info(i).expect("initialized in ext builder"); + assert_eq!(candidate_state.total_counted, 20); + let top_delegations = + ParachainStaking::top_delegations(i).expect("initialized in ext builder"); + assert!(top_delegations.delegations.is_empty()); + } + }); +} + +#[test] +fn cannot_execute_leave_delegators_before_delay() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_noop!( + ParachainStaking::execute_leave_delegators(Origin::signed(2), 2, 1), + Error::::DelegatorCannotLeaveYet + ); + // can execute after delay + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + }); +} + +#[test] +fn insufficient_execute_leave_delegators_weight_hint_fails() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + for i in 3..7 { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + i + ))); + } + roll_to(10); + for i in 3..7 { + assert_noop!( + ParachainStaking::execute_leave_delegators(Origin::signed(i), i, 0), + Error::::TooLowDelegationCountToLeaveDelegators + ); + } + }); +} + +#[test] +fn sufficient_execute_leave_delegators_weight_hint_succeeds() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + for i in 3..7 { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + i + ))); + } + roll_to(10); + for i in 3..7 { + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(i), + i, + 1 + )); + } + }); +} + +// CANCEL LEAVE DELEGATORS + +#[test] +fn cancel_leave_delegators_emits_correct_event() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::cancel_leave_delegators(Origin::signed(2))); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegatorExitCancelled( + 2 + ))); + }); +} + +#[test] +fn cancel_leave_delegators_updates_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::cancel_leave_delegators(Origin::signed(2))); + let delegator = + ParachainStaking::delegator_state(&2).expect("just cancelled exit so exists"); + assert!(delegator.is_active()); + }); +} + +// SCHEDULE REVOKE DELEGATION + +#[test] +fn revoke_delegation_event_emits_correctly() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::DelegationRevocationScheduled(1, 2, 1, 3,) + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + }); +} + +#[test] +fn can_revoke_delegation_if_revoking_another_delegation() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + // this is an exit implicitly because last delegation revoked + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 3 + )); + }); +} + +#[test] +fn can_revoke_if_leaving() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 3 + )); + }); +} + +#[test] +fn cannot_revoke_delegation_if_not_delegator() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_revoke_delegation(Origin::signed(2), 1), + Error::::DelegatorDNE + ); + }); +} + +#[test] +fn cannot_revoke_delegation_that_dne() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_revoke_delegation(Origin::signed(2), 3), + Error::::DelegationDNE + ); + }); +} + +#[test] +// See `cannot_execute_revoke_delegation_below_min_delegator_stake` for where the "must be above +// MinDelegatorStk" rule is now enforced. +fn can_schedule_revoke_delegation_below_min_delegator_stake() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 8), (3, 20)]) + .with_candidates(vec![(1, 20), (3, 20)]) + .with_delegations(vec![(2, 1, 5), (2, 3, 3)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + }); +} + +// DELEGATOR BOND MORE + +#[test] +fn delegator_bond_more_reserves_balance() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 5); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!(Balances::reserved_balance(&2), 15); + assert_eq!(Balances::free_balance(&2), 0); + }); +} + +#[test] +fn delegator_bond_more_increases_total_staked() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!(ParachainStaking::total(), 45); + }); +} + +#[test] +fn delegator_bond_more_updates_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 10 + ); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 15 + ); + }); +} + +#[test] +fn delegator_bond_more_updates_candidate_state_top_delegations() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 10 + ); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 15 + ); + }); +} + +#[test] +fn delegator_bond_more_updates_candidate_state_bottom_delegations() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![ + (2, 1, 10), + (3, 1, 20), + (4, 1, 20), + (5, 1, 20), + (6, 1, 20), + ]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .owner, + 2 + ); + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .amount, + 10 + ); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegationIncreased( + 2, 1, 5, false + ))); + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .owner, + 2 + ); + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .amount, + 15 + ); + }); +} + +#[test] +fn delegator_bond_more_increases_total() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!(ParachainStaking::total(), 45); + }); +} + +#[test] +fn can_delegator_bond_more_for_leaving_candidate() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + }); +} + +// DELEGATOR BOND LESS + +#[test] +fn delegator_bond_less_event_emits_correctly() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::DelegationDecreaseScheduled(2, 1, 5, 3,) + )); + }); +} + +#[test] +fn delegator_bond_less_updates_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + let state = + ParachainStaking::delegator_state(&2).expect("just request bonded less so exists"); + assert_eq!( + state.requests().get(&1), + Some(&DelegationRequest { + collator: 1, + amount: 5, + when_executable: 3, + action: DelegationChange::Decrease + }) + ); + }); +} + +#[test] +fn can_delegator_bond_less_if_leaving() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 1 + )); + }); +} + +#[test] +fn cannot_delegator_bond_less_if_revoking() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 25), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 1), + Error::::PendingDelegationRequestAlreadyExists + ); + }); +} + +#[test] +fn cannot_delegator_bond_less_if_not_delegator() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 5), + Error::::DelegatorDNE + ); + }); +} + +#[test] +fn cannot_delegator_bond_less_if_candidate_dne() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 3, 5), + Error::::DelegationDNE + ); + }); +} + +#[test] +fn cannot_delegator_bond_less_if_delegation_dne() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 3, 5), + Error::::DelegationDNE + ); + }); +} + +#[test] +fn cannot_delegator_bond_less_below_min_collator_stk() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 6), + Error::::DelegatorBondBelowMin + ); + }); +} + +#[test] +fn cannot_delegator_bond_less_more_than_total_delegation() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 11), + Error::::DelegatorBondBelowMin + ); + }); +} + +#[test] +fn cannot_delegator_bond_less_below_min_delegation() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 8), + Error::::DelegationBelowMin + ); + }); +} + +// EXECUTE PENDING DELEGATION REQUEST + +// 1. REVOKE DELEGATION + +#[test] +fn execute_revoke_delegation_emits_exit_event_if_exit_happens() { + // last delegation is revocation + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + assert_event_emitted!(Event::DelegatorLeft(2, 10)); + }); +} + +#[test] +fn cannot_execute_revoke_delegation_below_min_delegator_stake() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 8), (3, 20)]) + .with_candidates(vec![(1, 20), (3, 20)]) + .with_delegations(vec![(2, 1, 5), (2, 3, 3)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_noop!( + ParachainStaking::execute_delegation_request(Origin::signed(2), 2, 1), + Error::::DelegatorBondBelowMin + ); + // but delegator can cancel the request and request to leave instead: + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(20); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 2 + )); + }); +} + +#[test] +fn revoke_delegation_executes_exit_if_last_delegation() { + // last delegation is revocation + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + assert_event_emitted!(Event::DelegatorLeft(2, 10)); + }); +} + +#[test] +fn execute_revoke_delegation_emits_correct_event() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + }); +} + +#[test] +fn execute_revoke_delegation_unreserves_balance() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + }); +} + +#[test] +fn execute_revoke_delegation_adds_revocation_to_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .requests + .get(&1) + .is_none()); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert!(ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .requests + .get(&1) + .is_some()); + }); +} + +#[test] +fn execute_revoke_delegation_removes_revocation_from_delegator_state_upon_execution() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .requests + .get(&1) + .is_none()); + }); +} + +#[test] +fn execute_revoke_delegation_decreases_total_staked() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 30); + }); +} + +#[test] +fn execute_revoke_delegation_for_last_delegation_removes_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2).is_some()); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + // this will be confusing for people + // if status is leaving, then execute_delegation_request works if last delegation + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::delegator_state(2).is_none()); + }); +} + +#[test] +fn execute_revoke_delegation_removes_delegation_from_candidate_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::candidate_info(1) + .expect("exists") + .delegation_count, + 1u32 + ); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::candidate_info(1) + .expect("exists") + .delegation_count + .is_zero()); + }); +} + +#[test] +fn can_execute_revoke_delegation_for_leaving_candidate() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + // can execute delegation request for leaving candidate + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + }); +} + +#[test] +fn can_execute_leave_candidates_if_revoking_candidate() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + // revocation executes during execute leave candidates (callable by anyone) + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 1 + )); + assert!(!ParachainStaking::is_delegator(&2)); + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + }); +} + +#[test] +fn delegator_bond_more_after_revoke_delegation_does_not_effect_exit() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 30), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 3, + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::is_delegator(&2)); + assert_eq!(Balances::reserved_balance(&2), 20); + assert_eq!(Balances::free_balance(&2), 10); + }); +} + +#[test] +fn delegator_bond_less_after_revoke_delegation_does_not_effect_exit() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 30), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::DelegationRevocationScheduled(1, 2, 1, 3,) + )); + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 2), + Error::::PendingDelegationRequestAlreadyExists + ); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 3, + 2 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 3 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegationDecreased( + 2, 3, 2, true + ))); + assert!(ParachainStaking::is_delegator(&2)); + assert_eq!(Balances::reserved_balance(&2), 8); + assert_eq!(Balances::free_balance(&2), 22); + }); +} + +// 2. EXECUTE BOND LESS + +#[test] +fn execute_delegator_bond_less_unreserves_balance() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(Balances::reserved_balance(&2), 5); + assert_eq!(Balances::free_balance(&2), 5); + }); +} + +#[test] +fn execute_delegator_bond_less_decreases_total_staked() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 35); + }); +} + +#[test] +fn execute_delegator_bond_less_updates_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 10 + ); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 5 + ); + }); +} + +#[test] +fn execute_delegator_bond_less_updates_candidate_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 10 + ); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 5 + ); + }); +} + +#[test] +fn execute_delegator_bond_less_decreases_total() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 35); + }); +} + +#[test] +fn execute_delegator_bond_less_updates_just_bottom_delegations() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (2, 1, 10), + (3, 1, 11), + (4, 1, 12), + (5, 1, 14), + (6, 1, 15), + ]) + .build() + .execute_with(|| { + let pre_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let pre_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let pre_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 2 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + let post_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let post_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let post_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + let mut not_equal = false; + for Bond { owner, amount } in pre_call_bottom_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_bottom_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + not_equal = true; + break; + } + } + } + } + assert!(not_equal); + let mut equal = true; + for Bond { owner, amount } in pre_call_top_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_top_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + equal = false; + break; + } + } + } + } + assert!(equal); + assert_eq!( + pre_call_candidate_info.total_counted, + post_call_candidate_info.total_counted + ); + }); +} + +#[test] +fn execute_delegator_bond_less_does_not_delete_bottom_delegations() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (2, 1, 10), + (3, 1, 11), + (4, 1, 12), + (5, 1, 14), + (6, 1, 15), + ]) + .build() + .execute_with(|| { + let pre_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let pre_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let pre_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(6), + 1, + 4 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(6), + 6, + 1 + )); + let post_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let post_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let post_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + let mut equal = true; + for Bond { owner, amount } in pre_call_bottom_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_bottom_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + equal = false; + break; + } + } + } + } + assert!(equal); + let mut not_equal = false; + for Bond { owner, amount } in pre_call_top_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_top_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + not_equal = true; + break; + } + } + } + } + assert!(not_equal); + assert_eq!( + pre_call_candidate_info.total_counted - 4, + post_call_candidate_info.total_counted + ); + }); +} + +#[test] +fn can_execute_delegator_bond_less_for_leaving_candidate() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 15)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + // can execute bond more delegation request for leaving candidate + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + }); +} + +// CANCEL PENDING DELEGATION REQUEST +// 1. CANCEL REVOKE DELEGATION + +#[test] +fn cancel_revoke_delegation_emits_correct_event() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CancelledDelegationRequest( + 2, + DelegationRequest { + collator: 1, + amount: 10, + when_executable: 3, + action: DelegationChange::Revoke, + }, + ) + )); + }); +} + +#[test] +fn cancel_revoke_delegation_updates_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert_eq!( + state.requests().get(&1), + Some(&DelegationRequest { + collator: 1, + amount: 10, + when_executable: 3, + action: DelegationChange::Revoke, + }) + ); + assert_eq!(state.requests.less_total, 10); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert!(state.requests().get(&1).is_none()); + assert_eq!(state.requests.less_total, 0); + }); +} + +// 2. CANCEL DELEGATOR BOND LESS + +#[test] +fn cancel_delegator_bond_less_correct_event() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 15)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CancelledDelegationRequest( + 2, + DelegationRequest { + collator: 1, + amount: 5, + when_executable: 3, + action: DelegationChange::Decrease, + }, + ) + )); + }); +} + +#[test] +fn cancel_delegator_bond_less_updates_delegator_state() { + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 15)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert_eq!( + state.requests().get(&1), + Some(&DelegationRequest { + collator: 1, + amount: 5, + when_executable: 3, + action: DelegationChange::Decrease, + }) + ); + assert_eq!(state.requests.less_total, 5); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert!(state.requests().get(&1).is_none()); + assert_eq!(state.requests.less_total, 0); + }); } // ~~ PROPERTY-BASED TESTS ~~ #[test] -fn nominator_schedule_revocation_total() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 40), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20)]) - .with_nominations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10)]) - .build() - .execute_with(|| { - roll_to(1); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 1)); - assert_eq!( - Stake::nominator_state2(2) - .expect("exists") - .scheduled_revocations_total, - 10 - ); - roll_to(10); - assert_eq!( - Stake::nominator_state2(2) - .expect("exists") - .scheduled_revocations_total, - 0 - ); - assert_ok!(Stake::nominate(Origin::signed(2), 5, 10, 0, 2)); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 3)); - assert_ok!(Stake::revoke_nomination(Origin::signed(2), 4)); - assert_eq!( - Stake::nominator_state2(2) - .expect("exists") - .scheduled_revocations_total, - 20 - ); - roll_to(20); - assert_eq!( - Stake::nominator_state2(2) - .expect("exists") - .scheduled_revocations_total, - 0 - ); - }); +fn delegator_schedule_revocation_total() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 40), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 10 + ); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 0 + ); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 5, 10, 0, 2)); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 3 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 4 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 20 + ); + roll_to(20); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 3 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 10 + ); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 4 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 0 + ); + }); } #[test] fn parachain_bond_inflation_reserve_matches_config() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - (11, 1), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_nominations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - assert_eq!(Balances::free_balance(&11), 1); - // set parachain bond account so DefaultParachainBondReservePercent = 30% of inflation - // is allocated to this account hereafter - assert_ok!(Stake::set_parachain_bond_account(Origin::root(), 11)); - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::ParachainBondAccountSet(0, 11), - Event::CollatorChosen(2, 1, 50), - Event::CollatorChosen(2, 2, 40), - Event::CollatorChosen(2, 3, 20), - Event::CollatorChosen(2, 4, 20), - Event::CollatorChosen(2, 5, 10), - Event::NewRound(5, 2, 5, 140), - ]; - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 1); - // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); - roll_to(16); - // distribute total issuance to collator 1 and its nominators 6, 7, 19 - let mut new = vec![ - Event::CollatorChosen(3, 1, 50), - Event::CollatorChosen(3, 2, 40), - Event::CollatorChosen(3, 3, 20), - Event::CollatorChosen(3, 4, 20), - Event::CollatorChosen(3, 5, 10), - Event::NewRound(10, 3, 5, 140), - Event::ReservedForParachainBond(11, 15), - Event::Rewarded(1, 20), - Event::Rewarded(6, 5), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - Event::CollatorChosen(4, 1, 50), - Event::CollatorChosen(4, 2, 40), - Event::CollatorChosen(4, 3, 20), - Event::CollatorChosen(4, 4, 20), - Event::CollatorChosen(4, 5, 10), - Event::NewRound(15, 4, 5, 140), - ]; - expected.append(&mut new); - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 16); - // ~ set block author as 1 for all blocks this round - set_author(3, 1, 100); - set_author(4, 1, 100); - set_author(5, 1, 100); - // 1. ensure nominators are paid for 2 rounds after they leave - assert_noop!( - Stake::leave_nominators(Origin::signed(66), 10), - Error::::NominatorDNE - ); - assert_ok!(Stake::leave_nominators(Origin::signed(6), 10)); - // fast forward to block in which nominator 6 exit executes - roll_to(25); - let mut new2 = vec![ - Event::NominatorExitScheduled(4, 6, 6), - Event::ReservedForParachainBond(11, 16), - Event::Rewarded(1, 21), - Event::Rewarded(6, 5), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - Event::CollatorChosen(5, 1, 50), - Event::CollatorChosen(5, 2, 40), - Event::CollatorChosen(5, 3, 20), - Event::CollatorChosen(5, 4, 20), - Event::CollatorChosen(5, 5, 10), - Event::NewRound(20, 5, 5, 140), - Event::ReservedForParachainBond(11, 16), - Event::Rewarded(1, 22), - Event::Rewarded(6, 6), - Event::Rewarded(7, 6), - Event::Rewarded(10, 6), - Event::NominatorLeftCollator(6, 1, 10, 40), - Event::NominatorLeft(6, 10), - Event::CollatorChosen(6, 1, 40), - Event::CollatorChosen(6, 2, 40), - Event::CollatorChosen(6, 3, 20), - Event::CollatorChosen(6, 4, 20), - Event::CollatorChosen(6, 5, 10), - Event::NewRound(25, 6, 5, 130), - ]; - expected.append(&mut new2); - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 48); - assert_ok!(Stake::set_parachain_bond_reserve_percent( - Origin::root(), - Percent::from_percent(50) - )); - // 6 won't be paid for this round because they left already - set_author(6, 1, 100); - roll_to(30); - // keep paying 6 - let mut new3 = vec![ - Event::ParachainBondReservePercentSet( - Percent::from_percent(30), - Percent::from_percent(50), - ), - Event::ReservedForParachainBond(11, 29), - Event::Rewarded(1, 19), - Event::Rewarded(6, 3), - Event::Rewarded(7, 3), - Event::Rewarded(10, 3), - Event::CollatorChosen(7, 1, 40), - Event::CollatorChosen(7, 2, 40), - Event::CollatorChosen(7, 3, 20), - Event::CollatorChosen(7, 4, 20), - Event::CollatorChosen(7, 5, 10), - Event::NewRound(30, 7, 5, 130), - ]; - expected.append(&mut new3); - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 77); - set_author(7, 1, 100); - roll_to(35); - // no more paying 6 - let mut new4 = vec![ - Event::ReservedForParachainBond(11, 30), - Event::Rewarded(1, 21), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - Event::CollatorChosen(8, 1, 40), - Event::CollatorChosen(8, 2, 40), - Event::CollatorChosen(8, 3, 20), - Event::CollatorChosen(8, 4, 20), - Event::CollatorChosen(8, 5, 10), - Event::NewRound(35, 8, 5, 130), - ]; - expected.append(&mut new4); - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 107); - set_author(8, 1, 100); - assert_ok!(Stake::nominate(Origin::signed(8), 1, 10, 10, 10)); - roll_to(40); - // new nomination is not rewarded yet - let mut new5 = vec![ - Event::Nomination(8, 10, 1, NominatorAdded::AddedToTop { new_total: 50 }), - Event::ReservedForParachainBond(11, 32), - Event::Rewarded(1, 22), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - Event::CollatorChosen(9, 1, 50), - Event::CollatorChosen(9, 2, 40), - Event::CollatorChosen(9, 3, 20), - Event::CollatorChosen(9, 4, 20), - Event::CollatorChosen(9, 5, 10), - Event::NewRound(40, 9, 5, 140), - ]; - expected.append(&mut new5); - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 139); - set_author(9, 1, 100); - roll_to(45); - // new nomination is still not rewarded yet - let mut new6 = vec![ - Event::ReservedForParachainBond(11, 33), - Event::Rewarded(1, 23), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - Event::CollatorChosen(10, 1, 50), - Event::CollatorChosen(10, 2, 40), - Event::CollatorChosen(10, 3, 20), - Event::CollatorChosen(10, 4, 20), - Event::CollatorChosen(10, 5, 10), - Event::NewRound(45, 10, 5, 140), - ]; - expected.append(&mut new6); - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 172); - roll_to(50); - // new nomination is rewarded, 2 rounds after joining (`RewardPaymentDelay` is 2) - let mut new7 = vec![ - Event::ReservedForParachainBond(11, 35), - Event::Rewarded(1, 22), - Event::Rewarded(7, 4), - Event::Rewarded(8, 4), - Event::Rewarded(10, 4), - Event::CollatorChosen(11, 1, 50), - Event::CollatorChosen(11, 2, 40), - Event::CollatorChosen(11, 3, 20), - Event::CollatorChosen(11, 4, 20), - Event::CollatorChosen(11, 5, 10), - Event::NewRound(50, 11, 5, 140), - ]; - expected.append(&mut new7); - assert_eq!(events(), expected); - assert_eq!(Balances::free_balance(&11), 207); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + (11, 1), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + assert_eq!(Balances::free_balance(&11), 1); + // set parachain bond account so DefaultParachainBondReservePercent = 30% of inflation + // is allocated to this account hereafter + assert_ok!(ParachainStaking::set_parachain_bond_account( + Origin::root(), + 11 + )); + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::ParachainBondAccountSet(0, 11), + Event::CollatorChosen(2, 1, 50), + Event::CollatorChosen(2, 2, 40), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::CollatorChosen(2, 5, 10), + Event::NewRound(5, 2, 5, 140), + ]; + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 1); + // ~ set block author as 1 for all blocks this round + set_author(2, 1, 100); + roll_to(16); + // distribute total issuance to collator 1 and its delegators 6, 7, 19 + let mut new = vec![ + Event::CollatorChosen(3, 1, 50), + Event::CollatorChosen(3, 2, 40), + Event::CollatorChosen(3, 3, 20), + Event::CollatorChosen(3, 4, 20), + Event::CollatorChosen(3, 5, 10), + Event::NewRound(10, 3, 5, 140), + Event::ReservedForParachainBond(11, 15), + Event::CollatorChosen(4, 1, 50), + Event::CollatorChosen(4, 2, 40), + Event::CollatorChosen(4, 3, 20), + Event::CollatorChosen(4, 4, 20), + Event::CollatorChosen(4, 5, 10), + Event::NewRound(15, 4, 5, 140), + Event::Rewarded(1, 20), + Event::Rewarded(6, 5), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 16); + // ~ set block author as 1 for all blocks this round + set_author(3, 1, 100); + set_author(4, 1, 100); + set_author(5, 1, 100); + // 1. ensure delegators are paid for 2 rounds after they leave + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(66)), + Error::::DelegatorDNE + ); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 6 + ))); + // fast forward to block in which delegator 6 exit executes + roll_to(25); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(6), + 6, + 10 + )); + roll_to(30); + let mut new2 = vec![ + Event::DelegatorExitScheduled(4, 6, 6), + Event::ReservedForParachainBond(11, 16), + Event::CollatorChosen(5, 1, 50), + Event::CollatorChosen(5, 2, 40), + Event::CollatorChosen(5, 3, 20), + Event::CollatorChosen(5, 4, 20), + Event::CollatorChosen(5, 5, 10), + Event::NewRound(20, 5, 5, 140), + Event::Rewarded(1, 21), + Event::Rewarded(6, 5), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + Event::ReservedForParachainBond(11, 16), + Event::CollatorChosen(6, 1, 50), + Event::CollatorChosen(6, 2, 40), + Event::CollatorChosen(6, 3, 20), + Event::CollatorChosen(6, 4, 20), + Event::CollatorChosen(6, 5, 10), + Event::NewRound(25, 6, 5, 140), + Event::Rewarded(1, 22), + Event::Rewarded(6, 6), + Event::Rewarded(7, 6), + Event::Rewarded(10, 6), + Event::DelegatorLeftCandidate(6, 1, 10, 40), + Event::DelegatorLeft(6, 10), + Event::ReservedForParachainBond(11, 17), + Event::CollatorChosen(7, 1, 40), + Event::CollatorChosen(7, 2, 40), + Event::CollatorChosen(7, 3, 20), + Event::CollatorChosen(7, 4, 20), + Event::CollatorChosen(7, 5, 10), + Event::NewRound(30, 7, 5, 130), + Event::Rewarded(1, 24), + Event::Rewarded(6, 6), + Event::Rewarded(7, 6), + Event::Rewarded(10, 6), + ]; + expected.append(&mut new2); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 65); + assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(50) + )); + // 6 won't be paid for this round because they left already + set_author(6, 1, 100); + roll_to(35); + // keep paying 6 + let mut new3 = vec![ + Event::ParachainBondReservePercentSet( + Percent::from_percent(30), + Percent::from_percent(50), + ), + Event::ReservedForParachainBond(11, 30), + Event::CollatorChosen(8, 1, 40), + Event::CollatorChosen(8, 2, 40), + Event::CollatorChosen(8, 3, 20), + Event::CollatorChosen(8, 4, 20), + Event::CollatorChosen(8, 5, 10), + Event::NewRound(35, 8, 5, 130), + Event::Rewarded(1, 20), + Event::Rewarded(6, 4), + Event::Rewarded(7, 4), + Event::Rewarded(10, 4), + ]; + expected.append(&mut new3); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 95); + set_author(7, 1, 100); + roll_to(40); + // no more paying 6 + let mut new4 = vec![ + Event::ReservedForParachainBond(11, 32), + Event::CollatorChosen(9, 1, 40), + Event::CollatorChosen(9, 2, 40), + Event::CollatorChosen(9, 3, 20), + Event::CollatorChosen(9, 4, 20), + Event::CollatorChosen(9, 5, 10), + Event::NewRound(40, 9, 5, 130), + Event::Rewarded(1, 22), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new4); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 127); + set_author(8, 1, 100); + assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); + roll_to(45); + // new delegation is not rewarded yet + let mut new5 = vec![ + Event::Delegation(8, 10, 1, DelegatorAdded::AddedToTop { new_total: 50 }), + Event::ReservedForParachainBond(11, 33), + Event::CollatorChosen(10, 1, 50), + Event::CollatorChosen(10, 2, 40), + Event::CollatorChosen(10, 3, 20), + Event::CollatorChosen(10, 4, 20), + Event::CollatorChosen(10, 5, 10), + Event::NewRound(45, 10, 5, 140), + Event::Rewarded(1, 23), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new5); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 160); + set_author(9, 1, 100); + set_author(10, 1, 100); + roll_to(50); + // new delegation is still not rewarded yet + let mut new6 = vec![ + Event::ReservedForParachainBond(11, 35), + Event::CollatorChosen(11, 1, 50), + Event::CollatorChosen(11, 2, 40), + Event::CollatorChosen(11, 3, 20), + Event::CollatorChosen(11, 4, 20), + Event::CollatorChosen(11, 5, 10), + Event::NewRound(50, 11, 5, 140), + Event::Rewarded(1, 24), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new6); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 195); + roll_to(55); + // new delegation is rewarded, 2 rounds after joining (`RewardPaymentDelay` is 2) + let mut new7 = vec![ + Event::ReservedForParachainBond(11, 37), + Event::CollatorChosen(12, 1, 50), + Event::CollatorChosen(12, 2, 40), + Event::CollatorChosen(12, 3, 20), + Event::CollatorChosen(12, 4, 20), + Event::CollatorChosen(12, 5, 10), + Event::NewRound(55, 12, 5, 140), + Event::Rewarded(1, 24), + Event::Rewarded(7, 4), + Event::Rewarded(10, 4), + Event::Rewarded(8, 4), + ]; + expected.append(&mut new7); + assert_eq_events!(expected); + assert_eq!(Balances::free_balance(&11), 232); + }); } #[test] fn paid_collator_commission_matches_config() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - ]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![(2, 1, 10), (3, 1, 10)]) - .build() - .execute_with(|| { - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 40), - Event::NewRound(5, 2, 1, 40), - ]; - assert_eq!(events(), expected); - assert_ok!(Stake::join_candidates(Origin::signed(4), 20u128, 100u32)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::JoinedCollatorCandidates(4, 20u128, 60u128)) - ); - roll_to(9); - assert_ok!(Stake::nominate(Origin::signed(5), 4, 10, 10, 10)); - assert_ok!(Stake::nominate(Origin::signed(6), 4, 10, 10, 10)); - roll_to(11); - let mut new = vec![ - Event::JoinedCollatorCandidates(4, 20, 60), - Event::Nomination(5, 10, 4, NominatorAdded::AddedToTop { new_total: 30 }), - Event::Nomination(6, 10, 4, NominatorAdded::AddedToTop { new_total: 40 }), - Event::CollatorChosen(3, 1, 40), - Event::CollatorChosen(3, 4, 40), - Event::NewRound(10, 3, 2, 80), - ]; - expected.append(&mut new); - assert_eq!(events(), expected); - // only reward author with id 4 - set_author(3, 4, 100); - roll_to(21); - // 20% of 10 is commission + due_portion (4) = 2 + 4 = 6 - // all nominator payouts are 10-2 = 8 * stake_pct - let mut new2 = vec![ - Event::CollatorChosen(4, 1, 40), - Event::CollatorChosen(4, 4, 40), - Event::NewRound(15, 4, 2, 80), - Event::Rewarded(4, 18), - Event::Rewarded(5, 6), - Event::Rewarded(6, 6), - Event::CollatorChosen(5, 1, 40), - Event::CollatorChosen(5, 4, 40), - Event::NewRound(20, 5, 2, 80), - ]; - expected.append(&mut new2); - assert_eq!(events(), expected); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + ]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(2, 1, 10), (3, 1, 10)]) + .build() + .execute_with(|| { + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 40), + Event::NewRound(5, 2, 1, 40), + ]; + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(4), + 20u128, + 100u32 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::JoinedCollatorCandidates(4, 20u128, 60u128,) + )); + roll_to(9); + assert_ok!(ParachainStaking::delegate(Origin::signed(5), 4, 10, 10, 10)); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 4, 10, 10, 10)); + roll_to(11); + let mut new = vec![ + Event::JoinedCollatorCandidates(4, 20, 60), + Event::Delegation(5, 10, 4, DelegatorAdded::AddedToTop { new_total: 30 }), + Event::Delegation(6, 10, 4, DelegatorAdded::AddedToTop { new_total: 40 }), + Event::CollatorChosen(3, 1, 40), + Event::CollatorChosen(3, 4, 40), + Event::NewRound(10, 3, 2, 80), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + // only reward author with id 4 + set_author(3, 4, 100); + roll_to(21); + // 20% of 10 is commission + due_portion (0) = 2 + 4 = 6 + // all delegator payouts are 10-2 = 8 * stake_pct + let mut new2 = vec![ + Event::CollatorChosen(4, 1, 40), + Event::CollatorChosen(4, 4, 40), + Event::NewRound(15, 4, 2, 80), + Event::CollatorChosen(5, 1, 40), + Event::CollatorChosen(5, 4, 40), + Event::NewRound(20, 5, 2, 80), + Event::Rewarded(4, 18), + Event::Rewarded(5, 6), + Event::Rewarded(6, 6), + ]; + expected.append(&mut new2); + assert_eq_events!(expected); + }); } #[test] fn collator_exit_executes_after_delay() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 300), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 9), - (9, 4), - ]) - .with_candidates(vec![(1, 500), (2, 200)]) - .with_nominations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) - .build() - .execute_with(|| { - roll_to(11); - assert_ok!(Stake::leave_candidates(Origin::signed(2), 2)); - let info = Stake::collator_state2(&2).unwrap(); - assert_eq!(info.state, CollatorStatus::Leaving(5)); - roll_to(21); - // we must exclude leaving collators from rewards while - // holding them retroactively accountable for previous faults - // (within the last T::SlashingWindow blocks) - let expected = vec![ - Event::CollatorChosen(2, 1, 700), - Event::CollatorChosen(2, 2, 400), - Event::NewRound(5, 2, 2, 1100), - Event::CollatorChosen(3, 1, 700), - Event::CollatorChosen(3, 2, 400), - Event::NewRound(10, 3, 2, 1100), - Event::CollatorScheduledExit(3, 2, 5), - Event::CollatorChosen(4, 1, 700), - Event::NewRound(15, 4, 1, 700), - Event::CollatorLeft(2, 400, 700), - Event::CollatorChosen(5, 1, 700), - Event::NewRound(20, 5, 1, 700), - ]; - assert_eq!(events(), expected); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 300), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 9), + (9, 4), + ]) + .with_candidates(vec![(1, 500), (2, 200)]) + .with_delegations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) + .build() + .execute_with(|| { + roll_to(11); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(2), + 2 + )); + let info = ParachainStaking::candidate_info(&2).unwrap(); + assert_eq!(info.status, CollatorStatus::Leaving(5)); + roll_to(21); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 2, + 2 + )); + // we must exclude leaving collators from rewards while + // holding them retroactively accountable for previous faults + // (within the last T::SlashingWindow blocks) + let expected = vec![ + Event::CollatorChosen(2, 1, 700), + Event::CollatorChosen(2, 2, 400), + Event::NewRound(5, 2, 2, 1100), + Event::CollatorChosen(3, 1, 700), + Event::CollatorChosen(3, 2, 400), + Event::NewRound(10, 3, 2, 1100), + Event::CandidateScheduledExit(3, 2, 5), + Event::CollatorChosen(4, 1, 700), + Event::NewRound(15, 4, 1, 700), + Event::CollatorChosen(5, 1, 700), + Event::NewRound(20, 5, 1, 700), + Event::CandidateLeft(2, 400, 700), + ]; + assert_eq_events!(expected); + }); } #[test] fn collator_selection_chooses_top_candidates() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 1000), - (3, 1000), - (4, 1000), - (5, 1000), - (6, 1000), - (7, 33), - (8, 33), - (9, 33), - ]) - .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) - .build() - .execute_with(|| { - roll_to(8); - // should choose top TotalSelectedCandidates (5), in order - let expected = vec![ - Event::CollatorChosen(2, 1, 100), - Event::CollatorChosen(2, 2, 90), - Event::CollatorChosen(2, 3, 80), - Event::CollatorChosen(2, 4, 70), - Event::CollatorChosen(2, 5, 60), - Event::NewRound(5, 2, 5, 400), - ]; - assert_eq!(events(), expected); - assert_ok!(Stake::leave_candidates(Origin::signed(6), 6)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorScheduledExit(2, 6, 4)) - ); - roll_to(21); - assert_ok!(Stake::join_candidates(Origin::signed(6), 69u128, 100u32)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::JoinedCollatorCandidates(6, 69u128, 469u128)) - ); - roll_to(27); - // should choose top TotalSelectedCandidates (5), in order - let expected = vec![ - Event::CollatorChosen(2, 1, 100), - Event::CollatorChosen(2, 2, 90), - Event::CollatorChosen(2, 3, 80), - Event::CollatorChosen(2, 4, 70), - Event::CollatorChosen(2, 5, 60), - Event::NewRound(5, 2, 5, 400), - Event::CollatorScheduledExit(2, 6, 4), - Event::CollatorChosen(3, 1, 100), - Event::CollatorChosen(3, 2, 90), - Event::CollatorChosen(3, 3, 80), - Event::CollatorChosen(3, 4, 70), - Event::CollatorChosen(3, 5, 60), - Event::NewRound(10, 3, 5, 400), - Event::CollatorLeft(6, 50, 400), - Event::CollatorChosen(4, 1, 100), - Event::CollatorChosen(4, 2, 90), - Event::CollatorChosen(4, 3, 80), - Event::CollatorChosen(4, 4, 70), - Event::CollatorChosen(4, 5, 60), - Event::NewRound(15, 4, 5, 400), - Event::CollatorChosen(5, 1, 100), - Event::CollatorChosen(5, 2, 90), - Event::CollatorChosen(5, 3, 80), - Event::CollatorChosen(5, 4, 70), - Event::CollatorChosen(5, 5, 60), - Event::NewRound(20, 5, 5, 400), - Event::JoinedCollatorCandidates(6, 69, 469), - Event::CollatorChosen(6, 1, 100), - Event::CollatorChosen(6, 2, 90), - Event::CollatorChosen(6, 3, 80), - Event::CollatorChosen(6, 4, 70), - Event::CollatorChosen(6, 6, 69), - Event::NewRound(25, 6, 5, 409), - ]; - assert_eq!(events(), expected); - }); -} - -#[test] -fn exit_queue_executes_in_order() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 1000), - (3, 1000), - (4, 1000), - (5, 1000), - (6, 1000), - (7, 33), - (8, 33), - (9, 33), - ]) - .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) - .build() - .execute_with(|| { - roll_to(8); - // should choose top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 100), - Event::CollatorChosen(2, 2, 90), - Event::CollatorChosen(2, 3, 80), - Event::CollatorChosen(2, 4, 70), - Event::CollatorChosen(2, 5, 60), - Event::NewRound(5, 2, 5, 400), - ]; - assert_eq!(events(), expected); - assert_ok!(Stake::leave_candidates(Origin::signed(6), 6)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorScheduledExit(2, 6, 4)) - ); - roll_to(11); - assert_ok!(Stake::leave_candidates(Origin::signed(5), 5)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorScheduledExit(3, 5, 5)) - ); - roll_to(16); - assert_ok!(Stake::leave_candidates(Origin::signed(4), 4)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorScheduledExit(4, 4, 6)) - ); - roll_to(21); - let mut new_events = vec![ - Event::CollatorScheduledExit(2, 6, 4), - Event::CollatorChosen(3, 1, 100), - Event::CollatorChosen(3, 2, 90), - Event::CollatorChosen(3, 3, 80), - Event::CollatorChosen(3, 4, 70), - Event::CollatorChosen(3, 5, 60), - Event::NewRound(10, 3, 5, 400), - Event::CollatorScheduledExit(3, 5, 5), - Event::CollatorLeft(6, 50, 400), - Event::CollatorChosen(4, 1, 100), - Event::CollatorChosen(4, 2, 90), - Event::CollatorChosen(4, 3, 80), - Event::CollatorChosen(4, 4, 70), - Event::NewRound(15, 4, 4, 340), - Event::CollatorScheduledExit(4, 4, 6), - Event::CollatorLeft(5, 60, 340), - Event::CollatorChosen(5, 1, 100), - Event::CollatorChosen(5, 2, 90), - Event::CollatorChosen(5, 3, 80), - Event::NewRound(20, 5, 3, 270), - ]; - expected.append(&mut new_events); - assert_eq!(events(), expected); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), + (6, 1000), + (7, 33), + (8, 33), + (9, 33), + ]) + .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) + .build() + .execute_with(|| { + roll_to(8); + // should choose top TotalSelectedCandidates (5), in order + let expected = vec![ + Event::CollatorChosen(2, 1, 100), + Event::CollatorChosen(2, 2, 90), + Event::CollatorChosen(2, 3, 80), + Event::CollatorChosen(2, 4, 70), + Event::CollatorChosen(2, 5, 60), + Event::NewRound(5, 2, 5, 400), + ]; + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(6), + 6 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( + 2, 6, 4 + ))); + roll_to(21); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(6), + 6, + 0 + )); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(6), + 69u128, + 100u32 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::JoinedCollatorCandidates(6, 69u128, 469u128,) + )); + roll_to(27); + // should choose top TotalSelectedCandidates (5), in order + let expected = vec![ + Event::CollatorChosen(2, 1, 100), + Event::CollatorChosen(2, 2, 90), + Event::CollatorChosen(2, 3, 80), + Event::CollatorChosen(2, 4, 70), + Event::CollatorChosen(2, 5, 60), + Event::NewRound(5, 2, 5, 400), + Event::CandidateScheduledExit(2, 6, 4), + Event::CollatorChosen(3, 1, 100), + Event::CollatorChosen(3, 2, 90), + Event::CollatorChosen(3, 3, 80), + Event::CollatorChosen(3, 4, 70), + Event::CollatorChosen(3, 5, 60), + Event::NewRound(10, 3, 5, 400), + Event::CollatorChosen(4, 1, 100), + Event::CollatorChosen(4, 2, 90), + Event::CollatorChosen(4, 3, 80), + Event::CollatorChosen(4, 4, 70), + Event::CollatorChosen(4, 5, 60), + Event::NewRound(15, 4, 5, 400), + Event::CollatorChosen(5, 1, 100), + Event::CollatorChosen(5, 2, 90), + Event::CollatorChosen(5, 3, 80), + Event::CollatorChosen(5, 4, 70), + Event::CollatorChosen(5, 5, 60), + Event::NewRound(20, 5, 5, 400), + Event::CandidateLeft(6, 50, 400), + Event::JoinedCollatorCandidates(6, 69, 469), + Event::CollatorChosen(6, 1, 100), + Event::CollatorChosen(6, 2, 90), + Event::CollatorChosen(6, 3, 80), + Event::CollatorChosen(6, 4, 70), + Event::CollatorChosen(6, 6, 69), + Event::NewRound(25, 6, 5, 409), + ]; + assert_eq_events!(expected); + }); } #[test] fn payout_distribution_to_solo_collators() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 1000), - (3, 1000), - (4, 1000), - (5, 1000), - (6, 1000), - (7, 33), - (8, 33), - (9, 33), - ]) - .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) - .build() - .execute_with(|| { - roll_to(8); - // should choose top TotalCandidatesSelected (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 100), - Event::CollatorChosen(2, 2, 90), - Event::CollatorChosen(2, 3, 80), - Event::CollatorChosen(2, 4, 70), - Event::CollatorChosen(2, 5, 60), - Event::NewRound(5, 2, 5, 400), - ]; - assert_eq!(events(), expected); - // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); - roll_to(16); - // pay total issuance to 1 - let mut new = vec![ - Event::CollatorChosen(3, 1, 100), - Event::CollatorChosen(3, 2, 90), - Event::CollatorChosen(3, 3, 80), - Event::CollatorChosen(3, 4, 70), - Event::CollatorChosen(3, 5, 60), - Event::NewRound(10, 3, 5, 400), - Event::Rewarded(1, 305), - Event::CollatorChosen(4, 1, 100), - Event::CollatorChosen(4, 2, 90), - Event::CollatorChosen(4, 3, 80), - Event::CollatorChosen(4, 4, 70), - Event::CollatorChosen(4, 5, 60), - Event::NewRound(15, 4, 5, 400), - ]; - expected.append(&mut new); - assert_eq!(events(), expected); - // ~ set block author as 1 for 3 blocks this round - set_author(4, 1, 60); - // ~ set block author as 2 for 2 blocks this round - set_author(4, 2, 40); - roll_to(26); - // pay 60% total issuance to 1 and 40% total issuance to 2 - let mut new1 = vec![ - Event::CollatorChosen(5, 1, 100), - Event::CollatorChosen(5, 2, 90), - Event::CollatorChosen(5, 3, 80), - Event::CollatorChosen(5, 4, 70), - Event::CollatorChosen(5, 5, 60), - Event::NewRound(20, 5, 5, 400), - Event::Rewarded(1, 192), - Event::Rewarded(2, 128), - Event::CollatorChosen(6, 1, 100), - Event::CollatorChosen(6, 2, 90), - Event::CollatorChosen(6, 3, 80), - Event::CollatorChosen(6, 4, 70), - Event::CollatorChosen(6, 5, 60), - Event::NewRound(25, 6, 5, 400), - ]; - expected.append(&mut new1); - assert_eq!(events(), expected); - // ~ each collator produces 1 block this round - set_author(6, 1, 20); - set_author(6, 2, 20); - set_author(6, 3, 20); - set_author(6, 4, 20); - set_author(6, 5, 20); - roll_to(36); - // pay 20% issuance for all collators - let mut new2 = vec![ - Event::CollatorChosen(7, 1, 100), - Event::CollatorChosen(7, 2, 90), - Event::CollatorChosen(7, 3, 80), - Event::CollatorChosen(7, 4, 70), - Event::CollatorChosen(7, 5, 60), - Event::NewRound(30, 7, 5, 400), - Event::Rewarded(5, 67), - Event::Rewarded(3, 67), - Event::Rewarded(4, 67), - Event::Rewarded(1, 67), - Event::Rewarded(2, 67), - Event::CollatorChosen(8, 1, 100), - Event::CollatorChosen(8, 2, 90), - Event::CollatorChosen(8, 3, 80), - Event::CollatorChosen(8, 4, 70), - Event::CollatorChosen(8, 5, 60), - Event::NewRound(35, 8, 5, 400), - ]; - expected.append(&mut new2); - assert_eq!(events(), expected); - // check that distributing rewards clears awarded pts - assert!(Stake::awarded_pts(1, 1).is_zero()); - assert!(Stake::awarded_pts(4, 1).is_zero()); - assert!(Stake::awarded_pts(4, 2).is_zero()); - assert!(Stake::awarded_pts(6, 1).is_zero()); - assert!(Stake::awarded_pts(6, 2).is_zero()); - assert!(Stake::awarded_pts(6, 3).is_zero()); - assert!(Stake::awarded_pts(6, 4).is_zero()); - assert!(Stake::awarded_pts(6, 5).is_zero()); - }); -} - -#[test] -fn multiple_nominations() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_nominations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 50), - Event::CollatorChosen(2, 2, 40), - Event::CollatorChosen(2, 3, 20), - Event::CollatorChosen(2, 4, 20), - Event::CollatorChosen(2, 5, 10), - Event::NewRound(5, 2, 5, 140), - ]; - assert_eq!(events(), expected); - assert_ok!(Stake::nominate(Origin::signed(6), 2, 10, 10, 10)); - assert_ok!(Stake::nominate(Origin::signed(6), 3, 10, 10, 10)); - assert_ok!(Stake::nominate(Origin::signed(6), 4, 10, 10, 10)); - roll_to(16); - let mut new = vec![ - Event::Nomination(6, 10, 2, NominatorAdded::AddedToTop { new_total: 50 }), - Event::Nomination(6, 10, 3, NominatorAdded::AddedToTop { new_total: 30 }), - Event::Nomination(6, 10, 4, NominatorAdded::AddedToTop { new_total: 30 }), - Event::CollatorChosen(3, 1, 50), - Event::CollatorChosen(3, 2, 50), - Event::CollatorChosen(3, 3, 30), - Event::CollatorChosen(3, 4, 30), - Event::CollatorChosen(3, 5, 10), - Event::NewRound(10, 3, 5, 170), - Event::CollatorChosen(4, 1, 50), - Event::CollatorChosen(4, 2, 50), - Event::CollatorChosen(4, 3, 30), - Event::CollatorChosen(4, 4, 30), - Event::CollatorChosen(4, 5, 10), - Event::NewRound(15, 4, 5, 170), - ]; - expected.append(&mut new); - assert_eq!(events(), expected); - roll_to(21); - assert_ok!(Stake::nominate(Origin::signed(7), 2, 80, 10, 10)); - assert_ok!(Stake::nominate(Origin::signed(10), 2, 10, 10, 10),); - roll_to(26); - let mut new2 = vec![ - Event::CollatorChosen(5, 1, 50), - Event::CollatorChosen(5, 2, 50), - Event::CollatorChosen(5, 3, 30), - Event::CollatorChosen(5, 4, 30), - Event::CollatorChosen(5, 5, 10), - Event::NewRound(20, 5, 5, 170), - Event::Nomination(7, 80, 2, NominatorAdded::AddedToTop { new_total: 130 }), - Event::Nomination(10, 10, 2, NominatorAdded::AddedToBottom), - Event::CollatorChosen(6, 1, 50), - Event::CollatorChosen(6, 2, 130), - Event::CollatorChosen(6, 3, 30), - Event::CollatorChosen(6, 4, 30), - Event::CollatorChosen(6, 5, 10), - Event::NewRound(25, 6, 5, 250), - ]; - expected.append(&mut new2); - assert_eq!(events(), expected); - assert_ok!(Stake::leave_candidates(Origin::signed(2), 5)); - assert_eq!( - last_event(), - MetaEvent::Stake(Event::CollatorScheduledExit(6, 2, 8)) - ); - roll_to(31); - let mut new3 = vec![ - Event::CollatorScheduledExit(6, 2, 8), - Event::CollatorChosen(7, 1, 50), - Event::CollatorChosen(7, 3, 30), - Event::CollatorChosen(7, 4, 30), - Event::CollatorChosen(7, 5, 10), - Event::NewRound(30, 7, 4, 120), - ]; - expected.append(&mut new3); - assert_eq!(events(), expected); - // verify that nominations are removed after collator leaves, not before - assert_eq!(Stake::nominator_state2(7).unwrap().total, 90); - assert_eq!( - Stake::nominator_state2(7).unwrap().nominations.0.len(), - 2usize - ); - assert_eq!(Stake::nominator_state2(6).unwrap().total, 40); - assert_eq!( - Stake::nominator_state2(6).unwrap().nominations.0.len(), - 4usize - ); - assert_eq!(Balances::reserved_balance(&6), 40); - assert_eq!(Balances::reserved_balance(&7), 90); - assert_eq!(Balances::free_balance(&6), 60); - assert_eq!(Balances::free_balance(&7), 10); - roll_to(40); - assert_eq!(Stake::nominator_state2(7).unwrap().total, 10); - assert_eq!(Stake::nominator_state2(6).unwrap().total, 30); - assert_eq!( - Stake::nominator_state2(7).unwrap().nominations.0.len(), - 1usize - ); - assert_eq!( - Stake::nominator_state2(6).unwrap().nominations.0.len(), - 3usize - ); - assert_eq!(Balances::reserved_balance(&6), 30); - assert_eq!(Balances::reserved_balance(&7), 10); - assert_eq!(Balances::free_balance(&6), 70); - assert_eq!(Balances::free_balance(&7), 90); - }); -} - -#[test] -fn payouts_follow_nomination_changes() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_nominations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 50), - Event::CollatorChosen(2, 2, 40), - Event::CollatorChosen(2, 3, 20), - Event::CollatorChosen(2, 4, 20), - Event::CollatorChosen(2, 5, 10), - Event::NewRound(5, 2, 5, 140), - ]; - assert_eq!(events(), expected); - // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); - roll_to(16); - // distribute total issuance to collator 1 and its nominators 6, 7, 19 - let mut new = vec![ - Event::CollatorChosen(3, 1, 50), - Event::CollatorChosen(3, 2, 40), - Event::CollatorChosen(3, 3, 20), - Event::CollatorChosen(3, 4, 20), - Event::CollatorChosen(3, 5, 10), - Event::NewRound(10, 3, 5, 140), - Event::Rewarded(1, 26), - Event::Rewarded(6, 8), - Event::Rewarded(7, 8), - Event::Rewarded(10, 8), - Event::CollatorChosen(4, 1, 50), - Event::CollatorChosen(4, 2, 40), - Event::CollatorChosen(4, 3, 20), - Event::CollatorChosen(4, 4, 20), - Event::CollatorChosen(4, 5, 10), - Event::NewRound(15, 4, 5, 140), - ]; - expected.append(&mut new); - assert_eq!(events(), expected); - // ~ set block author as 1 for all blocks this round - set_author(3, 1, 100); - set_author(4, 1, 100); - set_author(5, 1, 100); - // 1. ensure nominators are paid for 2 rounds after they leave - assert_noop!( - Stake::leave_nominators(Origin::signed(66), 10), - Error::::NominatorDNE - ); - assert_ok!(Stake::leave_nominators(Origin::signed(6), 10)); - // fast forward to block in which nominator 6 exit executes - roll_to(25); - // keep paying 6 (note: inflation is in terms of total issuance so that's why 1 is 21) - let mut new2 = vec![ - Event::NominatorExitScheduled(4, 6, 6), - Event::Rewarded(1, 27), - Event::Rewarded(6, 8), - Event::Rewarded(7, 8), - Event::Rewarded(10, 8), - Event::CollatorChosen(5, 1, 50), - Event::CollatorChosen(5, 2, 40), - Event::CollatorChosen(5, 3, 20), - Event::CollatorChosen(5, 4, 20), - Event::CollatorChosen(5, 5, 10), - Event::NewRound(20, 5, 5, 140), - Event::Rewarded(1, 29), - Event::Rewarded(6, 9), - Event::Rewarded(7, 9), - Event::Rewarded(10, 9), - Event::NominatorLeftCollator(6, 1, 10, 40), - Event::NominatorLeft(6, 10), - Event::CollatorChosen(6, 1, 40), - Event::CollatorChosen(6, 2, 40), - Event::CollatorChosen(6, 3, 20), - Event::CollatorChosen(6, 4, 20), - Event::CollatorChosen(6, 5, 10), - Event::NewRound(25, 6, 5, 130), - ]; - expected.append(&mut new2); - assert_eq!(events(), expected); - // 6 won't be paid for this round because they left already - set_author(6, 1, 100); - roll_to(30); - // keep paying 6 - let mut new3 = vec![ - Event::Rewarded(1, 30), - Event::Rewarded(6, 9), - Event::Rewarded(7, 9), - Event::Rewarded(10, 9), - Event::CollatorChosen(7, 1, 40), - Event::CollatorChosen(7, 2, 40), - Event::CollatorChosen(7, 3, 20), - Event::CollatorChosen(7, 4, 20), - Event::CollatorChosen(7, 5, 10), - Event::NewRound(30, 7, 5, 130), - ]; - expected.append(&mut new3); - assert_eq!(events(), expected); - set_author(7, 1, 100); - roll_to(35); - // no more paying 6 - let mut new4 = vec![ - Event::Rewarded(1, 36), - Event::Rewarded(7, 12), - Event::Rewarded(10, 12), - Event::CollatorChosen(8, 1, 40), - Event::CollatorChosen(8, 2, 40), - Event::CollatorChosen(8, 3, 20), - Event::CollatorChosen(8, 4, 20), - Event::CollatorChosen(8, 5, 10), - Event::NewRound(35, 8, 5, 130), - ]; - expected.append(&mut new4); - assert_eq!(events(), expected); - set_author(8, 1, 100); - assert_ok!(Stake::nominate(Origin::signed(8), 1, 10, 10, 10)); - roll_to(40); - // new nomination is not rewarded yet - let mut new5 = vec![ - Event::Nomination(8, 10, 1, NominatorAdded::AddedToTop { new_total: 50 }), - Event::Rewarded(1, 38), - Event::Rewarded(7, 13), - Event::Rewarded(10, 13), - Event::CollatorChosen(9, 1, 50), - Event::CollatorChosen(9, 2, 40), - Event::CollatorChosen(9, 3, 20), - Event::CollatorChosen(9, 4, 20), - Event::CollatorChosen(9, 5, 10), - Event::NewRound(40, 9, 5, 140), - ]; - expected.append(&mut new5); - assert_eq!(events(), expected); - set_author(9, 1, 100); - roll_to(45); - // new nomination is still not rewarded yet - let mut new6 = vec![ - Event::Rewarded(1, 40), - Event::Rewarded(7, 13), - Event::Rewarded(10, 13), - Event::CollatorChosen(10, 1, 50), - Event::CollatorChosen(10, 2, 40), - Event::CollatorChosen(10, 3, 20), - Event::CollatorChosen(10, 4, 20), - Event::CollatorChosen(10, 5, 10), - Event::NewRound(45, 10, 5, 140), - ]; - expected.append(&mut new6); - assert_eq!(events(), expected); - roll_to(50); - // new nomination is rewarded for first time, 2 rounds after joining (`RewardPaymentDelay` = 2) - let mut new7 = vec![ - Event::Rewarded(1, 36), - Event::Rewarded(7, 11), - Event::Rewarded(8, 11), - Event::Rewarded(10, 11), - Event::CollatorChosen(11, 1, 50), - Event::CollatorChosen(11, 2, 40), - Event::CollatorChosen(11, 3, 20), - Event::CollatorChosen(11, 4, 20), - Event::CollatorChosen(11, 5, 10), - Event::NewRound(50, 11, 5, 140), - ]; - expected.append(&mut new7); - assert_eq!(events(), expected); - }); -} - -#[test] -fn nominations_merged_before_reward_payout() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 120)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) - .with_nominations(vec![(5, 1, 30), (5, 2, 30), (5, 3, 30), (5, 4, 30)]) - .build() - .execute_with(|| { - roll_to(8); - set_author(1, 1, 1); - set_author(1, 2, 1); - set_author(1, 3, 1); - set_author(1, 4, 1); - roll_to(16); - let expected_events = vec![ - Event::CollatorChosen(2, 1, 50), - Event::CollatorChosen(2, 2, 50), - Event::CollatorChosen(2, 3, 50), - Event::CollatorChosen(2, 4, 50), - Event::NewRound(5, 2, 4, 200), - Event::Rewarded(3, 1), - Event::Rewarded(4, 1), - Event::Rewarded(1, 1), - Event::Rewarded(2, 1), - // ALL REWARDS FOR 5 are merged into one payment + event - Event::Rewarded(5, 4), - Event::CollatorChosen(3, 1, 50), - Event::CollatorChosen(3, 2, 50), - Event::CollatorChosen(3, 3, 50), - Event::CollatorChosen(3, 4, 50), - Event::NewRound(10, 3, 4, 200), - Event::CollatorChosen(4, 1, 50), - Event::CollatorChosen(4, 2, 50), - Event::CollatorChosen(4, 3, 50), - Event::CollatorChosen(4, 4, 50), - Event::NewRound(15, 4, 4, 200), - ]; - assert_eq!(events(), expected_events); - }); -} - -#[test] -// MaxNominatorsPerCollator = 4 -fn bottom_nominations_are_empty_when_top_nominations_not_full() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 10), (3, 10), (4, 10), (5, 10)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - // no top nominators => no bottom nominators - let collator_state = Stake::collator_state2(1).unwrap(); - assert!(collator_state.top_nominators.is_empty()); - assert!(collator_state.bottom_nominators.is_empty()); - // 1 nominator => 1 top nominator, 0 bottom nominators - assert_ok!(Stake::nominate(Origin::signed(2), 1, 10, 10, 10)); - let collator_state = Stake::collator_state2(1).unwrap(); - assert_eq!(collator_state.top_nominators.len(), 1usize); - assert!(collator_state.bottom_nominators.is_empty()); - // 2 nominators => 2 top nominators, 0 bottom nominators - assert_ok!(Stake::nominate(Origin::signed(3), 1, 10, 10, 10)); - let collator_state = Stake::collator_state2(1).unwrap(); - assert_eq!(collator_state.top_nominators.len(), 2usize); - assert!(collator_state.bottom_nominators.is_empty()); - // 3 nominators => 3 top nominators, 0 bottom nominators - assert_ok!(Stake::nominate(Origin::signed(4), 1, 10, 10, 10)); - let collator_state = Stake::collator_state2(1).unwrap(); - assert_eq!(collator_state.top_nominators.len(), 3usize); - assert!(collator_state.bottom_nominators.is_empty()); - // 4 nominators => 4 top nominators, 0 bottom nominators - assert_ok!(Stake::nominate(Origin::signed(5), 1, 10, 10, 10)); - let collator_state = Stake::collator_state2(1).unwrap(); - assert_eq!(collator_state.top_nominators.len(), 4usize); - assert!(collator_state.bottom_nominators.is_empty()); - }); -} - -#[test] -// MaxNominatorsPerCollator = 4 + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), + (6, 1000), + (7, 33), + (8, 33), + (9, 33), + ]) + .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) + .build() + .execute_with(|| { + roll_to(8); + // should choose top TotalCandidatesSelected (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 100), + Event::CollatorChosen(2, 2, 90), + Event::CollatorChosen(2, 3, 80), + Event::CollatorChosen(2, 4, 70), + Event::CollatorChosen(2, 5, 60), + Event::NewRound(5, 2, 5, 400), + ]; + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for all blocks this round + set_author(2, 1, 100); + roll_to(16); + // pay total issuance to 1 + let mut new = vec![ + Event::CollatorChosen(3, 1, 100), + Event::CollatorChosen(3, 2, 90), + Event::CollatorChosen(3, 3, 80), + Event::CollatorChosen(3, 4, 70), + Event::CollatorChosen(3, 5, 60), + Event::NewRound(10, 3, 5, 400), + Event::CollatorChosen(4, 1, 100), + Event::CollatorChosen(4, 2, 90), + Event::CollatorChosen(4, 3, 80), + Event::CollatorChosen(4, 4, 70), + Event::CollatorChosen(4, 5, 60), + Event::NewRound(15, 4, 5, 400), + Event::Rewarded(1, 305), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for 3 blocks this round + set_author(4, 1, 60); + // ~ set block author as 2 for 2 blocks this round + set_author(4, 2, 40); + roll_to(26); + // pay 60% total issuance to 1 and 40% total issuance to 2 + let mut new1 = vec![ + Event::CollatorChosen(5, 1, 100), + Event::CollatorChosen(5, 2, 90), + Event::CollatorChosen(5, 3, 80), + Event::CollatorChosen(5, 4, 70), + Event::CollatorChosen(5, 5, 60), + Event::NewRound(20, 5, 5, 400), + Event::CollatorChosen(6, 1, 100), + Event::CollatorChosen(6, 2, 90), + Event::CollatorChosen(6, 3, 80), + Event::CollatorChosen(6, 4, 70), + Event::CollatorChosen(6, 5, 60), + Event::NewRound(25, 6, 5, 400), + Event::Rewarded(1, 192), + Event::Rewarded(2, 128), + ]; + expected.append(&mut new1); + assert_eq_events!(expected.clone()); + // ~ each collator produces 1 block this round + set_author(6, 1, 20); + set_author(6, 2, 20); + set_author(6, 3, 20); + set_author(6, 4, 20); + set_author(6, 5, 20); + roll_to(39); + // pay 20% issuance for all collators + let mut new2 = vec![ + Event::CollatorChosen(7, 1, 100), + Event::CollatorChosen(7, 2, 90), + Event::CollatorChosen(7, 3, 80), + Event::CollatorChosen(7, 4, 70), + Event::CollatorChosen(7, 5, 60), + Event::NewRound(30, 7, 5, 400), + Event::CollatorChosen(8, 1, 100), + Event::CollatorChosen(8, 2, 90), + Event::CollatorChosen(8, 3, 80), + Event::CollatorChosen(8, 4, 70), + Event::CollatorChosen(8, 5, 60), + Event::NewRound(35, 8, 5, 400), + Event::Rewarded(5, 67), + Event::Rewarded(3, 67), + Event::Rewarded(4, 67), + Event::Rewarded(1, 67), + Event::Rewarded(2, 67), + ]; + expected.append(&mut new2); + assert_eq_events!(expected); + // check that distributing rewards clears awarded pts + assert!(ParachainStaking::awarded_pts(1, 1).is_zero()); + assert!(ParachainStaking::awarded_pts(4, 1).is_zero()); + assert!(ParachainStaking::awarded_pts(4, 2).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 1).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 2).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 3).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 4).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 5).is_zero()); + }); +} + +#[test] +fn multiple_delegations() { + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 50), + Event::CollatorChosen(2, 2, 40), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::CollatorChosen(2, 5, 10), + Event::NewRound(5, 2, 5, 140), + ]; + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 2, 10, 10, 10)); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 3, 10, 10, 10)); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 4, 10, 10, 10)); + roll_to(16); + let mut new = vec![ + Event::Delegation(6, 10, 2, DelegatorAdded::AddedToTop { new_total: 50 }), + Event::Delegation(6, 10, 3, DelegatorAdded::AddedToTop { new_total: 30 }), + Event::Delegation(6, 10, 4, DelegatorAdded::AddedToTop { new_total: 30 }), + Event::CollatorChosen(3, 1, 50), + Event::CollatorChosen(3, 2, 50), + Event::CollatorChosen(3, 3, 30), + Event::CollatorChosen(3, 4, 30), + Event::CollatorChosen(3, 5, 10), + Event::NewRound(10, 3, 5, 170), + Event::CollatorChosen(4, 1, 50), + Event::CollatorChosen(4, 2, 50), + Event::CollatorChosen(4, 3, 30), + Event::CollatorChosen(4, 4, 30), + Event::CollatorChosen(4, 5, 10), + Event::NewRound(15, 4, 5, 170), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + roll_to(21); + assert_ok!(ParachainStaking::delegate(Origin::signed(7), 2, 80, 10, 10)); + assert_ok!(ParachainStaking::delegate( + Origin::signed(10), + 2, + 10, + 10, + 10 + ),); + roll_to(26); + let mut new2 = vec![ + Event::CollatorChosen(5, 1, 50), + Event::CollatorChosen(5, 2, 50), + Event::CollatorChosen(5, 3, 30), + Event::CollatorChosen(5, 4, 30), + Event::CollatorChosen(5, 5, 10), + Event::NewRound(20, 5, 5, 170), + Event::Delegation(7, 80, 2, DelegatorAdded::AddedToTop { new_total: 130 }), + Event::Delegation(10, 10, 2, DelegatorAdded::AddedToBottom), + Event::CollatorChosen(6, 1, 50), + Event::CollatorChosen(6, 2, 130), + Event::CollatorChosen(6, 3, 30), + Event::CollatorChosen(6, 4, 30), + Event::CollatorChosen(6, 5, 10), + Event::NewRound(25, 6, 5, 250), + ]; + expected.append(&mut new2); + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(2), + 5 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( + 6, 2, 8 + ))); + roll_to(31); + let mut new3 = vec![ + Event::CandidateScheduledExit(6, 2, 8), + Event::CollatorChosen(7, 1, 50), + Event::CollatorChosen(7, 3, 30), + Event::CollatorChosen(7, 4, 30), + Event::CollatorChosen(7, 5, 10), + Event::NewRound(30, 7, 4, 120), + ]; + expected.append(&mut new3); + assert_eq_events!(expected); + // verify that delegations are removed after collator leaves, not before + assert_eq!(ParachainStaking::delegator_state(7).unwrap().total, 90); + assert_eq!( + ParachainStaking::delegator_state(7) + .unwrap() + .delegations + .0 + .len(), + 2usize + ); + assert_eq!(ParachainStaking::delegator_state(6).unwrap().total, 40); + assert_eq!( + ParachainStaking::delegator_state(6) + .unwrap() + .delegations + .0 + .len(), + 4usize + ); + assert_eq!(Balances::reserved_balance(&6), 40); + assert_eq!(Balances::reserved_balance(&7), 90); + assert_eq!(Balances::free_balance(&6), 60); + assert_eq!(Balances::free_balance(&7), 10); + roll_to(40); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 2, + 5 + )); + assert_eq!(ParachainStaking::delegator_state(7).unwrap().total, 10); + assert_eq!(ParachainStaking::delegator_state(6).unwrap().total, 30); + assert_eq!( + ParachainStaking::delegator_state(7) + .unwrap() + .delegations + .0 + .len(), + 1usize + ); + assert_eq!( + ParachainStaking::delegator_state(6) + .unwrap() + .delegations + .0 + .len(), + 3usize + ); + assert_eq!(Balances::reserved_balance(&6), 30); + assert_eq!(Balances::reserved_balance(&7), 10); + assert_eq!(Balances::free_balance(&6), 70); + assert_eq!(Balances::free_balance(&7), 90); + }); +} + +#[test] +// The test verifies that the pending revoke request is removed by 2's exit so there is no dangling +// revoke request after 2 exits +fn execute_leave_candidate_removes_delegations() { + ExtBuilder::default() + .with_balances(vec![(1, 100), (2, 100), (3, 100), (4, 100)]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 10), (3, 2, 10), (4, 1, 10), (4, 2, 10)]) + .build() + .execute_with(|| { + // Verifies the revocation count is originally at 0 + assert_eq!( + ParachainStaking::delegator_state(3) + .unwrap() + .requests + .revocations_count, + 0 + ); + + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(2), + 2 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(3), + 2 + )); + // Verifies the revocation count has been updated to 1 + assert_eq!( + ParachainStaking::delegator_state(3) + .unwrap() + .requests + .revocations_count, + 1 + ); + + roll_to(16); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 2, + 2 + )); + // Verifies the revocation count has been reduced to 0 + assert_eq!( + ParachainStaking::delegator_state(3) + .unwrap() + .requests + .revocations_count, + 0 + ); + }); +} + +#[test] +fn payouts_follow_delegation_changes() { + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 50), + Event::CollatorChosen(2, 2, 40), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::CollatorChosen(2, 5, 10), + Event::NewRound(5, 2, 5, 140), + ]; + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for all blocks this round + set_author(2, 1, 100); + roll_to(16); + // distribute total issuance to collator 1 and its delegators 6, 7, 19 + let mut new = vec![ + Event::CollatorChosen(3, 1, 50), + Event::CollatorChosen(3, 2, 40), + Event::CollatorChosen(3, 3, 20), + Event::CollatorChosen(3, 4, 20), + Event::CollatorChosen(3, 5, 10), + Event::NewRound(10, 3, 5, 140), + Event::CollatorChosen(4, 1, 50), + Event::CollatorChosen(4, 2, 40), + Event::CollatorChosen(4, 3, 20), + Event::CollatorChosen(4, 4, 20), + Event::CollatorChosen(4, 5, 10), + Event::NewRound(15, 4, 5, 140), + Event::Rewarded(1, 26), + Event::Rewarded(6, 8), + Event::Rewarded(7, 8), + Event::Rewarded(10, 8), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for all blocks this round + set_author(3, 1, 100); + set_author(4, 1, 100); + set_author(5, 1, 100); + set_author(6, 1, 100); + // 1. ensure delegators are paid for 2 rounds after they leave + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(66)), + Error::::DelegatorDNE + ); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 6 + ))); + // fast forward to block in which delegator 6 exit executes + roll_to(25); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(6), + 6, + 10 + )); + // keep paying 6 (note: inflation is in terms of total issuance so that's why 1 is 21) + let mut new2 = vec![ + Event::DelegatorExitScheduled(4, 6, 6), + Event::CollatorChosen(5, 1, 50), + Event::CollatorChosen(5, 2, 40), + Event::CollatorChosen(5, 3, 20), + Event::CollatorChosen(5, 4, 20), + Event::CollatorChosen(5, 5, 10), + Event::NewRound(20, 5, 5, 140), + Event::Rewarded(1, 27), + Event::Rewarded(6, 8), + Event::Rewarded(7, 8), + Event::Rewarded(10, 8), + Event::CollatorChosen(6, 1, 50), + Event::CollatorChosen(6, 2, 40), + Event::CollatorChosen(6, 3, 20), + Event::CollatorChosen(6, 4, 20), + Event::CollatorChosen(6, 5, 10), + Event::NewRound(25, 6, 5, 140), + Event::Rewarded(1, 29), + Event::Rewarded(6, 9), + Event::Rewarded(7, 9), + Event::Rewarded(10, 9), + Event::DelegatorLeftCandidate(6, 1, 10, 40), + Event::DelegatorLeft(6, 10), + ]; + expected.append(&mut new2); + assert_eq_events!(expected.clone()); + // 6 won't be paid for this round because they left already + set_author(7, 1, 100); + roll_to(35); + // keep paying 6 + let mut new3 = vec![ + Event::CollatorChosen(7, 1, 40), + Event::CollatorChosen(7, 2, 40), + Event::CollatorChosen(7, 3, 20), + Event::CollatorChosen(7, 4, 20), + Event::CollatorChosen(7, 5, 10), + Event::NewRound(30, 7, 5, 130), + Event::Rewarded(1, 30), + Event::Rewarded(6, 9), + Event::Rewarded(7, 9), + Event::Rewarded(10, 9), + Event::CollatorChosen(8, 1, 40), + Event::CollatorChosen(8, 2, 40), + Event::CollatorChosen(8, 3, 20), + Event::CollatorChosen(8, 4, 20), + Event::CollatorChosen(8, 5, 10), + Event::NewRound(35, 8, 5, 130), + Event::Rewarded(1, 32), + Event::Rewarded(6, 10), + Event::Rewarded(7, 10), + Event::Rewarded(10, 10), + ]; + expected.append(&mut new3); + assert_eq_events!(expected.clone()); + set_author(8, 1, 100); + roll_to(40); + // no more paying 6 + let mut new4 = vec![ + Event::CollatorChosen(9, 1, 40), + Event::CollatorChosen(9, 2, 40), + Event::CollatorChosen(9, 3, 20), + Event::CollatorChosen(9, 4, 20), + Event::CollatorChosen(9, 5, 10), + Event::NewRound(40, 9, 5, 130), + Event::Rewarded(1, 38), + Event::Rewarded(7, 13), + Event::Rewarded(10, 13), + ]; + expected.append(&mut new4); + assert_eq_events!(expected.clone()); + set_author(9, 1, 100); + assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); + roll_to(45); + // new delegation is not rewarded yet + let mut new5 = vec![ + Event::Delegation(8, 10, 1, DelegatorAdded::AddedToTop { new_total: 50 }), + Event::CollatorChosen(10, 1, 50), + Event::CollatorChosen(10, 2, 40), + Event::CollatorChosen(10, 3, 20), + Event::CollatorChosen(10, 4, 20), + Event::CollatorChosen(10, 5, 10), + Event::NewRound(45, 10, 5, 140), + Event::Rewarded(1, 40), + Event::Rewarded(7, 13), + Event::Rewarded(10, 13), + ]; + expected.append(&mut new5); + assert_eq_events!(expected.clone()); + set_author(10, 1, 100); + roll_to(50); + // new delegation not rewarded yet + let mut new6 = vec![ + Event::CollatorChosen(11, 1, 50), + Event::CollatorChosen(11, 2, 40), + Event::CollatorChosen(11, 3, 20), + Event::CollatorChosen(11, 4, 20), + Event::CollatorChosen(11, 5, 10), + Event::NewRound(50, 11, 5, 140), + Event::Rewarded(1, 42), + Event::Rewarded(7, 14), + Event::Rewarded(10, 14), + ]; + expected.append(&mut new6); + assert_eq_events!(expected.clone()); + roll_to(55); + // new delegation is rewarded for first time + // 2 rounds after joining (`RewardPaymentDelay` = 2) + let mut new7 = vec![ + Event::CollatorChosen(12, 1, 50), + Event::CollatorChosen(12, 2, 40), + Event::CollatorChosen(12, 3, 20), + Event::CollatorChosen(12, 4, 20), + Event::CollatorChosen(12, 5, 10), + Event::NewRound(55, 12, 5, 140), + Event::Rewarded(1, 39), + Event::Rewarded(7, 12), + Event::Rewarded(10, 12), + Event::Rewarded(8, 12), + ]; + expected.append(&mut new7); + assert_eq_events!(expected); + }); +} + +#[test] +fn bottom_delegations_are_empty_when_top_delegations_not_full() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 10), (3, 10), (4, 10), (5, 10)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + // no top delegators => no bottom delegators + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert!(top_delegations.delegations.is_empty()); + assert!(bottom_delegations.delegations.is_empty()); + // 1 delegator => 1 top delegator, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 1usize); + assert!(bottom_delegations.delegations.is_empty()); + // 2 delegators => 2 top delegators, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(3), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 2usize); + assert!(bottom_delegations.delegations.is_empty()); + // 3 delegators => 3 top delegators, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(4), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 3usize); + assert!(bottom_delegations.delegations.is_empty()); + // 4 delegators => 4 top delegators, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(5), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 4usize); + assert!(bottom_delegations.delegations.is_empty()); + }); +} + +#[test] fn candidate_pool_updates_when_total_counted_changes() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (3, 19), - (4, 20), - (5, 21), - (6, 22), - (7, 15), - (8, 16), - (9, 17), - (10, 18), - ]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![ - (3, 1, 11), - (4, 1, 12), - (5, 1, 13), - (6, 1, 14), - (7, 1, 15), - (8, 1, 16), - (9, 1, 17), - (10, 1, 18), - ]) - .build() - .execute_with(|| { - fn is_candidate_pool_bond(account: u64, bond: u128) { - let pool = Stake::candidate_pool(); - for candidate in pool.0 { - if candidate.owner == account { - assert_eq!(candidate.amount, bond); - } - } - } - // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) - is_candidate_pool_bond(1, 86); - assert_ok!(Stake::nominator_bond_more(Origin::signed(3), 1, 8)); - // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) - is_candidate_pool_bond(1, 90); - assert_ok!(Stake::nominator_bond_more(Origin::signed(4), 1, 8)); - // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) - is_candidate_pool_bond(1, 94); - assert_ok!(Stake::nominator_bond_less(Origin::signed(10), 1, 3)); - // 16 + 17 + 19 + 20 + 20 = 92 (top 4 + self bond) - is_candidate_pool_bond(1, 92); - assert_ok!(Stake::nominator_bond_less(Origin::signed(9), 1, 4)); - // 15 + 16 + 19 + 20 + 20 = 90 (top 4 + self bond) - is_candidate_pool_bond(1, 90); - }); -} - -#[test] -// MaxNominatorsPerCollator = 4 + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (3, 19), + (4, 20), + (5, 21), + (6, 22), + (7, 15), + (8, 16), + (9, 17), + (10, 18), + ]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (3, 1, 11), + (4, 1, 12), + (5, 1, 13), + (6, 1, 14), + (7, 1, 15), + (8, 1, 16), + (9, 1, 17), + (10, 1, 18), + ]) + .build() + .execute_with(|| { + fn is_candidate_pool_bond(account: u64, bond: u128) { + let pool = ParachainStaking::candidate_pool(); + for candidate in pool.0 { + if candidate.owner == account { + assert_eq!( + candidate.amount, bond, + "Candidate Bond {:?} is Not Equal to Expected: {:?}", + candidate.amount, bond + ); + } + } + } + // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) + is_candidate_pool_bond(1, 86); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(3), + 1, + 8 + )); + // 3: 11 -> 19 => 3 is in top, bumps out 7 + // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) + is_candidate_pool_bond(1, 90); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(4), + 1, + 8 + )); + // 4: 12 -> 20 => 4 is in top, bumps out 8 + // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) + is_candidate_pool_bond(1, 94); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(10), + 1, + 3 + )); + roll_to(30); + // 10: 18 -> 15 => 10 bumped to bottom, 8 bumped to top (- 18 + 16 = -2 for count) + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(10), + 10, + 1 + )); + // 16 + 17 + 19 + 20 + 20 = 92 (top 4 + self bond) + is_candidate_pool_bond(1, 92); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(9), + 1, + 4 + )); + roll_to(40); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(9), + 9, + 1 + )); + // 15 + 16 + 19 + 20 + 20 = 90 (top 4 + self bond) + is_candidate_pool_bond(1, 90); + }); +} + +#[test] fn only_top_collators_are_counted() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (3, 19), - (4, 20), - (5, 21), - (6, 22), - (7, 15), - (8, 16), - (9, 17), - (10, 18), - ]) - .with_candidates(vec![(1, 20)]) - .with_nominations(vec![ - (3, 1, 11), - (4, 1, 12), - (5, 1, 13), - (6, 1, 14), - (7, 1, 15), - (8, 1, 16), - (9, 1, 17), - (10, 1, 18), - ]) - .build() - .execute_with(|| { - // sanity check that 3-10 are nominators immediately - for i in 3..11 { - assert!(Stake::is_nominator(&i)); - } - let mut expected_events = Vec::new(); - let collator_state = Stake::collator_state2(1).unwrap(); - // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 86); - // 11 + 12 + 13 + 14 = 50 - assert_eq!( - collator_state.total_counted + 50, - collator_state.total_backing - ); - // bump bottom to the top - assert_ok!(Stake::nominator_bond_more(Origin::signed(3), 1, 8)); - expected_events.push(Event::NominationIncreased(3, 1, 8, true)); - assert_eq!(events(), expected_events); - let collator_state = Stake::collator_state2(1).unwrap(); - // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 90); - // 12 + 13 + 14 + 15 = 54 - assert_eq!( - collator_state.total_counted + 54, - collator_state.total_backing - ); - // bump bottom to the top - assert_ok!(Stake::nominator_bond_more(Origin::signed(4), 1, 8)); - expected_events.push(Event::NominationIncreased(4, 1, 8, true)); - assert_eq!(events(), expected_events); - let collator_state = Stake::collator_state2(1).unwrap(); - // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 94); - // 13 + 14 + 15 + 16 = 58 - assert_eq!( - collator_state.total_counted + 58, - collator_state.total_backing - ); - // bump bottom to the top - assert_ok!(Stake::nominator_bond_more(Origin::signed(5), 1, 8)); - expected_events.push(Event::NominationIncreased(5, 1, 8, true)); - assert_eq!(events(), expected_events); - let collator_state = Stake::collator_state2(1).unwrap(); - // 18 + 19 + 20 + 21 + 20 = 98 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 98); - // 14 + 15 + 16 + 17 = 62 - assert_eq!( - collator_state.total_counted + 62, - collator_state.total_backing - ); - // bump bottom to the top - assert_ok!(Stake::nominator_bond_more(Origin::signed(6), 1, 8)); - expected_events.push(Event::NominationIncreased(6, 1, 8, true)); - assert_eq!(events(), expected_events); - let collator_state = Stake::collator_state2(1).unwrap(); - // 19 + 20 + 21 + 22 + 20 = 102 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 102); - // 15 + 16 + 17 + 18 = 66 - assert_eq!( - collator_state.total_counted + 66, - collator_state.total_backing - ); - }); -} - -#[test] -fn nomination_events_convey_correct_position() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20)]) - .with_nominations(vec![(3, 1, 11), (4, 1, 12), (5, 1, 13), (6, 1, 14)]) - .build() - .execute_with(|| { - let collator1_state = Stake::collator_state2(1).unwrap(); - // 11 + 12 + 13 + 14 + 20 = 70 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 70); - assert_eq!(collator1_state.total_counted, collator1_state.total_backing); - // Top nominations are full, new highest nomination is made - assert_ok!(Stake::nominate(Origin::signed(7), 1, 15, 10, 10)); - let mut expected_events = Vec::new(); - expected_events.push(Event::Nomination( - 7, - 15, - 1, - NominatorAdded::AddedToTop { new_total: 74 }, - )); - assert_eq!(events(), expected_events); - let collator1_state = Stake::collator_state2(1).unwrap(); - // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 74); - // 11 = 11 - assert_eq!( - collator1_state.total_counted + 11, - collator1_state.total_backing - ); - // New nomination is added to the bottom - assert_ok!(Stake::nominate(Origin::signed(8), 1, 10, 10, 10)); - expected_events.push(Event::Nomination(8, 10, 1, NominatorAdded::AddedToBottom)); - assert_eq!(events(), expected_events); - let collator1_state = Stake::collator_state2(1).unwrap(); - // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 74); - // 10 + 11 = 21 - assert_eq!( - collator1_state.total_counted + 21, - collator1_state.total_backing - ); - // 8 increases nomination to the top - assert_ok!(Stake::nominator_bond_more(Origin::signed(8), 1, 3)); - expected_events.push(Event::NominationIncreased(8, 1, 3, true)); - assert_eq!(events(), expected_events); - let collator1_state = Stake::collator_state2(1).unwrap(); - // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 75); - // 11 + 12 = 23 - assert_eq!( - collator1_state.total_counted + 23, - collator1_state.total_backing - ); - // 3 increases nomination but stays in bottom - assert_ok!(Stake::nominator_bond_more(Origin::signed(3), 1, 1)); - expected_events.push(Event::NominationIncreased(3, 1, 1, false)); - assert_eq!(events(), expected_events); - let collator1_state = Stake::collator_state2(1).unwrap(); - // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 75); - // 12 + 12 = 24 - assert_eq!( - collator1_state.total_counted + 24, - collator1_state.total_backing - ); - // 6 decreases nomination but stays in top - assert_ok!(Stake::nominator_bond_less(Origin::signed(6), 1, 2)); - expected_events.push(Event::NominationDecreased(6, 1, 2, true)); - assert_eq!(events(), expected_events); - let collator1_state = Stake::collator_state2(1).unwrap(); - // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 73); - // 12 + 12 = 24 - assert_eq!( - collator1_state.total_counted + 24, - collator1_state.total_backing - ); - // 6 decreases nomination and is bumped to bottom - assert_ok!(Stake::nominator_bond_less(Origin::signed(6), 1, 1)); - expected_events.push(Event::NominationDecreased(6, 1, 1, false)); - assert_eq!(events(), expected_events); - let collator1_state = Stake::collator_state2(1).unwrap(); - // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 73); - // 11 + 12 = 23 - assert_eq!( - collator1_state.total_counted + 23, - collator1_state.total_backing - ); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (3, 19), + (4, 20), + (5, 21), + (6, 22), + (7, 15), + (8, 16), + (9, 17), + (10, 18), + ]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (3, 1, 11), + (4, 1, 12), + (5, 1, 13), + (6, 1, 14), + (7, 1, 15), + (8, 1, 16), + (9, 1, 17), + (10, 1, 18), + ]) + .build() + .execute_with(|| { + // sanity check that 3-10 are delegators immediately + for i in 3..11 { + assert!(ParachainStaking::is_delegator(&i)); + } + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 86); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(3), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(3, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 90); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(4), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(4, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 94); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(5), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(5, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 18 + 19 + 20 + 21 + 20 = 98 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 98); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(6), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(6, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 19 + 20 + 21 + 22 + 20 = 102 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 102); + }); +} + +#[test] +fn delegation_events_convey_correct_position() { + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 11), (4, 1, 12), (5, 1, 13), (6, 1, 14)]) + .build() + .execute_with(|| { + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 11 + 12 + 13 + 14 + 20 = 70 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 70); + // Top delegations are full, new highest delegation is made + assert_ok!(ParachainStaking::delegate(Origin::signed(7), 1, 15, 10, 10)); + assert_event_emitted!(Event::Delegation( + 7, + 15, + 1, + DelegatorAdded::AddedToTop { new_total: 74 }, + )); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 74); + // New delegation is added to the bottom + assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); + assert_event_emitted!(Event::Delegation(8, 10, 1, DelegatorAdded::AddedToBottom)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 74); + // 8 increases delegation to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(8), + 1, + 3 + )); + assert_event_emitted!(Event::DelegationIncreased(8, 1, 3, true)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 75); + // 3 increases delegation but stays in bottom + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(3), + 1, + 1 + )); + assert_event_emitted!(Event::DelegationIncreased(3, 1, 1, false)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 75); + // 6 decreases delegation but stays in top + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(6), + 1, + 2 + )); + assert_event_emitted!(Event::DelegationDecreaseScheduled(6, 1, 2, 3)); + roll_to(30); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(6), + 6, + 1 + )); + assert_event_emitted!(Event::DelegationDecreased(6, 1, 2, true)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond)Æ’ + assert_eq!(collator1_state.total_counted, 73); + // 6 decreases delegation and is bumped to bottom + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(6), + 1, + 1 + )); + assert_event_emitted!(Event::DelegationDecreaseScheduled(6, 1, 1, 9)); + roll_to(40); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(6), + 6, + 1 + )); + assert_event_emitted!(Event::DelegationDecreased(6, 1, 1, false)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 73); + }); +} + +#[test] +fn no_rewards_paid_until_after_reward_payment_delay() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + .build() + .execute_with(|| { + roll_to_round_begin(2); + // payouts for round 1 + set_author(1, 1, 1); + set_author(1, 2, 1); + set_author(1, 3, 1); + set_author(1, 4, 1); + set_author(1, 4, 1); + let mut expected = vec![ + Event::CollatorChosen(2, 1, 20), + Event::CollatorChosen(2, 2, 20), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::NewRound(5, 2, 4, 80), + ]; + assert_eq_events!(expected); + + roll_to_round_begin(3); + expected.append(&mut vec![ + Event::CollatorChosen(3, 1, 20), + Event::CollatorChosen(3, 2, 20), + Event::CollatorChosen(3, 3, 20), + Event::CollatorChosen(3, 4, 20), + Event::NewRound(10, 3, 4, 80), + // rewards will begin immediately following a NewRound + Event::Rewarded(3, 1), + ]); + assert_eq_events!(expected); + + // roll to the next block where we start round 3; we should have round change and first + // payout made. + roll_one_block(); + expected.push(Event::Rewarded(4, 2)); + assert_eq_events!(expected); + + roll_one_block(); + expected.push(Event::Rewarded(1, 1)); + assert_eq_events!(expected); + + roll_one_block(); + expected.push(Event::Rewarded(2, 1)); + assert_eq_events!(expected); + + // there should be no more payments in this round... + let num_blocks_rolled = roll_to_round_end(3); + assert_eq_events!(expected); + assert_eq!(num_blocks_rolled, 1); + }); +} + +#[test] +fn deferred_payment_storage_items_are_cleaned_up() { + use crate::*; + + // this test sets up two collators, gives them points in round one, and focuses on the + // storage over the next several blocks to show that it is properly cleaned up + + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20)]) + .with_candidates(vec![(1, 20), (2, 20)]) + .build() + .execute_with(|| { + let mut round: u32 = 1; + set_author(round, 1, 1); + set_author(round, 2, 1); + + // reflects genesis? + assert!(>::contains_key(round, 1)); + assert!(>::contains_key(round, 2)); + + round = 2; + roll_to_round_begin(round.into()); + let mut expected = vec![ + Event::CollatorChosen(round, 1, 20), + Event::CollatorChosen(round, 2, 20), + Event::NewRound(5, round, 2, 40), + ]; + assert_eq_events!(expected); + + // we should have AtStake snapshots as soon as we start a round... + assert!(>::contains_key(2, 1)); + assert!(>::contains_key(2, 2)); + // ...and it should persist until the round is fully paid out + assert!(>::contains_key(1, 1)); + assert!(>::contains_key(1, 2)); + + assert!( + !>::contains_key(1), + "DelayedPayouts shouldn't be populated until after RewardPaymentDelay" + ); + assert!( + >::contains_key(1), + "Points should be populated during current round" + ); + assert!( + >::contains_key(1), + "Staked should be populated when round changes" + ); + + assert!( + !>::contains_key(2), + "Points should not be populated until author noted" + ); + assert!( + >::contains_key(2), + "Staked should be populated when round changes" + ); + + // first payout occurs in round 3 + round = 3; + roll_to_round_begin(round.into()); + expected.append(&mut vec![ + Event::CollatorChosen(round, 1, 20), + Event::CollatorChosen(round, 2, 20), + Event::NewRound(10, round, 2, 40), + Event::Rewarded(1, 1), + ]); + assert_eq_events!(expected); + + // payouts should exist for past rounds that haven't been paid out yet.. + assert!(>::contains_key(3, 1)); + assert!(>::contains_key(3, 2)); + assert!(>::contains_key(2, 1)); + assert!(>::contains_key(2, 2)); + + assert!( + >::contains_key(1), + "DelayedPayouts should be populated after RewardPaymentDelay" + ); + assert!(>::contains_key(1)); + assert!( + !>::contains_key(1), + "Staked should be cleaned up after round change" + ); + + assert!(!>::contains_key(2)); + assert!( + !>::contains_key(2), + "We never rewarded points for round 2" + ); + assert!(>::contains_key(2)); + + assert!(!>::contains_key(3)); + assert!( + !>::contains_key(3), + "We never awarded points for round 3" + ); + assert!(>::contains_key(3)); + + // collator 1 has been paid in this last block and associated storage cleaned up + assert!(!>::contains_key(1, 1)); + assert!(!>::contains_key(1, 1)); + + // but collator 2 hasn't been paid + assert!(>::contains_key(1, 2)); + assert!(>::contains_key(1, 2)); + + round = 4; + roll_to_round_begin(round.into()); + expected.append(&mut vec![ + Event::Rewarded(2, 1), // from previous round + Event::CollatorChosen(round, 1, 20), + Event::CollatorChosen(round, 2, 20), + Event::NewRound(15, round, 2, 40), + ]); + assert_eq_events!(expected); + + // collators have both been paid and storage fully cleaned up for round 1 + assert!(!>::contains_key(1, 2)); + assert!(!>::contains_key(1, 2)); + assert!(!>::contains_key(1)); + assert!(!>::contains_key(1)); // points should be cleaned up + assert!(!>::contains_key(1)); + + roll_to_round_end(4); + + // no more events expected + assert_eq_events!(expected); + }); +} + +#[test] +fn deferred_payment_steady_state_event_flow() { + use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons}; + + // this test "flows" through a number of rounds, asserting that certain things do/don't happen + // once the staking pallet is in a "steady state" (specifically, once we are past the first few + // rounds to clear RewardPaymentDelay) + + ExtBuilder::default() + .with_balances(vec![ + // collators + (1, 200), + (2, 200), + (3, 200), + (4, 200), + // delegators + (11, 200), + (22, 200), + (33, 200), + (44, 200), + // burn account, see `reset_issuance()` + (111, 1000), + ]) + .with_candidates(vec![(1, 200), (2, 200), (3, 200), (4, 200)]) + .with_delegations(vec![ + // delegator 11 delegates 100 to 1 and 2 + (11, 1, 100), + (11, 2, 100), + // delegator 22 delegates 100 to 2 and 3 + (22, 2, 100), + (22, 3, 100), + // delegator 33 delegates 100 to 3 and 4 + (33, 3, 100), + (33, 4, 100), + // delegator 44 delegates 100 to 4 and 1 + (44, 4, 100), + (44, 1, 100), + ]) + .build() + .execute_with(|| { + // convenience to set the round points consistently + let set_round_points = |round: u64| { + set_author(round as u32, 1, 1); + set_author(round as u32, 2, 1); + set_author(round as u32, 3, 1); + set_author(round as u32, 4, 1); + }; + + // grab initial issuance -- we will reset it before round issuance is calculated so that + // it is consistent every round + let initial_issuance = Balances::total_issuance(); + let reset_issuance = || { + let new_issuance = Balances::total_issuance(); + let diff = new_issuance - initial_issuance; + let burned = Balances::burn(diff); + Balances::settle( + &111, + burned, + WithdrawReasons::FEE, + ExistenceRequirement::AllowDeath, + ) + .expect("Account can absorb burn"); + }; + + // fn to roll through the first RewardPaymentDelay rounds. returns new round index + let roll_through_initial_rounds = |mut round: u64| -> u64 { + while round < crate::mock::RewardPaymentDelay::get() as u64 + 1 { + set_round_points(round); + + roll_to_round_end(round); + round += 1; + } + + reset_issuance(); + + round + }; + + // roll through a "steady state" round and make all of our assertions + // returns new round index + let roll_through_steady_state_round = |round: u64| -> u64 { + let num_rounds_rolled = roll_to_round_begin(round); + assert_eq!( + num_rounds_rolled, 1, + "expected to be at round begin already" + ); + + let expected = vec![ + Event::CollatorChosen(round as u32, 1, 400), + Event::CollatorChosen(round as u32, 2, 400), + Event::CollatorChosen(round as u32, 3, 400), + Event::CollatorChosen(round as u32, 4, 400), + Event::NewRound((round - 1) * 5, round as u32, 4, 1600), + // first payout should occur on round change + Event::Rewarded(3, 19), + Event::Rewarded(22, 6), + Event::Rewarded(33, 6), + ]; + assert_eq_last_events!(expected); + + set_round_points(round); + + roll_one_block(); + let expected = vec![ + Event::Rewarded(4, 19), + Event::Rewarded(33, 6), + Event::Rewarded(44, 6), + ]; + assert_eq_last_events!(expected); + + roll_one_block(); + let expected = vec![ + Event::Rewarded(1, 19), + Event::Rewarded(11, 6), + Event::Rewarded(44, 6), + ]; + assert_eq_last_events!(expected); + + roll_one_block(); + let expected = vec![ + Event::Rewarded(2, 19), + Event::Rewarded(11, 6), + Event::Rewarded(22, 6), + ]; + assert_eq_last_events!(expected); + + roll_one_block(); + let expected = vec![ + // we paid everyone out by now, should repeat last event + Event::Rewarded(22, 6), + ]; + assert_eq_last_events!(expected); + + let num_rounds_rolled = roll_to_round_end(round); + assert_eq!(num_rounds_rolled, 0, "expected to be at round end already"); + + reset_issuance(); + + round + 1 + }; + + let mut round = 1; + round = roll_through_initial_rounds(round); // we should be at RewardPaymentDelay + for _ in 1..5 { + round = roll_through_steady_state_round(round); + } + }); +} + +// HOTFIX UNIT TESTs + +#[test] +fn hotfix_remove_delegation_requests_works() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let mut requests: BTreeMap< + ::AccountId, + DelegationRequest<::AccountId, BalanceOf>, + > = BTreeMap::new(); + requests.insert( + 3, + DelegationRequest { + collator: 3, + amount: 5, + when_executable: 0, + action: DelegationChange::Decrease, + }, + ); + requests.insert( + 4, + DelegationRequest { + collator: 4, + amount: 20, + when_executable: 0, + action: DelegationChange::Revoke, + }, + ); + let corrupted_delegator_state = Delegator { + id: 2, + delegations: OrderedSet::from(vec![Bond { + owner: 1, + amount: 20, + }]), + total: 20, + requests: PendingDelegationRequests { + revocations_count: 1, + requests, + less_total: 25, + }, + status: DelegatorStatus::Active, + }; + >::insert(2, corrupted_delegator_state); + assert_ok!(ParachainStaking::hotfix_remove_delegation_requests( + Origin::root(), + vec![2, 5] + )); + assert!(ParachainStaking::delegator_state(&5).is_none()); + let fixed_delegator_state = + ParachainStaking::delegator_state(&2).expect("inserted => exists"); + assert_eq!(fixed_delegator_state.requests.revocations_count, 0); + assert_eq!(fixed_delegator_state.requests.less_total, 0); + }); +} + +#[test] +fn hotfix_update_candidate_pool_value_updates_candidate_pool() { + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + // corrupt CandidatePool + >::put(OrderedSet::from(vec![ + Bond { + owner: 1, + amount: 15, + }, + Bond { + owner: 2, + amount: 16, + }, + Bond { + owner: 3, + amount: 17, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 19, + }, + ])); + // run migration and pass in 6 even though not a candidate + assert_ok!(ParachainStaking::hotfix_update_candidate_pool_value( + Origin::root(), + vec![1, 2, 3, 4, 5, 6] + )); + // CandidatePool is now fixed for all input accounts + let pool = >::get(); + for Bond { owner, amount } in pool.0 { + // 6 is not in the candidate pool despite being passed in + assert!(owner <= 5 && owner >= 1); + // all amounts are fixed + assert_eq!(amount, 20); + } + }); +} + +// MIGRATION UNIT TESTS +use frame_support::traits::OnRuntimeUpgrade; + +#[test] +/// Kicks extra bottom delegations to force leave delegators if last delegation +fn split_candidate_state_kicks_extra_bottom_delegators_to_exit() { + ExtBuilder::default() + .with_balances(vec![(11, 22), (12, 20)]) + .build() + .execute_with(|| { + for i in 11..13 { + let old_delegator_state = Delegator { + id: i, + delegations: OrderedSet::from(vec![ + Bond { + owner: 1, + amount: 10, + }, + Bond { + owner: 2, + amount: 10, + }, + ]), + total: 20, + requests: PendingDelegationRequests::new(), + status: DelegatorStatus::Active, + }; + >::insert(&i, old_delegator_state); + } + assert_ok!(::Currency::reserve(&11, 22)); + assert_ok!(::Currency::reserve(&12, 20)); + assert_eq!(Balances::reserved_balance(&11), 22); + assert_eq!(Balances::reserved_balance(&12), 20); + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 12, + amount: 10, + }, + Bond { + owner: 11, + amount: 11, + }, + Bond { + owner: 10, + amount: 12, + }, + Bond { + owner: 9, + amount: 13, + }, + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 165, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + // total is 165 * 2 = 330 + >::put(330); + assert!(ParachainStaking::is_delegator(&11)); + assert!(ParachainStaking::is_delegator(&12)); + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + assert_event_emitted!(Event::DelegationKicked(11, 1, 11)); + assert_event_emitted!(Event::DelegationKicked(11, 2, 11)); + assert_event_emitted!(Event::DelegationKicked(12, 1, 10)); + assert_event_emitted!(Event::DelegationKicked(12, 2, 10)); + assert_event_emitted!(Event::DelegatorLeft(12, 10)); + assert_event_emitted!(Event::DelegatorLeft(11, 11)); + // kicked 11 and 12 and revoked them + assert_eq!(Balances::free_balance(&11), 22); + assert_eq!(Balances::free_balance(&12), 20); + assert!(!ParachainStaking::is_delegator(&11)); + assert!(!ParachainStaking::is_delegator(&12)); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 54); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + }, + Bond { + owner: 9, + amount: 13 + }, + Bond { + owner: 10, + amount: 12 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); + } + }); +} + +#[test] +/// Force revokes candidate state +fn split_candidate_state_kicks_extra_bottom_delegations_without_exit() { + ExtBuilder::default() + .with_balances(vec![(11, 32), (12, 30)]) + .build() + .execute_with(|| { + for i in 11..13 { + let old_delegator_state = Delegator { + id: i, + delegations: OrderedSet::from(vec![ + Bond { + owner: 1, + amount: 10, + }, + Bond { + owner: 2, + amount: 10, + }, + Bond { + owner: 3, + amount: 10, + }, + ]), + total: 30, + requests: PendingDelegationRequests::new(), + status: DelegatorStatus::Active, + }; + >::insert(&i, old_delegator_state); + } + assert_ok!(::Currency::reserve(&11, 32)); + assert_ok!(::Currency::reserve(&12, 30)); + assert_eq!(Balances::reserved_balance(&11), 32); + assert_eq!(Balances::reserved_balance(&12), 30); + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 12, + amount: 10, + }, + Bond { + owner: 11, + amount: 11, + }, + Bond { + owner: 10, + amount: 12, + }, + Bond { + owner: 9, + amount: 13, + }, + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 165, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + // total is 165 * 2 + 20 = 330 + >::put(350); + assert!(ParachainStaking::is_delegator(&11)); + assert!(ParachainStaking::is_delegator(&12)); + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + assert_event_emitted!(Event::DelegationKicked(11, 1, 11)); + assert_event_emitted!(Event::DelegationKicked(11, 2, 11)); + assert_event_emitted!(Event::DelegationKicked(12, 1, 10)); + assert_event_emitted!(Event::DelegationKicked(12, 2, 10)); + assert_event_not_emitted!(Event::DelegatorLeft(12, 10)); + assert_event_not_emitted!(Event::DelegatorLeft(11, 10)); + // kicked 11 and 12 and revoked them + assert_eq!(Balances::free_balance(&11), 22); + assert_eq!(Balances::free_balance(&12), 20); + assert_eq!(Balances::reserved_balance(&11), 10); + assert_eq!(Balances::reserved_balance(&12), 10); + assert!(ParachainStaking::is_delegator(&11)); + assert!(ParachainStaking::is_delegator(&12)); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 54); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + }, + Bond { + owner: 9, + amount: 13 + }, + Bond { + owner: 10, + amount: 12 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); + } + }); +} + +#[test] +fn split_candidate_state_migrates_empty_delegations_correctly() { + ExtBuilder::default() + // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + // .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + .build() + .execute_with(|| { + // set candidate state as per commented out lines above + for i in 1..5 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::new(), + top_delegations: Vec::new(), + bottom_delegations: Vec::new(), + total_counted: 20, + total_backing: 20, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..5 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 0); + assert!(top_delegations.delegations.is_empty()); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 0); + assert!(bottom_delegations.delegations.is_empty()); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 0); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); + } + }); +} + +#[test] +fn split_candidate_state_migrates_partial_top_delegations_correctly() { + ExtBuilder::default() + // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![(3, 1, 10), (4, 1, 10), (3, 2, 10), (4, 2, 10)]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines above + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 10, + }, + Bond { + owner: 4, + amount: 10, + }, + ], + bottom_delegations: Vec::new(), + total_counted: 40, + total_backing: 40, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 20); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 10 + }, + Bond { + owner: 4, + amount: 10 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 0); + assert!(bottom_delegations.delegations.is_empty()); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Partial); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 10); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); + } + }); +} + +#[test] +fn split_candidate_state_migrates_full_top_delegations_correctly() { + ExtBuilder::default() + // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![ + // (3, 1, 10), + // (4, 1, 10), + // (5, 1, 10), + // (6, 1, 10), + // (3, 2, 10), + // (4, 2, 10), + // (5, 2, 10), + // (6, 2, 10), + // ]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 10, + }, + Bond { + owner: 4, + amount: 10, + }, + Bond { + owner: 5, + amount: 10, + }, + Bond { + owner: 6, + amount: 10, + }, + ], + bottom_delegations: Vec::new(), + total_counted: 60, + total_backing: 60, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 40); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 10 + }, + Bond { + owner: 4, + amount: 10 + }, + Bond { + owner: 5, + amount: 10 + }, + Bond { + owner: 6, + amount: 10 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 0); + assert!(bottom_delegations.delegations.is_empty()); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 10); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); + } + }); +} + +#[test] +fn split_candidate_state_migrates_full_top_partial_bottom_delegations_correctly() { + ExtBuilder::default() + // .with_balances(vec![ + // (1, 20), + // (2, 20), + // (3, 38), + // (4, 36), + // (5, 34), + // (6, 32), + // (7, 30), + // (8, 28), + // ]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![ + // (3, 1, 19), + // (4, 1, 18), + // (5, 1, 17), + // (6, 1, 16), + // (7, 1, 15), + // (8, 1, 14), + // (3, 2, 19), + // (4, 2, 18), + // (5, 2, 17), + // (6, 2, 16), + // (7, 2, 15), + // (8, 2, 14), + // ]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 119, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 29); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Partial); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 14); + } + }); +} + +#[test] +fn split_candidate_state_migrates_full_top_and_bottom_delegations_correctly() { + ExtBuilder::default() + // .with_balances(vec![ + // (1, 20), + // (2, 20), + // (3, 38), + // (4, 36), + // (5, 34), + // (6, 32), + // (7, 30), + // (8, 28), + // (9, 26), + // (10, 24), + // ]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![ + // (3, 1, 19), + // (4, 1, 18), + // (5, 1, 17), + // (6, 1, 16), + // (7, 1, 15), + // (8, 1, 14), + // (9, 1, 13), + // (10, 1, 12), + // (3, 2, 19), + // (4, 2, 18), + // (5, 2, 17), + // (6, 2, 16), + // (7, 2, 15), + // (8, 2, 14), + // (9, 2, 13), + // (10, 2, 12), + // ]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 10, + amount: 12, + }, + Bond { + owner: 9, + amount: 13, + }, + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 144, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 54); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + }, + Bond { + owner: 9, + amount: 13 + }, + Bond { + owner: 10, + amount: 12 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); + } + }); +} + +// #[test] +// fn remove_exit_queue_migration_migrates_leaving_candidates() { +// use crate::pallet::ExitQueue2; +// use crate::set::*; +// use crate::*; +// ExtBuilder::default() +// .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) +// .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) +// .build() +// .execute_with(|| { +// // prepare leaving state for all 5 candidates before the migration +// for i in 1..6 { +// // manually change the CollatorState2 status +// >::insert( +// i, +// Collator2 { +// id: i, +// bond: 20, +// nominators: OrderedSet::new(), +// top_nominators: Vec::new(), +// bottom_nominators: Vec::new(), +// total_counted: 20, +// total_backing: 20, +// // set to leaving +// state: CollatorStatus::Leaving(3), +// }, +// ); +// } +// >::put(ExitQ { +// candidates: OrderedSet(vec![1, 2, 3, 4, 5]), +// candidate_schedule: vec![(1, 3), (2, 3), (3, 3), (4, 3), (5, 3)], +// ..Default::default() +// }); +// // execute migration +// migrations::RemoveExitQueue::::on_runtime_upgrade(); +// // check expected candidate state reflects previous state +// for i in 1..6 { +// assert!(>::get(i).is_none()); +// assert_eq!( +// >::get(i).unwrap().state, +// CollatorStatus::Leaving(3) +// ); +// } +// // exit queue should be empty +// assert_eq!(>::get(), ExitQ::default()); +// }); +// } + +// #[test] +// fn remove_exit_queue_migration_migrates_leaving_delegators() { +// use crate::pallet::ExitQueue2; +// use crate::set::*; +// use crate::*; +// ExtBuilder::default() +// .with_balances(vec![(2, 100), (3, 100), (4, 100), (5, 100), (6, 100)]) +// .with_candidates(vec![(2, 20)]) +// .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) +// .build() +// .execute_with(|| { +// // prepare leaving state for all 4 delegators before the migration +// for i in 3..7 { +// >::insert( +// i, +// Nominator2 { +// delegations: OrderedSet(vec![Bond { +// owner: 1, +// amount: 10, +// }]), +// revocations: OrderedSet::new(), +// total: 10, +// scheduled_revocations_count: 0u32, +// scheduled_revocations_total: 0u32.into(), +// status: DelegatorStatus::Leaving(3), +// }, +// ); +// } +// >::put(ExitQ { +// nominators_leaving: OrderedSet(vec![3, 4, 5, 6]), +// nominator_schedule: vec![(3, None, 3), (4, None, 3), (5, None, 3), (6, None, 3)], +// ..Default::default() +// }); +// // execute migration +// migrations::RemoveExitQueue::::on_runtime_upgrade(); +// // check expected delegator state reflects previous state +// for i in 3..7 { +// assert!(>::get(i).is_none()); +// assert_eq!( +// ParachainStaking::delegator_state(i).unwrap().status, +// DelegatorStatus::Leaving(3) +// ); +// } +// // exit queue should be empty +// assert_eq!(>::get(), ExitQ::default()); +// }); +// } + +// #[test] +// fn remove_exit_queue_migration_migrates_delegator_revocations() { +// use crate::pallet::ExitQueue2; +// use crate::set::*; +// use crate::*; +// ExtBuilder::default() +// .with_balances(vec![(2, 100), (3, 100), (4, 100), (5, 100), (6, 100)]) +// .with_candidates(vec![(2, 20)]) +// .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) +// .build() +// .execute_with(|| { +// // prepare leaving state for all 4 delegators before the migration +// for i in 3..7 { +// >::insert( +// i, +// Nominator2 { +// delegations: OrderedSet(vec![Bond { +// owner: 1, +// amount: 10, +// }]), +// revocations: OrderedSet(vec![1]), +// total: 10, +// scheduled_revocations_count: 1u32, +// scheduled_revocations_total: 10u32.into(), +// status: DelegatorStatus::Active, +// }, +// ); +// } +// >::put(ExitQ { +// nominator_schedule: vec![ +// (3, Some(1), 3), +// (4, Some(1), 3), +// (5, Some(1), 3), +// (6, Some(1), 3), +// ], +// ..Default::default() +// }); +// // execute migration +// migrations::RemoveExitQueue::::on_runtime_upgrade(); +// // check expected delegator state reflects previous state +// for i in 3..7 { +// assert!(>::get(i).is_none()); +// assert_eq!( +// ParachainStaking::delegator_state(i) +// .unwrap() +// .requests +// .requests +// .get(&1), +// Some(&DelegationRequest { +// collator: 1, +// amount: 10, +// when_executable: 3, +// action: DelegationChange::Revoke +// }) +// ); +// } +// // exit queue should be empty +// assert_eq!(>::get(), ExitQ::default()); +// }); +// } + +#[test] +fn verify_purge_storage_migration_works() { + use crate::{Points, Round, RoundInfo, Staked}; + ExtBuilder::default().build().execute_with(|| { + // mutate storage similar to if 10 rounds had passed + for i in 1..=10 { + >::insert(i, 100); + >::insert(i, 100); + } + // set the round information to the 10th round + // (we do not use roll_to because the payment logic uses `take` in the code) + >::put(RoundInfo { + current: 10, + first: 45, + length: 5, + }); + // execute the migration + crate::migrations::PurgeStaleStorage::::on_runtime_upgrade(); + // verify that all inserted items are removed except last 2 rounds + for i in 1..=8 { + assert_eq!(>::get(i), 0); + assert_eq!(>::get(i), 0); + } + // last 2 rounds are still stored (necessary for future payouts) + for i in 9..=10 { + assert_eq!(>::get(i), 100); + assert_eq!(>::get(i), 100); + } + }); } diff --git a/pallets/parachain-staking/src/weights.rs b/pallets/parachain-staking/src/weights.rs index 91665366..6a12cf0f 100644 --- a/pallets/parachain-staking/src/weights.rs +++ b/pallets/parachain-staking/src/weights.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2021 PureStake Inc. +// Copyright 2019-2022 PureStake Inc. // This file is part of Moonbeam. // Moonbeam is free software: you can redistribute it and/or modify @@ -44,276 +44,419 @@ #![allow(unused_imports)] use frame_support::{ - traits::Get, - weights::{constants::RocksDbWeight, Weight}, + traits::Get, + weights::{constants::RocksDbWeight, Weight}, }; use sp_std::marker::PhantomData; /// Weight functions needed for parachain_staking. pub trait WeightInfo { - fn set_staking_expectations() -> Weight; - fn set_inflation() -> Weight; - fn set_parachain_bond_account() -> Weight; - fn set_parachain_bond_reserve_percent() -> Weight; - fn set_total_selected() -> Weight; - fn set_collator_commission() -> Weight; - fn set_blocks_per_round() -> Weight; - fn join_candidates(x: u32) -> Weight; - fn leave_candidates(x: u32) -> Weight; - fn go_offline() -> Weight; - fn go_online() -> Weight; - fn candidate_bond_more() -> Weight; - fn candidate_bond_less() -> Weight; - fn nominate(x: u32, y: u32) -> Weight; - fn leave_nominators(x: u32) -> Weight; - fn revoke_nomination() -> Weight; - fn nominator_bond_more() -> Weight; - fn nominator_bond_less() -> Weight; - fn active_on_initialize(x: u32, y: u32) -> Weight; - fn passive_on_initialize() -> Weight; + fn hotfix_remove_delegation_requests(x: u32) -> Weight; + fn hotfix_update_candidate_pool_value(x: u32) -> Weight; + fn set_staking_expectations() -> Weight; + fn set_inflation() -> Weight; + fn set_parachain_bond_account() -> Weight; + fn set_parachain_bond_reserve_percent() -> Weight; + fn set_total_selected() -> Weight; + fn set_collator_commission() -> Weight; + fn set_blocks_per_round() -> Weight; + fn join_candidates(x: u32) -> Weight; + fn schedule_leave_candidates(x: u32) -> Weight; + fn execute_leave_candidates(x: u32) -> Weight; + fn cancel_leave_candidates(x: u32) -> Weight; + fn go_offline() -> Weight; + fn go_online() -> Weight; + fn candidate_bond_more() -> Weight; + fn schedule_candidate_bond_less() -> Weight; + fn execute_candidate_bond_less() -> Weight; + fn cancel_candidate_bond_less() -> Weight; + fn delegate(x: u32, y: u32) -> Weight; + fn schedule_leave_delegators() -> Weight; + fn execute_leave_delegators(x: u32) -> Weight; + fn cancel_leave_delegators() -> Weight; + fn schedule_revoke_delegation() -> Weight; + fn delegator_bond_more() -> Weight; + fn schedule_delegator_bond_less() -> Weight; + fn execute_revoke_delegation() -> Weight; + fn execute_delegator_bond_less() -> Weight; + fn cancel_revoke_delegation() -> Weight; + fn cancel_delegator_bond_less() -> Weight; + fn round_transition_on_initialize(x: u32, y: u32) -> Weight; + fn base_on_initialize() -> Weight; + fn pay_one_collator_reward(y: u32) -> Weight; } /// Weights for parachain_staking using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn set_staking_expectations() -> Weight { - (20_719_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_inflation() -> Weight { - (63_011_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_account() -> Weight { - (20_434_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_reserve_percent() -> Weight { - (19_239_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_total_selected() -> Weight { - (18_402_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_collator_commission() -> Weight { - (18_178_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_blocks_per_round() -> Weight { - (65_939_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn join_candidates(x: u32) -> Weight { - (84_807_000 as Weight) - // Standard Error: 1_000 - .saturating_add((333_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(6 as Weight)) - } - fn leave_candidates(x: u32) -> Weight { - (64_426_000 as Weight) - // Standard Error: 1_000 - .saturating_add((332_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - } - fn go_offline() -> Weight { - (36_577_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn go_online() -> Weight { - (36_134_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn candidate_bond_more() -> Weight { - (59_735_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(6 as Weight)) - } - fn candidate_bond_less() -> Weight { - (59_421_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(6 as Weight)) - } - fn nominate(x: u32, y: u32) -> Weight { - (71_656_000 as Weight) - // Standard Error: 1_000 - .saturating_add((1_049_000 as Weight).saturating_mul(x as Weight)) - // Standard Error: 5_000 - .saturating_add((947_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } - fn leave_nominators(x: u32) -> Weight { - (36_354_000 as Weight) - // Standard Error: 2_000 - .saturating_add((694_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn revoke_nomination() -> Weight { - (37_580_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn nominator_bond_more() -> Weight { - (70_867_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } - fn nominator_bond_less() -> Weight { - (70_857_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } - // If this takes up too much block space, run again on code - // - #743 benchmarks post reward payout optimization were 3x lower per collator, - // 15x lower per nominator - fn active_on_initialize(x: u32, y: u32) -> Weight { - (0 as Weight) - // Standard Error: 299_000 - .saturating_add((208_550_000 as Weight).saturating_mul(x as Weight)) - // Standard Error: 27_000 - .saturating_add((15_580_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(T::DbWeight::get().reads(26 as Weight)) - .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) - .saturating_add(T::DbWeight::get().writes(16 as Weight)) - .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(x as Weight))) - } - fn passive_on_initialize() -> Weight { - (4_913_000 as Weight).saturating_add(T::DbWeight::get().reads(1 as Weight)) - } + fn hotfix_remove_delegation_requests(x: u32) -> Weight { + (0 as Weight) // Standard Error: 3_000 + .saturating_add((8_132_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(x as Weight))) + } + fn hotfix_update_candidate_pool_value(x: u32) -> Weight { + (0 as Weight) // Standard Error: 147_000 + .saturating_add((26_825_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn set_staking_expectations() -> Weight { + (20_719_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_inflation() -> Weight { + (63_011_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_account() -> Weight { + (20_434_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_reserve_percent() -> Weight { + (19_239_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_total_selected() -> Weight { + (18_402_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_collator_commission() -> Weight { + (18_178_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_blocks_per_round() -> Weight { + (65_939_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn join_candidates(x: u32) -> Weight { + (80_619_000 as Weight) // Standard Error: 1_000 + .saturating_add((107_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_candidates(x: u32) -> Weight { + (50_933_000 as Weight) // Standard Error: 1_000 + .saturating_add((108_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn execute_leave_candidates(x: u32) -> Weight { + (8_634_000 as Weight) // Standard Error: 6_000 + .saturating_add((26_979_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) + } + fn cancel_leave_candidates(x: u32) -> Weight { + (43_482_000 as Weight) // Standard Error: 0 + .saturating_add((111_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn go_offline() -> Weight { + (30_778_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn go_online() -> Weight { + (31_178_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn candidate_bond_more() -> Weight { + (53_492_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + } + fn schedule_candidate_bond_less() -> Weight { + (29_393_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn execute_candidate_bond_less() -> Weight { + (62_395_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + } + fn cancel_candidate_bond_less() -> Weight { + (25_564_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn delegate(x: u32, y: u32) -> Weight { + (103_760_000 as Weight) // Standard Error: 12_000 + .saturating_add((198_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3000 + .saturating_add((112_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_delegators() -> Weight { + (30_908_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn execute_leave_delegators(x: u32) -> Weight { + (1_091_000 as Weight) // Standard Error: 14_000 + .saturating_add((37_192_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) + } + fn cancel_leave_delegators() -> Weight { + (26_796_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn schedule_revoke_delegation() -> Weight { + (37_580_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn delegator_bond_more() -> Weight { + (65_757_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn schedule_delegator_bond_less() -> Weight { + (70_859_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn execute_revoke_delegation() -> Weight { + (87_836_000 as Weight) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn execute_delegator_bond_less() -> Weight { + (80_983_000 as Weight) + .saturating_add(T::DbWeight::get().reads(11 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) + } + fn cancel_revoke_delegation() -> Weight { + (37_923_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn cancel_delegator_bond_less() -> Weight { + (70_813_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn round_transition_on_initialize(x: u32, y: u32) -> Weight { + (0 as Weight) // Standard Error: 4_087_000 + // Standard Error: 12_000 + .saturating_add((100_164_000 as Weight).saturating_mul(x as Weight)) + .saturating_add((1_202_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(x as Weight))) + } + fn base_on_initialize() -> Weight { + (4_913_000 as Weight).saturating_add(T::DbWeight::get().reads(1 as Weight)) + } + fn pay_one_collator_reward(y: u32) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((23_284_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(T::DbWeight::get().reads(11 as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(y as Weight))) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(y as Weight))) + } } // For backwards compatibility and tests impl WeightInfo for () { - fn set_staking_expectations() -> Weight { - (20_719_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_inflation() -> Weight { - (63_011_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_account() -> Weight { - (20_434_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_reserve_percent() -> Weight { - (19_239_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_total_selected() -> Weight { - (18_402_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_collator_commission() -> Weight { - (18_178_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_blocks_per_round() -> Weight { - (65_939_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn join_candidates(x: u32) -> Weight { - (84_807_000 as Weight) - // Standard Error: 1_000 - .saturating_add((333_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(6 as Weight)) - } - fn leave_candidates(x: u32) -> Weight { - (64_426_000 as Weight) - // Standard Error: 1_000 - .saturating_add((332_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) - .saturating_add(RocksDbWeight::get().writes(5 as Weight)) - } - fn go_offline() -> Weight { - (36_577_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn go_online() -> Weight { - (36_134_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn candidate_bond_more() -> Weight { - (59_735_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) - .saturating_add(RocksDbWeight::get().writes(6 as Weight)) - } - fn candidate_bond_less() -> Weight { - (59_421_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) - .saturating_add(RocksDbWeight::get().writes(6 as Weight)) - } - fn nominate(x: u32, y: u32) -> Weight { - (71_656_000 as Weight) - // Standard Error: 1_000 - .saturating_add((1_049_000 as Weight).saturating_mul(x as Weight)) - // Standard Error: 5_000 - .saturating_add((947_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(7 as Weight)) - } - fn leave_nominators(x: u32) -> Weight { - (36_354_000 as Weight) - // Standard Error: 2_000 - .saturating_add((694_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn revoke_nomination() -> Weight { - (37_580_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn nominator_bond_more() -> Weight { - (70_867_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(7 as Weight)) - } - fn nominator_bond_less() -> Weight { - (70_857_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(7 as Weight)) - } - // If this takes up too much block space, run again on code - // - #743 benchmarks post reward payout optimization were 3x lower per collator, - // 15x lower per nominator - fn active_on_initialize(x: u32, y: u32) -> Weight { - (0 as Weight) - // Standard Error: 299_000 - .saturating_add((208_550_000 as Weight).saturating_mul(x as Weight)) - // Standard Error: 27_000 - .saturating_add((15_580_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(RocksDbWeight::get().reads(26 as Weight)) - .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) - .saturating_add(RocksDbWeight::get().writes(16 as Weight)) - .saturating_add( - RocksDbWeight::get().writes((4 as Weight).saturating_mul(x as Weight)), - ) - } - fn passive_on_initialize() -> Weight { - (4_913_000 as Weight).saturating_add(RocksDbWeight::get().reads(1 as Weight)) - } + fn hotfix_remove_delegation_requests(x: u32) -> Weight { + (0 as Weight) // Standard Error: 3_000 + .saturating_add((8_132_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(x as Weight))) + } + fn hotfix_update_candidate_pool_value(x: u32) -> Weight { + (0 as Weight) // Standard Error: 147_000 + .saturating_add((26_825_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn set_staking_expectations() -> Weight { + (20_719_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_inflation() -> Weight { + (63_011_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_account() -> Weight { + (20_434_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_reserve_percent() -> Weight { + (19_239_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_total_selected() -> Weight { + (18_402_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_collator_commission() -> Weight { + (18_178_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_blocks_per_round() -> Weight { + (65_939_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn join_candidates(x: u32) -> Weight { + (80_619_000 as Weight) // Standard Error: 1_000 + .saturating_add((107_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_candidates(x: u32) -> Weight { + (50_933_000 as Weight) // Standard Error: 1_000 + .saturating_add((108_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn execute_leave_candidates(x: u32) -> Weight { + (8_634_000 as Weight) // Standard Error: 6_000 + .saturating_add((26_979_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) + } + fn cancel_leave_candidates(x: u32) -> Weight { + (43_482_000 as Weight) // Standard Error: 0 + .saturating_add((111_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn go_offline() -> Weight { + (30_778_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn go_online() -> Weight { + (31_178_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn candidate_bond_more() -> Weight { + (53_492_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } + fn schedule_candidate_bond_less() -> Weight { + (29_393_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn execute_candidate_bond_less() -> Weight { + (62_395_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } + fn cancel_candidate_bond_less() -> Weight { + (25_564_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn delegate(x: u32, y: u32) -> Weight { + (103_760_000 as Weight) // Standard Error: 12_000 + .saturating_add((198_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3000 + .saturating_add((112_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(RocksDbWeight::get().reads(10 as Weight)) + .saturating_add(RocksDbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_delegators() -> Weight { + (30_908_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn execute_leave_delegators(x: u32) -> Weight { + (1_091_000 as Weight) // Standard Error: 14_000 + .saturating_add((37_192_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) + } + fn cancel_leave_delegators() -> Weight { + (26_796_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn schedule_revoke_delegation() -> Weight { + (37_580_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn delegator_bond_more() -> Weight { + (65_757_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn schedule_delegator_bond_less() -> Weight { + (70_859_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn execute_revoke_delegation() -> Weight { + (87_836_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(10 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn execute_delegator_bond_less() -> Weight { + (80_983_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(11 as Weight)) + .saturating_add(RocksDbWeight::get().writes(8 as Weight)) + } + fn cancel_revoke_delegation() -> Weight { + (37_923_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn cancel_delegator_bond_less() -> Weight { + (70_813_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn round_transition_on_initialize(x: u32, y: u32) -> Weight { + (0 as Weight) // Standard Error: 4_087_000 + // Standard Error: 12_000 + .saturating_add((100_164_000 as Weight).saturating_mul(x as Weight)) + .saturating_add((1_202_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(x as Weight))) + } + fn base_on_initialize() -> Weight { + (4_913_000 as Weight).saturating_add(RocksDbWeight::get().reads(1 as Weight)) + } + fn pay_one_collator_reward(y: u32) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((23_284_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(RocksDbWeight::get().reads(11 as Weight)) + .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(y as Weight))) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(y as Weight))) + } } From 7be6e923cc8efd8ff498e25a67ad575ae399b83e Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 00:30:30 +0300 Subject: [PATCH 03/13] fix sp-mvm mock --- pallets/sp-mvm/tests/common/mock.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pallets/sp-mvm/tests/common/mock.rs b/pallets/sp-mvm/tests/common/mock.rs index ad01d64a..730b7811 100644 --- a/pallets/sp-mvm/tests/common/mock.rs +++ b/pallets/sp-mvm/tests/common/mock.rs @@ -9,7 +9,7 @@ use parity_scale_codec::{Decode, Encode}; use system::EnsureRoot; use frame_support::{ PalletId, parameter_types, - traits::Everything, + traits::{Everything, ConstU32}, weights::{Weight, constants::WEIGHT_PER_SECOND}, }; use sp_std::vec; @@ -38,7 +38,7 @@ pub const MILLIUNIT: Balance = 1_000_000_000; pub const MICROUNIT: Balance = 1_000_000; // Implement signature just for test. -#[derive(Eq, PartialEq, Clone, Default, Encode, Decode, TypeInfo, Debug)] +#[derive(Eq, PartialEq, Clone, Encode, Decode, TypeInfo, Debug)] pub struct AnySignature(sr25519::Signature); impl Verify for AnySignature { @@ -108,6 +108,7 @@ impl system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<12>; } // --- gas --- // From e8e1812f04e6273be91d16ce052b5cf177170659 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 02:52:13 +0300 Subject: [PATCH 04/13] cargo fmt, runtime fixes --- pallets/author-mapping/src/lib.rs | 6 +- pallets/author-mapping/src/migrations.rs | 1 - pallets/author-mapping/src/mock.rs | 20 +- pallets/author-mapping/src/tests.rs | 68 +- pallets/currencies/src/mock.rs | 16 +- pallets/parachain-staking/src/benchmarks.rs | 2594 ++--- pallets/parachain-staking/src/inflation.rs | 288 +- pallets/parachain-staking/src/lib.rs | 6402 +++++------ pallets/parachain-staking/src/mock.rs | 758 +- pallets/parachain-staking/src/set.rs | 98 +- pallets/parachain-staking/src/tests.rs | 10524 +++++++++--------- pallets/parachain-staking/src/weights.rs | 812 +- runtime/src/lib.rs | 101 +- runtime/src/tests/parachain/mock_runtime.rs | 25 +- runtime/src/tests/parachain/mod.rs | 7 +- 15 files changed, 10931 insertions(+), 10789 deletions(-) diff --git a/pallets/author-mapping/src/lib.rs b/pallets/author-mapping/src/lib.rs index cd074261..35da6d2a 100644 --- a/pallets/author-mapping/src/lib.rs +++ b/pallets/author-mapping/src/lib.rs @@ -145,9 +145,9 @@ pub mod pallet { Error::::NotYourAssociation ); ensure!( - MappingWithDeposit::::get(&new_author_id).is_none(), - Error::::AlreadyAssociated - ); + MappingWithDeposit::::get(&new_author_id).is_none(), + Error::::AlreadyAssociated + ); MappingWithDeposit::::remove(&old_author_id); MappingWithDeposit::::insert(&new_author_id, &stored_info); diff --git a/pallets/author-mapping/src/migrations.rs b/pallets/author-mapping/src/migrations.rs index 7b71cb19..798778c9 100644 --- a/pallets/author-mapping/src/migrations.rs +++ b/pallets/author-mapping/src/migrations.rs @@ -28,7 +28,6 @@ use sp_std::convert::TryInto; use sp_std::vec::Vec; use nimbus_primitives::NimbusId; - /// Migrates the AuthorMapping's storage map fro mthe insecure Twox64 hasher to the secure /// BlakeTwo hasher. pub struct TwoXToBlake(PhantomData); diff --git a/pallets/author-mapping/src/mock.rs b/pallets/author-mapping/src/mock.rs index f98c6710..b953d026 100644 --- a/pallets/author-mapping/src/mock.rs +++ b/pallets/author-mapping/src/mock.rs @@ -42,18 +42,18 @@ pub enum TestAuthor { Charlie, } impl Default for TestAuthor { - fn default() -> TestAuthor { - TestAuthor::Alice - } + fn default() -> TestAuthor { + TestAuthor::Alice + } } impl Into for TestAuthor { - fn into(self) -> NimbusId { - match self { - Self::Alice => NimbusId::from_slice(&[0u8; 32]).unwrap(), - Self::Bob => NimbusId::from_slice(&[1u8; 32]).unwrap(), - Self::Charlie => NimbusId::from_slice(&[2u8; 32]).unwrap(), - } - } + fn into(self) -> NimbusId { + match self { + Self::Alice => NimbusId::from_slice(&[0u8; 32]).unwrap(), + Self::Bob => NimbusId::from_slice(&[1u8; 32]).unwrap(), + Self::Charlie => NimbusId::from_slice(&[2u8; 32]).unwrap(), + } + } } pub type AccountId = u64; pub type Balance = u128; diff --git a/pallets/author-mapping/src/tests.rs b/pallets/author-mapping/src/tests.rs index 7dd5de6d..0a022edc 100644 --- a/pallets/author-mapping/src/tests.rs +++ b/pallets/author-mapping/src/tests.rs @@ -32,7 +32,10 @@ fn genesis_builder_works() { assert!(System::events().is_empty()); assert_eq!(Balances::free_balance(&1), 900); assert_eq!(Balances::reserved_balance(&1), 100); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), Some(1)); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Alice.into()), + Some(1) + ); assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), None); }) } @@ -50,7 +53,10 @@ fn eligible_account_can_register() { assert_eq!(Balances::free_balance(&2), 900); assert_eq!(Balances::reserved_balance(&2), 100); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), Some(2)); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Bob.into()), + Some(2) + ); assert_eq!( last_event(), @@ -71,7 +77,10 @@ fn cannot_register_without_deposit() { ); assert_eq!(Balances::free_balance(&2), 10); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), None); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Alice.into()), + None + ); }) } @@ -89,7 +98,10 @@ fn double_registration_costs_twice_as_much() { assert_eq!(Balances::free_balance(&2), 900); assert_eq!(Balances::reserved_balance(&2), 100); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), Some(2)); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Bob.into()), + Some(2) + ); assert_eq!( last_event(), @@ -104,7 +116,10 @@ fn double_registration_costs_twice_as_much() { assert_eq!(Balances::free_balance(&2), 800); assert_eq!(Balances::reserved_balance(&2), 200); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), Some(2)); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Alice.into()), + Some(2) + ); assert_eq!( last_event(), @@ -112,7 +127,10 @@ fn double_registration_costs_twice_as_much() { ); // Should still be registered as Bob as well - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), Some(2)); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Bob.into()), + Some(2) + ); }) } @@ -130,7 +148,10 @@ fn registered_account_can_clear() { assert_eq!(Balances::free_balance(&1), 1000); assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Alice.into()), None); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Alice.into()), + None + ); assert_eq!( last_event(), @@ -191,7 +212,10 @@ fn registered_can_rotate() { )); assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Bob.into()), None); - assert_eq!(AuthorMapping::account_id_of(&TestAuthor::Charlie.into()), Some(2)); + assert_eq!( + AuthorMapping::account_id_of(&TestAuthor::Charlie.into()), + Some(2) + ); // Should still only ahve paid a single security deposit assert_eq!(Balances::free_balance(&2), 900); @@ -233,20 +257,20 @@ fn registered_author_cannot_be_rotated_by_non_owner() { #[test] fn rotating_to_the_same_author_id_leaves_registration_in_tact() { - ExtBuilder::default() - .with_balances(vec![(1, 1000)]) - .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) - .build() - .execute_with(|| { - assert_noop!( - AuthorMapping::update_association( - Origin::signed(1), - TestAuthor::Alice.into(), - TestAuthor::Alice.into() - ), - Error::::AlreadyAssociated - ); - }) + ExtBuilder::default() + .with_balances(vec![(1, 1000)]) + .with_mappings(vec![(TestAuthor::Alice.into(), 1)]) + .build() + .execute_with(|| { + assert_noop!( + AuthorMapping::update_association( + Origin::signed(1), + TestAuthor::Alice.into(), + TestAuthor::Alice.into() + ), + Error::::AlreadyAssociated + ); + }) } //TODO Test ideas in case we bring back the narc extrinsic diff --git a/pallets/currencies/src/mock.rs b/pallets/currencies/src/mock.rs index 21bafb18..6dfa8218 100644 --- a/pallets/currencies/src/mock.rs +++ b/pallets/currencies/src/mock.rs @@ -43,7 +43,19 @@ use serde::{Deserialize, Serialize}; use scale_info::TypeInfo; // Currencies id. -#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] +#[derive( + Encode, + Decode, + Eq, + PartialEq, + Copy, + Clone, + RuntimeDebug, + PartialOrd, + Ord, + TypeInfo, + MaxEncodedLen, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum CurrencyId { // Relaychain's currency. @@ -88,7 +100,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<12>; + type MaxConsumers = ConstU32<12>; } type Balance = u128; diff --git a/pallets/parachain-staking/src/benchmarks.rs b/pallets/parachain-staking/src/benchmarks.rs index 6e0da6fa..7ef77e30 100644 --- a/pallets/parachain-staking/src/benchmarks.rs +++ b/pallets/parachain-staking/src/benchmarks.rs @@ -18,8 +18,8 @@ //! Benchmarking use crate::{ - BalanceOf, Call, CandidateBondLessRequest, Config, DelegationChange, DelegationRequest, Pallet, - Range, + BalanceOf, Call, CandidateBondLessRequest, Config, DelegationChange, DelegationRequest, + Pallet, Range, }; use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite}; use frame_support::traits::{Currency, Get, OnFinalize, OnInitialize, ReservableCurrency}; @@ -30,1336 +30,1336 @@ use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; /// Minimum collator candidate stake fn min_candidate_stk() -> BalanceOf { - <::MinCollatorStk as Get>>::get() + <::MinCollatorStk as Get>>::get() } /// Minimum delegator stake fn min_delegator_stk() -> BalanceOf { - <::MinDelegatorStk as Get>>::get() + <::MinDelegatorStk as Get>>::get() } /// Create a funded user. /// Extra + min_candidate_stk is total minted funds /// Returns tuple (id, balance) fn create_funded_user( - string: &'static str, - n: u32, - extra: BalanceOf, + string: &'static str, + n: u32, + extra: BalanceOf, ) -> (T::AccountId, BalanceOf) { - const SEED: u32 = 0; - let user = account(string, n, SEED); - let min_candidate_stk = min_candidate_stk::(); - let total = min_candidate_stk + extra; - T::Currency::make_free_balance_be(&user, total); - T::Currency::issue(total); - (user, total) + const SEED: u32 = 0; + let user = account(string, n, SEED); + let min_candidate_stk = min_candidate_stk::(); + let total = min_candidate_stk + extra; + T::Currency::make_free_balance_be(&user, total); + T::Currency::issue(total); + (user, total) } /// Create a funded delegator. fn create_funded_delegator( - string: &'static str, - n: u32, - extra: BalanceOf, - collator: T::AccountId, - min_bond: bool, - collator_delegator_count: u32, + string: &'static str, + n: u32, + extra: BalanceOf, + collator: T::AccountId, + min_bond: bool, + collator_delegator_count: u32, ) -> Result { - let (user, total) = create_funded_user::(string, n, extra); - let bond = if min_bond { - min_delegator_stk::() - } else { - total - }; - Pallet::::delegate( - RawOrigin::Signed(user.clone()).into(), - collator, - bond, - collator_delegator_count, - 0u32, // first delegation for all calls - )?; - Ok(user) + let (user, total) = create_funded_user::(string, n, extra); + let bond = if min_bond { + min_delegator_stk::() + } else { + total + }; + Pallet::::delegate( + RawOrigin::Signed(user.clone()).into(), + collator, + bond, + collator_delegator_count, + 0u32, // first delegation for all calls + )?; + Ok(user) } /// Create a funded collator. fn create_funded_collator( - string: &'static str, - n: u32, - extra: BalanceOf, - min_bond: bool, - candidate_count: u32, + string: &'static str, + n: u32, + extra: BalanceOf, + min_bond: bool, + candidate_count: u32, ) -> Result { - let (user, total) = create_funded_user::(string, n, extra); - let bond = if min_bond { - min_candidate_stk::() - } else { - total - }; - Pallet::::join_candidates( - RawOrigin::Signed(user.clone()).into(), - bond, - candidate_count, - )?; - Ok(user) + let (user, total) = create_funded_user::(string, n, extra); + let bond = if min_bond { + min_candidate_stk::() + } else { + total + }; + Pallet::::join_candidates( + RawOrigin::Signed(user.clone()).into(), + bond, + candidate_count, + )?; + Ok(user) } /// Run to end block and author fn roll_to_and_author(round_delay: u32, author: T::AccountId) { - let total_rounds = round_delay + 1u32; - let round_length: T::BlockNumber = Pallet::::round().length.into(); - let mut now = >::block_number() + 1u32.into(); - let end = Pallet::::round().first + (round_length * total_rounds.into()); - while now < end { - Pallet::::note_author(author.clone()); - >::on_finalize(>::block_number()); - >::set_block_number( - >::block_number() + 1u32.into(), - ); - >::on_initialize(>::block_number()); - Pallet::::on_initialize(>::block_number()); - now += 1u32.into(); - } + let total_rounds = round_delay + 1u32; + let round_length: T::BlockNumber = Pallet::::round().length.into(); + let mut now = >::block_number() + 1u32.into(); + let end = Pallet::::round().first + (round_length * total_rounds.into()); + while now < end { + Pallet::::note_author(author.clone()); + >::on_finalize(>::block_number()); + >::set_block_number( + >::block_number() + 1u32.into(), + ); + >::on_initialize(>::block_number()); + Pallet::::on_initialize(>::block_number()); + now += 1u32.into(); + } } const USER_SEED: u32 = 999666; benchmarks! { - // HOTFIX BENCHMARK - hotfix_remove_delegation_requests { - let x in 2..<::MaxTopDelegationsPerCandidate as Get>::get() - + <::MaxBottomDelegationsPerCandidate as Get>::get(); - let mut delegators: Vec = Vec::new(); - let collator = create_funded_collator::( - "candidate", - 100, - 0u32.into(), - true, - 1u32 - )?; - let mut col_del_count = 0u32; - for i in 1..x { - let seed = USER_SEED + i; - let delegator = create_funded_delegator::( - "delegator", - seed, - 0u32.into(), - collator.clone(), - true, - col_del_count, - )?; - delegators.push(delegator); - col_del_count += 1u32; - } - }: _(RawOrigin::Root, delegators) - verify { } - - hotfix_update_candidate_pool_value { - let x in 5..200; - let mut candidates: Vec = Vec::new(); - for i in 1..x { - let account = create_funded_collator::( - "candidate", - i + 100, - 0u32.into(), - true, - i - )?; - candidates.push(account); - } - }: _(RawOrigin::Root, candidates) - verify { } - - // MONETARY ORIGIN DISPATCHABLES - - set_staking_expectations { - let stake_range: Range> = Range { - min: 100u32.into(), - ideal: 200u32.into(), - max: 300u32.into(), - }; - }: _(RawOrigin::Root, stake_range) - verify { - assert_eq!(Pallet::::inflation_config().expect, stake_range); - } - - set_inflation { - let inflation_range: Range = Range { - min: Perbill::from_perthousand(1), - ideal: Perbill::from_perthousand(2), - max: Perbill::from_perthousand(3), - }; - - }: _(RawOrigin::Root, inflation_range) - verify { - assert_eq!(Pallet::::inflation_config().annual, inflation_range); - } - - set_parachain_bond_account { - let parachain_bond_account: T::AccountId = account("TEST", 0u32, USER_SEED); - }: _(RawOrigin::Root, parachain_bond_account.clone()) - verify { - assert_eq!(Pallet::::parachain_bond_info().account, parachain_bond_account); - } - - set_parachain_bond_reserve_percent { - }: _(RawOrigin::Root, Percent::from_percent(33)) - verify { - assert_eq!(Pallet::::parachain_bond_info().percent, Percent::from_percent(33)); - } - - // ROOT DISPATCHABLES - - set_total_selected { - Pallet::::set_blocks_per_round(RawOrigin::Root.into(), 100u32)?; - }: _(RawOrigin::Root, 100u32) - verify { - assert_eq!(Pallet::::total_selected(), 100u32); - } - - set_collator_commission {}: _(RawOrigin::Root, Perbill::from_percent(33)) - verify { - assert_eq!(Pallet::::collator_commission(), Perbill::from_percent(33)); - } - - set_blocks_per_round {}: _(RawOrigin::Root, 1200u32) - verify { - assert_eq!(Pallet::::round().length, 1200u32); - } - - // USER DISPATCHABLES - - join_candidates { - let x in 3..1_000; - // Worst Case Complexity is insertion into an ordered list so \exists full list before call - let mut candidate_count = 1u32; - for i in 2..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - true, - candidate_count - )?; - candidate_count += 1u32; - } - let (caller, min_candidate_stk) = create_funded_user::("caller", USER_SEED, 0u32.into()); - }: _(RawOrigin::Signed(caller.clone()), min_candidate_stk, candidate_count) - verify { - assert!(Pallet::::is_candidate(&caller)); - } - - // This call schedules the collator's exit and removes them from the candidate pool - // -> it retains the self-bond and delegator bonds - schedule_leave_candidates { - let x in 3..1_000; - // Worst Case Complexity is removal from an ordered list so \exists full list before call - let mut candidate_count = 1u32; - for i in 2..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - true, - candidate_count - )?; - candidate_count += 1u32; - } - let caller: T::AccountId = create_funded_collator::( - "caller", - USER_SEED, - 0u32.into(), - true, - candidate_count, - )?; - candidate_count += 1u32; - }: _(RawOrigin::Signed(caller.clone()), candidate_count) - verify { - assert!(Pallet::::candidate_info(&caller).unwrap().is_leaving()); - } - - execute_leave_candidates { - // x is total number of delegations for the candidate - let x in 2..(<::MaxTopDelegationsPerCandidate as Get>::get() - + <::MaxBottomDelegationsPerCandidate as Get>::get()); - let candidate: T::AccountId = create_funded_collator::( - "unique_caller", - USER_SEED - 100, - 0u32.into(), - true, - 1u32, - )?; - // 2nd delegation required for all delegators to ensure DelegatorState updated not removed - let second_candidate: T::AccountId = create_funded_collator::( - "unique__caller", - USER_SEED - 99, - 0u32.into(), - true, - 2u32, - )?; - let mut delegators: Vec = Vec::new(); - let mut col_del_count = 0u32; - for i in 1..x { - let seed = USER_SEED + i; - let delegator = create_funded_delegator::( - "delegator", - seed, - min_delegator_stk::(), - candidate.clone(), - true, - col_del_count, - )?; - Pallet::::delegate( - RawOrigin::Signed(delegator.clone()).into(), - second_candidate.clone(), - min_delegator_stk::(), - col_del_count, - 1u32, - )?; - Pallet::::schedule_revoke_delegation( - RawOrigin::Signed(delegator.clone()).into(), - candidate.clone() - )?; - delegators.push(delegator); - col_del_count += 1u32; - } - Pallet::::schedule_leave_candidates( - RawOrigin::Signed(candidate.clone()).into(), - 3u32 - )?; - roll_to_and_author::(2, candidate.clone()); - }: _(RawOrigin::Signed(candidate.clone()), candidate.clone(), col_del_count) - verify { - assert!(Pallet::::candidate_info(&candidate).is_none()); - assert!(Pallet::::candidate_info(&second_candidate).is_some()); - for delegator in delegators { - assert!(Pallet::::is_delegator(&delegator)); - } - } - - cancel_leave_candidates { - let x in 3..1_000; - // Worst Case Complexity is removal from an ordered list so \exists full list before call - let mut candidate_count = 1u32; - for i in 2..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - true, - candidate_count - )?; - candidate_count += 1u32; - } - let caller: T::AccountId = create_funded_collator::( - "caller", - USER_SEED, - 0u32.into(), - true, - candidate_count, - )?; - candidate_count += 1u32; - Pallet::::schedule_leave_candidates( - RawOrigin::Signed(caller.clone()).into(), - candidate_count - )?; - candidate_count -= 1u32; - }: _(RawOrigin::Signed(caller.clone()), candidate_count) - verify { - assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); - } - - go_offline { - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert!(!Pallet::::candidate_info(&caller).unwrap().is_active()); - } - - go_online { - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - Pallet::::go_offline(RawOrigin::Signed(caller.clone()).into())?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); - } - - candidate_bond_more { - let more = min_candidate_stk::(); - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - more, - true, - 1u32, - )?; - }: _(RawOrigin::Signed(caller.clone()), more) - verify { - let expected_bond = more * 2u32.into(); - assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); - } - - schedule_candidate_bond_less { - let min_candidate_stk = min_candidate_stk::(); - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - min_candidate_stk, - false, - 1u32, - )?; - }: _(RawOrigin::Signed(caller.clone()), min_candidate_stk) - verify { - let state = Pallet::::candidate_info(&caller).expect("request bonded less so exists"); - assert_eq!( - state.request, - Some(CandidateBondLessRequest { - amount: min_candidate_stk, - when_executable: 3, - }) - ); - } - - execute_candidate_bond_less { - let min_candidate_stk = min_candidate_stk::(); - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - min_candidate_stk, - false, - 1u32, - )?; - Pallet::::schedule_candidate_bond_less( - RawOrigin::Signed(caller.clone()).into(), - min_candidate_stk - )?; - roll_to_and_author::(2, caller.clone()); - }: { - Pallet::::execute_candidate_bond_less( - RawOrigin::Signed(caller.clone()).into(), - caller.clone() - )?; - } verify { - assert_eq!(T::Currency::reserved_balance(&caller), min_candidate_stk); - } - - cancel_candidate_bond_less { - let min_candidate_stk = min_candidate_stk::(); - let caller: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - min_candidate_stk, - false, - 1u32, - )?; - Pallet::::schedule_candidate_bond_less( - RawOrigin::Signed(caller.clone()).into(), - min_candidate_stk - )?; - }: { - Pallet::::cancel_candidate_bond_less( - RawOrigin::Signed(caller.clone()).into(), - )?; - } verify { - assert!( - Pallet::::candidate_info(&caller).unwrap().request.is_none() - ); - } - - delegate { - let x in 3..<::MaxDelegationsPerDelegator as Get>::get(); - let y in 2..<::MaxTopDelegationsPerCandidate as Get>::get(); - // Worst Case is full of delegations before calling `delegate` - let mut collators: Vec = Vec::new(); - // Initialize MaxDelegationsPerDelegator collator candidates - for i in 2..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - true, - collators.len() as u32 + 1u32, - )?; - collators.push(collator.clone()); - } - let bond = <::MinDelegatorStk as Get>>::get(); - let extra = if (bond * (collators.len() as u32 + 1u32).into()) > min_candidate_stk::() { - (bond * (collators.len() as u32 + 1u32).into()) - min_candidate_stk::() - } else { - 0u32.into() - }; - let (caller, _) = create_funded_user::("caller", USER_SEED, extra.into()); - // Delegation count - let mut del_del_count = 0u32; - // Nominate MaxDelegationsPerDelegators collator candidates - for col in collators.clone() { - Pallet::::delegate( - RawOrigin::Signed(caller.clone()).into(), col, bond, 0u32, del_del_count - )?; - del_del_count += 1u32; - } - // Last collator to be delegated - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - collators.len() as u32 + 1u32, - )?; - // Worst Case Complexity is insertion into an almost full collator - let mut col_del_count = 0u32; - for i in 1..y { - let seed = USER_SEED + i; - let _ = create_funded_delegator::( - "delegator", - seed, - 0u32.into(), - collator.clone(), - true, - col_del_count, - )?; - col_del_count += 1u32; - } - }: _(RawOrigin::Signed(caller.clone()), collator, bond, col_del_count, del_del_count) - verify { - assert!(Pallet::::is_delegator(&caller)); - } - - schedule_leave_delegators { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinDelegatorStk as Get>>::get(); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert!(Pallet::::delegator_state(&caller).unwrap().is_leaving()); - } - - execute_leave_delegators { - let x in 2..<::MaxDelegationsPerDelegator as Get>::get(); - // Worst Case is full of delegations before execute exit - let mut collators: Vec = Vec::new(); - // Initialize MaxDelegationsPerDelegator collator candidates - for i in 1..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - 0u32.into(), - true, - collators.len() as u32 + 1u32 - )?; - collators.push(collator.clone()); - } - let bond = <::MinDelegatorStk as Get>>::get(); - let need = bond * (collators.len() as u32).into(); - let default_minted = min_candidate_stk::(); - let need: BalanceOf = if need > default_minted { - need - default_minted - } else { - 0u32.into() - }; - // Fund the delegator - let (caller, _) = create_funded_user::("caller", USER_SEED, need); - // Delegation count - let mut delegation_count = 0u32; - let author = collators[0].clone(); - // Nominate MaxDelegationsPerDelegators collator candidates - for col in collators { - Pallet::::delegate( - RawOrigin::Signed(caller.clone()).into(), - col, - bond, - 0u32, - delegation_count - )?; - delegation_count += 1u32; - } - Pallet::::schedule_leave_delegators(RawOrigin::Signed(caller.clone()).into())?; - roll_to_and_author::(2, author); - }: _(RawOrigin::Signed(caller.clone()), caller.clone(), delegation_count) - verify { - assert!(Pallet::::delegator_state(&caller).is_none()); - } - - cancel_leave_delegators { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinDelegatorStk as Get>>::get(); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - Pallet::::schedule_leave_delegators(RawOrigin::Signed(caller.clone()).into())?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert!(Pallet::::delegator_state(&caller).unwrap().is_active()); - } - - schedule_revoke_delegation { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinDelegatorStk as Get>>::get(); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - }: _(RawOrigin::Signed(caller.clone()), collator.clone()) - verify { - assert_eq!( - Pallet::::delegator_state(&caller).unwrap().requests().get(&collator), - Some(&DelegationRequest { - collator, - amount: bond, - when_executable: 3, - action: DelegationChange::Revoke - }) - ); - } - - delegator_bond_more { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinDelegatorStk as Get>>::get(); - Pallet::::delegate( - RawOrigin::Signed(caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - }: _(RawOrigin::Signed(caller.clone()), collator.clone(), bond) - verify { - let expected_bond = bond * 2u32.into(); - assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); - } - - schedule_delegator_bond_less { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - total, - 0u32, - 0u32 - )?; - let bond_less = <::MinDelegatorStk as Get>>::get(); - }: _(RawOrigin::Signed(caller.clone()), collator.clone(), bond_less) - verify { - let state = Pallet::::delegator_state(&caller) - .expect("just request bonded less so exists"); - assert_eq!( - state.requests().get(&collator), - Some(&DelegationRequest { - collator, - amount: 5u32.into(), - when_executable: 3, - action: DelegationChange::Decrease - }) - ); - } - - execute_revoke_delegation { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinDelegatorStk as Get>>::get(); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - Pallet::::schedule_revoke_delegation(RawOrigin::Signed( - caller.clone()).into(), - collator.clone() - )?; - roll_to_and_author::(2, collator.clone()); - }: { - Pallet::::execute_delegation_request( - RawOrigin::Signed(caller.clone()).into(), - caller.clone(), - collator.clone() - )?; - } verify { - assert!( - !Pallet::::is_delegator(&caller) - ); - } - - execute_delegator_bond_less { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - total, - 0u32, - 0u32 - )?; - let bond_less = <::MinDelegatorStk as Get>>::get(); - Pallet::::schedule_delegator_bond_less( - RawOrigin::Signed(caller.clone()).into(), - collator.clone(), - bond_less - )?; - roll_to_and_author::(2, collator.clone()); - }: { - Pallet::::execute_delegation_request( - RawOrigin::Signed(caller.clone()).into(), - caller.clone(), - collator.clone() - )?; - } verify { - let expected = total - bond_less; - assert_eq!(T::Currency::reserved_balance(&caller), expected); - } - - cancel_revoke_delegation { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); - let bond = <::MinDelegatorStk as Get>>::get(); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - bond, - 0u32, - 0u32 - )?; - Pallet::::schedule_revoke_delegation( - RawOrigin::Signed(caller.clone()).into(), - collator.clone() - )?; - }: { - Pallet::::cancel_delegation_request( - RawOrigin::Signed(caller.clone()).into(), - collator.clone() - )?; - } verify { - assert!( - Pallet::::delegator_state(&caller).unwrap().requests().get(&collator).is_none() - ); - } - - cancel_delegator_bond_less { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); - Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - collator.clone(), - total, - 0u32, - 0u32 - )?; - let bond_less = <::MinDelegatorStk as Get>>::get(); - Pallet::::schedule_delegator_bond_less( - RawOrigin::Signed(caller.clone()).into(), - collator.clone(), - bond_less - )?; - roll_to_and_author::(2, collator.clone()); - }: { - Pallet::::cancel_delegation_request( - RawOrigin::Signed(caller.clone()).into(), - collator.clone() - )?; - } verify { - assert!( - Pallet::::delegator_state(&caller) - .unwrap() - .requests() - .get(&collator) - .is_none() - ); - } - - // ON_INITIALIZE - - round_transition_on_initialize { - // TOTAL SELECTED COLLATORS PER ROUND - let x in 1..28; - // DELEGATIONS - let y in 0..(<::MaxTopDelegationsPerCandidate as Get>::get() * 28); - let max_delegators_per_collator = - <::MaxTopDelegationsPerCandidate as Get>::get(); - let max_delegations = x * max_delegators_per_collator; - // y should depend on x but cannot directly, we overwrite y here if necessary to bound it - let total_delegations: u32 = if max_delegations < y { max_delegations } else { y }; - // INITIALIZE RUNTIME STATE - let high_inflation: Range = Range { - min: Perbill::one(), - ideal: Perbill::one(), - max: Perbill::one(), - }; - Pallet::::set_inflation(RawOrigin::Root.into(), high_inflation.clone())?; - Pallet::::set_total_selected(RawOrigin::Root.into(), 28u32)?; - // INITIALIZE COLLATOR STATE - let mut collators: Vec = Vec::new(); - let mut collator_count = 1u32; - for i in 0..x { - let seed = USER_SEED - i; - let collator = create_funded_collator::( - "collator", - seed, - min_candidate_stk::() * 1_000_000u32.into(), - true, - collator_count - )?; - collators.push(collator); - collator_count += 1u32; - } - // STORE starting balances for all collators - let collator_starting_balances: Vec<( - T::AccountId, - <::Currency as Currency>::Balance - )> = collators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); - // INITIALIZE DELEGATIONS - let mut col_del_count: BTreeMap = BTreeMap::new(); - collators.iter().for_each(|x| { - col_del_count.insert(x.clone(), 0u32); - }); - let mut delegators: Vec = Vec::new(); - let mut remaining_delegations = if total_delegations > max_delegators_per_collator { - for j in 1..(max_delegators_per_collator + 1) { - let seed = USER_SEED + j; - let delegator = create_funded_delegator::( - "delegator", - seed, - min_candidate_stk::() * 1_000_000u32.into(), - collators[0].clone(), - true, - delegators.len() as u32, - )?; - delegators.push(delegator); - } - total_delegations - max_delegators_per_collator - } else { - for j in 1..(total_delegations + 1) { - let seed = USER_SEED + j; - let delegator = create_funded_delegator::( - "delegator", - seed, - min_candidate_stk::() * 1_000_000u32.into(), - collators[0].clone(), - true, - delegators.len() as u32, - )?; - delegators.push(delegator); - } - 0u32 - }; - col_del_count.insert(collators[0].clone(), delegators.len() as u32); - // FILL remaining delegations - if remaining_delegations > 0 { - for (col, n_count) in col_del_count.iter_mut() { - if n_count < &mut (delegators.len() as u32) { - // assumes delegators.len() <= MaxTopDelegationsPerCandidate - let mut open_spots = delegators.len() as u32 - *n_count; - while open_spots > 0 && remaining_delegations > 0 { - let caller = delegators[open_spots as usize - 1usize].clone(); - if let Ok(_) = Pallet::::delegate(RawOrigin::Signed( - caller.clone()).into(), - col.clone(), - <::MinDelegatorStk as Get>>::get(), - *n_count, - collators.len() as u32, // overestimate - ) { - *n_count += 1; - remaining_delegations -= 1; - } - open_spots -= 1; - } - } - if remaining_delegations == 0 { - break; - } - } - } - // STORE starting balances for all delegators - let delegator_starting_balances: Vec<( - T::AccountId, - <::Currency as Currency>::Balance - )> = delegators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); - // PREPARE RUN_TO_BLOCK LOOP - let before_running_round_index = Pallet::::round().current; - let round_length: T::BlockNumber = Pallet::::round().length.into(); - let reward_delay = <::RewardPaymentDelay as Get>::get() + 2u32; - let mut now = >::block_number() + 1u32.into(); - let mut counter = 0usize; - let end = Pallet::::round().first + (round_length * reward_delay.into()); - // SET collators as authors for blocks from now - end - while now < end { - let author = collators[counter % collators.len()].clone(); - Pallet::::note_author(author); - >::on_finalize(>::block_number()); - >::set_block_number( - >::block_number() + 1u32.into() - ); - >::on_initialize(>::block_number()); - Pallet::::on_initialize(>::block_number()); - now += 1u32.into(); - counter += 1usize; - } - Pallet::::note_author(collators[counter % collators.len()].clone()); - >::on_finalize(>::block_number()); - >::set_block_number( - >::block_number() + 1u32.into() - ); - >::on_initialize(>::block_number()); - }: { Pallet::::on_initialize(>::block_number()); } - verify { - // Collators have been paid - for (col, initial) in collator_starting_balances { - assert!(T::Currency::free_balance(&col) > initial); - } - // Nominators have been paid - for (col, initial) in delegator_starting_balances { - assert!(T::Currency::free_balance(&col) > initial); - } - // Round transitions - assert_eq!(Pallet::::round().current, before_running_round_index + reward_delay); - } - - pay_one_collator_reward { - // y controls number of delegators - // TODO: mock.rs sets MaxTopDelegationsPerCandidate to 4, which is too low for this test to be - // meaningful. we use a higher value here, which works so long as we don't invoke any of - // pallet_staking's logic which uses MaxTopDelegationsPerCandidate as a constraint. this is - // brittle, to say the least... - let y in 0..2000; - - // must come after 'let foo in 0..` statements for macro - use crate::{ - DelayedPayout, DelayedPayouts, AtStake, CollatorSnapshot, Bond, Points, - AwardedPts, - }; - - let before_running_round_index = Pallet::::round().current; - let initial_stake_amount = min_candidate_stk::() * 1_000_000u32.into(); - - let mut total_staked = 0u32.into(); - - // initialize our single collator - let sole_collator = create_funded_collator::( - "collator", - 0, - initial_stake_amount, - true, - 1u32, - )?; - total_staked += initial_stake_amount; - - // generate funded collator accounts - let mut delegators: Vec = Vec::new(); - for i in 0..y { - let seed = USER_SEED + i; - let delegator = create_funded_delegator::( - "delegator", - seed, - initial_stake_amount, - sole_collator.clone(), - true, - delegators.len() as u32, - )?; - delegators.push(delegator); - total_staked += initial_stake_amount; - } - - // rather than roll through rounds in order to initialize the storage we want, we set it - // directly and then call pay_one_collator_reward directly. - - let round_for_payout = 5; - >::insert(&round_for_payout, DelayedPayout { - // NOTE: round_issuance is not correct here, but it doesn't seem to cause problems - round_issuance: 1000u32.into(), - total_staking_reward: total_staked, - collator_commission: Perbill::from_rational(1u32, 100u32), - }); - - let mut delegations: Vec>> = Vec::new(); - for delegator in &delegators { - delegations.push(Bond { - owner: delegator.clone(), - amount: 100u32.into(), - }); - } - - >::insert(round_for_payout, &sole_collator, CollatorSnapshot { - bond: 1_000u32.into(), - delegations, - total: 1_000_000u32.into(), - }); - - >::insert(round_for_payout, 100); - >::insert(round_for_payout, &sole_collator, 20); - - }: { - let round_for_payout = 5; - // TODO: this is an extra read right here (we should whitelist it?) - let payout_info = Pallet::::delayed_payouts(round_for_payout).expect("payout expected"); - let result = Pallet::::pay_one_collator_reward(round_for_payout, payout_info); - assert!(result.0.is_some()); // TODO: how to keep this in scope so it can be done in verify block? - } - verify { - // collator should have been paid - assert!( - T::Currency::free_balance(&sole_collator) > initial_stake_amount, - "collator should have been paid in pay_one_collator_reward" - ); - // nominators should have been paid - for delegator in &delegators { - assert!( - T::Currency::free_balance(&delegator) > initial_stake_amount, - "delegator should have been paid in pay_one_collator_reward" - ); - } - } - - base_on_initialize { - let collator: T::AccountId = create_funded_collator::( - "collator", - USER_SEED, - 0u32.into(), - true, - 1u32 - )?; - let start = >::block_number(); - Pallet::::note_author(collator.clone()); - >::on_finalize(start); - >::set_block_number( - start + 1u32.into() - ); - let end = >::block_number(); - >::on_initialize(end); - }: { Pallet::::on_initialize(end); } - verify { - // Round transitions - assert_eq!(start + 1u32.into(), end); - } + // HOTFIX BENCHMARK + hotfix_remove_delegation_requests { + let x in 2..<::MaxTopDelegationsPerCandidate as Get>::get() + + <::MaxBottomDelegationsPerCandidate as Get>::get(); + let mut delegators: Vec = Vec::new(); + let collator = create_funded_collator::( + "candidate", + 100, + 0u32.into(), + true, + 1u32 + )?; + let mut col_del_count = 0u32; + for i in 1..x { + let seed = USER_SEED + i; + let delegator = create_funded_delegator::( + "delegator", + seed, + 0u32.into(), + collator.clone(), + true, + col_del_count, + )?; + delegators.push(delegator); + col_del_count += 1u32; + } + }: _(RawOrigin::Root, delegators) + verify { } + + hotfix_update_candidate_pool_value { + let x in 5..200; + let mut candidates: Vec = Vec::new(); + for i in 1..x { + let account = create_funded_collator::( + "candidate", + i + 100, + 0u32.into(), + true, + i + )?; + candidates.push(account); + } + }: _(RawOrigin::Root, candidates) + verify { } + + // MONETARY ORIGIN DISPATCHABLES + + set_staking_expectations { + let stake_range: Range> = Range { + min: 100u32.into(), + ideal: 200u32.into(), + max: 300u32.into(), + }; + }: _(RawOrigin::Root, stake_range) + verify { + assert_eq!(Pallet::::inflation_config().expect, stake_range); + } + + set_inflation { + let inflation_range: Range = Range { + min: Perbill::from_perthousand(1), + ideal: Perbill::from_perthousand(2), + max: Perbill::from_perthousand(3), + }; + + }: _(RawOrigin::Root, inflation_range) + verify { + assert_eq!(Pallet::::inflation_config().annual, inflation_range); + } + + set_parachain_bond_account { + let parachain_bond_account: T::AccountId = account("TEST", 0u32, USER_SEED); + }: _(RawOrigin::Root, parachain_bond_account.clone()) + verify { + assert_eq!(Pallet::::parachain_bond_info().account, parachain_bond_account); + } + + set_parachain_bond_reserve_percent { + }: _(RawOrigin::Root, Percent::from_percent(33)) + verify { + assert_eq!(Pallet::::parachain_bond_info().percent, Percent::from_percent(33)); + } + + // ROOT DISPATCHABLES + + set_total_selected { + Pallet::::set_blocks_per_round(RawOrigin::Root.into(), 100u32)?; + }: _(RawOrigin::Root, 100u32) + verify { + assert_eq!(Pallet::::total_selected(), 100u32); + } + + set_collator_commission {}: _(RawOrigin::Root, Perbill::from_percent(33)) + verify { + assert_eq!(Pallet::::collator_commission(), Perbill::from_percent(33)); + } + + set_blocks_per_round {}: _(RawOrigin::Root, 1200u32) + verify { + assert_eq!(Pallet::::round().length, 1200u32); + } + + // USER DISPATCHABLES + + join_candidates { + let x in 3..1_000; + // Worst Case Complexity is insertion into an ordered list so \exists full list before call + let mut candidate_count = 1u32; + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + candidate_count + )?; + candidate_count += 1u32; + } + let (caller, min_candidate_stk) = create_funded_user::("caller", USER_SEED, 0u32.into()); + }: _(RawOrigin::Signed(caller.clone()), min_candidate_stk, candidate_count) + verify { + assert!(Pallet::::is_candidate(&caller)); + } + + // This call schedules the collator's exit and removes them from the candidate pool + // -> it retains the self-bond and delegator bonds + schedule_leave_candidates { + let x in 3..1_000; + // Worst Case Complexity is removal from an ordered list so \exists full list before call + let mut candidate_count = 1u32; + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + candidate_count + )?; + candidate_count += 1u32; + } + let caller: T::AccountId = create_funded_collator::( + "caller", + USER_SEED, + 0u32.into(), + true, + candidate_count, + )?; + candidate_count += 1u32; + }: _(RawOrigin::Signed(caller.clone()), candidate_count) + verify { + assert!(Pallet::::candidate_info(&caller).unwrap().is_leaving()); + } + + execute_leave_candidates { + // x is total number of delegations for the candidate + let x in 2..(<::MaxTopDelegationsPerCandidate as Get>::get() + + <::MaxBottomDelegationsPerCandidate as Get>::get()); + let candidate: T::AccountId = create_funded_collator::( + "unique_caller", + USER_SEED - 100, + 0u32.into(), + true, + 1u32, + )?; + // 2nd delegation required for all delegators to ensure DelegatorState updated not removed + let second_candidate: T::AccountId = create_funded_collator::( + "unique__caller", + USER_SEED - 99, + 0u32.into(), + true, + 2u32, + )?; + let mut delegators: Vec = Vec::new(); + let mut col_del_count = 0u32; + for i in 1..x { + let seed = USER_SEED + i; + let delegator = create_funded_delegator::( + "delegator", + seed, + min_delegator_stk::(), + candidate.clone(), + true, + col_del_count, + )?; + Pallet::::delegate( + RawOrigin::Signed(delegator.clone()).into(), + second_candidate.clone(), + min_delegator_stk::(), + col_del_count, + 1u32, + )?; + Pallet::::schedule_revoke_delegation( + RawOrigin::Signed(delegator.clone()).into(), + candidate.clone() + )?; + delegators.push(delegator); + col_del_count += 1u32; + } + Pallet::::schedule_leave_candidates( + RawOrigin::Signed(candidate.clone()).into(), + 3u32 + )?; + roll_to_and_author::(2, candidate.clone()); + }: _(RawOrigin::Signed(candidate.clone()), candidate.clone(), col_del_count) + verify { + assert!(Pallet::::candidate_info(&candidate).is_none()); + assert!(Pallet::::candidate_info(&second_candidate).is_some()); + for delegator in delegators { + assert!(Pallet::::is_delegator(&delegator)); + } + } + + cancel_leave_candidates { + let x in 3..1_000; + // Worst Case Complexity is removal from an ordered list so \exists full list before call + let mut candidate_count = 1u32; + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + candidate_count + )?; + candidate_count += 1u32; + } + let caller: T::AccountId = create_funded_collator::( + "caller", + USER_SEED, + 0u32.into(), + true, + candidate_count, + )?; + candidate_count += 1u32; + Pallet::::schedule_leave_candidates( + RawOrigin::Signed(caller.clone()).into(), + candidate_count + )?; + candidate_count -= 1u32; + }: _(RawOrigin::Signed(caller.clone()), candidate_count) + verify { + assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); + } + + go_offline { + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(!Pallet::::candidate_info(&caller).unwrap().is_active()); + } + + go_online { + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + Pallet::::go_offline(RawOrigin::Signed(caller.clone()).into())?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(Pallet::::candidate_info(&caller).unwrap().is_active()); + } + + candidate_bond_more { + let more = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + more, + true, + 1u32, + )?; + }: _(RawOrigin::Signed(caller.clone()), more) + verify { + let expected_bond = more * 2u32.into(); + assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); + } + + schedule_candidate_bond_less { + let min_candidate_stk = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + min_candidate_stk, + false, + 1u32, + )?; + }: _(RawOrigin::Signed(caller.clone()), min_candidate_stk) + verify { + let state = Pallet::::candidate_info(&caller).expect("request bonded less so exists"); + assert_eq!( + state.request, + Some(CandidateBondLessRequest { + amount: min_candidate_stk, + when_executable: 3, + }) + ); + } + + execute_candidate_bond_less { + let min_candidate_stk = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + min_candidate_stk, + false, + 1u32, + )?; + Pallet::::schedule_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + min_candidate_stk + )?; + roll_to_and_author::(2, caller.clone()); + }: { + Pallet::::execute_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + caller.clone() + )?; + } verify { + assert_eq!(T::Currency::reserved_balance(&caller), min_candidate_stk); + } + + cancel_candidate_bond_less { + let min_candidate_stk = min_candidate_stk::(); + let caller: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + min_candidate_stk, + false, + 1u32, + )?; + Pallet::::schedule_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + min_candidate_stk + )?; + }: { + Pallet::::cancel_candidate_bond_less( + RawOrigin::Signed(caller.clone()).into(), + )?; + } verify { + assert!( + Pallet::::candidate_info(&caller).unwrap().request.is_none() + ); + } + + delegate { + let x in 3..<::MaxDelegationsPerDelegator as Get>::get(); + let y in 2..<::MaxTopDelegationsPerCandidate as Get>::get(); + // Worst Case is full of delegations before calling `delegate` + let mut collators: Vec = Vec::new(); + // Initialize MaxDelegationsPerDelegator collator candidates + for i in 2..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + collators.len() as u32 + 1u32, + )?; + collators.push(collator.clone()); + } + let bond = <::MinDelegatorStk as Get>>::get(); + let extra = if (bond * (collators.len() as u32 + 1u32).into()) > min_candidate_stk::() { + (bond * (collators.len() as u32 + 1u32).into()) - min_candidate_stk::() + } else { + 0u32.into() + }; + let (caller, _) = create_funded_user::("caller", USER_SEED, extra.into()); + // Delegation count + let mut del_del_count = 0u32; + // Nominate MaxDelegationsPerDelegators collator candidates + for col in collators.clone() { + Pallet::::delegate( + RawOrigin::Signed(caller.clone()).into(), col, bond, 0u32, del_del_count + )?; + del_del_count += 1u32; + } + // Last collator to be delegated + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + collators.len() as u32 + 1u32, + )?; + // Worst Case Complexity is insertion into an almost full collator + let mut col_del_count = 0u32; + for i in 1..y { + let seed = USER_SEED + i; + let _ = create_funded_delegator::( + "delegator", + seed, + 0u32.into(), + collator.clone(), + true, + col_del_count, + )?; + col_del_count += 1u32; + } + }: _(RawOrigin::Signed(caller.clone()), collator, bond, col_del_count, del_del_count) + verify { + assert!(Pallet::::is_delegator(&caller)); + } + + schedule_leave_delegators { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(Pallet::::delegator_state(&caller).unwrap().is_leaving()); + } + + execute_leave_delegators { + let x in 2..<::MaxDelegationsPerDelegator as Get>::get(); + // Worst Case is full of delegations before execute exit + let mut collators: Vec = Vec::new(); + // Initialize MaxDelegationsPerDelegator collator candidates + for i in 1..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + 0u32.into(), + true, + collators.len() as u32 + 1u32 + )?; + collators.push(collator.clone()); + } + let bond = <::MinDelegatorStk as Get>>::get(); + let need = bond * (collators.len() as u32).into(); + let default_minted = min_candidate_stk::(); + let need: BalanceOf = if need > default_minted { + need - default_minted + } else { + 0u32.into() + }; + // Fund the delegator + let (caller, _) = create_funded_user::("caller", USER_SEED, need); + // Delegation count + let mut delegation_count = 0u32; + let author = collators[0].clone(); + // Nominate MaxDelegationsPerDelegators collator candidates + for col in collators { + Pallet::::delegate( + RawOrigin::Signed(caller.clone()).into(), + col, + bond, + 0u32, + delegation_count + )?; + delegation_count += 1u32; + } + Pallet::::schedule_leave_delegators(RawOrigin::Signed(caller.clone()).into())?; + roll_to_and_author::(2, author); + }: _(RawOrigin::Signed(caller.clone()), caller.clone(), delegation_count) + verify { + assert!(Pallet::::delegator_state(&caller).is_none()); + } + + cancel_leave_delegators { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + Pallet::::schedule_leave_delegators(RawOrigin::Signed(caller.clone()).into())?; + }: _(RawOrigin::Signed(caller.clone())) + verify { + assert!(Pallet::::delegator_state(&caller).unwrap().is_active()); + } + + schedule_revoke_delegation { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + }: _(RawOrigin::Signed(caller.clone()), collator.clone()) + verify { + assert_eq!( + Pallet::::delegator_state(&caller).unwrap().requests().get(&collator), + Some(&DelegationRequest { + collator, + amount: bond, + when_executable: 3, + action: DelegationChange::Revoke + }) + ); + } + + delegator_bond_more { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate( + RawOrigin::Signed(caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + }: _(RawOrigin::Signed(caller.clone()), collator.clone(), bond) + verify { + let expected_bond = bond * 2u32.into(); + assert_eq!(T::Currency::reserved_balance(&caller), expected_bond); + } + + schedule_delegator_bond_less { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + total, + 0u32, + 0u32 + )?; + let bond_less = <::MinDelegatorStk as Get>>::get(); + }: _(RawOrigin::Signed(caller.clone()), collator.clone(), bond_less) + verify { + let state = Pallet::::delegator_state(&caller) + .expect("just request bonded less so exists"); + assert_eq!( + state.requests().get(&collator), + Some(&DelegationRequest { + collator, + amount: 5u32.into(), + when_executable: 3, + action: DelegationChange::Decrease + }) + ); + } + + execute_revoke_delegation { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + Pallet::::schedule_revoke_delegation(RawOrigin::Signed( + caller.clone()).into(), + collator.clone() + )?; + roll_to_and_author::(2, collator.clone()); + }: { + Pallet::::execute_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + caller.clone(), + collator.clone() + )?; + } verify { + assert!( + !Pallet::::is_delegator(&caller) + ); + } + + execute_delegator_bond_less { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + total, + 0u32, + 0u32 + )?; + let bond_less = <::MinDelegatorStk as Get>>::get(); + Pallet::::schedule_delegator_bond_less( + RawOrigin::Signed(caller.clone()).into(), + collator.clone(), + bond_less + )?; + roll_to_and_author::(2, collator.clone()); + }: { + Pallet::::execute_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + caller.clone(), + collator.clone() + )?; + } verify { + let expected = total - bond_less; + assert_eq!(T::Currency::reserved_balance(&caller), expected); + } + + cancel_revoke_delegation { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, _) = create_funded_user::("caller", USER_SEED, 0u32.into()); + let bond = <::MinDelegatorStk as Get>>::get(); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + bond, + 0u32, + 0u32 + )?; + Pallet::::schedule_revoke_delegation( + RawOrigin::Signed(caller.clone()).into(), + collator.clone() + )?; + }: { + Pallet::::cancel_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + collator.clone() + )?; + } verify { + assert!( + Pallet::::delegator_state(&caller).unwrap().requests().get(&collator).is_none() + ); + } + + cancel_delegator_bond_less { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let (caller, total) = create_funded_user::("caller", USER_SEED, 0u32.into()); + Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + collator.clone(), + total, + 0u32, + 0u32 + )?; + let bond_less = <::MinDelegatorStk as Get>>::get(); + Pallet::::schedule_delegator_bond_less( + RawOrigin::Signed(caller.clone()).into(), + collator.clone(), + bond_less + )?; + roll_to_and_author::(2, collator.clone()); + }: { + Pallet::::cancel_delegation_request( + RawOrigin::Signed(caller.clone()).into(), + collator.clone() + )?; + } verify { + assert!( + Pallet::::delegator_state(&caller) + .unwrap() + .requests() + .get(&collator) + .is_none() + ); + } + + // ON_INITIALIZE + + round_transition_on_initialize { + // TOTAL SELECTED COLLATORS PER ROUND + let x in 1..28; + // DELEGATIONS + let y in 0..(<::MaxTopDelegationsPerCandidate as Get>::get() * 28); + let max_delegators_per_collator = + <::MaxTopDelegationsPerCandidate as Get>::get(); + let max_delegations = x * max_delegators_per_collator; + // y should depend on x but cannot directly, we overwrite y here if necessary to bound it + let total_delegations: u32 = if max_delegations < y { max_delegations } else { y }; + // INITIALIZE RUNTIME STATE + let high_inflation: Range = Range { + min: Perbill::one(), + ideal: Perbill::one(), + max: Perbill::one(), + }; + Pallet::::set_inflation(RawOrigin::Root.into(), high_inflation.clone())?; + Pallet::::set_total_selected(RawOrigin::Root.into(), 28u32)?; + // INITIALIZE COLLATOR STATE + let mut collators: Vec = Vec::new(); + let mut collator_count = 1u32; + for i in 0..x { + let seed = USER_SEED - i; + let collator = create_funded_collator::( + "collator", + seed, + min_candidate_stk::() * 1_000_000u32.into(), + true, + collator_count + )?; + collators.push(collator); + collator_count += 1u32; + } + // STORE starting balances for all collators + let collator_starting_balances: Vec<( + T::AccountId, + <::Currency as Currency>::Balance + )> = collators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); + // INITIALIZE DELEGATIONS + let mut col_del_count: BTreeMap = BTreeMap::new(); + collators.iter().for_each(|x| { + col_del_count.insert(x.clone(), 0u32); + }); + let mut delegators: Vec = Vec::new(); + let mut remaining_delegations = if total_delegations > max_delegators_per_collator { + for j in 1..(max_delegators_per_collator + 1) { + let seed = USER_SEED + j; + let delegator = create_funded_delegator::( + "delegator", + seed, + min_candidate_stk::() * 1_000_000u32.into(), + collators[0].clone(), + true, + delegators.len() as u32, + )?; + delegators.push(delegator); + } + total_delegations - max_delegators_per_collator + } else { + for j in 1..(total_delegations + 1) { + let seed = USER_SEED + j; + let delegator = create_funded_delegator::( + "delegator", + seed, + min_candidate_stk::() * 1_000_000u32.into(), + collators[0].clone(), + true, + delegators.len() as u32, + )?; + delegators.push(delegator); + } + 0u32 + }; + col_del_count.insert(collators[0].clone(), delegators.len() as u32); + // FILL remaining delegations + if remaining_delegations > 0 { + for (col, n_count) in col_del_count.iter_mut() { + if n_count < &mut (delegators.len() as u32) { + // assumes delegators.len() <= MaxTopDelegationsPerCandidate + let mut open_spots = delegators.len() as u32 - *n_count; + while open_spots > 0 && remaining_delegations > 0 { + let caller = delegators[open_spots as usize - 1usize].clone(); + if let Ok(_) = Pallet::::delegate(RawOrigin::Signed( + caller.clone()).into(), + col.clone(), + <::MinDelegatorStk as Get>>::get(), + *n_count, + collators.len() as u32, // overestimate + ) { + *n_count += 1; + remaining_delegations -= 1; + } + open_spots -= 1; + } + } + if remaining_delegations == 0 { + break; + } + } + } + // STORE starting balances for all delegators + let delegator_starting_balances: Vec<( + T::AccountId, + <::Currency as Currency>::Balance + )> = delegators.iter().map(|x| (x.clone(), T::Currency::free_balance(&x))).collect(); + // PREPARE RUN_TO_BLOCK LOOP + let before_running_round_index = Pallet::::round().current; + let round_length: T::BlockNumber = Pallet::::round().length.into(); + let reward_delay = <::RewardPaymentDelay as Get>::get() + 2u32; + let mut now = >::block_number() + 1u32.into(); + let mut counter = 0usize; + let end = Pallet::::round().first + (round_length * reward_delay.into()); + // SET collators as authors for blocks from now - end + while now < end { + let author = collators[counter % collators.len()].clone(); + Pallet::::note_author(author); + >::on_finalize(>::block_number()); + >::set_block_number( + >::block_number() + 1u32.into() + ); + >::on_initialize(>::block_number()); + Pallet::::on_initialize(>::block_number()); + now += 1u32.into(); + counter += 1usize; + } + Pallet::::note_author(collators[counter % collators.len()].clone()); + >::on_finalize(>::block_number()); + >::set_block_number( + >::block_number() + 1u32.into() + ); + >::on_initialize(>::block_number()); + }: { Pallet::::on_initialize(>::block_number()); } + verify { + // Collators have been paid + for (col, initial) in collator_starting_balances { + assert!(T::Currency::free_balance(&col) > initial); + } + // Nominators have been paid + for (col, initial) in delegator_starting_balances { + assert!(T::Currency::free_balance(&col) > initial); + } + // Round transitions + assert_eq!(Pallet::::round().current, before_running_round_index + reward_delay); + } + + pay_one_collator_reward { + // y controls number of delegators + // TODO: mock.rs sets MaxTopDelegationsPerCandidate to 4, which is too low for this test to be + // meaningful. we use a higher value here, which works so long as we don't invoke any of + // pallet_staking's logic which uses MaxTopDelegationsPerCandidate as a constraint. this is + // brittle, to say the least... + let y in 0..2000; + + // must come after 'let foo in 0..` statements for macro + use crate::{ + DelayedPayout, DelayedPayouts, AtStake, CollatorSnapshot, Bond, Points, + AwardedPts, + }; + + let before_running_round_index = Pallet::::round().current; + let initial_stake_amount = min_candidate_stk::() * 1_000_000u32.into(); + + let mut total_staked = 0u32.into(); + + // initialize our single collator + let sole_collator = create_funded_collator::( + "collator", + 0, + initial_stake_amount, + true, + 1u32, + )?; + total_staked += initial_stake_amount; + + // generate funded collator accounts + let mut delegators: Vec = Vec::new(); + for i in 0..y { + let seed = USER_SEED + i; + let delegator = create_funded_delegator::( + "delegator", + seed, + initial_stake_amount, + sole_collator.clone(), + true, + delegators.len() as u32, + )?; + delegators.push(delegator); + total_staked += initial_stake_amount; + } + + // rather than roll through rounds in order to initialize the storage we want, we set it + // directly and then call pay_one_collator_reward directly. + + let round_for_payout = 5; + >::insert(&round_for_payout, DelayedPayout { + // NOTE: round_issuance is not correct here, but it doesn't seem to cause problems + round_issuance: 1000u32.into(), + total_staking_reward: total_staked, + collator_commission: Perbill::from_rational(1u32, 100u32), + }); + + let mut delegations: Vec>> = Vec::new(); + for delegator in &delegators { + delegations.push(Bond { + owner: delegator.clone(), + amount: 100u32.into(), + }); + } + + >::insert(round_for_payout, &sole_collator, CollatorSnapshot { + bond: 1_000u32.into(), + delegations, + total: 1_000_000u32.into(), + }); + + >::insert(round_for_payout, 100); + >::insert(round_for_payout, &sole_collator, 20); + + }: { + let round_for_payout = 5; + // TODO: this is an extra read right here (we should whitelist it?) + let payout_info = Pallet::::delayed_payouts(round_for_payout).expect("payout expected"); + let result = Pallet::::pay_one_collator_reward(round_for_payout, payout_info); + assert!(result.0.is_some()); // TODO: how to keep this in scope so it can be done in verify block? + } + verify { + // collator should have been paid + assert!( + T::Currency::free_balance(&sole_collator) > initial_stake_amount, + "collator should have been paid in pay_one_collator_reward" + ); + // nominators should have been paid + for delegator in &delegators { + assert!( + T::Currency::free_balance(&delegator) > initial_stake_amount, + "delegator should have been paid in pay_one_collator_reward" + ); + } + } + + base_on_initialize { + let collator: T::AccountId = create_funded_collator::( + "collator", + USER_SEED, + 0u32.into(), + true, + 1u32 + )?; + let start = >::block_number(); + Pallet::::note_author(collator.clone()); + >::on_finalize(start); + >::set_block_number( + start + 1u32.into() + ); + let end = >::block_number(); + >::on_initialize(end); + }: { Pallet::::on_initialize(end); } + verify { + // Round transitions + assert_eq!(start + 1u32.into(), end); + } } #[cfg(test)] mod tests { - use crate::benchmarks::*; - use crate::mock::Test; - use frame_support::assert_ok; - use sp_io::TestExternalities; - - pub fn new_test_ext() -> TestExternalities { - let t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - TestExternalities::new(t) - } - - #[test] - fn bench_hotfix_remove_delegation_requests() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_hotfix_remove_delegation_requests()); - }); - } - - #[test] - fn bench_hotfix_update_candidate_pool_value() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_hotfix_update_candidate_pool_value()); - }); - } - - #[test] - fn bench_set_staking_expectations() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_set_staking_expectations()); - }); - } - - #[test] - fn bench_set_inflation() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_set_inflation()); - }); - } - - #[test] - fn bench_set_parachain_bond_account() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_set_parachain_bond_account()); - }); - } - - #[test] - fn bench_set_parachain_bond_reserve_percent() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_set_parachain_bond_reserve_percent()); - }); - } - - #[test] - fn bench_set_total_selected() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_set_total_selected()); - }); - } - - #[test] - fn bench_set_collator_commission() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_set_collator_commission()); - }); - } - - #[test] - fn bench_set_blocks_per_round() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_set_blocks_per_round()); - }); - } - - #[test] - fn bench_join_candidates() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_join_candidates()); - }); - } - - #[test] - fn bench_schedule_leave_candidates() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_schedule_leave_candidates()); - }); - } - - #[test] - fn bench_execute_leave_candidates() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_execute_leave_candidates()); - }); - } - - #[test] - fn bench_cancel_leave_candidates() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_cancel_leave_candidates()); - }); - } - - #[test] - fn bench_go_offline() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_go_offline()); - }); - } - - #[test] - fn bench_go_online() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_go_online()); - }); - } - - #[test] - fn bench_candidate_bond_more() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_candidate_bond_more()); - }); - } - - #[test] - fn bench_schedule_candidate_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_schedule_candidate_bond_less()); - }); - } - - #[test] - fn bench_execute_candidate_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_execute_candidate_bond_less()); - }); - } - - #[test] - fn bench_cancel_candidate_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_cancel_candidate_bond_less()); - }); - } - - #[test] - fn bench_delegate() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_delegate()); - }); - } - - #[test] - fn bench_schedule_leave_delegators() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_schedule_leave_delegators()); - }); - } - - #[test] - fn bench_execute_leave_delegators() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_execute_leave_delegators()); - }); - } - - #[test] - fn bench_cancel_leave_delegators() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_cancel_leave_delegators()); - }); - } - - #[test] - fn bench_schedule_revoke_delegation() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_schedule_revoke_delegation()); - }); - } - - #[test] - fn bench_delegator_bond_more() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_delegator_bond_more()); - }); - } - - #[test] - fn bench_schedule_delegator_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_schedule_delegator_bond_less()); - }); - } - - #[test] - fn bench_execute_revoke_delegation() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_execute_revoke_delegation()); - }); - } - - #[test] - fn bench_execute_delegator_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_execute_delegator_bond_less()); - }); - } - - #[test] - fn bench_cancel_revoke_delegation() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_cancel_revoke_delegation()); - }); - } - - #[test] - fn bench_cancel_delegator_bond_less() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_cancel_delegator_bond_less()); - }); - } - - #[test] - fn bench_round_transition_on_initialize() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_round_transition_on_initialize()); - }); - } - - #[test] - fn bench_base_on_initialize() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_base_on_initialize()); - }); - } + use crate::benchmarks::*; + use crate::mock::Test; + use frame_support::assert_ok; + use sp_io::TestExternalities; + + pub fn new_test_ext() -> TestExternalities { + let t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + TestExternalities::new(t) + } + + #[test] + fn bench_hotfix_remove_delegation_requests() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_hotfix_remove_delegation_requests()); + }); + } + + #[test] + fn bench_hotfix_update_candidate_pool_value() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_hotfix_update_candidate_pool_value()); + }); + } + + #[test] + fn bench_set_staking_expectations() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_staking_expectations()); + }); + } + + #[test] + fn bench_set_inflation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_inflation()); + }); + } + + #[test] + fn bench_set_parachain_bond_account() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_parachain_bond_account()); + }); + } + + #[test] + fn bench_set_parachain_bond_reserve_percent() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_parachain_bond_reserve_percent()); + }); + } + + #[test] + fn bench_set_total_selected() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_total_selected()); + }); + } + + #[test] + fn bench_set_collator_commission() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_collator_commission()); + }); + } + + #[test] + fn bench_set_blocks_per_round() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_set_blocks_per_round()); + }); + } + + #[test] + fn bench_join_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_join_candidates()); + }); + } + + #[test] + fn bench_schedule_leave_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_leave_candidates()); + }); + } + + #[test] + fn bench_execute_leave_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_leave_candidates()); + }); + } + + #[test] + fn bench_cancel_leave_candidates() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_leave_candidates()); + }); + } + + #[test] + fn bench_go_offline() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_go_offline()); + }); + } + + #[test] + fn bench_go_online() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_go_online()); + }); + } + + #[test] + fn bench_candidate_bond_more() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_candidate_bond_more()); + }); + } + + #[test] + fn bench_schedule_candidate_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_candidate_bond_less()); + }); + } + + #[test] + fn bench_execute_candidate_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_candidate_bond_less()); + }); + } + + #[test] + fn bench_cancel_candidate_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_candidate_bond_less()); + }); + } + + #[test] + fn bench_delegate() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_delegate()); + }); + } + + #[test] + fn bench_schedule_leave_delegators() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_leave_delegators()); + }); + } + + #[test] + fn bench_execute_leave_delegators() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_leave_delegators()); + }); + } + + #[test] + fn bench_cancel_leave_delegators() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_leave_delegators()); + }); + } + + #[test] + fn bench_schedule_revoke_delegation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_revoke_delegation()); + }); + } + + #[test] + fn bench_delegator_bond_more() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_delegator_bond_more()); + }); + } + + #[test] + fn bench_schedule_delegator_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_schedule_delegator_bond_less()); + }); + } + + #[test] + fn bench_execute_revoke_delegation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_revoke_delegation()); + }); + } + + #[test] + fn bench_execute_delegator_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_execute_delegator_bond_less()); + }); + } + + #[test] + fn bench_cancel_revoke_delegation() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_revoke_delegation()); + }); + } + + #[test] + fn bench_cancel_delegator_bond_less() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_cancel_delegator_bond_less()); + }); + } + + #[test] + fn bench_round_transition_on_initialize() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_round_transition_on_initialize()); + }); + } + + #[test] + fn bench_base_on_initialize() { + new_test_ext().execute_with(|| { + assert_ok!(Pallet::::test_benchmark_base_on_initialize()); + }); + } } impl_benchmark_test_suite!( - Pallet, - crate::benchmarks::tests::new_test_ext(), - crate::mock::Test + Pallet, + crate::benchmarks::tests::new_test_ext(), + crate::mock::Test ); diff --git a/pallets/parachain-staking/src/inflation.rs b/pallets/parachain-staking/src/inflation.rs index f2181565..5df689b0 100644 --- a/pallets/parachain-staking/src/inflation.rs +++ b/pallets/parachain-staking/src/inflation.rs @@ -31,184 +31,184 @@ const SECONDS_PER_BLOCK: u32 = 12; pub const BLOCKS_PER_YEAR: u32 = SECONDS_PER_YEAR / SECONDS_PER_BLOCK; fn rounds_per_year() -> u32 { - let blocks_per_round = >::round().length; - BLOCKS_PER_YEAR / blocks_per_round + let blocks_per_round = >::round().length; + BLOCKS_PER_YEAR / blocks_per_round } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive( - Eq, PartialEq, Clone, Copy, Encode, Decode, Default, RuntimeDebug, MaxEncodedLen, TypeInfo, + Eq, PartialEq, Clone, Copy, Encode, Decode, Default, RuntimeDebug, MaxEncodedLen, TypeInfo, )] pub struct Range { - pub min: T, - pub ideal: T, - pub max: T, + pub min: T, + pub ideal: T, + pub max: T, } impl Range { - pub fn is_valid(&self) -> bool { - self.max >= self.ideal && self.ideal >= self.min - } + pub fn is_valid(&self) -> bool { + self.max >= self.ideal && self.ideal >= self.min + } } impl From for Range { - fn from(other: T) -> Range { - Range { - min: other, - ideal: other, - max: other, - } - } + fn from(other: T) -> Range { + Range { + min: other, + ideal: other, + max: other, + } + } } /// Convert an annual inflation to a round inflation /// round = (1+annual)^(1/rounds_per_year) - 1 pub fn perbill_annual_to_perbill_round( - annual: Range, - rounds_per_year: u32, + annual: Range, + rounds_per_year: u32, ) -> Range { - let exponent = I32F32::from_num(1) / I32F32::from_num(rounds_per_year); - let annual_to_round = |annual: Perbill| -> Perbill { - let x = I32F32::from_num(annual.deconstruct()) / I32F32::from_num(Perbill::ACCURACY); - let y: I64F64 = floatpow(I32F32::from_num(1) + x, exponent) - .expect("Cannot overflow since rounds_per_year is u32 so worst case 0; QED"); - Perbill::from_parts( - ((y - I64F64::from_num(1)) * I64F64::from_num(Perbill::ACCURACY)) - .ceil() - .to_num::(), - ) - }; - Range { - min: annual_to_round(annual.min), - ideal: annual_to_round(annual.ideal), - max: annual_to_round(annual.max), - } + let exponent = I32F32::from_num(1) / I32F32::from_num(rounds_per_year); + let annual_to_round = |annual: Perbill| -> Perbill { + let x = I32F32::from_num(annual.deconstruct()) / I32F32::from_num(Perbill::ACCURACY); + let y: I64F64 = floatpow(I32F32::from_num(1) + x, exponent) + .expect("Cannot overflow since rounds_per_year is u32 so worst case 0; QED"); + Perbill::from_parts( + ((y - I64F64::from_num(1)) * I64F64::from_num(Perbill::ACCURACY)) + .ceil() + .to_num::(), + ) + }; + Range { + min: annual_to_round(annual.min), + ideal: annual_to_round(annual.ideal), + max: annual_to_round(annual.max), + } } /// Convert annual inflation rate range to round inflation range pub fn annual_to_round(annual: Range) -> Range { - let periods = rounds_per_year::(); - perbill_annual_to_perbill_round(annual, periods) + let periods = rounds_per_year::(); + perbill_annual_to_perbill_round(annual, periods) } /// Compute round issuance range from round inflation range and current total issuance pub fn round_issuance_range(round: Range) -> Range> { - let circulating = T::Currency::total_issuance(); - Range { - min: round.min * circulating, - ideal: round.ideal * circulating, - max: round.max * circulating, - } + let circulating = T::Currency::total_issuance(); + Range { + min: round.min * circulating, + ideal: round.ideal * circulating, + max: round.max * circulating, + } } #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Eq, PartialEq, Clone, Encode, Decode, Default, RuntimeDebug, TypeInfo)] pub struct InflationInfo { - /// Staking expectations - pub expect: Range, - /// Annual inflation range - pub annual: Range, - /// Round inflation range - pub round: Range, + /// Staking expectations + pub expect: Range, + /// Annual inflation range + pub annual: Range, + /// Round inflation range + pub round: Range, } impl InflationInfo { - pub fn new( - annual: Range, - expect: Range, - ) -> InflationInfo { - InflationInfo { - expect, - annual, - round: annual_to_round::(annual), - } - } - /// Set round inflation range according to input annual inflation range - pub fn set_round_from_annual(&mut self, new: Range) { - self.round = annual_to_round::(new); - } - /// Reset round inflation rate based on changes to round length - pub fn reset_round(&mut self, new_length: u32) { - let periods = BLOCKS_PER_YEAR / new_length; - self.round = perbill_annual_to_perbill_round(self.annual, periods); - } - /// Set staking expectations - pub fn set_expectations(&mut self, expect: Range) { - self.expect = expect; - } + pub fn new( + annual: Range, + expect: Range, + ) -> InflationInfo { + InflationInfo { + expect, + annual, + round: annual_to_round::(annual), + } + } + /// Set round inflation range according to input annual inflation range + pub fn set_round_from_annual(&mut self, new: Range) { + self.round = annual_to_round::(new); + } + /// Reset round inflation rate based on changes to round length + pub fn reset_round(&mut self, new_length: u32) { + let periods = BLOCKS_PER_YEAR / new_length; + self.round = perbill_annual_to_perbill_round(self.annual, periods); + } + /// Set staking expectations + pub fn set_expectations(&mut self, expect: Range) { + self.expect = expect; + } } #[cfg(test)] mod tests { - use super::*; - fn mock_annual_to_round(annual: Range, rounds_per_year: u32) -> Range { - perbill_annual_to_perbill_round(annual, rounds_per_year) - } - fn mock_round_issuance_range( - // Total circulating before minting - circulating: u128, - // Round inflation range - round: Range, - ) -> Range { - Range { - min: round.min * circulating, - ideal: round.ideal * circulating, - max: round.max * circulating, - } - } - #[test] - fn simple_issuance_conversion() { - // 5% inflation for 10_000_0000 = 500,000 minted over the year - // let's assume there are 10 periods in a year - // => mint 500_000 over 10 periods => 50_000 minted per period - let expected_round_issuance_range: Range = Range { - min: 48_909, - ideal: 48_909, - max: 48_909, - }; - let schedule = Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5), - }; - assert_eq!( - expected_round_issuance_range, - mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) - ); - } - #[test] - fn range_issuance_conversion() { - // 3-5% inflation for 10_000_0000 = 300_000-500,000 minted over the year - // let's assume there are 10 periods in a year - // => mint 300_000-500_000 over 10 periods => 30_000-50_000 minted per period - let expected_round_issuance_range: Range = Range { - min: 29_603, - ideal: 39298, - max: 48_909, - }; - let schedule = Range { - min: Perbill::from_percent(3), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(5), - }; - assert_eq!( - expected_round_issuance_range, - mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) - ); - } - #[test] - fn expected_parameterization() { - let expected_round_schedule: Range = Range { - min: 45, - ideal: 56, - max: 56, - }; - let schedule = Range { - min: Perbill::from_percent(4), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5), - }; - assert_eq!( - expected_round_schedule, - mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 8766)) - ); - } + use super::*; + fn mock_annual_to_round(annual: Range, rounds_per_year: u32) -> Range { + perbill_annual_to_perbill_round(annual, rounds_per_year) + } + fn mock_round_issuance_range( + // Total circulating before minting + circulating: u128, + // Round inflation range + round: Range, + ) -> Range { + Range { + min: round.min * circulating, + ideal: round.ideal * circulating, + max: round.max * circulating, + } + } + #[test] + fn simple_issuance_conversion() { + // 5% inflation for 10_000_0000 = 500,000 minted over the year + // let's assume there are 10 periods in a year + // => mint 500_000 over 10 periods => 50_000 minted per period + let expected_round_issuance_range: Range = Range { + min: 48_909, + ideal: 48_909, + max: 48_909, + }; + let schedule = Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5), + }; + assert_eq!( + expected_round_issuance_range, + mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) + ); + } + #[test] + fn range_issuance_conversion() { + // 3-5% inflation for 10_000_0000 = 300_000-500,000 minted over the year + // let's assume there are 10 periods in a year + // => mint 300_000-500_000 over 10 periods => 30_000-50_000 minted per period + let expected_round_issuance_range: Range = Range { + min: 29_603, + ideal: 39298, + max: 48_909, + }; + let schedule = Range { + min: Perbill::from_percent(3), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(5), + }; + assert_eq!( + expected_round_issuance_range, + mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 10)) + ); + } + #[test] + fn expected_parameterization() { + let expected_round_schedule: Range = Range { + min: 45, + ideal: 56, + max: 56, + }; + let schedule = Range { + min: Perbill::from_percent(4), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5), + }; + assert_eq!( + expected_round_schedule, + mock_round_issuance_range(10_000_000, mock_annual_to_round(schedule, 8766)) + ); + } } diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index 6583d688..7e511c5d 100644 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -67,3203 +67,3233 @@ pub use pallet::*; #[pallet] pub mod pallet { - use crate::{set::OrderedSet, InflationInfo, Range, WeightInfo}; - use frame_support::pallet_prelude::*; - use frame_support::traits::{Currency, Get, Imbalance, ReservableCurrency}; - use frame_system::pallet_prelude::*; - use parity_scale_codec::{Decode, Encode}; - use scale_info::TypeInfo; - use sp_runtime::{ - traits::{AtLeast32BitUnsigned, Saturating, Zero}, - Perbill, Percent, RuntimeDebug, - }; - use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; - - /// Pallet for parachain staking - #[pallet::pallet] - #[pallet::without_storage_info] - pub struct Pallet(PhantomData); - - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] - pub struct Bond { - pub owner: AccountId, - pub amount: Balance, - } - - impl Default for Bond { - fn default() -> Bond { - Bond { - owner: A::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) - .expect("infinite length input; no invalid inputs for type; qed"), - amount: B::default(), - } - } - } - - impl Bond { - fn from_owner(owner: A) -> Self { - Bond { - owner, - amount: B::default(), - } - } - } - - impl Eq for Bond {} - - impl Ord for Bond { - fn cmp(&self, other: &Self) -> Ordering { - self.owner.cmp(&other.owner) - } - } - - impl PartialOrd for Bond { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } - } - - impl PartialEq for Bond { - fn eq(&self, other: &Self) -> bool { - self.owner == other.owner - } - } - - #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// The activity status of the collator - pub enum CollatorStatus { - /// Committed to be online and producing valid blocks (not equivocating) - Active, - /// Temporarily inactive and excused for inactivity - Idle, - /// Bonded until the inner round - Leaving(RoundIndex), - } - - impl Default for CollatorStatus { - fn default() -> CollatorStatus { - CollatorStatus::Active - } - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] - /// Snapshot of collator state at the start of the round for which they are selected - pub struct CollatorSnapshot { - pub bond: Balance, - pub delegations: Vec>, - pub total: Balance, - } - - impl Default for CollatorSnapshot { - fn default() -> CollatorSnapshot { - CollatorSnapshot { - bond: B::default(), - delegations: Vec::new(), - total: B::default(), - } - } - } - - #[derive(Default, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Info needed to make delayed payments to stakers after round end - pub struct DelayedPayout { - /// Total round reward (result of compute_issuance() at round end) - pub round_issuance: Balance, - /// The total inflation paid this round to stakers (e.g. less parachain bond fund) - pub total_staking_reward: Balance, - /// Snapshot of collator commission rate at the end of the round - pub collator_commission: Perbill, - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] - /// DEPRECATED - /// Collator state with commission fee, bonded stake, and delegations - pub struct Collator2 { - /// The account of this collator - pub id: AccountId, - /// This collator's self stake. - pub bond: Balance, - /// Set of all nominator AccountIds (to prevent >1 nomination per AccountId) - pub nominators: OrderedSet, - /// Top T::MaxDelegatorsPerCollator::get() nominators, ordered greatest to least - pub top_nominators: Vec>, - /// Bottom nominators (unbounded), ordered least to greatest - pub bottom_nominators: Vec>, - /// Sum of top delegations + self.bond - pub total_counted: Balance, - /// Sum of all delegations + self.bond = (total_counted + uncounted) - pub total_backing: Balance, - /// Current status of the collator - pub state: CollatorStatus, - } - - impl From> for CollatorCandidate { - fn from(other: Collator2) -> CollatorCandidate { - CollatorCandidate { - id: other.id, - bond: other.bond, - delegators: other.nominators, - top_delegations: other.top_nominators, - bottom_delegations: other.bottom_nominators, - total_counted: other.total_counted, - total_backing: other.total_backing, - request: None, - state: other.state, - } - } - } - - #[derive(PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Request scheduled to change the collator candidate self-bond - pub struct CandidateBondLessRequest { - pub amount: Balance, - pub when_executable: RoundIndex, - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] - /// DEPRECATED, replaced by `CandidateMetadata` and two storage instances of `Delegations` - /// Collator candidate state with self bond + delegations - pub struct CollatorCandidate { - /// The account of this collator - pub id: AccountId, - /// This collator's self stake. - pub bond: Balance, - /// Set of all delegator AccountIds (to prevent >1 delegation per AccountId) - pub delegators: OrderedSet, - /// Top T::MaxDelegatorsPerCollator::get() delegations, ordered greatest to least - pub top_delegations: Vec>, - /// Bottom delegations (unbounded), ordered least to greatest - pub bottom_delegations: Vec>, - /// Sum of top delegations + self.bond - pub total_counted: Balance, - /// Sum of all delegations + self.bond = (total_counted + uncounted) - pub total_backing: Balance, - /// Maximum 1 pending request to decrease candidate self bond at any given time - pub request: Option>, - /// Current status of the collator - pub state: CollatorStatus, - } - - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Type for top and bottom delegation storage item - pub struct Delegations { - pub delegations: Vec>, - pub total: Balance, - } - - impl Default for Delegations { - fn default() -> Delegations { - Delegations { - delegations: Vec::new(), - total: B::default(), - } - } - } - - impl - Delegations - { - pub fn sort_greatest_to_least(&mut self) { - self.delegations.sort_by(|a, b| b.amount.cmp(&a.amount)); - } - /// Insert sorted greatest to least and increase .total accordingly - /// Insertion respects first come first serve so new delegations are pushed after existing - /// delegations if the amount is the same - pub fn insert_sorted_greatest_to_least(&mut self, delegation: Bond) { - self.total = self.total.saturating_add(delegation.amount); - // if delegations nonempty && last_element == delegation.amount => push input and return - if !self.delegations.is_empty() { - // if last_element == delegation.amount => push the delegation and return early - if self.delegations[self.delegations.len() - 1].amount == delegation.amount { - self.delegations.push(delegation); - // early return - return; - } - } - // else binary search insertion - match self - .delegations - .binary_search_by(|x| delegation.amount.cmp(&x.amount)) - { - // sorted insertion on sorted vec - // enforces first come first serve for equal bond amounts - Ok(i) => { - let mut new_index = i + 1; - while new_index <= (self.delegations.len() - 1) { - if self.delegations[new_index].amount == delegation.amount { - new_index += 1; - } else { - self.delegations.insert(new_index, delegation); - return; - } - } - self.delegations.push(delegation) - } - Err(i) => self.delegations.insert(i, delegation), - } - } - /// Return the capacity status for top delegations - pub fn top_capacity(&self) -> CapacityStatus { - match &self.delegations { - x if x.len() as u32 >= T::MaxTopDelegationsPerCandidate::get() => { - CapacityStatus::Full - } - x if x.is_empty() => CapacityStatus::Empty, - _ => CapacityStatus::Partial, - } - } - /// Return the capacity status for bottom delegations - pub fn bottom_capacity(&self) -> CapacityStatus { - match &self.delegations { - x if x.len() as u32 >= T::MaxBottomDelegationsPerCandidate::get() => { - CapacityStatus::Full - } - x if x.is_empty() => CapacityStatus::Empty, - _ => CapacityStatus::Partial, - } - } - /// Return last delegation amount without popping the delegation - pub fn lowest_delegation_amount(&self) -> Balance { - self.delegations - .last() - .map(|x| x.amount) - .unwrap_or(Balance::zero()) - } - /// Return highest delegation amount - pub fn highest_delegation_amount(&self) -> Balance { - self.delegations - .first() - .map(|x| x.amount) - .unwrap_or(Balance::zero()) - } - } - - #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Capacity status for top or bottom delegations - pub enum CapacityStatus { - /// Reached capacity - Full, - /// Empty aka contains no delegations - Empty, - /// Partially full (nonempty and not full) - Partial, - } - - #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] - /// All candidate info except the top and bottom delegations - pub struct CandidateMetadata { - /// This candidate's self bond amount - pub bond: Balance, - /// Total number of delegations to this candidate - pub delegation_count: u32, - /// Self bond + sum of top delegations - pub total_counted: Balance, - /// The smallest top delegation amount - pub lowest_top_delegation_amount: Balance, - /// The highest bottom delegation amount - pub highest_bottom_delegation_amount: Balance, - /// The smallest bottom delegation amount - pub lowest_bottom_delegation_amount: Balance, - /// Capacity status for top delegations - pub top_capacity: CapacityStatus, - /// Capacity status for bottom delegations - pub bottom_capacity: CapacityStatus, - /// Maximum 1 pending request to decrease candidate self bond at any given time - pub request: Option>, - /// Current status of the collator - pub status: CollatorStatus, - } - - impl< - Balance: Copy - + Zero - + PartialOrd - + sp_std::ops::AddAssign - + sp_std::ops::SubAssign - + sp_std::ops::Sub - + sp_std::fmt::Debug, - > CandidateMetadata - { - pub fn new(bond: Balance) -> Self { - CandidateMetadata { - bond, - delegation_count: 0u32, - total_counted: bond, - lowest_top_delegation_amount: Zero::zero(), - highest_bottom_delegation_amount: Zero::zero(), - lowest_bottom_delegation_amount: Zero::zero(), - top_capacity: CapacityStatus::Empty, - bottom_capacity: CapacityStatus::Empty, - request: None, - status: CollatorStatus::Active, - } - } - pub fn is_active(&self) -> bool { - matches!(self.status, CollatorStatus::Active) - } - pub fn is_leaving(&self) -> bool { - matches!(self.status, CollatorStatus::Leaving(_)) - } - pub fn schedule_leave( - &mut self, - ) -> Result<(RoundIndex, RoundIndex), DispatchError> { - ensure!(!self.is_leaving(), Error::::CandidateAlreadyLeaving); - let now = >::get().current; - let when = now + T::LeaveCandidatesDelay::get(); - self.status = CollatorStatus::Leaving(when); - Ok((now, when)) - } - pub fn can_leave(&self) -> DispatchResult { - if let CollatorStatus::Leaving(when) = self.status { - ensure!( - >::get().current >= when, - Error::::CandidateCannotLeaveYet - ); - Ok(()) - } else { - Err(Error::::CandidateNotLeaving.into()) - } - } - pub fn go_offline(&mut self) { - self.status = CollatorStatus::Idle; - } - pub fn go_online(&mut self) { - self.status = CollatorStatus::Active; - } - pub fn bond_more(&mut self, who: T::AccountId, more: Balance) -> DispatchResult - where - BalanceOf: From, - { - T::Currency::reserve(&who, more.into())?; - let new_total = >::get().saturating_add(more.into()); - >::put(new_total); - self.bond += more; - self.total_counted += more; - >::deposit_event(Event::CandidateBondedMore( - who.clone(), - more.into(), - self.bond.into(), - )); - Ok(()) - } - /// Schedule executable decrease of collator candidate self bond - /// Returns the round at which the collator can execute the pending request - pub fn schedule_bond_less( - &mut self, - less: Balance, - ) -> Result - where - BalanceOf: Into, - { - // ensure no pending request - ensure!( - self.request.is_none(), - Error::::PendingCandidateRequestAlreadyExists - ); - // ensure bond above min after decrease - ensure!(self.bond > less, Error::::CandidateBondBelowMin); - ensure!( - self.bond - less >= T::MinCandidateStk::get().into(), - Error::::CandidateBondBelowMin - ); - let when_executable = >::get().current + T::CandidateBondLessDelay::get(); - self.request = Some(CandidateBondLessRequest { - amount: less, - when_executable, - }); - Ok(when_executable) - } - /// Execute pending request to decrease the collator self bond - /// Returns the event to be emitted - pub fn execute_bond_less(&mut self, who: T::AccountId) -> DispatchResult - where - BalanceOf: From, - { - let request = self - .request - .ok_or(Error::::PendingCandidateRequestsDNE)?; - ensure!( - request.when_executable <= >::get().current, - Error::::PendingCandidateRequestNotDueYet - ); - T::Currency::unreserve(&who, request.amount.into()); - let new_total_staked = >::get().saturating_sub(request.amount.into()); - >::put(new_total_staked); - // Arithmetic assumptions are self.bond > less && self.bond - less > CollatorMinBond - // (assumptions enforced by `schedule_bond_less`; if storage corrupts, must re-verify) - self.bond -= request.amount; - self.total_counted -= request.amount; - let event = Event::CandidateBondedLess( - who.clone().into(), - request.amount.into(), - self.bond.into(), - ); - // reset s.t. no pending request - self.request = None; - // update candidate pool value because it must change if self bond changes - if self.is_active() { - Pallet::::update_active(who.into(), self.total_counted.into()); - } - Pallet::::deposit_event(event); - Ok(()) - } - /// Cancel candidate bond less request - pub fn cancel_bond_less(&mut self, who: T::AccountId) -> DispatchResult - where - BalanceOf: From, - { - let request = self - .request - .ok_or(Error::::PendingCandidateRequestsDNE)?; - let event = Event::CancelledCandidateBondLess( - who.clone().into(), - request.amount.into(), - request.when_executable, - ); - self.request = None; - Pallet::::deposit_event(event); - Ok(()) - } - /// Reset top delegations metadata - pub fn reset_top_data( - &mut self, - top_delegations: &Delegations>, - ) where - BalanceOf: Into, - { - self.lowest_top_delegation_amount = top_delegations.lowest_delegation_amount().into(); - self.top_capacity = top_delegations.top_capacity::(); - self.total_counted = self.bond + top_delegations.total.into(); - } - /// Reset bottom delegations metadata - pub fn reset_bottom_data( - &mut self, - bottom_delegations: &Delegations>, - ) where - BalanceOf: Into, - { - self.lowest_bottom_delegation_amount = - bottom_delegations.lowest_delegation_amount().into(); - self.highest_bottom_delegation_amount = - bottom_delegations.highest_delegation_amount().into(); - self.bottom_capacity = bottom_delegations.bottom_capacity::(); - } - /// Add delegation - /// Returns whether delegator was added and an optional negative total counted remainder - /// for if a bottom delegation was kicked - /// MUST ensure no delegation exists for this candidate in the `DelegatorState` before call - pub fn add_delegation( - &mut self, - candidate: &T::AccountId, - delegation: Bond>, - ) -> Result<(DelegatorAdded, Option), DispatchError> - where - BalanceOf: Into, - { - let mut less_total_staked = None; - let delegator_added = match self.top_capacity { - CapacityStatus::Full => { - // top is full, insert into top iff the lowest_top < amount - if self.lowest_top_delegation_amount < delegation.amount.into() { - // bumps lowest top to the bottom inside this function call - less_total_staked = self.add_top_delegation::(candidate, delegation); - DelegatorAdded::AddedToTop { - new_total: self.total_counted, - } - } else { - // if bottom is full, only insert if greater than lowest bottom (which will - // be bumped out) - if matches!(self.bottom_capacity, CapacityStatus::Full) { - ensure!( - delegation.amount.into() > self.lowest_bottom_delegation_amount, - Error::::CannotDelegateLessThanLowestBottomWhenBottomIsFull - ); - // need to subtract from total staked - less_total_staked = Some(self.lowest_bottom_delegation_amount); - } - // insert into bottom - self.add_bottom_delegation::(false, candidate, delegation); - DelegatorAdded::AddedToBottom - } - } - // top is either empty or partially full - _ => { - self.add_top_delegation::(candidate, delegation); - DelegatorAdded::AddedToTop { - new_total: self.total_counted, - } - } - }; - Ok((delegator_added, less_total_staked)) - } - /// Add delegation to top delegation - /// Returns Option - /// Only call if lowest top delegation is less than delegation.amount || !top_full - pub fn add_top_delegation( - &mut self, - candidate: &T::AccountId, - delegation: Bond>, - ) -> Option - where - BalanceOf: Into, - { - let mut less_total_staked = None; - let mut top_delegations = >::get(candidate) - .expect("CandidateInfo existence => TopDelegations existence"); - let max_top_delegations_per_candidate = T::MaxTopDelegationsPerCandidate::get(); - if top_delegations.delegations.len() as u32 == max_top_delegations_per_candidate { - // pop lowest top delegation - let new_bottom_delegation = top_delegations.delegations.pop().expect(""); - top_delegations.total = top_delegations - .total - .saturating_sub(new_bottom_delegation.amount); - if matches!(self.bottom_capacity, CapacityStatus::Full) { - less_total_staked = Some(self.lowest_bottom_delegation_amount); - } - self.add_bottom_delegation::(true, candidate, new_bottom_delegation); - } - // insert into top - top_delegations.insert_sorted_greatest_to_least(delegation); - // update candidate info - self.reset_top_data::(&top_delegations); - if less_total_staked.is_none() { - // only increment delegation count if we are not kicking a bottom delegation - self.delegation_count += 1u32; - } - >::insert(&candidate, top_delegations); - less_total_staked - } - /// Add delegation to bottom delegations - /// Check before call that if capacity is full, inserted delegation is higher than lowest - /// bottom delegation (and if so, need to adjust the total storage item) - /// CALLER MUST ensure(lowest_bottom_to_be_kicked.amount < delegation.amount) - pub fn add_bottom_delegation( - &mut self, - bumped_from_top: bool, - candidate: &T::AccountId, - delegation: Bond>, - ) where - BalanceOf: Into, - { - let mut bottom_delegations = >::get(candidate) - .expect("CandidateInfo existence => BottomDelegations existence"); - // if bottom is full, kick the lowest bottom (which is expected to be lower than input - // as per check) - let increase_delegation_count = if bottom_delegations.delegations.len() as u32 - == T::MaxBottomDelegationsPerCandidate::get() - { - let lowest_bottom_to_be_kicked = bottom_delegations - .delegations - .pop() - .expect("if at full capacity (>0), then >0 bottom delegations exist; qed"); - // EXPECT lowest_bottom_to_be_kicked.amount < delegation.amount enforced by caller - // if lowest_bottom_to_be_kicked.amount == delegation.amount, we will still kick - // the lowest bottom to enforce first come first served - bottom_delegations.total = bottom_delegations - .total - .saturating_sub(lowest_bottom_to_be_kicked.amount); - // update delegator state - // unreserve kicked bottom - T::Currency::unreserve( - &lowest_bottom_to_be_kicked.owner, - lowest_bottom_to_be_kicked.amount, - ); - // total staked is updated via propagation of lowest bottom delegation amount prior - // to call - let mut delegator_state = - >::get(&lowest_bottom_to_be_kicked.owner) - .expect("Delegation existence => DelegatorState existence"); - let leaving = delegator_state.delegations.0.len() == 1usize; - delegator_state.rm_delegation(candidate); - Pallet::::deposit_event(Event::DelegationKicked( - lowest_bottom_to_be_kicked.owner.clone(), - candidate.clone(), - lowest_bottom_to_be_kicked.amount, - )); - if leaving { - >::remove(&lowest_bottom_to_be_kicked.owner); - Pallet::::deposit_event(Event::DelegatorLeft( - lowest_bottom_to_be_kicked.owner, - lowest_bottom_to_be_kicked.amount, - )); - } else { - >::insert(&lowest_bottom_to_be_kicked.owner, delegator_state); - } - false - } else { - !bumped_from_top - }; - // only increase delegation count if new bottom delegation (1) doesn't come from top && - // (2) doesn't pop the lowest delegation from the bottom - if increase_delegation_count { - self.delegation_count += 1u32; - } - bottom_delegations.insert_sorted_greatest_to_least(delegation); - self.reset_bottom_data::(&bottom_delegations); - >::insert(candidate, bottom_delegations); - } - /// Remove delegation - /// Removes from top if amount is above lowest top or top is not full - /// Return Ok(if_total_counted_changed) - pub fn rm_delegation_if_exists( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - amount: Balance, - ) -> Result - where - BalanceOf: Into + From, - { - let amount_geq_lowest_top = amount >= self.lowest_top_delegation_amount; - let top_is_not_full = !matches!(self.top_capacity, CapacityStatus::Full); - let lowest_top_eq_highest_bottom = - self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; - let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); - if top_is_not_full || (amount_geq_lowest_top && !lowest_top_eq_highest_bottom) { - self.rm_top_delegation::(candidate, delegator) - } else if amount_geq_lowest_top && lowest_top_eq_highest_bottom { - let result = self.rm_top_delegation::(candidate, delegator.clone()); - if result == Err(delegation_dne_err) { - // worst case removal - self.rm_bottom_delegation::(candidate, delegator) - } else { - result - } - } else { - self.rm_bottom_delegation::(candidate, delegator) - } - } - /// Remove top delegation, bumps top bottom delegation if exists - pub fn rm_top_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - ) -> Result - where - BalanceOf: Into, - { - let old_total_counted = self.total_counted; - // remove top delegation - let mut top_delegations = >::get(candidate) - .expect("CandidateInfo exists => TopDelegations exists"); - let mut actual_amount_option: Option> = None; - top_delegations.delegations = top_delegations - .delegations - .clone() - .into_iter() - .filter_map(|d| { - if d.owner != delegator { - Some(d) - } else { - actual_amount_option = Some(d.amount); - None - } - }) - .collect(); - let actual_amount = actual_amount_option.ok_or(Error::::DelegationDNE)?; - top_delegations.total -= actual_amount; - // if bottom nonempty => bump top bottom to top - if !matches!(self.bottom_capacity, CapacityStatus::Empty) { - let mut bottom_delegations = >::get(candidate) - .expect("bottom is nonempty as just checked"); - // expect already stored greatest to least by bond amount - let highest_bottom_delegation = bottom_delegations.delegations.remove(0); - bottom_delegations.total = bottom_delegations - .total - .saturating_sub(highest_bottom_delegation.amount); - self.reset_bottom_data::(&bottom_delegations); - >::insert(candidate, bottom_delegations); - // insert highest bottom into top delegations - top_delegations.insert_sorted_greatest_to_least(highest_bottom_delegation); - } - // update candidate info - self.reset_top_data::(&top_delegations); - self.delegation_count -= 1u32; - >::insert(candidate, top_delegations); - // return whether total counted changed - Ok(old_total_counted == self.total_counted) - } - /// Remove bottom delegation - /// Returns if_total_counted_changed: bool - pub fn rm_bottom_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - ) -> Result - where - BalanceOf: Into, - { - // remove bottom delegation - let mut bottom_delegations = >::get(candidate) - .expect("CandidateInfo exists => BottomDelegations exists"); - let mut actual_amount_option: Option> = None; - bottom_delegations.delegations = bottom_delegations - .delegations - .clone() - .into_iter() - .filter_map(|d| { - if d.owner != delegator { - Some(d) - } else { - actual_amount_option = Some(d.amount); - None - } - }) - .collect(); - let actual_amount = actual_amount_option.ok_or(Error::::DelegationDNE)?; - bottom_delegations.total = bottom_delegations.total.saturating_sub(actual_amount); - // update candidate info - self.reset_bottom_data::(&bottom_delegations); - self.delegation_count = self.delegation_count.saturating_sub(1u32); - >::insert(candidate, bottom_delegations); - Ok(false) - } - /// Increase delegation amount - pub fn increase_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - bond: BalanceOf, - more: BalanceOf, - ) -> Result - where - BalanceOf: Into, - { - let lowest_top_eq_highest_bottom = - self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; - let bond_geq_lowest_top = bond.into() >= self.lowest_top_delegation_amount; - let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); - if bond_geq_lowest_top && !lowest_top_eq_highest_bottom { - // definitely in top - self.increase_top_delegation::(candidate, delegator.clone(), more) - } else if bond_geq_lowest_top && lowest_top_eq_highest_bottom { - // update top but if error then update bottom (because could be in bottom because - // lowest_top_eq_highest_bottom) - let result = self.increase_top_delegation::(candidate, delegator.clone(), more); - if result == Err(delegation_dne_err) { - self.increase_bottom_delegation::(candidate, delegator, bond, more) - } else { - result - } - } else { - self.increase_bottom_delegation::(candidate, delegator, bond, more) - } - } - /// Increase top delegation - pub fn increase_top_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - more: BalanceOf, - ) -> Result - where - BalanceOf: Into, - { - let mut top_delegations = >::get(candidate) - .expect("CandidateInfo exists => TopDelegations exists"); - let mut in_top = false; - top_delegations.delegations = top_delegations - .delegations - .clone() - .into_iter() - .map(|d| { - if d.owner != delegator { - d - } else { - in_top = true; - let new_amount = d.amount.saturating_add(more); - Bond { - owner: d.owner, - amount: new_amount, - } - } - }) - .collect(); - ensure!(in_top, Error::::DelegationDNE); - top_delegations.sort_greatest_to_least(); - self.reset_top_data::(&top_delegations); - >::insert(candidate, top_delegations); - Ok(true) - } - /// Increase bottom delegation - pub fn increase_bottom_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - bond: BalanceOf, - more: BalanceOf, - ) -> Result - where - BalanceOf: Into, - { - let mut bottom_delegations = - >::get(candidate).ok_or(Error::::CandidateDNE)?; - let mut delegation_option: Option>> = None; - let in_top_after = - if (bond.saturating_add(more)).into() > self.lowest_top_delegation_amount { - // bump it from bottom - bottom_delegations.delegations = bottom_delegations - .delegations - .clone() - .into_iter() - .filter_map(|d| { - if d.owner != delegator { - Some(d) - } else { - delegation_option = Some(Bond { - owner: d.owner, - amount: d.amount.saturating_add(more), - }); - None - } - }) - .collect(); - let delegation = delegation_option.ok_or(Error::::DelegationDNE)?; - bottom_delegations.total = bottom_delegations.total.saturating_sub(bond); - // add it to top - let mut top_delegations = >::get(candidate) - .expect("CandidateInfo existence => TopDelegations existence"); - // if top is full, pop lowest top - if matches!(top_delegations.top_capacity::(), CapacityStatus::Full) { - // pop lowest top delegation - let new_bottom_delegation = top_delegations - .delegations - .pop() - .expect("Top capacity full => Exists at least 1 top delegation"); - top_delegations.total = top_delegations - .total - .saturating_sub(new_bottom_delegation.amount); - bottom_delegations.insert_sorted_greatest_to_least(new_bottom_delegation); - } - // insert into top - top_delegations.insert_sorted_greatest_to_least(delegation); - self.reset_top_data::(&top_delegations); - >::insert(candidate, top_delegations); - true - } else { - let mut in_bottom = false; - // just increase the delegation - bottom_delegations.delegations = bottom_delegations - .delegations - .clone() - .into_iter() - .map(|d| { - if d.owner != delegator { - d - } else { - in_bottom = true; - Bond { - owner: d.owner, - amount: d.amount.saturating_add(more), - } - } - }) - .collect(); - ensure!(in_bottom, Error::::DelegationDNE); - bottom_delegations.sort_greatest_to_least(); - false - }; - self.reset_bottom_data::(&bottom_delegations); - >::insert(candidate, bottom_delegations); - Ok(in_top_after) - } - /// Decrease delegation - pub fn decrease_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - bond: Balance, - less: BalanceOf, - ) -> Result - where - BalanceOf: Into + From, - { - let lowest_top_eq_highest_bottom = - self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; - let bond_geq_lowest_top = bond >= self.lowest_top_delegation_amount; - let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); - if bond_geq_lowest_top && !lowest_top_eq_highest_bottom { - // definitely in top - self.decrease_top_delegation::(candidate, delegator.clone(), bond.into(), less) - } else if bond_geq_lowest_top && lowest_top_eq_highest_bottom { - // update top but if error then update bottom (because could be in bottom because - // lowest_top_eq_highest_bottom) - let result = self.decrease_top_delegation::( - candidate, - delegator.clone(), - bond.into(), - less, - ); - if result == Err(delegation_dne_err) { - self.decrease_bottom_delegation::(candidate, delegator, less) - } else { - result - } - } else { - self.decrease_bottom_delegation::(candidate, delegator, less) - } - } - /// Decrease top delegation - pub fn decrease_top_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - bond: BalanceOf, - less: BalanceOf, - ) -> Result - where - BalanceOf: Into, - { - // The delegation after the `decrease-delegation` will be strictly less than the - // highest bottom delegation - let bond_after_less_than_highest_bottom = - bond.saturating_sub(less).into() < self.highest_bottom_delegation_amount; - // The top delegations is full and the bottom delegations has at least one delegation - let full_top_and_nonempty_bottom = matches!(self.top_capacity, CapacityStatus::Full) - && !matches!(self.bottom_capacity, CapacityStatus::Empty); - let mut top_delegations = - >::get(candidate).ok_or(Error::::CandidateDNE)?; - let in_top_after = if bond_after_less_than_highest_bottom - && full_top_and_nonempty_bottom - { - let mut delegation_option: Option>> = None; - // take delegation from top - top_delegations.delegations = top_delegations - .delegations - .clone() - .into_iter() - .filter_map(|d| { - if d.owner != delegator { - Some(d) - } else { - top_delegations.total = top_delegations.total.saturating_sub(d.amount); - delegation_option = Some(Bond { - owner: d.owner, - amount: d.amount.saturating_sub(less), - }); - None - } - }) - .collect(); - let delegation = delegation_option.ok_or(Error::::DelegationDNE)?; - // pop highest bottom by reverse and popping - let mut bottom_delegations = >::get(candidate) - .expect("CandidateInfo existence => BottomDelegations existence"); - let highest_bottom_delegation = bottom_delegations.delegations.remove(0); - bottom_delegations.total = bottom_delegations - .total - .saturating_sub(highest_bottom_delegation.amount); - // insert highest bottom into top - top_delegations.insert_sorted_greatest_to_least(highest_bottom_delegation); - // insert previous top into bottom - bottom_delegations.insert_sorted_greatest_to_least(delegation); - self.reset_bottom_data::(&bottom_delegations); - >::insert(candidate, bottom_delegations); - false - } else { - // keep it in the top - let mut is_in_top = false; - top_delegations.delegations = top_delegations - .delegations - .clone() - .into_iter() - .map(|d| { - if d.owner != delegator { - d - } else { - is_in_top = true; - Bond { - owner: d.owner, - amount: d.amount.saturating_sub(less), - } - } - }) - .collect(); - ensure!(is_in_top, Error::::DelegationDNE); - top_delegations.total = top_delegations.total.saturating_sub(less); - top_delegations.sort_greatest_to_least(); - true - }; - self.reset_top_data::(&top_delegations); - >::insert(candidate, top_delegations); - Ok(in_top_after) - } - /// Decrease bottom delegation - pub fn decrease_bottom_delegation( - &mut self, - candidate: &T::AccountId, - delegator: T::AccountId, - less: BalanceOf, - ) -> Result - where - BalanceOf: Into, - { - let mut bottom_delegations = >::get(candidate) - .expect("CandidateInfo exists => BottomDelegations exists"); - let mut in_bottom = false; - bottom_delegations.delegations = bottom_delegations - .delegations - .clone() - .into_iter() - .map(|d| { - if d.owner != delegator { - d - } else { - in_bottom = true; - Bond { - owner: d.owner, - amount: d.amount.saturating_sub(less), - } - } - }) - .collect(); - ensure!(in_bottom, Error::::DelegationDNE); - bottom_delegations.sort_greatest_to_least(); - self.reset_bottom_data::(&bottom_delegations); - >::insert(candidate, bottom_delegations); - Ok(false) - } - } - - // Temporary manual implementation for migration testing purposes - impl PartialEq for CollatorCandidate { - fn eq(&self, other: &Self) -> bool { - let must_be_true = self.id == other.id - && self.bond == other.bond - && self.total_counted == other.total_counted - && self.total_backing == other.total_backing - && self.request == other.request - && self.state == other.state; - if !must_be_true { - return false; - } - for (x, y) in self.delegators.0.iter().zip(other.delegators.0.iter()) { - if x != y { - return false; - } - } - for ( - Bond { - owner: o1, - amount: a1, - }, - Bond { - owner: o2, - amount: a2, - }, - ) in self - .top_delegations - .iter() - .zip(other.top_delegations.iter()) - { - if o1 != o2 || a1 != a2 { - return false; - } - } - for ( - Bond { - owner: o1, - amount: a1, - }, - Bond { - owner: o2, - amount: a2, - }, - ) in self - .bottom_delegations - .iter() - .zip(other.bottom_delegations.iter()) - { - if o1 != o2 || a1 != a2 { - return false; - } - } - true - } - } - - /// Convey relevant information describing if a delegator was added to the top or bottom - /// Delegations added to the top yield a new total - #[derive(Clone, Copy, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] - pub enum DelegatorAdded { - AddedToTop { new_total: B }, - AddedToBottom, - } - - impl< - A: Ord + Clone + sp_std::fmt::Debug, - B: AtLeast32BitUnsigned - + Ord - + Copy - + sp_std::ops::AddAssign - + sp_std::ops::SubAssign - + sp_std::fmt::Debug, - > CollatorCandidate - { - pub fn is_active(&self) -> bool { - self.state == CollatorStatus::Active - } - } - - impl From> for CollatorSnapshot { - fn from(other: CollatorCandidate) -> CollatorSnapshot { - CollatorSnapshot { - bond: other.bond, - delegations: other.top_delegations, - total: other.total_counted, - } - } - } - - #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] - pub enum DelegatorStatus { - /// Active with no scheduled exit - Active, - /// Schedule exit to revoke all ongoing delegations - Leaving(RoundIndex), - } - - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Delegator state - pub struct Delegator { - /// Delegator account - pub id: AccountId, - /// All current delegations - pub delegations: OrderedSet>, - /// Total balance locked for this delegator - pub total: Balance, - /// Requests to change delegations, relevant iff active - pub requests: PendingDelegationRequests, - /// Status for this delegator - pub status: DelegatorStatus, - } - - // Temporary manual implementation for migration testing purposes - impl PartialEq for Delegator { - fn eq(&self, other: &Self) -> bool { - let must_be_true = self.id == other.id - && self.total == other.total - && self.requests == other.requests - && self.status == other.status; - if !must_be_true { - return false; - } - for ( - Bond { - owner: o1, - amount: a1, - }, - Bond { - owner: o2, - amount: a2, - }, - ) in self.delegations.0.iter().zip(other.delegations.0.iter()) - { - if o1 != o2 || a1 != a2 { - return false; - } - } - true - } - } - - impl< - AccountId: Ord + Clone, - Balance: Copy - + sp_std::ops::AddAssign - + sp_std::ops::Add - + sp_std::ops::SubAssign - + sp_std::ops::Sub - + Ord - + Zero - + Default, - > Delegator - { - pub fn new(id: AccountId, collator: AccountId, amount: Balance) -> Self { - Delegator { - id, - delegations: OrderedSet::from(vec![Bond { - owner: collator, - amount, - }]), - total: amount, - requests: PendingDelegationRequests::new(), - status: DelegatorStatus::Active, - } - } - pub fn requests(&self) -> BTreeMap> { - self.requests.requests.clone() - } - pub fn is_active(&self) -> bool { - matches!(self.status, DelegatorStatus::Active) - } - pub fn is_leaving(&self) -> bool { - matches!(self.status, DelegatorStatus::Leaving(_)) - } - /// Can only leave if the current round is less than or equal to scheduled execution round - /// - returns None if not in leaving state - pub fn can_execute_leave(&self, delegation_weight_hint: u32) -> DispatchResult { - ensure!( - delegation_weight_hint >= (self.delegations.0.len() as u32), - Error::::TooLowDelegationCountToLeaveDelegators - ); - if let DelegatorStatus::Leaving(when) = self.status { - ensure!( - >::get().current >= when, - Error::::DelegatorCannotLeaveYet - ); - Ok(()) - } else { - Err(Error::::DelegatorNotLeaving.into()) - } - } - /// Set status to leaving - pub(crate) fn set_leaving(&mut self, when: RoundIndex) { - self.status = DelegatorStatus::Leaving(when); - } - /// Schedule status to exit - pub fn schedule_leave(&mut self) -> (RoundIndex, RoundIndex) { - let now = >::get().current; - let when = now + T::LeaveDelegatorsDelay::get(); - self.set_leaving(when); - (now, when) - } - /// Set delegator status to active - pub fn cancel_leave(&mut self) { - self.status = DelegatorStatus::Active - } - pub fn add_delegation(&mut self, bond: Bond) -> bool { - let amt = bond.amount; - if self.delegations.insert(bond) { - self.total += amt; - true - } else { - false - } - } - // Return Some(remaining balance), must be more than MinDelegatorStk - // Return None if delegation not found - pub fn rm_delegation(&mut self, collator: &AccountId) -> Option { - let mut amt: Option = None; - let delegations = self - .delegations - .0 - .iter() - .filter_map(|x| { - if &x.owner == collator { - amt = Some(x.amount); - None - } else { - Some(x.clone()) - } - }) - .collect(); - if let Some(balance) = amt { - self.delegations = OrderedSet::from(delegations); - self.total -= balance; - Some(self.total) - } else { - None - } - } - pub fn increase_delegation( - &mut self, - candidate: AccountId, - amount: Balance, - ) -> DispatchResult - where - BalanceOf: From, - T::AccountId: From, - Delegator>: From>, - { - let delegator_id: T::AccountId = self.id.clone().into(); - let candidate_id: T::AccountId = candidate.clone().into(); - let balance_amt: BalanceOf = amount.into(); - // increase delegation - for x in &mut self.delegations.0 { - if x.owner == candidate { - let before_amount: BalanceOf = x.amount.into(); - x.amount += amount; - self.total += amount; - // update collator state delegation - let mut collator_state = - >::get(&candidate_id).ok_or(Error::::CandidateDNE)?; - T::Currency::reserve(&self.id.clone().into(), balance_amt)?; - let before = collator_state.total_counted; - let in_top = collator_state.increase_delegation::( - &candidate_id, - delegator_id.clone(), - before_amount, - balance_amt, - )?; - let after = collator_state.total_counted; - if collator_state.is_active() && (before != after) { - Pallet::::update_active(candidate_id.clone(), after); - } - >::insert(&candidate_id, collator_state); - let new_total_staked = >::get().saturating_add(balance_amt); - >::put(new_total_staked); - let nom_st: Delegator> = self.clone().into(); - >::insert(&delegator_id, nom_st); - Pallet::::deposit_event(Event::DelegationIncreased( - delegator_id, - candidate_id, - balance_amt, - in_top, - )); - return Ok(()); - } - } - Err(Error::::DelegationDNE.into()) - } - /// Schedule decrease delegation - pub fn schedule_decrease_delegation( - &mut self, - collator: AccountId, - less: Balance, - ) -> Result - where - BalanceOf: Into + From, - { - // get delegation amount - let Bond { amount, .. } = self - .delegations - .0 - .iter() - .find(|b| b.owner == collator) - .ok_or(Error::::DelegationDNE)?; - ensure!(*amount > less, Error::::DelegatorBondBelowMin); - let expected_amt: BalanceOf = (*amount - less).into(); - ensure!( - expected_amt >= T::MinDelegation::get(), - Error::::DelegationBelowMin - ); - // Net Total is total after pending orders are executed - let net_total = self.total - self.requests.less_total; - // Net Total is always >= MinDelegatorStk - let max_subtracted_amount = net_total - T::MinDelegatorStk::get().into(); - ensure!( - less <= max_subtracted_amount, - Error::::DelegatorBondBelowMin - ); - let when = >::get().current + T::DelegationBondLessDelay::get(); - self.requests.bond_less::(collator, less, when)?; - Ok(when) - } - /// Temporary function to migrate revocations - pub fn hotfix_set_revoke(&mut self, collator: AccountId, when: RoundIndex) { - // get delegation amount - let maybe_bond = self.delegations.0.iter().find(|b| b.owner == collator); - if let Some(Bond { amount, .. }) = maybe_bond { - // add revocation to pending requests - if let Err(e) = self.requests.revoke::(collator, *amount, when) { - log::warn!("Migrate revocation request failed with error: {:?}", e); - } - } else { - log::warn!("Migrate revocation request failed because delegation DNE"); - } - } - /// Schedule revocation for the given collator - pub fn schedule_revoke( - &mut self, - collator: AccountId, - ) -> Result<(RoundIndex, RoundIndex), DispatchError> - where - BalanceOf: Into, - { - // get delegation amount - let Bond { amount, .. } = self - .delegations - .0 - .iter() - .find(|b| b.owner == collator) - .ok_or(Error::::DelegationDNE)?; - let now = >::get().current; - let when = now + T::RevokeDelegationDelay::get(); - // add revocation to pending requests - self.requests.revoke::(collator, *amount, when)?; - Ok((now, when)) - } - /// Execute pending delegation change request - pub fn execute_pending_request(&mut self, candidate: AccountId) -> DispatchResult - where - BalanceOf: From + Into, - T::AccountId: From, - Delegator>: From>, - { - let now = >::get().current; - let DelegationRequest { - amount, - action, - when_executable, - .. - } = self - .requests - .requests - .remove(&candidate) - .ok_or(Error::::PendingDelegationRequestDNE)?; - ensure!( - when_executable <= now, - Error::::PendingDelegationRequestNotDueYet - ); - let (balance_amt, candidate_id, delegator_id): ( - BalanceOf, - T::AccountId, - T::AccountId, - ) = ( - amount.into(), - candidate.clone().into(), - self.id.clone().into(), - ); - match action { - DelegationChange::Revoke => { - // revoking last delegation => leaving set of delegators - let leaving = if self.delegations.0.len() == 1usize { - true - } else { - ensure!( - self.total - T::MinDelegatorStk::get().into() >= amount, - Error::::DelegatorBondBelowMin - ); - false - }; - // remove from pending requests - self.requests.less_total -= amount; - self.requests.revocations_count -= 1u32; - // remove delegation from delegator state - self.rm_delegation(&candidate); - // remove delegation from collator state delegations - Pallet::::delegator_leaves_candidate( - candidate_id.clone(), - delegator_id.clone(), - balance_amt, - )?; - Pallet::::deposit_event(Event::DelegationRevoked( - delegator_id.clone(), - candidate_id, - balance_amt, - )); - if leaving { - >::remove(&delegator_id); - Pallet::::deposit_event(Event::DelegatorLeft(delegator_id, balance_amt)); - } else { - let nom_st: Delegator> = self.clone().into(); - >::insert(&delegator_id, nom_st); - } - Ok(()) - } - DelegationChange::Decrease => { - // remove from pending requests - self.requests.less_total -= amount; - // decrease delegation - for x in &mut self.delegations.0 { - if x.owner == candidate { - if x.amount > amount { - let amount_before: BalanceOf = x.amount.into(); - x.amount -= amount; - self.total -= amount; - let new_total: BalanceOf = self.total.into(); - ensure!( - new_total >= T::MinDelegation::get(), - Error::::DelegationBelowMin - ); - ensure!( - new_total >= T::MinDelegatorStk::get(), - Error::::DelegatorBondBelowMin - ); - let mut collator = >::get(&candidate_id) - .ok_or(Error::::CandidateDNE)?; - T::Currency::unreserve(&delegator_id, balance_amt); - let before = collator.total_counted; - // need to go into decrease_delegation - let in_top = collator.decrease_delegation::( - &candidate_id, - delegator_id.clone(), - amount_before, - balance_amt, - )?; - let after = collator.total_counted; - if collator.is_active() && (before != after) { - Pallet::::update_active(candidate_id.clone(), after); - } - >::insert(&candidate_id, collator); - let new_total_staked = - >::get().saturating_sub(balance_amt); - >::put(new_total_staked); - let nom_st: Delegator> = - self.clone().into(); - >::insert(&delegator_id, nom_st); - Pallet::::deposit_event(Event::DelegationDecreased( - delegator_id, - candidate_id, - balance_amt, - in_top, - )); - return Ok(()); - } else { - // must rm entire delegation if x.amount <= less or cancel request - return Err(Error::::DelegationBelowMin.into()); - } - } - } - Err(Error::::DelegationDNE.into()) - } - } - } - /// Cancel pending delegation change request - pub fn cancel_pending_request( - &mut self, - candidate: AccountId, - ) -> Result, DispatchError> { - let order = self - .requests - .requests - .remove(&candidate) - .ok_or(Error::::PendingDelegationRequestDNE)?; - match order.action { - DelegationChange::Revoke => { - self.requests.revocations_count -= 1u32; - self.requests.less_total -= order.amount; - } - DelegationChange::Decrease => { - self.requests.less_total -= order.amount; - } - } - Ok(order) - } - } - - #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Changes requested by the delegator - /// - limit of 1 ongoing change per delegation - pub enum DelegationChange { - Revoke, - Decrease, - } - - #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] - pub struct DelegationRequest { - pub collator: AccountId, - pub amount: Balance, - pub when_executable: RoundIndex, - pub action: DelegationChange, - } - - #[derive(Clone, Encode, PartialEq, Decode, RuntimeDebug, TypeInfo)] - /// Pending requests to mutate delegations for each delegator - pub struct PendingDelegationRequests { - /// Number of pending revocations (necessary for determining whether revoke is exit) - pub revocations_count: u32, - /// Map from collator -> Request (enforces at most 1 pending request per delegation) - pub requests: BTreeMap>, - /// Sum of pending revocation amounts + bond less amounts - pub less_total: Balance, - } - - impl Default for PendingDelegationRequests { - fn default() -> PendingDelegationRequests { - PendingDelegationRequests { - revocations_count: 0u32, - requests: BTreeMap::new(), - less_total: B::zero(), - } - } - } - - impl< - A: Ord + Clone, - B: Zero - + Ord - + Copy - + Clone - + sp_std::ops::AddAssign - + sp_std::ops::Add - + sp_std::ops::SubAssign - + sp_std::ops::Sub, - > PendingDelegationRequests - { - /// New default (empty) pending requests - pub fn new() -> PendingDelegationRequests { - PendingDelegationRequests::default() - } - /// Add bond less order to pending requests, only succeeds if returns true - /// - limit is the maximum amount allowed that can be subtracted from the delegation - /// before it would be below the minimum delegation amount - pub fn bond_less( - &mut self, - collator: A, - amount: B, - when_executable: RoundIndex, - ) -> DispatchResult { - ensure!( - self.requests.get(&collator).is_none(), - Error::::PendingDelegationRequestAlreadyExists - ); - self.requests.insert( - collator.clone(), - DelegationRequest { - collator, - amount, - when_executable, - action: DelegationChange::Decrease, - }, - ); - self.less_total += amount; - Ok(()) - } - /// Add revoke order to pending requests - /// - limit is the maximum amount allowed that can be subtracted from the delegation - /// before it would be below the minimum delegation amount - pub fn revoke( - &mut self, - collator: A, - amount: B, - when_executable: RoundIndex, - ) -> DispatchResult { - ensure!( - self.requests.get(&collator).is_none(), - Error::::PendingDelegationRequestAlreadyExists - ); - self.requests.insert( - collator.clone(), - DelegationRequest { - collator, - amount, - when_executable, - action: DelegationChange::Revoke, - }, - ); - self.revocations_count += 1u32; - self.less_total += amount; - Ok(()) - } - } - - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] - /// DEPRECATED in favor of Delegator - /// Nominator state - pub struct Nominator2 { - /// All current delegations - pub delegations: OrderedSet>, - /// Delegations scheduled to be revoked - pub revocations: OrderedSet, - /// Total balance locked for this nominator - pub total: Balance, - /// Total number of revocations scheduled to be executed - pub scheduled_revocations_count: u32, - /// Total amount to be unbonded once revocations are executed - pub scheduled_revocations_total: Balance, - /// Status for this nominator - pub status: DelegatorStatus, - } - - // /// Temporary function to migrate state - // pub(crate) fn migrate_nominator_to_delegator_state( - // id: T::AccountId, - // nominator: Nominator2>, - // ) -> Delegator> { - // Delegator { - // id, - // delegations: nominator.delegations, - // total: nominator.total, - // requests: PendingDelegationRequests::new(), - // status: nominator.status, - // } - // } - - #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// The current round index and transition information - pub struct RoundInfo { - /// Current round index - pub current: RoundIndex, - /// The first block of the current round - pub first: BlockNumber, - /// The length of the current round in number of blocks - pub length: u32, - } - impl< - B: Copy - + sp_std::ops::Add - + sp_std::ops::Sub - + From - + PartialOrd, - > RoundInfo - { - pub fn new(current: RoundIndex, first: B, length: u32) -> RoundInfo { - RoundInfo { - current, - first, - length, - } - } - /// Check if the round should be updated - pub fn should_update(&self, now: B) -> bool { - now - self.first >= self.length.into() - } - /// New round - pub fn update(&mut self, now: B) { - self.current += 1u32; - self.first = now; - } - } - impl< - B: Copy - + sp_std::ops::Add - + sp_std::ops::Sub - + From - + PartialOrd, - > Default for RoundInfo - { - fn default() -> RoundInfo { - RoundInfo::new(1u32, 1u32.into(), 20u32) - } - } - - #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] - /// Reserve information { account, percent_of_inflation } - pub struct ParachainBondConfig { - /// Account which receives funds intended for parachain bond - pub account: AccountId, - /// Percent of inflation set aside for parachain bond account - pub percent: Percent, - } - impl Default for ParachainBondConfig { - fn default() -> ParachainBondConfig { - ParachainBondConfig { - account: A::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) - .expect("infinite length input; no invalid inputs for type; qed"), - percent: Percent::zero(), - } - } - } - - pub(crate) type RoundIndex = u32; - type RewardPoint = u32; - pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - - /// Configuration trait of this pallet. - #[pallet::config] - pub trait Config: frame_system::Config { - /// Overarching event type - type Event: From> + IsType<::Event>; - /// The currency type - type Currency: Currency + ReservableCurrency; - /// The origin for monetary governance - type MonetaryGovernanceOrigin: EnsureOrigin; - /// Minimum number of blocks per round - #[pallet::constant] - type MinBlocksPerRound: Get; - /// Default number of blocks per round at genesis - #[pallet::constant] - type DefaultBlocksPerRound: Get; - /// Number of rounds that candidates remain bonded before exit request is executable - #[pallet::constant] - type LeaveCandidatesDelay: Get; - /// Number of rounds candidate requests to decrease self-bond must wait to be executable - #[pallet::constant] - type CandidateBondLessDelay: Get; - /// Number of rounds that delegators remain bonded before exit request is executable - #[pallet::constant] - type LeaveDelegatorsDelay: Get; - /// Number of rounds that delegations remain bonded before revocation request is executable - #[pallet::constant] - type RevokeDelegationDelay: Get; - /// Number of rounds that delegation less requests must wait before executable - #[pallet::constant] - type DelegationBondLessDelay: Get; - /// Number of rounds after which block authors are rewarded - #[pallet::constant] - type RewardPaymentDelay: Get; - /// Minimum number of selected candidates every round - #[pallet::constant] - type MinSelectedCandidates: Get; - /// Maximum top delegations counted per candidate - #[pallet::constant] - type MaxTopDelegationsPerCandidate: Get; - /// Maximum bottom delegations (not counted) per candidate - #[pallet::constant] - type MaxBottomDelegationsPerCandidate: Get; - /// Maximum delegations per delegator - #[pallet::constant] - type MaxDelegationsPerDelegator: Get; - /// Default commission due to collators, is `CollatorCommission` storage value in genesis - #[pallet::constant] - type DefaultCollatorCommission: Get; - /// Default percent of inflation set aside for parachain bond account - #[pallet::constant] - type DefaultParachainBondReservePercent: Get; - /// Minimum stake required for any candidate to be in `SelectedCandidates` for the round - #[pallet::constant] - type MinCollatorStk: Get>; - /// Minimum stake required for any account to be a collator candidate - #[pallet::constant] - type MinCandidateStk: Get>; - /// Minimum stake for any registered on-chain account to delegate - #[pallet::constant] - type MinDelegation: Get>; - /// Minimum stake for any registered on-chain account to be a delegator - #[pallet::constant] - type MinDelegatorStk: Get>; - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; - } - - #[pallet::error] - pub enum Error { - DelegatorDNE, - DelegatorDNEinTopNorBottom, - DelegatorDNEInDelegatorSet, - CandidateDNE, - DelegationDNE, - DelegatorExists, - CandidateExists, - CandidateBondBelowMin, - InsufficientBalance, - DelegatorBondBelowMin, - DelegationBelowMin, - AlreadyOffline, - AlreadyActive, - DelegatorAlreadyLeaving, - DelegatorNotLeaving, - DelegatorCannotLeaveYet, - CannotDelegateIfLeaving, - CandidateAlreadyLeaving, - CandidateNotLeaving, - CandidateCannotLeaveYet, - CannotGoOnlineIfLeaving, - ExceedMaxDelegationsPerDelegator, - AlreadyDelegatedCandidate, - InvalidSchedule, - CannotSetBelowMin, - RoundLengthMustBeAtLeastTotalSelectedCollators, - NoWritingSameValue, - TooLowCandidateCountWeightHintJoinCandidates, - TooLowCandidateCountWeightHintCancelLeaveCandidates, - TooLowCandidateCountToLeaveCandidates, - TooLowDelegationCountToDelegate, - TooLowCandidateDelegationCountToDelegate, - TooLowCandidateDelegationCountToLeaveCandidates, - TooLowDelegationCountToLeaveDelegators, - PendingCandidateRequestsDNE, - PendingCandidateRequestAlreadyExists, - PendingCandidateRequestNotDueYet, - PendingDelegationRequestDNE, - PendingDelegationRequestAlreadyExists, - PendingDelegationRequestNotDueYet, - CannotDelegateLessThanLowestBottomWhenBottomIsFull, - } - - #[pallet::event] - #[pallet::generate_deposit(pub(crate) fn deposit_event)] - pub enum Event { - /// Starting Block, Round, Number of Collators Selected, Total Balance - NewRound(T::BlockNumber, RoundIndex, u32, BalanceOf), - /// Account, Amount Locked, New Total Amt Locked - JoinedCollatorCandidates(T::AccountId, BalanceOf, BalanceOf), - /// Round, Collator Account, Total Exposed Amount (includes all delegations) - CollatorChosen(RoundIndex, T::AccountId, BalanceOf), - /// Candidate, Amount To Decrease, Round at which request can be executed by caller - CandidateBondLessRequested(T::AccountId, BalanceOf, RoundIndex), - /// Candidate, Amount, New Bond Total - CandidateBondedMore(T::AccountId, BalanceOf, BalanceOf), - /// Candidate, Amount, New Bond - CandidateBondedLess(T::AccountId, BalanceOf, BalanceOf), - /// Candidate - CandidateWentOffline(T::AccountId), - /// Candidate - CandidateBackOnline(T::AccountId), - /// Round At Which Exit Is Allowed, Candidate, Scheduled Exit - CandidateScheduledExit(RoundIndex, T::AccountId, RoundIndex), - /// Candidate - CancelledCandidateExit(T::AccountId), - /// Candidate, Amount, Round at which could be executed - CancelledCandidateBondLess(T::AccountId, BalanceOf, RoundIndex), - /// Ex-Candidate, Amount Unlocked, New Total Amt Locked - CandidateLeft(T::AccountId, BalanceOf, BalanceOf), - /// Delegator, Candidate, Amount to be decreased, Round at which can be executed - DelegationDecreaseScheduled(T::AccountId, T::AccountId, BalanceOf, RoundIndex), - // Delegator, Candidate, Amount, If in top delegations for candidate after increase - DelegationIncreased(T::AccountId, T::AccountId, BalanceOf, bool), - // Delegator, Candidate, Amount, If in top delegations for candidate after decrease - DelegationDecreased(T::AccountId, T::AccountId, BalanceOf, bool), - /// Round, Delegator, Scheduled Exit - DelegatorExitScheduled(RoundIndex, T::AccountId, RoundIndex), - /// Round, Delegator, Candidate, Scheduled Exit - DelegationRevocationScheduled(RoundIndex, T::AccountId, T::AccountId, RoundIndex), - /// Delegator, Amount Unstaked - DelegatorLeft(T::AccountId, BalanceOf), - /// Delegator, Candidate, Amount Unstaked - DelegationRevoked(T::AccountId, T::AccountId, BalanceOf), - /// Delegator, Candidate, Amount Unstaked - DelegationKicked(T::AccountId, T::AccountId, BalanceOf), - /// Delegator - DelegatorExitCancelled(T::AccountId), - /// Delegator, Cancelled Request - CancelledDelegationRequest(T::AccountId, DelegationRequest>), - /// Delegator, Amount Locked, Candidate, Delegator Position with New Total Counted if in Top - Delegation( - T::AccountId, - BalanceOf, - T::AccountId, - DelegatorAdded>, - ), - /// Delegator, Candidate, Amount Unstaked, New Total Amt Staked for Candidate - DelegatorLeftCandidate(T::AccountId, T::AccountId, BalanceOf, BalanceOf), - /// Paid the account (delegator or collator) the balance as liquid rewards - Rewarded(T::AccountId, BalanceOf), - /// Transferred to account which holds funds reserved for parachain bond - ReservedForParachainBond(T::AccountId, BalanceOf), - /// Account (re)set for parachain bond treasury [old, new] - ParachainBondAccountSet(T::AccountId, T::AccountId), - /// Percent of inflation reserved for parachain bond (re)set [old, new] - ParachainBondReservePercentSet(Percent, Percent), - /// Annual inflation input (first 3) was used to derive new per-round inflation (last 3) - InflationSet(Perbill, Perbill, Perbill, Perbill, Perbill, Perbill), - /// Staking expectations set - StakeExpectationsSet(BalanceOf, BalanceOf, BalanceOf), - /// Set total selected candidates to this value [old, new] - TotalSelectedSet(u32, u32), - /// Set collator commission to this value [old, new] - CollatorCommissionSet(Perbill, Perbill), - /// Set blocks per round [current_round, first_block, old, new, new_per_round_inflation] - BlocksPerRoundSet( - RoundIndex, - T::BlockNumber, - u32, - u32, - Perbill, - Perbill, - Perbill, - ), - } - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(n: T::BlockNumber) -> Weight { - let mut weight = T::WeightInfo::base_on_initialize(); - - let mut round = >::get(); - if round.should_update(n) { - // mutate round - round.update(n); - // pay all stakers for T::RewardPaymentDelay rounds ago - Self::prepare_staking_payouts(round.current); - // select top collator candidates for next round - let (collator_count, delegation_count, total_staked) = - Self::select_top_candidates(round.current); - // start next round - >::put(round); - // snapshot total stake - >::insert(round.current, >::get()); - Self::deposit_event(Event::NewRound( - round.first, - round.current, - collator_count, - total_staked, - )); - weight += - T::WeightInfo::round_transition_on_initialize(collator_count, delegation_count); - } - - weight += Self::handle_delayed_payouts(round.current); - - weight - } - } - - #[pallet::storage] - #[pallet::getter(fn collator_commission)] - /// Commission percent taken off of rewards for all collators - type CollatorCommission = StorageValue<_, Perbill, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn total_selected)] - /// The total candidates selected every round - type TotalSelected = StorageValue<_, u32, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn parachain_bond_info)] - /// Parachain bond config info { account, percent_of_inflation } - type ParachainBondInfo = - StorageValue<_, ParachainBondConfig, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn round)] - /// Current round index and next round scheduled transition - pub(crate) type Round = StorageValue<_, RoundInfo, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn nominator_state2)] - /// DEPRECATED in favor of DelegatorState - /// Get nominator state associated with an account if account is nominating else None - pub(crate) type NominatorState2 = StorageMap< - _, - Twox64Concat, - T::AccountId, - Nominator2>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn delegator_state)] - /// Get delegator state associated with an account if account is delegating else None - pub(crate) type DelegatorState = StorageMap< - _, - Twox64Concat, - T::AccountId, - Delegator>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn candidate_state)] - /// DEPRECATED - /// Get collator candidate state associated with an account if account is a candidate else None - pub(crate) type CandidateState = StorageMap< - _, - Twox64Concat, - T::AccountId, - CollatorCandidate>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn candidate_info)] - /// Get collator candidate info associated with an account if account is candidate else None - pub(crate) type CandidateInfo = - StorageMap<_, Twox64Concat, T::AccountId, CandidateMetadata>, OptionQuery>; - - #[pallet::storage] - #[pallet::getter(fn top_delegations)] - /// Top delegations for collator candidate - pub(crate) type TopDelegations = StorageMap< - _, - Twox64Concat, - T::AccountId, - Delegations>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn bottom_delegations)] - /// Bottom delegations for collator candidate - pub(crate) type BottomDelegations = StorageMap< - _, - Twox64Concat, - T::AccountId, - Delegations>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn collator_state2)] - /// DEPRECATED in favor of CandidateState - /// Get collator state associated with an account if account is collating else None - pub(crate) type CollatorState2 = StorageMap< - _, - Twox64Concat, - T::AccountId, - Collator2>, - OptionQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn selected_candidates)] - /// The collator candidates selected for the current round - type SelectedCandidates = StorageValue<_, Vec, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn total)] - /// Total capital locked by this staking pallet - pub(crate) type Total = StorageValue<_, BalanceOf, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn candidate_pool)] - /// The pool of collator candidates, each with their total backing stake - pub(crate) type CandidatePool = - StorageValue<_, OrderedSet>>, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn at_stake)] - /// Snapshot of collator delegation stake at the start of the round - pub type AtStake = StorageDoubleMap< - _, - Twox64Concat, - RoundIndex, - Twox64Concat, - T::AccountId, - CollatorSnapshot>, - ValueQuery, - >; - - #[pallet::storage] - #[pallet::getter(fn delayed_payouts)] - /// Delayed payouts - pub type DelayedPayouts = - StorageMap<_, Twox64Concat, RoundIndex, DelayedPayout>, OptionQuery>; - - #[pallet::storage] - #[pallet::getter(fn staked)] - /// Total counted stake for selected candidates in the round - pub type Staked = StorageMap<_, Twox64Concat, RoundIndex, BalanceOf, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn inflation_config)] - /// Inflation configuration - pub type InflationConfig = StorageValue<_, InflationInfo>, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn points)] - /// Total points awarded to collators for block production in the round - pub type Points = StorageMap<_, Twox64Concat, RoundIndex, RewardPoint, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn awarded_pts)] - /// Points for each collator per round - pub type AwardedPts = StorageDoubleMap< - _, - Twox64Concat, - RoundIndex, - Twox64Concat, - T::AccountId, - RewardPoint, - ValueQuery, - >; - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub candidates: Vec<(T::AccountId, BalanceOf)>, - /// Vec of tuples of the format (delegator AccountId, collator AccountId, delegation Amount) - pub delegations: Vec<(T::AccountId, T::AccountId, BalanceOf)>, - pub inflation_config: InflationInfo>, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - Self { - candidates: vec![], - delegations: vec![], - ..Default::default() - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - >::put(self.inflation_config.clone()); - let mut candidate_count = 0u32; - // Initialize the candidates - for &(ref candidate, balance) in &self.candidates { - assert!( - T::Currency::free_balance(candidate) >= balance, - "Account does not have enough balance to bond as a candidate." - ); - candidate_count += 1u32; - if let Err(error) = >::join_candidates( - T::Origin::from(Some(candidate.clone()).into()), - balance, - candidate_count, - ) { - log::warn!("Join candidates failed in genesis with error {:?}", error); - } else { - candidate_count += 1u32; - } - } - let mut col_delegator_count: BTreeMap = BTreeMap::new(); - let mut del_delegation_count: BTreeMap = BTreeMap::new(); - // Initialize the delegations - for &(ref delegator, ref target, balance) in &self.delegations { - assert!( - T::Currency::free_balance(delegator) >= balance, - "Account does not have enough balance to place delegation." - ); - let cd_count = if let Some(x) = col_delegator_count.get(target) { - *x - } else { - 0u32 - }; - let dd_count = if let Some(x) = del_delegation_count.get(delegator) { - *x - } else { - 0u32 - }; - if let Err(error) = >::delegate( - T::Origin::from(Some(delegator.clone()).into()), - target.clone(), - balance, - cd_count, - dd_count, - ) { - log::warn!("Delegate failed in genesis with error {:?}", error); - } else { - if let Some(x) = col_delegator_count.get_mut(target) { - *x += 1u32; - } else { - col_delegator_count.insert(target.clone(), 1u32); - }; - if let Some(x) = del_delegation_count.get_mut(delegator) { - *x += 1u32; - } else { - del_delegation_count.insert(delegator.clone(), 1u32); - }; - } - } - // Set collator commission to default config - >::put(T::DefaultCollatorCommission::get()); - // Set parachain bond config to default config - >::put(ParachainBondConfig { - // must be set soon; if not => due inflation will be sent to collators/delegators - account: T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) - .expect("infinite length input; no invalid inputs for type; qed"), - percent: T::DefaultParachainBondReservePercent::get(), - }); - // Set total selected candidates to minimum config - >::put(T::MinSelectedCandidates::get()); - // Choose top TotalSelected collator candidates - let (v_count, _, total_staked) = >::select_top_candidates(1u32); - // Start Round 1 at Block 0 - let round: RoundInfo = - RoundInfo::new(1u32, 0u32.into(), T::DefaultBlocksPerRound::get()); - >::put(round); - // Snapshot total stake - >::insert(1u32, >::get()); - >::deposit_event(Event::NewRound( - T::BlockNumber::zero(), - 1u32, - v_count, - total_staked, - )); - } - } - - #[pallet::call] - impl Pallet { - #[pallet::weight( + use crate::{set::OrderedSet, InflationInfo, Range, WeightInfo}; + use frame_support::pallet_prelude::*; + use frame_support::traits::{Currency, Get, Imbalance, ReservableCurrency}; + use frame_system::pallet_prelude::*; + use parity_scale_codec::{Decode, Encode}; + use scale_info::TypeInfo; + use sp_runtime::{ + traits::{AtLeast32BitUnsigned, Saturating, Zero}, + Perbill, Percent, RuntimeDebug, + }; + use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; + + /// Pallet for parachain staking + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(PhantomData); + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + pub struct Bond { + pub owner: AccountId, + pub amount: Balance, + } + + impl Default for Bond { + fn default() -> Bond { + Bond { + owner: A::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + amount: B::default(), + } + } + } + + impl Bond { + fn from_owner(owner: A) -> Self { + Bond { + owner, + amount: B::default(), + } + } + } + + impl Eq for Bond {} + + impl Ord for Bond { + fn cmp(&self, other: &Self) -> Ordering { + self.owner.cmp(&other.owner) + } + } + + impl PartialOrd for Bond { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + + impl PartialEq for Bond { + fn eq(&self, other: &Self) -> bool { + self.owner == other.owner + } + } + + #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// The activity status of the collator + pub enum CollatorStatus { + /// Committed to be online and producing valid blocks (not equivocating) + Active, + /// Temporarily inactive and excused for inactivity + Idle, + /// Bonded until the inner round + Leaving(RoundIndex), + } + + impl Default for CollatorStatus { + fn default() -> CollatorStatus { + CollatorStatus::Active + } + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// Snapshot of collator state at the start of the round for which they are selected + pub struct CollatorSnapshot { + pub bond: Balance, + pub delegations: Vec>, + pub total: Balance, + } + + impl Default for CollatorSnapshot { + fn default() -> CollatorSnapshot { + CollatorSnapshot { + bond: B::default(), + delegations: Vec::new(), + total: B::default(), + } + } + } + + #[derive(Default, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Info needed to make delayed payments to stakers after round end + pub struct DelayedPayout { + /// Total round reward (result of compute_issuance() at round end) + pub round_issuance: Balance, + /// The total inflation paid this round to stakers (e.g. less parachain bond fund) + pub total_staking_reward: Balance, + /// Snapshot of collator commission rate at the end of the round + pub collator_commission: Perbill, + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// DEPRECATED + /// Collator state with commission fee, bonded stake, and delegations + pub struct Collator2 { + /// The account of this collator + pub id: AccountId, + /// This collator's self stake. + pub bond: Balance, + /// Set of all nominator AccountIds (to prevent >1 nomination per AccountId) + pub nominators: OrderedSet, + /// Top T::MaxDelegatorsPerCollator::get() nominators, ordered greatest to least + pub top_nominators: Vec>, + /// Bottom nominators (unbounded), ordered least to greatest + pub bottom_nominators: Vec>, + /// Sum of top delegations + self.bond + pub total_counted: Balance, + /// Sum of all delegations + self.bond = (total_counted + uncounted) + pub total_backing: Balance, + /// Current status of the collator + pub state: CollatorStatus, + } + + impl From> for CollatorCandidate { + fn from(other: Collator2) -> CollatorCandidate { + CollatorCandidate { + id: other.id, + bond: other.bond, + delegators: other.nominators, + top_delegations: other.top_nominators, + bottom_delegations: other.bottom_nominators, + total_counted: other.total_counted, + total_backing: other.total_backing, + request: None, + state: other.state, + } + } + } + + #[derive(PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Request scheduled to change the collator candidate self-bond + pub struct CandidateBondLessRequest { + pub amount: Balance, + pub when_executable: RoundIndex, + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// DEPRECATED, replaced by `CandidateMetadata` and two storage instances of `Delegations` + /// Collator candidate state with self bond + delegations + pub struct CollatorCandidate { + /// The account of this collator + pub id: AccountId, + /// This collator's self stake. + pub bond: Balance, + /// Set of all delegator AccountIds (to prevent >1 delegation per AccountId) + pub delegators: OrderedSet, + /// Top T::MaxDelegatorsPerCollator::get() delegations, ordered greatest to least + pub top_delegations: Vec>, + /// Bottom delegations (unbounded), ordered least to greatest + pub bottom_delegations: Vec>, + /// Sum of top delegations + self.bond + pub total_counted: Balance, + /// Sum of all delegations + self.bond = (total_counted + uncounted) + pub total_backing: Balance, + /// Maximum 1 pending request to decrease candidate self bond at any given time + pub request: Option>, + /// Current status of the collator + pub state: CollatorStatus, + } + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Type for top and bottom delegation storage item + pub struct Delegations { + pub delegations: Vec>, + pub total: Balance, + } + + impl Default for Delegations { + fn default() -> Delegations { + Delegations { + delegations: Vec::new(), + total: B::default(), + } + } + } + + impl + Delegations + { + pub fn sort_greatest_to_least(&mut self) { + self.delegations.sort_by(|a, b| b.amount.cmp(&a.amount)); + } + /// Insert sorted greatest to least and increase .total accordingly + /// Insertion respects first come first serve so new delegations are pushed after existing + /// delegations if the amount is the same + pub fn insert_sorted_greatest_to_least(&mut self, delegation: Bond) { + self.total = self.total.saturating_add(delegation.amount); + // if delegations nonempty && last_element == delegation.amount => push input and return + if !self.delegations.is_empty() { + // if last_element == delegation.amount => push the delegation and return early + if self.delegations[self.delegations.len() - 1].amount == delegation.amount { + self.delegations.push(delegation); + // early return + return; + } + } + // else binary search insertion + match self + .delegations + .binary_search_by(|x| delegation.amount.cmp(&x.amount)) + { + // sorted insertion on sorted vec + // enforces first come first serve for equal bond amounts + Ok(i) => { + let mut new_index = i + 1; + while new_index <= (self.delegations.len() - 1) { + if self.delegations[new_index].amount == delegation.amount { + new_index += 1; + } else { + self.delegations.insert(new_index, delegation); + return; + } + } + self.delegations.push(delegation) + } + Err(i) => self.delegations.insert(i, delegation), + } + } + /// Return the capacity status for top delegations + pub fn top_capacity(&self) -> CapacityStatus { + match &self.delegations { + x if x.len() as u32 >= T::MaxTopDelegationsPerCandidate::get() => { + CapacityStatus::Full + } + x if x.is_empty() => CapacityStatus::Empty, + _ => CapacityStatus::Partial, + } + } + /// Return the capacity status for bottom delegations + pub fn bottom_capacity(&self) -> CapacityStatus { + match &self.delegations { + x if x.len() as u32 >= T::MaxBottomDelegationsPerCandidate::get() => { + CapacityStatus::Full + } + x if x.is_empty() => CapacityStatus::Empty, + _ => CapacityStatus::Partial, + } + } + /// Return last delegation amount without popping the delegation + pub fn lowest_delegation_amount(&self) -> Balance { + self.delegations + .last() + .map(|x| x.amount) + .unwrap_or(Balance::zero()) + } + /// Return highest delegation amount + pub fn highest_delegation_amount(&self) -> Balance { + self.delegations + .first() + .map(|x| x.amount) + .unwrap_or(Balance::zero()) + } + } + + #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Capacity status for top or bottom delegations + pub enum CapacityStatus { + /// Reached capacity + Full, + /// Empty aka contains no delegations + Empty, + /// Partially full (nonempty and not full) + Partial, + } + + #[derive(Encode, Decode, RuntimeDebug, TypeInfo)] + /// All candidate info except the top and bottom delegations + pub struct CandidateMetadata { + /// This candidate's self bond amount + pub bond: Balance, + /// Total number of delegations to this candidate + pub delegation_count: u32, + /// Self bond + sum of top delegations + pub total_counted: Balance, + /// The smallest top delegation amount + pub lowest_top_delegation_amount: Balance, + /// The highest bottom delegation amount + pub highest_bottom_delegation_amount: Balance, + /// The smallest bottom delegation amount + pub lowest_bottom_delegation_amount: Balance, + /// Capacity status for top delegations + pub top_capacity: CapacityStatus, + /// Capacity status for bottom delegations + pub bottom_capacity: CapacityStatus, + /// Maximum 1 pending request to decrease candidate self bond at any given time + pub request: Option>, + /// Current status of the collator + pub status: CollatorStatus, + } + + impl< + Balance: Copy + + Zero + + PartialOrd + + sp_std::ops::AddAssign + + sp_std::ops::SubAssign + + sp_std::ops::Sub + + sp_std::fmt::Debug, + > CandidateMetadata + { + pub fn new(bond: Balance) -> Self { + CandidateMetadata { + bond, + delegation_count: 0u32, + total_counted: bond, + lowest_top_delegation_amount: Zero::zero(), + highest_bottom_delegation_amount: Zero::zero(), + lowest_bottom_delegation_amount: Zero::zero(), + top_capacity: CapacityStatus::Empty, + bottom_capacity: CapacityStatus::Empty, + request: None, + status: CollatorStatus::Active, + } + } + pub fn is_active(&self) -> bool { + matches!(self.status, CollatorStatus::Active) + } + pub fn is_leaving(&self) -> bool { + matches!(self.status, CollatorStatus::Leaving(_)) + } + pub fn schedule_leave( + &mut self, + ) -> Result<(RoundIndex, RoundIndex), DispatchError> { + ensure!(!self.is_leaving(), Error::::CandidateAlreadyLeaving); + let now = >::get().current; + let when = now + T::LeaveCandidatesDelay::get(); + self.status = CollatorStatus::Leaving(when); + Ok((now, when)) + } + pub fn can_leave(&self) -> DispatchResult { + if let CollatorStatus::Leaving(when) = self.status { + ensure!( + >::get().current >= when, + Error::::CandidateCannotLeaveYet + ); + Ok(()) + } else { + Err(Error::::CandidateNotLeaving.into()) + } + } + pub fn go_offline(&mut self) { + self.status = CollatorStatus::Idle; + } + pub fn go_online(&mut self) { + self.status = CollatorStatus::Active; + } + pub fn bond_more(&mut self, who: T::AccountId, more: Balance) -> DispatchResult + where + BalanceOf: From, + { + T::Currency::reserve(&who, more.into())?; + let new_total = >::get().saturating_add(more.into()); + >::put(new_total); + self.bond += more; + self.total_counted += more; + >::deposit_event(Event::CandidateBondedMore( + who.clone(), + more.into(), + self.bond.into(), + )); + Ok(()) + } + /// Schedule executable decrease of collator candidate self bond + /// Returns the round at which the collator can execute the pending request + pub fn schedule_bond_less( + &mut self, + less: Balance, + ) -> Result + where + BalanceOf: Into, + { + // ensure no pending request + ensure!( + self.request.is_none(), + Error::::PendingCandidateRequestAlreadyExists + ); + // ensure bond above min after decrease + ensure!(self.bond > less, Error::::CandidateBondBelowMin); + ensure!( + self.bond - less >= T::MinCandidateStk::get().into(), + Error::::CandidateBondBelowMin + ); + let when_executable = >::get().current + T::CandidateBondLessDelay::get(); + self.request = Some(CandidateBondLessRequest { + amount: less, + when_executable, + }); + Ok(when_executable) + } + /// Execute pending request to decrease the collator self bond + /// Returns the event to be emitted + pub fn execute_bond_less(&mut self, who: T::AccountId) -> DispatchResult + where + BalanceOf: From, + { + let request = self + .request + .ok_or(Error::::PendingCandidateRequestsDNE)?; + ensure!( + request.when_executable <= >::get().current, + Error::::PendingCandidateRequestNotDueYet + ); + T::Currency::unreserve(&who, request.amount.into()); + let new_total_staked = >::get().saturating_sub(request.amount.into()); + >::put(new_total_staked); + // Arithmetic assumptions are self.bond > less && self.bond - less > CollatorMinBond + // (assumptions enforced by `schedule_bond_less`; if storage corrupts, must re-verify) + self.bond -= request.amount; + self.total_counted -= request.amount; + let event = Event::CandidateBondedLess( + who.clone().into(), + request.amount.into(), + self.bond.into(), + ); + // reset s.t. no pending request + self.request = None; + // update candidate pool value because it must change if self bond changes + if self.is_active() { + Pallet::::update_active(who.into(), self.total_counted.into()); + } + Pallet::::deposit_event(event); + Ok(()) + } + /// Cancel candidate bond less request + pub fn cancel_bond_less(&mut self, who: T::AccountId) -> DispatchResult + where + BalanceOf: From, + { + let request = self + .request + .ok_or(Error::::PendingCandidateRequestsDNE)?; + let event = Event::CancelledCandidateBondLess( + who.clone().into(), + request.amount.into(), + request.when_executable, + ); + self.request = None; + Pallet::::deposit_event(event); + Ok(()) + } + /// Reset top delegations metadata + pub fn reset_top_data( + &mut self, + top_delegations: &Delegations>, + ) where + BalanceOf: Into, + { + self.lowest_top_delegation_amount = top_delegations.lowest_delegation_amount().into(); + self.top_capacity = top_delegations.top_capacity::(); + self.total_counted = self.bond + top_delegations.total.into(); + } + /// Reset bottom delegations metadata + pub fn reset_bottom_data( + &mut self, + bottom_delegations: &Delegations>, + ) where + BalanceOf: Into, + { + self.lowest_bottom_delegation_amount = + bottom_delegations.lowest_delegation_amount().into(); + self.highest_bottom_delegation_amount = + bottom_delegations.highest_delegation_amount().into(); + self.bottom_capacity = bottom_delegations.bottom_capacity::(); + } + /// Add delegation + /// Returns whether delegator was added and an optional negative total counted remainder + /// for if a bottom delegation was kicked + /// MUST ensure no delegation exists for this candidate in the `DelegatorState` before call + pub fn add_delegation( + &mut self, + candidate: &T::AccountId, + delegation: Bond>, + ) -> Result<(DelegatorAdded, Option), DispatchError> + where + BalanceOf: Into, + { + let mut less_total_staked = None; + let delegator_added = match self.top_capacity { + CapacityStatus::Full => { + // top is full, insert into top iff the lowest_top < amount + if self.lowest_top_delegation_amount < delegation.amount.into() { + // bumps lowest top to the bottom inside this function call + less_total_staked = self.add_top_delegation::(candidate, delegation); + DelegatorAdded::AddedToTop { + new_total: self.total_counted, + } + } else { + // if bottom is full, only insert if greater than lowest bottom (which will + // be bumped out) + if matches!(self.bottom_capacity, CapacityStatus::Full) { + ensure!( + delegation.amount.into() > self.lowest_bottom_delegation_amount, + Error::::CannotDelegateLessThanLowestBottomWhenBottomIsFull + ); + // need to subtract from total staked + less_total_staked = Some(self.lowest_bottom_delegation_amount); + } + // insert into bottom + self.add_bottom_delegation::(false, candidate, delegation); + DelegatorAdded::AddedToBottom + } + } + // top is either empty or partially full + _ => { + self.add_top_delegation::(candidate, delegation); + DelegatorAdded::AddedToTop { + new_total: self.total_counted, + } + } + }; + Ok((delegator_added, less_total_staked)) + } + /// Add delegation to top delegation + /// Returns Option + /// Only call if lowest top delegation is less than delegation.amount || !top_full + pub fn add_top_delegation( + &mut self, + candidate: &T::AccountId, + delegation: Bond>, + ) -> Option + where + BalanceOf: Into, + { + let mut less_total_staked = None; + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo existence => TopDelegations existence"); + let max_top_delegations_per_candidate = T::MaxTopDelegationsPerCandidate::get(); + if top_delegations.delegations.len() as u32 == max_top_delegations_per_candidate { + // pop lowest top delegation + let new_bottom_delegation = top_delegations.delegations.pop().expect(""); + top_delegations.total = top_delegations + .total + .saturating_sub(new_bottom_delegation.amount); + if matches!(self.bottom_capacity, CapacityStatus::Full) { + less_total_staked = Some(self.lowest_bottom_delegation_amount); + } + self.add_bottom_delegation::(true, candidate, new_bottom_delegation); + } + // insert into top + top_delegations.insert_sorted_greatest_to_least(delegation); + // update candidate info + self.reset_top_data::(&top_delegations); + if less_total_staked.is_none() { + // only increment delegation count if we are not kicking a bottom delegation + self.delegation_count += 1u32; + } + >::insert(&candidate, top_delegations); + less_total_staked + } + /// Add delegation to bottom delegations + /// Check before call that if capacity is full, inserted delegation is higher than lowest + /// bottom delegation (and if so, need to adjust the total storage item) + /// CALLER MUST ensure(lowest_bottom_to_be_kicked.amount < delegation.amount) + pub fn add_bottom_delegation( + &mut self, + bumped_from_top: bool, + candidate: &T::AccountId, + delegation: Bond>, + ) where + BalanceOf: Into, + { + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo existence => BottomDelegations existence"); + // if bottom is full, kick the lowest bottom (which is expected to be lower than input + // as per check) + let increase_delegation_count = if bottom_delegations.delegations.len() as u32 + == T::MaxBottomDelegationsPerCandidate::get() + { + let lowest_bottom_to_be_kicked = bottom_delegations + .delegations + .pop() + .expect("if at full capacity (>0), then >0 bottom delegations exist; qed"); + // EXPECT lowest_bottom_to_be_kicked.amount < delegation.amount enforced by caller + // if lowest_bottom_to_be_kicked.amount == delegation.amount, we will still kick + // the lowest bottom to enforce first come first served + bottom_delegations.total = bottom_delegations + .total + .saturating_sub(lowest_bottom_to_be_kicked.amount); + // update delegator state + // unreserve kicked bottom + T::Currency::unreserve( + &lowest_bottom_to_be_kicked.owner, + lowest_bottom_to_be_kicked.amount, + ); + // total staked is updated via propagation of lowest bottom delegation amount prior + // to call + let mut delegator_state = + >::get(&lowest_bottom_to_be_kicked.owner) + .expect("Delegation existence => DelegatorState existence"); + let leaving = delegator_state.delegations.0.len() == 1usize; + delegator_state.rm_delegation(candidate); + Pallet::::deposit_event(Event::DelegationKicked( + lowest_bottom_to_be_kicked.owner.clone(), + candidate.clone(), + lowest_bottom_to_be_kicked.amount, + )); + if leaving { + >::remove(&lowest_bottom_to_be_kicked.owner); + Pallet::::deposit_event(Event::DelegatorLeft( + lowest_bottom_to_be_kicked.owner, + lowest_bottom_to_be_kicked.amount, + )); + } else { + >::insert( + &lowest_bottom_to_be_kicked.owner, + delegator_state, + ); + } + false + } else { + !bumped_from_top + }; + // only increase delegation count if new bottom delegation (1) doesn't come from top && + // (2) doesn't pop the lowest delegation from the bottom + if increase_delegation_count { + self.delegation_count += 1u32; + } + bottom_delegations.insert_sorted_greatest_to_least(delegation); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + } + /// Remove delegation + /// Removes from top if amount is above lowest top or top is not full + /// Return Ok(if_total_counted_changed) + pub fn rm_delegation_if_exists( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + amount: Balance, + ) -> Result + where + BalanceOf: Into + From, + { + let amount_geq_lowest_top = amount >= self.lowest_top_delegation_amount; + let top_is_not_full = !matches!(self.top_capacity, CapacityStatus::Full); + let lowest_top_eq_highest_bottom = + self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; + let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); + if top_is_not_full || (amount_geq_lowest_top && !lowest_top_eq_highest_bottom) { + self.rm_top_delegation::(candidate, delegator) + } else if amount_geq_lowest_top && lowest_top_eq_highest_bottom { + let result = self.rm_top_delegation::(candidate, delegator.clone()); + if result == Err(delegation_dne_err) { + // worst case removal + self.rm_bottom_delegation::(candidate, delegator) + } else { + result + } + } else { + self.rm_bottom_delegation::(candidate, delegator) + } + } + /// Remove top delegation, bumps top bottom delegation if exists + pub fn rm_top_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + ) -> Result + where + BalanceOf: Into, + { + let old_total_counted = self.total_counted; + // remove top delegation + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo exists => TopDelegations exists"); + let mut actual_amount_option: Option> = None; + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + actual_amount_option = Some(d.amount); + None + } + }) + .collect(); + let actual_amount = actual_amount_option.ok_or(Error::::DelegationDNE)?; + top_delegations.total -= actual_amount; + // if bottom nonempty => bump top bottom to top + if !matches!(self.bottom_capacity, CapacityStatus::Empty) { + let mut bottom_delegations = >::get(candidate) + .expect("bottom is nonempty as just checked"); + // expect already stored greatest to least by bond amount + let highest_bottom_delegation = bottom_delegations.delegations.remove(0); + bottom_delegations.total = bottom_delegations + .total + .saturating_sub(highest_bottom_delegation.amount); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + // insert highest bottom into top delegations + top_delegations.insert_sorted_greatest_to_least(highest_bottom_delegation); + } + // update candidate info + self.reset_top_data::(&top_delegations); + self.delegation_count -= 1u32; + >::insert(candidate, top_delegations); + // return whether total counted changed + Ok(old_total_counted == self.total_counted) + } + /// Remove bottom delegation + /// Returns if_total_counted_changed: bool + pub fn rm_bottom_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + ) -> Result + where + BalanceOf: Into, + { + // remove bottom delegation + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo exists => BottomDelegations exists"); + let mut actual_amount_option: Option> = None; + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + actual_amount_option = Some(d.amount); + None + } + }) + .collect(); + let actual_amount = actual_amount_option.ok_or(Error::::DelegationDNE)?; + bottom_delegations.total = bottom_delegations.total.saturating_sub(actual_amount); + // update candidate info + self.reset_bottom_data::(&bottom_delegations); + self.delegation_count = self.delegation_count.saturating_sub(1u32); + >::insert(candidate, bottom_delegations); + Ok(false) + } + /// Increase delegation amount + pub fn increase_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: BalanceOf, + more: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let lowest_top_eq_highest_bottom = + self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; + let bond_geq_lowest_top = bond.into() >= self.lowest_top_delegation_amount; + let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); + if bond_geq_lowest_top && !lowest_top_eq_highest_bottom { + // definitely in top + self.increase_top_delegation::(candidate, delegator.clone(), more) + } else if bond_geq_lowest_top && lowest_top_eq_highest_bottom { + // update top but if error then update bottom (because could be in bottom because + // lowest_top_eq_highest_bottom) + let result = + self.increase_top_delegation::(candidate, delegator.clone(), more); + if result == Err(delegation_dne_err) { + self.increase_bottom_delegation::(candidate, delegator, bond, more) + } else { + result + } + } else { + self.increase_bottom_delegation::(candidate, delegator, bond, more) + } + } + /// Increase top delegation + pub fn increase_top_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + more: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo exists => TopDelegations exists"); + let mut in_top = false; + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + in_top = true; + let new_amount = d.amount.saturating_add(more); + Bond { + owner: d.owner, + amount: new_amount, + } + } + }) + .collect(); + ensure!(in_top, Error::::DelegationDNE); + top_delegations.sort_greatest_to_least(); + self.reset_top_data::(&top_delegations); + >::insert(candidate, top_delegations); + Ok(true) + } + /// Increase bottom delegation + pub fn increase_bottom_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: BalanceOf, + more: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let mut bottom_delegations = + >::get(candidate).ok_or(Error::::CandidateDNE)?; + let mut delegation_option: Option>> = None; + let in_top_after = + if (bond.saturating_add(more)).into() > self.lowest_top_delegation_amount { + // bump it from bottom + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + delegation_option = Some(Bond { + owner: d.owner, + amount: d.amount.saturating_add(more), + }); + None + } + }) + .collect(); + let delegation = delegation_option.ok_or(Error::::DelegationDNE)?; + bottom_delegations.total = bottom_delegations.total.saturating_sub(bond); + // add it to top + let mut top_delegations = >::get(candidate) + .expect("CandidateInfo existence => TopDelegations existence"); + // if top is full, pop lowest top + if matches!(top_delegations.top_capacity::(), CapacityStatus::Full) { + // pop lowest top delegation + let new_bottom_delegation = top_delegations + .delegations + .pop() + .expect("Top capacity full => Exists at least 1 top delegation"); + top_delegations.total = top_delegations + .total + .saturating_sub(new_bottom_delegation.amount); + bottom_delegations.insert_sorted_greatest_to_least(new_bottom_delegation); + } + // insert into top + top_delegations.insert_sorted_greatest_to_least(delegation); + self.reset_top_data::(&top_delegations); + >::insert(candidate, top_delegations); + true + } else { + let mut in_bottom = false; + // just increase the delegation + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + in_bottom = true; + Bond { + owner: d.owner, + amount: d.amount.saturating_add(more), + } + } + }) + .collect(); + ensure!(in_bottom, Error::::DelegationDNE); + bottom_delegations.sort_greatest_to_least(); + false + }; + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + Ok(in_top_after) + } + /// Decrease delegation + pub fn decrease_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: Balance, + less: BalanceOf, + ) -> Result + where + BalanceOf: Into + From, + { + let lowest_top_eq_highest_bottom = + self.lowest_top_delegation_amount == self.highest_bottom_delegation_amount; + let bond_geq_lowest_top = bond >= self.lowest_top_delegation_amount; + let delegation_dne_err: DispatchError = Error::::DelegationDNE.into(); + if bond_geq_lowest_top && !lowest_top_eq_highest_bottom { + // definitely in top + self.decrease_top_delegation::(candidate, delegator.clone(), bond.into(), less) + } else if bond_geq_lowest_top && lowest_top_eq_highest_bottom { + // update top but if error then update bottom (because could be in bottom because + // lowest_top_eq_highest_bottom) + let result = self.decrease_top_delegation::( + candidate, + delegator.clone(), + bond.into(), + less, + ); + if result == Err(delegation_dne_err) { + self.decrease_bottom_delegation::(candidate, delegator, less) + } else { + result + } + } else { + self.decrease_bottom_delegation::(candidate, delegator, less) + } + } + /// Decrease top delegation + pub fn decrease_top_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + bond: BalanceOf, + less: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + // The delegation after the `decrease-delegation` will be strictly less than the + // highest bottom delegation + let bond_after_less_than_highest_bottom = + bond.saturating_sub(less).into() < self.highest_bottom_delegation_amount; + // The top delegations is full and the bottom delegations has at least one delegation + let full_top_and_nonempty_bottom = matches!(self.top_capacity, CapacityStatus::Full) + && !matches!(self.bottom_capacity, CapacityStatus::Empty); + let mut top_delegations = + >::get(candidate).ok_or(Error::::CandidateDNE)?; + let in_top_after = + if bond_after_less_than_highest_bottom && full_top_and_nonempty_bottom { + let mut delegation_option: Option>> = None; + // take delegation from top + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .filter_map(|d| { + if d.owner != delegator { + Some(d) + } else { + top_delegations.total = + top_delegations.total.saturating_sub(d.amount); + delegation_option = Some(Bond { + owner: d.owner, + amount: d.amount.saturating_sub(less), + }); + None + } + }) + .collect(); + let delegation = delegation_option.ok_or(Error::::DelegationDNE)?; + // pop highest bottom by reverse and popping + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo existence => BottomDelegations existence"); + let highest_bottom_delegation = bottom_delegations.delegations.remove(0); + bottom_delegations.total = bottom_delegations + .total + .saturating_sub(highest_bottom_delegation.amount); + // insert highest bottom into top + top_delegations.insert_sorted_greatest_to_least(highest_bottom_delegation); + // insert previous top into bottom + bottom_delegations.insert_sorted_greatest_to_least(delegation); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + false + } else { + // keep it in the top + let mut is_in_top = false; + top_delegations.delegations = top_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + is_in_top = true; + Bond { + owner: d.owner, + amount: d.amount.saturating_sub(less), + } + } + }) + .collect(); + ensure!(is_in_top, Error::::DelegationDNE); + top_delegations.total = top_delegations.total.saturating_sub(less); + top_delegations.sort_greatest_to_least(); + true + }; + self.reset_top_data::(&top_delegations); + >::insert(candidate, top_delegations); + Ok(in_top_after) + } + /// Decrease bottom delegation + pub fn decrease_bottom_delegation( + &mut self, + candidate: &T::AccountId, + delegator: T::AccountId, + less: BalanceOf, + ) -> Result + where + BalanceOf: Into, + { + let mut bottom_delegations = >::get(candidate) + .expect("CandidateInfo exists => BottomDelegations exists"); + let mut in_bottom = false; + bottom_delegations.delegations = bottom_delegations + .delegations + .clone() + .into_iter() + .map(|d| { + if d.owner != delegator { + d + } else { + in_bottom = true; + Bond { + owner: d.owner, + amount: d.amount.saturating_sub(less), + } + } + }) + .collect(); + ensure!(in_bottom, Error::::DelegationDNE); + bottom_delegations.sort_greatest_to_least(); + self.reset_bottom_data::(&bottom_delegations); + >::insert(candidate, bottom_delegations); + Ok(false) + } + } + + // Temporary manual implementation for migration testing purposes + impl PartialEq for CollatorCandidate { + fn eq(&self, other: &Self) -> bool { + let must_be_true = self.id == other.id + && self.bond == other.bond + && self.total_counted == other.total_counted + && self.total_backing == other.total_backing + && self.request == other.request + && self.state == other.state; + if !must_be_true { + return false; + } + for (x, y) in self.delegators.0.iter().zip(other.delegators.0.iter()) { + if x != y { + return false; + } + } + for ( + Bond { + owner: o1, + amount: a1, + }, + Bond { + owner: o2, + amount: a2, + }, + ) in self + .top_delegations + .iter() + .zip(other.top_delegations.iter()) + { + if o1 != o2 || a1 != a2 { + return false; + } + } + for ( + Bond { + owner: o1, + amount: a1, + }, + Bond { + owner: o2, + amount: a2, + }, + ) in self + .bottom_delegations + .iter() + .zip(other.bottom_delegations.iter()) + { + if o1 != o2 || a1 != a2 { + return false; + } + } + true + } + } + + /// Convey relevant information describing if a delegator was added to the top or bottom + /// Delegations added to the top yield a new total + #[derive(Clone, Copy, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + pub enum DelegatorAdded { + AddedToTop { new_total: B }, + AddedToBottom, + } + + impl< + A: Ord + Clone + sp_std::fmt::Debug, + B: AtLeast32BitUnsigned + + Ord + + Copy + + sp_std::ops::AddAssign + + sp_std::ops::SubAssign + + sp_std::fmt::Debug, + > CollatorCandidate + { + pub fn is_active(&self) -> bool { + self.state == CollatorStatus::Active + } + } + + impl From> for CollatorSnapshot { + fn from(other: CollatorCandidate) -> CollatorSnapshot { + CollatorSnapshot { + bond: other.bond, + delegations: other.top_delegations, + total: other.total_counted, + } + } + } + + #[derive(Clone, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + pub enum DelegatorStatus { + /// Active with no scheduled exit + Active, + /// Schedule exit to revoke all ongoing delegations + Leaving(RoundIndex), + } + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Delegator state + pub struct Delegator { + /// Delegator account + pub id: AccountId, + /// All current delegations + pub delegations: OrderedSet>, + /// Total balance locked for this delegator + pub total: Balance, + /// Requests to change delegations, relevant iff active + pub requests: PendingDelegationRequests, + /// Status for this delegator + pub status: DelegatorStatus, + } + + // Temporary manual implementation for migration testing purposes + impl PartialEq for Delegator { + fn eq(&self, other: &Self) -> bool { + let must_be_true = self.id == other.id + && self.total == other.total + && self.requests == other.requests + && self.status == other.status; + if !must_be_true { + return false; + } + for ( + Bond { + owner: o1, + amount: a1, + }, + Bond { + owner: o2, + amount: a2, + }, + ) in self.delegations.0.iter().zip(other.delegations.0.iter()) + { + if o1 != o2 || a1 != a2 { + return false; + } + } + true + } + } + + impl< + AccountId: Ord + Clone, + Balance: Copy + + sp_std::ops::AddAssign + + sp_std::ops::Add + + sp_std::ops::SubAssign + + sp_std::ops::Sub + + Ord + + Zero + + Default, + > Delegator + { + pub fn new(id: AccountId, collator: AccountId, amount: Balance) -> Self { + Delegator { + id, + delegations: OrderedSet::from(vec![Bond { + owner: collator, + amount, + }]), + total: amount, + requests: PendingDelegationRequests::new(), + status: DelegatorStatus::Active, + } + } + pub fn requests(&self) -> BTreeMap> { + self.requests.requests.clone() + } + pub fn is_active(&self) -> bool { + matches!(self.status, DelegatorStatus::Active) + } + pub fn is_leaving(&self) -> bool { + matches!(self.status, DelegatorStatus::Leaving(_)) + } + /// Can only leave if the current round is less than or equal to scheduled execution round + /// - returns None if not in leaving state + pub fn can_execute_leave( + &self, + delegation_weight_hint: u32, + ) -> DispatchResult { + ensure!( + delegation_weight_hint >= (self.delegations.0.len() as u32), + Error::::TooLowDelegationCountToLeaveDelegators + ); + if let DelegatorStatus::Leaving(when) = self.status { + ensure!( + >::get().current >= when, + Error::::DelegatorCannotLeaveYet + ); + Ok(()) + } else { + Err(Error::::DelegatorNotLeaving.into()) + } + } + /// Set status to leaving + pub(crate) fn set_leaving(&mut self, when: RoundIndex) { + self.status = DelegatorStatus::Leaving(when); + } + /// Schedule status to exit + pub fn schedule_leave(&mut self) -> (RoundIndex, RoundIndex) { + let now = >::get().current; + let when = now + T::LeaveDelegatorsDelay::get(); + self.set_leaving(when); + (now, when) + } + /// Set delegator status to active + pub fn cancel_leave(&mut self) { + self.status = DelegatorStatus::Active + } + pub fn add_delegation(&mut self, bond: Bond) -> bool { + let amt = bond.amount; + if self.delegations.insert(bond) { + self.total += amt; + true + } else { + false + } + } + // Return Some(remaining balance), must be more than MinDelegatorStk + // Return None if delegation not found + pub fn rm_delegation(&mut self, collator: &AccountId) -> Option { + let mut amt: Option = None; + let delegations = self + .delegations + .0 + .iter() + .filter_map(|x| { + if &x.owner == collator { + amt = Some(x.amount); + None + } else { + Some(x.clone()) + } + }) + .collect(); + if let Some(balance) = amt { + self.delegations = OrderedSet::from(delegations); + self.total -= balance; + Some(self.total) + } else { + None + } + } + pub fn increase_delegation( + &mut self, + candidate: AccountId, + amount: Balance, + ) -> DispatchResult + where + BalanceOf: From, + T::AccountId: From, + Delegator>: From>, + { + let delegator_id: T::AccountId = self.id.clone().into(); + let candidate_id: T::AccountId = candidate.clone().into(); + let balance_amt: BalanceOf = amount.into(); + // increase delegation + for x in &mut self.delegations.0 { + if x.owner == candidate { + let before_amount: BalanceOf = x.amount.into(); + x.amount += amount; + self.total += amount; + // update collator state delegation + let mut collator_state = + >::get(&candidate_id).ok_or(Error::::CandidateDNE)?; + T::Currency::reserve(&self.id.clone().into(), balance_amt)?; + let before = collator_state.total_counted; + let in_top = collator_state.increase_delegation::( + &candidate_id, + delegator_id.clone(), + before_amount, + balance_amt, + )?; + let after = collator_state.total_counted; + if collator_state.is_active() && (before != after) { + Pallet::::update_active(candidate_id.clone(), after); + } + >::insert(&candidate_id, collator_state); + let new_total_staked = >::get().saturating_add(balance_amt); + >::put(new_total_staked); + let nom_st: Delegator> = self.clone().into(); + >::insert(&delegator_id, nom_st); + Pallet::::deposit_event(Event::DelegationIncreased( + delegator_id, + candidate_id, + balance_amt, + in_top, + )); + return Ok(()); + } + } + Err(Error::::DelegationDNE.into()) + } + /// Schedule decrease delegation + pub fn schedule_decrease_delegation( + &mut self, + collator: AccountId, + less: Balance, + ) -> Result + where + BalanceOf: Into + From, + { + // get delegation amount + let Bond { amount, .. } = self + .delegations + .0 + .iter() + .find(|b| b.owner == collator) + .ok_or(Error::::DelegationDNE)?; + ensure!(*amount > less, Error::::DelegatorBondBelowMin); + let expected_amt: BalanceOf = (*amount - less).into(); + ensure!( + expected_amt >= T::MinDelegation::get(), + Error::::DelegationBelowMin + ); + // Net Total is total after pending orders are executed + let net_total = self.total - self.requests.less_total; + // Net Total is always >= MinDelegatorStk + let max_subtracted_amount = net_total - T::MinDelegatorStk::get().into(); + ensure!( + less <= max_subtracted_amount, + Error::::DelegatorBondBelowMin + ); + let when = >::get().current + T::DelegationBondLessDelay::get(); + self.requests.bond_less::(collator, less, when)?; + Ok(when) + } + /// Temporary function to migrate revocations + pub fn hotfix_set_revoke(&mut self, collator: AccountId, when: RoundIndex) { + // get delegation amount + let maybe_bond = self.delegations.0.iter().find(|b| b.owner == collator); + if let Some(Bond { amount, .. }) = maybe_bond { + // add revocation to pending requests + if let Err(e) = self.requests.revoke::(collator, *amount, when) { + log::warn!("Migrate revocation request failed with error: {:?}", e); + } + } else { + log::warn!("Migrate revocation request failed because delegation DNE"); + } + } + /// Schedule revocation for the given collator + pub fn schedule_revoke( + &mut self, + collator: AccountId, + ) -> Result<(RoundIndex, RoundIndex), DispatchError> + where + BalanceOf: Into, + { + // get delegation amount + let Bond { amount, .. } = self + .delegations + .0 + .iter() + .find(|b| b.owner == collator) + .ok_or(Error::::DelegationDNE)?; + let now = >::get().current; + let when = now + T::RevokeDelegationDelay::get(); + // add revocation to pending requests + self.requests.revoke::(collator, *amount, when)?; + Ok((now, when)) + } + /// Execute pending delegation change request + pub fn execute_pending_request( + &mut self, + candidate: AccountId, + ) -> DispatchResult + where + BalanceOf: From + Into, + T::AccountId: From, + Delegator>: From>, + { + let now = >::get().current; + let DelegationRequest { + amount, + action, + when_executable, + .. + } = self + .requests + .requests + .remove(&candidate) + .ok_or(Error::::PendingDelegationRequestDNE)?; + ensure!( + when_executable <= now, + Error::::PendingDelegationRequestNotDueYet + ); + let (balance_amt, candidate_id, delegator_id): ( + BalanceOf, + T::AccountId, + T::AccountId, + ) = ( + amount.into(), + candidate.clone().into(), + self.id.clone().into(), + ); + match action { + DelegationChange::Revoke => { + // revoking last delegation => leaving set of delegators + let leaving = if self.delegations.0.len() == 1usize { + true + } else { + ensure!( + self.total - T::MinDelegatorStk::get().into() >= amount, + Error::::DelegatorBondBelowMin + ); + false + }; + // remove from pending requests + self.requests.less_total -= amount; + self.requests.revocations_count -= 1u32; + // remove delegation from delegator state + self.rm_delegation(&candidate); + // remove delegation from collator state delegations + Pallet::::delegator_leaves_candidate( + candidate_id.clone(), + delegator_id.clone(), + balance_amt, + )?; + Pallet::::deposit_event(Event::DelegationRevoked( + delegator_id.clone(), + candidate_id, + balance_amt, + )); + if leaving { + >::remove(&delegator_id); + Pallet::::deposit_event(Event::DelegatorLeft( + delegator_id, + balance_amt, + )); + } else { + let nom_st: Delegator> = self.clone().into(); + >::insert(&delegator_id, nom_st); + } + Ok(()) + } + DelegationChange::Decrease => { + // remove from pending requests + self.requests.less_total -= amount; + // decrease delegation + for x in &mut self.delegations.0 { + if x.owner == candidate { + if x.amount > amount { + let amount_before: BalanceOf = x.amount.into(); + x.amount -= amount; + self.total -= amount; + let new_total: BalanceOf = self.total.into(); + ensure!( + new_total >= T::MinDelegation::get(), + Error::::DelegationBelowMin + ); + ensure!( + new_total >= T::MinDelegatorStk::get(), + Error::::DelegatorBondBelowMin + ); + let mut collator = >::get(&candidate_id) + .ok_or(Error::::CandidateDNE)?; + T::Currency::unreserve(&delegator_id, balance_amt); + let before = collator.total_counted; + // need to go into decrease_delegation + let in_top = collator.decrease_delegation::( + &candidate_id, + delegator_id.clone(), + amount_before, + balance_amt, + )?; + let after = collator.total_counted; + if collator.is_active() && (before != after) { + Pallet::::update_active(candidate_id.clone(), after); + } + >::insert(&candidate_id, collator); + let new_total_staked = + >::get().saturating_sub(balance_amt); + >::put(new_total_staked); + let nom_st: Delegator> = + self.clone().into(); + >::insert(&delegator_id, nom_st); + Pallet::::deposit_event(Event::DelegationDecreased( + delegator_id, + candidate_id, + balance_amt, + in_top, + )); + return Ok(()); + } else { + // must rm entire delegation if x.amount <= less or cancel request + return Err(Error::::DelegationBelowMin.into()); + } + } + } + Err(Error::::DelegationDNE.into()) + } + } + } + /// Cancel pending delegation change request + pub fn cancel_pending_request( + &mut self, + candidate: AccountId, + ) -> Result, DispatchError> { + let order = self + .requests + .requests + .remove(&candidate) + .ok_or(Error::::PendingDelegationRequestDNE)?; + match order.action { + DelegationChange::Revoke => { + self.requests.revocations_count -= 1u32; + self.requests.less_total -= order.amount; + } + DelegationChange::Decrease => { + self.requests.less_total -= order.amount; + } + } + Ok(order) + } + } + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Changes requested by the delegator + /// - limit of 1 ongoing change per delegation + pub enum DelegationChange { + Revoke, + Decrease, + } + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] + pub struct DelegationRequest { + pub collator: AccountId, + pub amount: Balance, + pub when_executable: RoundIndex, + pub action: DelegationChange, + } + + #[derive(Clone, Encode, PartialEq, Decode, RuntimeDebug, TypeInfo)] + /// Pending requests to mutate delegations for each delegator + pub struct PendingDelegationRequests { + /// Number of pending revocations (necessary for determining whether revoke is exit) + pub revocations_count: u32, + /// Map from collator -> Request (enforces at most 1 pending request per delegation) + pub requests: BTreeMap>, + /// Sum of pending revocation amounts + bond less amounts + pub less_total: Balance, + } + + impl Default for PendingDelegationRequests { + fn default() -> PendingDelegationRequests { + PendingDelegationRequests { + revocations_count: 0u32, + requests: BTreeMap::new(), + less_total: B::zero(), + } + } + } + + impl< + A: Ord + Clone, + B: Zero + + Ord + + Copy + + Clone + + sp_std::ops::AddAssign + + sp_std::ops::Add + + sp_std::ops::SubAssign + + sp_std::ops::Sub, + > PendingDelegationRequests + { + /// New default (empty) pending requests + pub fn new() -> PendingDelegationRequests { + PendingDelegationRequests::default() + } + /// Add bond less order to pending requests, only succeeds if returns true + /// - limit is the maximum amount allowed that can be subtracted from the delegation + /// before it would be below the minimum delegation amount + pub fn bond_less( + &mut self, + collator: A, + amount: B, + when_executable: RoundIndex, + ) -> DispatchResult { + ensure!( + self.requests.get(&collator).is_none(), + Error::::PendingDelegationRequestAlreadyExists + ); + self.requests.insert( + collator.clone(), + DelegationRequest { + collator, + amount, + when_executable, + action: DelegationChange::Decrease, + }, + ); + self.less_total += amount; + Ok(()) + } + /// Add revoke order to pending requests + /// - limit is the maximum amount allowed that can be subtracted from the delegation + /// before it would be below the minimum delegation amount + pub fn revoke( + &mut self, + collator: A, + amount: B, + when_executable: RoundIndex, + ) -> DispatchResult { + ensure!( + self.requests.get(&collator).is_none(), + Error::::PendingDelegationRequestAlreadyExists + ); + self.requests.insert( + collator.clone(), + DelegationRequest { + collator, + amount, + when_executable, + action: DelegationChange::Revoke, + }, + ); + self.revocations_count += 1u32; + self.less_total += amount; + Ok(()) + } + } + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + /// DEPRECATED in favor of Delegator + /// Nominator state + pub struct Nominator2 { + /// All current delegations + pub delegations: OrderedSet>, + /// Delegations scheduled to be revoked + pub revocations: OrderedSet, + /// Total balance locked for this nominator + pub total: Balance, + /// Total number of revocations scheduled to be executed + pub scheduled_revocations_count: u32, + /// Total amount to be unbonded once revocations are executed + pub scheduled_revocations_total: Balance, + /// Status for this nominator + pub status: DelegatorStatus, + } + + // /// Temporary function to migrate state + // pub(crate) fn migrate_nominator_to_delegator_state( + // id: T::AccountId, + // nominator: Nominator2>, + // ) -> Delegator> { + // Delegator { + // id, + // delegations: nominator.delegations, + // total: nominator.total, + // requests: PendingDelegationRequests::new(), + // status: nominator.status, + // } + // } + + #[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// The current round index and transition information + pub struct RoundInfo { + /// Current round index + pub current: RoundIndex, + /// The first block of the current round + pub first: BlockNumber, + /// The length of the current round in number of blocks + pub length: u32, + } + impl< + B: Copy + + sp_std::ops::Add + + sp_std::ops::Sub + + From + + PartialOrd, + > RoundInfo + { + pub fn new(current: RoundIndex, first: B, length: u32) -> RoundInfo { + RoundInfo { + current, + first, + length, + } + } + /// Check if the round should be updated + pub fn should_update(&self, now: B) -> bool { + now - self.first >= self.length.into() + } + /// New round + pub fn update(&mut self, now: B) { + self.current += 1u32; + self.first = now; + } + } + impl< + B: Copy + + sp_std::ops::Add + + sp_std::ops::Sub + + From + + PartialOrd, + > Default for RoundInfo + { + fn default() -> RoundInfo { + RoundInfo::new(1u32, 1u32.into(), 20u32) + } + } + + #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)] + /// Reserve information { account, percent_of_inflation } + pub struct ParachainBondConfig { + /// Account which receives funds intended for parachain bond + pub account: AccountId, + /// Percent of inflation set aside for parachain bond account + pub percent: Percent, + } + impl Default for ParachainBondConfig { + fn default() -> ParachainBondConfig { + ParachainBondConfig { + account: A::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + percent: Percent::zero(), + } + } + } + + pub(crate) type RoundIndex = u32; + type RewardPoint = u32; + pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + + /// Configuration trait of this pallet. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Overarching event type + type Event: From> + IsType<::Event>; + /// The currency type + type Currency: Currency + ReservableCurrency; + /// The origin for monetary governance + type MonetaryGovernanceOrigin: EnsureOrigin; + /// Minimum number of blocks per round + #[pallet::constant] + type MinBlocksPerRound: Get; + /// Default number of blocks per round at genesis + #[pallet::constant] + type DefaultBlocksPerRound: Get; + /// Number of rounds that candidates remain bonded before exit request is executable + #[pallet::constant] + type LeaveCandidatesDelay: Get; + /// Number of rounds candidate requests to decrease self-bond must wait to be executable + #[pallet::constant] + type CandidateBondLessDelay: Get; + /// Number of rounds that delegators remain bonded before exit request is executable + #[pallet::constant] + type LeaveDelegatorsDelay: Get; + /// Number of rounds that delegations remain bonded before revocation request is executable + #[pallet::constant] + type RevokeDelegationDelay: Get; + /// Number of rounds that delegation less requests must wait before executable + #[pallet::constant] + type DelegationBondLessDelay: Get; + /// Number of rounds after which block authors are rewarded + #[pallet::constant] + type RewardPaymentDelay: Get; + /// Minimum number of selected candidates every round + #[pallet::constant] + type MinSelectedCandidates: Get; + /// Maximum top delegations counted per candidate + #[pallet::constant] + type MaxTopDelegationsPerCandidate: Get; + /// Maximum bottom delegations (not counted) per candidate + #[pallet::constant] + type MaxBottomDelegationsPerCandidate: Get; + /// Maximum delegations per delegator + #[pallet::constant] + type MaxDelegationsPerDelegator: Get; + /// Default commission due to collators, is `CollatorCommission` storage value in genesis + #[pallet::constant] + type DefaultCollatorCommission: Get; + /// Default percent of inflation set aside for parachain bond account + #[pallet::constant] + type DefaultParachainBondReservePercent: Get; + /// Minimum stake required for any candidate to be in `SelectedCandidates` for the round + #[pallet::constant] + type MinCollatorStk: Get>; + /// Minimum stake required for any account to be a collator candidate + #[pallet::constant] + type MinCandidateStk: Get>; + /// Minimum stake for any registered on-chain account to delegate + #[pallet::constant] + type MinDelegation: Get>; + /// Minimum stake for any registered on-chain account to be a delegator + #[pallet::constant] + type MinDelegatorStk: Get>; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::error] + pub enum Error { + DelegatorDNE, + DelegatorDNEinTopNorBottom, + DelegatorDNEInDelegatorSet, + CandidateDNE, + DelegationDNE, + DelegatorExists, + CandidateExists, + CandidateBondBelowMin, + InsufficientBalance, + DelegatorBondBelowMin, + DelegationBelowMin, + AlreadyOffline, + AlreadyActive, + DelegatorAlreadyLeaving, + DelegatorNotLeaving, + DelegatorCannotLeaveYet, + CannotDelegateIfLeaving, + CandidateAlreadyLeaving, + CandidateNotLeaving, + CandidateCannotLeaveYet, + CannotGoOnlineIfLeaving, + ExceedMaxDelegationsPerDelegator, + AlreadyDelegatedCandidate, + InvalidSchedule, + CannotSetBelowMin, + RoundLengthMustBeAtLeastTotalSelectedCollators, + NoWritingSameValue, + TooLowCandidateCountWeightHintJoinCandidates, + TooLowCandidateCountWeightHintCancelLeaveCandidates, + TooLowCandidateCountToLeaveCandidates, + TooLowDelegationCountToDelegate, + TooLowCandidateDelegationCountToDelegate, + TooLowCandidateDelegationCountToLeaveCandidates, + TooLowDelegationCountToLeaveDelegators, + PendingCandidateRequestsDNE, + PendingCandidateRequestAlreadyExists, + PendingCandidateRequestNotDueYet, + PendingDelegationRequestDNE, + PendingDelegationRequestAlreadyExists, + PendingDelegationRequestNotDueYet, + CannotDelegateLessThanLowestBottomWhenBottomIsFull, + } + + #[pallet::event] + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event { + /// Starting Block, Round, Number of Collators Selected, Total Balance + NewRound(T::BlockNumber, RoundIndex, u32, BalanceOf), + /// Account, Amount Locked, New Total Amt Locked + JoinedCollatorCandidates(T::AccountId, BalanceOf, BalanceOf), + /// Round, Collator Account, Total Exposed Amount (includes all delegations) + CollatorChosen(RoundIndex, T::AccountId, BalanceOf), + /// Candidate, Amount To Decrease, Round at which request can be executed by caller + CandidateBondLessRequested(T::AccountId, BalanceOf, RoundIndex), + /// Candidate, Amount, New Bond Total + CandidateBondedMore(T::AccountId, BalanceOf, BalanceOf), + /// Candidate, Amount, New Bond + CandidateBondedLess(T::AccountId, BalanceOf, BalanceOf), + /// Candidate + CandidateWentOffline(T::AccountId), + /// Candidate + CandidateBackOnline(T::AccountId), + /// Round At Which Exit Is Allowed, Candidate, Scheduled Exit + CandidateScheduledExit(RoundIndex, T::AccountId, RoundIndex), + /// Candidate + CancelledCandidateExit(T::AccountId), + /// Candidate, Amount, Round at which could be executed + CancelledCandidateBondLess(T::AccountId, BalanceOf, RoundIndex), + /// Ex-Candidate, Amount Unlocked, New Total Amt Locked + CandidateLeft(T::AccountId, BalanceOf, BalanceOf), + /// Delegator, Candidate, Amount to be decreased, Round at which can be executed + DelegationDecreaseScheduled(T::AccountId, T::AccountId, BalanceOf, RoundIndex), + // Delegator, Candidate, Amount, If in top delegations for candidate after increase + DelegationIncreased(T::AccountId, T::AccountId, BalanceOf, bool), + // Delegator, Candidate, Amount, If in top delegations for candidate after decrease + DelegationDecreased(T::AccountId, T::AccountId, BalanceOf, bool), + /// Round, Delegator, Scheduled Exit + DelegatorExitScheduled(RoundIndex, T::AccountId, RoundIndex), + /// Round, Delegator, Candidate, Scheduled Exit + DelegationRevocationScheduled(RoundIndex, T::AccountId, T::AccountId, RoundIndex), + /// Delegator, Amount Unstaked + DelegatorLeft(T::AccountId, BalanceOf), + /// Delegator, Candidate, Amount Unstaked + DelegationRevoked(T::AccountId, T::AccountId, BalanceOf), + /// Delegator, Candidate, Amount Unstaked + DelegationKicked(T::AccountId, T::AccountId, BalanceOf), + /// Delegator + DelegatorExitCancelled(T::AccountId), + /// Delegator, Cancelled Request + CancelledDelegationRequest(T::AccountId, DelegationRequest>), + /// Delegator, Amount Locked, Candidate, Delegator Position with New Total Counted if in Top + Delegation( + T::AccountId, + BalanceOf, + T::AccountId, + DelegatorAdded>, + ), + /// Delegator, Candidate, Amount Unstaked, New Total Amt Staked for Candidate + DelegatorLeftCandidate(T::AccountId, T::AccountId, BalanceOf, BalanceOf), + /// Paid the account (delegator or collator) the balance as liquid rewards + Rewarded(T::AccountId, BalanceOf), + /// Transferred to account which holds funds reserved for parachain bond + ReservedForParachainBond(T::AccountId, BalanceOf), + /// Account (re)set for parachain bond treasury [old, new] + ParachainBondAccountSet(T::AccountId, T::AccountId), + /// Percent of inflation reserved for parachain bond (re)set [old, new] + ParachainBondReservePercentSet(Percent, Percent), + /// Annual inflation input (first 3) was used to derive new per-round inflation (last 3) + InflationSet(Perbill, Perbill, Perbill, Perbill, Perbill, Perbill), + /// Staking expectations set + StakeExpectationsSet(BalanceOf, BalanceOf, BalanceOf), + /// Set total selected candidates to this value [old, new] + TotalSelectedSet(u32, u32), + /// Set collator commission to this value [old, new] + CollatorCommissionSet(Perbill, Perbill), + /// Set blocks per round [current_round, first_block, old, new, new_per_round_inflation] + BlocksPerRoundSet( + RoundIndex, + T::BlockNumber, + u32, + u32, + Perbill, + Perbill, + Perbill, + ), + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(n: T::BlockNumber) -> Weight { + let mut weight = T::WeightInfo::base_on_initialize(); + + let mut round = >::get(); + if round.should_update(n) { + // mutate round + round.update(n); + // pay all stakers for T::RewardPaymentDelay rounds ago + Self::prepare_staking_payouts(round.current); + // select top collator candidates for next round + let (collator_count, delegation_count, total_staked) = + Self::select_top_candidates(round.current); + // start next round + >::put(round); + // snapshot total stake + >::insert(round.current, >::get()); + Self::deposit_event(Event::NewRound( + round.first, + round.current, + collator_count, + total_staked, + )); + weight += T::WeightInfo::round_transition_on_initialize( + collator_count, + delegation_count, + ); + } + + weight += Self::handle_delayed_payouts(round.current); + + weight + } + } + + #[pallet::storage] + #[pallet::getter(fn collator_commission)] + /// Commission percent taken off of rewards for all collators + type CollatorCommission = StorageValue<_, Perbill, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn total_selected)] + /// The total candidates selected every round + type TotalSelected = StorageValue<_, u32, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn parachain_bond_info)] + /// Parachain bond config info { account, percent_of_inflation } + type ParachainBondInfo = + StorageValue<_, ParachainBondConfig, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn round)] + /// Current round index and next round scheduled transition + pub(crate) type Round = StorageValue<_, RoundInfo, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn nominator_state2)] + /// DEPRECATED in favor of DelegatorState + /// Get nominator state associated with an account if account is nominating else None + pub(crate) type NominatorState2 = StorageMap< + _, + Twox64Concat, + T::AccountId, + Nominator2>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn delegator_state)] + /// Get delegator state associated with an account if account is delegating else None + pub(crate) type DelegatorState = StorageMap< + _, + Twox64Concat, + T::AccountId, + Delegator>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn candidate_state)] + /// DEPRECATED + /// Get collator candidate state associated with an account if account is a candidate else None + pub(crate) type CandidateState = StorageMap< + _, + Twox64Concat, + T::AccountId, + CollatorCandidate>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn candidate_info)] + /// Get collator candidate info associated with an account if account is candidate else None + pub(crate) type CandidateInfo = + StorageMap<_, Twox64Concat, T::AccountId, CandidateMetadata>, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn top_delegations)] + /// Top delegations for collator candidate + pub(crate) type TopDelegations = StorageMap< + _, + Twox64Concat, + T::AccountId, + Delegations>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn bottom_delegations)] + /// Bottom delegations for collator candidate + pub(crate) type BottomDelegations = StorageMap< + _, + Twox64Concat, + T::AccountId, + Delegations>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn collator_state2)] + /// DEPRECATED in favor of CandidateState + /// Get collator state associated with an account if account is collating else None + pub(crate) type CollatorState2 = StorageMap< + _, + Twox64Concat, + T::AccountId, + Collator2>, + OptionQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn selected_candidates)] + /// The collator candidates selected for the current round + type SelectedCandidates = StorageValue<_, Vec, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn total)] + /// Total capital locked by this staking pallet + pub(crate) type Total = StorageValue<_, BalanceOf, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn candidate_pool)] + /// The pool of collator candidates, each with their total backing stake + pub(crate) type CandidatePool = + StorageValue<_, OrderedSet>>, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn at_stake)] + /// Snapshot of collator delegation stake at the start of the round + pub type AtStake = StorageDoubleMap< + _, + Twox64Concat, + RoundIndex, + Twox64Concat, + T::AccountId, + CollatorSnapshot>, + ValueQuery, + >; + + #[pallet::storage] + #[pallet::getter(fn delayed_payouts)] + /// Delayed payouts + pub type DelayedPayouts = + StorageMap<_, Twox64Concat, RoundIndex, DelayedPayout>, OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn staked)] + /// Total counted stake for selected candidates in the round + pub type Staked = + StorageMap<_, Twox64Concat, RoundIndex, BalanceOf, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn inflation_config)] + /// Inflation configuration + pub type InflationConfig = + StorageValue<_, InflationInfo>, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn points)] + /// Total points awarded to collators for block production in the round + pub type Points = StorageMap<_, Twox64Concat, RoundIndex, RewardPoint, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn awarded_pts)] + /// Points for each collator per round + pub type AwardedPts = StorageDoubleMap< + _, + Twox64Concat, + RoundIndex, + Twox64Concat, + T::AccountId, + RewardPoint, + ValueQuery, + >; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub candidates: Vec<(T::AccountId, BalanceOf)>, + /// Vec of tuples of the format (delegator AccountId, collator AccountId, delegation Amount) + pub delegations: Vec<(T::AccountId, T::AccountId, BalanceOf)>, + pub inflation_config: InflationInfo>, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self { + candidates: vec![], + delegations: vec![], + ..Default::default() + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + >::put(self.inflation_config.clone()); + let mut candidate_count = 0u32; + // Initialize the candidates + for &(ref candidate, balance) in &self.candidates { + assert!( + T::Currency::free_balance(candidate) >= balance, + "Account does not have enough balance to bond as a candidate." + ); + candidate_count += 1u32; + if let Err(error) = >::join_candidates( + T::Origin::from(Some(candidate.clone()).into()), + balance, + candidate_count, + ) { + log::warn!("Join candidates failed in genesis with error {:?}", error); + } else { + candidate_count += 1u32; + } + } + let mut col_delegator_count: BTreeMap = BTreeMap::new(); + let mut del_delegation_count: BTreeMap = BTreeMap::new(); + // Initialize the delegations + for &(ref delegator, ref target, balance) in &self.delegations { + assert!( + T::Currency::free_balance(delegator) >= balance, + "Account does not have enough balance to place delegation." + ); + let cd_count = if let Some(x) = col_delegator_count.get(target) { + *x + } else { + 0u32 + }; + let dd_count = if let Some(x) = del_delegation_count.get(delegator) { + *x + } else { + 0u32 + }; + if let Err(error) = >::delegate( + T::Origin::from(Some(delegator.clone()).into()), + target.clone(), + balance, + cd_count, + dd_count, + ) { + log::warn!("Delegate failed in genesis with error {:?}", error); + } else { + if let Some(x) = col_delegator_count.get_mut(target) { + *x += 1u32; + } else { + col_delegator_count.insert(target.clone(), 1u32); + }; + if let Some(x) = del_delegation_count.get_mut(delegator) { + *x += 1u32; + } else { + del_delegation_count.insert(delegator.clone(), 1u32); + }; + } + } + // Set collator commission to default config + >::put(T::DefaultCollatorCommission::get()); + // Set parachain bond config to default config + >::put(ParachainBondConfig { + // must be set soon; if not => due inflation will be sent to collators/delegators + account: T::AccountId::decode( + &mut sp_runtime::traits::TrailingZeroInput::zeroes(), + ) + .expect("infinite length input; no invalid inputs for type; qed"), + percent: T::DefaultParachainBondReservePercent::get(), + }); + // Set total selected candidates to minimum config + >::put(T::MinSelectedCandidates::get()); + // Choose top TotalSelected collator candidates + let (v_count, _, total_staked) = >::select_top_candidates(1u32); + // Start Round 1 at Block 0 + let round: RoundInfo = + RoundInfo::new(1u32, 0u32.into(), T::DefaultBlocksPerRound::get()); + >::put(round); + // Snapshot total stake + >::insert(1u32, >::get()); + >::deposit_event(Event::NewRound( + T::BlockNumber::zero(), + 1u32, + v_count, + total_staked, + )); + } + } + + #[pallet::call] + impl Pallet { + #[pallet::weight( ::WeightInfo::hotfix_remove_delegation_requests(delegators.len() as u32) )] - /// Hotfix patch to remove all delegation requests not removed during a candidate exit - pub fn hotfix_remove_delegation_requests( - origin: OriginFor, - delegators: Vec, - ) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - for delegator in delegators { - if let Some(mut state) = >::get(&delegator) { - // go through all requests and remove ones without corresponding delegation - for (candidate, request) in state.requests.requests.clone().into_iter() { - if state - .delegations - .0 - .iter() - .find(|x| x.owner == candidate) - .is_none() - { - state.requests.requests.remove(&candidate); - state.requests.less_total = - state.requests.less_total.saturating_sub(request.amount); - if matches!(request.action, DelegationChange::Revoke) { - state.requests.revocations_count -= 1u32; - } - } - } - >::insert(&delegator, state); - } // else delegator is not a delegator so no update needed - } - Ok(().into()) - } - #[pallet::weight( + /// Hotfix patch to remove all delegation requests not removed during a candidate exit + pub fn hotfix_remove_delegation_requests( + origin: OriginFor, + delegators: Vec, + ) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + for delegator in delegators { + if let Some(mut state) = >::get(&delegator) { + // go through all requests and remove ones without corresponding delegation + for (candidate, request) in state.requests.requests.clone().into_iter() { + if state + .delegations + .0 + .iter() + .find(|x| x.owner == candidate) + .is_none() + { + state.requests.requests.remove(&candidate); + state.requests.less_total = + state.requests.less_total.saturating_sub(request.amount); + if matches!(request.action, DelegationChange::Revoke) { + state.requests.revocations_count -= 1u32; + } + } + } + >::insert(&delegator, state); + } // else delegator is not a delegator so no update needed + } + Ok(().into()) + } + #[pallet::weight( ::WeightInfo::hotfix_update_candidate_pool_value(candidates.len() as u32) )] - /// Hotfix patch to correct and update CandidatePool value for candidates that have - /// called candidate_bond_more when it did not update the CandidatePool value - pub fn hotfix_update_candidate_pool_value( - origin: OriginFor, - candidates: Vec, - ) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - for candidate in candidates { - if let Some(state) = >::get(&candidate) { - Self::update_active(candidate, state.total_counted); - } // else candidate is not a candidate so no update needed - } - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_staking_expectations())] - /// Set the expectations for total staked. These expectations determine the issuance for - /// the round according to logic in `fn compute_issuance` - pub fn set_staking_expectations( - origin: OriginFor, - expectations: Range>, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - ensure!(expectations.is_valid(), Error::::InvalidSchedule); - let mut config = >::get(); - ensure!( - config.expect != expectations, - Error::::NoWritingSameValue - ); - config.set_expectations(expectations); - Self::deposit_event(Event::StakeExpectationsSet( - config.expect.min, - config.expect.ideal, - config.expect.max, - )); - >::put(config); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_inflation())] - /// Set the annual inflation rate to derive per-round inflation - pub fn set_inflation( - origin: OriginFor, - schedule: Range, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - ensure!(schedule.is_valid(), Error::::InvalidSchedule); - let mut config = >::get(); - ensure!(config.annual != schedule, Error::::NoWritingSameValue); - config.annual = schedule; - config.set_round_from_annual::(schedule); - Self::deposit_event(Event::InflationSet( - config.annual.min, - config.annual.ideal, - config.annual.max, - config.round.min, - config.round.ideal, - config.round.max, - )); - >::put(config); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_parachain_bond_account())] - /// Set the account that will hold funds set aside for parachain bond - pub fn set_parachain_bond_account( - origin: OriginFor, - new: T::AccountId, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - let ParachainBondConfig { - account: old, - percent, - } = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); - >::put(ParachainBondConfig { - account: new.clone(), - percent, - }); - Self::deposit_event(Event::ParachainBondAccountSet(old, new)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_parachain_bond_reserve_percent())] - /// Set the percent of inflation set aside for parachain bond - pub fn set_parachain_bond_reserve_percent( - origin: OriginFor, - new: Percent, - ) -> DispatchResultWithPostInfo { - T::MonetaryGovernanceOrigin::ensure_origin(origin)?; - let ParachainBondConfig { - account, - percent: old, - } = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); - >::put(ParachainBondConfig { - account, - percent: new, - }); - Self::deposit_event(Event::ParachainBondReservePercentSet(old, new)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_total_selected())] - /// Set the total number of collator candidates selected per round - /// - changes are not applied until the start of the next round - pub fn set_total_selected(origin: OriginFor, new: u32) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - ensure!( - new >= T::MinSelectedCandidates::get(), - Error::::CannotSetBelowMin - ); - let old = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); - ensure!( - new <= >::get().length, - Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, - ); - >::put(new); - Self::deposit_event(Event::TotalSelectedSet(old, new)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_collator_commission())] - /// Set the commission for all collators - pub fn set_collator_commission( - origin: OriginFor, - new: Perbill, - ) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - let old = >::get(); - ensure!(old != new, Error::::NoWritingSameValue); - >::put(new); - Self::deposit_event(Event::CollatorCommissionSet(old, new)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::set_blocks_per_round())] - /// Set blocks per round - /// - if called with `new` less than length of current round, will transition immediately - /// in the next block - /// - also updates per-round inflation config - pub fn set_blocks_per_round(origin: OriginFor, new: u32) -> DispatchResultWithPostInfo { - frame_system::ensure_root(origin)?; - ensure!( - new >= T::MinBlocksPerRound::get(), - Error::::CannotSetBelowMin - ); - let mut round = >::get(); - let (now, first, old) = (round.current, round.first, round.length); - ensure!(old != new, Error::::NoWritingSameValue); - ensure!( - new >= >::get(), - Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, - ); - round.length = new; - // update per-round inflation given new rounds per year - let mut inflation_config = >::get(); - inflation_config.reset_round(new); - >::put(round); - Self::deposit_event(Event::BlocksPerRoundSet( - now, - first, - old, - new, - inflation_config.round.min, - inflation_config.round.ideal, - inflation_config.round.max, - )); - >::put(inflation_config); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::join_candidates(*candidate_count))] - /// Join the set of collator candidates - pub fn join_candidates( - origin: OriginFor, - bond: BalanceOf, - candidate_count: u32, - ) -> DispatchResultWithPostInfo { - let acc = ensure_signed(origin)?; - ensure!(!Self::is_candidate(&acc), Error::::CandidateExists); - ensure!(!Self::is_delegator(&acc), Error::::DelegatorExists); - ensure!( - bond >= T::MinCandidateStk::get(), - Error::::CandidateBondBelowMin - ); - let mut candidates = >::get(); - let old_count = candidates.0.len() as u32; - ensure!( - candidate_count >= old_count, - Error::::TooLowCandidateCountWeightHintJoinCandidates - ); - ensure!( - candidates.insert(Bond { - owner: acc.clone(), - amount: bond - }), - Error::::CandidateExists - ); - T::Currency::reserve(&acc, bond)?; - let candidate = CandidateMetadata::new(bond); - >::insert(&acc, candidate); - let empty_delegations: Delegations> = Default::default(); - // insert empty top delegations - >::insert(&acc, empty_delegations.clone()); - // insert empty bottom delegations - >::insert(&acc, empty_delegations); - >::put(candidates); - let new_total = >::get().saturating_add(bond); - >::put(new_total); - Self::deposit_event(Event::JoinedCollatorCandidates(acc, bond, new_total)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::schedule_leave_candidates(*candidate_count))] - /// Request to leave the set of candidates. If successful, the account is immediately - /// removed from the candidate pool to prevent selection as a collator. - pub fn schedule_leave_candidates( - origin: OriginFor, - candidate_count: u32, - ) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; - let (now, when) = state.schedule_leave::()?; - let mut candidates = >::get(); - ensure!( - candidate_count >= candidates.0.len() as u32, - Error::::TooLowCandidateCountToLeaveCandidates - ); - if candidates.remove(&Bond::from_owner(collator.clone())) { - >::put(candidates); - } - >::insert(&collator, state); - Self::deposit_event(Event::CandidateScheduledExit(now, collator, when)); - Ok(().into()) - } - #[pallet::weight( + /// Hotfix patch to correct and update CandidatePool value for candidates that have + /// called candidate_bond_more when it did not update the CandidatePool value + pub fn hotfix_update_candidate_pool_value( + origin: OriginFor, + candidates: Vec, + ) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + for candidate in candidates { + if let Some(state) = >::get(&candidate) { + Self::update_active(candidate, state.total_counted); + } // else candidate is not a candidate so no update needed + } + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_staking_expectations())] + /// Set the expectations for total staked. These expectations determine the issuance for + /// the round according to logic in `fn compute_issuance` + pub fn set_staking_expectations( + origin: OriginFor, + expectations: Range>, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + ensure!(expectations.is_valid(), Error::::InvalidSchedule); + let mut config = >::get(); + ensure!( + config.expect != expectations, + Error::::NoWritingSameValue + ); + config.set_expectations(expectations); + Self::deposit_event(Event::StakeExpectationsSet( + config.expect.min, + config.expect.ideal, + config.expect.max, + )); + >::put(config); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_inflation())] + /// Set the annual inflation rate to derive per-round inflation + pub fn set_inflation( + origin: OriginFor, + schedule: Range, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + ensure!(schedule.is_valid(), Error::::InvalidSchedule); + let mut config = >::get(); + ensure!(config.annual != schedule, Error::::NoWritingSameValue); + config.annual = schedule; + config.set_round_from_annual::(schedule); + Self::deposit_event(Event::InflationSet( + config.annual.min, + config.annual.ideal, + config.annual.max, + config.round.min, + config.round.ideal, + config.round.max, + )); + >::put(config); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_parachain_bond_account())] + /// Set the account that will hold funds set aside for parachain bond + pub fn set_parachain_bond_account( + origin: OriginFor, + new: T::AccountId, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + let ParachainBondConfig { + account: old, + percent, + } = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + >::put(ParachainBondConfig { + account: new.clone(), + percent, + }); + Self::deposit_event(Event::ParachainBondAccountSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_parachain_bond_reserve_percent())] + /// Set the percent of inflation set aside for parachain bond + pub fn set_parachain_bond_reserve_percent( + origin: OriginFor, + new: Percent, + ) -> DispatchResultWithPostInfo { + T::MonetaryGovernanceOrigin::ensure_origin(origin)?; + let ParachainBondConfig { + account, + percent: old, + } = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + >::put(ParachainBondConfig { + account, + percent: new, + }); + Self::deposit_event(Event::ParachainBondReservePercentSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_total_selected())] + /// Set the total number of collator candidates selected per round + /// - changes are not applied until the start of the next round + pub fn set_total_selected(origin: OriginFor, new: u32) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + ensure!( + new >= T::MinSelectedCandidates::get(), + Error::::CannotSetBelowMin + ); + let old = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + ensure!( + new <= >::get().length, + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + >::put(new); + Self::deposit_event(Event::TotalSelectedSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_collator_commission())] + /// Set the commission for all collators + pub fn set_collator_commission( + origin: OriginFor, + new: Perbill, + ) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + let old = >::get(); + ensure!(old != new, Error::::NoWritingSameValue); + >::put(new); + Self::deposit_event(Event::CollatorCommissionSet(old, new)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::set_blocks_per_round())] + /// Set blocks per round + /// - if called with `new` less than length of current round, will transition immediately + /// in the next block + /// - also updates per-round inflation config + pub fn set_blocks_per_round( + origin: OriginFor, + new: u32, + ) -> DispatchResultWithPostInfo { + frame_system::ensure_root(origin)?; + ensure!( + new >= T::MinBlocksPerRound::get(), + Error::::CannotSetBelowMin + ); + let mut round = >::get(); + let (now, first, old) = (round.current, round.first, round.length); + ensure!(old != new, Error::::NoWritingSameValue); + ensure!( + new >= >::get(), + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + round.length = new; + // update per-round inflation given new rounds per year + let mut inflation_config = >::get(); + inflation_config.reset_round(new); + >::put(round); + Self::deposit_event(Event::BlocksPerRoundSet( + now, + first, + old, + new, + inflation_config.round.min, + inflation_config.round.ideal, + inflation_config.round.max, + )); + >::put(inflation_config); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::join_candidates(*candidate_count))] + /// Join the set of collator candidates + pub fn join_candidates( + origin: OriginFor, + bond: BalanceOf, + candidate_count: u32, + ) -> DispatchResultWithPostInfo { + let acc = ensure_signed(origin)?; + ensure!(!Self::is_candidate(&acc), Error::::CandidateExists); + ensure!(!Self::is_delegator(&acc), Error::::DelegatorExists); + ensure!( + bond >= T::MinCandidateStk::get(), + Error::::CandidateBondBelowMin + ); + let mut candidates = >::get(); + let old_count = candidates.0.len() as u32; + ensure!( + candidate_count >= old_count, + Error::::TooLowCandidateCountWeightHintJoinCandidates + ); + ensure!( + candidates.insert(Bond { + owner: acc.clone(), + amount: bond + }), + Error::::CandidateExists + ); + T::Currency::reserve(&acc, bond)?; + let candidate = CandidateMetadata::new(bond); + >::insert(&acc, candidate); + let empty_delegations: Delegations> = Default::default(); + // insert empty top delegations + >::insert(&acc, empty_delegations.clone()); + // insert empty bottom delegations + >::insert(&acc, empty_delegations); + >::put(candidates); + let new_total = >::get().saturating_add(bond); + >::put(new_total); + Self::deposit_event(Event::JoinedCollatorCandidates(acc, bond, new_total)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_leave_candidates(*candidate_count))] + /// Request to leave the set of candidates. If successful, the account is immediately + /// removed from the candidate pool to prevent selection as a collator. + pub fn schedule_leave_candidates( + origin: OriginFor, + candidate_count: u32, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + let (now, when) = state.schedule_leave::()?; + let mut candidates = >::get(); + ensure!( + candidate_count >= candidates.0.len() as u32, + Error::::TooLowCandidateCountToLeaveCandidates + ); + if candidates.remove(&Bond::from_owner(collator.clone())) { + >::put(candidates); + } + >::insert(&collator, state); + Self::deposit_event(Event::CandidateScheduledExit(now, collator, when)); + Ok(().into()) + } + #[pallet::weight( ::WeightInfo::execute_leave_candidates(*candidate_delegation_count) )] - /// Execute leave candidates request - pub fn execute_leave_candidates( - origin: OriginFor, - candidate: T::AccountId, - candidate_delegation_count: u32, - ) -> DispatchResultWithPostInfo { - ensure_signed(origin)?; - let state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; - ensure!( - state.delegation_count <= candidate_delegation_count, - Error::::TooLowCandidateDelegationCountToLeaveCandidates - ); - state.can_leave::()?; - let return_stake = |bond: Bond>| { - T::Currency::unreserve(&bond.owner, bond.amount); - // remove delegation from delegator state - let mut delegator = DelegatorState::::get(&bond.owner).expect( - "Collator state and delegator state are consistent. + /// Execute leave candidates request + pub fn execute_leave_candidates( + origin: OriginFor, + candidate: T::AccountId, + candidate_delegation_count: u32, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + let state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; + ensure!( + state.delegation_count <= candidate_delegation_count, + Error::::TooLowCandidateDelegationCountToLeaveCandidates + ); + state.can_leave::()?; + let return_stake = |bond: Bond>| { + T::Currency::unreserve(&bond.owner, bond.amount); + // remove delegation from delegator state + let mut delegator = DelegatorState::::get(&bond.owner).expect( + "Collator state and delegator state are consistent. Collator state has a record of this delegation. Therefore, Delegator state also has a record. qed.", - ); - if let Some(remaining) = delegator.rm_delegation(&candidate) { - if remaining.is_zero() { - >::remove(&bond.owner); - } else { - if let Some(request) = delegator.requests.requests.remove(&candidate) { - delegator.requests.less_total = - delegator.requests.less_total.saturating_sub(request.amount); - if matches!(request.action, DelegationChange::Revoke) { - delegator.requests.revocations_count -= 1u32; - } - } - >::insert(&bond.owner, delegator); - } - } - }; - // total backing stake is at least the candidate self bond - let mut total_backing = state.bond; - // return all top delegations - let top_delegations = - >::take(&candidate).expect("CandidateInfo existence checked"); - for bond in top_delegations.delegations { - return_stake(bond); - } - total_backing += top_delegations.total; - // return all bottom delegations - let bottom_delegations = - >::take(&candidate).expect("CandidateInfo existence checked"); - for bond in bottom_delegations.delegations { - return_stake(bond); - } - total_backing += bottom_delegations.total; - // return stake to collator - T::Currency::unreserve(&candidate, state.bond); - >::remove(&candidate); - >::remove(&candidate); - >::remove(&candidate); - let new_total_staked = >::get().saturating_sub(total_backing); - >::put(new_total_staked); - Self::deposit_event(Event::CandidateLeft( - candidate, - total_backing, - new_total_staked, - )); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::cancel_leave_candidates(*candidate_count))] - /// Cancel open request to leave candidates - /// - only callable by collator account - /// - result upon successful call is the candidate is active in the candidate pool - pub fn cancel_leave_candidates( - origin: OriginFor, - candidate_count: u32, - ) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(state.is_leaving(), Error::::CandidateNotLeaving); - state.go_online(); - let mut candidates = >::get(); - ensure!( - candidates.0.len() as u32 <= candidate_count, - Error::::TooLowCandidateCountWeightHintCancelLeaveCandidates - ); - ensure!( - candidates.insert(Bond { - owner: collator.clone(), - amount: state.total_counted - }), - Error::::AlreadyActive - ); - >::put(candidates); - >::insert(&collator, state); - Self::deposit_event(Event::CancelledCandidateExit(collator)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::go_offline())] - /// Temporarily leave the set of collator candidates without unbonding - pub fn go_offline(origin: OriginFor) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(state.is_active(), Error::::AlreadyOffline); - state.go_offline(); - let mut candidates = >::get(); - if candidates.remove(&Bond::from_owner(collator.clone())) { - >::put(candidates); - } - >::insert(&collator, state); - Self::deposit_event(Event::CandidateWentOffline(collator)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::go_online())] - /// Rejoin the set of collator candidates if previously had called `go_offline` - pub fn go_online(origin: OriginFor) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; - ensure!(!state.is_active(), Error::::AlreadyActive); - ensure!(!state.is_leaving(), Error::::CannotGoOnlineIfLeaving); - state.go_online(); - let mut candidates = >::get(); - ensure!( - candidates.insert(Bond { - owner: collator.clone(), - amount: state.total_counted - }), - Error::::AlreadyActive - ); - >::put(candidates); - >::insert(&collator, state); - Self::deposit_event(Event::CandidateBackOnline(collator)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::candidate_bond_more())] - /// Increase collator candidate self bond by `more` - pub fn candidate_bond_more( - origin: OriginFor, - more: BalanceOf, - ) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; - state.bond_more::(collator.clone(), more)?; - let (is_active, total_counted) = (state.is_active(), state.total_counted); - >::insert(&collator, state); - if is_active { - Self::update_active(collator, total_counted); - } - Ok(().into()) - } - #[pallet::weight(::WeightInfo::schedule_candidate_bond_less())] - /// Request by collator candidate to decrease self bond by `less` - pub fn schedule_candidate_bond_less( - origin: OriginFor, - less: BalanceOf, - ) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; - let when = state.schedule_bond_less::(less)?; - >::insert(&collator, state); - Self::deposit_event(Event::CandidateBondLessRequested(collator, less, when)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::execute_candidate_bond_less())] - /// Execute pending request to adjust the collator candidate self bond - pub fn execute_candidate_bond_less( - origin: OriginFor, - candidate: T::AccountId, - ) -> DispatchResultWithPostInfo { - ensure_signed(origin)?; // we may want to reward this if caller != candidate - let mut state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; - state.execute_bond_less::(candidate.clone())?; - >::insert(&candidate, state); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::cancel_candidate_bond_less())] - /// Cancel pending request to adjust the collator candidate self bond - pub fn cancel_candidate_bond_less(origin: OriginFor) -> DispatchResultWithPostInfo { - let collator = ensure_signed(origin)?; - let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; - state.cancel_bond_less::(collator.clone())?; - >::insert(&collator, state); - Ok(().into()) - } - #[pallet::weight( + ); + if let Some(remaining) = delegator.rm_delegation(&candidate) { + if remaining.is_zero() { + >::remove(&bond.owner); + } else { + if let Some(request) = delegator.requests.requests.remove(&candidate) { + delegator.requests.less_total = + delegator.requests.less_total.saturating_sub(request.amount); + if matches!(request.action, DelegationChange::Revoke) { + delegator.requests.revocations_count -= 1u32; + } + } + >::insert(&bond.owner, delegator); + } + } + }; + // total backing stake is at least the candidate self bond + let mut total_backing = state.bond; + // return all top delegations + let top_delegations = + >::take(&candidate).expect("CandidateInfo existence checked"); + for bond in top_delegations.delegations { + return_stake(bond); + } + total_backing += top_delegations.total; + // return all bottom delegations + let bottom_delegations = >::take(&candidate) + .expect("CandidateInfo existence checked"); + for bond in bottom_delegations.delegations { + return_stake(bond); + } + total_backing += bottom_delegations.total; + // return stake to collator + T::Currency::unreserve(&candidate, state.bond); + >::remove(&candidate); + >::remove(&candidate); + >::remove(&candidate); + let new_total_staked = >::get().saturating_sub(total_backing); + >::put(new_total_staked); + Self::deposit_event(Event::CandidateLeft( + candidate, + total_backing, + new_total_staked, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_leave_candidates(*candidate_count))] + /// Cancel open request to leave candidates + /// - only callable by collator account + /// - result upon successful call is the candidate is active in the candidate pool + pub fn cancel_leave_candidates( + origin: OriginFor, + candidate_count: u32, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + ensure!(state.is_leaving(), Error::::CandidateNotLeaving); + state.go_online(); + let mut candidates = >::get(); + ensure!( + candidates.0.len() as u32 <= candidate_count, + Error::::TooLowCandidateCountWeightHintCancelLeaveCandidates + ); + ensure!( + candidates.insert(Bond { + owner: collator.clone(), + amount: state.total_counted + }), + Error::::AlreadyActive + ); + >::put(candidates); + >::insert(&collator, state); + Self::deposit_event(Event::CancelledCandidateExit(collator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::go_offline())] + /// Temporarily leave the set of collator candidates without unbonding + pub fn go_offline(origin: OriginFor) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + ensure!(state.is_active(), Error::::AlreadyOffline); + state.go_offline(); + let mut candidates = >::get(); + if candidates.remove(&Bond::from_owner(collator.clone())) { + >::put(candidates); + } + >::insert(&collator, state); + Self::deposit_event(Event::CandidateWentOffline(collator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::go_online())] + /// Rejoin the set of collator candidates if previously had called `go_offline` + pub fn go_online(origin: OriginFor) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + ensure!(!state.is_active(), Error::::AlreadyActive); + ensure!(!state.is_leaving(), Error::::CannotGoOnlineIfLeaving); + state.go_online(); + let mut candidates = >::get(); + ensure!( + candidates.insert(Bond { + owner: collator.clone(), + amount: state.total_counted + }), + Error::::AlreadyActive + ); + >::put(candidates); + >::insert(&collator, state); + Self::deposit_event(Event::CandidateBackOnline(collator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::candidate_bond_more())] + /// Increase collator candidate self bond by `more` + pub fn candidate_bond_more( + origin: OriginFor, + more: BalanceOf, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + state.bond_more::(collator.clone(), more)?; + let (is_active, total_counted) = (state.is_active(), state.total_counted); + >::insert(&collator, state); + if is_active { + Self::update_active(collator, total_counted); + } + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_candidate_bond_less())] + /// Request by collator candidate to decrease self bond by `less` + pub fn schedule_candidate_bond_less( + origin: OriginFor, + less: BalanceOf, + ) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + let when = state.schedule_bond_less::(less)?; + >::insert(&collator, state); + Self::deposit_event(Event::CandidateBondLessRequested(collator, less, when)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::execute_candidate_bond_less())] + /// Execute pending request to adjust the collator candidate self bond + pub fn execute_candidate_bond_less( + origin: OriginFor, + candidate: T::AccountId, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; // we may want to reward this if caller != candidate + let mut state = + >::get(&candidate).ok_or(Error::::CandidateDNE)?; + state.execute_bond_less::(candidate.clone())?; + >::insert(&candidate, state); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_candidate_bond_less())] + /// Cancel pending request to adjust the collator candidate self bond + pub fn cancel_candidate_bond_less(origin: OriginFor) -> DispatchResultWithPostInfo { + let collator = ensure_signed(origin)?; + let mut state = >::get(&collator).ok_or(Error::::CandidateDNE)?; + state.cancel_bond_less::(collator.clone())?; + >::insert(&collator, state); + Ok(().into()) + } + #[pallet::weight( ::WeightInfo::delegate( *candidate_delegation_count, *delegation_count ) )] - /// If caller is not a delegator and not a collator, then join the set of delegators - /// If caller is a delegator, then makes delegation to change their delegation state - pub fn delegate( - origin: OriginFor, - candidate: T::AccountId, - amount: BalanceOf, - // will_be_in_top: bool // weight hint - // look into returning weight in DispatchResult - candidate_delegation_count: u32, - delegation_count: u32, - ) -> DispatchResultWithPostInfo { - let delegator = ensure_signed(origin)?; - // check that caller can reserve the amount before any changes to storage - ensure!( - T::Currency::can_reserve(&delegator, amount), - Error::::InsufficientBalance - ); - let delegator_state = if let Some(mut state) = >::get(&delegator) { - ensure!(state.is_active(), Error::::CannotDelegateIfLeaving); - // delegation after first - ensure!( - amount >= T::MinDelegation::get(), - Error::::DelegationBelowMin - ); - ensure!( - delegation_count >= state.delegations.0.len() as u32, - Error::::TooLowDelegationCountToDelegate - ); - ensure!( - (state.delegations.0.len() as u32) < T::MaxDelegationsPerDelegator::get(), - Error::::ExceedMaxDelegationsPerDelegator - ); - ensure!( - state.add_delegation(Bond { - owner: candidate.clone(), - amount - }), - Error::::AlreadyDelegatedCandidate - ); - state - } else { - // first delegation - ensure!( - amount >= T::MinDelegatorStk::get(), - Error::::DelegatorBondBelowMin - ); - ensure!(!Self::is_candidate(&delegator), Error::::CandidateExists); - Delegator::new(delegator.clone(), candidate.clone(), amount) - }; - let mut state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; - ensure!( - candidate_delegation_count >= state.delegation_count, - Error::::TooLowCandidateDelegationCountToDelegate - ); - let (delegator_position, less_total_staked) = state.add_delegation::( - &candidate, - Bond { - owner: delegator.clone(), - amount, - }, - )?; - T::Currency::reserve(&delegator, amount) - .expect("verified can reserve at top of this extrinsic body"); - if let DelegatorAdded::AddedToTop { new_total } = delegator_position { - if state.is_active() { - Self::update_active(candidate.clone(), new_total); - } - } - // only is_some if kicked the lowest bottom as a consequence of this new delegation - let net_total_increase = if let Some(less) = less_total_staked { - amount - less - } else { - amount - }; - let new_total_locked = >::get() + net_total_increase; - >::put(new_total_locked); - >::insert(&candidate, state); - >::insert(&delegator, delegator_state); - Self::deposit_event(Event::Delegation( - delegator, - amount, - candidate, - delegator_position, - )); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::schedule_leave_delegators())] - /// Request to leave the set of delegators. If successful, the caller is scheduled - /// to be allowed to exit. Success forbids future delegator actions until the request is - /// invoked or cancelled. - pub fn schedule_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { - let acc = ensure_signed(origin)?; - let mut state = >::get(&acc).ok_or(Error::::DelegatorDNE)?; - ensure!(!state.is_leaving(), Error::::DelegatorAlreadyLeaving); - let (now, when) = state.schedule_leave::(); - >::insert(&acc, state); - Self::deposit_event(Event::DelegatorExitScheduled(now, acc, when)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::execute_leave_delegators(*delegation_count))] - /// Execute the right to exit the set of delegators and revoke all ongoing delegations. - pub fn execute_leave_delegators( - origin: OriginFor, - delegator: T::AccountId, - delegation_count: u32, - ) -> DispatchResultWithPostInfo { - ensure_signed(origin)?; - let state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; - state.can_execute_leave::(delegation_count)?; - for bond in state.delegations.0 { - if let Err(error) = Self::delegator_leaves_candidate( - bond.owner.clone(), - delegator.clone(), - bond.amount, - ) { - log::warn!( - "STORAGE CORRUPTED \nDelegator leaving collator failed with error: {:?}", - error - ); - } - } - >::remove(&delegator); - Self::deposit_event(Event::DelegatorLeft(delegator, state.total)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::cancel_leave_delegators())] - /// Cancel a pending request to exit the set of delegators. Success clears the pending exit - /// request (thereby resetting the delay upon another `leave_delegators` call). - pub fn cancel_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { - let delegator = ensure_signed(origin)?; - // ensure delegator state exists - let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; - // ensure state is leaving - ensure!(state.is_leaving(), Error::::DelegatorDNE); - // cancel exit request - state.cancel_leave(); - >::insert(&delegator, state); - Self::deposit_event(Event::DelegatorExitCancelled(delegator)); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::schedule_revoke_delegation())] - /// Request to revoke an existing delegation. If successful, the delegation is scheduled - /// to be allowed to be revoked via the `execute_delegation_request` extrinsic. - pub fn schedule_revoke_delegation( - origin: OriginFor, - collator: T::AccountId, - ) -> DispatchResultWithPostInfo { - let delegator = ensure_signed(origin)?; - let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; - let (now, when) = state.schedule_revoke::(collator.clone())?; - >::insert(&delegator, state); - Self::deposit_event(Event::DelegationRevocationScheduled( - now, delegator, collator, when, - )); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::delegator_bond_more())] - /// Bond more for delegators wrt a specific collator candidate. - pub fn delegator_bond_more( - origin: OriginFor, - candidate: T::AccountId, - more: BalanceOf, - ) -> DispatchResultWithPostInfo { - let delegator = ensure_signed(origin)?; - let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; - state.increase_delegation::(candidate.clone(), more)?; - Ok(().into()) - } - #[pallet::weight(::WeightInfo::schedule_delegator_bond_less())] - /// Request bond less for delegators wrt a specific collator candidate. - pub fn schedule_delegator_bond_less( - origin: OriginFor, - candidate: T::AccountId, - less: BalanceOf, - ) -> DispatchResultWithPostInfo { - let caller = ensure_signed(origin)?; - let mut state = >::get(&caller).ok_or(Error::::DelegatorDNE)?; - let when = state.schedule_decrease_delegation::(candidate.clone(), less)?; - >::insert(&caller, state); - Self::deposit_event(Event::DelegationDecreaseScheduled( - caller, candidate, less, when, - )); - Ok(().into()) - } - #[pallet::weight(::WeightInfo::execute_delegator_bond_less())] - /// Execute pending request to change an existing delegation - pub fn execute_delegation_request( - origin: OriginFor, - delegator: T::AccountId, - candidate: T::AccountId, - ) -> DispatchResultWithPostInfo { - ensure_signed(origin)?; // we may want to reward caller if caller != delegator - let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; - state.execute_pending_request::(candidate)?; - Ok(().into()) - } - #[pallet::weight(::WeightInfo::cancel_delegator_bond_less())] - /// Cancel request to change an existing delegation. - pub fn cancel_delegation_request( - origin: OriginFor, - candidate: T::AccountId, - ) -> DispatchResultWithPostInfo { - let delegator = ensure_signed(origin)?; - let mut state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; - let request = state.cancel_pending_request::(candidate)?; - >::insert(&delegator, state); - Self::deposit_event(Event::CancelledDelegationRequest(delegator, request)); - Ok(().into()) - } - } - - impl Pallet { - pub fn is_delegator(acc: &T::AccountId) -> bool { - >::get(acc).is_some() - } - pub fn is_candidate(acc: &T::AccountId) -> bool { - >::get(acc).is_some() - } - pub fn is_selected_candidate(acc: &T::AccountId) -> bool { - >::get().binary_search(acc).is_ok() - } - /// Caller must ensure candidate is active before calling - pub(crate) fn update_active(candidate: T::AccountId, total: BalanceOf) { - let mut candidates = >::get(); - candidates.remove(&Bond::from_owner(candidate.clone())); - candidates.insert(Bond { - owner: candidate, - amount: total, - }); - >::put(candidates); - } - /// Compute round issuance based on total staked for the given round - fn compute_issuance(staked: BalanceOf) -> BalanceOf { - let config = >::get(); - let round_issuance = crate::inflation::round_issuance_range::(config.round); - // TODO: consider interpolation instead of bounded range - if staked < config.expect.min { - round_issuance.min - } else if staked > config.expect.max { - round_issuance.max - } else { - round_issuance.ideal - } - } - /// Remove delegation from candidate state - /// Amount input should be retrieved from delegator and it informs the storage lookups - fn delegator_leaves_candidate( - candidate: T::AccountId, - delegator: T::AccountId, - amount: BalanceOf, - ) -> DispatchResult { - let mut state = >::get(&candidate).ok_or(Error::::CandidateDNE)?; - let total_changed = - state.rm_delegation_if_exists::(&candidate, delegator.clone(), amount)?; - T::Currency::unreserve(&delegator, amount); - if state.is_active() && total_changed { - Self::update_active(candidate.clone(), state.total_counted); - } - let new_total_locked = >::get().saturating_sub(amount); - >::put(new_total_locked); - let new_total = state.total_counted; - >::insert(&candidate, state); - Self::deposit_event(Event::DelegatorLeftCandidate( - delegator, candidate, amount, new_total, - )); - Ok(()) - } - fn prepare_staking_payouts(now: RoundIndex) { - // payout is now - delay rounds ago => now - delay > 0 else return early - let delay = T::RewardPaymentDelay::get(); - if now <= delay { - return; - } - let round_to_payout = now - delay; - let total_points = >::get(round_to_payout); - if total_points.is_zero() { - return; - } - let total_staked = >::take(round_to_payout); - let total_issuance = Self::compute_issuance(total_staked); - let mut left_issuance = total_issuance; - // reserve portion of issuance for parachain bond account - let bond_config = >::get(); - let parachain_bond_reserve = bond_config.percent * total_issuance; - if let Ok(imb) = - T::Currency::deposit_into_existing(&bond_config.account, parachain_bond_reserve) - { - // update round issuance iff transfer succeeds - left_issuance -= imb.peek(); - Self::deposit_event(Event::ReservedForParachainBond( - bond_config.account, - imb.peek(), - )); - } - - let payout = DelayedPayout { - round_issuance: total_issuance, - total_staking_reward: left_issuance, - collator_commission: >::get(), - }; - - >::insert(round_to_payout, payout); - } - - /// Wrapper around pay_one_collator_reward which handles the following logic: - /// * whether or not a payout needs to be made - /// * cleaning up when payouts are done - /// * returns the weight consumed by pay_one_collator_reward if applicable - fn handle_delayed_payouts(now: RoundIndex) -> Weight { - let delay = T::RewardPaymentDelay::get(); - - // don't underflow uint - if now < delay { - return 0u64.into(); - } - - let paid_for_round = now - delay; - - if let Some(payout_info) = >::get(paid_for_round) { - let result = Self::pay_one_collator_reward(paid_for_round, payout_info); - if result.0.is_none() { - // result.0 indicates whether or not a payout was made - // clean up storage items that we no longer need - >::remove(paid_for_round); - >::remove(paid_for_round); - } - result.1 // weight consumed by pay_one_collator_reward - } else { - 0u64.into() - } - } - - /// Payout a single collator from the given round. - /// - /// Returns an optional tuple of (Collator's AccountId, total paid) - /// or None if there were no more payouts to be made for the round. - pub(crate) fn pay_one_collator_reward( - paid_for_round: RoundIndex, - payout_info: DelayedPayout>, - ) -> (Option<(T::AccountId, BalanceOf)>, Weight) { - // TODO: it would probably be optimal to roll Points into the DelayedPayouts storage - // item so that we do fewer reads each block - let total_points = >::get(paid_for_round); - if total_points.is_zero() { - // TODO: this case is obnoxious... it's a value query, so it could mean one of two - // different logic errors: - // 1. we removed it before we should have - // 2. we called pay_one_collator_reward when we were actually done with deferred - // payouts - log::warn!("pay_one_collator_reward called with no > for the round!"); - return (None, 0u64.into()); - } - - let mint = |amt: BalanceOf, to: T::AccountId| { - if let Ok(amount_transferred) = T::Currency::deposit_into_existing(&to, amt) { - Self::deposit_event(Event::Rewarded(to.clone(), amount_transferred.peek())); - } - }; - - let collator_fee = payout_info.collator_commission; - let collator_issuance = collator_fee * payout_info.round_issuance; - - if let Some((collator, pts)) = - >::iter_prefix(paid_for_round).drain().next() - { - let pct_due = Perbill::from_rational(pts, total_points); - let total_paid = pct_due * payout_info.total_staking_reward; - let mut amt_due = total_paid; - // Take the snapshot of block author and delegations - let state = >::take(paid_for_round, &collator); - let num_delegators = state.delegations.len(); - if state.delegations.is_empty() { - // solo collator with no delegators - mint(amt_due, collator.clone()); - } else { - // pay collator first; commission + due_portion - let collator_pct = Perbill::from_rational(state.bond, state.total); - let commission = pct_due * collator_issuance; - amt_due -= commission; - let collator_reward = (collator_pct * amt_due) + commission; - mint(collator_reward, collator.clone()); - // pay delegators due portion - for Bond { owner, amount } in state.delegations { - let percent = Perbill::from_rational(amount, state.total); - let due = percent * amt_due; - mint(due, owner.clone()); - } - } - - ( - Some((collator, total_paid)), - T::WeightInfo::pay_one_collator_reward(num_delegators as u32), - ) - } else { - // Note that we don't clean up storage here; it is cleaned up in - // handle_delayed_payouts() - (None, 0u64.into()) - } - } - - /// Compute the top `TotalSelected` candidates in the CandidatePool and return - /// a vec of their AccountIds (in the order of selection) - pub fn compute_top_candidates() -> Vec { - let mut candidates = >::get().0; - // order candidates by stake (least to greatest so requires `rev()`) - candidates.sort_by(|a, b| a.amount.partial_cmp(&b.amount).unwrap()); - let top_n = >::get() as usize; - // choose the top TotalSelected qualified candidates, ordered by stake - let mut collators = candidates - .into_iter() - .rev() - .take(top_n) - .filter(|x| x.amount >= T::MinCollatorStk::get()) - .map(|x| x.owner) - .collect::>(); - collators.sort(); - collators - } - /// Best as in most cumulatively supported in terms of stake - /// Returns [collator_count, delegation_count, total staked] - fn select_top_candidates(now: RoundIndex) -> (u32, u32, BalanceOf) { - let (mut collator_count, mut delegation_count, mut total) = - (0u32, 0u32, BalanceOf::::zero()); - // choose the top TotalSelected qualified candidates, ordered by stake - let collators = Self::compute_top_candidates(); - // snapshot exposure for round for weighting reward distribution - for account in collators.iter() { - let state = >::get(account) - .expect("all members of CandidateQ must be candidates"); - let top_delegations = >::get(account) - .expect("all members of CandidateQ must be candidates"); - collator_count += 1u32; - delegation_count += state.delegation_count; - total += state.total_counted; - let snapshot_total = state.total_counted; - let snapshot = CollatorSnapshot { - bond: state.bond, - delegations: top_delegations.delegations, - total: state.total_counted, - }; - >::insert(now, account, snapshot); - Self::deposit_event(Event::CollatorChosen(now, account.clone(), snapshot_total)); - } - // insert canonical collator set - >::put(collators); - (collator_count, delegation_count, total) - } - } - - /// Add reward points to block authors: - /// * 20 points to the block producer for producing a block in the chain - impl nimbus_primitives::EventHandler for Pallet { - fn note_author(author: T::AccountId) { - let now = >::get().current; - let score_plus_20 = >::get(now, &author) + 20; - >::insert(now, author, score_plus_20); - >::mutate(now, |x| *x += 20); - } - } - - impl nimbus_primitives::CanAuthor for Pallet { - fn can_author(account: &T::AccountId, _slot: &u32) -> bool { - Self::is_selected_candidate(account) - } - } - - impl Get> for Pallet { - fn get() -> Vec { - Self::selected_candidates() - } - } + /// If caller is not a delegator and not a collator, then join the set of delegators + /// If caller is a delegator, then makes delegation to change their delegation state + pub fn delegate( + origin: OriginFor, + candidate: T::AccountId, + amount: BalanceOf, + // will_be_in_top: bool // weight hint + // look into returning weight in DispatchResult + candidate_delegation_count: u32, + delegation_count: u32, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + // check that caller can reserve the amount before any changes to storage + ensure!( + T::Currency::can_reserve(&delegator, amount), + Error::::InsufficientBalance + ); + let delegator_state = if let Some(mut state) = >::get(&delegator) { + ensure!(state.is_active(), Error::::CannotDelegateIfLeaving); + // delegation after first + ensure!( + amount >= T::MinDelegation::get(), + Error::::DelegationBelowMin + ); + ensure!( + delegation_count >= state.delegations.0.len() as u32, + Error::::TooLowDelegationCountToDelegate + ); + ensure!( + (state.delegations.0.len() as u32) < T::MaxDelegationsPerDelegator::get(), + Error::::ExceedMaxDelegationsPerDelegator + ); + ensure!( + state.add_delegation(Bond { + owner: candidate.clone(), + amount + }), + Error::::AlreadyDelegatedCandidate + ); + state + } else { + // first delegation + ensure!( + amount >= T::MinDelegatorStk::get(), + Error::::DelegatorBondBelowMin + ); + ensure!(!Self::is_candidate(&delegator), Error::::CandidateExists); + Delegator::new(delegator.clone(), candidate.clone(), amount) + }; + let mut state = + >::get(&candidate).ok_or(Error::::CandidateDNE)?; + ensure!( + candidate_delegation_count >= state.delegation_count, + Error::::TooLowCandidateDelegationCountToDelegate + ); + let (delegator_position, less_total_staked) = state.add_delegation::( + &candidate, + Bond { + owner: delegator.clone(), + amount, + }, + )?; + T::Currency::reserve(&delegator, amount) + .expect("verified can reserve at top of this extrinsic body"); + if let DelegatorAdded::AddedToTop { new_total } = delegator_position { + if state.is_active() { + Self::update_active(candidate.clone(), new_total); + } + } + // only is_some if kicked the lowest bottom as a consequence of this new delegation + let net_total_increase = if let Some(less) = less_total_staked { + amount - less + } else { + amount + }; + let new_total_locked = >::get() + net_total_increase; + >::put(new_total_locked); + >::insert(&candidate, state); + >::insert(&delegator, delegator_state); + Self::deposit_event(Event::Delegation( + delegator, + amount, + candidate, + delegator_position, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_leave_delegators())] + /// Request to leave the set of delegators. If successful, the caller is scheduled + /// to be allowed to exit. Success forbids future delegator actions until the request is + /// invoked or cancelled. + pub fn schedule_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { + let acc = ensure_signed(origin)?; + let mut state = >::get(&acc).ok_or(Error::::DelegatorDNE)?; + ensure!(!state.is_leaving(), Error::::DelegatorAlreadyLeaving); + let (now, when) = state.schedule_leave::(); + >::insert(&acc, state); + Self::deposit_event(Event::DelegatorExitScheduled(now, acc, when)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::execute_leave_delegators(*delegation_count))] + /// Execute the right to exit the set of delegators and revoke all ongoing delegations. + pub fn execute_leave_delegators( + origin: OriginFor, + delegator: T::AccountId, + delegation_count: u32, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + let state = >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + state.can_execute_leave::(delegation_count)?; + for bond in state.delegations.0 { + if let Err(error) = Self::delegator_leaves_candidate( + bond.owner.clone(), + delegator.clone(), + bond.amount, + ) { + log::warn!( + "STORAGE CORRUPTED \nDelegator leaving collator failed with error: {:?}", + error + ); + } + } + >::remove(&delegator); + Self::deposit_event(Event::DelegatorLeft(delegator, state.total)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_leave_delegators())] + /// Cancel a pending request to exit the set of delegators. Success clears the pending exit + /// request (thereby resetting the delay upon another `leave_delegators` call). + pub fn cancel_leave_delegators(origin: OriginFor) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + // ensure delegator state exists + let mut state = + >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + // ensure state is leaving + ensure!(state.is_leaving(), Error::::DelegatorDNE); + // cancel exit request + state.cancel_leave(); + >::insert(&delegator, state); + Self::deposit_event(Event::DelegatorExitCancelled(delegator)); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_revoke_delegation())] + /// Request to revoke an existing delegation. If successful, the delegation is scheduled + /// to be allowed to be revoked via the `execute_delegation_request` extrinsic. + pub fn schedule_revoke_delegation( + origin: OriginFor, + collator: T::AccountId, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + let mut state = + >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + let (now, when) = state.schedule_revoke::(collator.clone())?; + >::insert(&delegator, state); + Self::deposit_event(Event::DelegationRevocationScheduled( + now, delegator, collator, when, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::delegator_bond_more())] + /// Bond more for delegators wrt a specific collator candidate. + pub fn delegator_bond_more( + origin: OriginFor, + candidate: T::AccountId, + more: BalanceOf, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + let mut state = + >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + state.increase_delegation::(candidate.clone(), more)?; + Ok(().into()) + } + #[pallet::weight(::WeightInfo::schedule_delegator_bond_less())] + /// Request bond less for delegators wrt a specific collator candidate. + pub fn schedule_delegator_bond_less( + origin: OriginFor, + candidate: T::AccountId, + less: BalanceOf, + ) -> DispatchResultWithPostInfo { + let caller = ensure_signed(origin)?; + let mut state = >::get(&caller).ok_or(Error::::DelegatorDNE)?; + let when = state.schedule_decrease_delegation::(candidate.clone(), less)?; + >::insert(&caller, state); + Self::deposit_event(Event::DelegationDecreaseScheduled( + caller, candidate, less, when, + )); + Ok(().into()) + } + #[pallet::weight(::WeightInfo::execute_delegator_bond_less())] + /// Execute pending request to change an existing delegation + pub fn execute_delegation_request( + origin: OriginFor, + delegator: T::AccountId, + candidate: T::AccountId, + ) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; // we may want to reward caller if caller != delegator + let mut state = + >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + state.execute_pending_request::(candidate)?; + Ok(().into()) + } + #[pallet::weight(::WeightInfo::cancel_delegator_bond_less())] + /// Cancel request to change an existing delegation. + pub fn cancel_delegation_request( + origin: OriginFor, + candidate: T::AccountId, + ) -> DispatchResultWithPostInfo { + let delegator = ensure_signed(origin)?; + let mut state = + >::get(&delegator).ok_or(Error::::DelegatorDNE)?; + let request = state.cancel_pending_request::(candidate)?; + >::insert(&delegator, state); + Self::deposit_event(Event::CancelledDelegationRequest(delegator, request)); + Ok(().into()) + } + } + + impl Pallet { + pub fn is_delegator(acc: &T::AccountId) -> bool { + >::get(acc).is_some() + } + pub fn is_candidate(acc: &T::AccountId) -> bool { + >::get(acc).is_some() + } + pub fn is_selected_candidate(acc: &T::AccountId) -> bool { + >::get().binary_search(acc).is_ok() + } + /// Caller must ensure candidate is active before calling + pub(crate) fn update_active(candidate: T::AccountId, total: BalanceOf) { + let mut candidates = >::get(); + candidates.remove(&Bond::from_owner(candidate.clone())); + candidates.insert(Bond { + owner: candidate, + amount: total, + }); + >::put(candidates); + } + /// Compute round issuance based on total staked for the given round + fn compute_issuance(staked: BalanceOf) -> BalanceOf { + let config = >::get(); + let round_issuance = crate::inflation::round_issuance_range::(config.round); + // TODO: consider interpolation instead of bounded range + if staked < config.expect.min { + round_issuance.min + } else if staked > config.expect.max { + round_issuance.max + } else { + round_issuance.ideal + } + } + /// Remove delegation from candidate state + /// Amount input should be retrieved from delegator and it informs the storage lookups + fn delegator_leaves_candidate( + candidate: T::AccountId, + delegator: T::AccountId, + amount: BalanceOf, + ) -> DispatchResult { + let mut state = + >::get(&candidate).ok_or(Error::::CandidateDNE)?; + let total_changed = + state.rm_delegation_if_exists::(&candidate, delegator.clone(), amount)?; + T::Currency::unreserve(&delegator, amount); + if state.is_active() && total_changed { + Self::update_active(candidate.clone(), state.total_counted); + } + let new_total_locked = >::get().saturating_sub(amount); + >::put(new_total_locked); + let new_total = state.total_counted; + >::insert(&candidate, state); + Self::deposit_event(Event::DelegatorLeftCandidate( + delegator, candidate, amount, new_total, + )); + Ok(()) + } + fn prepare_staking_payouts(now: RoundIndex) { + // payout is now - delay rounds ago => now - delay > 0 else return early + let delay = T::RewardPaymentDelay::get(); + if now <= delay { + return; + } + let round_to_payout = now - delay; + let total_points = >::get(round_to_payout); + if total_points.is_zero() { + return; + } + let total_staked = >::take(round_to_payout); + let total_issuance = Self::compute_issuance(total_staked); + let mut left_issuance = total_issuance; + // reserve portion of issuance for parachain bond account + let bond_config = >::get(); + let parachain_bond_reserve = bond_config.percent * total_issuance; + if let Ok(imb) = + T::Currency::deposit_into_existing(&bond_config.account, parachain_bond_reserve) + { + // update round issuance iff transfer succeeds + left_issuance -= imb.peek(); + Self::deposit_event(Event::ReservedForParachainBond( + bond_config.account, + imb.peek(), + )); + } + + let payout = DelayedPayout { + round_issuance: total_issuance, + total_staking_reward: left_issuance, + collator_commission: >::get(), + }; + + >::insert(round_to_payout, payout); + } + + /// Wrapper around pay_one_collator_reward which handles the following logic: + /// * whether or not a payout needs to be made + /// * cleaning up when payouts are done + /// * returns the weight consumed by pay_one_collator_reward if applicable + fn handle_delayed_payouts(now: RoundIndex) -> Weight { + let delay = T::RewardPaymentDelay::get(); + + // don't underflow uint + if now < delay { + return 0u64.into(); + } + + let paid_for_round = now - delay; + + if let Some(payout_info) = >::get(paid_for_round) { + let result = Self::pay_one_collator_reward(paid_for_round, payout_info); + if result.0.is_none() { + // result.0 indicates whether or not a payout was made + // clean up storage items that we no longer need + >::remove(paid_for_round); + >::remove(paid_for_round); + } + result.1 // weight consumed by pay_one_collator_reward + } else { + 0u64.into() + } + } + + /// Payout a single collator from the given round. + /// + /// Returns an optional tuple of (Collator's AccountId, total paid) + /// or None if there were no more payouts to be made for the round. + pub(crate) fn pay_one_collator_reward( + paid_for_round: RoundIndex, + payout_info: DelayedPayout>, + ) -> (Option<(T::AccountId, BalanceOf)>, Weight) { + // TODO: it would probably be optimal to roll Points into the DelayedPayouts storage + // item so that we do fewer reads each block + let total_points = >::get(paid_for_round); + if total_points.is_zero() { + // TODO: this case is obnoxious... it's a value query, so it could mean one of two + // different logic errors: + // 1. we removed it before we should have + // 2. we called pay_one_collator_reward when we were actually done with deferred + // payouts + log::warn!("pay_one_collator_reward called with no > for the round!"); + return (None, 0u64.into()); + } + + let mint = |amt: BalanceOf, to: T::AccountId| { + if let Ok(amount_transferred) = T::Currency::deposit_into_existing(&to, amt) { + Self::deposit_event(Event::Rewarded(to.clone(), amount_transferred.peek())); + } + }; + + let collator_fee = payout_info.collator_commission; + let collator_issuance = collator_fee * payout_info.round_issuance; + + if let Some((collator, pts)) = + >::iter_prefix(paid_for_round).drain().next() + { + let pct_due = Perbill::from_rational(pts, total_points); + let total_paid = pct_due * payout_info.total_staking_reward; + let mut amt_due = total_paid; + // Take the snapshot of block author and delegations + let state = >::take(paid_for_round, &collator); + let num_delegators = state.delegations.len(); + if state.delegations.is_empty() { + // solo collator with no delegators + mint(amt_due, collator.clone()); + } else { + // pay collator first; commission + due_portion + let collator_pct = Perbill::from_rational(state.bond, state.total); + let commission = pct_due * collator_issuance; + amt_due -= commission; + let collator_reward = (collator_pct * amt_due) + commission; + mint(collator_reward, collator.clone()); + // pay delegators due portion + for Bond { owner, amount } in state.delegations { + let percent = Perbill::from_rational(amount, state.total); + let due = percent * amt_due; + mint(due, owner.clone()); + } + } + + ( + Some((collator, total_paid)), + T::WeightInfo::pay_one_collator_reward(num_delegators as u32), + ) + } else { + // Note that we don't clean up storage here; it is cleaned up in + // handle_delayed_payouts() + (None, 0u64.into()) + } + } + + /// Compute the top `TotalSelected` candidates in the CandidatePool and return + /// a vec of their AccountIds (in the order of selection) + pub fn compute_top_candidates() -> Vec { + let mut candidates = >::get().0; + // order candidates by stake (least to greatest so requires `rev()`) + candidates.sort_by(|a, b| a.amount.partial_cmp(&b.amount).unwrap()); + let top_n = >::get() as usize; + // choose the top TotalSelected qualified candidates, ordered by stake + let mut collators = candidates + .into_iter() + .rev() + .take(top_n) + .filter(|x| x.amount >= T::MinCollatorStk::get()) + .map(|x| x.owner) + .collect::>(); + collators.sort(); + collators + } + /// Best as in most cumulatively supported in terms of stake + /// Returns [collator_count, delegation_count, total staked] + fn select_top_candidates(now: RoundIndex) -> (u32, u32, BalanceOf) { + let (mut collator_count, mut delegation_count, mut total) = + (0u32, 0u32, BalanceOf::::zero()); + // choose the top TotalSelected qualified candidates, ordered by stake + let collators = Self::compute_top_candidates(); + // snapshot exposure for round for weighting reward distribution + for account in collators.iter() { + let state = >::get(account) + .expect("all members of CandidateQ must be candidates"); + let top_delegations = >::get(account) + .expect("all members of CandidateQ must be candidates"); + collator_count += 1u32; + delegation_count += state.delegation_count; + total += state.total_counted; + let snapshot_total = state.total_counted; + let snapshot = CollatorSnapshot { + bond: state.bond, + delegations: top_delegations.delegations, + total: state.total_counted, + }; + >::insert(now, account, snapshot); + Self::deposit_event(Event::CollatorChosen(now, account.clone(), snapshot_total)); + } + // insert canonical collator set + >::put(collators); + (collator_count, delegation_count, total) + } + } + + /// Add reward points to block authors: + /// * 20 points to the block producer for producing a block in the chain + impl nimbus_primitives::EventHandler for Pallet { + fn note_author(author: T::AccountId) { + let now = >::get().current; + let score_plus_20 = >::get(now, &author) + 20; + >::insert(now, author, score_plus_20); + >::mutate(now, |x| *x += 20); + } + } + + impl nimbus_primitives::CanAuthor for Pallet { + fn can_author(account: &T::AccountId, _slot: &u32) -> bool { + Self::is_selected_candidate(account) + } + } + + impl Get> for Pallet { + fn get() -> Vec { + Self::selected_candidates() + } + } } diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index 5c1b2a54..17e731e5 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -18,16 +18,16 @@ use crate as parachain_staking; use crate::{pallet, AwardedPts, Config, InflationInfo, Points, Range}; use frame_support::{ - construct_runtime, parameter_types, - traits::{Everything, GenesisBuild, OnFinalize, OnInitialize}, - weights::Weight, + construct_runtime, parameter_types, + traits::{Everything, GenesisBuild, OnFinalize, OnInitialize}, + weights::Weight, }; use sp_core::H256; use sp_io; use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, - Perbill, Percent, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + Perbill, Percent, }; pub type AccountId = u64; @@ -39,272 +39,272 @@ type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParachainStaking: parachain_staking::{Pallet, Call, Storage, Config, Event}, - } + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParachainStaking: parachain_staking::{Pallet, Call, Storage, Config, Event}, + } ); parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const SS58Prefix: u8 = 42; + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const SS58Prefix: u8 = 42; } impl frame_system::Config for Test { - type BaseCallFilter = Everything; - type DbWeight = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = BlockNumber; - type Call = Call; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type BlockHashCount = BlockHashCount; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type BlockWeights = (); - type BlockLength = (); - type SS58Prefix = SS58Prefix; - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; + type BaseCallFilter = Everything; + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type BlockWeights = (); + type BlockLength = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { - pub const ExistentialDeposit: u128 = 1; + pub const ExistentialDeposit: u128 = 1; } impl pallet_balances::Config for Test { - type MaxReserves = (); - type ReserveIdentifier = [u8; 4]; - type MaxLocks = (); - type Balance = Balance; - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); } parameter_types! { - pub const MinBlocksPerRound: u32 = 3; - pub const DefaultBlocksPerRound: u32 = 5; - pub const LeaveCandidatesDelay: u32 = 2; - pub const CandidateBondLessDelay: u32 = 2; - pub const LeaveDelegatorsDelay: u32 = 2; - pub const RevokeDelegationDelay: u32 = 2; - pub const DelegationBondLessDelay: u32 = 2; - pub const RewardPaymentDelay: u32 = 2; - pub const MinSelectedCandidates: u32 = 5; - pub const MaxTopDelegationsPerCandidate: u32 = 4; - pub const MaxBottomDelegationsPerCandidate: u32 = 4; - pub const MaxDelegationsPerDelegator: u32 = 4; - pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(20); - pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30); - pub const MinCollatorStk: u128 = 10; - pub const MinDelegatorStk: u128 = 5; - pub const MinDelegation: u128 = 3; + pub const MinBlocksPerRound: u32 = 3; + pub const DefaultBlocksPerRound: u32 = 5; + pub const LeaveCandidatesDelay: u32 = 2; + pub const CandidateBondLessDelay: u32 = 2; + pub const LeaveDelegatorsDelay: u32 = 2; + pub const RevokeDelegationDelay: u32 = 2; + pub const DelegationBondLessDelay: u32 = 2; + pub const RewardPaymentDelay: u32 = 2; + pub const MinSelectedCandidates: u32 = 5; + pub const MaxTopDelegationsPerCandidate: u32 = 4; + pub const MaxBottomDelegationsPerCandidate: u32 = 4; + pub const MaxDelegationsPerDelegator: u32 = 4; + pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(20); + pub const DefaultParachainBondReservePercent: Percent = Percent::from_percent(30); + pub const MinCollatorStk: u128 = 10; + pub const MinDelegatorStk: u128 = 5; + pub const MinDelegation: u128 = 3; } impl Config for Test { - type Event = Event; - type Currency = Balances; - type MonetaryGovernanceOrigin = frame_system::EnsureRoot; - type MinBlocksPerRound = MinBlocksPerRound; - type DefaultBlocksPerRound = DefaultBlocksPerRound; - type LeaveCandidatesDelay = LeaveCandidatesDelay; - type CandidateBondLessDelay = CandidateBondLessDelay; - type LeaveDelegatorsDelay = LeaveDelegatorsDelay; - type RevokeDelegationDelay = RevokeDelegationDelay; - type DelegationBondLessDelay = DelegationBondLessDelay; - type RewardPaymentDelay = RewardPaymentDelay; - type MinSelectedCandidates = MinSelectedCandidates; - type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; - type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; - type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; - type DefaultCollatorCommission = DefaultCollatorCommission; - type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; - type MinCollatorStk = MinCollatorStk; - type MinCandidateStk = MinCollatorStk; - type MinDelegatorStk = MinDelegatorStk; - type MinDelegation = MinDelegation; - type WeightInfo = (); + type Event = Event; + type Currency = Balances; + type MonetaryGovernanceOrigin = frame_system::EnsureRoot; + type MinBlocksPerRound = MinBlocksPerRound; + type DefaultBlocksPerRound = DefaultBlocksPerRound; + type LeaveCandidatesDelay = LeaveCandidatesDelay; + type CandidateBondLessDelay = CandidateBondLessDelay; + type LeaveDelegatorsDelay = LeaveDelegatorsDelay; + type RevokeDelegationDelay = RevokeDelegationDelay; + type DelegationBondLessDelay = DelegationBondLessDelay; + type RewardPaymentDelay = RewardPaymentDelay; + type MinSelectedCandidates = MinSelectedCandidates; + type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; + type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; + type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; + type DefaultCollatorCommission = DefaultCollatorCommission; + type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; + type MinCollatorStk = MinCollatorStk; + type MinCandidateStk = MinCollatorStk; + type MinDelegatorStk = MinDelegatorStk; + type MinDelegation = MinDelegation; + type WeightInfo = (); } pub(crate) struct ExtBuilder { - // endowed accounts with balances - balances: Vec<(AccountId, Balance)>, - // [collator, amount] - collators: Vec<(AccountId, Balance)>, - // [delegator, collator, delegation_amount] - delegations: Vec<(AccountId, AccountId, Balance)>, - // inflation config - inflation: InflationInfo, + // endowed accounts with balances + balances: Vec<(AccountId, Balance)>, + // [collator, amount] + collators: Vec<(AccountId, Balance)>, + // [delegator, collator, delegation_amount] + delegations: Vec<(AccountId, AccountId, Balance)>, + // inflation config + inflation: InflationInfo, } impl Default for ExtBuilder { - fn default() -> ExtBuilder { - ExtBuilder { - balances: vec![], - delegations: vec![], - collators: vec![], - inflation: InflationInfo { - expect: Range { - min: 700, - ideal: 700, - max: 700, - }, - // not used - annual: Range { - min: Perbill::from_percent(50), - ideal: Perbill::from_percent(50), - max: Perbill::from_percent(50), - }, - // unrealistically high parameterization, only for testing - round: Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5), - }, - }, - } - } + fn default() -> ExtBuilder { + ExtBuilder { + balances: vec![], + delegations: vec![], + collators: vec![], + inflation: InflationInfo { + expect: Range { + min: 700, + ideal: 700, + max: 700, + }, + // not used + annual: Range { + min: Perbill::from_percent(50), + ideal: Perbill::from_percent(50), + max: Perbill::from_percent(50), + }, + // unrealistically high parameterization, only for testing + round: Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5), + }, + }, + } + } } impl ExtBuilder { - pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self { - self.balances = balances; - self - } - - pub(crate) fn with_candidates(mut self, collators: Vec<(AccountId, Balance)>) -> Self { - self.collators = collators; - self - } - - pub(crate) fn with_delegations( - mut self, - delegations: Vec<(AccountId, AccountId, Balance)>, - ) -> Self { - self.delegations = delegations; - self - } - - #[allow(dead_code)] - pub(crate) fn with_inflation(mut self, inflation: InflationInfo) -> Self { - self.inflation = inflation; - self - } - - pub(crate) fn build(self) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .expect("Frame system builds valid default genesis config"); - - pallet_balances::GenesisConfig:: { - balances: self.balances, - } - .assimilate_storage(&mut t) - .expect("Pallet balances storage can be assimilated"); - parachain_staking::GenesisConfig:: { - candidates: self.collators, - delegations: self.delegations, - inflation_config: self.inflation, - } - .assimilate_storage(&mut t) - .expect("Parachain Staking's storage can be assimilated"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } + pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self { + self.balances = balances; + self + } + + pub(crate) fn with_candidates(mut self, collators: Vec<(AccountId, Balance)>) -> Self { + self.collators = collators; + self + } + + pub(crate) fn with_delegations( + mut self, + delegations: Vec<(AccountId, AccountId, Balance)>, + ) -> Self { + self.delegations = delegations; + self + } + + #[allow(dead_code)] + pub(crate) fn with_inflation(mut self, inflation: InflationInfo) -> Self { + self.inflation = inflation; + self + } + + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: self.balances, + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + parachain_staking::GenesisConfig:: { + candidates: self.collators, + delegations: self.delegations, + inflation_config: self.inflation, + } + .assimilate_storage(&mut t) + .expect("Parachain Staking's storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } } /// Rolls forward one block. Returns the new block number. pub(crate) fn roll_one_block() -> u64 { - ParachainStaking::on_finalize(System::block_number()); - Balances::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()); - Balances::on_initialize(System::block_number()); - ParachainStaking::on_initialize(System::block_number()); - System::block_number() + ParachainStaking::on_finalize(System::block_number()); + Balances::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()); + Balances::on_initialize(System::block_number()); + ParachainStaking::on_initialize(System::block_number()); + System::block_number() } /// Rolls to the desired block. Returns the number of blocks played. pub(crate) fn roll_to(n: u64) -> u64 { - let mut num_blocks = 0; - let mut block = System::block_number(); - while block < n { - block = roll_one_block(); - num_blocks += 1; - } - num_blocks + let mut num_blocks = 0; + let mut block = System::block_number(); + while block < n { + block = roll_one_block(); + num_blocks += 1; + } + num_blocks } /// Rolls block-by-block to the beginning of the specified round. /// This will complete the block in which the round change occurs. /// Returns the number of blocks played. pub(crate) fn roll_to_round_begin(round: u64) -> u64 { - let block = (round - 1) * DefaultBlocksPerRound::get() as u64; - roll_to(block) + let block = (round - 1) * DefaultBlocksPerRound::get() as u64; + roll_to(block) } /// Rolls block-by-block to the end of the specified round. /// The block following will be the one in which the specified round change occurs. pub(crate) fn roll_to_round_end(round: u64) -> u64 { - let block = round * DefaultBlocksPerRound::get() as u64 - 1; - roll_to(block) + let block = round * DefaultBlocksPerRound::get() as u64 - 1; + roll_to(block) } pub(crate) fn last_event() -> Event { - System::events().pop().expect("Event expected").event + System::events().pop().expect("Event expected").event } pub(crate) fn events() -> Vec> { - System::events() - .into_iter() - .map(|r| r.event) - .filter_map(|e| { - if let Event::ParachainStaking(inner) = e { - Some(inner) - } else { - None - } - }) - .collect::>() + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + if let Event::ParachainStaking(inner) = e { + Some(inner) + } else { + None + } + }) + .collect::>() } /// Assert input equal to the last event emitted #[macro_export] macro_rules! assert_last_event { - ($event:expr) => { - match &$event { - e => assert_eq!(*e, crate::mock::last_event()), - } - }; + ($event:expr) => { + match &$event { + e => assert_eq!(*e, crate::mock::last_event()), + } + }; } /// Compares the system events with passed in events /// Prints highlighted diff iff assert_eq fails #[macro_export] macro_rules! assert_eq_events { - ($events:expr) => { - match &$events { - e => similar_asserts::assert_eq!(*e, crate::mock::events()), - } - }; + ($events:expr) => { + match &$events { + e => similar_asserts::assert_eq!(*e, crate::mock::events()), + } + }; } /// Compares the last N system events with passed in events, where N is the length of events passed @@ -325,228 +325,228 @@ macro_rules! assert_eq_events { /// Note that events are filtered to only match parachain-staking (see events()). #[macro_export] macro_rules! assert_eq_last_events { - ($events:expr) => { - assert_tail_eq!($events, crate::mock::events()); - }; + ($events:expr) => { + assert_tail_eq!($events, crate::mock::events()); + }; } /// Assert that one array is equal to the tail of the other. A more generic and testable version of /// assert_eq_last_events. #[macro_export] macro_rules! assert_tail_eq { - ($tail:expr, $arr:expr) => { - if $tail.len() != 0 { - // 0-length always passes - - if $tail.len() > $arr.len() { - similar_asserts::assert_eq!($tail, $arr); // will fail - } - - let len_diff = $arr.len() - $tail.len(); - similar_asserts::assert_eq!($tail, $arr[len_diff..]); - } - }; + ($tail:expr, $arr:expr) => { + if $tail.len() != 0 { + // 0-length always passes + + if $tail.len() > $arr.len() { + similar_asserts::assert_eq!($tail, $arr); // will fail + } + + let len_diff = $arr.len() - $tail.len(); + similar_asserts::assert_eq!($tail, $arr[len_diff..]); + } + }; } /// Panics if an event is not found in the system log of events #[macro_export] macro_rules! assert_event_emitted { - ($event:expr) => { - match &$event { - e => { - assert!( - crate::mock::events().iter().find(|x| *x == e).is_some(), - "Event {:?} was not found in events: \n {:?}", - e, - crate::mock::events() - ); - } - } - }; + ($event:expr) => { + match &$event { + e => { + assert!( + crate::mock::events().iter().find(|x| *x == e).is_some(), + "Event {:?} was not found in events: \n {:?}", + e, + crate::mock::events() + ); + } + } + }; } /// Panics if an event is found in the system log of events #[macro_export] macro_rules! assert_event_not_emitted { - ($event:expr) => { - match &$event { - e => { - assert!( - crate::mock::events().iter().find(|x| *x == e).is_none(), - "Event {:?} was found in events: \n {:?}", - e, - crate::mock::events() - ); - } - } - }; + ($event:expr) => { + match &$event { + e => { + assert!( + crate::mock::events().iter().find(|x| *x == e).is_none(), + "Event {:?} was found in events: \n {:?}", + e, + crate::mock::events() + ); + } + } + }; } // Same storage changes as EventHandler::note_author impl pub(crate) fn set_author(round: u32, acc: u64, pts: u32) { - >::mutate(round, |p| *p += pts); - >::mutate(round, acc, |p| *p += pts); + >::mutate(round, |p| *p += pts); + >::mutate(round, acc, |p| *p += pts); } #[test] fn geneses() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 300), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 9), - (9, 4), - ]) - .with_candidates(vec![(1, 500), (2, 200)]) - .with_delegations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) - .build() - .execute_with(|| { - assert!(System::events().is_empty()); - // collators - assert_eq!(Balances::reserved_balance(&1), 500); - assert_eq!(Balances::free_balance(&1), 500); - assert!(ParachainStaking::is_candidate(&1)); - assert_eq!(Balances::reserved_balance(&2), 200); - assert_eq!(Balances::free_balance(&2), 100); - assert!(ParachainStaking::is_candidate(&2)); - // delegators - for x in 3..7 { - assert!(ParachainStaking::is_delegator(&x)); - assert_eq!(Balances::free_balance(&x), 0); - assert_eq!(Balances::reserved_balance(&x), 100); - } - // uninvolved - for x in 7..10 { - assert!(!ParachainStaking::is_delegator(&x)); - } - assert_eq!(Balances::free_balance(&7), 100); - assert_eq!(Balances::reserved_balance(&7), 0); - assert_eq!(Balances::free_balance(&8), 9); - assert_eq!(Balances::reserved_balance(&8), 0); - assert_eq!(Balances::free_balance(&9), 4); - assert_eq!(Balances::reserved_balance(&9), 0); - }); - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_delegations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - assert!(System::events().is_empty()); - // collators - for x in 1..5 { - assert!(ParachainStaking::is_candidate(&x)); - assert_eq!(Balances::free_balance(&x), 80); - assert_eq!(Balances::reserved_balance(&x), 20); - } - assert!(ParachainStaking::is_candidate(&5)); - assert_eq!(Balances::free_balance(&5), 90); - assert_eq!(Balances::reserved_balance(&5), 10); - // delegators - for x in 6..11 { - assert!(ParachainStaking::is_delegator(&x)); - assert_eq!(Balances::free_balance(&x), 90); - assert_eq!(Balances::reserved_balance(&x), 10); - } - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 300), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 9), + (9, 4), + ]) + .with_candidates(vec![(1, 500), (2, 200)]) + .with_delegations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) + .build() + .execute_with(|| { + assert!(System::events().is_empty()); + // collators + assert_eq!(Balances::reserved_balance(&1), 500); + assert_eq!(Balances::free_balance(&1), 500); + assert!(ParachainStaking::is_candidate(&1)); + assert_eq!(Balances::reserved_balance(&2), 200); + assert_eq!(Balances::free_balance(&2), 100); + assert!(ParachainStaking::is_candidate(&2)); + // delegators + for x in 3..7 { + assert!(ParachainStaking::is_delegator(&x)); + assert_eq!(Balances::free_balance(&x), 0); + assert_eq!(Balances::reserved_balance(&x), 100); + } + // uninvolved + for x in 7..10 { + assert!(!ParachainStaking::is_delegator(&x)); + } + assert_eq!(Balances::free_balance(&7), 100); + assert_eq!(Balances::reserved_balance(&7), 0); + assert_eq!(Balances::free_balance(&8), 9); + assert_eq!(Balances::reserved_balance(&8), 0); + assert_eq!(Balances::free_balance(&9), 4); + assert_eq!(Balances::reserved_balance(&9), 0); + }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + assert!(System::events().is_empty()); + // collators + for x in 1..5 { + assert!(ParachainStaking::is_candidate(&x)); + assert_eq!(Balances::free_balance(&x), 80); + assert_eq!(Balances::reserved_balance(&x), 20); + } + assert!(ParachainStaking::is_candidate(&5)); + assert_eq!(Balances::free_balance(&5), 90); + assert_eq!(Balances::reserved_balance(&5), 10); + // delegators + for x in 6..11 { + assert!(ParachainStaking::is_delegator(&x)); + assert_eq!(Balances::free_balance(&x), 90); + assert_eq!(Balances::reserved_balance(&x), 10); + } + }); } #[test] fn roll_to_round_begin_works() { - ExtBuilder::default().build().execute_with(|| { - // these tests assume blocks-per-round of 5, as established by DefaultBlocksPerRound - assert_eq!(System::block_number(), 1); // we start on block 1 - - let num_blocks = roll_to_round_begin(1); - assert_eq!(System::block_number(), 1); // no-op, we're already on this round - assert_eq!(num_blocks, 0); - - let num_blocks = roll_to_round_begin(2); - assert_eq!(System::block_number(), 5); - assert_eq!(num_blocks, 4); - - let num_blocks = roll_to_round_begin(3); - assert_eq!(System::block_number(), 10); - assert_eq!(num_blocks, 5); - }); + ExtBuilder::default().build().execute_with(|| { + // these tests assume blocks-per-round of 5, as established by DefaultBlocksPerRound + assert_eq!(System::block_number(), 1); // we start on block 1 + + let num_blocks = roll_to_round_begin(1); + assert_eq!(System::block_number(), 1); // no-op, we're already on this round + assert_eq!(num_blocks, 0); + + let num_blocks = roll_to_round_begin(2); + assert_eq!(System::block_number(), 5); + assert_eq!(num_blocks, 4); + + let num_blocks = roll_to_round_begin(3); + assert_eq!(System::block_number(), 10); + assert_eq!(num_blocks, 5); + }); } #[test] fn roll_to_round_end_works() { - ExtBuilder::default().build().execute_with(|| { - // these tests assume blocks-per-round of 5, as established by DefaultBlocksPerRound - assert_eq!(System::block_number(), 1); // we start on block 1 - - let num_blocks = roll_to_round_end(1); - assert_eq!(System::block_number(), 4); - assert_eq!(num_blocks, 3); - - let num_blocks = roll_to_round_end(2); - assert_eq!(System::block_number(), 9); - assert_eq!(num_blocks, 5); - - let num_blocks = roll_to_round_end(3); - assert_eq!(System::block_number(), 14); - assert_eq!(num_blocks, 5); - }); + ExtBuilder::default().build().execute_with(|| { + // these tests assume blocks-per-round of 5, as established by DefaultBlocksPerRound + assert_eq!(System::block_number(), 1); // we start on block 1 + + let num_blocks = roll_to_round_end(1); + assert_eq!(System::block_number(), 4); + assert_eq!(num_blocks, 3); + + let num_blocks = roll_to_round_end(2); + assert_eq!(System::block_number(), 9); + assert_eq!(num_blocks, 5); + + let num_blocks = roll_to_round_end(3); + assert_eq!(System::block_number(), 14); + assert_eq!(num_blocks, 5); + }); } #[test] fn assert_tail_eq_works() { - assert_tail_eq!(vec![1, 2], vec![0, 1, 2]); + assert_tail_eq!(vec![1, 2], vec![0, 1, 2]); - assert_tail_eq!(vec![1], vec![1]); + assert_tail_eq!(vec![1], vec![1]); - assert_tail_eq!( - vec![0u32; 0], // 0 length array - vec![0u32; 1] // 1-length array - ); + assert_tail_eq!( + vec![0u32; 0], // 0 length array + vec![0u32; 1] // 1-length array + ); - assert_tail_eq!(vec![0u32, 0], vec![0u32, 0]); + assert_tail_eq!(vec![0u32, 0], vec![0u32, 0]); } #[test] #[should_panic] fn assert_tail_eq_panics_on_non_equal_tail() { - assert_tail_eq!(vec![2, 2], vec![0, 1, 2]); + assert_tail_eq!(vec![2, 2], vec![0, 1, 2]); } #[test] #[should_panic] fn assert_tail_eq_panics_on_empty_arr() { - assert_tail_eq!(vec![2, 2], vec![0u32; 0]); + assert_tail_eq!(vec![2, 2], vec![0u32; 0]); } #[test] #[should_panic] fn assert_tail_eq_panics_on_longer_tail() { - assert_tail_eq!(vec![1, 2, 3], vec![1, 2]); + assert_tail_eq!(vec![1, 2, 3], vec![1, 2]); } #[test] #[should_panic] fn assert_tail_eq_panics_on_unequal_elements_same_length_array() { - assert_tail_eq!(vec![1, 2, 3], vec![0, 1, 2]); + assert_tail_eq!(vec![1, 2, 3], vec![0, 1, 2]); } diff --git a/pallets/parachain-staking/src/set.rs b/pallets/parachain-staking/src/set.rs index 8e4e2964..d4775eba 100644 --- a/pallets/parachain-staking/src/set.rs +++ b/pallets/parachain-staking/src/set.rs @@ -28,62 +28,62 @@ use sp_std::prelude::*; pub struct OrderedSet(pub Vec); impl OrderedSet { - /// Create a new empty set - pub fn new() -> Self { - Self(Vec::new()) - } + /// Create a new empty set + pub fn new() -> Self { + Self(Vec::new()) + } - /// Create a set from a `Vec`. - /// `v` will be sorted and dedup first. - pub fn from(mut v: Vec) -> Self { - v.sort(); - v.dedup(); - Self::from_sorted_set(v) - } + /// Create a set from a `Vec`. + /// `v` will be sorted and dedup first. + pub fn from(mut v: Vec) -> Self { + v.sort(); + v.dedup(); + Self::from_sorted_set(v) + } - /// Create a set from a `Vec`. - /// Assume `v` is sorted and contain unique elements. - pub fn from_sorted_set(v: Vec) -> Self { - Self(v) - } + /// Create a set from a `Vec`. + /// Assume `v` is sorted and contain unique elements. + pub fn from_sorted_set(v: Vec) -> Self { + Self(v) + } - /// Insert an element. - /// Return true if insertion happened. - pub fn insert(&mut self, value: T) -> bool { - match self.0.binary_search(&value) { - Ok(_) => false, - Err(loc) => { - self.0.insert(loc, value); - true - } - } - } + /// Insert an element. + /// Return true if insertion happened. + pub fn insert(&mut self, value: T) -> bool { + match self.0.binary_search(&value) { + Ok(_) => false, + Err(loc) => { + self.0.insert(loc, value); + true + } + } + } - /// Remove an element. - /// Return true if removal happened. - pub fn remove(&mut self, value: &T) -> bool { - match self.0.binary_search(value) { - Ok(loc) => { - self.0.remove(loc); - true - } - Err(_) => false, - } - } + /// Remove an element. + /// Return true if removal happened. + pub fn remove(&mut self, value: &T) -> bool { + match self.0.binary_search(value) { + Ok(loc) => { + self.0.remove(loc); + true + } + Err(_) => false, + } + } - /// Return if the set contains `value` - pub fn contains(&self, value: &T) -> bool { - self.0.binary_search(value).is_ok() - } + /// Return if the set contains `value` + pub fn contains(&self, value: &T) -> bool { + self.0.binary_search(value).is_ok() + } - /// Clear the set - pub fn clear(&mut self) { - self.0.clear(); - } + /// Clear the set + pub fn clear(&mut self) { + self.0.clear(); + } } impl From> for OrderedSet { - fn from(v: Vec) -> Self { - Self::from(v) - } + fn from(v: Vec) -> Self { + Self::from(v) + } } diff --git a/pallets/parachain-staking/src/tests.rs b/pallets/parachain-staking/src/tests.rs index a67fefbc..1866d718 100644 --- a/pallets/parachain-staking/src/tests.rs +++ b/pallets/parachain-staking/src/tests.rs @@ -22,16 +22,16 @@ //! 3. Public (Collator, Nominator) //! 4. Miscellaneous Property-Based Tests use crate::mock::{ - roll_one_block, roll_to, roll_to_round_begin, roll_to_round_end, set_author, Balances, - Event as MetaEvent, ExtBuilder, Origin, ParachainStaking, Test, + roll_one_block, roll_to, roll_to_round_begin, roll_to_round_end, set_author, Balances, + Event as MetaEvent, ExtBuilder, Origin, ParachainStaking, Test, }; use crate::{ - assert_eq_events, assert_eq_last_events, assert_event_emitted, assert_event_not_emitted, - assert_last_event, assert_tail_eq, pallet::CapacityStatus, set::OrderedSet, BalanceOf, Bond, - BottomDelegations, CandidateInfo, CandidatePool, CandidateState, CollatorCandidate, - CollatorStatus, Config, DelegationChange, DelegationRequest, Delegator, DelegatorAdded, - DelegatorState, DelegatorStatus, Error, Event, PendingDelegationRequests, Range, - TopDelegations, Total, + assert_eq_events, assert_eq_last_events, assert_event_emitted, assert_event_not_emitted, + assert_last_event, assert_tail_eq, pallet::CapacityStatus, set::OrderedSet, BalanceOf, Bond, + BottomDelegations, CandidateInfo, CandidatePool, CandidateState, CollatorCandidate, + CollatorStatus, Config, DelegationChange, DelegationRequest, Delegator, DelegatorAdded, + DelegatorState, DelegatorStatus, Error, Event, PendingDelegationRequests, Range, + TopDelegations, Total, }; use frame_support::{assert_noop, assert_ok, traits::ReservableCurrency}; use sp_runtime::{traits::Zero, DispatchError, Perbill, Percent}; @@ -41,576 +41,579 @@ use sp_std::collections::btree_map::BTreeMap; #[test] fn invalid_root_origin_fails() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_total_selected(Origin::signed(45), 6u32), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - ParachainStaking::set_collator_commission(Origin::signed(45), Perbill::from_percent(5)), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - ParachainStaking::set_blocks_per_round(Origin::signed(45), 3u32), - sp_runtime::DispatchError::BadOrigin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_total_selected(Origin::signed(45), 6u32), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_collator_commission( + Origin::signed(45), + Perbill::from_percent(5) + ), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::signed(45), 3u32), + sp_runtime::DispatchError::BadOrigin + ); + }); } // SET TOTAL SELECTED #[test] fn set_total_selected_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - // before we can bump total_selected we must bump the blocks per round - assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); - assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 6u32)); - assert_last_event!(MetaEvent::ParachainStaking(Event::TotalSelectedSet( - 5u32, 6u32 - ))); - }); + ExtBuilder::default().build().execute_with(|| { + // before we can bump total_selected we must bump the blocks per round + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 6u32)); + assert_last_event!(MetaEvent::ParachainStaking(Event::TotalSelectedSet( + 5u32, 6u32 + ))); + }); } #[test] fn set_total_selected_fails_if_above_blocks_per_round() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::round().length, 5); // test relies on this - assert_noop!( - ParachainStaking::set_total_selected(Origin::root(), 6u32), - Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::round().length, 5); // test relies on this + assert_noop!( + ParachainStaking::set_total_selected(Origin::root(), 6u32), + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + }); } #[test] fn set_total_selected_passes_if_equal_to_blocks_per_round() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_blocks_per_round( - Origin::root(), - 10u32 - )); - assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 10u32)); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 10u32)); + }); } #[test] fn set_total_selected_passes_if_below_blocks_per_round() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_blocks_per_round( - Origin::root(), - 10u32 - )); - assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 9u32)); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 9u32)); + }); } #[test] fn set_blocks_per_round_fails_if_below_total_selected() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_blocks_per_round( - Origin::root(), - 20u32 - )); - assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 15u32)); - assert_noop!( - ParachainStaking::set_blocks_per_round(Origin::root(), 14u32), - Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 20u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 15u32)); + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::root(), 14u32), + Error::::RoundLengthMustBeAtLeastTotalSelectedCollators, + ); + }); } #[test] fn set_blocks_per_round_passes_if_equal_to_total_selected() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_blocks_per_round( - Origin::root(), - 10u32 - )); - assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 9u32)); - assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 9u32)); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 9u32)); + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 9u32)); + }); } #[test] fn set_blocks_per_round_passes_if_above_total_selected() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::round().length, 5); // test relies on this - assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::round().length, 5); // test relies on this + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + }); } #[test] fn set_total_selected_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - // round length must be >= total_selected, so update that first - assert_ok!(ParachainStaking::set_blocks_per_round( - Origin::root(), - 10u32 - )); + ExtBuilder::default().build().execute_with(|| { + // round length must be >= total_selected, so update that first + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); - assert_eq!(ParachainStaking::total_selected(), 5u32); - assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 6u32)); - assert_eq!(ParachainStaking::total_selected(), 6u32); - }); + assert_eq!(ParachainStaking::total_selected(), 5u32); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 6u32)); + assert_eq!(ParachainStaking::total_selected(), 6u32); + }); } #[test] fn cannot_set_total_selected_to_current_total_selected() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_total_selected(Origin::root(), 5u32), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_total_selected(Origin::root(), 5u32), + Error::::NoWritingSameValue + ); + }); } #[test] fn cannot_set_total_selected_below_module_min() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_total_selected(Origin::root(), 4u32), - Error::::CannotSetBelowMin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_total_selected(Origin::root(), 4u32), + Error::::CannotSetBelowMin + ); + }); } // SET COLLATOR COMMISSION #[test] fn set_collator_commission_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_collator_commission( - Origin::root(), - Perbill::from_percent(5) - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::CollatorCommissionSet( - Perbill::from_percent(20), - Perbill::from_percent(5), - ))); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_collator_commission( + Origin::root(), + Perbill::from_percent(5) + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CollatorCommissionSet( + Perbill::from_percent(20), + Perbill::from_percent(5), + ))); + }); } #[test] fn set_collator_commission_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - ParachainStaking::collator_commission(), - Perbill::from_percent(20) - ); - assert_ok!(ParachainStaking::set_collator_commission( - Origin::root(), - Perbill::from_percent(5) - )); - assert_eq!( - ParachainStaking::collator_commission(), - Perbill::from_percent(5) - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + ParachainStaking::collator_commission(), + Perbill::from_percent(20) + ); + assert_ok!(ParachainStaking::set_collator_commission( + Origin::root(), + Perbill::from_percent(5) + )); + assert_eq!( + ParachainStaking::collator_commission(), + Perbill::from_percent(5) + ); + }); } #[test] fn cannot_set_collator_commission_to_current_collator_commission() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_collator_commission(Origin::root(), Perbill::from_percent(20)), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_collator_commission(Origin::root(), Perbill::from_percent(20)), + Error::::NoWritingSameValue + ); + }); } // SET BLOCKS PER ROUND #[test] fn set_blocks_per_round_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); - assert_last_event!(MetaEvent::ParachainStaking(Event::BlocksPerRoundSet( - 1, - 0, - 5, - 6, - Perbill::from_parts(926), - Perbill::from_parts(926), - Perbill::from_parts(926), - ))); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + assert_last_event!(MetaEvent::ParachainStaking(Event::BlocksPerRoundSet( + 1, + 0, + 5, + 6, + Perbill::from_parts(926), + Perbill::from_parts(926), + Perbill::from_parts(926), + ))); + }); } #[test] fn set_blocks_per_round_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::round().length, 5); - assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); - assert_eq!(ParachainStaking::round().length, 6); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::round().length, 5); + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 6u32)); + assert_eq!(ParachainStaking::round().length, 6); + }); } #[test] fn cannot_set_blocks_per_round_below_module_min() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_blocks_per_round(Origin::root(), 2u32), - Error::::CannotSetBelowMin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::root(), 2u32), + Error::::CannotSetBelowMin + ); + }); } #[test] fn cannot_set_blocks_per_round_to_current_blocks_per_round() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_blocks_per_round(Origin::root(), 5u32), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_blocks_per_round(Origin::root(), 5u32), + Error::::NoWritingSameValue + ); + }); } #[test] fn round_immediately_jumps_if_current_duration_exceeds_new_blocks_per_round() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - // we can't lower the blocks per round because it must be above the number of collators, - // and we can't lower the number of collators because it must be above - // MinSelectedCandidates. so we first raise blocks per round, then lower it. - assert_ok!(ParachainStaking::set_blocks_per_round( - Origin::root(), - 10u32 - )); - - roll_to(17); - assert_last_event!(MetaEvent::ParachainStaking(Event::NewRound(10, 2, 1, 20))); - assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 5u32)); - roll_to(18); - assert_last_event!(MetaEvent::ParachainStaking(Event::NewRound(18, 3, 1, 20))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + // we can't lower the blocks per round because it must be above the number of collators, + // and we can't lower the number of collators because it must be above + // MinSelectedCandidates. so we first raise blocks per round, then lower it. + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 10u32 + )); + + roll_to(17); + assert_last_event!(MetaEvent::ParachainStaking(Event::NewRound(10, 2, 1, 20))); + assert_ok!(ParachainStaking::set_blocks_per_round(Origin::root(), 5u32)); + roll_to(18); + assert_last_event!(MetaEvent::ParachainStaking(Event::NewRound(18, 3, 1, 20))); + }); } // ~~ MONETARY GOVERNANCE ~~ #[test] fn invalid_monetary_origin_fails() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_staking_expectations( - Origin::signed(45), - Range { - min: 3u32.into(), - ideal: 4u32.into(), - max: 5u32.into() - } - ), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - ParachainStaking::set_inflation( - Origin::signed(45), - Range { - min: Perbill::from_percent(3), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(5) - } - ), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - ParachainStaking::set_inflation( - Origin::signed(45), - Range { - min: Perbill::from_percent(3), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(5) - } - ), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - ParachainStaking::set_parachain_bond_account(Origin::signed(45), 11), - sp_runtime::DispatchError::BadOrigin - ); - assert_noop!( - ParachainStaking::set_parachain_bond_reserve_percent( - Origin::signed(45), - Percent::from_percent(2) - ), - sp_runtime::DispatchError::BadOrigin - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_staking_expectations( + Origin::signed(45), + Range { + min: 3u32.into(), + ideal: 4u32.into(), + max: 5u32.into() + } + ), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_inflation( + Origin::signed(45), + Range { + min: Perbill::from_percent(3), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(5) + } + ), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_inflation( + Origin::signed(45), + Range { + min: Perbill::from_percent(3), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(5) + } + ), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_parachain_bond_account(Origin::signed(45), 11), + sp_runtime::DispatchError::BadOrigin + ); + assert_noop!( + ParachainStaking::set_parachain_bond_reserve_percent( + Origin::signed(45), + Percent::from_percent(2) + ), + sp_runtime::DispatchError::BadOrigin + ); + }); } // SET STAKING EXPECTATIONS #[test] fn set_staking_event_emits_event_correctly() { - ExtBuilder::default().build().execute_with(|| { - // valid call succeeds - assert_ok!(ParachainStaking::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128, - } - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::StakeExpectationsSet( - 3u128, 4u128, 5u128, - ))); - }); + ExtBuilder::default().build().execute_with(|| { + // valid call succeeds + assert_ok!(ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128, + } + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::StakeExpectationsSet( + 3u128, 4u128, 5u128, + ))); + }); } #[test] fn set_staking_updates_storage_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - ParachainStaking::inflation_config().expect, - Range { - min: 700, - ideal: 700, - max: 700 - } - ); - assert_ok!(ParachainStaking::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128, - } - )); - assert_eq!( - ParachainStaking::inflation_config().expect, - Range { - min: 3u128, - ideal: 4u128, - max: 5u128 - } - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + ParachainStaking::inflation_config().expect, + Range { + min: 700, + ideal: 700, + max: 700 + } + ); + assert_ok!(ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128, + } + )); + assert_eq!( + ParachainStaking::inflation_config().expect, + Range { + min: 3u128, + ideal: 4u128, + max: 5u128 + } + ); + }); } #[test] fn cannot_set_invalid_staking_expectations() { - ExtBuilder::default().build().execute_with(|| { - // invalid call fails - assert_noop!( - ParachainStaking::set_staking_expectations( - Origin::root(), - Range { - min: 5u128, - ideal: 4u128, - max: 3u128 - } - ), - Error::::InvalidSchedule - ); - }); + ExtBuilder::default().build().execute_with(|| { + // invalid call fails + assert_noop!( + ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 5u128, + ideal: 4u128, + max: 3u128 + } + ), + Error::::InvalidSchedule + ); + }); } #[test] fn cannot_set_same_staking_expectations() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128 - } - )); - assert_noop!( - ParachainStaking::set_staking_expectations( - Origin::root(), - Range { - min: 3u128, - ideal: 4u128, - max: 5u128 - } - ), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128 + } + )); + assert_noop!( + ParachainStaking::set_staking_expectations( + Origin::root(), + Range { + min: 3u128, + ideal: 4u128, + max: 5u128 + } + ), + Error::::NoWritingSameValue + ); + }); } // SET INFLATION #[test] fn set_inflation_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - let (min, ideal, max): (Perbill, Perbill, Perbill) = ( - Perbill::from_percent(3), - Perbill::from_percent(4), - Perbill::from_percent(5), - ); - assert_ok!(ParachainStaking::set_inflation( - Origin::root(), - Range { min, ideal, max } - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::InflationSet( - min, - ideal, - max, - Perbill::from_parts(57), - Perbill::from_parts(75), - Perbill::from_parts(93), - ))); - }); + ExtBuilder::default().build().execute_with(|| { + let (min, ideal, max): (Perbill, Perbill, Perbill) = ( + Perbill::from_percent(3), + Perbill::from_percent(4), + Perbill::from_percent(5), + ); + assert_ok!(ParachainStaking::set_inflation( + Origin::root(), + Range { min, ideal, max } + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::InflationSet( + min, + ideal, + max, + Perbill::from_parts(57), + Perbill::from_parts(75), + Perbill::from_parts(93), + ))); + }); } #[test] fn set_inflation_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - let (min, ideal, max): (Perbill, Perbill, Perbill) = ( - Perbill::from_percent(3), - Perbill::from_percent(4), - Perbill::from_percent(5), - ); - assert_eq!( - ParachainStaking::inflation_config().annual, - Range { - min: Perbill::from_percent(50), - ideal: Perbill::from_percent(50), - max: Perbill::from_percent(50) - } - ); - assert_eq!( - ParachainStaking::inflation_config().round, - Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(5), - max: Perbill::from_percent(5) - } - ); - assert_ok!(ParachainStaking::set_inflation( - Origin::root(), - Range { min, ideal, max } - ),); - assert_eq!( - ParachainStaking::inflation_config().annual, - Range { min, ideal, max } - ); - assert_eq!( - ParachainStaking::inflation_config().round, - Range { - min: Perbill::from_parts(57), - ideal: Perbill::from_parts(75), - max: Perbill::from_parts(93) - } - ); - }); + ExtBuilder::default().build().execute_with(|| { + let (min, ideal, max): (Perbill, Perbill, Perbill) = ( + Perbill::from_percent(3), + Perbill::from_percent(4), + Perbill::from_percent(5), + ); + assert_eq!( + ParachainStaking::inflation_config().annual, + Range { + min: Perbill::from_percent(50), + ideal: Perbill::from_percent(50), + max: Perbill::from_percent(50) + } + ); + assert_eq!( + ParachainStaking::inflation_config().round, + Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(5), + max: Perbill::from_percent(5) + } + ); + assert_ok!(ParachainStaking::set_inflation( + Origin::root(), + Range { min, ideal, max } + ),); + assert_eq!( + ParachainStaking::inflation_config().annual, + Range { min, ideal, max } + ); + assert_eq!( + ParachainStaking::inflation_config().round, + Range { + min: Perbill::from_parts(57), + ideal: Perbill::from_parts(75), + max: Perbill::from_parts(93) + } + ); + }); } #[test] fn cannot_set_invalid_inflation() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_inflation( - Origin::root(), - Range { - min: Perbill::from_percent(5), - ideal: Perbill::from_percent(4), - max: Perbill::from_percent(3) - } - ), - Error::::InvalidSchedule - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_inflation( + Origin::root(), + Range { + min: Perbill::from_percent(5), + ideal: Perbill::from_percent(4), + max: Perbill::from_percent(3) + } + ), + Error::::InvalidSchedule + ); + }); } #[test] fn cannot_set_same_inflation() { - ExtBuilder::default().build().execute_with(|| { - let (min, ideal, max): (Perbill, Perbill, Perbill) = ( - Perbill::from_percent(3), - Perbill::from_percent(4), - Perbill::from_percent(5), - ); - assert_ok!(ParachainStaking::set_inflation( - Origin::root(), - Range { min, ideal, max } - ),); - assert_noop!( - ParachainStaking::set_inflation(Origin::root(), Range { min, ideal, max }), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + let (min, ideal, max): (Perbill, Perbill, Perbill) = ( + Perbill::from_percent(3), + Perbill::from_percent(4), + Perbill::from_percent(5), + ); + assert_ok!(ParachainStaking::set_inflation( + Origin::root(), + Range { min, ideal, max } + ),); + assert_noop!( + ParachainStaking::set_inflation(Origin::root(), Range { min, ideal, max }), + Error::::NoWritingSameValue + ); + }); } // SET PARACHAIN BOND ACCOUNT #[test] fn set_parachain_bond_account_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_parachain_bond_account( - Origin::root(), - 11 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::ParachainBondAccountSet( - 0, 11 - ))); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_parachain_bond_account( + Origin::root(), + 11 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::ParachainBondAccountSet( + 0, 11 + ))); + }); } #[test] fn set_parachain_bond_account_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(ParachainStaking::parachain_bond_info().account, 0); - assert_ok!(ParachainStaking::set_parachain_bond_account( - Origin::root(), - 11 - )); - assert_eq!(ParachainStaking::parachain_bond_info().account, 11); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!(ParachainStaking::parachain_bond_info().account, 0); + assert_ok!(ParachainStaking::set_parachain_bond_account( + Origin::root(), + 11 + )); + assert_eq!(ParachainStaking::parachain_bond_info().account, 11); + }); } // SET PARACHAIN BOND RESERVE PERCENT #[test] fn set_parachain_bond_reserve_percent_event_emits_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( - Origin::root(), - Percent::from_percent(50) - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::ParachainBondReservePercentSet( - Percent::from_percent(30), - Percent::from_percent(50), - ) - )); - }); + ExtBuilder::default().build().execute_with(|| { + assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(50) + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::ParachainBondReservePercentSet( + Percent::from_percent(30), + Percent::from_percent(50), + ) + )); + }); } #[test] fn set_parachain_bond_reserve_percent_storage_updates_correctly() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!( - ParachainStaking::parachain_bond_info().percent, - Percent::from_percent(30) - ); - assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( - Origin::root(), - Percent::from_percent(50) - )); - assert_eq!( - ParachainStaking::parachain_bond_info().percent, - Percent::from_percent(50) - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_eq!( + ParachainStaking::parachain_bond_info().percent, + Percent::from_percent(30) + ); + assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(50) + )); + assert_eq!( + ParachainStaking::parachain_bond_info().percent, + Percent::from_percent(50) + ); + }); } #[test] fn cannot_set_same_parachain_bond_reserve_percent() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::set_parachain_bond_reserve_percent( - Origin::root(), - Percent::from_percent(30) - ), - Error::::NoWritingSameValue - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(30) + ), + Error::::NoWritingSameValue + ); + }); } // ~~ PUBLIC ~~ @@ -619,2057 +622,2058 @@ fn cannot_set_same_parachain_bond_reserve_percent() { #[test] fn join_candidates_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(1), - 10u128, - 0u32 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::JoinedCollatorCandidates(1, 10u128, 10u128,) - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::JoinedCollatorCandidates(1, 10u128, 10u128,) + )); + }); } #[test] fn join_candidates_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(Balances::free_balance(&1), 10); - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(1), - 10u128, - 0u32 - )); - assert_eq!(Balances::reserved_balance(&1), 10); - assert_eq!(Balances::free_balance(&1), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(&1), 10); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + assert_eq!(Balances::reserved_balance(&1), 10); + assert_eq!(Balances::free_balance(&1), 0); + }); } #[test] fn join_candidates_increases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 0); - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(1), - 10u128, - 0u32 - )); - assert_eq!(ParachainStaking::total(), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 0); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + assert_eq!(ParachainStaking::total(), 10); + }); } #[test] fn join_candidates_creates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert!(ParachainStaking::candidate_info(1).is_none()); - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(1), - 10u128, - 0u32 - )); - let candidate_state = - ParachainStaking::candidate_info(1).expect("just joined => exists"); - assert_eq!(candidate_state.bond, 10u128); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::candidate_info(1).is_none()); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + let candidate_state = + ParachainStaking::candidate_info(1).expect("just joined => exists"); + assert_eq!(candidate_state.bond, 10u128); + }); } #[test] fn join_candidates_adds_to_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .build() - .execute_with(|| { - assert!(ParachainStaking::candidate_pool().0.is_empty()); - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(1), - 10u128, - 0u32 - )); - let candidate_pool = ParachainStaking::candidate_pool(); - assert_eq!(candidate_pool.0[0].owner, 1); - assert_eq!(candidate_pool.0[0].amount, 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(1), + 10u128, + 0u32 + )); + let candidate_pool = ParachainStaking::candidate_pool(); + assert_eq!(candidate_pool.0[0].owner, 1); + assert_eq!(candidate_pool.0[0].amount, 10); + }); } #[test] fn cannot_join_candidates_if_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 1000)]) - .with_candidates(vec![(1, 500)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::join_candidates(Origin::signed(1), 11u128, 100u32), - Error::::CandidateExists - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 1000)]) + .with_candidates(vec![(1, 500)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(1), 11u128, 100u32), + Error::::CandidateExists + ); + }); } #[test] fn cannot_join_candidates_if_delegator() { - ExtBuilder::default() - .with_balances(vec![(1, 50), (2, 20)]) - .with_candidates(vec![(1, 50)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::join_candidates(Origin::signed(2), 10u128, 1u32), - Error::::DelegatorExists - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50), (2, 20)]) + .with_candidates(vec![(1, 50)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(2), 10u128, 1u32), + Error::::DelegatorExists + ); + }); } #[test] fn cannot_join_candidates_without_min_bond() { - ExtBuilder::default() - .with_balances(vec![(1, 1000)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::join_candidates(Origin::signed(1), 9u128, 100u32), - Error::::CandidateBondBelowMin - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 1000)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(1), 9u128, 100u32), + Error::::CandidateBondBelowMin + ); + }); } #[test] fn cannot_join_candidates_with_more_than_available_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 500)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::join_candidates(Origin::signed(1), 501u128, 100u32), - DispatchError::Module { - index: 1, - error: 2, - message: Some("InsufficientBalance") - } - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 500)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(1), 501u128, 100u32), + DispatchError::Module { + index: 1, + error: 2, + message: Some("InsufficientBalance") + } + ); + }); } #[test] fn insufficient_join_candidates_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - for i in 0..5 { - assert_noop!( - ParachainStaking::join_candidates(Origin::signed(6), 20, i), - Error::::TooLowCandidateCountWeightHintJoinCandidates - ); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + for i in 0..5 { + assert_noop!( + ParachainStaking::join_candidates(Origin::signed(6), 20, i), + Error::::TooLowCandidateCountWeightHintJoinCandidates + ); + } + }); } #[test] fn sufficient_join_candidates_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (2, 20), - (3, 20), - (4, 20), - (5, 20), - (6, 20), - (7, 20), - (8, 20), - (9, 20), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - let mut count = 5u32; - for i in 6..10 { - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(i), - 20, - count - )); - count += 1u32; - } - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (2, 20), + (3, 20), + (4, 20), + (5, 20), + (6, 20), + (7, 20), + (8, 20), + (9, 20), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + let mut count = 5u32; + for i in 6..10 { + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(i), + 20, + count + )); + count += 1u32; + } + }); } // SCHEDULE LEAVE CANDIDATES #[test] fn leave_candidates_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( - 1, 1, 3 - ))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( + 1, 1, 3 + ))); + }); } #[test] fn leave_candidates_removes_candidate_from_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - assert!(ParachainStaking::candidate_pool().0.is_empty()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert!(ParachainStaking::candidate_pool().0.is_empty()); + }); } #[test] fn cannot_leave_candidates_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::schedule_leave_candidates(Origin::signed(1), 1u32), - Error::::CandidateDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_leave_candidates(Origin::signed(1), 1u32), + Error::::CandidateDNE + ); + }); } #[test] fn cannot_leave_candidates_if_already_leaving_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - assert_noop!( - ParachainStaking::schedule_leave_candidates(Origin::signed(1), 1u32), - Error::::CandidateAlreadyLeaving - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_noop!( + ParachainStaking::schedule_leave_candidates(Origin::signed(1), 1u32), + Error::::CandidateAlreadyLeaving + ); + }); } #[test] fn insufficient_leave_candidates_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - for i in 1..6 { - assert_noop!( - ParachainStaking::schedule_leave_candidates(Origin::signed(i), 4u32), - Error::::TooLowCandidateCountToLeaveCandidates - ); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + for i in 1..6 { + assert_noop!( + ParachainStaking::schedule_leave_candidates(Origin::signed(i), 4u32), + Error::::TooLowCandidateCountToLeaveCandidates + ); + } + }); } #[test] fn sufficient_leave_candidates_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - let mut count = 5u32; - for i in 1..6 { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(i), - count - )); - count -= 1u32; - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + let mut count = 5u32; + for i in 1..6 { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(i), + count + )); + count -= 1u32; + } + }); } // EXECUTE LEAVE CANDIDATES #[test] fn execute_leave_candidates_emits_event() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(1), - 1, - 0 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateLeft(1, 10, 0))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateLeft(1, 10, 0))); + }); } #[test] fn execute_leave_candidates_callable_by_any_signed() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(2), - 1, - 0 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 1, + 0 + )); + }); } #[test] fn execute_leave_candidates_requires_correct_weight_hint() { - ExtBuilder::default() - .with_balances(vec![(1, 10), (2, 10), (3, 10), (4, 10)]) - .with_candidates(vec![(1, 10)]) - .with_delegations(vec![(2, 1, 10), (3, 1, 10), (4, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - roll_to(10); - for i in 0..3 { - assert_noop!( - ParachainStaking::execute_leave_candidates(Origin::signed(1), 1, i), - Error::::TooLowCandidateDelegationCountToLeaveCandidates - ); - } - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(2), - 1, - 3 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10), (2, 10), (3, 10), (4, 10)]) + .with_candidates(vec![(1, 10)]) + .with_delegations(vec![(2, 1, 10), (3, 1, 10), (4, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + for i in 0..3 { + assert_noop!( + ParachainStaking::execute_leave_candidates(Origin::signed(1), 1, i), + Error::::TooLowCandidateDelegationCountToLeaveCandidates + ); + } + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 1, + 3 + )); + }); } #[test] fn execute_leave_candidates_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&1), 10); - assert_eq!(Balances::free_balance(&1), 0); - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(1), - 1, - 0 - )); - assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(Balances::free_balance(&1), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 10); + assert_eq!(Balances::free_balance(&1), 0); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(&1), 10); + }); } #[test] fn execute_leave_candidates_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 10); - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(1), - 1, - 0 - )); - assert_eq!(ParachainStaking::total(), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 10); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_eq!(ParachainStaking::total(), 0); + }); } #[test] fn execute_leave_candidates_removes_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - // candidate state is not immediately removed - let candidate_state = - ParachainStaking::candidate_info(1).expect("just left => still exists"); - assert_eq!(candidate_state.bond, 10u128); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(1), - 1, - 0 - )); - assert!(ParachainStaking::candidate_state(1).is_none()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + // candidate state is not immediately removed + let candidate_state = + ParachainStaking::candidate_info(1).expect("just left => still exists"); + assert_eq!(candidate_state.bond, 10u128); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert!(ParachainStaking::candidate_state(1).is_none()); + }); } #[test] fn cannot_execute_leave_candidates_before_delay() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - assert_noop!( - ParachainStaking::execute_leave_candidates(Origin::signed(3), 1, 0), - Error::::CandidateCannotLeaveYet - ); - roll_to(9); - assert_noop!( - ParachainStaking::execute_leave_candidates(Origin::signed(3), 1, 0), - Error::::CandidateCannotLeaveYet - ); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(3), - 1, - 0 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_noop!( + ParachainStaking::execute_leave_candidates(Origin::signed(3), 1, 0), + Error::::CandidateCannotLeaveYet + ); + roll_to(9); + assert_noop!( + ParachainStaking::execute_leave_candidates(Origin::signed(3), 1, 0), + Error::::CandidateCannotLeaveYet + ); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(3), + 1, + 0 + )); + }); } // CANCEL LEAVE CANDIDATES #[test] fn cancel_leave_candidates_emits_event() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - assert_ok!(ParachainStaking::cancel_leave_candidates( - Origin::signed(1), - 1 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::CancelledCandidateExit( - 1 - ))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_ok!(ParachainStaking::cancel_leave_candidates( + Origin::signed(1), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CancelledCandidateExit( + 1 + ))); + }); } #[test] fn cancel_leave_candidates_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - assert_ok!(ParachainStaking::cancel_leave_candidates( - Origin::signed(1), - 1 - )); - let candidate = - ParachainStaking::candidate_info(&1).expect("just cancelled leave so exists"); - assert!(candidate.is_active()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_ok!(ParachainStaking::cancel_leave_candidates( + Origin::signed(1), + 1 + )); + let candidate = + ParachainStaking::candidate_info(&1).expect("just cancelled leave so exists"); + assert!(candidate.is_active()); + }); } #[test] fn cancel_leave_candidates_adds_to_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 10)]) - .with_candidates(vec![(1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1u32 - )); - assert_ok!(ParachainStaking::cancel_leave_candidates( - Origin::signed(1), - 1 - )); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 10)]) + .with_candidates(vec![(1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1u32 + )); + assert_ok!(ParachainStaking::cancel_leave_candidates( + Origin::signed(1), + 1 + )); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 10); + }); } // GO OFFLINE #[test] fn go_offline_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateWentOffline(1))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateWentOffline(1))); + }); } #[test] fn go_offline_removes_candidate_from_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); - assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); - assert!(ParachainStaking::candidate_pool().0.is_empty()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0.len(), 1); + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert!(ParachainStaking::candidate_pool().0.is_empty()); + }); } #[test] fn go_offline_updates_candidate_state_to_idle() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - let candidate_state = ParachainStaking::candidate_info(1).expect("is active candidate"); - assert_eq!(candidate_state.status, CollatorStatus::Active); - assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); - let candidate_state = - ParachainStaking::candidate_info(1).expect("is candidate, just offline"); - assert_eq!(candidate_state.status, CollatorStatus::Idle); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let candidate_state = + ParachainStaking::candidate_info(1).expect("is active candidate"); + assert_eq!(candidate_state.status, CollatorStatus::Active); + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + let candidate_state = + ParachainStaking::candidate_info(1).expect("is candidate, just offline"); + assert_eq!(candidate_state.status, CollatorStatus::Idle); + }); } #[test] fn cannot_go_offline_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::go_offline(Origin::signed(3)), - Error::::CandidateDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::go_offline(Origin::signed(3)), + Error::::CandidateDNE + ); + }); } #[test] fn cannot_go_offline_if_already_offline() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); - assert_noop!( - ParachainStaking::go_offline(Origin::signed(1)), - Error::::AlreadyOffline - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert_noop!( + ParachainStaking::go_offline(Origin::signed(1)), + Error::::AlreadyOffline + ); + }); } // GO ONLINE #[test] fn go_online_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); - assert_ok!(ParachainStaking::go_online(Origin::signed(1))); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBackOnline(1))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert_ok!(ParachainStaking::go_online(Origin::signed(1))); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBackOnline(1))); + }); } #[test] fn go_online_adds_to_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); - assert!(ParachainStaking::candidate_pool().0.is_empty()); - assert_ok!(ParachainStaking::go_online(Origin::signed(1))); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + assert!(ParachainStaking::candidate_pool().0.is_empty()); + assert_ok!(ParachainStaking::go_online(Origin::signed(1))); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + }); } #[test] fn go_online_storage_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); - let candidate_state = - ParachainStaking::candidate_info(1).expect("offline still exists"); - assert_eq!(candidate_state.status, CollatorStatus::Idle); - assert_ok!(ParachainStaking::go_online(Origin::signed(1))); - let candidate_state = ParachainStaking::candidate_info(1).expect("online so exists"); - assert_eq!(candidate_state.status, CollatorStatus::Active); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::go_offline(Origin::signed(1))); + let candidate_state = + ParachainStaking::candidate_info(1).expect("offline still exists"); + assert_eq!(candidate_state.status, CollatorStatus::Idle); + assert_ok!(ParachainStaking::go_online(Origin::signed(1))); + let candidate_state = ParachainStaking::candidate_info(1).expect("online so exists"); + assert_eq!(candidate_state.status, CollatorStatus::Active); + }); } #[test] fn cannot_go_online_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::go_online(Origin::signed(3)), - Error::::CandidateDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::go_online(Origin::signed(3)), + Error::::CandidateDNE + ); + }); } #[test] fn cannot_go_online_if_already_online() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::go_online(Origin::signed(1)), - Error::::AlreadyActive - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::go_online(Origin::signed(1)), + Error::::AlreadyActive + ); + }); } #[test] fn cannot_go_online_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1 - )); - assert_noop!( - ParachainStaking::go_online(Origin::signed(1)), - Error::::CannotGoOnlineIfLeaving - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_noop!( + ParachainStaking::go_online(Origin::signed(1)), + Error::::CannotGoOnlineIfLeaving + ); + }); } // CANDIDATE BOND MORE #[test] fn candidate_bond_more_emits_correct_event() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBondedMore( - 1, 30, 50 - ))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBondedMore( + 1, 30, 50 + ))); + }); } #[test] fn candidate_bond_more_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&1), 20); - assert_eq!(Balances::free_balance(&1), 30); - assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); - assert_eq!(Balances::reserved_balance(&1), 50); - assert_eq!(Balances::free_balance(&1), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 20); + assert_eq!(Balances::free_balance(&1), 30); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + assert_eq!(Balances::reserved_balance(&1), 50); + assert_eq!(Balances::free_balance(&1), 0); + }); } #[test] fn candidate_bond_more_increases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - let mut total = ParachainStaking::total(); - assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); - total += 30; - assert_eq!(ParachainStaking::total(), total); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let mut total = ParachainStaking::total(); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + total += 30; + assert_eq!(ParachainStaking::total(), total); + }); } #[test] fn candidate_bond_more_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 20); - assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 50); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 20); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 50); + }); } #[test] fn candidate_bond_more_updates_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); - assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 50); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + assert_ok!(ParachainStaking::candidate_bond_more(Origin::signed(1), 30)); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 50); + }); } // SCHEDULE CANDIDATE BOND LESS #[test] fn schedule_candidate_bond_less_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::CandidateBondLessRequested(1, 10, 3,) - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CandidateBondLessRequested(1, 10, 3,) + )); + }); } #[test] fn cannot_schedule_candidate_bond_less_if_request_exists() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 5 - )); - assert_noop!( - ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 5), - Error::::PendingCandidateRequestAlreadyExists - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 5 + )); + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 5), + Error::::PendingCandidateRequestAlreadyExists + ); + }); } #[test] fn cannot_schedule_candidate_bond_less_if_not_candidate() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::schedule_candidate_bond_less(Origin::signed(6), 50), - Error::::CandidateDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(6), 50), + Error::::CandidateDNE + ); + }); } #[test] fn cannot_schedule_candidate_bond_less_if_new_total_below_min_candidate_stk() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 21), - Error::::CandidateBondBelowMin - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 21), + Error::::CandidateBondBelowMin + ); + }); } #[test] fn can_schedule_candidate_bond_less_if_leaving_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1 - )); - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + }); } #[test] fn cannot_schedule_candidate_bond_less_if_exited_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(1), - 1, - 0 - )); - assert_noop!( - ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 10), - Error::::CandidateDNE - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 0 + )); + assert_noop!( + ParachainStaking::schedule_candidate_bond_less(Origin::signed(1), 10), + Error::::CandidateDNE + ); + }); } // 2. EXECUTE BOND LESS REQUEST #[test] fn execute_candidate_bond_less_emits_correct_event() { - ExtBuilder::default() - .with_balances(vec![(1, 50)]) - .with_candidates(vec![(1, 50)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 30 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_candidate_bond_less( - Origin::signed(1), - 1 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBondedLess( - 1, 30, 20 - ))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 50)]) + .with_candidates(vec![(1, 50)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 30 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateBondedLess( + 1, 30, 20 + ))); + }); } #[test] fn execute_candidate_bond_less_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&1), 30); - assert_eq!(Balances::free_balance(&1), 0); - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_candidate_bond_less( - Origin::signed(1), - 1 - )); - assert_eq!(Balances::reserved_balance(&1), 20); - assert_eq!(Balances::free_balance(&1), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&1), 30); + assert_eq!(Balances::free_balance(&1), 0); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + assert_eq!(Balances::reserved_balance(&1), 20); + assert_eq!(Balances::free_balance(&1), 10); + }); } #[test] fn execute_candidate_bond_less_decreases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - let mut total = ParachainStaking::total(); - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_candidate_bond_less( - Origin::signed(1), - 1 - )); - total -= 10; - assert_eq!(ParachainStaking::total(), total); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + let mut total = ParachainStaking::total(); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + total -= 10; + assert_eq!(ParachainStaking::total(), total); + }); } #[test] fn execute_candidate_bond_less_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 30); - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_candidate_bond_less( - Origin::signed(1), - 1 - )); - let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); - assert_eq!(candidate_state.bond, 20); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 30); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + let candidate_state = ParachainStaking::candidate_info(1).expect("updated => exists"); + assert_eq!(candidate_state.bond, 20); + }); } #[test] fn execute_candidate_bond_less_updates_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 30); - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_candidate_bond_less( - Origin::signed(1), - 1 - )); - assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); - assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 30); + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_candidate_bond_less( + Origin::signed(1), + 1 + )); + assert_eq!(ParachainStaking::candidate_pool().0[0].owner, 1); + assert_eq!(ParachainStaking::candidate_pool().0[0].amount, 20); + }); } // CANCEL CANDIDATE BOND LESS REQUEST #[test] fn cancel_candidate_bond_less_emits_event() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - assert_ok!(ParachainStaking::cancel_candidate_bond_less( - Origin::signed(1) - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::CancelledCandidateBondLess(1, 10, 3,) - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_ok!(ParachainStaking::cancel_candidate_bond_less( + Origin::signed(1) + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CancelledCandidateBondLess(1, 10, 3,) + )); + }); } #[test] fn cancel_candidate_bond_less_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - assert_ok!(ParachainStaking::cancel_candidate_bond_less( - Origin::signed(1) - )); - assert!(ParachainStaking::candidate_info(&1) - .unwrap() - .request - .is_none()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_ok!(ParachainStaking::cancel_candidate_bond_less( + Origin::signed(1) + )); + assert!(ParachainStaking::candidate_info(&1) + .unwrap() + .request + .is_none()); + }); } #[test] fn only_candidate_can_cancel_candidate_bond_less_request() { - ExtBuilder::default() - .with_balances(vec![(1, 30)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_candidate_bond_less( - Origin::signed(1), - 10 - )); - assert_noop!( - ParachainStaking::cancel_candidate_bond_less(Origin::signed(2)), - Error::::CandidateDNE - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_candidate_bond_less( + Origin::signed(1), + 10 + )); + assert_noop!( + ParachainStaking::cancel_candidate_bond_less(Origin::signed(2)), + Error::::CandidateDNE + ); + }); } // NOMINATE #[test] fn delegate_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); - assert_last_event!(MetaEvent::ParachainStaking(Event::Delegation( - 2, - 10, - 1, - DelegatorAdded::AddedToTop { new_total: 40 }, - ))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + assert_last_event!(MetaEvent::ParachainStaking(Event::Delegation( + 2, + 10, + 1, + DelegatorAdded::AddedToTop { new_total: 40 }, + ))); + }); } #[test] fn delegate_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + }); } #[test] fn delegate_updates_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert!(ParachainStaking::delegator_state(2).is_none()); - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); - let delegator_state = - ParachainStaking::delegator_state(2).expect("just delegated => exists"); - assert_eq!(delegator_state.total, 10); - assert_eq!(delegator_state.delegations.0[0].owner, 1); - assert_eq!(delegator_state.delegations.0[0].amount, 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2).is_none()); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + let delegator_state = + ParachainStaking::delegator_state(2).expect("just delegated => exists"); + assert_eq!(delegator_state.total, 10); + assert_eq!(delegator_state.delegations.0[0].owner, 1); + assert_eq!(delegator_state.delegations.0[0].amount, 10); + }); } #[test] fn delegate_updates_collator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - let candidate_state = - ParachainStaking::candidate_info(1).expect("registered in genesis"); - assert_eq!(candidate_state.total_counted, 30); - let top_delegations = - ParachainStaking::top_delegations(1).expect("registered in genesis"); - assert!(top_delegations.delegations.is_empty()); - assert!(top_delegations.total.is_zero()); - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); - let candidate_state = - ParachainStaking::candidate_info(1).expect("just delegated => exists"); - assert_eq!(candidate_state.total_counted, 40); - let top_delegations = - ParachainStaking::top_delegations(1).expect("just delegated => exists"); - assert_eq!(top_delegations.delegations[0].owner, 2); - assert_eq!(top_delegations.delegations[0].amount, 10); - assert_eq!(top_delegations.total, 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + let candidate_state = + ParachainStaking::candidate_info(1).expect("registered in genesis"); + assert_eq!(candidate_state.total_counted, 30); + let top_delegations = + ParachainStaking::top_delegations(1).expect("registered in genesis"); + assert!(top_delegations.delegations.is_empty()); + assert!(top_delegations.total.is_zero()); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0)); + let candidate_state = + ParachainStaking::candidate_info(1).expect("just delegated => exists"); + assert_eq!(candidate_state.total_counted, 40); + let top_delegations = + ParachainStaking::top_delegations(1).expect("just delegated => exists"); + assert_eq!(top_delegations.delegations[0].owner, 2); + assert_eq!(top_delegations.delegations[0].amount, 10); + assert_eq!(top_delegations.total, 10); + }); } #[test] fn can_delegate_immediately_after_other_join_candidates() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::join_candidates(Origin::signed(1), 20, 0)); - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 20, 0, 0)); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::join_candidates(Origin::signed(1), 20, 0)); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 20, 0, 0)); + }); } #[test] fn can_delegate_if_revoking() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 30), (3, 20), (4, 20)]) - .with_candidates(vec![(1, 20), (3, 20), (4, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 4, 10, 0, 2)); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 30), (3, 20), (4, 20)]) + .with_candidates(vec![(1, 20), (3, 20), (4, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 4, 10, 0, 2)); + }); } #[test] fn cannot_delegate_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 20), (3, 20)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_noop!( - ParachainStaking::delegate(Origin::signed(2), 3, 10, 0, 1), - Error::::CannotDelegateIfLeaving - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 20), (3, 20)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 3, 10, 0, 1), + Error::::CannotDelegateIfLeaving + ); + }); } #[test] fn cannot_delegate_if_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 30)]) - .with_candidates(vec![(1, 20), (2, 20)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0), - Error::::CandidateExists - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 30)]) + .with_candidates(vec![(1, 20), (2, 20)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 1, 10, 0, 0), + Error::::CandidateExists + ); + }); } #[test] fn cannot_delegate_if_already_delegated() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 30)]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![(2, 1, 20)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::delegate(Origin::signed(2), 1, 10, 1, 1), - Error::::AlreadyDelegatedCandidate - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 30)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(2, 1, 20)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 1, 10, 1, 1), + Error::::AlreadyDelegatedCandidate + ); + }); } #[test] fn cannot_delegate_more_than_max_delegations() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 50), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10), (2, 5, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::delegate(Origin::signed(2), 6, 10, 0, 4), - Error::::ExceedMaxDelegationsPerDelegator, - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 50), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10), (2, 5, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::delegate(Origin::signed(2), 6, 10, 0, 4), + Error::::ExceedMaxDelegationsPerDelegator, + ); + }); } #[test] fn sufficient_delegate_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (2, 20), - (3, 20), - (4, 20), - (5, 20), - (6, 20), - (7, 20), - (8, 20), - (9, 20), - (10, 20), - ]) - .with_candidates(vec![(1, 20), (2, 20)]) - .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - let mut count = 4u32; - for i in 7..11 { - assert_ok!(ParachainStaking::delegate( - Origin::signed(i), - 1, - 10, - count, - 0u32 - )); - count += 1u32; - } - let mut count = 0u32; - for i in 3..11 { - assert_ok!(ParachainStaking::delegate( - Origin::signed(i), - 2, - 10, - count, - 1u32 - )); - count += 1u32; - } - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (2, 20), + (3, 20), + (4, 20), + (5, 20), + (6, 20), + (7, 20), + (8, 20), + (9, 20), + (10, 20), + ]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + let mut count = 4u32; + for i in 7..11 { + assert_ok!(ParachainStaking::delegate( + Origin::signed(i), + 1, + 10, + count, + 0u32 + )); + count += 1u32; + } + let mut count = 0u32; + for i in 3..11 { + assert_ok!(ParachainStaking::delegate( + Origin::signed(i), + 2, + 10, + count, + 1u32 + )); + count += 1u32; + } + }); } #[test] fn insufficient_delegate_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (2, 20), - (3, 20), - (4, 20), - (5, 20), - (6, 20), - (7, 20), - (8, 20), - (9, 20), - (10, 20), - ]) - .with_candidates(vec![(1, 20), (2, 20)]) - .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - let mut count = 3u32; - for i in 7..11 { - assert_noop!( - ParachainStaking::delegate(Origin::signed(i), 1, 10, count, 0u32), - Error::::TooLowCandidateDelegationCountToDelegate - ); - } - // to set up for next error test - count = 4u32; - for i in 7..11 { - assert_ok!(ParachainStaking::delegate( - Origin::signed(i), - 1, - 10, - count, - 0u32 - )); - count += 1u32; - } - count = 0u32; - for i in 3..11 { - assert_noop!( - ParachainStaking::delegate(Origin::signed(i), 2, 10, count, 0u32), - Error::::TooLowDelegationCountToDelegate - ); - count += 1u32; - } - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (2, 20), + (3, 20), + (4, 20), + (5, 20), + (6, 20), + (7, 20), + (8, 20), + (9, 20), + (10, 20), + ]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + let mut count = 3u32; + for i in 7..11 { + assert_noop!( + ParachainStaking::delegate(Origin::signed(i), 1, 10, count, 0u32), + Error::::TooLowCandidateDelegationCountToDelegate + ); + } + // to set up for next error test + count = 4u32; + for i in 7..11 { + assert_ok!(ParachainStaking::delegate( + Origin::signed(i), + 1, + 10, + count, + 0u32 + )); + count += 1u32; + } + count = 0u32; + for i in 3..11 { + assert_noop!( + ParachainStaking::delegate(Origin::signed(i), 2, 10, count, 0u32), + Error::::TooLowDelegationCountToDelegate + ); + count += 1u32; + } + }); } // SCHEDULE LEAVE DELEGATORS #[test] fn schedule_leave_delegators_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_last_event!(MetaEvent::ParachainStaking(Event::DelegatorExitScheduled( - 1, 2, 3 - ))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegatorExitScheduled( + 1, 2, 3 + ))); + }); } #[test] fn cannot_schedule_leave_delegators_if_already_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_noop!( - ParachainStaking::schedule_leave_delegators(Origin::signed(2)), - Error::::DelegatorAlreadyLeaving - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(2)), + Error::::DelegatorAlreadyLeaving + ); + }); } #[test] fn cannot_schedule_leave_delegators_if_not_delegator() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_leave_delegators(Origin::signed(2)), - Error::::DelegatorDNE - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(2)), + Error::::DelegatorDNE + ); + }); } // EXECUTE LEAVE DELEGATORS #[test] fn execute_leave_delegators_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(2), - 2, - 1 - )); - assert_event_emitted!(Event::DelegatorLeft(2, 10)); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeft(2, 10)); + }); } #[test] fn execute_leave_delegators_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(2), - 2, - 1 - )); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + }); } #[test] fn execute_leave_delegators_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(2), - 2, - 1 - )); - assert_eq!(ParachainStaking::total(), 30); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 30); + }); } #[test] fn execute_leave_delegators_removes_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert!(ParachainStaking::delegator_state(2).is_some()); - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(2), - 2, - 1 - )); - assert!(ParachainStaking::delegator_state(2).is_none()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2).is_some()); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::delegator_state(2).is_none()); + }); } #[test] fn execute_leave_delegators_removes_delegations_from_collator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 100), (2, 20), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(2, 20), (3, 20), (4, 20), (5, 20)]) - .with_delegations(vec![(1, 2, 10), (1, 3, 10), (1, 4, 10), (1, 5, 10)]) - .build() - .execute_with(|| { - for i in 2..6 { - let candidate_state = - ParachainStaking::candidate_info(i).expect("initialized in ext builder"); - assert_eq!(candidate_state.total_counted, 30); - let top_delegations = - ParachainStaking::top_delegations(i).expect("initialized in ext builder"); - assert_eq!(top_delegations.delegations[0].owner, 1); - assert_eq!(top_delegations.delegations[0].amount, 10); - assert_eq!(top_delegations.total, 10); - } - assert_eq!( - ParachainStaking::delegator_state(1) - .unwrap() - .delegations - .0 - .len(), - 4usize - ); - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 1 - ))); - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(1), - 1, - 10 - )); - for i in 2..6 { - let candidate_state = - ParachainStaking::candidate_info(i).expect("initialized in ext builder"); - assert_eq!(candidate_state.total_counted, 20); - let top_delegations = - ParachainStaking::top_delegations(i).expect("initialized in ext builder"); - assert!(top_delegations.delegations.is_empty()); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 100), (2, 20), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(2, 20), (3, 20), (4, 20), (5, 20)]) + .with_delegations(vec![(1, 2, 10), (1, 3, 10), (1, 4, 10), (1, 5, 10)]) + .build() + .execute_with(|| { + for i in 2..6 { + let candidate_state = + ParachainStaking::candidate_info(i).expect("initialized in ext builder"); + assert_eq!(candidate_state.total_counted, 30); + let top_delegations = + ParachainStaking::top_delegations(i).expect("initialized in ext builder"); + assert_eq!(top_delegations.delegations[0].owner, 1); + assert_eq!(top_delegations.delegations[0].amount, 10); + assert_eq!(top_delegations.total, 10); + } + assert_eq!( + ParachainStaking::delegator_state(1) + .unwrap() + .delegations + .0 + .len(), + 4usize + ); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 1 + ))); + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(1), + 1, + 10 + )); + for i in 2..6 { + let candidate_state = + ParachainStaking::candidate_info(i).expect("initialized in ext builder"); + assert_eq!(candidate_state.total_counted, 20); + let top_delegations = + ParachainStaking::top_delegations(i).expect("initialized in ext builder"); + assert!(top_delegations.delegations.is_empty()); + } + }); } #[test] fn cannot_execute_leave_delegators_before_delay() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_noop!( - ParachainStaking::execute_leave_delegators(Origin::signed(2), 2, 1), - Error::::DelegatorCannotLeaveYet - ); - // can execute after delay - roll_to(10); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(2), - 2, - 1 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_noop!( + ParachainStaking::execute_leave_delegators(Origin::signed(2), 2, 1), + Error::::DelegatorCannotLeaveYet + ); + // can execute after delay + roll_to(10); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 1 + )); + }); } #[test] fn insufficient_execute_leave_delegators_weight_hint_fails() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - for i in 3..7 { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - i - ))); - } - roll_to(10); - for i in 3..7 { - assert_noop!( - ParachainStaking::execute_leave_delegators(Origin::signed(i), i, 0), - Error::::TooLowDelegationCountToLeaveDelegators - ); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + for i in 3..7 { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + i + ))); + } + roll_to(10); + for i in 3..7 { + assert_noop!( + ParachainStaking::execute_leave_delegators(Origin::signed(i), i, 0), + Error::::TooLowDelegationCountToLeaveDelegators + ); + } + }); } #[test] fn sufficient_execute_leave_delegators_weight_hint_succeeds() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) - .build() - .execute_with(|| { - for i in 3..7 { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - i - ))); - } - roll_to(10); - for i in 3..7 { - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(i), - i, - 1 - )); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(3, 1, 10), (4, 1, 10), (5, 1, 10), (6, 1, 10)]) + .build() + .execute_with(|| { + for i in 3..7 { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + i + ))); + } + roll_to(10); + for i in 3..7 { + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(i), + i, + 1 + )); + } + }); } // CANCEL LEAVE DELEGATORS #[test] fn cancel_leave_delegators_emits_correct_event() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_ok!(ParachainStaking::cancel_leave_delegators(Origin::signed(2))); - assert_last_event!(MetaEvent::ParachainStaking(Event::DelegatorExitCancelled( - 2 - ))); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::cancel_leave_delegators(Origin::signed(2))); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegatorExitCancelled( + 2 + ))); + }); } #[test] fn cancel_leave_delegators_updates_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_ok!(ParachainStaking::cancel_leave_delegators(Origin::signed(2))); - let delegator = - ParachainStaking::delegator_state(&2).expect("just cancelled exit so exists"); - assert!(delegator.is_active()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::cancel_leave_delegators(Origin::signed(2))); + let delegator = + ParachainStaking::delegator_state(&2).expect("just cancelled exit so exists"); + assert!(delegator.is_active()); + }); } // SCHEDULE REVOKE DELEGATION #[test] fn revoke_delegation_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::DelegationRevocationScheduled(1, 2, 1, 3,) - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::DelegationRevocationScheduled(1, 2, 1, 3,) + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + }); } #[test] fn can_revoke_delegation_if_revoking_another_delegation() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - // this is an exit implicitly because last delegation revoked - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 3 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + // this is an exit implicitly because last delegation revoked + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 3 + )); + }); } #[test] fn can_revoke_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 3 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 3 + )); + }); } #[test] fn cannot_revoke_delegation_if_not_delegator() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::schedule_revoke_delegation(Origin::signed(2), 1), - Error::::DelegatorDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_revoke_delegation(Origin::signed(2), 1), + Error::::DelegatorDNE + ); + }); } #[test] fn cannot_revoke_delegation_that_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_revoke_delegation(Origin::signed(2), 3), - Error::::DelegationDNE - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_revoke_delegation(Origin::signed(2), 3), + Error::::DelegationDNE + ); + }); } #[test] // See `cannot_execute_revoke_delegation_below_min_delegator_stake` for where the "must be above // MinDelegatorStk" rule is now enforced. fn can_schedule_revoke_delegation_below_min_delegator_stake() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 8), (3, 20)]) - .with_candidates(vec![(1, 20), (3, 20)]) - .with_delegations(vec![(2, 1, 5), (2, 3, 3)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 8), (3, 20)]) + .with_candidates(vec![(1, 20), (3, 20)]) + .with_delegations(vec![(2, 1, 5), (2, 3, 3)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + }); } // DELEGATOR BOND MORE #[test] fn delegator_bond_more_reserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 5); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 1, - 5 - )); - assert_eq!(Balances::reserved_balance(&2), 15); - assert_eq!(Balances::free_balance(&2), 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 5); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!(Balances::reserved_balance(&2), 15); + assert_eq!(Balances::free_balance(&2), 0); + }); } #[test] fn delegator_bond_more_increases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 1, - 5 - )); - assert_eq!(ParachainStaking::total(), 45); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!(ParachainStaking::total(), 45); + }); } #[test] fn delegator_bond_more_updates_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!( - ParachainStaking::delegator_state(2).expect("exists").total, - 10 - ); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 1, - 5 - )); - assert_eq!( - ParachainStaking::delegator_state(2).expect("exists").total, - 15 - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 10 + ); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 15 + ); + }); } #[test] fn delegator_bond_more_updates_candidate_state_top_delegations() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, - 2 - ); - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, - 10 - ); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 1, - 5 - )); - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, - 2 - ); - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, - 15 - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 10 + ); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 15 + ); + }); } #[test] fn delegator_bond_more_updates_candidate_state_bottom_delegations() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![ - (2, 1, 10), - (3, 1, 20), - (4, 1, 20), - (5, 1, 20), - (6, 1, 20), - ]) - .build() - .execute_with(|| { - assert_eq!( - ParachainStaking::bottom_delegations(1) - .expect("exists") - .delegations[0] - .owner, - 2 - ); - assert_eq!( - ParachainStaking::bottom_delegations(1) - .expect("exists") - .delegations[0] - .amount, - 10 - ); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 1, - 5 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::DelegationIncreased( - 2, 1, 5, false - ))); - assert_eq!( - ParachainStaking::bottom_delegations(1) - .expect("exists") - .delegations[0] - .owner, - 2 - ); - assert_eq!( - ParachainStaking::bottom_delegations(1) - .expect("exists") - .delegations[0] - .amount, - 15 - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![ + (2, 1, 10), + (3, 1, 20), + (4, 1, 20), + (5, 1, 20), + (6, 1, 20), + ]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .owner, + 2 + ); + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .amount, + 10 + ); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegationIncreased( + 2, 1, 5, false + ))); + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .owner, + 2 + ); + assert_eq!( + ParachainStaking::bottom_delegations(1) + .expect("exists") + .delegations[0] + .amount, + 15 + ); + }); } #[test] fn delegator_bond_more_increases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 1, - 5 - )); - assert_eq!(ParachainStaking::total(), 45); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + assert_eq!(ParachainStaking::total(), 45); + }); } #[test] fn can_delegator_bond_more_for_leaving_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1 - )); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 1, - 5 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 1, + 5 + )); + }); } // DELEGATOR BOND LESS #[test] fn delegator_bond_less_event_emits_correctly() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::DelegationDecreaseScheduled(2, 1, 5, 3,) - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::DelegationDecreaseScheduled(2, 1, 5, 3,) + )); + }); } #[test] fn delegator_bond_less_updates_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - let state = - ParachainStaking::delegator_state(&2).expect("just request bonded less so exists"); - assert_eq!( - state.requests().get(&1), - Some(&DelegationRequest { - collator: 1, - amount: 5, - when_executable: 3, - action: DelegationChange::Decrease - }) - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + let state = ParachainStaking::delegator_state(&2) + .expect("just request bonded less so exists"); + assert_eq!( + state.requests().get(&1), + Some(&DelegationRequest { + collator: 1, + amount: 5, + when_executable: 3, + action: DelegationChange::Decrease + }) + ); + }); } #[test] fn can_delegator_bond_less_if_leaving() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 1 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 1 + )); + }); } #[test] fn cannot_delegator_bond_less_if_revoking() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 25), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 1), - Error::::PendingDelegationRequestAlreadyExists - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 25), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 1), + Error::::PendingDelegationRequestAlreadyExists + ); + }); } #[test] fn cannot_delegator_bond_less_if_not_delegator() { - ExtBuilder::default().build().execute_with(|| { - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 5), - Error::::DelegatorDNE - ); - }); + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 5), + Error::::DelegatorDNE + ); + }); } #[test] fn cannot_delegator_bond_less_if_candidate_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 3, 5), - Error::::DelegationDNE - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 3, 5), + Error::::DelegationDNE + ); + }); } #[test] fn cannot_delegator_bond_less_if_delegation_dne() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 3, 5), - Error::::DelegationDNE - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 3, 5), + Error::::DelegationDNE + ); + }); } #[test] fn cannot_delegator_bond_less_below_min_collator_stk() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 6), - Error::::DelegatorBondBelowMin - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 6), + Error::::DelegatorBondBelowMin + ); + }); } #[test] fn cannot_delegator_bond_less_more_than_total_delegation() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 11), - Error::::DelegatorBondBelowMin - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 11), + Error::::DelegatorBondBelowMin + ); + }); } #[test] fn cannot_delegator_bond_less_below_min_delegation() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 8), - Error::::DelegationBelowMin - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 8), + Error::::DelegationBelowMin + ); + }); } // EXECUTE PENDING DELEGATION REQUEST @@ -2678,715 +2682,715 @@ fn cannot_delegator_bond_less_below_min_delegation() { #[test] fn execute_revoke_delegation_emits_exit_event_if_exit_happens() { - // last delegation is revocation - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); - assert_event_emitted!(Event::DelegatorLeft(2, 10)); - }); + // last delegation is revocation + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + assert_event_emitted!(Event::DelegatorLeft(2, 10)); + }); } #[test] fn cannot_execute_revoke_delegation_below_min_delegator_stake() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 8), (3, 20)]) - .with_candidates(vec![(1, 20), (3, 20)]) - .with_delegations(vec![(2, 1, 5), (2, 3, 3)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_noop!( - ParachainStaking::execute_delegation_request(Origin::signed(2), 2, 1), - Error::::DelegatorBondBelowMin - ); - // but delegator can cancel the request and request to leave instead: - assert_ok!(ParachainStaking::cancel_delegation_request( - Origin::signed(2), - 1 - )); - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 2 - ))); - roll_to(20); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(2), - 2, - 2 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 8), (3, 20)]) + .with_candidates(vec![(1, 20), (3, 20)]) + .with_delegations(vec![(2, 1, 5), (2, 3, 3)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_noop!( + ParachainStaking::execute_delegation_request(Origin::signed(2), 2, 1), + Error::::DelegatorBondBelowMin + ); + // but delegator can cancel the request and request to leave instead: + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 2 + ))); + roll_to(20); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(2), + 2, + 2 + )); + }); } #[test] fn revoke_delegation_executes_exit_if_last_delegation() { - // last delegation is revocation - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); - assert_event_emitted!(Event::DelegatorLeft(2, 10)); - }); + // last delegation is revocation + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + assert_event_emitted!(Event::DelegatorLeft(2, 10)); + }); } #[test] fn execute_revoke_delegation_emits_correct_event() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_event_emitted!(Event::DelegatorLeftCandidate(2, 1, 10, 30)); + }); } #[test] fn execute_revoke_delegation_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + }); } #[test] fn execute_revoke_delegation_adds_revocation_to_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert!(ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .requests - .get(&1) - .is_none()); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert!(ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .requests - .get(&1) - .is_some()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .requests + .get(&1) + .is_none()); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert!(ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .requests + .get(&1) + .is_some()); + }); } #[test] fn execute_revoke_delegation_removes_revocation_from_delegator_state_upon_execution() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 20), (3, 20)]) - .with_candidates(vec![(1, 30), (3, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert!(ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .requests - .get(&1) - .is_none()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 20), (3, 20)]) + .with_candidates(vec![(1, 30), (3, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .requests + .get(&1) + .is_none()); + }); } #[test] fn execute_revoke_delegation_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!(ParachainStaking::total(), 30); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 30); + }); } #[test] fn execute_revoke_delegation_for_last_delegation_removes_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert!(ParachainStaking::delegator_state(2).is_some()); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - // this will be confusing for people - // if status is leaving, then execute_delegation_request works if last delegation - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert!(ParachainStaking::delegator_state(2).is_none()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert!(ParachainStaking::delegator_state(2).is_some()); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + // this will be confusing for people + // if status is leaving, then execute_delegation_request works if last delegation + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::delegator_state(2).is_none()); + }); } #[test] fn execute_revoke_delegation_removes_delegation_from_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!( - ParachainStaking::candidate_info(1) - .expect("exists") - .delegation_count, - 1u32 - ); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert!(ParachainStaking::candidate_info(1) - .expect("exists") - .delegation_count - .is_zero()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::candidate_info(1) + .expect("exists") + .delegation_count, + 1u32 + ); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::candidate_info(1) + .expect("exists") + .delegation_count + .is_zero()); + }); } #[test] fn can_execute_revoke_delegation_for_leaving_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1 - )); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - // can execute delegation request for leaving candidate - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + // can execute delegation request for leaving candidate + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + }); } #[test] fn can_execute_leave_candidates_if_revoking_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1 - )); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - roll_to(10); - // revocation executes during execute leave candidates (callable by anyone) - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(1), - 1, - 1 - )); - assert!(!ParachainStaking::is_delegator(&2)); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + roll_to(10); + // revocation executes during execute leave candidates (callable by anyone) + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(1), + 1, + 1 + )); + assert!(!ParachainStaking::is_delegator(&2)); + assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(&2), 10); + }); } #[test] fn delegator_bond_more_after_revoke_delegation_does_not_effect_exit() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 30), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(2), - 3, - 10 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert!(ParachainStaking::is_delegator(&2)); - assert_eq!(Balances::reserved_balance(&2), 20); - assert_eq!(Balances::free_balance(&2), 10); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 30), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(2), + 3, + 10 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert!(ParachainStaking::is_delegator(&2)); + assert_eq!(Balances::reserved_balance(&2), 20); + assert_eq!(Balances::free_balance(&2), 10); + }); } #[test] fn delegator_bond_less_after_revoke_delegation_does_not_effect_exit() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 30), (3, 30)]) - .with_candidates(vec![(1, 30), (3, 30)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::DelegationRevocationScheduled(1, 2, 1, 3,) - )); - assert_noop!( - ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 2), - Error::::PendingDelegationRequestAlreadyExists - ); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 3, - 2 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 3 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::DelegationDecreased( - 2, 3, 2, true - ))); - assert!(ParachainStaking::is_delegator(&2)); - assert_eq!(Balances::reserved_balance(&2), 8); - assert_eq!(Balances::free_balance(&2), 22); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 30), (3, 30)]) + .with_candidates(vec![(1, 30), (3, 30)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::DelegationRevocationScheduled(1, 2, 1, 3,) + )); + assert_noop!( + ParachainStaking::schedule_delegator_bond_less(Origin::signed(2), 1, 2), + Error::::PendingDelegationRequestAlreadyExists + ); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 3, + 2 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 3 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::DelegationDecreased( + 2, 3, 2, true + ))); + assert!(ParachainStaking::is_delegator(&2)); + assert_eq!(Balances::reserved_balance(&2), 8); + assert_eq!(Balances::free_balance(&2), 22); + }); } // 2. EXECUTE BOND LESS #[test] fn execute_delegator_bond_less_unreserves_balance() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(Balances::reserved_balance(&2), 10); - assert_eq!(Balances::free_balance(&2), 0); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!(Balances::reserved_balance(&2), 5); - assert_eq!(Balances::free_balance(&2), 5); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(Balances::reserved_balance(&2), 10); + assert_eq!(Balances::free_balance(&2), 0); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(Balances::reserved_balance(&2), 5); + assert_eq!(Balances::free_balance(&2), 5); + }); } #[test] fn execute_delegator_bond_less_decreases_total_staked() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!(ParachainStaking::total(), 35); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 35); + }); } #[test] fn execute_delegator_bond_less_updates_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!( - ParachainStaking::delegator_state(2).expect("exists").total, - 10 - ); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!( - ParachainStaking::delegator_state(2).expect("exists").total, - 5 - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 10 + ); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!( + ParachainStaking::delegator_state(2).expect("exists").total, + 5 + ); + }); } #[test] fn execute_delegator_bond_less_updates_candidate_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, - 2 - ); - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, - 10 - ); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, - 2 - ); - assert_eq!( - ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, - 5 - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 10 + ); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].owner, + 2 + ); + assert_eq!( + ParachainStaking::top_delegations(1).unwrap().delegations[0].amount, + 5 + ); + }); } #[test] fn execute_delegator_bond_less_decreases_total() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_eq!(ParachainStaking::total(), 40); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!(ParachainStaking::total(), 35); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_eq!(ParachainStaking::total(), 40); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!(ParachainStaking::total(), 35); + }); } #[test] fn execute_delegator_bond_less_updates_just_bottom_delegations() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![ - (2, 1, 10), - (3, 1, 11), - (4, 1, 12), - (5, 1, 14), - (6, 1, 15), - ]) - .build() - .execute_with(|| { - let pre_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); - let pre_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); - let pre_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 2 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - let post_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); - let post_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); - let post_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); - let mut not_equal = false; - for Bond { owner, amount } in pre_call_bottom_delegations.delegations { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_bottom_delegations.delegations - { - if &owner == post_owner { - if &amount != post_amount { - not_equal = true; - break; - } - } - } - } - assert!(not_equal); - let mut equal = true; - for Bond { owner, amount } in pre_call_top_delegations.delegations { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_top_delegations.delegations - { - if &owner == post_owner { - if &amount != post_amount { - equal = false; - break; - } - } - } - } - assert!(equal); - assert_eq!( - pre_call_candidate_info.total_counted, - post_call_candidate_info.total_counted - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (2, 1, 10), + (3, 1, 11), + (4, 1, 12), + (5, 1, 14), + (6, 1, 15), + ]) + .build() + .execute_with(|| { + let pre_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let pre_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let pre_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 2 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + let post_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let post_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let post_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + let mut not_equal = false; + for Bond { owner, amount } in pre_call_bottom_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_bottom_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + not_equal = true; + break; + } + } + } + } + assert!(not_equal); + let mut equal = true; + for Bond { owner, amount } in pre_call_top_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_top_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + equal = false; + break; + } + } + } + } + assert!(equal); + assert_eq!( + pre_call_candidate_info.total_counted, + post_call_candidate_info.total_counted + ); + }); } #[test] fn execute_delegator_bond_less_does_not_delete_bottom_delegations() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![ - (2, 1, 10), - (3, 1, 11), - (4, 1, 12), - (5, 1, 14), - (6, 1, 15), - ]) - .build() - .execute_with(|| { - let pre_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); - let pre_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); - let pre_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(6), - 1, - 4 - )); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(6), - 6, - 1 - )); - let post_call_candidate_info = - ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); - let post_call_top_delegations = - ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); - let post_call_bottom_delegations = - ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); - let mut equal = true; - for Bond { owner, amount } in pre_call_bottom_delegations.delegations { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_bottom_delegations.delegations - { - if &owner == post_owner { - if &amount != post_amount { - equal = false; - break; - } - } - } - } - assert!(equal); - let mut not_equal = false; - for Bond { owner, amount } in pre_call_top_delegations.delegations { - for Bond { - owner: post_owner, - amount: post_amount, - } in &post_call_top_delegations.delegations - { - if &owner == post_owner { - if &amount != post_amount { - not_equal = true; - break; - } - } - } - } - assert!(not_equal); - assert_eq!( - pre_call_candidate_info.total_counted - 4, - post_call_candidate_info.total_counted - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 10), (3, 11), (4, 12), (5, 14), (6, 15)]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (2, 1, 10), + (3, 1, 11), + (4, 1, 12), + (5, 1, 14), + (6, 1, 15), + ]) + .build() + .execute_with(|| { + let pre_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let pre_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let pre_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(6), + 1, + 4 + )); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(6), + 6, + 1 + )); + let post_call_candidate_info = + ParachainStaking::candidate_info(&1).expect("delegated by all so exists"); + let post_call_top_delegations = + ParachainStaking::top_delegations(&1).expect("delegated by all so exists"); + let post_call_bottom_delegations = + ParachainStaking::bottom_delegations(&1).expect("delegated by all so exists"); + let mut equal = true; + for Bond { owner, amount } in pre_call_bottom_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_bottom_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + equal = false; + break; + } + } + } + } + assert!(equal); + let mut not_equal = false; + for Bond { owner, amount } in pre_call_top_delegations.delegations { + for Bond { + owner: post_owner, + amount: post_amount, + } in &post_call_top_delegations.delegations + { + if &owner == post_owner { + if &amount != post_amount { + not_equal = true; + break; + } + } + } + } + assert!(not_equal); + assert_eq!( + pre_call_candidate_info.total_counted - 4, + post_call_candidate_info.total_counted + ); + }); } #[test] fn can_execute_delegator_bond_less_for_leaving_candidate() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 15)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(1), - 1 - )); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - roll_to(10); - // can execute bond more delegation request for leaving candidate - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 15)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(1), + 1 + )); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + roll_to(10); + // can execute bond more delegation request for leaving candidate + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + }); } // CANCEL PENDING DELEGATION REQUEST @@ -3394,1927 +3398,1927 @@ fn can_execute_delegator_bond_less_for_leaving_candidate() { #[test] fn cancel_revoke_delegation_emits_correct_event() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert_ok!(ParachainStaking::cancel_delegation_request( - Origin::signed(2), - 1 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::CancelledDelegationRequest( - 2, - DelegationRequest { - collator: 1, - amount: 10, - when_executable: 3, - action: DelegationChange::Revoke, - }, - ) - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CancelledDelegationRequest( + 2, + DelegationRequest { + collator: 1, + amount: 10, + when_executable: 3, + action: DelegationChange::Revoke, + }, + ) + )); + }); } #[test] fn cancel_revoke_delegation_updates_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 10)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - let state = ParachainStaking::delegator_state(&2).unwrap(); - assert_eq!( - state.requests().get(&1), - Some(&DelegationRequest { - collator: 1, - amount: 10, - when_executable: 3, - action: DelegationChange::Revoke, - }) - ); - assert_eq!(state.requests.less_total, 10); - assert_ok!(ParachainStaking::cancel_delegation_request( - Origin::signed(2), - 1 - )); - let state = ParachainStaking::delegator_state(&2).unwrap(); - assert!(state.requests().get(&1).is_none()); - assert_eq!(state.requests.less_total, 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 10)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert_eq!( + state.requests().get(&1), + Some(&DelegationRequest { + collator: 1, + amount: 10, + when_executable: 3, + action: DelegationChange::Revoke, + }) + ); + assert_eq!(state.requests.less_total, 10); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert!(state.requests().get(&1).is_none()); + assert_eq!(state.requests.less_total, 0); + }); } // 2. CANCEL DELEGATOR BOND LESS #[test] fn cancel_delegator_bond_less_correct_event() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 15)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - assert_ok!(ParachainStaking::cancel_delegation_request( - Origin::signed(2), - 1 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::CancelledDelegationRequest( - 2, - DelegationRequest { - collator: 1, - amount: 5, - when_executable: 3, - action: DelegationChange::Decrease, - }, - ) - )); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 15)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::CancelledDelegationRequest( + 2, + DelegationRequest { + collator: 1, + amount: 5, + when_executable: 3, + action: DelegationChange::Decrease, + }, + ) + )); + }); } #[test] fn cancel_delegator_bond_less_updates_delegator_state() { - ExtBuilder::default() - .with_balances(vec![(1, 30), (2, 15)]) - .with_candidates(vec![(1, 30)]) - .with_delegations(vec![(2, 1, 15)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(2), - 1, - 5 - )); - let state = ParachainStaking::delegator_state(&2).unwrap(); - assert_eq!( - state.requests().get(&1), - Some(&DelegationRequest { - collator: 1, - amount: 5, - when_executable: 3, - action: DelegationChange::Decrease, - }) - ); - assert_eq!(state.requests.less_total, 5); - assert_ok!(ParachainStaking::cancel_delegation_request( - Origin::signed(2), - 1 - )); - let state = ParachainStaking::delegator_state(&2).unwrap(); - assert!(state.requests().get(&1).is_none()); - assert_eq!(state.requests.less_total, 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 30), (2, 15)]) + .with_candidates(vec![(1, 30)]) + .with_delegations(vec![(2, 1, 15)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(2), + 1, + 5 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert_eq!( + state.requests().get(&1), + Some(&DelegationRequest { + collator: 1, + amount: 5, + when_executable: 3, + action: DelegationChange::Decrease, + }) + ); + assert_eq!(state.requests.less_total, 5); + assert_ok!(ParachainStaking::cancel_delegation_request( + Origin::signed(2), + 1 + )); + let state = ParachainStaking::delegator_state(&2).unwrap(); + assert!(state.requests().get(&1).is_none()); + assert_eq!(state.requests.less_total, 0); + }); } // ~~ PROPERTY-BASED TESTS ~~ #[test] fn delegator_schedule_revocation_total() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 40), (3, 20), (4, 20), (5, 20)]) - .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20)]) - .with_delegations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10)]) - .build() - .execute_with(|| { - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 1 - )); - assert_eq!( - ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .less_total, - 10 - ); - roll_to(10); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 1 - )); - assert_eq!( - ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .less_total, - 0 - ); - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 5, 10, 0, 2)); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 3 - )); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(2), - 4 - )); - assert_eq!( - ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .less_total, - 20 - ); - roll_to(20); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 3 - )); - assert_eq!( - ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .less_total, - 10 - ); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(2), - 2, - 4 - )); - assert_eq!( - ParachainStaking::delegator_state(2) - .expect("exists") - .requests - .less_total, - 0 - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 40), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(1, 20), (3, 20), (4, 20), (5, 20)]) + .with_delegations(vec![(2, 1, 10), (2, 3, 10), (2, 4, 10)]) + .build() + .execute_with(|| { + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 1 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 10 + ); + roll_to(10); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 1 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 0 + ); + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 5, 10, 0, 2)); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 3 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(2), + 4 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 20 + ); + roll_to(20); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 3 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 10 + ); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(2), + 2, + 4 + )); + assert_eq!( + ParachainStaking::delegator_state(2) + .expect("exists") + .requests + .less_total, + 0 + ); + }); } #[test] fn parachain_bond_inflation_reserve_matches_config() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - (11, 1), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_delegations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - assert_eq!(Balances::free_balance(&11), 1); - // set parachain bond account so DefaultParachainBondReservePercent = 30% of inflation - // is allocated to this account hereafter - assert_ok!(ParachainStaking::set_parachain_bond_account( - Origin::root(), - 11 - )); - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::ParachainBondAccountSet(0, 11), - Event::CollatorChosen(2, 1, 50), - Event::CollatorChosen(2, 2, 40), - Event::CollatorChosen(2, 3, 20), - Event::CollatorChosen(2, 4, 20), - Event::CollatorChosen(2, 5, 10), - Event::NewRound(5, 2, 5, 140), - ]; - assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 1); - // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); - roll_to(16); - // distribute total issuance to collator 1 and its delegators 6, 7, 19 - let mut new = vec![ - Event::CollatorChosen(3, 1, 50), - Event::CollatorChosen(3, 2, 40), - Event::CollatorChosen(3, 3, 20), - Event::CollatorChosen(3, 4, 20), - Event::CollatorChosen(3, 5, 10), - Event::NewRound(10, 3, 5, 140), - Event::ReservedForParachainBond(11, 15), - Event::CollatorChosen(4, 1, 50), - Event::CollatorChosen(4, 2, 40), - Event::CollatorChosen(4, 3, 20), - Event::CollatorChosen(4, 4, 20), - Event::CollatorChosen(4, 5, 10), - Event::NewRound(15, 4, 5, 140), - Event::Rewarded(1, 20), - Event::Rewarded(6, 5), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - ]; - expected.append(&mut new); - assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 16); - // ~ set block author as 1 for all blocks this round - set_author(3, 1, 100); - set_author(4, 1, 100); - set_author(5, 1, 100); - // 1. ensure delegators are paid for 2 rounds after they leave - assert_noop!( - ParachainStaking::schedule_leave_delegators(Origin::signed(66)), - Error::::DelegatorDNE - ); - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 6 - ))); - // fast forward to block in which delegator 6 exit executes - roll_to(25); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(6), - 6, - 10 - )); - roll_to(30); - let mut new2 = vec![ - Event::DelegatorExitScheduled(4, 6, 6), - Event::ReservedForParachainBond(11, 16), - Event::CollatorChosen(5, 1, 50), - Event::CollatorChosen(5, 2, 40), - Event::CollatorChosen(5, 3, 20), - Event::CollatorChosen(5, 4, 20), - Event::CollatorChosen(5, 5, 10), - Event::NewRound(20, 5, 5, 140), - Event::Rewarded(1, 21), - Event::Rewarded(6, 5), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - Event::ReservedForParachainBond(11, 16), - Event::CollatorChosen(6, 1, 50), - Event::CollatorChosen(6, 2, 40), - Event::CollatorChosen(6, 3, 20), - Event::CollatorChosen(6, 4, 20), - Event::CollatorChosen(6, 5, 10), - Event::NewRound(25, 6, 5, 140), - Event::Rewarded(1, 22), - Event::Rewarded(6, 6), - Event::Rewarded(7, 6), - Event::Rewarded(10, 6), - Event::DelegatorLeftCandidate(6, 1, 10, 40), - Event::DelegatorLeft(6, 10), - Event::ReservedForParachainBond(11, 17), - Event::CollatorChosen(7, 1, 40), - Event::CollatorChosen(7, 2, 40), - Event::CollatorChosen(7, 3, 20), - Event::CollatorChosen(7, 4, 20), - Event::CollatorChosen(7, 5, 10), - Event::NewRound(30, 7, 5, 130), - Event::Rewarded(1, 24), - Event::Rewarded(6, 6), - Event::Rewarded(7, 6), - Event::Rewarded(10, 6), - ]; - expected.append(&mut new2); - assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 65); - assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( - Origin::root(), - Percent::from_percent(50) - )); - // 6 won't be paid for this round because they left already - set_author(6, 1, 100); - roll_to(35); - // keep paying 6 - let mut new3 = vec![ - Event::ParachainBondReservePercentSet( - Percent::from_percent(30), - Percent::from_percent(50), - ), - Event::ReservedForParachainBond(11, 30), - Event::CollatorChosen(8, 1, 40), - Event::CollatorChosen(8, 2, 40), - Event::CollatorChosen(8, 3, 20), - Event::CollatorChosen(8, 4, 20), - Event::CollatorChosen(8, 5, 10), - Event::NewRound(35, 8, 5, 130), - Event::Rewarded(1, 20), - Event::Rewarded(6, 4), - Event::Rewarded(7, 4), - Event::Rewarded(10, 4), - ]; - expected.append(&mut new3); - assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 95); - set_author(7, 1, 100); - roll_to(40); - // no more paying 6 - let mut new4 = vec![ - Event::ReservedForParachainBond(11, 32), - Event::CollatorChosen(9, 1, 40), - Event::CollatorChosen(9, 2, 40), - Event::CollatorChosen(9, 3, 20), - Event::CollatorChosen(9, 4, 20), - Event::CollatorChosen(9, 5, 10), - Event::NewRound(40, 9, 5, 130), - Event::Rewarded(1, 22), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - ]; - expected.append(&mut new4); - assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 127); - set_author(8, 1, 100); - assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); - roll_to(45); - // new delegation is not rewarded yet - let mut new5 = vec![ - Event::Delegation(8, 10, 1, DelegatorAdded::AddedToTop { new_total: 50 }), - Event::ReservedForParachainBond(11, 33), - Event::CollatorChosen(10, 1, 50), - Event::CollatorChosen(10, 2, 40), - Event::CollatorChosen(10, 3, 20), - Event::CollatorChosen(10, 4, 20), - Event::CollatorChosen(10, 5, 10), - Event::NewRound(45, 10, 5, 140), - Event::Rewarded(1, 23), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - ]; - expected.append(&mut new5); - assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 160); - set_author(9, 1, 100); - set_author(10, 1, 100); - roll_to(50); - // new delegation is still not rewarded yet - let mut new6 = vec![ - Event::ReservedForParachainBond(11, 35), - Event::CollatorChosen(11, 1, 50), - Event::CollatorChosen(11, 2, 40), - Event::CollatorChosen(11, 3, 20), - Event::CollatorChosen(11, 4, 20), - Event::CollatorChosen(11, 5, 10), - Event::NewRound(50, 11, 5, 140), - Event::Rewarded(1, 24), - Event::Rewarded(7, 5), - Event::Rewarded(10, 5), - ]; - expected.append(&mut new6); - assert_eq_events!(expected.clone()); - assert_eq!(Balances::free_balance(&11), 195); - roll_to(55); - // new delegation is rewarded, 2 rounds after joining (`RewardPaymentDelay` is 2) - let mut new7 = vec![ - Event::ReservedForParachainBond(11, 37), - Event::CollatorChosen(12, 1, 50), - Event::CollatorChosen(12, 2, 40), - Event::CollatorChosen(12, 3, 20), - Event::CollatorChosen(12, 4, 20), - Event::CollatorChosen(12, 5, 10), - Event::NewRound(55, 12, 5, 140), - Event::Rewarded(1, 24), - Event::Rewarded(7, 4), - Event::Rewarded(10, 4), - Event::Rewarded(8, 4), - ]; - expected.append(&mut new7); - assert_eq_events!(expected); - assert_eq!(Balances::free_balance(&11), 232); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + (11, 1), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + assert_eq!(Balances::free_balance(&11), 1); + // set parachain bond account so DefaultParachainBondReservePercent = 30% of inflation + // is allocated to this account hereafter + assert_ok!(ParachainStaking::set_parachain_bond_account( + Origin::root(), + 11 + )); + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::ParachainBondAccountSet(0, 11), + Event::CollatorChosen(2, 1, 50), + Event::CollatorChosen(2, 2, 40), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::CollatorChosen(2, 5, 10), + Event::NewRound(5, 2, 5, 140), + ]; + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 1); + // ~ set block author as 1 for all blocks this round + set_author(2, 1, 100); + roll_to(16); + // distribute total issuance to collator 1 and its delegators 6, 7, 19 + let mut new = vec![ + Event::CollatorChosen(3, 1, 50), + Event::CollatorChosen(3, 2, 40), + Event::CollatorChosen(3, 3, 20), + Event::CollatorChosen(3, 4, 20), + Event::CollatorChosen(3, 5, 10), + Event::NewRound(10, 3, 5, 140), + Event::ReservedForParachainBond(11, 15), + Event::CollatorChosen(4, 1, 50), + Event::CollatorChosen(4, 2, 40), + Event::CollatorChosen(4, 3, 20), + Event::CollatorChosen(4, 4, 20), + Event::CollatorChosen(4, 5, 10), + Event::NewRound(15, 4, 5, 140), + Event::Rewarded(1, 20), + Event::Rewarded(6, 5), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 16); + // ~ set block author as 1 for all blocks this round + set_author(3, 1, 100); + set_author(4, 1, 100); + set_author(5, 1, 100); + // 1. ensure delegators are paid for 2 rounds after they leave + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(66)), + Error::::DelegatorDNE + ); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 6 + ))); + // fast forward to block in which delegator 6 exit executes + roll_to(25); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(6), + 6, + 10 + )); + roll_to(30); + let mut new2 = vec![ + Event::DelegatorExitScheduled(4, 6, 6), + Event::ReservedForParachainBond(11, 16), + Event::CollatorChosen(5, 1, 50), + Event::CollatorChosen(5, 2, 40), + Event::CollatorChosen(5, 3, 20), + Event::CollatorChosen(5, 4, 20), + Event::CollatorChosen(5, 5, 10), + Event::NewRound(20, 5, 5, 140), + Event::Rewarded(1, 21), + Event::Rewarded(6, 5), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + Event::ReservedForParachainBond(11, 16), + Event::CollatorChosen(6, 1, 50), + Event::CollatorChosen(6, 2, 40), + Event::CollatorChosen(6, 3, 20), + Event::CollatorChosen(6, 4, 20), + Event::CollatorChosen(6, 5, 10), + Event::NewRound(25, 6, 5, 140), + Event::Rewarded(1, 22), + Event::Rewarded(6, 6), + Event::Rewarded(7, 6), + Event::Rewarded(10, 6), + Event::DelegatorLeftCandidate(6, 1, 10, 40), + Event::DelegatorLeft(6, 10), + Event::ReservedForParachainBond(11, 17), + Event::CollatorChosen(7, 1, 40), + Event::CollatorChosen(7, 2, 40), + Event::CollatorChosen(7, 3, 20), + Event::CollatorChosen(7, 4, 20), + Event::CollatorChosen(7, 5, 10), + Event::NewRound(30, 7, 5, 130), + Event::Rewarded(1, 24), + Event::Rewarded(6, 6), + Event::Rewarded(7, 6), + Event::Rewarded(10, 6), + ]; + expected.append(&mut new2); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 65); + assert_ok!(ParachainStaking::set_parachain_bond_reserve_percent( + Origin::root(), + Percent::from_percent(50) + )); + // 6 won't be paid for this round because they left already + set_author(6, 1, 100); + roll_to(35); + // keep paying 6 + let mut new3 = vec![ + Event::ParachainBondReservePercentSet( + Percent::from_percent(30), + Percent::from_percent(50), + ), + Event::ReservedForParachainBond(11, 30), + Event::CollatorChosen(8, 1, 40), + Event::CollatorChosen(8, 2, 40), + Event::CollatorChosen(8, 3, 20), + Event::CollatorChosen(8, 4, 20), + Event::CollatorChosen(8, 5, 10), + Event::NewRound(35, 8, 5, 130), + Event::Rewarded(1, 20), + Event::Rewarded(6, 4), + Event::Rewarded(7, 4), + Event::Rewarded(10, 4), + ]; + expected.append(&mut new3); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 95); + set_author(7, 1, 100); + roll_to(40); + // no more paying 6 + let mut new4 = vec![ + Event::ReservedForParachainBond(11, 32), + Event::CollatorChosen(9, 1, 40), + Event::CollatorChosen(9, 2, 40), + Event::CollatorChosen(9, 3, 20), + Event::CollatorChosen(9, 4, 20), + Event::CollatorChosen(9, 5, 10), + Event::NewRound(40, 9, 5, 130), + Event::Rewarded(1, 22), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new4); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 127); + set_author(8, 1, 100); + assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); + roll_to(45); + // new delegation is not rewarded yet + let mut new5 = vec![ + Event::Delegation(8, 10, 1, DelegatorAdded::AddedToTop { new_total: 50 }), + Event::ReservedForParachainBond(11, 33), + Event::CollatorChosen(10, 1, 50), + Event::CollatorChosen(10, 2, 40), + Event::CollatorChosen(10, 3, 20), + Event::CollatorChosen(10, 4, 20), + Event::CollatorChosen(10, 5, 10), + Event::NewRound(45, 10, 5, 140), + Event::Rewarded(1, 23), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new5); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 160); + set_author(9, 1, 100); + set_author(10, 1, 100); + roll_to(50); + // new delegation is still not rewarded yet + let mut new6 = vec![ + Event::ReservedForParachainBond(11, 35), + Event::CollatorChosen(11, 1, 50), + Event::CollatorChosen(11, 2, 40), + Event::CollatorChosen(11, 3, 20), + Event::CollatorChosen(11, 4, 20), + Event::CollatorChosen(11, 5, 10), + Event::NewRound(50, 11, 5, 140), + Event::Rewarded(1, 24), + Event::Rewarded(7, 5), + Event::Rewarded(10, 5), + ]; + expected.append(&mut new6); + assert_eq_events!(expected.clone()); + assert_eq!(Balances::free_balance(&11), 195); + roll_to(55); + // new delegation is rewarded, 2 rounds after joining (`RewardPaymentDelay` is 2) + let mut new7 = vec![ + Event::ReservedForParachainBond(11, 37), + Event::CollatorChosen(12, 1, 50), + Event::CollatorChosen(12, 2, 40), + Event::CollatorChosen(12, 3, 20), + Event::CollatorChosen(12, 4, 20), + Event::CollatorChosen(12, 5, 10), + Event::NewRound(55, 12, 5, 140), + Event::Rewarded(1, 24), + Event::Rewarded(7, 4), + Event::Rewarded(10, 4), + Event::Rewarded(8, 4), + ]; + expected.append(&mut new7); + assert_eq_events!(expected); + assert_eq!(Balances::free_balance(&11), 232); + }); } #[test] fn paid_collator_commission_matches_config() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - ]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![(2, 1, 10), (3, 1, 10)]) - .build() - .execute_with(|| { - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 40), - Event::NewRound(5, 2, 1, 40), - ]; - assert_eq_events!(expected.clone()); - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(4), - 20u128, - 100u32 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::JoinedCollatorCandidates(4, 20u128, 60u128,) - )); - roll_to(9); - assert_ok!(ParachainStaking::delegate(Origin::signed(5), 4, 10, 10, 10)); - assert_ok!(ParachainStaking::delegate(Origin::signed(6), 4, 10, 10, 10)); - roll_to(11); - let mut new = vec![ - Event::JoinedCollatorCandidates(4, 20, 60), - Event::Delegation(5, 10, 4, DelegatorAdded::AddedToTop { new_total: 30 }), - Event::Delegation(6, 10, 4, DelegatorAdded::AddedToTop { new_total: 40 }), - Event::CollatorChosen(3, 1, 40), - Event::CollatorChosen(3, 4, 40), - Event::NewRound(10, 3, 2, 80), - ]; - expected.append(&mut new); - assert_eq_events!(expected.clone()); - // only reward author with id 4 - set_author(3, 4, 100); - roll_to(21); - // 20% of 10 is commission + due_portion (0) = 2 + 4 = 6 - // all delegator payouts are 10-2 = 8 * stake_pct - let mut new2 = vec![ - Event::CollatorChosen(4, 1, 40), - Event::CollatorChosen(4, 4, 40), - Event::NewRound(15, 4, 2, 80), - Event::CollatorChosen(5, 1, 40), - Event::CollatorChosen(5, 4, 40), - Event::NewRound(20, 5, 2, 80), - Event::Rewarded(4, 18), - Event::Rewarded(5, 6), - Event::Rewarded(6, 6), - ]; - expected.append(&mut new2); - assert_eq_events!(expected); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + ]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![(2, 1, 10), (3, 1, 10)]) + .build() + .execute_with(|| { + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 40), + Event::NewRound(5, 2, 1, 40), + ]; + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(4), + 20u128, + 100u32 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::JoinedCollatorCandidates(4, 20u128, 60u128,) + )); + roll_to(9); + assert_ok!(ParachainStaking::delegate(Origin::signed(5), 4, 10, 10, 10)); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 4, 10, 10, 10)); + roll_to(11); + let mut new = vec![ + Event::JoinedCollatorCandidates(4, 20, 60), + Event::Delegation(5, 10, 4, DelegatorAdded::AddedToTop { new_total: 30 }), + Event::Delegation(6, 10, 4, DelegatorAdded::AddedToTop { new_total: 40 }), + Event::CollatorChosen(3, 1, 40), + Event::CollatorChosen(3, 4, 40), + Event::NewRound(10, 3, 2, 80), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + // only reward author with id 4 + set_author(3, 4, 100); + roll_to(21); + // 20% of 10 is commission + due_portion (0) = 2 + 4 = 6 + // all delegator payouts are 10-2 = 8 * stake_pct + let mut new2 = vec![ + Event::CollatorChosen(4, 1, 40), + Event::CollatorChosen(4, 4, 40), + Event::NewRound(15, 4, 2, 80), + Event::CollatorChosen(5, 1, 40), + Event::CollatorChosen(5, 4, 40), + Event::NewRound(20, 5, 2, 80), + Event::Rewarded(4, 18), + Event::Rewarded(5, 6), + Event::Rewarded(6, 6), + ]; + expected.append(&mut new2); + assert_eq_events!(expected); + }); } #[test] fn collator_exit_executes_after_delay() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 300), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 9), - (9, 4), - ]) - .with_candidates(vec![(1, 500), (2, 200)]) - .with_delegations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) - .build() - .execute_with(|| { - roll_to(11); - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(2), - 2 - )); - let info = ParachainStaking::candidate_info(&2).unwrap(); - assert_eq!(info.status, CollatorStatus::Leaving(5)); - roll_to(21); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(2), - 2, - 2 - )); - // we must exclude leaving collators from rewards while - // holding them retroactively accountable for previous faults - // (within the last T::SlashingWindow blocks) - let expected = vec![ - Event::CollatorChosen(2, 1, 700), - Event::CollatorChosen(2, 2, 400), - Event::NewRound(5, 2, 2, 1100), - Event::CollatorChosen(3, 1, 700), - Event::CollatorChosen(3, 2, 400), - Event::NewRound(10, 3, 2, 1100), - Event::CandidateScheduledExit(3, 2, 5), - Event::CollatorChosen(4, 1, 700), - Event::NewRound(15, 4, 1, 700), - Event::CollatorChosen(5, 1, 700), - Event::NewRound(20, 5, 1, 700), - Event::CandidateLeft(2, 400, 700), - ]; - assert_eq_events!(expected); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 300), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 9), + (9, 4), + ]) + .with_candidates(vec![(1, 500), (2, 200)]) + .with_delegations(vec![(3, 1, 100), (4, 1, 100), (5, 2, 100), (6, 2, 100)]) + .build() + .execute_with(|| { + roll_to(11); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(2), + 2 + )); + let info = ParachainStaking::candidate_info(&2).unwrap(); + assert_eq!(info.status, CollatorStatus::Leaving(5)); + roll_to(21); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 2, + 2 + )); + // we must exclude leaving collators from rewards while + // holding them retroactively accountable for previous faults + // (within the last T::SlashingWindow blocks) + let expected = vec![ + Event::CollatorChosen(2, 1, 700), + Event::CollatorChosen(2, 2, 400), + Event::NewRound(5, 2, 2, 1100), + Event::CollatorChosen(3, 1, 700), + Event::CollatorChosen(3, 2, 400), + Event::NewRound(10, 3, 2, 1100), + Event::CandidateScheduledExit(3, 2, 5), + Event::CollatorChosen(4, 1, 700), + Event::NewRound(15, 4, 1, 700), + Event::CollatorChosen(5, 1, 700), + Event::NewRound(20, 5, 1, 700), + Event::CandidateLeft(2, 400, 700), + ]; + assert_eq_events!(expected); + }); } #[test] fn collator_selection_chooses_top_candidates() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 1000), - (3, 1000), - (4, 1000), - (5, 1000), - (6, 1000), - (7, 33), - (8, 33), - (9, 33), - ]) - .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) - .build() - .execute_with(|| { - roll_to(8); - // should choose top TotalSelectedCandidates (5), in order - let expected = vec![ - Event::CollatorChosen(2, 1, 100), - Event::CollatorChosen(2, 2, 90), - Event::CollatorChosen(2, 3, 80), - Event::CollatorChosen(2, 4, 70), - Event::CollatorChosen(2, 5, 60), - Event::NewRound(5, 2, 5, 400), - ]; - assert_eq_events!(expected.clone()); - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(6), - 6 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( - 2, 6, 4 - ))); - roll_to(21); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(6), - 6, - 0 - )); - assert_ok!(ParachainStaking::join_candidates( - Origin::signed(6), - 69u128, - 100u32 - )); - assert_last_event!(MetaEvent::ParachainStaking( - Event::JoinedCollatorCandidates(6, 69u128, 469u128,) - )); - roll_to(27); - // should choose top TotalSelectedCandidates (5), in order - let expected = vec![ - Event::CollatorChosen(2, 1, 100), - Event::CollatorChosen(2, 2, 90), - Event::CollatorChosen(2, 3, 80), - Event::CollatorChosen(2, 4, 70), - Event::CollatorChosen(2, 5, 60), - Event::NewRound(5, 2, 5, 400), - Event::CandidateScheduledExit(2, 6, 4), - Event::CollatorChosen(3, 1, 100), - Event::CollatorChosen(3, 2, 90), - Event::CollatorChosen(3, 3, 80), - Event::CollatorChosen(3, 4, 70), - Event::CollatorChosen(3, 5, 60), - Event::NewRound(10, 3, 5, 400), - Event::CollatorChosen(4, 1, 100), - Event::CollatorChosen(4, 2, 90), - Event::CollatorChosen(4, 3, 80), - Event::CollatorChosen(4, 4, 70), - Event::CollatorChosen(4, 5, 60), - Event::NewRound(15, 4, 5, 400), - Event::CollatorChosen(5, 1, 100), - Event::CollatorChosen(5, 2, 90), - Event::CollatorChosen(5, 3, 80), - Event::CollatorChosen(5, 4, 70), - Event::CollatorChosen(5, 5, 60), - Event::NewRound(20, 5, 5, 400), - Event::CandidateLeft(6, 50, 400), - Event::JoinedCollatorCandidates(6, 69, 469), - Event::CollatorChosen(6, 1, 100), - Event::CollatorChosen(6, 2, 90), - Event::CollatorChosen(6, 3, 80), - Event::CollatorChosen(6, 4, 70), - Event::CollatorChosen(6, 6, 69), - Event::NewRound(25, 6, 5, 409), - ]; - assert_eq_events!(expected); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), + (6, 1000), + (7, 33), + (8, 33), + (9, 33), + ]) + .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) + .build() + .execute_with(|| { + roll_to(8); + // should choose top TotalSelectedCandidates (5), in order + let expected = vec![ + Event::CollatorChosen(2, 1, 100), + Event::CollatorChosen(2, 2, 90), + Event::CollatorChosen(2, 3, 80), + Event::CollatorChosen(2, 4, 70), + Event::CollatorChosen(2, 5, 60), + Event::NewRound(5, 2, 5, 400), + ]; + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(6), + 6 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( + 2, 6, 4 + ))); + roll_to(21); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(6), + 6, + 0 + )); + assert_ok!(ParachainStaking::join_candidates( + Origin::signed(6), + 69u128, + 100u32 + )); + assert_last_event!(MetaEvent::ParachainStaking( + Event::JoinedCollatorCandidates(6, 69u128, 469u128,) + )); + roll_to(27); + // should choose top TotalSelectedCandidates (5), in order + let expected = vec![ + Event::CollatorChosen(2, 1, 100), + Event::CollatorChosen(2, 2, 90), + Event::CollatorChosen(2, 3, 80), + Event::CollatorChosen(2, 4, 70), + Event::CollatorChosen(2, 5, 60), + Event::NewRound(5, 2, 5, 400), + Event::CandidateScheduledExit(2, 6, 4), + Event::CollatorChosen(3, 1, 100), + Event::CollatorChosen(3, 2, 90), + Event::CollatorChosen(3, 3, 80), + Event::CollatorChosen(3, 4, 70), + Event::CollatorChosen(3, 5, 60), + Event::NewRound(10, 3, 5, 400), + Event::CollatorChosen(4, 1, 100), + Event::CollatorChosen(4, 2, 90), + Event::CollatorChosen(4, 3, 80), + Event::CollatorChosen(4, 4, 70), + Event::CollatorChosen(4, 5, 60), + Event::NewRound(15, 4, 5, 400), + Event::CollatorChosen(5, 1, 100), + Event::CollatorChosen(5, 2, 90), + Event::CollatorChosen(5, 3, 80), + Event::CollatorChosen(5, 4, 70), + Event::CollatorChosen(5, 5, 60), + Event::NewRound(20, 5, 5, 400), + Event::CandidateLeft(6, 50, 400), + Event::JoinedCollatorCandidates(6, 69, 469), + Event::CollatorChosen(6, 1, 100), + Event::CollatorChosen(6, 2, 90), + Event::CollatorChosen(6, 3, 80), + Event::CollatorChosen(6, 4, 70), + Event::CollatorChosen(6, 6, 69), + Event::NewRound(25, 6, 5, 409), + ]; + assert_eq_events!(expected); + }); } #[test] fn payout_distribution_to_solo_collators() { - ExtBuilder::default() - .with_balances(vec![ - (1, 1000), - (2, 1000), - (3, 1000), - (4, 1000), - (5, 1000), - (6, 1000), - (7, 33), - (8, 33), - (9, 33), - ]) - .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) - .build() - .execute_with(|| { - roll_to(8); - // should choose top TotalCandidatesSelected (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 100), - Event::CollatorChosen(2, 2, 90), - Event::CollatorChosen(2, 3, 80), - Event::CollatorChosen(2, 4, 70), - Event::CollatorChosen(2, 5, 60), - Event::NewRound(5, 2, 5, 400), - ]; - assert_eq_events!(expected.clone()); - // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); - roll_to(16); - // pay total issuance to 1 - let mut new = vec![ - Event::CollatorChosen(3, 1, 100), - Event::CollatorChosen(3, 2, 90), - Event::CollatorChosen(3, 3, 80), - Event::CollatorChosen(3, 4, 70), - Event::CollatorChosen(3, 5, 60), - Event::NewRound(10, 3, 5, 400), - Event::CollatorChosen(4, 1, 100), - Event::CollatorChosen(4, 2, 90), - Event::CollatorChosen(4, 3, 80), - Event::CollatorChosen(4, 4, 70), - Event::CollatorChosen(4, 5, 60), - Event::NewRound(15, 4, 5, 400), - Event::Rewarded(1, 305), - ]; - expected.append(&mut new); - assert_eq_events!(expected.clone()); - // ~ set block author as 1 for 3 blocks this round - set_author(4, 1, 60); - // ~ set block author as 2 for 2 blocks this round - set_author(4, 2, 40); - roll_to(26); - // pay 60% total issuance to 1 and 40% total issuance to 2 - let mut new1 = vec![ - Event::CollatorChosen(5, 1, 100), - Event::CollatorChosen(5, 2, 90), - Event::CollatorChosen(5, 3, 80), - Event::CollatorChosen(5, 4, 70), - Event::CollatorChosen(5, 5, 60), - Event::NewRound(20, 5, 5, 400), - Event::CollatorChosen(6, 1, 100), - Event::CollatorChosen(6, 2, 90), - Event::CollatorChosen(6, 3, 80), - Event::CollatorChosen(6, 4, 70), - Event::CollatorChosen(6, 5, 60), - Event::NewRound(25, 6, 5, 400), - Event::Rewarded(1, 192), - Event::Rewarded(2, 128), - ]; - expected.append(&mut new1); - assert_eq_events!(expected.clone()); - // ~ each collator produces 1 block this round - set_author(6, 1, 20); - set_author(6, 2, 20); - set_author(6, 3, 20); - set_author(6, 4, 20); - set_author(6, 5, 20); - roll_to(39); - // pay 20% issuance for all collators - let mut new2 = vec![ - Event::CollatorChosen(7, 1, 100), - Event::CollatorChosen(7, 2, 90), - Event::CollatorChosen(7, 3, 80), - Event::CollatorChosen(7, 4, 70), - Event::CollatorChosen(7, 5, 60), - Event::NewRound(30, 7, 5, 400), - Event::CollatorChosen(8, 1, 100), - Event::CollatorChosen(8, 2, 90), - Event::CollatorChosen(8, 3, 80), - Event::CollatorChosen(8, 4, 70), - Event::CollatorChosen(8, 5, 60), - Event::NewRound(35, 8, 5, 400), - Event::Rewarded(5, 67), - Event::Rewarded(3, 67), - Event::Rewarded(4, 67), - Event::Rewarded(1, 67), - Event::Rewarded(2, 67), - ]; - expected.append(&mut new2); - assert_eq_events!(expected); - // check that distributing rewards clears awarded pts - assert!(ParachainStaking::awarded_pts(1, 1).is_zero()); - assert!(ParachainStaking::awarded_pts(4, 1).is_zero()); - assert!(ParachainStaking::awarded_pts(4, 2).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 1).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 2).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 3).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 4).is_zero()); - assert!(ParachainStaking::awarded_pts(6, 5).is_zero()); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), + (6, 1000), + (7, 33), + (8, 33), + (9, 33), + ]) + .with_candidates(vec![(1, 100), (2, 90), (3, 80), (4, 70), (5, 60), (6, 50)]) + .build() + .execute_with(|| { + roll_to(8); + // should choose top TotalCandidatesSelected (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 100), + Event::CollatorChosen(2, 2, 90), + Event::CollatorChosen(2, 3, 80), + Event::CollatorChosen(2, 4, 70), + Event::CollatorChosen(2, 5, 60), + Event::NewRound(5, 2, 5, 400), + ]; + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for all blocks this round + set_author(2, 1, 100); + roll_to(16); + // pay total issuance to 1 + let mut new = vec![ + Event::CollatorChosen(3, 1, 100), + Event::CollatorChosen(3, 2, 90), + Event::CollatorChosen(3, 3, 80), + Event::CollatorChosen(3, 4, 70), + Event::CollatorChosen(3, 5, 60), + Event::NewRound(10, 3, 5, 400), + Event::CollatorChosen(4, 1, 100), + Event::CollatorChosen(4, 2, 90), + Event::CollatorChosen(4, 3, 80), + Event::CollatorChosen(4, 4, 70), + Event::CollatorChosen(4, 5, 60), + Event::NewRound(15, 4, 5, 400), + Event::Rewarded(1, 305), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for 3 blocks this round + set_author(4, 1, 60); + // ~ set block author as 2 for 2 blocks this round + set_author(4, 2, 40); + roll_to(26); + // pay 60% total issuance to 1 and 40% total issuance to 2 + let mut new1 = vec![ + Event::CollatorChosen(5, 1, 100), + Event::CollatorChosen(5, 2, 90), + Event::CollatorChosen(5, 3, 80), + Event::CollatorChosen(5, 4, 70), + Event::CollatorChosen(5, 5, 60), + Event::NewRound(20, 5, 5, 400), + Event::CollatorChosen(6, 1, 100), + Event::CollatorChosen(6, 2, 90), + Event::CollatorChosen(6, 3, 80), + Event::CollatorChosen(6, 4, 70), + Event::CollatorChosen(6, 5, 60), + Event::NewRound(25, 6, 5, 400), + Event::Rewarded(1, 192), + Event::Rewarded(2, 128), + ]; + expected.append(&mut new1); + assert_eq_events!(expected.clone()); + // ~ each collator produces 1 block this round + set_author(6, 1, 20); + set_author(6, 2, 20); + set_author(6, 3, 20); + set_author(6, 4, 20); + set_author(6, 5, 20); + roll_to(39); + // pay 20% issuance for all collators + let mut new2 = vec![ + Event::CollatorChosen(7, 1, 100), + Event::CollatorChosen(7, 2, 90), + Event::CollatorChosen(7, 3, 80), + Event::CollatorChosen(7, 4, 70), + Event::CollatorChosen(7, 5, 60), + Event::NewRound(30, 7, 5, 400), + Event::CollatorChosen(8, 1, 100), + Event::CollatorChosen(8, 2, 90), + Event::CollatorChosen(8, 3, 80), + Event::CollatorChosen(8, 4, 70), + Event::CollatorChosen(8, 5, 60), + Event::NewRound(35, 8, 5, 400), + Event::Rewarded(5, 67), + Event::Rewarded(3, 67), + Event::Rewarded(4, 67), + Event::Rewarded(1, 67), + Event::Rewarded(2, 67), + ]; + expected.append(&mut new2); + assert_eq_events!(expected); + // check that distributing rewards clears awarded pts + assert!(ParachainStaking::awarded_pts(1, 1).is_zero()); + assert!(ParachainStaking::awarded_pts(4, 1).is_zero()); + assert!(ParachainStaking::awarded_pts(4, 2).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 1).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 2).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 3).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 4).is_zero()); + assert!(ParachainStaking::awarded_pts(6, 5).is_zero()); + }); } #[test] fn multiple_delegations() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_delegations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 50), - Event::CollatorChosen(2, 2, 40), - Event::CollatorChosen(2, 3, 20), - Event::CollatorChosen(2, 4, 20), - Event::CollatorChosen(2, 5, 10), - Event::NewRound(5, 2, 5, 140), - ]; - assert_eq_events!(expected.clone()); - assert_ok!(ParachainStaking::delegate(Origin::signed(6), 2, 10, 10, 10)); - assert_ok!(ParachainStaking::delegate(Origin::signed(6), 3, 10, 10, 10)); - assert_ok!(ParachainStaking::delegate(Origin::signed(6), 4, 10, 10, 10)); - roll_to(16); - let mut new = vec![ - Event::Delegation(6, 10, 2, DelegatorAdded::AddedToTop { new_total: 50 }), - Event::Delegation(6, 10, 3, DelegatorAdded::AddedToTop { new_total: 30 }), - Event::Delegation(6, 10, 4, DelegatorAdded::AddedToTop { new_total: 30 }), - Event::CollatorChosen(3, 1, 50), - Event::CollatorChosen(3, 2, 50), - Event::CollatorChosen(3, 3, 30), - Event::CollatorChosen(3, 4, 30), - Event::CollatorChosen(3, 5, 10), - Event::NewRound(10, 3, 5, 170), - Event::CollatorChosen(4, 1, 50), - Event::CollatorChosen(4, 2, 50), - Event::CollatorChosen(4, 3, 30), - Event::CollatorChosen(4, 4, 30), - Event::CollatorChosen(4, 5, 10), - Event::NewRound(15, 4, 5, 170), - ]; - expected.append(&mut new); - assert_eq_events!(expected.clone()); - roll_to(21); - assert_ok!(ParachainStaking::delegate(Origin::signed(7), 2, 80, 10, 10)); - assert_ok!(ParachainStaking::delegate( - Origin::signed(10), - 2, - 10, - 10, - 10 - ),); - roll_to(26); - let mut new2 = vec![ - Event::CollatorChosen(5, 1, 50), - Event::CollatorChosen(5, 2, 50), - Event::CollatorChosen(5, 3, 30), - Event::CollatorChosen(5, 4, 30), - Event::CollatorChosen(5, 5, 10), - Event::NewRound(20, 5, 5, 170), - Event::Delegation(7, 80, 2, DelegatorAdded::AddedToTop { new_total: 130 }), - Event::Delegation(10, 10, 2, DelegatorAdded::AddedToBottom), - Event::CollatorChosen(6, 1, 50), - Event::CollatorChosen(6, 2, 130), - Event::CollatorChosen(6, 3, 30), - Event::CollatorChosen(6, 4, 30), - Event::CollatorChosen(6, 5, 10), - Event::NewRound(25, 6, 5, 250), - ]; - expected.append(&mut new2); - assert_eq_events!(expected.clone()); - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(2), - 5 - )); - assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( - 6, 2, 8 - ))); - roll_to(31); - let mut new3 = vec![ - Event::CandidateScheduledExit(6, 2, 8), - Event::CollatorChosen(7, 1, 50), - Event::CollatorChosen(7, 3, 30), - Event::CollatorChosen(7, 4, 30), - Event::CollatorChosen(7, 5, 10), - Event::NewRound(30, 7, 4, 120), - ]; - expected.append(&mut new3); - assert_eq_events!(expected); - // verify that delegations are removed after collator leaves, not before - assert_eq!(ParachainStaking::delegator_state(7).unwrap().total, 90); - assert_eq!( - ParachainStaking::delegator_state(7) - .unwrap() - .delegations - .0 - .len(), - 2usize - ); - assert_eq!(ParachainStaking::delegator_state(6).unwrap().total, 40); - assert_eq!( - ParachainStaking::delegator_state(6) - .unwrap() - .delegations - .0 - .len(), - 4usize - ); - assert_eq!(Balances::reserved_balance(&6), 40); - assert_eq!(Balances::reserved_balance(&7), 90); - assert_eq!(Balances::free_balance(&6), 60); - assert_eq!(Balances::free_balance(&7), 10); - roll_to(40); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(2), - 2, - 5 - )); - assert_eq!(ParachainStaking::delegator_state(7).unwrap().total, 10); - assert_eq!(ParachainStaking::delegator_state(6).unwrap().total, 30); - assert_eq!( - ParachainStaking::delegator_state(7) - .unwrap() - .delegations - .0 - .len(), - 1usize - ); - assert_eq!( - ParachainStaking::delegator_state(6) - .unwrap() - .delegations - .0 - .len(), - 3usize - ); - assert_eq!(Balances::reserved_balance(&6), 30); - assert_eq!(Balances::reserved_balance(&7), 10); - assert_eq!(Balances::free_balance(&6), 70); - assert_eq!(Balances::free_balance(&7), 90); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 50), + Event::CollatorChosen(2, 2, 40), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::CollatorChosen(2, 5, 10), + Event::NewRound(5, 2, 5, 140), + ]; + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 2, 10, 10, 10)); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 3, 10, 10, 10)); + assert_ok!(ParachainStaking::delegate(Origin::signed(6), 4, 10, 10, 10)); + roll_to(16); + let mut new = vec![ + Event::Delegation(6, 10, 2, DelegatorAdded::AddedToTop { new_total: 50 }), + Event::Delegation(6, 10, 3, DelegatorAdded::AddedToTop { new_total: 30 }), + Event::Delegation(6, 10, 4, DelegatorAdded::AddedToTop { new_total: 30 }), + Event::CollatorChosen(3, 1, 50), + Event::CollatorChosen(3, 2, 50), + Event::CollatorChosen(3, 3, 30), + Event::CollatorChosen(3, 4, 30), + Event::CollatorChosen(3, 5, 10), + Event::NewRound(10, 3, 5, 170), + Event::CollatorChosen(4, 1, 50), + Event::CollatorChosen(4, 2, 50), + Event::CollatorChosen(4, 3, 30), + Event::CollatorChosen(4, 4, 30), + Event::CollatorChosen(4, 5, 10), + Event::NewRound(15, 4, 5, 170), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + roll_to(21); + assert_ok!(ParachainStaking::delegate(Origin::signed(7), 2, 80, 10, 10)); + assert_ok!(ParachainStaking::delegate( + Origin::signed(10), + 2, + 10, + 10, + 10 + ),); + roll_to(26); + let mut new2 = vec![ + Event::CollatorChosen(5, 1, 50), + Event::CollatorChosen(5, 2, 50), + Event::CollatorChosen(5, 3, 30), + Event::CollatorChosen(5, 4, 30), + Event::CollatorChosen(5, 5, 10), + Event::NewRound(20, 5, 5, 170), + Event::Delegation(7, 80, 2, DelegatorAdded::AddedToTop { new_total: 130 }), + Event::Delegation(10, 10, 2, DelegatorAdded::AddedToBottom), + Event::CollatorChosen(6, 1, 50), + Event::CollatorChosen(6, 2, 130), + Event::CollatorChosen(6, 3, 30), + Event::CollatorChosen(6, 4, 30), + Event::CollatorChosen(6, 5, 10), + Event::NewRound(25, 6, 5, 250), + ]; + expected.append(&mut new2); + assert_eq_events!(expected.clone()); + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(2), + 5 + )); + assert_last_event!(MetaEvent::ParachainStaking(Event::CandidateScheduledExit( + 6, 2, 8 + ))); + roll_to(31); + let mut new3 = vec![ + Event::CandidateScheduledExit(6, 2, 8), + Event::CollatorChosen(7, 1, 50), + Event::CollatorChosen(7, 3, 30), + Event::CollatorChosen(7, 4, 30), + Event::CollatorChosen(7, 5, 10), + Event::NewRound(30, 7, 4, 120), + ]; + expected.append(&mut new3); + assert_eq_events!(expected); + // verify that delegations are removed after collator leaves, not before + assert_eq!(ParachainStaking::delegator_state(7).unwrap().total, 90); + assert_eq!( + ParachainStaking::delegator_state(7) + .unwrap() + .delegations + .0 + .len(), + 2usize + ); + assert_eq!(ParachainStaking::delegator_state(6).unwrap().total, 40); + assert_eq!( + ParachainStaking::delegator_state(6) + .unwrap() + .delegations + .0 + .len(), + 4usize + ); + assert_eq!(Balances::reserved_balance(&6), 40); + assert_eq!(Balances::reserved_balance(&7), 90); + assert_eq!(Balances::free_balance(&6), 60); + assert_eq!(Balances::free_balance(&7), 10); + roll_to(40); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 2, + 5 + )); + assert_eq!(ParachainStaking::delegator_state(7).unwrap().total, 10); + assert_eq!(ParachainStaking::delegator_state(6).unwrap().total, 30); + assert_eq!( + ParachainStaking::delegator_state(7) + .unwrap() + .delegations + .0 + .len(), + 1usize + ); + assert_eq!( + ParachainStaking::delegator_state(6) + .unwrap() + .delegations + .0 + .len(), + 3usize + ); + assert_eq!(Balances::reserved_balance(&6), 30); + assert_eq!(Balances::reserved_balance(&7), 10); + assert_eq!(Balances::free_balance(&6), 70); + assert_eq!(Balances::free_balance(&7), 90); + }); } #[test] // The test verifies that the pending revoke request is removed by 2's exit so there is no dangling // revoke request after 2 exits fn execute_leave_candidate_removes_delegations() { - ExtBuilder::default() - .with_balances(vec![(1, 100), (2, 100), (3, 100), (4, 100)]) - .with_candidates(vec![(1, 20), (2, 20)]) - .with_delegations(vec![(3, 1, 10), (3, 2, 10), (4, 1, 10), (4, 2, 10)]) - .build() - .execute_with(|| { - // Verifies the revocation count is originally at 0 - assert_eq!( - ParachainStaking::delegator_state(3) - .unwrap() - .requests - .revocations_count, - 0 - ); - - assert_ok!(ParachainStaking::schedule_leave_candidates( - Origin::signed(2), - 2 - )); - assert_ok!(ParachainStaking::schedule_revoke_delegation( - Origin::signed(3), - 2 - )); - // Verifies the revocation count has been updated to 1 - assert_eq!( - ParachainStaking::delegator_state(3) - .unwrap() - .requests - .revocations_count, - 1 - ); - - roll_to(16); - assert_ok!(ParachainStaking::execute_leave_candidates( - Origin::signed(2), - 2, - 2 - )); - // Verifies the revocation count has been reduced to 0 - assert_eq!( - ParachainStaking::delegator_state(3) - .unwrap() - .requests - .revocations_count, - 0 - ); - }); + ExtBuilder::default() + .with_balances(vec![(1, 100), (2, 100), (3, 100), (4, 100)]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 10), (3, 2, 10), (4, 1, 10), (4, 2, 10)]) + .build() + .execute_with(|| { + // Verifies the revocation count is originally at 0 + assert_eq!( + ParachainStaking::delegator_state(3) + .unwrap() + .requests + .revocations_count, + 0 + ); + + assert_ok!(ParachainStaking::schedule_leave_candidates( + Origin::signed(2), + 2 + )); + assert_ok!(ParachainStaking::schedule_revoke_delegation( + Origin::signed(3), + 2 + )); + // Verifies the revocation count has been updated to 1 + assert_eq!( + ParachainStaking::delegator_state(3) + .unwrap() + .requests + .revocations_count, + 1 + ); + + roll_to(16); + assert_ok!(ParachainStaking::execute_leave_candidates( + Origin::signed(2), + 2, + 2 + )); + // Verifies the revocation count has been reduced to 0 + assert_eq!( + ParachainStaking::delegator_state(3) + .unwrap() + .requests + .revocations_count, + 0 + ); + }); } #[test] fn payouts_follow_delegation_changes() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) - .with_delegations(vec![ - (6, 1, 10), - (7, 1, 10), - (8, 2, 10), - (9, 2, 10), - (10, 1, 10), - ]) - .build() - .execute_with(|| { - roll_to(8); - // chooses top TotalSelectedCandidates (5), in order - let mut expected = vec![ - Event::CollatorChosen(2, 1, 50), - Event::CollatorChosen(2, 2, 40), - Event::CollatorChosen(2, 3, 20), - Event::CollatorChosen(2, 4, 20), - Event::CollatorChosen(2, 5, 10), - Event::NewRound(5, 2, 5, 140), - ]; - assert_eq_events!(expected.clone()); - // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); - roll_to(16); - // distribute total issuance to collator 1 and its delegators 6, 7, 19 - let mut new = vec![ - Event::CollatorChosen(3, 1, 50), - Event::CollatorChosen(3, 2, 40), - Event::CollatorChosen(3, 3, 20), - Event::CollatorChosen(3, 4, 20), - Event::CollatorChosen(3, 5, 10), - Event::NewRound(10, 3, 5, 140), - Event::CollatorChosen(4, 1, 50), - Event::CollatorChosen(4, 2, 40), - Event::CollatorChosen(4, 3, 20), - Event::CollatorChosen(4, 4, 20), - Event::CollatorChosen(4, 5, 10), - Event::NewRound(15, 4, 5, 140), - Event::Rewarded(1, 26), - Event::Rewarded(6, 8), - Event::Rewarded(7, 8), - Event::Rewarded(10, 8), - ]; - expected.append(&mut new); - assert_eq_events!(expected.clone()); - // ~ set block author as 1 for all blocks this round - set_author(3, 1, 100); - set_author(4, 1, 100); - set_author(5, 1, 100); - set_author(6, 1, 100); - // 1. ensure delegators are paid for 2 rounds after they leave - assert_noop!( - ParachainStaking::schedule_leave_delegators(Origin::signed(66)), - Error::::DelegatorDNE - ); - assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( - 6 - ))); - // fast forward to block in which delegator 6 exit executes - roll_to(25); - assert_ok!(ParachainStaking::execute_leave_delegators( - Origin::signed(6), - 6, - 10 - )); - // keep paying 6 (note: inflation is in terms of total issuance so that's why 1 is 21) - let mut new2 = vec![ - Event::DelegatorExitScheduled(4, 6, 6), - Event::CollatorChosen(5, 1, 50), - Event::CollatorChosen(5, 2, 40), - Event::CollatorChosen(5, 3, 20), - Event::CollatorChosen(5, 4, 20), - Event::CollatorChosen(5, 5, 10), - Event::NewRound(20, 5, 5, 140), - Event::Rewarded(1, 27), - Event::Rewarded(6, 8), - Event::Rewarded(7, 8), - Event::Rewarded(10, 8), - Event::CollatorChosen(6, 1, 50), - Event::CollatorChosen(6, 2, 40), - Event::CollatorChosen(6, 3, 20), - Event::CollatorChosen(6, 4, 20), - Event::CollatorChosen(6, 5, 10), - Event::NewRound(25, 6, 5, 140), - Event::Rewarded(1, 29), - Event::Rewarded(6, 9), - Event::Rewarded(7, 9), - Event::Rewarded(10, 9), - Event::DelegatorLeftCandidate(6, 1, 10, 40), - Event::DelegatorLeft(6, 10), - ]; - expected.append(&mut new2); - assert_eq_events!(expected.clone()); - // 6 won't be paid for this round because they left already - set_author(7, 1, 100); - roll_to(35); - // keep paying 6 - let mut new3 = vec![ - Event::CollatorChosen(7, 1, 40), - Event::CollatorChosen(7, 2, 40), - Event::CollatorChosen(7, 3, 20), - Event::CollatorChosen(7, 4, 20), - Event::CollatorChosen(7, 5, 10), - Event::NewRound(30, 7, 5, 130), - Event::Rewarded(1, 30), - Event::Rewarded(6, 9), - Event::Rewarded(7, 9), - Event::Rewarded(10, 9), - Event::CollatorChosen(8, 1, 40), - Event::CollatorChosen(8, 2, 40), - Event::CollatorChosen(8, 3, 20), - Event::CollatorChosen(8, 4, 20), - Event::CollatorChosen(8, 5, 10), - Event::NewRound(35, 8, 5, 130), - Event::Rewarded(1, 32), - Event::Rewarded(6, 10), - Event::Rewarded(7, 10), - Event::Rewarded(10, 10), - ]; - expected.append(&mut new3); - assert_eq_events!(expected.clone()); - set_author(8, 1, 100); - roll_to(40); - // no more paying 6 - let mut new4 = vec![ - Event::CollatorChosen(9, 1, 40), - Event::CollatorChosen(9, 2, 40), - Event::CollatorChosen(9, 3, 20), - Event::CollatorChosen(9, 4, 20), - Event::CollatorChosen(9, 5, 10), - Event::NewRound(40, 9, 5, 130), - Event::Rewarded(1, 38), - Event::Rewarded(7, 13), - Event::Rewarded(10, 13), - ]; - expected.append(&mut new4); - assert_eq_events!(expected.clone()); - set_author(9, 1, 100); - assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); - roll_to(45); - // new delegation is not rewarded yet - let mut new5 = vec![ - Event::Delegation(8, 10, 1, DelegatorAdded::AddedToTop { new_total: 50 }), - Event::CollatorChosen(10, 1, 50), - Event::CollatorChosen(10, 2, 40), - Event::CollatorChosen(10, 3, 20), - Event::CollatorChosen(10, 4, 20), - Event::CollatorChosen(10, 5, 10), - Event::NewRound(45, 10, 5, 140), - Event::Rewarded(1, 40), - Event::Rewarded(7, 13), - Event::Rewarded(10, 13), - ]; - expected.append(&mut new5); - assert_eq_events!(expected.clone()); - set_author(10, 1, 100); - roll_to(50); - // new delegation not rewarded yet - let mut new6 = vec![ - Event::CollatorChosen(11, 1, 50), - Event::CollatorChosen(11, 2, 40), - Event::CollatorChosen(11, 3, 20), - Event::CollatorChosen(11, 4, 20), - Event::CollatorChosen(11, 5, 10), - Event::NewRound(50, 11, 5, 140), - Event::Rewarded(1, 42), - Event::Rewarded(7, 14), - Event::Rewarded(10, 14), - ]; - expected.append(&mut new6); - assert_eq_events!(expected.clone()); - roll_to(55); - // new delegation is rewarded for first time - // 2 rounds after joining (`RewardPaymentDelay` = 2) - let mut new7 = vec![ - Event::CollatorChosen(12, 1, 50), - Event::CollatorChosen(12, 2, 40), - Event::CollatorChosen(12, 3, 20), - Event::CollatorChosen(12, 4, 20), - Event::CollatorChosen(12, 5, 10), - Event::NewRound(55, 12, 5, 140), - Event::Rewarded(1, 39), - Event::Rewarded(7, 12), - Event::Rewarded(10, 12), - Event::Rewarded(8, 12), - ]; - expected.append(&mut new7); - assert_eq_events!(expected); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 10)]) + .with_delegations(vec![ + (6, 1, 10), + (7, 1, 10), + (8, 2, 10), + (9, 2, 10), + (10, 1, 10), + ]) + .build() + .execute_with(|| { + roll_to(8); + // chooses top TotalSelectedCandidates (5), in order + let mut expected = vec![ + Event::CollatorChosen(2, 1, 50), + Event::CollatorChosen(2, 2, 40), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::CollatorChosen(2, 5, 10), + Event::NewRound(5, 2, 5, 140), + ]; + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for all blocks this round + set_author(2, 1, 100); + roll_to(16); + // distribute total issuance to collator 1 and its delegators 6, 7, 19 + let mut new = vec![ + Event::CollatorChosen(3, 1, 50), + Event::CollatorChosen(3, 2, 40), + Event::CollatorChosen(3, 3, 20), + Event::CollatorChosen(3, 4, 20), + Event::CollatorChosen(3, 5, 10), + Event::NewRound(10, 3, 5, 140), + Event::CollatorChosen(4, 1, 50), + Event::CollatorChosen(4, 2, 40), + Event::CollatorChosen(4, 3, 20), + Event::CollatorChosen(4, 4, 20), + Event::CollatorChosen(4, 5, 10), + Event::NewRound(15, 4, 5, 140), + Event::Rewarded(1, 26), + Event::Rewarded(6, 8), + Event::Rewarded(7, 8), + Event::Rewarded(10, 8), + ]; + expected.append(&mut new); + assert_eq_events!(expected.clone()); + // ~ set block author as 1 for all blocks this round + set_author(3, 1, 100); + set_author(4, 1, 100); + set_author(5, 1, 100); + set_author(6, 1, 100); + // 1. ensure delegators are paid for 2 rounds after they leave + assert_noop!( + ParachainStaking::schedule_leave_delegators(Origin::signed(66)), + Error::::DelegatorDNE + ); + assert_ok!(ParachainStaking::schedule_leave_delegators(Origin::signed( + 6 + ))); + // fast forward to block in which delegator 6 exit executes + roll_to(25); + assert_ok!(ParachainStaking::execute_leave_delegators( + Origin::signed(6), + 6, + 10 + )); + // keep paying 6 (note: inflation is in terms of total issuance so that's why 1 is 21) + let mut new2 = vec![ + Event::DelegatorExitScheduled(4, 6, 6), + Event::CollatorChosen(5, 1, 50), + Event::CollatorChosen(5, 2, 40), + Event::CollatorChosen(5, 3, 20), + Event::CollatorChosen(5, 4, 20), + Event::CollatorChosen(5, 5, 10), + Event::NewRound(20, 5, 5, 140), + Event::Rewarded(1, 27), + Event::Rewarded(6, 8), + Event::Rewarded(7, 8), + Event::Rewarded(10, 8), + Event::CollatorChosen(6, 1, 50), + Event::CollatorChosen(6, 2, 40), + Event::CollatorChosen(6, 3, 20), + Event::CollatorChosen(6, 4, 20), + Event::CollatorChosen(6, 5, 10), + Event::NewRound(25, 6, 5, 140), + Event::Rewarded(1, 29), + Event::Rewarded(6, 9), + Event::Rewarded(7, 9), + Event::Rewarded(10, 9), + Event::DelegatorLeftCandidate(6, 1, 10, 40), + Event::DelegatorLeft(6, 10), + ]; + expected.append(&mut new2); + assert_eq_events!(expected.clone()); + // 6 won't be paid for this round because they left already + set_author(7, 1, 100); + roll_to(35); + // keep paying 6 + let mut new3 = vec![ + Event::CollatorChosen(7, 1, 40), + Event::CollatorChosen(7, 2, 40), + Event::CollatorChosen(7, 3, 20), + Event::CollatorChosen(7, 4, 20), + Event::CollatorChosen(7, 5, 10), + Event::NewRound(30, 7, 5, 130), + Event::Rewarded(1, 30), + Event::Rewarded(6, 9), + Event::Rewarded(7, 9), + Event::Rewarded(10, 9), + Event::CollatorChosen(8, 1, 40), + Event::CollatorChosen(8, 2, 40), + Event::CollatorChosen(8, 3, 20), + Event::CollatorChosen(8, 4, 20), + Event::CollatorChosen(8, 5, 10), + Event::NewRound(35, 8, 5, 130), + Event::Rewarded(1, 32), + Event::Rewarded(6, 10), + Event::Rewarded(7, 10), + Event::Rewarded(10, 10), + ]; + expected.append(&mut new3); + assert_eq_events!(expected.clone()); + set_author(8, 1, 100); + roll_to(40); + // no more paying 6 + let mut new4 = vec![ + Event::CollatorChosen(9, 1, 40), + Event::CollatorChosen(9, 2, 40), + Event::CollatorChosen(9, 3, 20), + Event::CollatorChosen(9, 4, 20), + Event::CollatorChosen(9, 5, 10), + Event::NewRound(40, 9, 5, 130), + Event::Rewarded(1, 38), + Event::Rewarded(7, 13), + Event::Rewarded(10, 13), + ]; + expected.append(&mut new4); + assert_eq_events!(expected.clone()); + set_author(9, 1, 100); + assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); + roll_to(45); + // new delegation is not rewarded yet + let mut new5 = vec![ + Event::Delegation(8, 10, 1, DelegatorAdded::AddedToTop { new_total: 50 }), + Event::CollatorChosen(10, 1, 50), + Event::CollatorChosen(10, 2, 40), + Event::CollatorChosen(10, 3, 20), + Event::CollatorChosen(10, 4, 20), + Event::CollatorChosen(10, 5, 10), + Event::NewRound(45, 10, 5, 140), + Event::Rewarded(1, 40), + Event::Rewarded(7, 13), + Event::Rewarded(10, 13), + ]; + expected.append(&mut new5); + assert_eq_events!(expected.clone()); + set_author(10, 1, 100); + roll_to(50); + // new delegation not rewarded yet + let mut new6 = vec![ + Event::CollatorChosen(11, 1, 50), + Event::CollatorChosen(11, 2, 40), + Event::CollatorChosen(11, 3, 20), + Event::CollatorChosen(11, 4, 20), + Event::CollatorChosen(11, 5, 10), + Event::NewRound(50, 11, 5, 140), + Event::Rewarded(1, 42), + Event::Rewarded(7, 14), + Event::Rewarded(10, 14), + ]; + expected.append(&mut new6); + assert_eq_events!(expected.clone()); + roll_to(55); + // new delegation is rewarded for first time + // 2 rounds after joining (`RewardPaymentDelay` = 2) + let mut new7 = vec![ + Event::CollatorChosen(12, 1, 50), + Event::CollatorChosen(12, 2, 40), + Event::CollatorChosen(12, 3, 20), + Event::CollatorChosen(12, 4, 20), + Event::CollatorChosen(12, 5, 10), + Event::NewRound(55, 12, 5, 140), + Event::Rewarded(1, 39), + Event::Rewarded(7, 12), + Event::Rewarded(10, 12), + Event::Rewarded(8, 12), + ]; + expected.append(&mut new7); + assert_eq_events!(expected); + }); } #[test] fn bottom_delegations_are_empty_when_top_delegations_not_full() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 10), (3, 10), (4, 10), (5, 10)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - // no top delegators => no bottom delegators - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); - assert!(top_delegations.delegations.is_empty()); - assert!(bottom_delegations.delegations.is_empty()); - // 1 delegator => 1 top delegator, 0 bottom delegators - assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); - assert_eq!(top_delegations.delegations.len(), 1usize); - assert!(bottom_delegations.delegations.is_empty()); - // 2 delegators => 2 top delegators, 0 bottom delegators - assert_ok!(ParachainStaking::delegate(Origin::signed(3), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); - assert_eq!(top_delegations.delegations.len(), 2usize); - assert!(bottom_delegations.delegations.is_empty()); - // 3 delegators => 3 top delegators, 0 bottom delegators - assert_ok!(ParachainStaking::delegate(Origin::signed(4), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); - assert_eq!(top_delegations.delegations.len(), 3usize); - assert!(bottom_delegations.delegations.is_empty()); - // 4 delegators => 4 top delegators, 0 bottom delegators - assert_ok!(ParachainStaking::delegate(Origin::signed(5), 1, 10, 10, 10)); - let top_delegations = ParachainStaking::top_delegations(1).unwrap(); - let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); - assert_eq!(top_delegations.delegations.len(), 4usize); - assert!(bottom_delegations.delegations.is_empty()); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 10), (3, 10), (4, 10), (5, 10)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + // no top delegators => no bottom delegators + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert!(top_delegations.delegations.is_empty()); + assert!(bottom_delegations.delegations.is_empty()); + // 1 delegator => 1 top delegator, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(2), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 1usize); + assert!(bottom_delegations.delegations.is_empty()); + // 2 delegators => 2 top delegators, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(3), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 2usize); + assert!(bottom_delegations.delegations.is_empty()); + // 3 delegators => 3 top delegators, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(4), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 3usize); + assert!(bottom_delegations.delegations.is_empty()); + // 4 delegators => 4 top delegators, 0 bottom delegators + assert_ok!(ParachainStaking::delegate(Origin::signed(5), 1, 10, 10, 10)); + let top_delegations = ParachainStaking::top_delegations(1).unwrap(); + let bottom_delegations = ParachainStaking::bottom_delegations(1).unwrap(); + assert_eq!(top_delegations.delegations.len(), 4usize); + assert!(bottom_delegations.delegations.is_empty()); + }); } #[test] fn candidate_pool_updates_when_total_counted_changes() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (3, 19), - (4, 20), - (5, 21), - (6, 22), - (7, 15), - (8, 16), - (9, 17), - (10, 18), - ]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![ - (3, 1, 11), - (4, 1, 12), - (5, 1, 13), - (6, 1, 14), - (7, 1, 15), - (8, 1, 16), - (9, 1, 17), - (10, 1, 18), - ]) - .build() - .execute_with(|| { - fn is_candidate_pool_bond(account: u64, bond: u128) { - let pool = ParachainStaking::candidate_pool(); - for candidate in pool.0 { - if candidate.owner == account { - assert_eq!( - candidate.amount, bond, - "Candidate Bond {:?} is Not Equal to Expected: {:?}", - candidate.amount, bond - ); - } - } - } - // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) - is_candidate_pool_bond(1, 86); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(3), - 1, - 8 - )); - // 3: 11 -> 19 => 3 is in top, bumps out 7 - // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) - is_candidate_pool_bond(1, 90); - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(4), - 1, - 8 - )); - // 4: 12 -> 20 => 4 is in top, bumps out 8 - // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) - is_candidate_pool_bond(1, 94); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(10), - 1, - 3 - )); - roll_to(30); - // 10: 18 -> 15 => 10 bumped to bottom, 8 bumped to top (- 18 + 16 = -2 for count) - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(10), - 10, - 1 - )); - // 16 + 17 + 19 + 20 + 20 = 92 (top 4 + self bond) - is_candidate_pool_bond(1, 92); - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(9), - 1, - 4 - )); - roll_to(40); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(9), - 9, - 1 - )); - // 15 + 16 + 19 + 20 + 20 = 90 (top 4 + self bond) - is_candidate_pool_bond(1, 90); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (3, 19), + (4, 20), + (5, 21), + (6, 22), + (7, 15), + (8, 16), + (9, 17), + (10, 18), + ]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (3, 1, 11), + (4, 1, 12), + (5, 1, 13), + (6, 1, 14), + (7, 1, 15), + (8, 1, 16), + (9, 1, 17), + (10, 1, 18), + ]) + .build() + .execute_with(|| { + fn is_candidate_pool_bond(account: u64, bond: u128) { + let pool = ParachainStaking::candidate_pool(); + for candidate in pool.0 { + if candidate.owner == account { + assert_eq!( + candidate.amount, bond, + "Candidate Bond {:?} is Not Equal to Expected: {:?}", + candidate.amount, bond + ); + } + } + } + // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) + is_candidate_pool_bond(1, 86); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(3), + 1, + 8 + )); + // 3: 11 -> 19 => 3 is in top, bumps out 7 + // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) + is_candidate_pool_bond(1, 90); + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(4), + 1, + 8 + )); + // 4: 12 -> 20 => 4 is in top, bumps out 8 + // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) + is_candidate_pool_bond(1, 94); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(10), + 1, + 3 + )); + roll_to(30); + // 10: 18 -> 15 => 10 bumped to bottom, 8 bumped to top (- 18 + 16 = -2 for count) + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(10), + 10, + 1 + )); + // 16 + 17 + 19 + 20 + 20 = 92 (top 4 + self bond) + is_candidate_pool_bond(1, 92); + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(9), + 1, + 4 + )); + roll_to(40); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(9), + 9, + 1 + )); + // 15 + 16 + 19 + 20 + 20 = 90 (top 4 + self bond) + is_candidate_pool_bond(1, 90); + }); } #[test] fn only_top_collators_are_counted() { - ExtBuilder::default() - .with_balances(vec![ - (1, 20), - (3, 19), - (4, 20), - (5, 21), - (6, 22), - (7, 15), - (8, 16), - (9, 17), - (10, 18), - ]) - .with_candidates(vec![(1, 20)]) - .with_delegations(vec![ - (3, 1, 11), - (4, 1, 12), - (5, 1, 13), - (6, 1, 14), - (7, 1, 15), - (8, 1, 16), - (9, 1, 17), - (10, 1, 18), - ]) - .build() - .execute_with(|| { - // sanity check that 3-10 are delegators immediately - for i in 3..11 { - assert!(ParachainStaking::is_delegator(&i)); - } - let collator_state = ParachainStaking::candidate_info(1).unwrap(); - // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 86); - // bump bottom to the top - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(3), - 1, - 8 - )); - assert_event_emitted!(Event::DelegationIncreased(3, 1, 8, true)); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); - // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 90); - // bump bottom to the top - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(4), - 1, - 8 - )); - assert_event_emitted!(Event::DelegationIncreased(4, 1, 8, true)); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); - // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 94); - // bump bottom to the top - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(5), - 1, - 8 - )); - assert_event_emitted!(Event::DelegationIncreased(5, 1, 8, true)); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); - // 18 + 19 + 20 + 21 + 20 = 98 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 98); - // bump bottom to the top - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(6), - 1, - 8 - )); - assert_event_emitted!(Event::DelegationIncreased(6, 1, 8, true)); - let collator_state = ParachainStaking::candidate_info(1).unwrap(); - // 19 + 20 + 21 + 22 + 20 = 102 (top 4 + self bond) - assert_eq!(collator_state.total_counted, 102); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 20), + (3, 19), + (4, 20), + (5, 21), + (6, 22), + (7, 15), + (8, 16), + (9, 17), + (10, 18), + ]) + .with_candidates(vec![(1, 20)]) + .with_delegations(vec![ + (3, 1, 11), + (4, 1, 12), + (5, 1, 13), + (6, 1, 14), + (7, 1, 15), + (8, 1, 16), + (9, 1, 17), + (10, 1, 18), + ]) + .build() + .execute_with(|| { + // sanity check that 3-10 are delegators immediately + for i in 3..11 { + assert!(ParachainStaking::is_delegator(&i)); + } + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 15 + 16 + 17 + 18 + 20 = 86 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 86); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(3), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(3, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 16 + 17 + 18 + 19 + 20 = 90 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 90); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(4), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(4, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 17 + 18 + 19 + 20 + 20 = 94 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 94); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(5), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(5, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 18 + 19 + 20 + 21 + 20 = 98 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 98); + // bump bottom to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(6), + 1, + 8 + )); + assert_event_emitted!(Event::DelegationIncreased(6, 1, 8, true)); + let collator_state = ParachainStaking::candidate_info(1).unwrap(); + // 19 + 20 + 21 + 22 + 20 = 102 (top 4 + self bond) + assert_eq!(collator_state.total_counted, 102); + }); } #[test] fn delegation_events_convey_correct_position() { - ExtBuilder::default() - .with_balances(vec![ - (1, 100), - (2, 100), - (3, 100), - (4, 100), - (5, 100), - (6, 100), - (7, 100), - (8, 100), - (9, 100), - (10, 100), - ]) - .with_candidates(vec![(1, 20), (2, 20)]) - .with_delegations(vec![(3, 1, 11), (4, 1, 12), (5, 1, 13), (6, 1, 14)]) - .build() - .execute_with(|| { - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); - // 11 + 12 + 13 + 14 + 20 = 70 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 70); - // Top delegations are full, new highest delegation is made - assert_ok!(ParachainStaking::delegate(Origin::signed(7), 1, 15, 10, 10)); - assert_event_emitted!(Event::Delegation( - 7, - 15, - 1, - DelegatorAdded::AddedToTop { new_total: 74 }, - )); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); - // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 74); - // New delegation is added to the bottom - assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); - assert_event_emitted!(Event::Delegation(8, 10, 1, DelegatorAdded::AddedToBottom)); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); - // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 74); - // 8 increases delegation to the top - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(8), - 1, - 3 - )); - assert_event_emitted!(Event::DelegationIncreased(8, 1, 3, true)); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); - // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 75); - // 3 increases delegation but stays in bottom - assert_ok!(ParachainStaking::delegator_bond_more( - Origin::signed(3), - 1, - 1 - )); - assert_event_emitted!(Event::DelegationIncreased(3, 1, 1, false)); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); - // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 75); - // 6 decreases delegation but stays in top - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(6), - 1, - 2 - )); - assert_event_emitted!(Event::DelegationDecreaseScheduled(6, 1, 2, 3)); - roll_to(30); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(6), - 6, - 1 - )); - assert_event_emitted!(Event::DelegationDecreased(6, 1, 2, true)); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); - // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond)Æ’ - assert_eq!(collator1_state.total_counted, 73); - // 6 decreases delegation and is bumped to bottom - assert_ok!(ParachainStaking::schedule_delegator_bond_less( - Origin::signed(6), - 1, - 1 - )); - assert_event_emitted!(Event::DelegationDecreaseScheduled(6, 1, 1, 9)); - roll_to(40); - assert_ok!(ParachainStaking::execute_delegation_request( - Origin::signed(6), - 6, - 1 - )); - assert_event_emitted!(Event::DelegationDecreased(6, 1, 1, false)); - let collator1_state = ParachainStaking::candidate_info(1).unwrap(); - // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond) - assert_eq!(collator1_state.total_counted, 73); - }); + ExtBuilder::default() + .with_balances(vec![ + (1, 100), + (2, 100), + (3, 100), + (4, 100), + (5, 100), + (6, 100), + (7, 100), + (8, 100), + (9, 100), + (10, 100), + ]) + .with_candidates(vec![(1, 20), (2, 20)]) + .with_delegations(vec![(3, 1, 11), (4, 1, 12), (5, 1, 13), (6, 1, 14)]) + .build() + .execute_with(|| { + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 11 + 12 + 13 + 14 + 20 = 70 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 70); + // Top delegations are full, new highest delegation is made + assert_ok!(ParachainStaking::delegate(Origin::signed(7), 1, 15, 10, 10)); + assert_event_emitted!(Event::Delegation( + 7, + 15, + 1, + DelegatorAdded::AddedToTop { new_total: 74 }, + )); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 74); + // New delegation is added to the bottom + assert_ok!(ParachainStaking::delegate(Origin::signed(8), 1, 10, 10, 10)); + assert_event_emitted!(Event::Delegation(8, 10, 1, DelegatorAdded::AddedToBottom)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 14 + 15 + 20 = 70 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 74); + // 8 increases delegation to the top + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(8), + 1, + 3 + )); + assert_event_emitted!(Event::DelegationIncreased(8, 1, 3, true)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 75); + // 3 increases delegation but stays in bottom + assert_ok!(ParachainStaking::delegator_bond_more( + Origin::signed(3), + 1, + 1 + )); + assert_event_emitted!(Event::DelegationIncreased(3, 1, 1, false)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 13 + 13 + 14 + 15 + 20 = 75 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 75); + // 6 decreases delegation but stays in top + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(6), + 1, + 2 + )); + assert_event_emitted!(Event::DelegationDecreaseScheduled(6, 1, 2, 3)); + roll_to(30); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(6), + 6, + 1 + )); + assert_event_emitted!(Event::DelegationDecreased(6, 1, 2, true)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond)Æ’ + assert_eq!(collator1_state.total_counted, 73); + // 6 decreases delegation and is bumped to bottom + assert_ok!(ParachainStaking::schedule_delegator_bond_less( + Origin::signed(6), + 1, + 1 + )); + assert_event_emitted!(Event::DelegationDecreaseScheduled(6, 1, 1, 9)); + roll_to(40); + assert_ok!(ParachainStaking::execute_delegation_request( + Origin::signed(6), + 6, + 1 + )); + assert_event_emitted!(Event::DelegationDecreased(6, 1, 1, false)); + let collator1_state = ParachainStaking::candidate_info(1).unwrap(); + // 12 + 13 + 13 + 15 + 20 = 73 (top 4 + self bond) + assert_eq!(collator1_state.total_counted, 73); + }); } #[test] fn no_rewards_paid_until_after_reward_payment_delay() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) - .build() - .execute_with(|| { - roll_to_round_begin(2); - // payouts for round 1 - set_author(1, 1, 1); - set_author(1, 2, 1); - set_author(1, 3, 1); - set_author(1, 4, 1); - set_author(1, 4, 1); - let mut expected = vec![ - Event::CollatorChosen(2, 1, 20), - Event::CollatorChosen(2, 2, 20), - Event::CollatorChosen(2, 3, 20), - Event::CollatorChosen(2, 4, 20), - Event::NewRound(5, 2, 4, 80), - ]; - assert_eq_events!(expected); - - roll_to_round_begin(3); - expected.append(&mut vec![ - Event::CollatorChosen(3, 1, 20), - Event::CollatorChosen(3, 2, 20), - Event::CollatorChosen(3, 3, 20), - Event::CollatorChosen(3, 4, 20), - Event::NewRound(10, 3, 4, 80), - // rewards will begin immediately following a NewRound - Event::Rewarded(3, 1), - ]); - assert_eq_events!(expected); - - // roll to the next block where we start round 3; we should have round change and first - // payout made. - roll_one_block(); - expected.push(Event::Rewarded(4, 2)); - assert_eq_events!(expected); - - roll_one_block(); - expected.push(Event::Rewarded(1, 1)); - assert_eq_events!(expected); - - roll_one_block(); - expected.push(Event::Rewarded(2, 1)); - assert_eq_events!(expected); - - // there should be no more payments in this round... - let num_blocks_rolled = roll_to_round_end(3); - assert_eq_events!(expected); - assert_eq!(num_blocks_rolled, 1); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + .build() + .execute_with(|| { + roll_to_round_begin(2); + // payouts for round 1 + set_author(1, 1, 1); + set_author(1, 2, 1); + set_author(1, 3, 1); + set_author(1, 4, 1); + set_author(1, 4, 1); + let mut expected = vec![ + Event::CollatorChosen(2, 1, 20), + Event::CollatorChosen(2, 2, 20), + Event::CollatorChosen(2, 3, 20), + Event::CollatorChosen(2, 4, 20), + Event::NewRound(5, 2, 4, 80), + ]; + assert_eq_events!(expected); + + roll_to_round_begin(3); + expected.append(&mut vec![ + Event::CollatorChosen(3, 1, 20), + Event::CollatorChosen(3, 2, 20), + Event::CollatorChosen(3, 3, 20), + Event::CollatorChosen(3, 4, 20), + Event::NewRound(10, 3, 4, 80), + // rewards will begin immediately following a NewRound + Event::Rewarded(3, 1), + ]); + assert_eq_events!(expected); + + // roll to the next block where we start round 3; we should have round change and first + // payout made. + roll_one_block(); + expected.push(Event::Rewarded(4, 2)); + assert_eq_events!(expected); + + roll_one_block(); + expected.push(Event::Rewarded(1, 1)); + assert_eq_events!(expected); + + roll_one_block(); + expected.push(Event::Rewarded(2, 1)); + assert_eq_events!(expected); + + // there should be no more payments in this round... + let num_blocks_rolled = roll_to_round_end(3); + assert_eq_events!(expected); + assert_eq!(num_blocks_rolled, 1); + }); } #[test] fn deferred_payment_storage_items_are_cleaned_up() { - use crate::*; - - // this test sets up two collators, gives them points in round one, and focuses on the - // storage over the next several blocks to show that it is properly cleaned up - - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20)]) - .with_candidates(vec![(1, 20), (2, 20)]) - .build() - .execute_with(|| { - let mut round: u32 = 1; - set_author(round, 1, 1); - set_author(round, 2, 1); - - // reflects genesis? - assert!(>::contains_key(round, 1)); - assert!(>::contains_key(round, 2)); - - round = 2; - roll_to_round_begin(round.into()); - let mut expected = vec![ - Event::CollatorChosen(round, 1, 20), - Event::CollatorChosen(round, 2, 20), - Event::NewRound(5, round, 2, 40), - ]; - assert_eq_events!(expected); - - // we should have AtStake snapshots as soon as we start a round... - assert!(>::contains_key(2, 1)); - assert!(>::contains_key(2, 2)); - // ...and it should persist until the round is fully paid out - assert!(>::contains_key(1, 1)); - assert!(>::contains_key(1, 2)); - - assert!( - !>::contains_key(1), - "DelayedPayouts shouldn't be populated until after RewardPaymentDelay" - ); - assert!( - >::contains_key(1), - "Points should be populated during current round" - ); - assert!( - >::contains_key(1), - "Staked should be populated when round changes" - ); - - assert!( - !>::contains_key(2), - "Points should not be populated until author noted" - ); - assert!( - >::contains_key(2), - "Staked should be populated when round changes" - ); - - // first payout occurs in round 3 - round = 3; - roll_to_round_begin(round.into()); - expected.append(&mut vec![ - Event::CollatorChosen(round, 1, 20), - Event::CollatorChosen(round, 2, 20), - Event::NewRound(10, round, 2, 40), - Event::Rewarded(1, 1), - ]); - assert_eq_events!(expected); - - // payouts should exist for past rounds that haven't been paid out yet.. - assert!(>::contains_key(3, 1)); - assert!(>::contains_key(3, 2)); - assert!(>::contains_key(2, 1)); - assert!(>::contains_key(2, 2)); - - assert!( - >::contains_key(1), - "DelayedPayouts should be populated after RewardPaymentDelay" - ); - assert!(>::contains_key(1)); - assert!( - !>::contains_key(1), - "Staked should be cleaned up after round change" - ); - - assert!(!>::contains_key(2)); - assert!( - !>::contains_key(2), - "We never rewarded points for round 2" - ); - assert!(>::contains_key(2)); - - assert!(!>::contains_key(3)); - assert!( - !>::contains_key(3), - "We never awarded points for round 3" - ); - assert!(>::contains_key(3)); - - // collator 1 has been paid in this last block and associated storage cleaned up - assert!(!>::contains_key(1, 1)); - assert!(!>::contains_key(1, 1)); - - // but collator 2 hasn't been paid - assert!(>::contains_key(1, 2)); - assert!(>::contains_key(1, 2)); - - round = 4; - roll_to_round_begin(round.into()); - expected.append(&mut vec![ - Event::Rewarded(2, 1), // from previous round - Event::CollatorChosen(round, 1, 20), - Event::CollatorChosen(round, 2, 20), - Event::NewRound(15, round, 2, 40), - ]); - assert_eq_events!(expected); - - // collators have both been paid and storage fully cleaned up for round 1 - assert!(!>::contains_key(1, 2)); - assert!(!>::contains_key(1, 2)); - assert!(!>::contains_key(1)); - assert!(!>::contains_key(1)); // points should be cleaned up - assert!(!>::contains_key(1)); - - roll_to_round_end(4); - - // no more events expected - assert_eq_events!(expected); - }); + use crate::*; + + // this test sets up two collators, gives them points in round one, and focuses on the + // storage over the next several blocks to show that it is properly cleaned up + + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20)]) + .with_candidates(vec![(1, 20), (2, 20)]) + .build() + .execute_with(|| { + let mut round: u32 = 1; + set_author(round, 1, 1); + set_author(round, 2, 1); + + // reflects genesis? + assert!(>::contains_key(round, 1)); + assert!(>::contains_key(round, 2)); + + round = 2; + roll_to_round_begin(round.into()); + let mut expected = vec![ + Event::CollatorChosen(round, 1, 20), + Event::CollatorChosen(round, 2, 20), + Event::NewRound(5, round, 2, 40), + ]; + assert_eq_events!(expected); + + // we should have AtStake snapshots as soon as we start a round... + assert!(>::contains_key(2, 1)); + assert!(>::contains_key(2, 2)); + // ...and it should persist until the round is fully paid out + assert!(>::contains_key(1, 1)); + assert!(>::contains_key(1, 2)); + + assert!( + !>::contains_key(1), + "DelayedPayouts shouldn't be populated until after RewardPaymentDelay" + ); + assert!( + >::contains_key(1), + "Points should be populated during current round" + ); + assert!( + >::contains_key(1), + "Staked should be populated when round changes" + ); + + assert!( + !>::contains_key(2), + "Points should not be populated until author noted" + ); + assert!( + >::contains_key(2), + "Staked should be populated when round changes" + ); + + // first payout occurs in round 3 + round = 3; + roll_to_round_begin(round.into()); + expected.append(&mut vec![ + Event::CollatorChosen(round, 1, 20), + Event::CollatorChosen(round, 2, 20), + Event::NewRound(10, round, 2, 40), + Event::Rewarded(1, 1), + ]); + assert_eq_events!(expected); + + // payouts should exist for past rounds that haven't been paid out yet.. + assert!(>::contains_key(3, 1)); + assert!(>::contains_key(3, 2)); + assert!(>::contains_key(2, 1)); + assert!(>::contains_key(2, 2)); + + assert!( + >::contains_key(1), + "DelayedPayouts should be populated after RewardPaymentDelay" + ); + assert!(>::contains_key(1)); + assert!( + !>::contains_key(1), + "Staked should be cleaned up after round change" + ); + + assert!(!>::contains_key(2)); + assert!( + !>::contains_key(2), + "We never rewarded points for round 2" + ); + assert!(>::contains_key(2)); + + assert!(!>::contains_key(3)); + assert!( + !>::contains_key(3), + "We never awarded points for round 3" + ); + assert!(>::contains_key(3)); + + // collator 1 has been paid in this last block and associated storage cleaned up + assert!(!>::contains_key(1, 1)); + assert!(!>::contains_key(1, 1)); + + // but collator 2 hasn't been paid + assert!(>::contains_key(1, 2)); + assert!(>::contains_key(1, 2)); + + round = 4; + roll_to_round_begin(round.into()); + expected.append(&mut vec![ + Event::Rewarded(2, 1), // from previous round + Event::CollatorChosen(round, 1, 20), + Event::CollatorChosen(round, 2, 20), + Event::NewRound(15, round, 2, 40), + ]); + assert_eq_events!(expected); + + // collators have both been paid and storage fully cleaned up for round 1 + assert!(!>::contains_key(1, 2)); + assert!(!>::contains_key(1, 2)); + assert!(!>::contains_key(1)); + assert!(!>::contains_key(1)); // points should be cleaned up + assert!(!>::contains_key(1)); + + roll_to_round_end(4); + + // no more events expected + assert_eq_events!(expected); + }); } #[test] fn deferred_payment_steady_state_event_flow() { - use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons}; - - // this test "flows" through a number of rounds, asserting that certain things do/don't happen - // once the staking pallet is in a "steady state" (specifically, once we are past the first few - // rounds to clear RewardPaymentDelay) - - ExtBuilder::default() - .with_balances(vec![ - // collators - (1, 200), - (2, 200), - (3, 200), - (4, 200), - // delegators - (11, 200), - (22, 200), - (33, 200), - (44, 200), - // burn account, see `reset_issuance()` - (111, 1000), - ]) - .with_candidates(vec![(1, 200), (2, 200), (3, 200), (4, 200)]) - .with_delegations(vec![ - // delegator 11 delegates 100 to 1 and 2 - (11, 1, 100), - (11, 2, 100), - // delegator 22 delegates 100 to 2 and 3 - (22, 2, 100), - (22, 3, 100), - // delegator 33 delegates 100 to 3 and 4 - (33, 3, 100), - (33, 4, 100), - // delegator 44 delegates 100 to 4 and 1 - (44, 4, 100), - (44, 1, 100), - ]) - .build() - .execute_with(|| { - // convenience to set the round points consistently - let set_round_points = |round: u64| { - set_author(round as u32, 1, 1); - set_author(round as u32, 2, 1); - set_author(round as u32, 3, 1); - set_author(round as u32, 4, 1); - }; - - // grab initial issuance -- we will reset it before round issuance is calculated so that - // it is consistent every round - let initial_issuance = Balances::total_issuance(); - let reset_issuance = || { - let new_issuance = Balances::total_issuance(); - let diff = new_issuance - initial_issuance; - let burned = Balances::burn(diff); - Balances::settle( - &111, - burned, - WithdrawReasons::FEE, - ExistenceRequirement::AllowDeath, - ) - .expect("Account can absorb burn"); - }; - - // fn to roll through the first RewardPaymentDelay rounds. returns new round index - let roll_through_initial_rounds = |mut round: u64| -> u64 { - while round < crate::mock::RewardPaymentDelay::get() as u64 + 1 { - set_round_points(round); - - roll_to_round_end(round); - round += 1; - } - - reset_issuance(); - - round - }; - - // roll through a "steady state" round and make all of our assertions - // returns new round index - let roll_through_steady_state_round = |round: u64| -> u64 { - let num_rounds_rolled = roll_to_round_begin(round); - assert_eq!( - num_rounds_rolled, 1, - "expected to be at round begin already" - ); - - let expected = vec![ - Event::CollatorChosen(round as u32, 1, 400), - Event::CollatorChosen(round as u32, 2, 400), - Event::CollatorChosen(round as u32, 3, 400), - Event::CollatorChosen(round as u32, 4, 400), - Event::NewRound((round - 1) * 5, round as u32, 4, 1600), - // first payout should occur on round change - Event::Rewarded(3, 19), - Event::Rewarded(22, 6), - Event::Rewarded(33, 6), - ]; - assert_eq_last_events!(expected); - - set_round_points(round); - - roll_one_block(); - let expected = vec![ - Event::Rewarded(4, 19), - Event::Rewarded(33, 6), - Event::Rewarded(44, 6), - ]; - assert_eq_last_events!(expected); - - roll_one_block(); - let expected = vec![ - Event::Rewarded(1, 19), - Event::Rewarded(11, 6), - Event::Rewarded(44, 6), - ]; - assert_eq_last_events!(expected); - - roll_one_block(); - let expected = vec![ - Event::Rewarded(2, 19), - Event::Rewarded(11, 6), - Event::Rewarded(22, 6), - ]; - assert_eq_last_events!(expected); - - roll_one_block(); - let expected = vec![ - // we paid everyone out by now, should repeat last event - Event::Rewarded(22, 6), - ]; - assert_eq_last_events!(expected); - - let num_rounds_rolled = roll_to_round_end(round); - assert_eq!(num_rounds_rolled, 0, "expected to be at round end already"); - - reset_issuance(); - - round + 1 - }; - - let mut round = 1; - round = roll_through_initial_rounds(round); // we should be at RewardPaymentDelay - for _ in 1..5 { - round = roll_through_steady_state_round(round); - } - }); + use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons}; + + // this test "flows" through a number of rounds, asserting that certain things do/don't happen + // once the staking pallet is in a "steady state" (specifically, once we are past the first few + // rounds to clear RewardPaymentDelay) + + ExtBuilder::default() + .with_balances(vec![ + // collators + (1, 200), + (2, 200), + (3, 200), + (4, 200), + // delegators + (11, 200), + (22, 200), + (33, 200), + (44, 200), + // burn account, see `reset_issuance()` + (111, 1000), + ]) + .with_candidates(vec![(1, 200), (2, 200), (3, 200), (4, 200)]) + .with_delegations(vec![ + // delegator 11 delegates 100 to 1 and 2 + (11, 1, 100), + (11, 2, 100), + // delegator 22 delegates 100 to 2 and 3 + (22, 2, 100), + (22, 3, 100), + // delegator 33 delegates 100 to 3 and 4 + (33, 3, 100), + (33, 4, 100), + // delegator 44 delegates 100 to 4 and 1 + (44, 4, 100), + (44, 1, 100), + ]) + .build() + .execute_with(|| { + // convenience to set the round points consistently + let set_round_points = |round: u64| { + set_author(round as u32, 1, 1); + set_author(round as u32, 2, 1); + set_author(round as u32, 3, 1); + set_author(round as u32, 4, 1); + }; + + // grab initial issuance -- we will reset it before round issuance is calculated so that + // it is consistent every round + let initial_issuance = Balances::total_issuance(); + let reset_issuance = || { + let new_issuance = Balances::total_issuance(); + let diff = new_issuance - initial_issuance; + let burned = Balances::burn(diff); + Balances::settle( + &111, + burned, + WithdrawReasons::FEE, + ExistenceRequirement::AllowDeath, + ) + .expect("Account can absorb burn"); + }; + + // fn to roll through the first RewardPaymentDelay rounds. returns new round index + let roll_through_initial_rounds = |mut round: u64| -> u64 { + while round < crate::mock::RewardPaymentDelay::get() as u64 + 1 { + set_round_points(round); + + roll_to_round_end(round); + round += 1; + } + + reset_issuance(); + + round + }; + + // roll through a "steady state" round and make all of our assertions + // returns new round index + let roll_through_steady_state_round = |round: u64| -> u64 { + let num_rounds_rolled = roll_to_round_begin(round); + assert_eq!( + num_rounds_rolled, 1, + "expected to be at round begin already" + ); + + let expected = vec![ + Event::CollatorChosen(round as u32, 1, 400), + Event::CollatorChosen(round as u32, 2, 400), + Event::CollatorChosen(round as u32, 3, 400), + Event::CollatorChosen(round as u32, 4, 400), + Event::NewRound((round - 1) * 5, round as u32, 4, 1600), + // first payout should occur on round change + Event::Rewarded(3, 19), + Event::Rewarded(22, 6), + Event::Rewarded(33, 6), + ]; + assert_eq_last_events!(expected); + + set_round_points(round); + + roll_one_block(); + let expected = vec![ + Event::Rewarded(4, 19), + Event::Rewarded(33, 6), + Event::Rewarded(44, 6), + ]; + assert_eq_last_events!(expected); + + roll_one_block(); + let expected = vec![ + Event::Rewarded(1, 19), + Event::Rewarded(11, 6), + Event::Rewarded(44, 6), + ]; + assert_eq_last_events!(expected); + + roll_one_block(); + let expected = vec![ + Event::Rewarded(2, 19), + Event::Rewarded(11, 6), + Event::Rewarded(22, 6), + ]; + assert_eq_last_events!(expected); + + roll_one_block(); + let expected = vec![ + // we paid everyone out by now, should repeat last event + Event::Rewarded(22, 6), + ]; + assert_eq_last_events!(expected); + + let num_rounds_rolled = roll_to_round_end(round); + assert_eq!(num_rounds_rolled, 0, "expected to be at round end already"); + + reset_issuance(); + + round + 1 + }; + + let mut round = 1; + round = roll_through_initial_rounds(round); // we should be at RewardPaymentDelay + for _ in 1..5 { + round = roll_through_steady_state_round(round); + } + }); } // HOTFIX UNIT TESTs #[test] fn hotfix_remove_delegation_requests_works() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20)]) - .with_candidates(vec![(1, 20)]) - .build() - .execute_with(|| { - let mut requests: BTreeMap< - ::AccountId, - DelegationRequest<::AccountId, BalanceOf>, - > = BTreeMap::new(); - requests.insert( - 3, - DelegationRequest { - collator: 3, - amount: 5, - when_executable: 0, - action: DelegationChange::Decrease, - }, - ); - requests.insert( - 4, - DelegationRequest { - collator: 4, - amount: 20, - when_executable: 0, - action: DelegationChange::Revoke, - }, - ); - let corrupted_delegator_state = Delegator { - id: 2, - delegations: OrderedSet::from(vec![Bond { - owner: 1, - amount: 20, - }]), - total: 20, - requests: PendingDelegationRequests { - revocations_count: 1, - requests, - less_total: 25, - }, - status: DelegatorStatus::Active, - }; - >::insert(2, corrupted_delegator_state); - assert_ok!(ParachainStaking::hotfix_remove_delegation_requests( - Origin::root(), - vec![2, 5] - )); - assert!(ParachainStaking::delegator_state(&5).is_none()); - let fixed_delegator_state = - ParachainStaking::delegator_state(&2).expect("inserted => exists"); - assert_eq!(fixed_delegator_state.requests.revocations_count, 0); - assert_eq!(fixed_delegator_state.requests.less_total, 0); - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20)]) + .with_candidates(vec![(1, 20)]) + .build() + .execute_with(|| { + let mut requests: BTreeMap< + ::AccountId, + DelegationRequest<::AccountId, BalanceOf>, + > = BTreeMap::new(); + requests.insert( + 3, + DelegationRequest { + collator: 3, + amount: 5, + when_executable: 0, + action: DelegationChange::Decrease, + }, + ); + requests.insert( + 4, + DelegationRequest { + collator: 4, + amount: 20, + when_executable: 0, + action: DelegationChange::Revoke, + }, + ); + let corrupted_delegator_state = Delegator { + id: 2, + delegations: OrderedSet::from(vec![Bond { + owner: 1, + amount: 20, + }]), + total: 20, + requests: PendingDelegationRequests { + revocations_count: 1, + requests, + less_total: 25, + }, + status: DelegatorStatus::Active, + }; + >::insert(2, corrupted_delegator_state); + assert_ok!(ParachainStaking::hotfix_remove_delegation_requests( + Origin::root(), + vec![2, 5] + )); + assert!(ParachainStaking::delegator_state(&5).is_none()); + let fixed_delegator_state = + ParachainStaking::delegator_state(&2).expect("inserted => exists"); + assert_eq!(fixed_delegator_state.requests.revocations_count, 0); + assert_eq!(fixed_delegator_state.requests.less_total, 0); + }); } #[test] fn hotfix_update_candidate_pool_value_updates_candidate_pool() { - ExtBuilder::default() - .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) - .build() - .execute_with(|| { - // corrupt CandidatePool - >::put(OrderedSet::from(vec![ - Bond { - owner: 1, - amount: 15, - }, - Bond { - owner: 2, - amount: 16, - }, - Bond { - owner: 3, - amount: 17, - }, - Bond { - owner: 4, - amount: 18, - }, - Bond { - owner: 5, - amount: 19, - }, - ])); - // run migration and pass in 6 even though not a candidate - assert_ok!(ParachainStaking::hotfix_update_candidate_pool_value( - Origin::root(), - vec![1, 2, 3, 4, 5, 6] - )); - // CandidatePool is now fixed for all input accounts - let pool = >::get(); - for Bond { owner, amount } in pool.0 { - // 6 is not in the candidate pool despite being passed in - assert!(owner <= 5 && owner >= 1); - // all amounts are fixed - assert_eq!(amount, 20); - } - }); + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + // corrupt CandidatePool + >::put(OrderedSet::from(vec![ + Bond { + owner: 1, + amount: 15, + }, + Bond { + owner: 2, + amount: 16, + }, + Bond { + owner: 3, + amount: 17, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 19, + }, + ])); + // run migration and pass in 6 even though not a candidate + assert_ok!(ParachainStaking::hotfix_update_candidate_pool_value( + Origin::root(), + vec![1, 2, 3, 4, 5, 6] + )); + // CandidatePool is now fixed for all input accounts + let pool = >::get(); + for Bond { owner, amount } in pool.0 { + // 6 is not in the candidate pool despite being passed in + assert!(owner <= 5 && owner >= 1); + // all amounts are fixed + assert_eq!(amount, 20); + } + }); } // MIGRATION UNIT TESTS @@ -5323,778 +5327,778 @@ use frame_support::traits::OnRuntimeUpgrade; #[test] /// Kicks extra bottom delegations to force leave delegators if last delegation fn split_candidate_state_kicks_extra_bottom_delegators_to_exit() { - ExtBuilder::default() - .with_balances(vec![(11, 22), (12, 20)]) - .build() - .execute_with(|| { - for i in 11..13 { - let old_delegator_state = Delegator { - id: i, - delegations: OrderedSet::from(vec![ - Bond { - owner: 1, - amount: 10, - }, - Bond { - owner: 2, - amount: 10, - }, - ]), - total: 20, - requests: PendingDelegationRequests::new(), - status: DelegatorStatus::Active, - }; - >::insert(&i, old_delegator_state); - } - assert_ok!(::Currency::reserve(&11, 22)); - assert_ok!(::Currency::reserve(&12, 20)); - assert_eq!(Balances::reserved_balance(&11), 22); - assert_eq!(Balances::reserved_balance(&12), 20); - for i in 1..3 { - let old_candidate_state = CollatorCandidate { - id: i, - bond: 20, - delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), - top_delegations: vec![ - Bond { - owner: 3, - amount: 19, - }, - Bond { - owner: 4, - amount: 18, - }, - Bond { - owner: 5, - amount: 17, - }, - Bond { - owner: 6, - amount: 16, - }, - ], - bottom_delegations: vec![ - Bond { - owner: 12, - amount: 10, - }, - Bond { - owner: 11, - amount: 11, - }, - Bond { - owner: 10, - amount: 12, - }, - Bond { - owner: 9, - amount: 13, - }, - Bond { - owner: 8, - amount: 14, - }, - Bond { - owner: 7, - amount: 15, - }, - ], - total_counted: 90, - total_backing: 165, - request: None, - state: CollatorStatus::Active, - }; - >::insert(&i, old_candidate_state); - } - // total is 165 * 2 = 330 - >::put(330); - assert!(ParachainStaking::is_delegator(&11)); - assert!(ParachainStaking::is_delegator(&12)); - crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); - assert_event_emitted!(Event::DelegationKicked(11, 1, 11)); - assert_event_emitted!(Event::DelegationKicked(11, 2, 11)); - assert_event_emitted!(Event::DelegationKicked(12, 1, 10)); - assert_event_emitted!(Event::DelegationKicked(12, 2, 10)); - assert_event_emitted!(Event::DelegatorLeft(12, 10)); - assert_event_emitted!(Event::DelegatorLeft(11, 11)); - // kicked 11 and 12 and revoked them - assert_eq!(Balances::free_balance(&11), 22); - assert_eq!(Balances::free_balance(&12), 20); - assert!(!ParachainStaking::is_delegator(&11)); - assert!(!ParachainStaking::is_delegator(&12)); - for i in 1..3 { - let top_delegations = >::get(&i).unwrap(); - assert_eq!(top_delegations.total, 70); - assert_eq!( - top_delegations.delegations, - vec![ - Bond { - owner: 3, - amount: 19 - }, - Bond { - owner: 4, - amount: 18 - }, - Bond { - owner: 5, - amount: 17 - }, - Bond { - owner: 6, - amount: 16 - } - ] - ); - let bottom_delegations = >::get(&i).unwrap(); - assert_eq!(bottom_delegations.total, 54); - assert_eq!( - bottom_delegations.delegations, - vec![ - Bond { - owner: 7, - amount: 15 - }, - Bond { - owner: 8, - amount: 14 - }, - Bond { - owner: 9, - amount: 13 - }, - Bond { - owner: 10, - amount: 12 - } - ] - ); - let candidate_metadata = >::get(&i).unwrap(); - assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); - assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); - assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); - } - }); + ExtBuilder::default() + .with_balances(vec![(11, 22), (12, 20)]) + .build() + .execute_with(|| { + for i in 11..13 { + let old_delegator_state = Delegator { + id: i, + delegations: OrderedSet::from(vec![ + Bond { + owner: 1, + amount: 10, + }, + Bond { + owner: 2, + amount: 10, + }, + ]), + total: 20, + requests: PendingDelegationRequests::new(), + status: DelegatorStatus::Active, + }; + >::insert(&i, old_delegator_state); + } + assert_ok!(::Currency::reserve(&11, 22)); + assert_ok!(::Currency::reserve(&12, 20)); + assert_eq!(Balances::reserved_balance(&11), 22); + assert_eq!(Balances::reserved_balance(&12), 20); + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 12, + amount: 10, + }, + Bond { + owner: 11, + amount: 11, + }, + Bond { + owner: 10, + amount: 12, + }, + Bond { + owner: 9, + amount: 13, + }, + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 165, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + // total is 165 * 2 = 330 + >::put(330); + assert!(ParachainStaking::is_delegator(&11)); + assert!(ParachainStaking::is_delegator(&12)); + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + assert_event_emitted!(Event::DelegationKicked(11, 1, 11)); + assert_event_emitted!(Event::DelegationKicked(11, 2, 11)); + assert_event_emitted!(Event::DelegationKicked(12, 1, 10)); + assert_event_emitted!(Event::DelegationKicked(12, 2, 10)); + assert_event_emitted!(Event::DelegatorLeft(12, 10)); + assert_event_emitted!(Event::DelegatorLeft(11, 11)); + // kicked 11 and 12 and revoked them + assert_eq!(Balances::free_balance(&11), 22); + assert_eq!(Balances::free_balance(&12), 20); + assert!(!ParachainStaking::is_delegator(&11)); + assert!(!ParachainStaking::is_delegator(&12)); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 54); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + }, + Bond { + owner: 9, + amount: 13 + }, + Bond { + owner: 10, + amount: 12 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); + } + }); } #[test] /// Force revokes candidate state fn split_candidate_state_kicks_extra_bottom_delegations_without_exit() { - ExtBuilder::default() - .with_balances(vec![(11, 32), (12, 30)]) - .build() - .execute_with(|| { - for i in 11..13 { - let old_delegator_state = Delegator { - id: i, - delegations: OrderedSet::from(vec![ - Bond { - owner: 1, - amount: 10, - }, - Bond { - owner: 2, - amount: 10, - }, - Bond { - owner: 3, - amount: 10, - }, - ]), - total: 30, - requests: PendingDelegationRequests::new(), - status: DelegatorStatus::Active, - }; - >::insert(&i, old_delegator_state); - } - assert_ok!(::Currency::reserve(&11, 32)); - assert_ok!(::Currency::reserve(&12, 30)); - assert_eq!(Balances::reserved_balance(&11), 32); - assert_eq!(Balances::reserved_balance(&12), 30); - for i in 1..3 { - let old_candidate_state = CollatorCandidate { - id: i, - bond: 20, - delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), - top_delegations: vec![ - Bond { - owner: 3, - amount: 19, - }, - Bond { - owner: 4, - amount: 18, - }, - Bond { - owner: 5, - amount: 17, - }, - Bond { - owner: 6, - amount: 16, - }, - ], - bottom_delegations: vec![ - Bond { - owner: 12, - amount: 10, - }, - Bond { - owner: 11, - amount: 11, - }, - Bond { - owner: 10, - amount: 12, - }, - Bond { - owner: 9, - amount: 13, - }, - Bond { - owner: 8, - amount: 14, - }, - Bond { - owner: 7, - amount: 15, - }, - ], - total_counted: 90, - total_backing: 165, - request: None, - state: CollatorStatus::Active, - }; - >::insert(&i, old_candidate_state); - } - // total is 165 * 2 + 20 = 330 - >::put(350); - assert!(ParachainStaking::is_delegator(&11)); - assert!(ParachainStaking::is_delegator(&12)); - crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); - assert_event_emitted!(Event::DelegationKicked(11, 1, 11)); - assert_event_emitted!(Event::DelegationKicked(11, 2, 11)); - assert_event_emitted!(Event::DelegationKicked(12, 1, 10)); - assert_event_emitted!(Event::DelegationKicked(12, 2, 10)); - assert_event_not_emitted!(Event::DelegatorLeft(12, 10)); - assert_event_not_emitted!(Event::DelegatorLeft(11, 10)); - // kicked 11 and 12 and revoked them - assert_eq!(Balances::free_balance(&11), 22); - assert_eq!(Balances::free_balance(&12), 20); - assert_eq!(Balances::reserved_balance(&11), 10); - assert_eq!(Balances::reserved_balance(&12), 10); - assert!(ParachainStaking::is_delegator(&11)); - assert!(ParachainStaking::is_delegator(&12)); - for i in 1..3 { - let top_delegations = >::get(&i).unwrap(); - assert_eq!(top_delegations.total, 70); - assert_eq!( - top_delegations.delegations, - vec![ - Bond { - owner: 3, - amount: 19 - }, - Bond { - owner: 4, - amount: 18 - }, - Bond { - owner: 5, - amount: 17 - }, - Bond { - owner: 6, - amount: 16 - } - ] - ); - let bottom_delegations = >::get(&i).unwrap(); - assert_eq!(bottom_delegations.total, 54); - assert_eq!( - bottom_delegations.delegations, - vec![ - Bond { - owner: 7, - amount: 15 - }, - Bond { - owner: 8, - amount: 14 - }, - Bond { - owner: 9, - amount: 13 - }, - Bond { - owner: 10, - amount: 12 - } - ] - ); - let candidate_metadata = >::get(&i).unwrap(); - assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); - assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); - assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); - } - }); + ExtBuilder::default() + .with_balances(vec![(11, 32), (12, 30)]) + .build() + .execute_with(|| { + for i in 11..13 { + let old_delegator_state = Delegator { + id: i, + delegations: OrderedSet::from(vec![ + Bond { + owner: 1, + amount: 10, + }, + Bond { + owner: 2, + amount: 10, + }, + Bond { + owner: 3, + amount: 10, + }, + ]), + total: 30, + requests: PendingDelegationRequests::new(), + status: DelegatorStatus::Active, + }; + >::insert(&i, old_delegator_state); + } + assert_ok!(::Currency::reserve(&11, 32)); + assert_ok!(::Currency::reserve(&12, 30)); + assert_eq!(Balances::reserved_balance(&11), 32); + assert_eq!(Balances::reserved_balance(&12), 30); + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10, 11, 12]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 12, + amount: 10, + }, + Bond { + owner: 11, + amount: 11, + }, + Bond { + owner: 10, + amount: 12, + }, + Bond { + owner: 9, + amount: 13, + }, + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 165, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + // total is 165 * 2 + 20 = 330 + >::put(350); + assert!(ParachainStaking::is_delegator(&11)); + assert!(ParachainStaking::is_delegator(&12)); + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + assert_event_emitted!(Event::DelegationKicked(11, 1, 11)); + assert_event_emitted!(Event::DelegationKicked(11, 2, 11)); + assert_event_emitted!(Event::DelegationKicked(12, 1, 10)); + assert_event_emitted!(Event::DelegationKicked(12, 2, 10)); + assert_event_not_emitted!(Event::DelegatorLeft(12, 10)); + assert_event_not_emitted!(Event::DelegatorLeft(11, 10)); + // kicked 11 and 12 and revoked them + assert_eq!(Balances::free_balance(&11), 22); + assert_eq!(Balances::free_balance(&12), 20); + assert_eq!(Balances::reserved_balance(&11), 10); + assert_eq!(Balances::reserved_balance(&12), 10); + assert!(ParachainStaking::is_delegator(&11)); + assert!(ParachainStaking::is_delegator(&12)); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 54); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + }, + Bond { + owner: 9, + amount: 13 + }, + Bond { + owner: 10, + amount: 12 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); + } + }); } #[test] fn split_candidate_state_migrates_empty_delegations_correctly() { - ExtBuilder::default() - // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) - // .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) - .build() - .execute_with(|| { - // set candidate state as per commented out lines above - for i in 1..5 { - let old_candidate_state = CollatorCandidate { - id: i, - bond: 20, - delegators: OrderedSet::new(), - top_delegations: Vec::new(), - bottom_delegations: Vec::new(), - total_counted: 20, - total_backing: 20, - request: None, - state: CollatorStatus::Active, - }; - >::insert(&i, old_candidate_state); - } - crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); - for i in 1..5 { - let top_delegations = >::get(&i).unwrap(); - assert_eq!(top_delegations.total, 0); - assert!(top_delegations.delegations.is_empty()); - let bottom_delegations = >::get(&i).unwrap(); - assert_eq!(bottom_delegations.total, 0); - assert!(bottom_delegations.delegations.is_empty()); - let candidate_metadata = >::get(&i).unwrap(); - assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Empty); - assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); - assert_eq!(candidate_metadata.lowest_top_delegation_amount, 0); - assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); - assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); - } - }); + ExtBuilder::default() + // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + // .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + .build() + .execute_with(|| { + // set candidate state as per commented out lines above + for i in 1..5 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::new(), + top_delegations: Vec::new(), + bottom_delegations: Vec::new(), + total_counted: 20, + total_backing: 20, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..5 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 0); + assert!(top_delegations.delegations.is_empty()); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 0); + assert!(bottom_delegations.delegations.is_empty()); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 0); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); + } + }); } #[test] fn split_candidate_state_migrates_partial_top_delegations_correctly() { - ExtBuilder::default() - // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) - // .with_candidates(vec![(1, 20), (2, 20)]) - // .with_delegations(vec![(3, 1, 10), (4, 1, 10), (3, 2, 10), (4, 2, 10)]) - .build() - .execute_with(|| { - // set up candidate state as per commented out lines above - for i in 1..3 { - let old_candidate_state = CollatorCandidate { - id: i, - bond: 20, - delegators: OrderedSet::from(vec![3, 4]), - top_delegations: vec![ - Bond { - owner: 3, - amount: 10, - }, - Bond { - owner: 4, - amount: 10, - }, - ], - bottom_delegations: Vec::new(), - total_counted: 40, - total_backing: 40, - request: None, - state: CollatorStatus::Active, - }; - >::insert(&i, old_candidate_state); - } - crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); - for i in 1..3 { - let top_delegations = >::get(&i).unwrap(); - assert_eq!(top_delegations.total, 20); - assert_eq!( - top_delegations.delegations, - vec![ - Bond { - owner: 3, - amount: 10 - }, - Bond { - owner: 4, - amount: 10 - } - ] - ); - let bottom_delegations = >::get(&i).unwrap(); - assert_eq!(bottom_delegations.total, 0); - assert!(bottom_delegations.delegations.is_empty()); - let candidate_metadata = >::get(&i).unwrap(); - assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Partial); - assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); - assert_eq!(candidate_metadata.lowest_top_delegation_amount, 10); - assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); - assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); - } - }); + ExtBuilder::default() + // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20)]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![(3, 1, 10), (4, 1, 10), (3, 2, 10), (4, 2, 10)]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines above + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 10, + }, + Bond { + owner: 4, + amount: 10, + }, + ], + bottom_delegations: Vec::new(), + total_counted: 40, + total_backing: 40, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 20); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 10 + }, + Bond { + owner: 4, + amount: 10 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 0); + assert!(bottom_delegations.delegations.is_empty()); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Partial); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 10); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); + } + }); } #[test] fn split_candidate_state_migrates_full_top_delegations_correctly() { - ExtBuilder::default() - // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) - // .with_candidates(vec![(1, 20), (2, 20)]) - // .with_delegations(vec![ - // (3, 1, 10), - // (4, 1, 10), - // (5, 1, 10), - // (6, 1, 10), - // (3, 2, 10), - // (4, 2, 10), - // (5, 2, 10), - // (6, 2, 10), - // ]) - .build() - .execute_with(|| { - // set up candidate state as per commented out lines - for i in 1..3 { - let old_candidate_state = CollatorCandidate { - id: i, - bond: 20, - delegators: OrderedSet::from(vec![3, 4, 5, 6]), - top_delegations: vec![ - Bond { - owner: 3, - amount: 10, - }, - Bond { - owner: 4, - amount: 10, - }, - Bond { - owner: 5, - amount: 10, - }, - Bond { - owner: 6, - amount: 10, - }, - ], - bottom_delegations: Vec::new(), - total_counted: 60, - total_backing: 60, - request: None, - state: CollatorStatus::Active, - }; - >::insert(&i, old_candidate_state); - } - crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); - for i in 1..3 { - let top_delegations = >::get(&i).unwrap(); - assert_eq!(top_delegations.total, 40); - assert_eq!( - top_delegations.delegations, - vec![ - Bond { - owner: 3, - amount: 10 - }, - Bond { - owner: 4, - amount: 10 - }, - Bond { - owner: 5, - amount: 10 - }, - Bond { - owner: 6, - amount: 10 - } - ] - ); - let bottom_delegations = >::get(&i).unwrap(); - assert_eq!(bottom_delegations.total, 0); - assert!(bottom_delegations.delegations.is_empty()); - let candidate_metadata = >::get(&i).unwrap(); - assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); - assert_eq!(candidate_metadata.lowest_top_delegation_amount, 10); - assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); - assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); - } - }); + ExtBuilder::default() + // .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20), (6, 20)]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![ + // (3, 1, 10), + // (4, 1, 10), + // (5, 1, 10), + // (6, 1, 10), + // (3, 2, 10), + // (4, 2, 10), + // (5, 2, 10), + // (6, 2, 10), + // ]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 10, + }, + Bond { + owner: 4, + amount: 10, + }, + Bond { + owner: 5, + amount: 10, + }, + Bond { + owner: 6, + amount: 10, + }, + ], + bottom_delegations: Vec::new(), + total_counted: 60, + total_backing: 60, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 40); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 10 + }, + Bond { + owner: 4, + amount: 10 + }, + Bond { + owner: 5, + amount: 10 + }, + Bond { + owner: 6, + amount: 10 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 0); + assert!(bottom_delegations.delegations.is_empty()); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Empty); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 10); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 0); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 0); + } + }); } #[test] fn split_candidate_state_migrates_full_top_partial_bottom_delegations_correctly() { - ExtBuilder::default() - // .with_balances(vec![ - // (1, 20), - // (2, 20), - // (3, 38), - // (4, 36), - // (5, 34), - // (6, 32), - // (7, 30), - // (8, 28), - // ]) - // .with_candidates(vec![(1, 20), (2, 20)]) - // .with_delegations(vec![ - // (3, 1, 19), - // (4, 1, 18), - // (5, 1, 17), - // (6, 1, 16), - // (7, 1, 15), - // (8, 1, 14), - // (3, 2, 19), - // (4, 2, 18), - // (5, 2, 17), - // (6, 2, 16), - // (7, 2, 15), - // (8, 2, 14), - // ]) - .build() - .execute_with(|| { - // set up candidate state as per commented out lines - for i in 1..3 { - let old_candidate_state = CollatorCandidate { - id: i, - bond: 20, - delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8]), - top_delegations: vec![ - Bond { - owner: 3, - amount: 19, - }, - Bond { - owner: 4, - amount: 18, - }, - Bond { - owner: 5, - amount: 17, - }, - Bond { - owner: 6, - amount: 16, - }, - ], - bottom_delegations: vec![ - Bond { - owner: 8, - amount: 14, - }, - Bond { - owner: 7, - amount: 15, - }, - ], - total_counted: 90, - total_backing: 119, - request: None, - state: CollatorStatus::Active, - }; - >::insert(&i, old_candidate_state); - } - crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); - for i in 1..3 { - let top_delegations = >::get(&i).unwrap(); - assert_eq!(top_delegations.total, 70); - assert_eq!( - top_delegations.delegations, - vec![ - Bond { - owner: 3, - amount: 19 - }, - Bond { - owner: 4, - amount: 18 - }, - Bond { - owner: 5, - amount: 17 - }, - Bond { - owner: 6, - amount: 16 - } - ] - ); - let bottom_delegations = >::get(&i).unwrap(); - assert_eq!(bottom_delegations.total, 29); - assert_eq!( - bottom_delegations.delegations, - vec![ - Bond { - owner: 7, - amount: 15 - }, - Bond { - owner: 8, - amount: 14 - } - ] - ); - let candidate_metadata = >::get(&i).unwrap(); - assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Partial); - assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); - assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); - assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 14); - } - }); + ExtBuilder::default() + // .with_balances(vec![ + // (1, 20), + // (2, 20), + // (3, 38), + // (4, 36), + // (5, 34), + // (6, 32), + // (7, 30), + // (8, 28), + // ]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![ + // (3, 1, 19), + // (4, 1, 18), + // (5, 1, 17), + // (6, 1, 16), + // (7, 1, 15), + // (8, 1, 14), + // (3, 2, 19), + // (4, 2, 18), + // (5, 2, 17), + // (6, 2, 16), + // (7, 2, 15), + // (8, 2, 14), + // ]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 119, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 29); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Partial); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 14); + } + }); } #[test] fn split_candidate_state_migrates_full_top_and_bottom_delegations_correctly() { - ExtBuilder::default() - // .with_balances(vec![ - // (1, 20), - // (2, 20), - // (3, 38), - // (4, 36), - // (5, 34), - // (6, 32), - // (7, 30), - // (8, 28), - // (9, 26), - // (10, 24), - // ]) - // .with_candidates(vec![(1, 20), (2, 20)]) - // .with_delegations(vec![ - // (3, 1, 19), - // (4, 1, 18), - // (5, 1, 17), - // (6, 1, 16), - // (7, 1, 15), - // (8, 1, 14), - // (9, 1, 13), - // (10, 1, 12), - // (3, 2, 19), - // (4, 2, 18), - // (5, 2, 17), - // (6, 2, 16), - // (7, 2, 15), - // (8, 2, 14), - // (9, 2, 13), - // (10, 2, 12), - // ]) - .build() - .execute_with(|| { - // set up candidate state as per commented out lines - for i in 1..3 { - let old_candidate_state = CollatorCandidate { - id: i, - bond: 20, - delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10]), - top_delegations: vec![ - Bond { - owner: 3, - amount: 19, - }, - Bond { - owner: 4, - amount: 18, - }, - Bond { - owner: 5, - amount: 17, - }, - Bond { - owner: 6, - amount: 16, - }, - ], - bottom_delegations: vec![ - Bond { - owner: 10, - amount: 12, - }, - Bond { - owner: 9, - amount: 13, - }, - Bond { - owner: 8, - amount: 14, - }, - Bond { - owner: 7, - amount: 15, - }, - ], - total_counted: 90, - total_backing: 144, - request: None, - state: CollatorStatus::Active, - }; - >::insert(&i, old_candidate_state); - } - crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); - for i in 1..3 { - let top_delegations = >::get(&i).unwrap(); - assert_eq!(top_delegations.total, 70); - assert_eq!( - top_delegations.delegations, - vec![ - Bond { - owner: 3, - amount: 19 - }, - Bond { - owner: 4, - amount: 18 - }, - Bond { - owner: 5, - amount: 17 - }, - Bond { - owner: 6, - amount: 16 - } - ] - ); - let bottom_delegations = >::get(&i).unwrap(); - assert_eq!(bottom_delegations.total, 54); - assert_eq!( - bottom_delegations.delegations, - vec![ - Bond { - owner: 7, - amount: 15 - }, - Bond { - owner: 8, - amount: 14 - }, - Bond { - owner: 9, - amount: 13 - }, - Bond { - owner: 10, - amount: 12 - } - ] - ); - let candidate_metadata = >::get(&i).unwrap(); - assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); - assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); - assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); - assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); - } - }); + ExtBuilder::default() + // .with_balances(vec![ + // (1, 20), + // (2, 20), + // (3, 38), + // (4, 36), + // (5, 34), + // (6, 32), + // (7, 30), + // (8, 28), + // (9, 26), + // (10, 24), + // ]) + // .with_candidates(vec![(1, 20), (2, 20)]) + // .with_delegations(vec![ + // (3, 1, 19), + // (4, 1, 18), + // (5, 1, 17), + // (6, 1, 16), + // (7, 1, 15), + // (8, 1, 14), + // (9, 1, 13), + // (10, 1, 12), + // (3, 2, 19), + // (4, 2, 18), + // (5, 2, 17), + // (6, 2, 16), + // (7, 2, 15), + // (8, 2, 14), + // (9, 2, 13), + // (10, 2, 12), + // ]) + .build() + .execute_with(|| { + // set up candidate state as per commented out lines + for i in 1..3 { + let old_candidate_state = CollatorCandidate { + id: i, + bond: 20, + delegators: OrderedSet::from(vec![3, 4, 5, 6, 7, 8, 9, 10]), + top_delegations: vec![ + Bond { + owner: 3, + amount: 19, + }, + Bond { + owner: 4, + amount: 18, + }, + Bond { + owner: 5, + amount: 17, + }, + Bond { + owner: 6, + amount: 16, + }, + ], + bottom_delegations: vec![ + Bond { + owner: 10, + amount: 12, + }, + Bond { + owner: 9, + amount: 13, + }, + Bond { + owner: 8, + amount: 14, + }, + Bond { + owner: 7, + amount: 15, + }, + ], + total_counted: 90, + total_backing: 144, + request: None, + state: CollatorStatus::Active, + }; + >::insert(&i, old_candidate_state); + } + crate::migrations::SplitCandidateStateToDecreasePoV::::on_runtime_upgrade(); + for i in 1..3 { + let top_delegations = >::get(&i).unwrap(); + assert_eq!(top_delegations.total, 70); + assert_eq!( + top_delegations.delegations, + vec![ + Bond { + owner: 3, + amount: 19 + }, + Bond { + owner: 4, + amount: 18 + }, + Bond { + owner: 5, + amount: 17 + }, + Bond { + owner: 6, + amount: 16 + } + ] + ); + let bottom_delegations = >::get(&i).unwrap(); + assert_eq!(bottom_delegations.total, 54); + assert_eq!( + bottom_delegations.delegations, + vec![ + Bond { + owner: 7, + amount: 15 + }, + Bond { + owner: 8, + amount: 14 + }, + Bond { + owner: 9, + amount: 13 + }, + Bond { + owner: 10, + amount: 12 + } + ] + ); + let candidate_metadata = >::get(&i).unwrap(); + assert_eq!(candidate_metadata.top_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.bottom_capacity, CapacityStatus::Full); + assert_eq!(candidate_metadata.lowest_top_delegation_amount, 16); + assert_eq!(candidate_metadata.highest_bottom_delegation_amount, 15); + assert_eq!(candidate_metadata.lowest_bottom_delegation_amount, 12); + } + }); } // #[test] @@ -6256,31 +6260,31 @@ fn split_candidate_state_migrates_full_top_and_bottom_delegations_correctly() { #[test] fn verify_purge_storage_migration_works() { - use crate::{Points, Round, RoundInfo, Staked}; - ExtBuilder::default().build().execute_with(|| { - // mutate storage similar to if 10 rounds had passed - for i in 1..=10 { - >::insert(i, 100); - >::insert(i, 100); - } - // set the round information to the 10th round - // (we do not use roll_to because the payment logic uses `take` in the code) - >::put(RoundInfo { - current: 10, - first: 45, - length: 5, - }); - // execute the migration - crate::migrations::PurgeStaleStorage::::on_runtime_upgrade(); - // verify that all inserted items are removed except last 2 rounds - for i in 1..=8 { - assert_eq!(>::get(i), 0); - assert_eq!(>::get(i), 0); - } - // last 2 rounds are still stored (necessary for future payouts) - for i in 9..=10 { - assert_eq!(>::get(i), 100); - assert_eq!(>::get(i), 100); - } - }); + use crate::{Points, Round, RoundInfo, Staked}; + ExtBuilder::default().build().execute_with(|| { + // mutate storage similar to if 10 rounds had passed + for i in 1..=10 { + >::insert(i, 100); + >::insert(i, 100); + } + // set the round information to the 10th round + // (we do not use roll_to because the payment logic uses `take` in the code) + >::put(RoundInfo { + current: 10, + first: 45, + length: 5, + }); + // execute the migration + crate::migrations::PurgeStaleStorage::::on_runtime_upgrade(); + // verify that all inserted items are removed except last 2 rounds + for i in 1..=8 { + assert_eq!(>::get(i), 0); + assert_eq!(>::get(i), 0); + } + // last 2 rounds are still stored (necessary for future payouts) + for i in 9..=10 { + assert_eq!(>::get(i), 100); + assert_eq!(>::get(i), 100); + } + }); } diff --git a/pallets/parachain-staking/src/weights.rs b/pallets/parachain-staking/src/weights.rs index 6a12cf0f..e183605e 100644 --- a/pallets/parachain-staking/src/weights.rs +++ b/pallets/parachain-staking/src/weights.rs @@ -44,419 +44,429 @@ #![allow(unused_imports)] use frame_support::{ - traits::Get, - weights::{constants::RocksDbWeight, Weight}, + traits::Get, + weights::{constants::RocksDbWeight, Weight}, }; use sp_std::marker::PhantomData; /// Weight functions needed for parachain_staking. pub trait WeightInfo { - fn hotfix_remove_delegation_requests(x: u32) -> Weight; - fn hotfix_update_candidate_pool_value(x: u32) -> Weight; - fn set_staking_expectations() -> Weight; - fn set_inflation() -> Weight; - fn set_parachain_bond_account() -> Weight; - fn set_parachain_bond_reserve_percent() -> Weight; - fn set_total_selected() -> Weight; - fn set_collator_commission() -> Weight; - fn set_blocks_per_round() -> Weight; - fn join_candidates(x: u32) -> Weight; - fn schedule_leave_candidates(x: u32) -> Weight; - fn execute_leave_candidates(x: u32) -> Weight; - fn cancel_leave_candidates(x: u32) -> Weight; - fn go_offline() -> Weight; - fn go_online() -> Weight; - fn candidate_bond_more() -> Weight; - fn schedule_candidate_bond_less() -> Weight; - fn execute_candidate_bond_less() -> Weight; - fn cancel_candidate_bond_less() -> Weight; - fn delegate(x: u32, y: u32) -> Weight; - fn schedule_leave_delegators() -> Weight; - fn execute_leave_delegators(x: u32) -> Weight; - fn cancel_leave_delegators() -> Weight; - fn schedule_revoke_delegation() -> Weight; - fn delegator_bond_more() -> Weight; - fn schedule_delegator_bond_less() -> Weight; - fn execute_revoke_delegation() -> Weight; - fn execute_delegator_bond_less() -> Weight; - fn cancel_revoke_delegation() -> Weight; - fn cancel_delegator_bond_less() -> Weight; - fn round_transition_on_initialize(x: u32, y: u32) -> Weight; - fn base_on_initialize() -> Weight; - fn pay_one_collator_reward(y: u32) -> Weight; + fn hotfix_remove_delegation_requests(x: u32) -> Weight; + fn hotfix_update_candidate_pool_value(x: u32) -> Weight; + fn set_staking_expectations() -> Weight; + fn set_inflation() -> Weight; + fn set_parachain_bond_account() -> Weight; + fn set_parachain_bond_reserve_percent() -> Weight; + fn set_total_selected() -> Weight; + fn set_collator_commission() -> Weight; + fn set_blocks_per_round() -> Weight; + fn join_candidates(x: u32) -> Weight; + fn schedule_leave_candidates(x: u32) -> Weight; + fn execute_leave_candidates(x: u32) -> Weight; + fn cancel_leave_candidates(x: u32) -> Weight; + fn go_offline() -> Weight; + fn go_online() -> Weight; + fn candidate_bond_more() -> Weight; + fn schedule_candidate_bond_less() -> Weight; + fn execute_candidate_bond_less() -> Weight; + fn cancel_candidate_bond_less() -> Weight; + fn delegate(x: u32, y: u32) -> Weight; + fn schedule_leave_delegators() -> Weight; + fn execute_leave_delegators(x: u32) -> Weight; + fn cancel_leave_delegators() -> Weight; + fn schedule_revoke_delegation() -> Weight; + fn delegator_bond_more() -> Weight; + fn schedule_delegator_bond_less() -> Weight; + fn execute_revoke_delegation() -> Weight; + fn execute_delegator_bond_less() -> Weight; + fn cancel_revoke_delegation() -> Weight; + fn cancel_delegator_bond_less() -> Weight; + fn round_transition_on_initialize(x: u32, y: u32) -> Weight; + fn base_on_initialize() -> Weight; + fn pay_one_collator_reward(y: u32) -> Weight; } /// Weights for parachain_staking using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn hotfix_remove_delegation_requests(x: u32) -> Weight { - (0 as Weight) // Standard Error: 3_000 - .saturating_add((8_132_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) - .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(x as Weight))) - } - fn hotfix_update_candidate_pool_value(x: u32) -> Weight { - (0 as Weight) // Standard Error: 147_000 - .saturating_add((26_825_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn set_staking_expectations() -> Weight { - (20_719_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_inflation() -> Weight { - (63_011_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_account() -> Weight { - (20_434_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_reserve_percent() -> Weight { - (19_239_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_total_selected() -> Weight { - (18_402_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_collator_commission() -> Weight { - (18_178_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn set_blocks_per_round() -> Weight { - (65_939_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn join_candidates(x: u32) -> Weight { - (80_619_000 as Weight) // Standard Error: 1_000 - .saturating_add((107_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(8 as Weight)) - } - fn schedule_leave_candidates(x: u32) -> Weight { - (50_933_000 as Weight) // Standard Error: 1_000 - .saturating_add((108_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn execute_leave_candidates(x: u32) -> Weight { - (8_634_000 as Weight) // Standard Error: 6_000 - .saturating_add((26_979_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) - } - fn cancel_leave_candidates(x: u32) -> Weight { - (43_482_000 as Weight) // Standard Error: 0 - .saturating_add((111_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn go_offline() -> Weight { - (30_778_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn go_online() -> Weight { - (31_178_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn candidate_bond_more() -> Weight { - (53_492_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(6 as Weight)) - } - fn schedule_candidate_bond_less() -> Weight { - (29_393_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn execute_candidate_bond_less() -> Weight { - (62_395_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(6 as Weight)) - } - fn cancel_candidate_bond_less() -> Weight { - (25_564_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn delegate(x: u32, y: u32) -> Weight { - (103_760_000 as Weight) // Standard Error: 12_000 - .saturating_add((198_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3000 - .saturating_add((112_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(T::DbWeight::get().reads(10 as Weight)) - .saturating_add(T::DbWeight::get().writes(8 as Weight)) - } - fn schedule_leave_delegators() -> Weight { - (30_908_000 as Weight) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn execute_leave_delegators(x: u32) -> Weight { - (1_091_000 as Weight) // Standard Error: 14_000 - .saturating_add((37_192_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) - } - fn cancel_leave_delegators() -> Weight { - (26_796_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn schedule_revoke_delegation() -> Weight { - (37_580_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn delegator_bond_more() -> Weight { - (65_757_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } - fn schedule_delegator_bond_less() -> Weight { - (70_859_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } - fn execute_revoke_delegation() -> Weight { - (87_836_000 as Weight) - .saturating_add(T::DbWeight::get().reads(10 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } - fn execute_delegator_bond_less() -> Weight { - (80_983_000 as Weight) - .saturating_add(T::DbWeight::get().reads(11 as Weight)) - .saturating_add(T::DbWeight::get().writes(8 as Weight)) - } - fn cancel_revoke_delegation() -> Weight { - (37_923_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } - fn cancel_delegator_bond_less() -> Weight { - (70_813_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } - fn round_transition_on_initialize(x: u32, y: u32) -> Weight { - (0 as Weight) // Standard Error: 4_087_000 - // Standard Error: 12_000 - .saturating_add((100_164_000 as Weight).saturating_mul(x as Weight)) - .saturating_add((1_202_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) - .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(x as Weight))) - } - fn base_on_initialize() -> Weight { - (4_913_000 as Weight).saturating_add(T::DbWeight::get().reads(1 as Weight)) - } - fn pay_one_collator_reward(y: u32) -> Weight { - (0 as Weight) - // Standard Error: 6_000 - .saturating_add((23_284_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(T::DbWeight::get().reads(11 as Weight)) - .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(y as Weight))) - .saturating_add(T::DbWeight::get().writes(6 as Weight)) - .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(y as Weight))) - } + fn hotfix_remove_delegation_requests(x: u32) -> Weight { + (0 as Weight) // Standard Error: 3_000 + .saturating_add((8_132_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(x as Weight))) + } + fn hotfix_update_candidate_pool_value(x: u32) -> Weight { + (0 as Weight) // Standard Error: 147_000 + .saturating_add((26_825_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn set_staking_expectations() -> Weight { + (20_719_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_inflation() -> Weight { + (63_011_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_account() -> Weight { + (20_434_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_reserve_percent() -> Weight { + (19_239_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_total_selected() -> Weight { + (18_402_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_collator_commission() -> Weight { + (18_178_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn set_blocks_per_round() -> Weight { + (65_939_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn join_candidates(x: u32) -> Weight { + (80_619_000 as Weight) // Standard Error: 1_000 + .saturating_add((107_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_candidates(x: u32) -> Weight { + (50_933_000 as Weight) // Standard Error: 1_000 + .saturating_add((108_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn execute_leave_candidates(x: u32) -> Weight { + (8_634_000 as Weight) // Standard Error: 6_000 + .saturating_add((26_979_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) + } + fn cancel_leave_candidates(x: u32) -> Weight { + (43_482_000 as Weight) // Standard Error: 0 + .saturating_add((111_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn go_offline() -> Weight { + (30_778_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn go_online() -> Weight { + (31_178_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn candidate_bond_more() -> Weight { + (53_492_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + } + fn schedule_candidate_bond_less() -> Weight { + (29_393_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn execute_candidate_bond_less() -> Weight { + (62_395_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + } + fn cancel_candidate_bond_less() -> Weight { + (25_564_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn delegate(x: u32, y: u32) -> Weight { + (103_760_000 as Weight) // Standard Error: 12_000 + .saturating_add((198_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3000 + .saturating_add((112_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_delegators() -> Weight { + (30_908_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn execute_leave_delegators(x: u32) -> Weight { + (1_091_000 as Weight) // Standard Error: 14_000 + .saturating_add((37_192_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) + } + fn cancel_leave_delegators() -> Weight { + (26_796_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn schedule_revoke_delegation() -> Weight { + (37_580_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn delegator_bond_more() -> Weight { + (65_757_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn schedule_delegator_bond_less() -> Weight { + (70_859_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn execute_revoke_delegation() -> Weight { + (87_836_000 as Weight) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn execute_delegator_bond_less() -> Weight { + (80_983_000 as Weight) + .saturating_add(T::DbWeight::get().reads(11 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) + } + fn cancel_revoke_delegation() -> Weight { + (37_923_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn cancel_delegator_bond_less() -> Weight { + (70_813_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } + fn round_transition_on_initialize(x: u32, y: u32) -> Weight { + (0 as Weight) // Standard Error: 4_087_000 + // Standard Error: 12_000 + .saturating_add((100_164_000 as Weight).saturating_mul(x as Weight)) + .saturating_add((1_202_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(x as Weight))) + } + fn base_on_initialize() -> Weight { + (4_913_000 as Weight).saturating_add(T::DbWeight::get().reads(1 as Weight)) + } + fn pay_one_collator_reward(y: u32) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((23_284_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(T::DbWeight::get().reads(11 as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(y as Weight))) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(y as Weight))) + } } // For backwards compatibility and tests impl WeightInfo for () { - fn hotfix_remove_delegation_requests(x: u32) -> Weight { - (0 as Weight) // Standard Error: 3_000 - .saturating_add((8_132_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) - .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(x as Weight))) - } - fn hotfix_update_candidate_pool_value(x: u32) -> Weight { - (0 as Weight) // Standard Error: 147_000 - .saturating_add((26_825_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - fn set_staking_expectations() -> Weight { - (20_719_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_inflation() -> Weight { - (63_011_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_account() -> Weight { - (20_434_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_parachain_bond_reserve_percent() -> Weight { - (19_239_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_total_selected() -> Weight { - (18_402_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_collator_commission() -> Weight { - (18_178_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn set_blocks_per_round() -> Weight { - (65_939_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn join_candidates(x: u32) -> Weight { - (80_619_000 as Weight) // Standard Error: 1_000 - .saturating_add((107_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(8 as Weight)) - } - fn schedule_leave_candidates(x: u32) -> Weight { - (50_933_000 as Weight) // Standard Error: 1_000 - .saturating_add((108_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn execute_leave_candidates(x: u32) -> Weight { - (8_634_000 as Weight) // Standard Error: 6_000 - .saturating_add((26_979_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) - .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) - .saturating_add(RocksDbWeight::get().writes(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) - } - fn cancel_leave_candidates(x: u32) -> Weight { - (43_482_000 as Weight) // Standard Error: 0 - .saturating_add((111_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn go_offline() -> Weight { - (30_778_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn go_online() -> Weight { - (31_178_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn candidate_bond_more() -> Weight { - (53_492_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) - .saturating_add(RocksDbWeight::get().writes(6 as Weight)) - } - fn schedule_candidate_bond_less() -> Weight { - (29_393_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn execute_candidate_bond_less() -> Weight { - (62_395_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(6 as Weight)) - } - fn cancel_candidate_bond_less() -> Weight { - (25_564_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn delegate(x: u32, y: u32) -> Weight { - (103_760_000 as Weight) // Standard Error: 12_000 - .saturating_add((198_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3000 - .saturating_add((112_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(RocksDbWeight::get().reads(10 as Weight)) - .saturating_add(RocksDbWeight::get().writes(8 as Weight)) - } - fn schedule_leave_delegators() -> Weight { - (30_908_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn execute_leave_delegators(x: u32) -> Weight { - (1_091_000 as Weight) // Standard Error: 14_000 - .saturating_add((37_192_000 as Weight).saturating_mul(x as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(x as Weight))) - } - fn cancel_leave_delegators() -> Weight { - (26_796_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn schedule_revoke_delegation() -> Weight { - (37_580_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn delegator_bond_more() -> Weight { - (65_757_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(7 as Weight)) - } - fn schedule_delegator_bond_less() -> Weight { - (70_859_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(9 as Weight)) - .saturating_add(RocksDbWeight::get().writes(7 as Weight)) - } - fn execute_revoke_delegation() -> Weight { - (87_836_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(10 as Weight)) - .saturating_add(RocksDbWeight::get().writes(7 as Weight)) - } - fn execute_delegator_bond_less() -> Weight { - (80_983_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(11 as Weight)) - .saturating_add(RocksDbWeight::get().writes(8 as Weight)) - } - fn cancel_revoke_delegation() -> Weight { - (37_923_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn cancel_delegator_bond_less() -> Weight { - (70_813_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - fn round_transition_on_initialize(x: u32, y: u32) -> Weight { - (0 as Weight) // Standard Error: 4_087_000 - // Standard Error: 12_000 - .saturating_add((100_164_000 as Weight).saturating_mul(x as Weight)) - .saturating_add((1_202_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) - .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(x as Weight))) - } - fn base_on_initialize() -> Weight { - (4_913_000 as Weight).saturating_add(RocksDbWeight::get().reads(1 as Weight)) - } - fn pay_one_collator_reward(y: u32) -> Weight { - (0 as Weight) - // Standard Error: 6_000 - .saturating_add((23_284_000 as Weight).saturating_mul(y as Weight)) - .saturating_add(RocksDbWeight::get().reads(11 as Weight)) - .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(y as Weight))) - .saturating_add(RocksDbWeight::get().writes(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(y as Weight))) - } + fn hotfix_remove_delegation_requests(x: u32) -> Weight { + (0 as Weight) // Standard Error: 3_000 + .saturating_add((8_132_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add( + RocksDbWeight::get().writes((1 as Weight).saturating_mul(x as Weight)), + ) + } + fn hotfix_update_candidate_pool_value(x: u32) -> Weight { + (0 as Weight) // Standard Error: 147_000 + .saturating_add((26_825_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn set_staking_expectations() -> Weight { + (20_719_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_inflation() -> Weight { + (63_011_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_account() -> Weight { + (20_434_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_parachain_bond_reserve_percent() -> Weight { + (19_239_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_total_selected() -> Weight { + (18_402_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_collator_commission() -> Weight { + (18_178_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn set_blocks_per_round() -> Weight { + (65_939_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn join_candidates(x: u32) -> Weight { + (80_619_000 as Weight) // Standard Error: 1_000 + .saturating_add((107_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_candidates(x: u32) -> Weight { + (50_933_000 as Weight) // Standard Error: 1_000 + .saturating_add((108_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn execute_leave_candidates(x: u32) -> Weight { + (8_634_000 as Weight) // Standard Error: 6_000 + .saturating_add((26_979_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + .saturating_add( + RocksDbWeight::get().writes((2 as Weight).saturating_mul(x as Weight)), + ) + } + fn cancel_leave_candidates(x: u32) -> Weight { + (43_482_000 as Weight) // Standard Error: 0 + .saturating_add((111_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn go_offline() -> Weight { + (30_778_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn go_online() -> Weight { + (31_178_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn candidate_bond_more() -> Weight { + (53_492_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } + fn schedule_candidate_bond_less() -> Weight { + (29_393_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn execute_candidate_bond_less() -> Weight { + (62_395_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + } + fn cancel_candidate_bond_less() -> Weight { + (25_564_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn delegate(x: u32, y: u32) -> Weight { + (103_760_000 as Weight) // Standard Error: 12_000 + .saturating_add((198_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3000 + .saturating_add((112_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(RocksDbWeight::get().reads(10 as Weight)) + .saturating_add(RocksDbWeight::get().writes(8 as Weight)) + } + fn schedule_leave_delegators() -> Weight { + (30_908_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn execute_leave_delegators(x: u32) -> Weight { + (1_091_000 as Weight) // Standard Error: 14_000 + .saturating_add((37_192_000 as Weight).saturating_mul(x as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(x as Weight))) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + .saturating_add( + RocksDbWeight::get().writes((2 as Weight).saturating_mul(x as Weight)), + ) + } + fn cancel_leave_delegators() -> Weight { + (26_796_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn schedule_revoke_delegation() -> Weight { + (37_580_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn delegator_bond_more() -> Weight { + (65_757_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn schedule_delegator_bond_less() -> Weight { + (70_859_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(9 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn execute_revoke_delegation() -> Weight { + (87_836_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(10 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } + fn execute_delegator_bond_less() -> Weight { + (80_983_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(11 as Weight)) + .saturating_add(RocksDbWeight::get().writes(8 as Weight)) + } + fn cancel_revoke_delegation() -> Weight { + (37_923_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn cancel_delegator_bond_less() -> Weight { + (70_813_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn round_transition_on_initialize(x: u32, y: u32) -> Weight { + (0 as Weight) // Standard Error: 4_087_000 + // Standard Error: 12_000 + .saturating_add((100_164_000 as Weight).saturating_mul(x as Weight)) + .saturating_add((1_202_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(x as Weight))) + .saturating_add( + RocksDbWeight::get().writes((3 as Weight).saturating_mul(x as Weight)), + ) + } + fn base_on_initialize() -> Weight { + (4_913_000 as Weight).saturating_add(RocksDbWeight::get().reads(1 as Weight)) + } + fn pay_one_collator_reward(y: u32) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((23_284_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(RocksDbWeight::get().reads(11 as Weight)) + .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(y as Weight))) + .saturating_add(RocksDbWeight::get().writes(6 as Weight)) + .saturating_add( + RocksDbWeight::get().writes((1 as Weight).saturating_mul(y as Weight)), + ) + } } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index bdafbd5c..33f33919 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -51,7 +51,7 @@ pub use frame_support::{ construct_runtime, parameter_types, StorageValue, match_type, traits::{ KeyOwnerProofSystem, Randomness, IsInVec, Everything, Nothing, EnsureOrigin, - OnUnbalanced, Imbalance, Get, Contains, EqualPrivilegeOnly, + OnUnbalanced, Imbalance, Get, Contains, EqualPrivilegeOnly, ConstU32, }, weights::{ Weight, IdentityFee, DispatchClass, @@ -107,6 +107,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, + state_version: 0, }; /// 1 in 4 blocks (on average) will be primary babe blocks @@ -206,6 +207,7 @@ impl frame_system::Config for Runtime { /// What to do if the user wants the code set to something. Just use `()` unless you are in /// cumulus. type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + type MaxConsumers = ConstU32<12>; } parameter_types! { @@ -228,13 +230,20 @@ parameter_types! { // Allow emergency. pub const InstantAllowed: bool = true; } + pub struct AssumeRootIsSudo(); impl EnsureOrigin for AssumeRootIsSudo { type Success = AccountId; + fn try_origin(o: Origin) -> Result { + use sp_core::Decode; + let f: Result<_, _> = o.into(); f.and_then(|t| match t { - RawOrigin::Root => Ok(Sudo::key()), + RawOrigin::Root => Ok(Sudo::key().unwrap_or( + AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + )), r => Err(Origin::from(r)), }) } @@ -288,6 +297,7 @@ parameter_types! { /// This value would be slashed if proposal rejected. pub const ProposalBond: Permill = Permill::from_percent(5); pub const ProposalBondMinimum: Balance = CurrencyId::NATIVE.times(100); + pub const ProposalBondMaximum: Balance = CurrencyId::NATIVE.times(1000); pub const MaxApprovals: u32 = 100; } @@ -304,6 +314,7 @@ impl pallet_treasury::Config for Runtime { type OnSlash = Treasury; type ProposalBond = ProposalBond; type ProposalBondMinimum = ProposalBondMinimum; + type ProposalBondMaximum = ProposalBondMaximum; type SpendPeriod = SpendPeriod; // Not burning. type Burn = (); @@ -315,6 +326,7 @@ impl pallet_treasury::Config for Runtime { parameter_types! { pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block; pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = None; } impl pallet_scheduler::Config for Runtime { @@ -327,6 +339,8 @@ impl pallet_scheduler::Config for Runtime { type OriginPrivilegeCmp = EqualPrivilegeOnly; type MaxScheduledPerBlock = MaxScheduledPerBlock; type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type PreimageProvider = (); + type NoPreimagePostponement = NoPreimagePostponement; } parameter_types! { @@ -426,7 +440,7 @@ parameter_types! { impl cumulus_pallet_parachain_system::Config for Runtime { type Event = Event; - type OnValidationData = (); + type OnSystemEvent = (); type SelfParaId = parachain_info::Pallet; type OutboundXcmpMessageSource = XcmpQueue; type XcmpMessageHandler = XcmpQueue; @@ -444,18 +458,24 @@ parameter_types! { pub const DefaultBlocksPerRound: u32 = 300; /// Collator candidate exits are delayed by 2 hours (2 * 300 * block_time) pub const LeaveCandidatesDelay: u32 = 2; + // Rounds before the candidate bond increase/decrease can be executed. + pub const CandidateBondLessDelay: u32 = 2; /// Nominator exits are delayed by 2 hours (2 * 300 * block_time) - pub const LeaveNominatorsDelay: u32 = 2; + pub const LeaveDelegatorsDelay: u32 = 2; /// Nomination revocations are delayed by 2 hours (2 * 300 * block_time) - pub const RevokeNominationDelay: u32 = 2; + pub const RevokeDelegationDelay: u32 = 2; + /// Rounds before the delegator bond increase/decrease can be executed + pub const DelegationBondLessDelay: u32 = 2; /// Reward payments are delayed by 2 hours (2 * 300 * block_time) pub const RewardPaymentDelay: u32 = 2; /// Minimum 8 collators selected per round, default at genesis and minimum forever after pub const MinSelectedCandidates: u32 = 8; - /// Maximum 10 nominators per collator - pub const MaxNominatorsPerCollator: u32 = 10; - /// Maximum 25 collators per nominator - pub const MaxCollatorsPerNominator: u32 = 25; + /// Maximum top 10 delegators per collator metters + pub const MaxTopDelegationsPerCandidate: u32 = 10; + /// Maximum bottom delegations per candidate + pub const MaxBottomDelegationsPerCandidate: u32 = 50; + /// Maximum delegations per delegator + pub const MaxDelegationsPerDelegator: u32 = 25; /// Default fixed percent a collator takes off the top of due rewards is 20% pub const DefaultCollatorCommission: Perbill = Perbill::from_percent(20); /// Default percent of inflation set aside for parachain bond every round @@ -463,9 +483,9 @@ parameter_types! { /// Minimum stake required to become a collator is 1_000 pub const MinCollatorStk: Balance = CurrencyId::NATIVE.times(1000); /// Minimum stake required to be reserved to be a candidate is 100 - pub const MinCollatorCandidateStk: Balance = CurrencyId::NATIVE.times(100); - /// Minimum stake required to be reserved to be a nominator is 5 - pub const MinNominatorStk: Balance = CurrencyId::NATIVE.times(1); + pub const MinCandidateStk: Balance = CurrencyId::NATIVE.times(100); + /// Minimum stake required to be reserved to be a delegator is 1. + pub const MinDelegatorStk: Balance = CurrencyId::NATIVE.times(1); } impl parachain_staking::Config for Runtime { type Event = Event; @@ -473,25 +493,27 @@ impl parachain_staking::Config for Runtime { type MonetaryGovernanceOrigin = EnsureRoot; type MinBlocksPerRound = MinBlocksPerRound; type DefaultBlocksPerRound = DefaultBlocksPerRound; + type CandidateBondLessDelay = CandidateBondLessDelay; type LeaveCandidatesDelay = LeaveCandidatesDelay; - type LeaveNominatorsDelay = LeaveNominatorsDelay; - type RevokeNominationDelay = RevokeNominationDelay; + type LeaveDelegatorsDelay = LeaveDelegatorsDelay; + type RevokeDelegationDelay = RevokeDelegationDelay; + type DelegationBondLessDelay = DelegationBondLessDelay; type RewardPaymentDelay = RewardPaymentDelay; type MinSelectedCandidates = MinSelectedCandidates; - type MaxNominatorsPerCollator = MaxNominatorsPerCollator; - type MaxCollatorsPerNominator = MaxCollatorsPerNominator; + type MaxTopDelegationsPerCandidate = MaxTopDelegationsPerCandidate; + type MaxBottomDelegationsPerCandidate = MaxBottomDelegationsPerCandidate; + type MaxDelegationsPerDelegator = MaxDelegationsPerDelegator; type DefaultCollatorCommission = DefaultCollatorCommission; type DefaultParachainBondReservePercent = DefaultParachainBondReservePercent; type MinCollatorStk = MinCollatorStk; - type MinCollatorCandidateStk = MinCollatorCandidateStk; - type MinNomination = MinNominatorStk; - type MinNominatorStk = MinNominatorStk; + type MinCandidateStk = MinCandidateStk; + type MinDelegatorStk = MinDelegatorStk; + type MinDelegation = MinDelegatorStk; type WeightInfo = parachain_staking::weights::SubstrateWeight; } // The pallet connect authors mapping, slots, and implement block executor for nimbus consensus. impl pallet_author_inherent::Config for Runtime { - type AuthorId = NimbusId; type SlotBeacon = RelaychainBlockNumberProvider; type AccountLookup = AuthorMapping; type EventHandler = ParachainStaking; @@ -506,7 +528,6 @@ parameter_types! { // We need author mapping to connect Nimbus Ids with Account Ids, all collators should register his AuthorId. impl pallet_author_mapping::Config for Runtime { type Event = Event; - type AuthorId = NimbusId; type DepositCurrency = Balances; type DepositAmount = DepositAmount; type WeightInfo = pallet_author_mapping::weights::SubstrateWeight; @@ -548,6 +569,7 @@ pub type LocalAssetTransactor = MultiCurrencyAdapter< LocationToAccountId, CurrencyId, CurrencyIdConvert, + (), >; /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -746,6 +768,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime { type XcmExecutor = XcmExecutor; type ChannelInfo = ParachainSystem; type VersionWrapper = PolkadotXcm; + type ExecuteOverweightOrigin = EnsureRoot; } impl cumulus_pallet_dmp_queue::Config for Runtime { @@ -964,6 +987,7 @@ impl Convert for AccountIdToMultiLocation { parameter_types! { pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into()))); pub const BaseXcmWeight: Weight = 100_000_000; + pub const MaxAssetsForTransfer: usize = 2; } impl orml_xtokens::Config for Runtime { @@ -977,6 +1001,7 @@ impl orml_xtokens::Config for Runtime { type Weigher = FixedWeightBounds; type BaseXcmWeight = BaseXcmWeight; type LocationInverter = LocationInverter; + type MaxAssetsForTransfer = MaxAssetsForTransfer; } impl orml_xcm::Config for Runtime { @@ -1043,7 +1068,7 @@ construct_runtime!( AuthorMapping: pallet_author_mapping::{Pallet, Call, Config, Storage, Event} = 43, // Democracy - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Config, Event} = 50, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 50, Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 51, Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event} = 52, @@ -1096,7 +1121,7 @@ pub type Executive = frame_executive::Executive< Block, frame_system::ChainContext, Runtime, - AllPallets, + AllPalletsReversedWithSystemFirst, >; impl_runtime_apis! { @@ -1158,8 +1183,8 @@ impl_runtime_apis! { } impl cumulus_primitives_core::CollectCollationInfo for Runtime { - fn collect_collation_info() -> cumulus_primitives_core::CollationInfo { - ParachainSystem::collect_collation_info() + fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { + ParachainSystem::collect_collation_info(header) } } @@ -1264,12 +1289,32 @@ impl_runtime_apis! { &(parent_header.number + 1), &parent_header.hash(), &parent_header.digest, - frame_system::InitKind::Inspection ); RandomnessCollectiveFlip::on_initialize(System::block_number()); - // And now the actual prediction call - AuthorInherent::can_author(&author, &slot) + // Because the staking solution calculates the next staking set at the beginning + // of the first block in the new round, the only way to accurately predict the + // authors is to compute the selection during prediction. + if parachain_staking::Pallet::::round().should_update(parent_header.number + 1) { + // get author account id + use nimbus_primitives::AccountLookup; + let author_account_id = if let Some(account) = + pallet_author_mapping::Pallet::::lookup_account(&author) { + account + } else { + // return false if author mapping not registered like in can_author impl + return false + }; + // predict eligibility post-selection by computing selection results now + let (eligible, _) = + pallet_author_slot_filter::compute_pseudo_random_subset::( + parachain_staking::Pallet::::compute_top_candidates(), + &slot + ); + eligible.contains(&author_account_id) + } else { + AuthorInherent::can_author(&author, &slot) + } } } diff --git a/runtime/src/tests/parachain/mock_runtime.rs b/runtime/src/tests/parachain/mock_runtime.rs index c1840703..80a1923c 100644 --- a/runtime/src/tests/parachain/mock_runtime.rs +++ b/runtime/src/tests/parachain/mock_runtime.rs @@ -11,7 +11,7 @@ use sp_runtime::{ use serde::{Deserialize, Serialize}; use sp_core::RuntimeDebug; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; // Polkadot & XCM imports @@ -43,7 +43,7 @@ pub use frame_support::{ construct_runtime, parameter_types, StorageValue, match_type, traits::{ KeyOwnerProofSystem, Randomness, IsInVec, Everything, Nothing, EnsureOrigin, - OnUnbalanced, Imbalance, Get, + OnUnbalanced, Imbalance, Get, ConstU32, }, weights::{ Weight, IdentityFee, DispatchClass, @@ -103,10 +103,23 @@ impl frame_system::Config for Runtime { type SS58Prefix = (); type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type Version = (); + type MaxConsumers = ConstU32<12>; } // Currencies id. -#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord, TypeInfo)] +#[derive( + Encode, + Decode, + Eq, + PartialEq, + Copy, + Clone, + RuntimeDebug, + PartialOrd, + Ord, + TypeInfo, + MaxEncodedLen, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum CurrencyId { // Relaychain's currency. @@ -141,7 +154,7 @@ parameter_types! { impl cumulus_pallet_parachain_system::Config for Runtime { type Event = Event; - type OnValidationData = (); + type OnSystemEvent = (); type SelfParaId = parachain_info::Pallet; type OutboundXcmpMessageSource = XcmpQueue; type XcmpMessageHandler = XcmpQueue; @@ -179,6 +192,7 @@ pub type LocalAssetTransactor = MultiCurrencyAdapter< LocationToAccountId, CurrencyId, CurrencyIdConvert, + (), >; /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -381,6 +395,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime { type XcmExecutor = XcmExecutor; type ChannelInfo = ParachainSystem; type VersionWrapper = PolkadotXcm; + type ExecuteOverweightOrigin = EnsureRoot; } impl cumulus_pallet_dmp_queue::Config for Runtime { @@ -522,6 +537,7 @@ impl Convert for AccountIdToMultiLocation { parameter_types! { pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into()))); pub const BaseXcmWeight: Weight = 100_000_000; + pub const MaxAssetsForTransfer: usize = 2; } impl orml_xtokens::Config for Runtime { @@ -535,6 +551,7 @@ impl orml_xtokens::Config for Runtime { type Weigher = FixedWeightBounds; type BaseXcmWeight = BaseXcmWeight; type LocationInverter = LocationInverter; + type MaxAssetsForTransfer = MaxAssetsForTransfer; } impl orml_xcm::Config for Runtime { diff --git a/runtime/src/tests/parachain/mod.rs b/runtime/src/tests/parachain/mod.rs index ad99d833..f789e706 100644 --- a/runtime/src/tests/parachain/mod.rs +++ b/runtime/src/tests/parachain/mod.rs @@ -30,7 +30,7 @@ decl_test_parachain! { decl_test_relay_chain! { pub struct Relay { Runtime = kusama_runtime::Runtime, - XcmConfig = kusama_runtime::XcmConfig, + XcmConfig = kusama_runtime::xcm_config::XcmConfig, new_ext = relay_ext(), } } @@ -124,14 +124,15 @@ pub fn para_ext(parachain_id: u32) -> TestExternalities { fn default_parachains_host_configuration() -> HostConfiguration { HostConfiguration { - validation_upgrade_frequency: 1u32, - validation_upgrade_delay: 1, + validation_upgrade_cooldown: 10u32, + validation_upgrade_delay: 10, code_retention_period: 1200, max_code_size: MAX_CODE_SIZE, max_pov_size: MAX_POV_SIZE, max_head_data_size: 32 * 1024, group_rotation_frequency: 20, chain_availability_period: 4, + minimum_validation_upgrade_delay: 8, thread_availability_period: 4, max_upward_queue_count: 8, max_upward_queue_size: 1024 * 1024, From 694896358c47943a54d975d136c0c67dac7e5c3f Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 04:47:34 +0300 Subject: [PATCH 05/13] parachain tests --- Cargo.lock | 38 ++++++++++----------- runtime/src/lib.rs | 2 +- runtime/src/tests/parachain/mock_runtime.rs | 2 +- runtime/src/tests/parachain/mod.rs | 2 +- runtime/src/tests/parachain/parachain.rs | 6 ++-- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d291b95..71913735 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1661,7 +1661,7 @@ name = "cumulus-pallet-parachain-system-proc-macro" version = "0.1.0" source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -2547,7 +2547,7 @@ version = "4.0.0-dev" source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -3604,7 +3604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d802063f7a3c867456955f9d2f15eb3ee0edb5ec9ec2b5526324756759221c0f" dependencies = [ "log", - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -4988,7 +4988,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro-error", "proc-macro2", "quote", @@ -6166,7 +6166,7 @@ name = "pallet-staking-reward-curve" version = "4.0.0-dev" source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -6433,7 +6433,7 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -7452,7 +7452,7 @@ name = "polkadot-overseer-gen-proc-macro" version = "0.9.16" source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -8121,9 +8121,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +checksum = "738b5123081e03ec93bdd0229f33e39891e6ee18745b72bfc8fdc04a080d5c38" dependencies = [ "thiserror", "toml", @@ -8231,9 +8231,9 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd136ff4382c4753fc061cb9e4712ab2af263376b95bbd5bd8cd50c020b78e69" +checksum = "6eca0fa5dd7c4c96e184cec588f0b1db1ee3165e678db21c09793105acb17e6f" dependencies = [ "cc", ] @@ -8912,7 +8912,7 @@ name = "sc-chain-spec-derive" version = "4.0.0-dev" source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -9732,7 +9732,7 @@ name = "sc-tracing-proc-macro" version = "4.0.0-dev" source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -9811,7 +9811,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baeb2780690380592f86205aa4ee49815feb2acad8c2f59e6dd207148c3f1fcd" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -10279,7 +10279,7 @@ version = "4.0.0-dev" source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "blake2-rfc", - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -10843,7 +10843,7 @@ name = "sp-npos-elections-solution-type" version = "4.0.0-dev" source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -10949,7 +10949,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57346f6b24875f8935280dba51fa8ab0a9ba1e39" dependencies = [ "Inflector", - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -10961,7 +10961,7 @@ version = "4.0.0" source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "Inflector", - "proc-macro-crate 1.1.0", + "proc-macro-crate 1.1.1", "proc-macro2", "quote", "syn", @@ -12794,7 +12794,7 @@ dependencies = [ [[package]] name = "xcm-emulator" version = "0.1.0" -source = "git+https://github.com/pontem-network/xcm-simulator?branch=polkadot-v0.9.16#d4a700a345789d21423879caad4eb8107eda44e9" +source = "git+https://github.com/pontem-network/xcm-simulator?branch=polkadot-v0.9.16#b91b7420bbd0337794e9295f7ca203afcdd16c8b" dependencies = [ "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 33f33919..b852b06d 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -132,7 +132,7 @@ const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(65); 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. + /// We allow for 2 seconds of compute with a 12 second average block time. pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() .base_block(BlockExecutionWeight::get()) .for_class(DispatchClass::all(), |weights| { diff --git a/runtime/src/tests/parachain/mock_runtime.rs b/runtime/src/tests/parachain/mock_runtime.rs index 80a1923c..46b2d32c 100644 --- a/runtime/src/tests/parachain/mock_runtime.rs +++ b/runtime/src/tests/parachain/mock_runtime.rs @@ -76,7 +76,7 @@ pub type BlockNumber = u64; pub type Index = u64; parameter_types! { - pub const BlockHashCount: BlockNumber = 250; + pub const BlockHashCount: BlockNumber = 2400; } impl frame_system::Config for Runtime { diff --git a/runtime/src/tests/parachain/mod.rs b/runtime/src/tests/parachain/mod.rs index f789e706..aa75f9a6 100644 --- a/runtime/src/tests/parachain/mod.rs +++ b/runtime/src/tests/parachain/mod.rs @@ -124,6 +124,7 @@ pub fn para_ext(parachain_id: u32) -> TestExternalities { fn default_parachains_host_configuration() -> HostConfiguration { HostConfiguration { + minimum_validation_upgrade_delay: 5, validation_upgrade_cooldown: 10u32, validation_upgrade_delay: 10, code_retention_period: 1200, @@ -132,7 +133,6 @@ fn default_parachains_host_configuration() -> HostConfiguration { max_head_data_size: 32 * 1024, group_rotation_frequency: 20, chain_availability_period: 4, - minimum_validation_upgrade_delay: 8, thread_availability_period: 4, max_upward_queue_count: 8, max_upward_queue_size: 1024 * 1024, diff --git a/runtime/src/tests/parachain/parachain.rs b/runtime/src/tests/parachain/parachain.rs index 6de210fb..7af14c33 100644 --- a/runtime/src/tests/parachain/parachain.rs +++ b/runtime/src/tests/parachain/parachain.rs @@ -171,9 +171,11 @@ fn send_relay_chain_asset_to_sibling() { } #[test] +#[ignore] fn send_self_parachain_asset_to_sibling() { TestNet::reset(); + // Send to paracahin B native currency from parachain A. ParaA::execute_with(|| { assert_ok!(ParaAXTokens::transfer( Some(Accounts::ALICE.account()).into(), @@ -221,7 +223,7 @@ fn send_self_parachain_asset_to_sibling() { Junction::Parachain(2000), Junction::AccountId32 { network: NetworkId::Any, - id: Accounts::BOB.into(), + id: Accounts::ALICE.into(), } ) ) @@ -238,7 +240,7 @@ fn send_self_parachain_asset_to_sibling() { ParaA::execute_with(|| { assert_eq!( - ParaABalances::free_balance(&Accounts::BOB.account()), + ParaABalances::free_balance(&Accounts::ALICE.account()), CurrencyId::NATIVE * 500 - 8 ); }); From b9df3ed0cfea7e176fe323174de25a69fe3b60ed Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 05:26:37 +0300 Subject: [PATCH 06/13] update runtime with reanchor canonical location --- runtime/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index b852b06d..6530d681 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -914,6 +914,11 @@ impl Convert> for CurrencyIdConvert { parents: 1, interior: X2(Parachain(_id), GeneralKey(key)), } if key.to_vec() == CurrencyId::NATIVE.symbol() => Some(CurrencyId::NATIVE), + // adapt for reanchor canonical location: https://github.com/paritytech/polkadot/pull/4470 + MultiLocation { + parents: 0, + interior: X1(GeneralKey(key)), + } if key.to_vec() == CurrencyId::NATIVE.symbol() => Some(CurrencyId::NATIVE), _ => None, } } From 060552661eed668b9cd5199754880b79f3285c92 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 05:26:50 +0300 Subject: [PATCH 07/13] return parachain test --- runtime/src/tests/parachain/parachain.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/runtime/src/tests/parachain/parachain.rs b/runtime/src/tests/parachain/parachain.rs index 7af14c33..d73012fd 100644 --- a/runtime/src/tests/parachain/parachain.rs +++ b/runtime/src/tests/parachain/parachain.rs @@ -171,7 +171,6 @@ fn send_relay_chain_asset_to_sibling() { } #[test] -#[ignore] fn send_self_parachain_asset_to_sibling() { TestNet::reset(); @@ -223,7 +222,7 @@ fn send_self_parachain_asset_to_sibling() { Junction::Parachain(2000), Junction::AccountId32 { network: NetworkId::Any, - id: Accounts::ALICE.into(), + id: Accounts::BOB.into(), } ) ) @@ -240,7 +239,7 @@ fn send_self_parachain_asset_to_sibling() { ParaA::execute_with(|| { assert_eq!( - ParaABalances::free_balance(&Accounts::ALICE.account()), + ParaABalances::free_balance(&Accounts::BOB.account()), CurrencyId::NATIVE * 500 - 8 ); }); From 6d1e22834d832445dcca4762cc47ca5c8b3fee25 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 09:09:32 +0300 Subject: [PATCH 08/13] update node to v0.9.16 --- Cargo.lock | 212 ++++++++++++++++++++++++++--------------- node/Cargo.toml | 4 + node/src/chain_spec.rs | 19 ++-- node/src/command.rs | 35 +++++-- node/src/service.rs | 100 +++++++++++-------- runtime/src/lib.rs | 22 +++-- 6 files changed, 258 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71913735..ff73f1c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -741,7 +741,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "finality-grandpa", "frame-support", @@ -757,7 +757,7 @@ dependencies = [ [[package]] name = "bp-message-dispatch" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-runtime", "frame-support", @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-runtime", @@ -785,7 +785,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-runtime", @@ -803,7 +803,7 @@ dependencies = [ [[package]] name = "bp-rococo" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -820,7 +820,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "hash-db", @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "ed25519-dalek", @@ -853,7 +853,7 @@ dependencies = [ [[package]] name = "bp-wococo" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -868,7 +868,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-messages", @@ -1790,6 +1790,34 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cumulus-relay-chain-local" +version = "0.1.0" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" +dependencies = [ + "async-trait", + "cumulus-primitives-core", + "cumulus-relay-chain-interface", + "futures 0.3.21", + "futures-timer", + "parking_lot 0.11.2", + "polkadot-client", + "polkadot-service", + "sc-client-api", + "sc-consensus-babe", + "sc-network", + "sc-service", + "sc-telemetry", + "sc-tracing", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core 4.1.0-dev", + "sp-runtime", + "sp-state-machine 0.10.0", + "tracing", +] + [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.1.0" @@ -2387,6 +2415,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.10.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b279436a715a9de95dcd26b151db590a71961cc06e54918b24fe0dd5b7d3fc4" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project 1.0.10", + "spin 0.9.2", +] + [[package]] name = "fnv" version = "1.0.7" @@ -3683,7 +3724,7 @@ dependencies = [ [[package]] name = "kusama-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -3771,7 +3812,7 @@ dependencies = [ [[package]] name = "kusama-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -4706,7 +4747,7 @@ dependencies = [ [[package]] name = "metered-channel" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -5079,6 +5120,15 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "nanorand" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958" +dependencies = [ + "getrandom 0.2.4", +] + [[package]] name = "net2" version = "0.2.37" @@ -5652,7 +5702,7 @@ dependencies = [ [[package]] name = "pallet-bridge-dispatch" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-runtime", @@ -5669,7 +5719,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "bp-runtime", @@ -5691,7 +5741,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-message-dispatch", @@ -6328,7 +6378,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -6346,7 +6396,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -6780,7 +6830,7 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "polkadot-approval-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-network-protocol", @@ -6794,7 +6844,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-network-protocol", @@ -6807,7 +6857,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -6829,7 +6879,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "lru 0.7.2", @@ -6849,7 +6899,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking-cli", "futures 0.3.21", @@ -6872,7 +6922,7 @@ dependencies = [ [[package]] name = "polkadot-client" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "frame-benchmarking", @@ -6904,7 +6954,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "derive_more", @@ -6925,7 +6975,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -6938,7 +6988,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -6960,7 +7010,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -6974,7 +7024,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -6994,7 +7044,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7013,7 +7063,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "parity-scale-codec", @@ -7031,7 +7081,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "derive_more", @@ -7059,7 +7109,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7079,7 +7129,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7097,7 +7147,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-subsystem", @@ -7112,7 +7162,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7130,7 +7180,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-subsystem", @@ -7145,7 +7195,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7162,7 +7212,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "kvdb", @@ -7180,7 +7230,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7197,7 +7247,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7214,7 +7264,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "assert_matches", @@ -7244,7 +7294,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-primitives", @@ -7260,7 +7310,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "memory-lru", @@ -7278,7 +7328,7 @@ dependencies = [ [[package]] name = "polkadot-node-jaeger" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-std", "lazy_static", @@ -7296,7 +7346,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bs58", "futures 0.3.21", @@ -7315,7 +7365,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", @@ -7333,7 +7383,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bounded-vec", "futures 0.3.21", @@ -7355,7 +7405,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "polkadot-node-jaeger", "polkadot-node-subsystem-types", @@ -7365,7 +7415,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -7384,7 +7434,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", @@ -7412,7 +7462,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7433,7 +7483,7 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7450,7 +7500,7 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen-proc-macro" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "proc-macro-crate 1.1.1", "proc-macro2", @@ -7461,7 +7511,7 @@ dependencies = [ [[package]] name = "polkadot-parachain" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "frame-support", @@ -7478,7 +7528,7 @@ dependencies = [ [[package]] name = "polkadot-performance-test" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "env_logger", "kusama-runtime", @@ -7493,7 +7543,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "frame-system", @@ -7523,7 +7573,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-gadget", "beefy-gadget-rpc", @@ -7554,7 +7604,7 @@ dependencies = [ [[package]] name = "polkadot-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7638,7 +7688,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7685,7 +7735,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -7697,7 +7747,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bs58", "parity-scale-codec", @@ -7709,7 +7759,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitflags", "bitvec", @@ -7750,7 +7800,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "beefy-gadget", @@ -7852,7 +7902,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "arrayvec 0.5.2", "derive_more", @@ -7873,7 +7923,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -7929,6 +7979,9 @@ dependencies = [ "cumulus-client-service", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", + "cumulus-relay-chain-interface", + "cumulus-relay-chain-local", + "flume", "frame-benchmarking", "frame-benchmarking-cli", "futures 0.3.21", @@ -8556,7 +8609,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi 0.3.9", @@ -8585,7 +8638,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bp-messages", @@ -8660,7 +8713,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -10162,7 +10215,7 @@ dependencies = [ [[package]] name = "slot-range-helper" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "enumn", "parity-scale-codec", @@ -11255,6 +11308,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" +dependencies = [ + "lock_api 0.4.6", +] + [[package]] name = "ss58-registry" version = "1.14.0" @@ -12567,7 +12629,7 @@ dependencies = [ [[package]] name = "westend-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -12653,7 +12715,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -12761,7 +12823,7 @@ dependencies = [ [[package]] name = "xcm" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derivative", "impl-trait-for-tuples", @@ -12774,7 +12836,7 @@ dependencies = [ [[package]] name = "xcm-builder" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -12818,7 +12880,7 @@ dependencies = [ [[package]] name = "xcm-executor" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -12836,7 +12898,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "Inflector", "proc-macro2", diff --git a/node/Cargo.toml b/node/Cargo.toml index b2c68f55..7824aa3b 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -83,12 +83,16 @@ cumulus-client-service = { git = 'https://github.com/paritytech/cumulus', branch cumulus-client-cli = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } cumulus-primitives-core = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } cumulus-primitives-parachain-inherent = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-relay-chain-local = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } +cumulus-relay-chain-interface = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } # Polkadot dependencies polkadot-primitives = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } polkadot-service = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } polkadot-parachain = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +flume = "0.10.9" + # Local dependencies pontem-runtime = { path = "../runtime" } sp-mvm-rpc = { path = "../pallets/sp-mvm/rpc" } diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index b1c4ba76..a93eb19d 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -10,7 +10,7 @@ use pontem_runtime::{ GenesisConfig, SudoConfig, SystemConfig, BalancesConfig, WASM_BINARY, ParachainInfoConfig, VestingConfig, MvmConfig, TransactionPauseConfig, ParachainStakingConfig, InflationInfo, Range, AuthorFilterConfig, AuthorMappingConfig, TreasuryConfig, TokensConfig, - DemocracyConfig, PolkadotXcmConfig, SchedulerConfig, + DemocracyConfig, PolkadotXcmConfig, }; use primitives::{currency::CurrencyId, AccountId, Signature, Balance, BlockNumber}; use constants::SS58_PREFIX; @@ -152,7 +152,7 @@ fn paused_extrinsics() -> Vec<(Vec, Vec)> { "teleport_assets", ], ), - ("ParachainStaking", vec!["join_candidates", "nominate"]), + ("ParachainStaking", vec!["join_candidates", "delegate"]), ("Treasury", vec!["propose_spend"]), ("Mvm", vec!["execute", "publish_module", "publish_package"]), ( @@ -246,6 +246,8 @@ pub fn development_config() -> Result { None, // Protocol ID None, + // Fork ID + None, // Properties properties(), // Extensions @@ -334,6 +336,8 @@ pub fn local_testnet_config() -> Result { None, // Protocol ID Some("pontem_testnet"), + // Fork ID + None, // Properties properties(), // Extensions @@ -465,6 +469,8 @@ pub fn westend_config() -> Result { None, // Protocol ID Some("nox_westend"), + // Fork ID + None, // Properties properties(), // Extensions @@ -709,6 +715,8 @@ pub fn nox_config() -> Result { None, // Protocol ID Some("nox_mainnet"), + // Fork ID + None, // Properties properties(), // Extensions @@ -724,7 +732,7 @@ fn genesis( wasm_binary: &[u8], root_key: AccountId, candidates: Vec<(AccountId, NimbusId, Balance)>, - nominations: Vec<(AccountId, AccountId, Balance)>, + delegations: Vec<(AccountId, AccountId, Balance)>, balances: Vec<(AccountId, Balance)>, vesting: Vec<(AccountId, BlockNumber, BlockNumber, Balance)>, paused: Vec<(Vec, Vec)>, @@ -754,7 +762,7 @@ fn genesis( parachain_info: ParachainInfoConfig { parachain_id: id }, sudo: SudoConfig { // Assign network admin rights. - key: root_key, + key: Some(root_key), }, parachain_staking: ParachainStakingConfig { candidates: candidates @@ -762,7 +770,7 @@ fn genesis( .cloned() .map(|(account, _, bond)| (account, bond)) .collect(), - nominations, + delegations, inflation_config: pontem_inflation_config(), }, author_filter: AuthorFilterConfig { @@ -790,7 +798,6 @@ fn genesis( vesting: VestingConfig { vesting }, treasury: TreasuryConfig {}, democracy: DemocracyConfig::default(), - scheduler: SchedulerConfig {}, } } diff --git a/node/src/command.rs b/node/src/command.rs index 64d74249..c528736e 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -207,8 +207,11 @@ pub fn run() -> sc_cli::Result<()> { builder.with_profiling(sc_tracing::TracingReceiver::Log, ""); let _ = builder.init(); - let block: Block = - generate_genesis_block(&load_spec(¶ms.chain.clone().unwrap_or_default())?)?; + let chain_spec = load_spec(¶ms.chain.clone().unwrap_or_default())?; + + let state_version = Cli::native_runtime_version(&chain_spec).state_version(); + + let block: Block = generate_genesis_block(&chain_spec, state_version)?; let raw_header = block.header().encode(); let output_buf = if params.raw { raw_header @@ -264,8 +267,11 @@ pub fn run() -> sc_cli::Result<()> { let parachain_account = AccountIdConversion::::into_account(&id); - let block: Block = - generate_genesis_block(&config.chain_spec).map_err(|e| format!("{:?}", e))?; + let state_version = + Cli::native_runtime_version(&config.chain_spec).state_version(); + + let block: Block = generate_genesis_block(&config.chain_spec, state_version) + .map_err(|e| format!("{:?}", e))?; let genesis_state = format!("0x{:?}", HexDisplay::from(&block.header().encode())); let task_executor = config.tokio_handle.clone(); @@ -348,11 +354,26 @@ impl sc_cli::CliConfiguration for RelayChainCli { self.base.base.rpc_ws(default_listen_port) } - fn prometheus_config(&self, default_listen_port: u16) -> Result> { - self.base.base.prometheus_config(default_listen_port) + fn prometheus_config( + &self, + default_listen_port: u16, + chain_spec: &Box, + ) -> Result> { + self.base + .base + .prometheus_config(default_listen_port, chain_spec) } - fn init(&self) -> Result<()> { + fn init( + &self, + _support_url: &String, + _impl_version: &String, + _logger_hook: F, + _config: &sc_service::Configuration, + ) -> Result<()> + where + F: FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration), + { unreachable!("PolkadotCli is never initialized; qed"); } diff --git a/node/src/service.rs b/node/src/service.rs index 0dfa41a6..1610e5a6 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -1,13 +1,15 @@ -use cumulus_client_network::build_block_announce_validator; +use cumulus_relay_chain_local::build_relay_chain_interface; use crate::cli::Sealing; -use cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider; +use cumulus_primitives_parachain_inherent::{MockValidationDataInherentDataProvider, MockXcmConfig}; use futures::StreamExt; use sp_core::H256; use cumulus_client_service::{ prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams, }; +use std::time::Duration; use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams}; +use cumulus_relay_chain_interface::RelayChainInterface; use cumulus_primitives_core::ParaId; use pontem_runtime::RuntimeApi; use sp_blockchain::HeaderBackend; @@ -17,10 +19,12 @@ use std::sync::Arc; use substrate_prometheus_endpoint::Registry; use sp_keystore::SyncCryptoStorePtr; use cumulus_client_consensus_common::ParachainConsensus; +use cumulus_client_network::BlockAnnounceValidator; use nimbus_primitives::NimbusId; -use nimbus_consensus::{build_nimbus_consensus, BuildNimbusConsensusParams}; +use nimbus_consensus::{BuildNimbusConsensusParams, NimbusConsensus}; use primitives::Block; use sc_executor::NativeElseWasmExecutor; +use sp_runtime::Percent; type FullBackend = TFullBackend; type FullClient = @@ -76,6 +80,7 @@ pub fn new_partial( config.wasm_method, config.default_heap_pages, config.max_runtime_instances, + config.runtime_cache_size, ); let (client, backend, keystore_container, task_manager) = @@ -122,6 +127,7 @@ pub fn new_partial( }, &task_manager.spawn_essential_handle(), config.prometheus_registry().clone(), + !dev_service, )? }; @@ -162,30 +168,24 @@ async fn start_node_impl( let params = new_partial(¶chain_config, false)?; let (mut telemetry, telemetry_worker_handle) = params.other; + let mut task_manager = params.task_manager; - let relay_chain_full_node = cumulus_client_service::build_polkadot_full_node( - polkadot_config, - telemetry_worker_handle, - ) - .map_err(|e| match e { - polkadot_service::Error::Sub(x) => x, - s => format!("{}", s).into(), - })?; + let (relay_chain_full_node, collator_key) = + build_relay_chain_interface(polkadot_config, telemetry_worker_handle, &mut task_manager) + .map_err(|e| match e { + polkadot_service::Error::Sub(x) => x, + s => format!("{}", s).into(), + })?; let client = params.client.clone(); let backend = params.backend.clone(); - let block_announce_validator = build_block_announce_validator( - relay_chain_full_node.client.clone(), - id, - Box::new(relay_chain_full_node.network.clone()), - relay_chain_full_node.backend.clone(), - ); + + let block_announce_validator = BlockAnnounceValidator::new(relay_chain_full_node.clone(), id); let is_validator = parachain_config.role.is_authority(); let force_authoring = parachain_config.force_authoring; let prometheus_registry = parachain_config.prometheus_registry().cloned(); let transaction_pool = params.transaction_pool.clone(); - let mut task_manager = params.task_manager; let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue); let (network, system_rpc_tx, start_network) = sc_service::build_network(sc_service::BuildNetworkParams { @@ -195,7 +195,9 @@ async fn start_node_impl( spawn_handle: task_manager.spawn_handle(), import_queue: import_queue.clone(), warp_sync: None, - block_announce_validator_builder: Some(Box::new(|_| block_announce_validator)), + block_announce_validator_builder: Some(Box::new(|_| { + Box::new(block_announce_validator) + })), })?; let rpc_extensions_builder = { @@ -232,6 +234,8 @@ async fn start_node_impl( Arc::new(move |hash, data| network.announce_block(hash, data)) }; + let relay_chain_slot_duration = Duration::from_secs(6); + if is_validator { let parachain_consensus = build_consensus( id, @@ -239,7 +243,7 @@ async fn start_node_impl( prometheus_registry.as_ref(), telemetry.as_ref().map(|t| t.handle()), &task_manager, - &relay_chain_full_node, + relay_chain_full_node.clone(), transaction_pool, params.keystore_container.sync_keystore(), force_authoring, @@ -251,10 +255,12 @@ async fn start_node_impl( announce_block, client: client.clone(), task_manager: &mut task_manager, - relay_chain_full_node, + relay_chain_interface: relay_chain_full_node, spawner, parachain_consensus, import_queue, + collator_key, + relay_chain_slot_duration, }; start_collator(params).await?; @@ -264,7 +270,9 @@ async fn start_node_impl( announce_block, task_manager: &mut task_manager, para_id: id, - relay_chain_full_node, + relay_chain_interface: relay_chain_full_node, + relay_chain_slot_duration, + import_queue, }; start_full_node(params)?; @@ -281,32 +289,32 @@ fn build_consensus( prometheus_registry: Option<&Registry>, telemetry: Option, task_manager: &TaskManager, - relay_chain_node: &polkadot_service::NewFull, + relay_chain_node: Arc, transaction_pool: Arc>, keystore: SyncCryptoStorePtr, force_authoring: bool, ) -> Result>, sc_service::Error> { - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + let mut proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( task_manager.spawn_handle(), client.clone(), transaction_pool, prometheus_registry.clone(), telemetry.clone(), ); - - let relay_chain_backend = relay_chain_node.backend.clone(); - let relay_chain_client = relay_chain_node.client.clone(); + proposer_factory.set_soft_deadline(Percent::from_percent(100)); let create_inherent_data_providers = move |_, (relay_parent, validation_data, author_id)| { - let parachain_inherent = - cumulus_primitives_parachain_inherent::ParachainInherentData::create_at_with_client( - relay_parent, - &relay_chain_client, - &*relay_chain_backend, - &validation_data, - id, - ); + let relay_chain_node = relay_chain_node.clone(); async move { + let parachain_inherent = + cumulus_primitives_parachain_inherent::ParachainInherentData::create_at( + relay_parent, + &relay_chain_node, + &validation_data, + id, + ) + .await; + let time = sp_timestamp::InherentDataProvider::from_system_time(); let parachain_inherent = parachain_inherent.ok_or_else(|| { @@ -321,12 +329,10 @@ fn build_consensus( } }; - Ok(build_nimbus_consensus(BuildNimbusConsensusParams { + Ok(NimbusConsensus::build(BuildNimbusConsensusParams { para_id: id, proposer_factory, block_import: client.clone(), - relay_chain_client: relay_chain_node.client.clone(), - relay_chain_backend: relay_chain_node.backend.clone(), parachain_client: client.clone(), keystore, skip_prediction: force_authoring, @@ -426,9 +432,13 @@ pub fn new_dev( let client_set_aside_for_cidp = client.clone(); + // Create channels for mocked XCM messages. + let (downward_xcm_sender, downward_xcm_receiver) = flume::bounded::>(100); + let (hrmp_xcm_sender, hrmp_xcm_receiver) = flume::bounded::<(ParaId, Vec)>(100); + task_manager.spawn_essential_handle().spawn_blocking( "authorship_task", - None, + Some("block-authoring"), run_manual_seal(ManualSealParams { block_import: client.clone(), env, @@ -444,6 +454,10 @@ pub fn new_dev( .expect("Header passed in as parent should be present in backend."); let author_id = author_id.clone(); + let client_for_xcm = client_set_aside_for_cidp.clone(); + let downward_xcm_receiver = downward_xcm_receiver.clone(); + let hrmp_xcm_receiver = hrmp_xcm_receiver.clone(); + async move { let time = sp_timestamp::InherentDataProvider::from_system_time(); @@ -451,6 +465,14 @@ pub fn new_dev( current_para_block, relay_offset: 1000, relay_blocks_per_para_block: 2, + xcm_config: MockXcmConfig::new( + &*client_for_xcm, + block, + Default::default(), + Default::default(), + ), + raw_downward_messages: downward_xcm_receiver.drain().collect(), + raw_horizontal_messages: hrmp_xcm_receiver.drain().collect(), }; let author = diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 6530d681..d2ae874f 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1278,29 +1278,30 @@ impl_runtime_apis! { } } - impl nimbus_primitives::AuthorFilterAPI for Runtime { + impl nimbus_primitives::NimbusApi for Runtime { fn can_author( - author: NimbusId, + author: nimbus_primitives::NimbusId, slot: u32, parent_header: &::Header ) -> bool { + use nimbus_primitives::CanAuthor; + let block_number = parent_header.number + 1; + // The Moonbeam runtimes use an entropy source that needs to do some accounting // work during block initialization. Therefore we initialize it here to match // the state it will be in when the next block is being executed. use frame_support::traits::OnInitialize; - use nimbus_primitives::CanAuthor; - System::initialize( - &(parent_header.number + 1), + &block_number, &parent_header.hash(), &parent_header.digest, ); - RandomnessCollectiveFlip::on_initialize(System::block_number()); + RandomnessCollectiveFlip::on_initialize(block_number); // Because the staking solution calculates the next staking set at the beginning // of the first block in the new round, the only way to accurately predict the // authors is to compute the selection during prediction. - if parachain_staking::Pallet::::round().should_update(parent_header.number + 1) { + if parachain_staking::Pallet::::round().should_update(block_number) { // get author account id use nimbus_primitives::AccountLookup; let author_account_id = if let Some(account) = @@ -1323,6 +1324,13 @@ impl_runtime_apis! { } } + // We also implement the old AuthorFilterAPI to meet the trait bounds on the client side. + impl nimbus_primitives::AuthorFilterAPI for Runtime { + fn can_author(_: NimbusId, _: u32, _: &::Header) -> bool { + panic!("AuthorFilterAPI is no longer supported. Please update your client.") + } + } + #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( From 80635a313a8c169bdbfe25d49ccf2ae4f34c8208 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 09:10:41 +0300 Subject: [PATCH 09/13] missed files --- pallets/parachain-staking/src/migrations.rs | 497 ++++++++++++++++++++ pallets/sp-mvm/tests/modules.rs | 63 +++ pallets/sp-mvm/tests/scripts.rs | 194 ++++++++ 3 files changed, 754 insertions(+) create mode 100644 pallets/parachain-staking/src/migrations.rs create mode 100644 pallets/sp-mvm/tests/modules.rs create mode 100644 pallets/sp-mvm/tests/scripts.rs diff --git a/pallets/parachain-staking/src/migrations.rs b/pallets/parachain-staking/src/migrations.rs new file mode 100644 index 00000000..836f4c20 --- /dev/null +++ b/pallets/parachain-staking/src/migrations.rs @@ -0,0 +1,497 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! # Migrations +use crate::{ + pallet::Total, BalanceOf, Bond, BottomDelegations, CandidateInfo, CandidateMetadata, + CandidateState, CapacityStatus, CollatorCandidate, Config, Delegations, DelegatorState, + Event, Pallet, Points, Round, Staked, TopDelegations, +}; +#[cfg(feature = "try-runtime")] +use crate::{Collator2, Delegator, Nominator2}; +#[cfg(feature = "try-runtime")] +use frame_support::traits::OnRuntimeUpgradeHelpersExt; +use frame_support::Twox64Concat; +extern crate alloc; +#[cfg(feature = "try-runtime")] +use alloc::format; +use frame_support::{ + migration::{remove_storage_prefix, storage_key_iter}, + pallet_prelude::PhantomData, + traits::{Get, OnRuntimeUpgrade, ReservableCurrency}, + weights::Weight, +}; +use sp_runtime::traits::Zero; +use sp_std::{convert::TryInto, vec::Vec}; + +/// Migration to split CandidateState and minimize unnecessary storage reads +/// for PoV optimization +/// This assumes Config::MaxTopDelegationsPerCandidate == OldConfig::MaxDelegatorsPerCandidate +pub struct SplitCandidateStateToDecreasePoV(PhantomData); +impl OnRuntimeUpgrade for SplitCandidateStateToDecreasePoV { + fn on_runtime_upgrade() -> Weight { + let pallet_prefix: &[u8] = b"ParachainStaking"; + let storage_item_prefix: &[u8] = b"CandidateState"; + // Read all the data into memory. + // https://crates.parity.io/frame_support/storage/migration/fn.storage_key_iter.html + let stored_data: Vec<_> = storage_key_iter::< + T::AccountId, + CollatorCandidate>, + Twox64Concat, + >(pallet_prefix, storage_item_prefix) + .collect(); + let migrated_count: Weight = stored_data + .len() + .try_into() + .expect("There are between 0 and 2**64 mappings stored."); + // Now remove the old storage + // https://crates.parity.io/frame_support/storage/migration/fn.remove_storage_prefix.html + remove_storage_prefix(pallet_prefix, storage_item_prefix, &[]); + // Assert that old storage is empty + assert!(storage_key_iter::< + T::AccountId, + CollatorCandidate>, + Twox64Concat, + >(pallet_prefix, storage_item_prefix) + .next() + .is_none()); + for (account, state) in stored_data { + // all delegations are stored greatest to least post migration + // but bottom delegations were least to greatest pre migration + let new_bottom_delegations: Vec>> = + if state.bottom_delegations.len() + > T::MaxBottomDelegationsPerCandidate::get() as usize + { + // if actual length > max bottom delegations, revoke the bottom actual - max + let rest = state.bottom_delegations.len() + - T::MaxBottomDelegationsPerCandidate::get() as usize; + let mut total_less = BalanceOf::::zero(); + state.bottom_delegations.iter().take(rest).for_each( + |Bond { owner, amount }| { + total_less += *amount; + // update delegator state + // unreserve kicked bottom + T::Currency::unreserve(&owner, *amount); + let mut delegator_state = >::get(&owner) + .expect("Delegation existence => DelegatorState existence"); + let leaving = delegator_state.delegations.0.len() == 1usize; + delegator_state.rm_delegation(&account); + Pallet::::deposit_event(Event::DelegationKicked( + owner.clone(), + account.clone(), + *amount, + )); + if leaving { + >::remove(&owner); + Pallet::::deposit_event(Event::DelegatorLeft( + owner.clone(), + *amount, + )); + } else { + >::insert(&owner, delegator_state); + } + }, + ); + let new_total = >::get() - total_less; + >::put(new_total); + state + .bottom_delegations + .into_iter() + .rev() + .take(T::MaxBottomDelegationsPerCandidate::get() as usize) + .collect() + } else { + state.bottom_delegations.into_iter().rev().collect() + }; + let lowest_top_delegation_amount = if state.top_delegations.is_empty() { + BalanceOf::::zero() + } else { + state.top_delegations[state.top_delegations.len() - 1].amount + }; + let highest_bottom_delegation_amount = if new_bottom_delegations.is_empty() { + BalanceOf::::zero() + } else { + new_bottom_delegations[0].amount + }; + // start here, + let lowest_bottom_delegation_amount = if new_bottom_delegations.is_empty() { + BalanceOf::::zero() + } else { + new_bottom_delegations[new_bottom_delegations.len() - 1].amount + }; + let top_capacity = match &state.top_delegations { + x if x.len() as u32 >= T::MaxTopDelegationsPerCandidate::get() => { + CapacityStatus::Full + } + x if x.is_empty() => CapacityStatus::Empty, + _ => CapacityStatus::Partial, + }; + let bottom_capacity = match &new_bottom_delegations { + x if x.len() as u32 >= T::MaxBottomDelegationsPerCandidate::get() => { + CapacityStatus::Full + } + x if x.is_empty() => CapacityStatus::Empty, + _ => CapacityStatus::Partial, + }; + let metadata = CandidateMetadata { + bond: state.bond, + delegation_count: state.top_delegations.len() as u32 + + new_bottom_delegations.len() as u32, + total_counted: state.total_counted, + lowest_top_delegation_amount, + highest_bottom_delegation_amount, + lowest_bottom_delegation_amount, + top_capacity, + bottom_capacity, + request: state.request, + status: state.state, + }; + >::insert(&account, metadata); + let top_delegations = Delegations { + total: state.total_counted - state.bond, + delegations: state.top_delegations, + }; + >::insert(&account, top_delegations); + let bottom_delegations = Delegations { + total: new_bottom_delegations + .iter() + .fold(BalanceOf::::zero(), |acc, b| acc + b.amount), + delegations: new_bottom_delegations, + }; + >::insert(&account, bottom_delegations); + } + let weight = T::DbWeight::get(); + migrated_count.saturating_mul(3 * weight.write + weight.read) + } + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + // get delegation count for all candidates to check consistency + for (account, state) in >::iter() { + // insert top + bottom into some temp map? + let total_delegation_count = + state.top_delegations.len() as u32 + state.bottom_delegations.len() as u32; + Self::set_temp_storage( + total_delegation_count, + &format!("Candidate{}DelegationCount", account)[..], + ); + } + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + // check that top + bottom are the same as the expected (stored in temp) + for (account, state) in >::iter() { + let expected_count: u32 = + Self::get_temp_storage(&format!("Candidate{}DelegationCount", account)[..]) + .expect("qed"); + let actual_count = state.delegation_count; + assert_eq!(expected_count, actual_count); + } + Ok(()) + } +} + +/// Migration to properly increase maximum delegations per collator +/// The logic may be used to recompute the top and bottom delegations whenever +/// MaxTopDelegationsPerCandidate changes (works for if decreases as well) +pub struct IncreaseMaxDelegationsPerCandidate(PhantomData); +impl OnRuntimeUpgrade for IncreaseMaxDelegationsPerCandidate { + fn on_runtime_upgrade() -> Weight { + let (mut reads, mut writes) = (0u64, 0u64); + for (account, state) in >::iter() { + reads += 1u64; + // 1. collect all delegations into single vec and order them + let mut all_delegations = state.top_delegations.clone(); + let mut starting_bottom_delegations = state.bottom_delegations.clone(); + all_delegations.append(&mut starting_bottom_delegations); + // sort all delegations from greatest to least + all_delegations.sort_unstable_by(|a, b| b.amount.cmp(&a.amount)); + let top_n = T::MaxTopDelegationsPerCandidate::get() as usize; + // 2. split them into top and bottom using the T::MaxNominatorsPerCollator + let top_delegations: Vec>> = + all_delegations.iter().take(top_n).cloned().collect(); + let bottom_delegations = if all_delegations.len() > top_n { + let rest = all_delegations.len() - top_n; + let bottom: Vec>> = + all_delegations.iter().rev().take(rest).cloned().collect(); + bottom + } else { + // empty, all nominations are in top + Vec::new() + }; + let (mut total_counted, mut total_backing): (BalanceOf, BalanceOf) = + (state.bond.into(), state.bond.into()); + for Bond { amount, .. } in &top_delegations { + total_counted += *amount; + total_backing += *amount; + } + for Bond { amount, .. } in &bottom_delegations { + total_backing += *amount; + } + // update candidate pool with new total counted if it changed + if state.total_counted != total_counted && state.is_active() { + reads += 1u64; + writes += 1u64; + >::update_active(account.clone(), total_counted); + } + >::insert( + account, + CollatorCandidate { + top_delegations, + bottom_delegations, + total_counted, + total_backing, + ..state + }, + ); + writes += 1u64; + } + let weight = T::DbWeight::get(); + // 20% of the max block weight as safety margin for computation + weight.reads(reads) + weight.writes(writes) + 100_000_000_000 + } + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + // get delegation count for all candidates to check consistency + for (account, state) in >::iter() { + // insert top + bottom into some temp map? + let total_delegation_count = + state.top_delegations.len() as u32 + state.bottom_delegations.len() as u32; + Self::set_temp_storage( + total_delegation_count, + &format!("Candidate{:?}DelegationCount", account)[..], + ); + } + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + // check that top + bottom are the same as the expected (stored in temp) + for (account, state) in >::iter() { + let expected_count: u32 = + Self::get_temp_storage(&format!("Candidate{:?}DelegationCount", account)[..]) + .expect("qed"); + let actual_count = + state.top_delegations.len() as u32 + state.bottom_delegations.len() as u32; + assert_eq!(expected_count, actual_count); + } + Ok(()) + } +} + +/// Migration to replace the automatic ExitQueue with a manual exits API. +/// This migration is idempotent so it can be run more than once without any risk. +// pub struct RemoveExitQueue(PhantomData); +// impl OnRuntimeUpgrade for RemoveExitQueue { +// fn on_runtime_upgrade() -> Weight { +// log::info!(target: "RemoveExitQueue", "running migration to remove staking exit queue"); +// let exit_queue = >::take(); +// let (mut reads, mut writes) = (1u64, 0u64); +// let mut delegator_exits: BTreeMap = BTreeMap::new(); +// let mut delegation_revocations: BTreeMap = +// BTreeMap::new(); +// // Track scheduled delegator exits and revocations before migrating state +// // Candidates already track exit info locally so no tracking is necessary +// for (delegator, is_revocation, when) in exit_queue.nominator_schedule { +// if let Some(revoking_candidate) = is_revocation { +// delegation_revocations.insert(delegator, (revoking_candidate, when)); +// } else { +// delegator_exits.insert(delegator, when); +// } +// } +// // execute candidate migration +// for (candidate_id, collator_state) in >::drain() { +// let candidate_state: CollatorCandidate> = +// collator_state.into(); +// >::insert(candidate_id, candidate_state); +// reads += 1u64; +// writes += 1u64; +// } +// // execute delegator migration +// for (delegator_id, nominator_state) in >::drain() { +// let mut delegator_state = +// migrate_nominator_to_delegator_state::(delegator_id.clone(), nominator_state); +// // add exit if it exists +// if let Some(when) = delegator_exits.get(&delegator_id) { +// delegator_state.set_leaving(*when); +// } +// // add revocation if exists +// if let Some((candidate, when)) = delegation_revocations.get(&delegator_id) { +// delegator_state.hotfix_set_revoke::(candidate.clone(), *when); +// } +// >::insert(delegator_id, delegator_state); +// reads += 1u64; +// writes += 1u64; +// } +// let db_weight = T::DbWeight::get(); +// if reads > 1u64 { +// // 50% of the max block weight as safety margin for computation +// db_weight.reads(reads) + db_weight.writes(writes) + 250_000_000_000 +// } else { +// // migration was already executed before +// db_weight.reads(reads) +// } +// } + +// #[cfg(feature = "try-runtime")] +// fn pre_upgrade() -> Result<(), &'static str> { +// use frame_support::storage::migration::storage_iter; + +// let pallet_prefix: &[u8] = b"ParachainStaking"; +// let collator_state_prefix: &[u8] = b"CollatorState2"; +// let nominator_state_prefix: &[u8] = b"NominatorState2"; + +// // Assert new storage is empty +// assert!(CandidateState::::iter().next().is_none()); +// assert!(DelegatorState::::iter().next().is_none()); + +// // Check number of old collator candidates, and set it aside in temp storage +// let old_collator_count = storage_iter::>>( +// pallet_prefix, +// collator_state_prefix, +// ) +// .count() as u64; +// Self::set_temp_storage(old_collator_count, "old_collator_count"); + +// // Read first old candidate from old storage and set it aside in temp storage +// if old_collator_count > 0 { +// let example_collator = storage_key_iter::< +// T::AccountId, +// Collator2>, +// Twox64Concat, +// >(pallet_prefix, collator_state_prefix) +// .next() +// .expect("We already confirmed that there was at least one item stored"); + +// Self::set_temp_storage(example_collator, "example_collator"); +// } + +// // Check number of new delegators, and set it aside in temp storage +// let old_nominator_count = storage_iter::>>( +// pallet_prefix, +// nominator_state_prefix, +// ) +// .count() as u64; +// Self::set_temp_storage(old_nominator_count, "old_nominator_count"); + +// // Read first new delegator from old storage and set it aside in temp storage +// if old_nominator_count > 0 { +// let example_nominator = storage_key_iter::< +// T::AccountId, +// Nominator2>, +// Twox64Concat, +// >(pallet_prefix, nominator_state_prefix) +// .next() +// .expect("We already confirmed that there was at least one item stored"); + +// Self::set_temp_storage(example_nominator, "example_nominator"); +// } +// Ok(()) +// } + +// #[cfg(feature = "try-runtime")] +// fn post_upgrade() -> Result<(), &'static str> { +// // Check number of candidates matches what was set aside in pre_upgrade +// let old_candidate_count: u64 = Self::get_temp_storage("old_collator_count") +// .expect("We stored the old collator candidate count so it should be there"); +// let new_candidate_count = CandidateState::::iter().count() as u64; +// assert_eq!(old_candidate_count, new_candidate_count); + +// // Check that our example candidate is converted correctly +// if new_candidate_count > 0 { +// let (account, original_collator_state): ( +// T::AccountId, +// Collator2>, +// ) = Self::get_temp_storage("example_collator").expect("qed"); +// let new_candidate_state = CandidateState::::get(account).expect("qed"); +// let old_candidate_converted: CollatorCandidate> = +// original_collator_state.into(); +// assert_eq!(new_candidate_state, old_candidate_converted); +// } + +// // Check number of delegators matches what was set aside in pre_upgrade +// let old_nominator_count: u64 = Self::get_temp_storage("old_nominator_count") +// .expect("We stored the old nominator count so it should be there"); +// let new_delegator_count = DelegatorState::::iter().count() as u64; +// assert_eq!(old_nominator_count, new_delegator_count); + +// // Check that our example delegator is converted correctly +// if new_delegator_count > 0 { +// let (account, original_delegator_state): ( +// T::AccountId, +// Nominator2>, +// ) = Self::get_temp_storage("example_nominator").expect("qed"); +// let new_delegator_state = DelegatorState::::get(&account).expect("qed"); +// let old_delegator_converted: Delegator> = +// migrate_nominator_to_delegator_state::(account, original_delegator_state); +// assert_eq!(old_delegator_converted, new_delegator_state); +// } +// Ok(()) +// } +// } + +/// Migration to purge staking storage bloat for `Points` and `AtStake` storage items +pub struct PurgeStaleStorage(PhantomData); +impl OnRuntimeUpgrade for PurgeStaleStorage { + fn on_runtime_upgrade() -> Weight { + log::info!(target: "PurgeStaleStorage", "running migration to remove storage bloat"); + let current_round = >::get().current; + let payment_delay = T::RewardPaymentDelay::get(); + let db_weight = T::DbWeight::get(); + let (reads, mut writes) = (3u64, 0u64); + if current_round <= payment_delay { + // early enough so no storage bloat exists yet + // (only relevant for chains <= payment_delay rounds old) + return db_weight.reads(reads); + } + // already paid out at the beginning of current round + let most_recent_round_to_kill = current_round - payment_delay; + for i in 1..=most_recent_round_to_kill { + writes += 2u64; + >::remove(i); + >::remove(i); + } + // 5% of the max block weight as safety margin for computation + db_weight.reads(reads) + db_weight.writes(writes) + 25_000_000_000 + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + // trivial migration + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + // expect only the storage items for the last 2 rounds to be stored + let staked_count = Staked::::iter().count() as u32; + let points_count = Points::::iter().count() as u32; + let delay = T::RewardPaymentDelay::get(); + assert_eq!( + staked_count, delay, + "Expected {} for `Staked` count, Found: {}", + delay, staked_count + ); + assert_eq!( + points_count, delay, + "Expected {} for `Points` count, Found: {}", + delay, staked_count + ); + Ok(()) + } +} diff --git a/pallets/sp-mvm/tests/modules.rs b/pallets/sp-mvm/tests/modules.rs new file mode 100644 index 00000000..637101ef --- /dev/null +++ b/pallets/sp-mvm/tests/modules.rs @@ -0,0 +1,63 @@ +/// Tests related to modules/packages publishing. +use frame_support::assert_err_ignore_postinfo; +use frame_support::dispatch::DispatchError; + +mod common; +use common::assets::{modules, ROOT_PACKAGE, USER_PACKAGE}; +use common::mock::*; +use common::addr::*; +use common::utils; + +#[test] +// Publish module as user. +fn publish_module() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + utils::publish_module(origin, &modules::user::STORE, None).unwrap(); + }); +} + +#[test] +/// Check publishing module compiled by one user but published by another one. +fn publish_module_as_wrong_user() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + assert_err_ignore_postinfo!( + utils::publish_module(origin, &modules::root::EVENT_PROXY, None), + DispatchError::Module { + index: 6, + error: 89, + message: Some("ModuleAddressDoesNotMatchSender") + } + ); + }); +} + +#[test] +/// Publish module as root (should be placed under CORE_CODE_ADDRESS). +fn publish_module_as_root() { + RuntimeBuilder::new().build().execute_with(|| { + utils::publish_module_as_root(&modules::root::EVENT_PROXY, None).unwrap(); + }); +} + +#[test] +/// Publish package as user. +fn publish_package_as_user() { + RuntimeBuilder::new().build().execute_with(|| { + let package = &USER_PACKAGE; + let origin = bob_public_key(); + + utils::publish_package(origin, package, None).unwrap(); + }); +} + +#[test] +/// Publish package as root (should be placed under CORE_CODE_ADDRESS). +fn publish_package_as_root() { + RuntimeBuilder::new().build().execute_with(|| { + let package = &ROOT_PACKAGE; + + utils::publish_package_as_root(package, None).unwrap(); + }); +} diff --git a/pallets/sp-mvm/tests/scripts.rs b/pallets/sp-mvm/tests/scripts.rs new file mode 100644 index 00000000..4afba67c --- /dev/null +++ b/pallets/sp-mvm/tests/scripts.rs @@ -0,0 +1,194 @@ +/// Tests related to scripts execution. +use serde::Deserialize; +use move_core_types::identifier::Identifier; +use move_core_types::language_storage::{StructTag, TypeTag}; +use frame_support::assert_err_ignore_postinfo; +use frame_support::dispatch::DispatchError; +use sp_mvm::Event; + +mod common; +use common::assets::{modules, transactions}; +use common::mock::*; +use common::addr::*; +use common::utils; + +/// Check stored value (u64) inside storage. +fn check_stored_value(expected: u64) { + #[derive(Deserialize, Debug, PartialEq)] + struct StoreU64 { + pub val: u64, + } + + let expected = StoreU64 { val: expected }; + + let tag = StructTag { + address: origin_move_addr(), + module: Identifier::new(modules::user::STORE.name()).unwrap(), + name: Identifier::new("U64").unwrap(), + type_params: vec![], + }; + + utils::check_storage_res(origin_move_addr(), tag, expected); +} + +/// Panics with inner message of the passed error. +/// If message does not exist, just panics with debug render of entire error. +fn unwrap_move_err_in_dispatch_err(err: &sp_runtime::DispatchError) -> ! { + match err { + sp_runtime::DispatchError::Module { + message: Some(message), + .. + } => panic!("{}", message), + _ => panic!("{:?}", err), + } +} + +#[test] +/// Execute script and store U64 number inside storage. +fn execute_script() { + RuntimeBuilder::new().build().execute_with(|| { + const EXPECTED: u64 = 42; + let origin = bob_public_key(); + + utils::publish_module(origin, &modules::user::STORE, None).unwrap(); + utils::execute_tx(origin, &transactions::STORE_U64, None).unwrap(); + + check_stored_value(EXPECTED); + }); +} + +#[test] +/// Execute storing of block height inside module by calling script. +fn execute_store_block() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + + utils::publish_module(origin, &modules::user::STORE, None).unwrap(); + + const EXPECTED: u64 = 3; + for _ in 0..EXPECTED { + roll_next_block(); + } + utils::execute_tx(origin, &transactions::STORE_SYSTEM_BLOCK, None).unwrap(); + check_stored_value(EXPECTED); + }); +} + +#[test] +/// Execute storing of timestamp inside module by calling script. +fn execute_store_time() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + + utils::publish_module(origin, &modules::user::STORE, None).unwrap(); + + const EXPECTED: u64 = 3; + for _ in 0..EXPECTED { + roll_next_block(); + } + utils::execute_tx(origin, &transactions::STORE_SYSTEM_TIMESTAMP, None).unwrap(); + check_stored_value(EXPECTED * TIME_BLOCK_MULTIPLIER); + }); +} + +#[test] +/// Check the pallet doesn't allow scripts contains root signers. +fn execute_script_as_root() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + let result = utils::execute_tx(origin, &transactions::AS_ROOT, None); + + assert_err_ignore_postinfo!( + result, + DispatchError::Module { + index: 6, + error: 7, + message: Some("TransactionIsNotAllowedError") + } + ); + }); +} + +#[test] +/// Deploy user module, execute script (storing value in module), check event. +fn execute_script_with_event() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + + utils::publish_module(origin, &modules::user::EVENT_PROXY, None).unwrap(); + + // we need next block because events are not populated on genesis: + roll_next_block(); + + assert!(Sys::events().is_empty()); + + utils::execute_tx(origin, &transactions::EMIT_EVENT, None).unwrap(); + + // construct event: that should be emitted in the method call directly above + let tt = TypeTag::Struct(StructTag { + address: to_move_addr(origin), + module: Identifier::new(modules::user::EVENT_PROXY.name()).unwrap(), + name: Identifier::new("U64").unwrap(), + type_params: Vec::with_capacity(0), + }) + .to_string(); + let tt = tt.as_bytes(); + + // guid is sequence number (8 bytes) followed by account address + let mut guid = vec![0; 8]; + guid.extend(&origin.0); + + let expected = Event::Event(guid, tt.to_vec(), 42u64.to_le_bytes().to_vec()).into(); + + // iterate through array of `EventRecord`s + assert!(Sys::events().iter().any(|rec| { rec.event == expected })) + }); +} + +#[test] +/// Test execution of transaction which __does not__ requires a root/sudo. +/// The Call signied by __ordinar signer__. +fn execute_with_one_signer() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + utils::execute_tx(origin, &transactions::ONE_SIGNER_USER, None) + .expect("tx without root requirement called by ordinar signer"); + }); +} + +#[test] +/// Test execution of transaction which __requires__ a root/sudo signature. +/// The Call signied by __sudo__. +fn execute_with_one_signer_with_root_by_root() { + RuntimeBuilder::new().build().execute_with(|| { + utils::execute_tx_by_root(&transactions::ONE_SIGNER_ROOT, None) + .expect("tx with root requirement called by root origin"); + }); +} + +#[test] +#[should_panic(expected = "TransactionIsNotAllowedError")] +/// Test execution of transaction which __does not__ requires a root/sudo. +/// The Call signied by __sudo__. +fn execute_with_one_signer_by_root() { + RuntimeBuilder::new().build().execute_with(|| { + let error = utils::execute_tx_by_root(&transactions::ONE_SIGNER_USER, None) + .expect_err("tx without root requirement called by root signer should fail") + .error; + unwrap_move_err_in_dispatch_err(&error); + }); +} + +#[test] +#[should_panic(expected = "TransactionIsNotAllowedError")] +/// Test execution of transaction which __requires__ a root/sudo signature. +/// The Call signied by __ordinar signer__, not sudo/root. +fn execute_with_one_signer_with_root() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + let error = utils::execute_tx(origin, &transactions::ONE_SIGNER_ROOT, None) + .expect_err("tx with root requirement called by signed origin should fail") + .error; + unwrap_move_err_in_dispatch_err(&error); + }); +} From bd417c500a924c272d3258b532db21d2eb17e38b Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 10:28:34 +0300 Subject: [PATCH 10/13] unused variables --- node/src/service.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/src/service.rs b/node/src/service.rs index 1610e5a6..a5e67cf4 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -433,8 +433,8 @@ pub fn new_dev( let client_set_aside_for_cidp = client.clone(); // Create channels for mocked XCM messages. - let (downward_xcm_sender, downward_xcm_receiver) = flume::bounded::>(100); - let (hrmp_xcm_sender, hrmp_xcm_receiver) = flume::bounded::<(ParaId, Vec)>(100); + let (_downward_xcm_sender, downward_xcm_receiver) = flume::bounded::>(100); + let (_hrmp_xcm_sender, hrmp_xcm_receiver) = flume::bounded::<(ParaId, Vec)>(100); task_manager.spawn_essential_handle().spawn_blocking( "authorship_task", From f7034c313a69bfd0aec53e916e4862f91ac7fe77 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 11:24:50 +0300 Subject: [PATCH 11/13] fix dev seal --- node/src/service.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/node/src/service.rs b/node/src/service.rs index a5e67cf4..16a5bbfc 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -21,7 +21,9 @@ use sp_keystore::SyncCryptoStorePtr; use cumulus_client_consensus_common::ParachainConsensus; use cumulus_client_network::BlockAnnounceValidator; use nimbus_primitives::NimbusId; -use nimbus_consensus::{BuildNimbusConsensusParams, NimbusConsensus}; +use nimbus_consensus::{ + BuildNimbusConsensusParams, NimbusConsensus, NimbusManualSealConsensusDataProvider, +}; use primitives::Block; use sc_executor::NativeElseWasmExecutor; use sp_runtime::Percent; @@ -446,7 +448,10 @@ pub fn new_dev( pool: transaction_pool.clone(), commands_stream, select_chain, - consensus_data_provider: None, + consensus_data_provider: Some(Box::new(NimbusManualSealConsensusDataProvider { + keystore: keystore_container.sync_keystore(), + client: client.clone(), + })), create_inherent_data_providers: move |block: H256, ()| { let current_para_block = client_set_aside_for_cidp .number(block) From e5cb80c42b6a2ff16159287fb975c314555e4290 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 11:33:48 +0300 Subject: [PATCH 12/13] fix cargo check --- Cargo.lock | 148 +++++++++++++++++----------------- pallets/currencies/Cargo.toml | 1 - 2 files changed, 74 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff73f1c2..5b23d96c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -741,7 +741,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "finality-grandpa", "frame-support", @@ -757,7 +757,7 @@ dependencies = [ [[package]] name = "bp-message-dispatch" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-runtime", "frame-support", @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-runtime", @@ -785,7 +785,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-runtime", @@ -803,7 +803,7 @@ dependencies = [ [[package]] name = "bp-rococo" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -820,7 +820,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "hash-db", @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "ed25519-dalek", @@ -853,7 +853,7 @@ dependencies = [ [[package]] name = "bp-wococo" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -868,7 +868,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-messages", @@ -3724,7 +3724,7 @@ dependencies = [ [[package]] name = "kusama-runtime" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -3812,7 +3812,7 @@ dependencies = [ [[package]] name = "kusama-runtime-constants" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -4747,7 +4747,7 @@ dependencies = [ [[package]] name = "metered-channel" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -5702,7 +5702,7 @@ dependencies = [ [[package]] name = "pallet-bridge-dispatch" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-runtime", @@ -5719,7 +5719,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "bp-runtime", @@ -5741,7 +5741,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-message-dispatch", @@ -6378,7 +6378,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -6396,7 +6396,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -6830,7 +6830,7 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "polkadot-approval-distribution" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-network-protocol", @@ -6844,7 +6844,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-network-protocol", @@ -6857,7 +6857,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -6879,7 +6879,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "lru 0.7.2", @@ -6899,7 +6899,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking-cli", "futures 0.3.21", @@ -6922,7 +6922,7 @@ dependencies = [ [[package]] name = "polkadot-client" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "frame-benchmarking", @@ -6954,7 +6954,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "derive_more", @@ -6975,7 +6975,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -6988,7 +6988,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -7010,7 +7010,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -7024,7 +7024,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7044,7 +7044,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7063,7 +7063,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "parity-scale-codec", @@ -7081,7 +7081,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "derive_more", @@ -7109,7 +7109,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7129,7 +7129,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7147,7 +7147,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-subsystem", @@ -7162,7 +7162,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7180,7 +7180,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-subsystem", @@ -7195,7 +7195,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7212,7 +7212,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "kvdb", @@ -7230,7 +7230,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7247,7 +7247,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7264,7 +7264,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "assert_matches", @@ -7294,7 +7294,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-primitives", @@ -7310,7 +7310,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "memory-lru", @@ -7328,7 +7328,7 @@ dependencies = [ [[package]] name = "polkadot-node-jaeger" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-std", "lazy_static", @@ -7346,7 +7346,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bs58", "futures 0.3.21", @@ -7365,7 +7365,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", @@ -7383,7 +7383,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bounded-vec", "futures 0.3.21", @@ -7405,7 +7405,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "polkadot-node-jaeger", "polkadot-node-subsystem-types", @@ -7415,7 +7415,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -7434,7 +7434,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", @@ -7462,7 +7462,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7483,7 +7483,7 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7500,7 +7500,7 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen-proc-macro" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "proc-macro-crate 1.1.1", "proc-macro2", @@ -7511,7 +7511,7 @@ dependencies = [ [[package]] name = "polkadot-parachain" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "frame-support", @@ -7528,7 +7528,7 @@ dependencies = [ [[package]] name = "polkadot-performance-test" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "env_logger", "kusama-runtime", @@ -7543,7 +7543,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "frame-system", @@ -7573,7 +7573,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-gadget", "beefy-gadget-rpc", @@ -7604,7 +7604,7 @@ dependencies = [ [[package]] name = "polkadot-runtime" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7688,7 +7688,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7735,7 +7735,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-constants" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -7747,7 +7747,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bs58", "parity-scale-codec", @@ -7759,7 +7759,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitflags", "bitvec", @@ -7800,7 +7800,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "beefy-gadget", @@ -7902,7 +7902,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "arrayvec 0.5.2", "derive_more", @@ -7923,7 +7923,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -8638,7 +8638,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bp-messages", @@ -8713,7 +8713,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -10215,7 +10215,7 @@ dependencies = [ [[package]] name = "slot-range-helper" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "enumn", "parity-scale-codec", @@ -12629,7 +12629,7 @@ dependencies = [ [[package]] name = "westend-runtime" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -12715,7 +12715,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -12823,7 +12823,7 @@ dependencies = [ [[package]] name = "xcm" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derivative", "impl-trait-for-tuples", @@ -12836,7 +12836,7 @@ dependencies = [ [[package]] name = "xcm-builder" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -12880,7 +12880,7 @@ dependencies = [ [[package]] name = "xcm-executor" version = "0.9.16" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -12898,7 +12898,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "Inflector", "proc-macro2", diff --git a/pallets/currencies/Cargo.toml b/pallets/currencies/Cargo.toml index c637a605..af5d242c 100644 --- a/pallets/currencies/Cargo.toml +++ b/pallets/currencies/Cargo.toml @@ -44,6 +44,5 @@ std = [ "orml-traits/std", "orml-utilities/std", "primitives/std", - "orml-tokens/std", ] try-runtime = ["frame-support/try-runtime"] From 791f42866b10232d7dd2040f06a38cf7e42ab902 Mon Sep 17 00:00:00 2001 From: borispovod Date: Wed, 16 Feb 2022 19:52:03 +0300 Subject: [PATCH 13/13] update deps: http -> https --- Cargo.lock | 511 +++++++++++++++++++++--------------------- node/Cargo.toml | 78 +++---- primitives/Cargo.toml | 6 +- runtime/Cargo.toml | 56 ++--- 4 files changed, 326 insertions(+), 325 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b23d96c..fc12239a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "beefy-gadget" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-primitives", "fnv", @@ -511,7 +511,7 @@ dependencies = [ [[package]] name = "beefy-gadget-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-gadget", "beefy-primitives", @@ -535,12 +535,12 @@ dependencies = [ [[package]] name = "beefy-merkle-tree" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" [[package]] name = "beefy-primitives" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -741,7 +741,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "finality-grandpa", "frame-support", @@ -757,7 +757,7 @@ dependencies = [ [[package]] name = "bp-message-dispatch" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-runtime", "frame-support", @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-runtime", @@ -785,7 +785,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-runtime", @@ -803,7 +803,7 @@ dependencies = [ [[package]] name = "bp-rococo" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -820,7 +820,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "hash-db", @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "ed25519-dalek", @@ -853,7 +853,7 @@ dependencies = [ [[package]] name = "bp-wococo" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -868,7 +868,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-messages", @@ -994,9 +994,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2ae6de944143141f6155a473a6b02f66c7c3f9f47316f802f80204ebfe6e12" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", @@ -1385,11 +1385,12 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-common" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" dependencies = [ "generic-array 0.14.5", + "typenum 1.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1661,7 +1662,7 @@ name = "cumulus-pallet-parachain-system-proc-macro" version = "0.1.0" source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.16#86f76c5619c64d1300315612695ad4b4fcd0f562" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -1983,9 +1984,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer 0.10.2", "crypto-common", @@ -2437,7 +2438,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", ] @@ -2455,7 +2456,7 @@ dependencies = [ [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -2476,7 +2477,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "Inflector", "chrono", @@ -2502,7 +2503,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -2516,7 +2517,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -2544,7 +2545,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "bitflags", "frame-metadata", @@ -2573,7 +2574,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "Inflector", "frame-support-procedural-tools", @@ -2585,10 +2586,10 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -2597,7 +2598,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro2", "quote", @@ -2607,7 +2608,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "log", @@ -2624,7 +2625,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -2639,7 +2640,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "sp-api", @@ -2648,7 +2649,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "sp-api", @@ -3645,7 +3646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d802063f7a3c867456955f9d2f15eb3ee0edb5ec9ec2b5526324756759221c0f" dependencies = [ "log", - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -3724,7 +3725,7 @@ dependencies = [ [[package]] name = "kusama-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -3812,7 +3813,7 @@ dependencies = [ [[package]] name = "kusama-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -4747,7 +4748,7 @@ dependencies = [ [[package]] name = "metered-channel" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -5029,7 +5030,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro-error", "proc-macro2", "quote", @@ -5553,7 +5554,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -5569,7 +5570,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -5584,7 +5585,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5608,7 +5609,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5628,7 +5629,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5643,7 +5644,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-primitives", "frame-support", @@ -5659,7 +5660,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "beefy-merkle-tree", "beefy-primitives", @@ -5684,7 +5685,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5702,7 +5703,7 @@ dependencies = [ [[package]] name = "pallet-bridge-dispatch" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-message-dispatch", "bp-runtime", @@ -5719,7 +5720,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bp-header-chain", "bp-runtime", @@ -5741,7 +5742,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "bp-message-dispatch", @@ -5762,7 +5763,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5779,7 +5780,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5795,7 +5796,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5819,7 +5820,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5837,7 +5838,7 @@ dependencies = [ [[package]] name = "pallet-gilt" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5852,7 +5853,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5875,7 +5876,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5891,7 +5892,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5911,7 +5912,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5928,7 +5929,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -5945,7 +5946,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ckb-merkle-mountain-range", "frame-benchmarking", @@ -5963,7 +5964,7 @@ dependencies = [ [[package]] name = "pallet-mmr-primitives" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -5979,7 +5980,7 @@ dependencies = [ [[package]] name = "pallet-mmr-rpc" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", @@ -5996,7 +5997,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6011,7 +6012,7 @@ dependencies = [ [[package]] name = "pallet-nicks" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6025,7 +6026,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6042,7 +6043,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6065,7 +6066,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6081,7 +6082,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6096,7 +6097,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6110,7 +6111,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6124,7 +6125,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6140,7 +6141,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6161,7 +6162,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6177,7 +6178,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6191,7 +6192,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -6214,9 +6215,9 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -6225,7 +6226,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "sp-arithmetic", @@ -6234,7 +6235,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6248,7 +6249,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6266,7 +6267,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6285,7 +6286,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-support", "frame-system", @@ -6302,7 +6303,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", @@ -6319,7 +6320,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -6330,7 +6331,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6347,7 +6348,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6363,7 +6364,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-benchmarking", "frame-support", @@ -6378,7 +6379,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -6396,7 +6397,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -6483,7 +6484,7 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -6830,7 +6831,7 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "polkadot-approval-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-network-protocol", @@ -6844,7 +6845,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-network-protocol", @@ -6857,7 +6858,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -6879,7 +6880,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "lru 0.7.2", @@ -6899,7 +6900,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking-cli", "futures 0.3.21", @@ -6922,7 +6923,7 @@ dependencies = [ [[package]] name = "polkadot-client" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "frame-benchmarking", @@ -6954,7 +6955,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "derive_more", @@ -6975,7 +6976,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -6988,7 +6989,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -7010,7 +7011,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -7024,7 +7025,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7044,7 +7045,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7063,7 +7064,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "parity-scale-codec", @@ -7081,7 +7082,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "derive_more", @@ -7109,7 +7110,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7129,7 +7130,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7147,7 +7148,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-subsystem", @@ -7162,7 +7163,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7180,7 +7181,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-subsystem", @@ -7195,7 +7196,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7212,7 +7213,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "kvdb", @@ -7230,7 +7231,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7247,7 +7248,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "futures 0.3.21", @@ -7264,7 +7265,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "always-assert", "assert_matches", @@ -7294,7 +7295,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "polkadot-node-primitives", @@ -7310,7 +7311,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "memory-lru", @@ -7328,7 +7329,7 @@ dependencies = [ [[package]] name = "polkadot-node-jaeger" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-std", "lazy_static", @@ -7346,7 +7347,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bs58", "futures 0.3.21", @@ -7365,7 +7366,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", @@ -7383,7 +7384,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bounded-vec", "futures 0.3.21", @@ -7405,7 +7406,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "polkadot-node-jaeger", "polkadot-node-subsystem-types", @@ -7415,7 +7416,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "futures 0.3.21", @@ -7434,7 +7435,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "derive_more", @@ -7462,7 +7463,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "futures 0.3.21", "futures-timer", @@ -7483,7 +7484,7 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "futures 0.3.21", @@ -7500,9 +7501,9 @@ dependencies = [ [[package]] name = "polkadot-overseer-gen-proc-macro" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -7511,7 +7512,7 @@ dependencies = [ [[package]] name = "polkadot-parachain" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derive_more", "frame-support", @@ -7528,7 +7529,7 @@ dependencies = [ [[package]] name = "polkadot-performance-test" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "env_logger", "kusama-runtime", @@ -7543,7 +7544,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitvec", "frame-system", @@ -7573,7 +7574,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-gadget", "beefy-gadget-rpc", @@ -7604,7 +7605,7 @@ dependencies = [ [[package]] name = "polkadot-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7688,7 +7689,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -7735,7 +7736,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -7747,7 +7748,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bs58", "parity-scale-codec", @@ -7759,7 +7760,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "bitflags", "bitvec", @@ -7800,7 +7801,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "async-trait", "beefy-gadget", @@ -7902,7 +7903,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "arrayvec 0.5.2", "derive_more", @@ -7923,7 +7924,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -8174,9 +8175,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "738b5123081e03ec93bdd0229f33e39891e6ee18745b72bfc8fdc04a080d5c38" +checksum = "9dada8c9981fcf32929c3c0f0cd796a9284aca335565227ed88c83babb1d43dc" dependencies = [ "thiserror", "toml", @@ -8561,7 +8562,7 @@ dependencies = [ [[package]] name = "remote-externalities" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "env_logger", "jsonrpsee", @@ -8638,7 +8639,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bp-messages", @@ -8713,7 +8714,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -8869,7 +8870,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "sp-core 4.1.0-dev", @@ -8880,7 +8881,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", @@ -8907,7 +8908,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "futures-timer", @@ -8930,7 +8931,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -8946,7 +8947,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-trait-for-tuples", "memmap2 0.5.3", @@ -8963,9 +8964,9 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -8974,7 +8975,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "chrono", "fdlimit", @@ -9012,7 +9013,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "fnv", "futures 0.3.21", @@ -9040,7 +9041,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", "kvdb", @@ -9065,7 +9066,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "futures 0.3.21", @@ -9089,7 +9090,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", @@ -9118,7 +9119,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", @@ -9161,7 +9162,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", "futures 0.3.21", @@ -9185,7 +9186,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "fork-tree", "parity-scale-codec", @@ -9198,7 +9199,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "assert_matches", "async-trait", @@ -9234,7 +9235,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "futures 0.3.21", @@ -9259,7 +9260,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "sc-client-api", "sp-authorship", @@ -9270,7 +9271,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "lazy_static", "libsecp256k1 0.7.0", @@ -9298,7 +9299,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", "environmental", @@ -9316,7 +9317,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "parity-scale-codec", @@ -9332,7 +9333,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "cfg-if 1.0.0", "libc", @@ -9350,7 +9351,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", @@ -9388,7 +9389,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", "finality-grandpa", @@ -9412,7 +9413,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ansi_term", "futures 0.3.21", @@ -9429,7 +9430,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", @@ -9444,7 +9445,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-std", "async-trait", @@ -9495,7 +9496,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "futures-timer", @@ -9511,7 +9512,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "bytes 1.1.0", "fnv", @@ -9539,7 +9540,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "libp2p", @@ -9552,7 +9553,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -9561,7 +9562,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "hash-db", @@ -9592,7 +9593,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "jsonrpc-core 18.0.0", @@ -9617,7 +9618,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "jsonrpc-core 18.0.0", @@ -9634,7 +9635,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "directories", @@ -9698,7 +9699,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "parity-scale-codec", @@ -9712,7 +9713,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpc-core 18.0.0", "jsonrpc-core-client 18.0.0", @@ -9734,7 +9735,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "chrono", "futures 0.3.21", @@ -9752,7 +9753,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ansi_term", "atty", @@ -9783,9 +9784,9 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -9794,7 +9795,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "futures-timer", @@ -9821,7 +9822,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "derive_more", "futures 0.3.21", @@ -9835,7 +9836,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "futures-timer", @@ -9864,7 +9865,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baeb2780690380592f86205aa4ee49815feb2acad8c2f59e6dd207148c3f1fcd" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -10110,7 +10111,7 @@ checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ "cfg-if 1.0.0", "cpufeatures 0.2.1", - "digest 0.10.2", + "digest 0.10.3", ] [[package]] @@ -10215,7 +10216,7 @@ dependencies = [ [[package]] name = "slot-range-helper" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "enumn", "parity-scale-codec", @@ -10312,7 +10313,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", "log", @@ -10329,10 +10330,10 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "blake2-rfc", - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -10341,7 +10342,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -10354,7 +10355,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "integer-sqrt", "num-traits", @@ -10369,7 +10370,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -10382,7 +10383,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "parity-scale-codec", @@ -10394,7 +10395,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "sp-api", @@ -10406,7 +10407,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "log", @@ -10424,7 +10425,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "futures 0.3.21", @@ -10443,7 +10444,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "parity-scale-codec", @@ -10461,7 +10462,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "merlin", @@ -10484,7 +10485,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -10496,7 +10497,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -10553,7 +10554,7 @@ dependencies = [ [[package]] name = "sp-core" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "base58 0.2.0", "bitflags", @@ -10601,7 +10602,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "blake2-rfc", "byteorder", @@ -10614,7 +10615,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro2", "quote", @@ -10625,7 +10626,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "kvdb", "parking_lot 0.11.2", @@ -10644,7 +10645,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "proc-macro2", "quote", @@ -10665,7 +10666,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.10.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "environmental", "parity-scale-codec", @@ -10676,7 +10677,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "finality-grandpa", "log", @@ -10694,7 +10695,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -10732,7 +10733,7 @@ dependencies = [ [[package]] name = "sp-io" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "futures 0.3.21", "hash-db", @@ -10756,7 +10757,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "lazy_static", "sp-core 4.1.0-dev", @@ -10783,7 +10784,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.10.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "derive_more", @@ -10800,7 +10801,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "zstd", ] @@ -10879,7 +10880,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -10894,9 +10895,9 @@ dependencies = [ [[package]] name = "sp-npos-elections-solution-type" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -10905,7 +10906,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "sp-api", "sp-core 4.1.0-dev", @@ -10923,7 +10924,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "backtrace", "lazy_static", @@ -10933,7 +10934,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "rustc-hash", "serde", @@ -10943,7 +10944,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "either", "hash256-std-hasher", @@ -10982,7 +10983,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -11002,7 +11003,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57346f6b24875f8935280dba51fa8ab0a9ba1e39" dependencies = [ "Inflector", - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -11011,10 +11012,10 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "Inflector", - "proc-macro-crate 1.1.1", + "proc-macro-crate 1.1.2", "proc-macro2", "quote", "syn", @@ -11023,7 +11024,7 @@ dependencies = [ [[package]] name = "sp-serializer" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "serde", "serde_json", @@ -11032,7 +11033,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -11046,7 +11047,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "scale-info", @@ -11080,7 +11081,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.10.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", "log", @@ -11108,7 +11109,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.11#57 [[package]] name = "sp-std" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" [[package]] name = "sp-storage" @@ -11126,7 +11127,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-serde", "parity-scale-codec", @@ -11139,7 +11140,7 @@ dependencies = [ [[package]] name = "sp-tasks" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "log", "sp-core 4.1.0-dev", @@ -11152,7 +11153,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "futures-timer", @@ -11186,7 +11187,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "sp-std 4.0.0", @@ -11198,7 +11199,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "sp-api", "sp-runtime", @@ -11207,7 +11208,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-trait", "log", @@ -11238,7 +11239,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "4.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "hash-db", "memory-db 0.28.0", @@ -11253,7 +11254,7 @@ dependencies = [ [[package]] name = "sp-version" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-serde", "parity-scale-codec", @@ -11270,7 +11271,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -11292,7 +11293,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "4.1.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "impl-trait-for-tuples", "log", @@ -11482,7 +11483,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "platforms", ] @@ -11500,7 +11501,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.21", @@ -11522,7 +11523,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "async-std", "derive_more", @@ -11536,7 +11537,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "ansi_term", "build-helper", @@ -12032,7 +12033,7 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+http://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.16#4aeb95f7f38fcd519e2628f32f79044a8fef99d5" dependencies = [ "jsonrpsee", "log", @@ -12629,7 +12630,7 @@ dependencies = [ [[package]] name = "westend-runtime" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "beefy-primitives", "bitvec", @@ -12715,7 +12716,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "polkadot-primitives", @@ -12823,7 +12824,7 @@ dependencies = [ [[package]] name = "xcm" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "derivative", "impl-trait-for-tuples", @@ -12836,7 +12837,7 @@ dependencies = [ [[package]] name = "xcm-builder" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-support", "frame-system", @@ -12880,7 +12881,7 @@ dependencies = [ [[package]] name = "xcm-executor" version = "0.9.16" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "frame-benchmarking", "frame-support", @@ -12898,7 +12899,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "0.1.0" -source = "git+http://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" +source = "git+https://github.com/paritytech/polkadot.git?branch=release-v0.9.16#41ab002d7451766324a9f314fee11c9c53314350" dependencies = [ "Inflector", "proc-macro2", diff --git a/node/Cargo.toml b/node/Cargo.toml index 7824aa3b..c9b1052a 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -31,45 +31,45 @@ log = "0.4" serde = { version = "1.0", features = ["derive"] } # Substrate dependencies -frame-benchmarking = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -frame-benchmarking-cli = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-transaction-payment-rpc = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -substrate-frame-rpc-system = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -substrate-prometheus-endpoint = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-benchmarking = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-benchmarking-cli = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-transaction-payment-rpc = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +substrate-frame-rpc-system = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +substrate-prometheus-endpoint = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Substarte Client Dependencies -sc-basic-authorship = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-cli = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } -sc-client-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-consensus = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-executor = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } -sc-finality-grandpa = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-keystore = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-rpc = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-rpc-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-service = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } -sc-telemetry = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-transaction-pool = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-tracing = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-chain-spec = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-network = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-transaction-pool-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sc-consensus-manual-seal = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-basic-authorship = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-cli = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } +sc-client-api = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-consensus = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-executor = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } +sc-finality-grandpa = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-keystore = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-rpc = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-rpc-api = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-service = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16', features = ['wasmtime'] } +sc-telemetry = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-transaction-pool = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-tracing = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-chain-spec = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-network = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-transaction-pool-api = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sc-consensus-manual-seal = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Substrate Primitive Dependencies -sp-api = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-block-builder = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-blockchain = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-consensus = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-core = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-finality-grandpa = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-inherents = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-runtime = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-transaction-pool = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-timestamp = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-session = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-offchain = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-keystore = { git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-api = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-block-builder = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-blockchain = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-consensus = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-finality-grandpa = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-inherents = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-transaction-pool = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-timestamp = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-session = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-offchain = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-keystore = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Nimbus dependencies nimbus-primitives = { git = "https://github.com/pontem-network/nimbus", branch = 'polkadot-v0.9.16' } @@ -87,9 +87,9 @@ cumulus-relay-chain-local = { git = 'https://github.com/paritytech/cumulus', bra cumulus-relay-chain-interface = { git = 'https://github.com/paritytech/cumulus', branch = 'polkadot-v0.9.16' } # Polkadot dependencies -polkadot-primitives = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } -polkadot-service = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } -polkadot-parachain = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +polkadot-primitives = { git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +polkadot-service = { git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } +polkadot-parachain = { git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } flume = "0.10.9" @@ -109,7 +109,7 @@ constants = { path = "../constants" } # # ** Don't enable relay chains you don't need, as this is a **very** heavy build for no reason** # More info: https://github.com/paritytech/polkadot/pull/3189 -polkadot-cli = { git = 'http://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16', features = ["kusama-native"] } +polkadot-cli = { git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16', features = ["kusama-native"] } [dependencies.move-vm] package = "mvm" diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 76eefa05..0e4fe551 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -11,9 +11,9 @@ version = '3.0.0' serde = { version = "1.0", optional = true } codec = { package = "parity-scale-codec", version = "2.3.1", default-features = false, features = ["max-encoded-len"] } scale-info = { version = "1.0", default-features = false, features = ["derive"] } -sp-std = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-core = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-runtime = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } [features] default = ["std"] diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index a512c9e6..0fc82e8f 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -26,35 +26,35 @@ smallvec = "1.6" # Substrate dependencies scale-info = { version = "1.0", default-features = false, features = ["derive"] } -frame-benchmarking = { default-features = false, optional = true, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -frame-executive = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -frame-support = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -frame-system = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -frame-system-benchmarking = { default-features = false, optional = true, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -frame-system-rpc-runtime-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-balances = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-randomness-collective-flip = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-sudo = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-timestamp = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-transaction-payment = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-vesting = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-treasury = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-democracy = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-scheduler = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-executive = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +frame-system-rpc-runtime-api = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-balances = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-randomness-collective-flip = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-sudo = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-timestamp = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-transaction-payment = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-vesting = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-treasury = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-democracy = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-scheduler = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } # Substrate Primitives dependencies -sp-api = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-block-builder = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-core = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-inherents = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-offchain = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-runtime = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-session = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-std = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-transaction-pool = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -sp-version = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } -pallet-multisig = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-api = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-block-builder = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-inherents = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-offchain = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-session = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-transaction-pool = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-version = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +pallet-multisig = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } pallet-xcm = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } xcm = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } xcm-builder = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } @@ -100,7 +100,7 @@ transaction-pause = { path = "../pallets/transaction-pause", default-features = xcm-emulator = { git = 'https://github.com/pontem-network/xcm-simulator', branch = 'polkadot-v0.9.16' } polkadot-runtime-parachains = { default-features = false, git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } kusama-runtime = { git = 'https://github.com/paritytech/polkadot.git', branch = 'release-v0.9.16' } -sp-io = { default-features = false, git = 'http://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } +sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.16' } assets = { path = '../assets', default-features = false } env_logger = "0.9.0" test-log = "0.2.8"