diff --git a/Cargo.lock b/Cargo.lock index d37babb5bbc0..e6bc093b9fca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,7 +27,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.28.0", + "gimli 0.28.1", ] [[package]] @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher 0.4.4", @@ -74,7 +74,7 @@ dependencies = [ "cipher 0.4.4", "ctr", "ghash", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -103,18 +103,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.4" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-primitives" @@ -138,13 +138,12 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.3" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" +checksum = "a43b18702501396fa9bcdeecd533bc85fac75150d308fc0f6800a01e6234a003" dependencies = [ "arrayvec 0.7.4", "bytes", - "smol_str", ] [[package]] @@ -157,9 +156,9 @@ dependencies = [ "dunce", "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", "syn-solidity", "tiny-keccak", ] @@ -214,50 +213,51 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -284,9 +284,9 @@ dependencies = [ "include_dir", "itertools 0.10.5", "proc-macro-error", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -518,7 +518,7 @@ checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint", "num-traits", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -549,20 +549,6 @@ dependencies = [ "hashbrown 0.13.2", ] -[[package]] -name = "ark-scale" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bd73bb6ddb72630987d37fa963e99196896c0d0ea81b7c894567e74a2f83af" -dependencies = [ - "ark-ec", - "ark-ff 0.4.2", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "parity-scale-codec", - "scale-info", -] - [[package]] name = "ark-scale" version = "0.0.12" @@ -620,7 +606,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -661,15 +647,15 @@ dependencies = [ [[package]] name = "array-bytes" -version = "6.2.2" +version = "6.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" +checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -704,11 +690,11 @@ dependencies = [ [[package]] name = "asn1-rs" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" dependencies = [ - "asn1-rs-derive 0.5.0", + "asn1-rs-derive 0.5.1", "asn1-rs-impl 0.2.0", "displaydoc", "nom", @@ -724,7 +710,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", "synstructure 0.12.6", @@ -732,13 +718,13 @@ dependencies = [ [[package]] name = "asn1-rs-derive" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", "synstructure 0.13.1", ] @@ -748,7 +734,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -759,21 +745,21 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "assert_cmd" -version = "2.0.14" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8" +checksum = "bc65048dd435533bb1baf2ed9956b9a278fbfdcf90301b39ee117f06c0199d37" dependencies = [ "anstyle", "bstr", "doc-comment", - "predicates 3.0.3", + "predicates 3.1.2", "predicates-core", "predicates-tree", "wait-timeout", @@ -1110,17 +1096,28 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-executor" -version = "1.5.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ - "async-lock 2.8.0", "async-task", "concurrent-queue", - "fastrand 1.9.0", - "futures-lite 1.13.0", + "fastrand 2.1.0", + "futures-lite 2.3.0", "slab", ] @@ -1138,16 +1135,16 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel", + "async-channel 2.3.1", "async-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io 2.3.3", + "async-lock 3.4.0", "blocking", - "futures-lite 1.13.0", + "futures-lite 2.3.0", "once_cell", ] @@ -1165,9 +1162,9 @@ dependencies = [ "log", "parking", "polling 2.8.0", - "rustix 0.37.23", + "rustix 0.37.27", "slab", - "socket2 0.4.9", + "socket2 0.4.10", "waker-fn", ] @@ -1183,8 +1180,8 @@ dependencies = [ "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.4.0", - "rustix 0.38.21", + "polling 3.7.2", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -1205,41 +1202,57 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 5.2.0", + "event-listener 5.3.1", "event-listener-strategy", "pin-project-lite", ] [[package]] name = "async-net" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" +checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" dependencies = [ "async-io 1.13.0", - "autocfg", "blocking", "futures-lite 1.13.0", ] [[package]] name = "async-process" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ "async-io 1.13.0", "async-lock 2.8.0", - "autocfg", + "async-signal", "blocking", "cfg-if", - "event-listener 2.5.3", + "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.37.23", - "signal-hook", + "rustix 0.38.34", "windows-sys 0.48.0", ] +[[package]] +name = "async-signal" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" +dependencies = [ + "async-io 2.3.3", + "async-lock 3.4.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.34", + "signal-hook-registry", + "slab", + "windows-sys 0.52.0", +] + [[package]] name = "async-std" version = "1.12.0" @@ -1247,7 +1260,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ "async-attributes", - "async-channel", + "async-channel 1.9.0", "async-global-executor", "async-io 1.13.0", "async-lock 2.8.0", @@ -1284,26 +1297,26 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "async-task" -version = "4.4.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -1327,9 +1340,9 @@ checksum = "a8ab6b55fe97976e46f91ddbed8d147d966475dc29b2032757ba47e02376fbc3" [[package]] name = "atomic-waker" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "attohttpc" @@ -1337,7 +1350,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" dependencies = [ - "http 0.2.9", + "http 0.2.12", "log", "url", ] @@ -1355,21 +1368,20 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backoff" @@ -1438,9 +1450,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" @@ -1454,15 +1466,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "basic-toml" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" -dependencies = [ - "serde", -] - [[package]] name = "beef" version = "0.5.2" @@ -1505,13 +1508,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.12", - "proc-macro2 1.0.82", + "prettyplease 0.2.20", + "proc-macro2 1.0.86", "quote 1.0.36", "regex", "rustc-hash", "shlex", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -1620,31 +1623,31 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq 0.2.6", + "constant_time_eq 0.3.0", ] [[package]] name = "blake2s_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq 0.2.6", + "constant_time_eq 0.3.0", ] [[package]] name = "blake3" -version = "1.5.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" dependencies = [ "arrayref", "arrayvec 0.7.4", @@ -1673,17 +1676,15 @@ dependencies = [ [[package]] name = "blocking" -version = "1.3.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel", - "async-lock 2.8.0", + "async-channel 2.3.1", "async-task", - "atomic-waker", - "fastrand 1.9.0", - "futures-lite 1.13.0", - "log", + "futures-io", + "futures-lite 2.3.0", + "piper", ] [[package]] @@ -2387,12 +2388,12 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.3.6", + "regex-automata 0.4.7", "serde", ] @@ -2407,9 +2408,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -2425,21 +2426,21 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "bzip2-sys" @@ -2464,18 +2465,18 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.3" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -2488,7 +2489,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.18", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -2508,9 +2509,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.0.94" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", @@ -2533,9 +2534,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.15.5" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", ] @@ -2613,23 +2614,23 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -2638,15 +2639,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -2709,9 +2710,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -2747,48 +2748,48 @@ dependencies = [ "once_cell", "strsim 0.10.0", "termcolor", - "textwrap 0.16.0", + "textwrap 0.16.1", ] [[package]] name = "clap" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", - "clap_derive 4.5.11", + "clap_derive 4.5.13", ] [[package]] name = "clap-num" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488557e97528174edaa2ee268b23a809e0c598213a4bbcb4f34575a46fda147e" +checksum = "0e063d263364859dc54fb064cedb7c122740cd4733644b14b176c097f51e8ab7" dependencies = [ "num-traits", ] [[package]] name = "clap_builder" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.0", - "strsim 0.11.0", + "clap_lex 0.7.2", + "strsim 0.11.1", "terminal_size", ] [[package]] name = "clap_complete" -version = "4.4.0" +version = "4.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" +checksum = "a8670053e87c316345e384ca1f3eba3006fc6355ed8b8a1140d104e109e3df34" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", ] [[package]] @@ -2799,21 +2800,21 @@ checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "clap_derive" -version = "4.5.11" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -2827,19 +2828,18 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "coarsetime" -version = "0.1.23" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90d114103adbc625300f346d4d09dfb4ab1c4a8df6868435dd903392ecf4354" +checksum = "13b3839cf01bb7960114be3ccf2340f541b6d0c81f8690b007b2b39f750f7e5d" dependencies = [ "libc", - "once_cell", - "wasi", + "wasix", "wasm-bindgen", ] @@ -2971,9 +2971,9 @@ dependencies = [ [[package]] name = "color-eyre" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" dependencies = [ "backtrace", "eyre", @@ -2984,47 +2984,46 @@ dependencies = [ [[package]] name = "color-print" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2a5e6504ed8648554968650feecea00557a3476bc040d0ffc33080e66b646d0" +checksum = "1ee543c60ff3888934877a5671f45494dd27ed4ba25c6670b9a7576b7ed7a8c0" dependencies = [ "color-print-proc-macro", ] [[package]] name = "color-print-proc-macro" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51beaa537d73d2d1ff34ee70bc095f170420ab2ec5d687ecd3ec2b0d092514b" +checksum = "77ff1a80c5f3cb1ca7c06ffdd71b6a6dd6d8f896c42141fbd43f50ed28dcdb93" dependencies = [ "nom", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -3032,12 +3031,12 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "strum 0.25.0", - "strum_macros 0.25.3", + "strum 0.26.3", + "strum_macros 0.26.4", "unicode-width", ] @@ -3065,9 +3064,9 @@ checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -3097,9 +3096,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" dependencies = [ "cfg-if", "cpufeatures", @@ -3110,29 +3109,27 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-random" -version = "0.1.15" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" dependencies = [ "const-random-macro", - "proc-macro-hack", ] [[package]] name = "const-random-macro" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ "getrandom", "once_cell", - "proc-macro-hack", "tiny-keccak", ] @@ -3142,12 +3139,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "constant_time_eq" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" - [[package]] name = "constant_time_eq" version = "0.3.0" @@ -3156,9 +3147,9 @@ checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "constcat" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f272d0c4cf831b4fa80ee529c7707f76585986e910e1fbce1d7921970bc1a241" +checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08" [[package]] name = "contracts-rococo-runtime" @@ -3476,9 +3467,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -3583,9 +3574,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2b432c56615136f8dba245fed7ec3d5518c500a31108661067e61e72fe7e6bc" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -3598,9 +3589,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -3614,7 +3605,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.11", + "clap 4.5.13", "criterion-plot", "futures", "is-terminal", @@ -3645,46 +3636,37 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -3694,13 +3676,13 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array 0.14.7", "rand_core", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -3732,7 +3714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.7", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -3748,7 +3730,7 @@ dependencies = [ name = "cumulus-client-cli" version = "0.7.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -4121,9 +4103,9 @@ name = "cumulus-pallet-parachain-system-proc-macro" version = "0.6.0" dependencies = [ "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -4211,7 +4193,7 @@ name = "cumulus-pov-validator" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.11", + "clap 4.5.13", "parity-scale-codec", "polkadot-node-primitives", "polkadot-parachain-primitives", @@ -4221,7 +4203,7 @@ dependencies = [ "sp-io", "sp-maybe-compressed-blob", "tracing", - "tracing-subscriber 0.3.18", + "tracing-subscriber", ] [[package]] @@ -4536,7 +4518,7 @@ name = "cumulus-test-service" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.5.11", + "clap 4.5.13", "criterion", "cumulus-client-cli", "cumulus-client-collator", @@ -4628,9 +4610,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.72+curl-8.6.0" +version = "0.4.74+curl-8.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" +checksum = "8af10b986114528fcdc4b63b6f5f021b7057618411046a4de2ba0f0149a097bf" dependencies = [ "cc", "libc", @@ -4654,19 +4636,19 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "rustc_version 0.4.0", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] [[package]] name = "curve25519-dalek-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -4684,9 +4666,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.106" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28403c86fc49e3401fdf45499ba37fad6493d9329449d6449d7f0e10f4654d28" +checksum = "273dcfd3acd4e1e276af13ed2a43eea7001318823e7a726a6b3ed39b4acc0b82" dependencies = [ "cc", "cxxbridge-flags", @@ -4696,60 +4678,60 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.106" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78da94fef01786dc3e0c76eafcd187abcaa9972c78e05ff4041e24fdf059c285" +checksum = "d8b2766fbd92be34e9ed143898fce6c572dc009de39506ed6903e5a05b68914e" dependencies = [ "cc", "codespan-reporting", "once_cell", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "scratch", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "cxxbridge-flags" -version = "1.0.106" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a6f5e1dfb4b34292ad4ea1facbfdaa1824705b231610087b00b17008641809" +checksum = "839fcd5e43464614ffaa989eaf1c139ef1f0c51672a1ed08023307fa1b909ccd" [[package]] name = "cxxbridge-macro" -version = "1.0.106" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c49547d73ba8dcfd4ad7325d64c6d5391ff4224d498fc39a6f3f49825a530d" +checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "dashmap" -version = "5.5.1" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd72493923899c6f10c641bdbdeddc7183d6396641d99c1a0d1597f37f92e28" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.8", + "parking_lot_core 0.9.10", ] [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-encoding-macro" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -4757,9 +4739,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" dependencies = [ "data-encoding", "syn 1.0.109", @@ -4776,9 +4758,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -4804,7 +4786,7 @@ version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" dependencies = [ - "asn1-rs 0.6.1", + "asn1-rs 0.6.2", "displaydoc", "nom", "num-bigint", @@ -4827,7 +4809,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -4838,9 +4820,9 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -4849,22 +4831,22 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "rustc_version 0.4.0", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -4906,7 +4888,7 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -4953,20 +4935,20 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "dissimilar" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" [[package]] name = "dleq_vrf" @@ -4975,7 +4957,7 @@ source = "git+https://github.com/w3f/ring-vrf?rev=0fef826#0fef8266d851932ad25d6b dependencies = [ "ark-ec", "ark-ff 0.4.2", - "ark-scale 0.0.12", + "ark-scale", "ark-secret-scalar", "ark-serialize 0.4.2", "ark-std 0.4.0", @@ -4986,11 +4968,13 @@ dependencies = [ [[package]] name = "dlmalloc" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203540e710bfadb90e5e29930baf5d10270cec1f43ab34f46f78b147b2de715a" +checksum = "3264b043b8e977326c1ee9e723da2c1f8d09a99df52cacf00b4dbce5ac54414d" dependencies = [ + "cfg-if", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -5017,12 +5001,12 @@ dependencies = [ "common-path", "derive-syn-parse", "once_cell", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "regex", - "syn 2.0.61", + "syn 2.0.72", "termcolor", - "toml 0.8.8", + "toml 0.8.19", "walkdir", ] @@ -5034,9 +5018,9 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dtoa" @@ -5046,9 +5030,9 @@ checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clonable" @@ -5066,22 +5050,22 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "dyn-clone" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", "digest 0.10.7", @@ -5094,9 +5078,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", "signature", @@ -5113,7 +5097,7 @@ dependencies = [ "rand_core", "serde", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -5125,7 +5109,7 @@ checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ "curve25519-dalek", "ed25519", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "rand_core", "sha2 0.10.8", @@ -5134,9 +5118,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -5154,7 +5138,7 @@ dependencies = [ "rand_core", "sec1", "serdect", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -5198,9 +5182,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -5212,7 +5196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -5224,47 +5208,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "enumflags2" -version = "0.7.7" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.7" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "enumn" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", ] @@ -5281,9 +5265,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -5294,9 +5278,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -5333,11 +5317,12 @@ dependencies = [ [[package]] name = "erased-serde" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" dependencies = [ "serde", + "typeid", ] [[package]] @@ -5352,23 +5337,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -5420,9 +5394,20 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "5.2.0" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -5435,7 +5420,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 5.2.0", + "event-listener 5.3.1", "pin-project-lite", ] @@ -5457,17 +5442,17 @@ dependencies = [ "blake2 0.10.6", "file-guard", "fs-err", - "prettyplease 0.2.12", - "proc-macro2 1.0.82", + "prettyplease 0.2.20", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -5528,11 +5513,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb42427514b063d97ce21d5199f36c0c307d981434a6be32582bc79fe5bd2303" dependencies = [ "expander", - "indexmap 2.2.3", + "indexmap 2.3.0", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -5568,7 +5553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -5586,9 +5571,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "file-guard" @@ -5606,20 +5591,20 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866" dependencies = [ - "env_logger 0.10.1", + "env_logger 0.10.2", "log", ] [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -5686,9 +5671,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -5799,7 +5784,7 @@ dependencies = [ "Inflector", "array-bytes", "chrono", - "clap 4.5.11", + "clap 4.5.13", "comfy-table", "frame-benchmarking", "frame-support", @@ -5862,11 +5847,11 @@ dependencies = [ "frame-support", "parity-scale-codec", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "scale-info", "sp-arithmetic", - "syn 2.0.61", + "syn 2.0.72", "trybuild", ] @@ -5891,7 +5876,7 @@ dependencies = [ name = "frame-election-solution-type-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-support", @@ -5963,7 +5948,7 @@ dependencies = [ name = "frame-omni-bencher" version = "0.1.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "cumulus-primitives-proof-size-hostfunction", "frame-benchmarking-cli", "log", @@ -6056,8 +6041,8 @@ dependencies = [ "macro_magic", "parity-scale-codec", "pretty_assertions", - "proc-macro-warning 1.0.0", - "proc-macro2 1.0.82", + "proc-macro-warning 1.0.2", + "proc-macro2 1.0.86", "quote 1.0.36", "regex", "scale-info", @@ -6067,7 +6052,7 @@ dependencies = [ "sp-metadata-ir", "sp-runtime", "static_assertions", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -6076,18 +6061,18 @@ version = "10.0.0" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "frame-support-procedural-tools-derive" version = "11.0.0" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -6210,9 +6195,12 @@ dependencies = [ [[package]] name = "fs-err" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] [[package]] name = "fs2" @@ -6230,7 +6218,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -6326,7 +6314,10 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ + "fastrand 2.1.0", "futures-core", + "futures-io", + "parking", "pin-project-lite", ] @@ -6336,9 +6327,9 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -6348,7 +6339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" dependencies = [ "futures-io", - "rustls 0.21.7", + "rustls 0.21.12", ] [[package]] @@ -6441,9 +6432,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -6462,11 +6453,11 @@ dependencies = [ [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", "polyval", ] @@ -6483,9 +6474,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator 0.3.0", "stable_deref_trait", @@ -6556,9 +6547,9 @@ dependencies = [ [[package]] name = "governor" -version = "0.6.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "821239e5672ff23e2a7060901fa622950bbd80b649cdaadd78d1c1767ed14eb4" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" dependencies = [ "cfg-if", "dashmap", @@ -6567,9 +6558,11 @@ dependencies = [ "no-std-compat", "nonzero_ext", "parking_lot 0.12.3", + "portable-atomic", "quanta", "rand", "smallvec", + "spinning_top", ] [[package]] @@ -6580,7 +6573,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -6594,8 +6587,8 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.9", - "indexmap 2.2.3", + "http 0.2.12", + "indexmap 2.3.0", "slab", "tokio", "tokio-util", @@ -6614,7 +6607,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.2.3", + "indexmap 2.3.0", "slab", "tokio", "tokio-util", @@ -6623,15 +6616,19 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "handlebars" -version = "5.1.0" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab283476b99e66691dee3f1640fea91487a8d81f50fb5ecc75538f8f8879a1e4" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" dependencies = [ "log", "pest", @@ -6676,9 +6673,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", @@ -6691,7 +6688,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -6726,9 +6723,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -6738,9 +6741,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-conservative" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" [[package]] name = "hex-literal" @@ -6750,9 +6753,9 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac 0.12.1", ] @@ -6787,15 +6790,24 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "honggfuzz" -version = "0.5.55" +version = "0.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848e9c511092e0daa0a35a63e8e6e475a3e8f870741448b9f6028d69b142f18e" +checksum = "7c76b6234c13c9ea73946d1379d33186151148e0da231506b964b44f3d023505" dependencies = [ "arbitrary", "lazy_static", - "memmap2 0.5.10", + "memmap2 0.9.4", "rustc_version 0.4.0", ] @@ -6812,9 +6824,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -6834,20 +6846,20 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.9", + "http 0.2.12", "pin-project-lite", ] [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http 1.1.0", @@ -6862,15 +6874,15 @@ dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -6886,17 +6898,17 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.29" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2 0.3.26", - "http 0.2.9", - "http-body 0.4.5", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -6910,16 +6922,16 @@ dependencies = [ [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", "futures-util", "h2 0.4.5", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -6936,10 +6948,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http 0.2.9", - "hyper 0.14.29", + "http 0.2.12", + "hyper 0.14.30", "log", - "rustls 0.21.7", + "rustls 0.21.12", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", @@ -6953,10 +6965,10 @@ checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.3.1", + "hyper 1.4.1", "hyper-util", "log", - "rustls 0.23.10", + "rustls 0.23.12", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -6965,16 +6977,16 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", + "http-body 1.0.1", + "hyper 1.4.1", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -6985,16 +6997,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows 0.48.0", + "windows-core 0.52.0", ] [[package]] @@ -7076,8 +7088,8 @@ dependencies = [ "attohttpc", "bytes", "futures", - "http 0.2.9", - "hyper 0.14.29", + "http 0.2.12", + "hyper 0.14.30", "log", "rand", "tokio", @@ -7129,27 +7141,27 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "include_dir" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" dependencies = [ "include_dir_macros", ] [[package]] name = "include_dir_macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", ] @@ -7172,12 +7184,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -7188,9 +7200,9 @@ checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -7210,9 +7222,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -7238,7 +7250,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -7263,19 +7275,19 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.2", - "rustix 0.38.21", - "windows-sys 0.48.0", + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -7287,13 +7299,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "isahc" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" dependencies = [ - "async-channel", + "async-channel 1.9.0", "castaway", "crossbeam-utils", "curl", @@ -7301,7 +7319,7 @@ dependencies = [ "encoding_rs", "event-listener 2.5.3", "futures-lite 1.13.0", - "http 0.2.9", + "http 0.2.12", "log", "mime", "once_cell", @@ -7332,11 +7350,20 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni" @@ -7360,18 +7387,18 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -7420,7 +7447,7 @@ dependencies = [ "http 1.1.0", "jsonrpsee-core", "pin-project", - "rustls 0.23.10", + "rustls 0.23.12", "rustls-pki-types", "rustls-platform-verifier", "soketto 0.8.0", @@ -7445,7 +7472,7 @@ dependencies = [ "futures-timer", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", "jsonrpsee-types", "parking_lot 0.12.3", @@ -7468,13 +7495,13 @@ checksum = "2d90064e04fb9d7282b1c71044ea94d0bbc6eff5621c66f1a0bce9e9de7cf3ac" dependencies = [ "async-trait", "base64 0.22.1", - "http-body 1.0.0", - "hyper 1.3.1", + "http-body 1.0.1", + "hyper 1.4.1", "hyper-rustls 0.27.2", "hyper-util", "jsonrpsee-core", "jsonrpsee-types", - "rustls 0.23.10", + "rustls 0.23.12", "rustls-platform-verifier", "serde", "serde_json", @@ -7493,9 +7520,9 @@ checksum = "7895f186d5921065d96e16bd795e5ca89ac8356ec423fafc6e3d7cf8ec11aee4" dependencies = [ "heck 0.5.0", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -7507,9 +7534,9 @@ dependencies = [ "anyhow", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.1", "hyper-util", "jsonrpsee-core", "jsonrpsee-types", @@ -7568,9 +7595,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -7662,9 +7689,9 @@ dependencies = [ [[package]] name = "landlock" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1530c5b973eeed4ac216af7e24baf5737645a6272e361f1fb95710678b67d9cc" +checksum = "9baa9eeb6e315942429397e617a190f4fdc696ef1ee0342939d641029cbb4ea7" dependencies = [ "enumflags2", "libc", @@ -7673,9 +7700,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -7728,12 +7755,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "winapi", + "windows-targets 0.52.6", ] [[package]] @@ -7744,9 +7771,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libnghttp2-sys" -version = "0.1.9+1.58.0" +version = "0.1.10+1.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57e858af2798e167e709b9d969325b6d8e9d50232fcbc494d7d54f976854a64" +checksum = "959c25552127d2e1fa72f0e52548ec04fc386e827ba71a7bd01db46a447dc135" dependencies = [ "cc", "libc", @@ -7872,7 +7899,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "log", - "lru 0.12.3", + "lru 0.12.4", "quick-protobuf", "quick-protobuf-codec", "smallvec", @@ -7882,9 +7909,9 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999ec70441b2fb35355076726a6bc466c932e9bdc66f6a11c6c0aa17c7ab9be0" +checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" dependencies = [ "bs58 0.5.1", "ed25519-dalek", @@ -8026,7 +8053,7 @@ dependencies = [ "quinn 0.10.2", "rand", "ring 0.16.20", - "rustls 0.21.7", + "rustls 0.21.12", "socket2 0.5.7", "thiserror", "tokio", @@ -8081,9 +8108,9 @@ checksum = "c4d5ec2a3df00c7836d7696c136274c9c59705bac69133253696a6c932cd1d74" dependencies = [ "heck 0.4.1", "proc-macro-warning 0.4.2", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -8115,8 +8142,8 @@ dependencies = [ "libp2p-identity", "rcgen", "ring 0.16.20", - "rustls 0.21.7", - "rustls-webpki 0.101.4", + "rustls 0.21.12", + "rustls-webpki 0.101.7", "thiserror", "x509-parser 0.15.1", "yasna", @@ -8170,7 +8197,7 @@ dependencies = [ "soketto 0.8.0", "thiserror", "url", - "webpki-roots 0.25.2", + "webpki-roots 0.25.4", ] [[package]] @@ -8186,6 +8213,16 @@ dependencies = [ "yamux", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + [[package]] name = "librocksdb-sys" version = "0.11.0+8.1.1" @@ -8228,7 +8265,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ "crunchy", "digest 0.9.0", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -8251,9 +8288,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -8287,9 +8324,9 @@ dependencies = [ [[package]] name = "linregress" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de0b5f52a9f84544d268f5fabb71b38962d6aa3c6600b8bcd27d44ccf9c9c45" +checksum = "4de04dcecc58d366391f9920245b85ffa684558a5ef6e7736e754347c3aea9c2" dependencies = [ "nalgebra", ] @@ -8308,9 +8345,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lioness" @@ -8356,7 +8393,7 @@ dependencies = [ "futures", "futures-timer", "hex-literal", - "indexmap 2.2.3", + "indexmap 2.3.0", "libc", "mockall 0.12.1", "multiaddr 0.17.1", @@ -8399,9 +8436,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -8428,17 +8465,17 @@ dependencies = [ [[package]] name = "lru" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" [[package]] name = "lru" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -8452,9 +8489,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.24.0" +version = "1.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" +checksum = "958b4caa893816eea05507c20cfe47574a43d9a697138a7872990bba8a0ece68" dependencies = [ "libc", "lz4-sys", @@ -8462,9 +8499,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.4" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868" dependencies = [ "cc", "libc", @@ -8479,15 +8516,6 @@ dependencies = [ "libc", ] -[[package]] -name = "mach2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" -dependencies = [ - "libc", -] - [[package]] name = "macro_magic" version = "0.5.1" @@ -8497,7 +8525,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -8509,9 +8537,9 @@ dependencies = [ "const-random", "derive-syn-parse", "macro_magic_core_macros", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -8520,9 +8548,9 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -8533,7 +8561,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -8548,15 +8576,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -[[package]] -name = "matchers" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" -dependencies = [ - "regex-automata 0.1.10", -] - [[package]] name = "matchers" version = "0.1.0" @@ -8574,9 +8593,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matrixmultiply" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" dependencies = [ "autocfg", "rawpointer", @@ -8590,11 +8609,11 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memfd" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.37.23", + "rustix 0.38.34", ] [[package]] @@ -8608,9 +8627,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" dependencies = [ "libc", ] @@ -8624,15 +8643,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "memory-db" version = "0.32.0" @@ -8725,7 +8735,7 @@ dependencies = [ name = "minimal-template-node" version = "0.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "docify", "futures", "futures-timer", @@ -8777,22 +8787,23 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -8815,7 +8826,7 @@ dependencies = [ "rand", "rand_chacha", "rand_distr", - "subtle 2.5.0", + "subtle 2.6.1", "thiserror", "zeroize", ] @@ -8884,7 +8895,7 @@ dependencies = [ "fragile", "lazy_static", "mockall_derive 0.12.1", - "predicates 3.0.3", + "predicates 3.1.2", "predicates-tree", ] @@ -8895,7 +8906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -8907,9 +8918,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" dependencies = [ "cfg-if", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -9013,13 +9024,13 @@ dependencies = [ [[package]] name = "multihash-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro-error", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", "synstructure 0.12.6", @@ -9031,6 +9042,12 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + [[package]] name = "multistream-select" version = "0.13.0" @@ -9047,9 +9064,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.3" +version = "0.32.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" +checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" dependencies = [ "approx", "matrixmultiply", @@ -9063,13 +9080,13 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -9143,9 +9160,9 @@ dependencies = [ [[package]] name = "netlink-sys" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" +checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ "bytes", "futures", @@ -9156,9 +9173,9 @@ dependencies = [ [[package]] name = "network-interface" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae72fd9dbd7f55dda80c00d66acc3b2130436fcba9ea89118fc508eaae48dfb0" +checksum = "a4a43439bf756eed340bdf8feba761e2d50c7d47175d87545cd5cbe4a137c4d1" dependencies = [ "cc", "libc", @@ -9179,14 +9196,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "static_assertions", ] [[package]] @@ -9218,7 +9234,7 @@ name = "node-bench" version = "0.9.0-dev" dependencies = [ "array-bytes", - "clap 4.5.11", + "clap 4.5.13", "derive_more", "fs_extra", "futures", @@ -9296,7 +9312,7 @@ dependencies = [ name = "node-runtime-generate-bags" version = "3.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "generate-bags", "kitchensink-runtime", ] @@ -9305,7 +9321,7 @@ dependencies = [ name = "node-template-release" version = "3.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "flate2", "fs_extra", "glob", @@ -9415,9 +9431,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ "num-bigint", "num-complex", @@ -9429,20 +9445,19 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -9459,9 +9474,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -9476,19 +9491,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -9497,11 +9511,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -9509,9 +9522,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -9523,7 +9536,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.9", "libc", ] @@ -9578,7 +9591,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" dependencies = [ - "asn1-rs 0.6.1", + "asn1-rs 0.6.2", ] [[package]] @@ -9589,9 +9602,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "opaque-debug" @@ -9601,15 +9614,15 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -9626,9 +9639,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -9639,18 +9652,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.3+3.2.1" +version = "300.3.1+3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -9689,11 +9702,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7b1d40dd8f367db3c65bec8d3dd47d4a604ee8874480738f93191bddab4e0e0" dependencies = [ "expander", - "indexmap 2.2.3", + "indexmap 2.3.0", "itertools 0.11.0", "petgraph", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -9709,9 +9722,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.1" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "overload" @@ -10352,7 +10365,7 @@ dependencies = [ "polkavm-linker", "sp-runtime", "tempfile", - "toml 0.8.8", + "toml 0.8.19", "twox-hash", ] @@ -10397,9 +10410,9 @@ dependencies = [ name = "pallet-contracts-proc-macro" version = "18.0.0" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -10468,8 +10481,10 @@ dependencies = [ "frame-election-provider-support", "frame-support", "frame-system", + "pallet-bags-list", "pallet-balances", "pallet-nomination-pools", + "pallet-stake-tracker", "pallet-staking", "pallet-staking-reward-curve", "pallet-timestamp", @@ -10530,6 +10545,7 @@ dependencies = [ "pallet-election-provider-multi-phase", "pallet-nomination-pools", "pallet-session", + "pallet-stake-tracker", "pallet-staking", "pallet-timestamp", "parity-scale-codec", @@ -10565,7 +10581,7 @@ dependencies = [ "sp-npos-elections", "sp-runtime", "sp-tracing 16.0.0", - "strum 0.26.2", + "strum 0.26.3", ] [[package]] @@ -11163,6 +11179,7 @@ dependencies = [ "pallet-balances", "pallet-delegated-staking", "pallet-nomination-pools", + "pallet-stake-tracker", "pallet-staking", "pallet-staking-reward-curve", "pallet-timestamp", @@ -11187,6 +11204,7 @@ dependencies = [ "pallet-bags-list", "pallet-balances", "pallet-nomination-pools", + "pallet-stake-tracker", "pallet-staking", "pallet-staking-reward-curve", "pallet-timestamp", @@ -11597,6 +11615,26 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "pallet-stake-tracker" +version = "0.1.0" +dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "pallet-bags-list", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-npos-elections", + "sp-runtime", + "sp-staking", + "sp-tracing 16.0.0", +] + [[package]] name = "pallet-staking" version = "28.0.0" @@ -11609,7 +11647,9 @@ dependencies = [ "pallet-authorship", "pallet-bags-list", "pallet-balances", + "pallet-migrations", "pallet-session", + "pallet-stake-tracker", "pallet-staking-reward-curve", "pallet-timestamp", "parity-scale-codec", @@ -11631,10 +11671,10 @@ name = "pallet-staking-reward-curve" version = "11.0.0" dependencies = [ "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "sp-runtime", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -12026,7 +12066,7 @@ dependencies = [ name = "parachain-template-node" version = "0.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "color-print", "cumulus-client-cli", "cumulus-client-collator", @@ -12236,9 +12276,9 @@ checksum = "16b56e3a2420138bdb970f84dfb9c774aea80fa0e7371549eedec0d80c209c67" [[package]] name = "parity-db" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e9ab494af9e6e813c72170f0d3c1de1500990d62c97cc05cc7576f91aa402f" +checksum = "592a28a24b09c9dc20ac8afaa6839abc417c720afe42c12e1e4a9d6aa2508d2e" dependencies = [ "blake2 0.10.6", "crc32fast", @@ -12252,6 +12292,7 @@ dependencies = [ "rand", "siphasher", "snap", + "winapi", ] [[package]] @@ -12276,7 +12317,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -12305,7 +12346,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "syn 1.0.109", "synstructure 0.12.6", ] @@ -12318,9 +12359,9 @@ checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" [[package]] name = "parking" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" @@ -12340,7 +12381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", + "parking_lot_core 0.9.10", ] [[package]] @@ -12359,15 +12400,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -12384,7 +12425,7 @@ checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -12696,19 +12737,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.2" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -12716,22 +12758,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -12740,32 +12782,32 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.3", + "indexmap 2.3.0", ] [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -12780,6 +12822,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" +dependencies = [ + "atomic-waker", + "fastrand 2.1.0", + "futures-io", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -12792,21 +12845,21 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" -version = "3.0.2" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "0e4c7666f2019727f9e8e14bf14456e99c707d780922869f1ba473eee101fa49" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ "num-traits", "plotters-backend", @@ -12817,15 +12870,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ "plotters-backend", ] @@ -12985,7 +13038,7 @@ name = "polkadot-cli" version = "7.0.0" dependencies = [ "cfg-if", - "clap 4.5.11", + "clap 4.5.13", "frame-benchmarking-cli", "futures", "log", @@ -13054,13 +13107,13 @@ name = "polkadot-dispute-distribution" version = "7.0.0" dependencies = [ "assert_matches", - "async-channel", + "async-channel 1.9.0", "async-trait", "derive_more", "fatality", "futures", "futures-timer", - "indexmap 2.2.3", + "indexmap 2.3.0", "lazy_static", "parity-scale-codec", "polkadot-erasure-coding", @@ -13637,7 +13690,7 @@ dependencies = [ "futures", "futures-timer", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.1", "hyper-util", "log", "parity-scale-codec", @@ -13660,7 +13713,7 @@ dependencies = [ name = "polkadot-node-network-protocol" version = "7.0.0" dependencies = [ - "async-channel", + "async-channel 1.9.0", "async-trait", "bitvec", "derive_more", @@ -13677,7 +13730,7 @@ dependencies = [ "sc-network", "sc-network-types", "sp-runtime", - "strum 0.26.2", + "strum 0.26.3", "thiserror", "tracing-gum", ] @@ -13843,7 +13896,7 @@ dependencies = [ "async-trait", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", - "clap 4.5.11", + "clap 4.5.13", "collectives-westend-runtime", "color-print", "contracts-rococo-runtime", @@ -14307,6 +14360,7 @@ dependencies = [ "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", + "pallet-stake-tracker", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", @@ -14785,12 +14839,12 @@ version = "7.0.0" dependencies = [ "arrayvec 0.7.4", "assert_matches", - "async-channel", + "async-channel 1.9.0", "bitvec", "fatality", "futures", "futures-timer", - "indexmap 2.2.3", + "indexmap 2.3.0", "parity-scale-codec", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -14832,7 +14886,7 @@ dependencies = [ "async-trait", "bincode", "bitvec", - "clap 4.5.11", + "clap 4.5.13", "clap-num", "color-eyre", "colored", @@ -14889,7 +14943,7 @@ dependencies = [ "sp-runtime", "sp-timestamp", "sp-tracing 16.0.0", - "strum 0.26.2", + "strum 0.26.3", "substrate-prometheus-endpoint", "tokio", "tracing-gum", @@ -14930,7 +14984,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.5.11", + "clap 4.5.13", "color-eyre", "futures", "futures-timer", @@ -15072,7 +15126,7 @@ dependencies = [ name = "polkadot-voter-bags" version = "7.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "generate-bags", "sp-io", "westend-runtime", @@ -15125,9 +15179,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c" dependencies = [ "polkavm-common", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -15137,7 +15191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" dependencies = [ "polkavm-derive-impl", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -15146,8 +15200,8 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7be503e60cf56c0eb785f90aaba4b583b36bff00e93997d93fef97f9553c39" dependencies = [ - "gimli 0.28.0", - "hashbrown 0.14.3", + "gimli 0.28.1", + "hashbrown 0.14.5", "log", "object 0.32.2", "polkavm-common", @@ -15179,14 +15233,15 @@ dependencies = [ [[package]] name = "polling" -version = "3.4.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.21", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] @@ -15198,27 +15253,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", "universal-hash", ] [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.4.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "portpicker" @@ -15246,7 +15301,7 @@ dependencies = [ "findshlibs", "libc", "log", - "nix 0.26.2", + "nix 0.26.4", "once_cell", "parking_lot 0.12.3", "smallvec", @@ -15257,9 +15312,12 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "predicates" @@ -15277,27 +15335,26 @@ dependencies = [ [[package]] name = "predicates" -version = "3.0.3" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9" +checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" dependencies = [ "anstyle", "difflib", - "itertools 0.10.5", "predicates-core", ] [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" dependencies = [ "predicates-core", "termtree", @@ -15319,25 +15376,25 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "syn 1.0.109", ] [[package]] name = "prettyplease" -version = "0.2.12" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ - "proc-macro2 1.0.82", - "syn 2.0.61", + "proc-macro2 1.0.86", + "syn 2.0.72", ] [[package]] name = "primitive-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", @@ -15366,12 +15423,12 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "thiserror", + "toml 0.5.11", ] [[package]] @@ -15380,7 +15437,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -15390,7 +15447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", "version_check", @@ -15402,37 +15459,31 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro-warning" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "proc-macro-warning" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b698b0b09d40e9b7c1a47b132d66a8b54bcd20583d9b6d06e4535e383b4405c" +checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -15446,9 +15497,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -15465,7 +15516,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.21", + "rustix 0.38.34", ] [[package]] @@ -15481,9 +15532,9 @@ dependencies = [ [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", @@ -15511,28 +15562,28 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "prometheus-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2aa5feb83bf4b2c8919eaf563f51dbab41183de73ba2353c0e03cd7b6bd892" +checksum = "811031bea65e5a401fb2e1f37d802cca6601e204ac463809a3189352d13b78a5" dependencies = [ "chrono", - "itertools 0.10.5", + "itertools 0.12.1", "once_cell", "regex", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", @@ -15542,7 +15593,7 @@ dependencies = [ "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", "rusty-fork", "tempfile", "unarray", @@ -15579,7 +15630,7 @@ dependencies = [ "itertools 0.10.5", "lazy_static", "log", - "multimap", + "multimap 0.8.3", "petgraph", "prettyplease 0.1.25", "prost 0.11.9", @@ -15592,22 +15643,22 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.11.0", + "itertools 0.12.1", "log", - "multimap", + "multimap 0.10.0", "once_cell", "petgraph", - "prettyplease 0.2.12", + "prettyplease 0.2.20", "prost 0.12.6", - "prost-types 0.12.4", + "prost-types 0.12.6", "regex", - "syn 2.0.61", + "syn 2.0.72", "tempfile", ] @@ -15619,7 +15670,7 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools 0.10.5", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -15631,10 +15682,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", - "proc-macro2 1.0.82", + "itertools 0.12.1", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -15648,9 +15699,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ "prost 0.12.6", ] @@ -15696,13 +15747,12 @@ dependencies = [ [[package]] name = "quanta" -version = "0.11.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" dependencies = [ "crossbeam-utils", "libc", - "mach2", "once_cell", "raw-cpuid", "wasi", @@ -15790,7 +15840,7 @@ dependencies = [ "quinn-proto 0.10.6", "quinn-udp 0.4.1", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.12", "thiserror", "tokio", "tracing", @@ -15824,7 +15874,7 @@ dependencies = [ "rand", "ring 0.16.20", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.12", "slab", "thiserror", "tinyvec", @@ -15839,7 +15889,7 @@ checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" dependencies = [ "libc", "quinn-proto 0.9.6", - "socket2 0.4.9", + "socket2 0.4.10", "tracing", "windows-sys 0.42.0", ] @@ -15872,7 +15922,7 @@ version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", ] [[package]] @@ -15941,11 +15991,11 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "10.7.0" +version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] @@ -16017,30 +16067,30 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] @@ -16071,9 +16121,9 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -16103,14 +16153,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -16124,19 +16174,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" - -[[package]] -name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] @@ -16147,15 +16191,15 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "relative-path" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "relay-substrate-client" @@ -16227,7 +16271,7 @@ dependencies = [ name = "remote-ext-tests-bags-list" version = "1.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "frame-system", "log", "pallet-bags-list-remote-tests", @@ -16240,19 +16284,19 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", "h2 0.3.26", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.29", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", "hyper-rustls 0.24.2", "ipnet", "js-sys", @@ -16261,11 +16305,13 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.7", - "rustls-pemfile 1.0.3", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", "tokio-rustls 0.24.1", "tower-service", @@ -16273,7 +16319,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.2", + "webpki-roots 0.25.4", "winreg", ] @@ -16294,7 +16340,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac 0.12.1", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -16331,16 +16377,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -16592,13 +16639,13 @@ checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" [[package]] name = "rpassword" -version = "7.2.0" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", "rtoolbox", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -16621,12 +16668,12 @@ checksum = "d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605" dependencies = [ "cfg-if", "glob", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "regex", "relative-path", "rustc_version 0.4.0", - "syn 2.0.61", + "syn 2.0.72", "unicode-ident", ] @@ -16647,19 +16694,19 @@ dependencies = [ [[package]] name = "rtoolbox" -version = "0.0.1" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "ruint" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -16681,15 +16728,15 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -16727,7 +16774,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver 1.0.23", ] [[package]] @@ -16741,9 +16788,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.15" +version = "0.36.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" +checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed" dependencies = [ "bitflags 1.3.2", "errno", @@ -16755,9 +16802,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", "errno", @@ -16769,15 +16816,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", ] [[package]] @@ -16793,28 +16840,28 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.16.20", - "rustls-webpki 0.101.4", + "ring 0.17.8", + "rustls-webpki 0.101.7", "sct", ] [[package]] name = "rustls" -version = "0.23.10" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "log", "once_cell", - "ring 0.17.7", + "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.4", - "subtle 2.5.0", + "rustls-webpki 0.102.6", + "subtle 2.6.1", "zeroize", ] @@ -16825,19 +16872,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.3", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" dependencies = [ "openssl-probe", - "rustls-pemfile 2.0.0", + "rustls-pemfile 2.1.3", "rustls-pki-types", "schannel", "security-framework", @@ -16845,20 +16892,20 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", ] [[package]] name = "rustls-pemfile" -version = "2.0.0" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ - "base64 0.21.2", + "base64 0.22.1", "rustls-pki-types", ] @@ -16870,19 +16917,19 @@ checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-platform-verifier" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5f0d26fa1ce3c790f9590868f0109289a044acb954525f933e2aa3b871c157d" +checksum = "93bda3f493b9abe5b93b3e7e3ecde0df292f2bd28c0296b90586ee0055ff5123" dependencies = [ "core-foundation", "core-foundation-sys", "jni", "log", "once_cell", - "rustls 0.23.10", - "rustls-native-certs 0.7.0", + "rustls 0.23.12", + "rustls-native-certs 0.7.1", "rustls-platform-verifier-android", - "rustls-webpki 0.102.4", + "rustls-webpki 0.102.6", "security-framework", "security-framework-sys", "webpki-roots 0.26.3", @@ -16891,36 +16938,36 @@ dependencies = [ [[package]] name = "rustls-platform-verifier-android" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e217e7fdc8466b5b35d30f8c0a30febd29173df4a3a0c2115d306b9c4117ad" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.101.4" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -16958,9 +17005,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe-mix" @@ -16973,9 +17020,9 @@ dependencies = [ [[package]] name = "safe_arch" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" dependencies = [ "bytemuck", ] @@ -17013,7 +17060,7 @@ dependencies = [ "multihash 0.19.1", "parity-scale-codec", "prost 0.12.6", - "prost-build 0.12.4", + "prost-build 0.12.6", "quickcheck", "rand", "sc-client-api", @@ -17077,10 +17124,10 @@ name = "sc-chain-spec" version = "28.0.0" dependencies = [ "array-bytes", - "clap 4.5.11", + "clap 4.5.13", "docify", "log", - "memmap2 0.9.3", + "memmap2 0.9.4", "parity-scale-codec", "regex", "sc-chain-spec-derive", @@ -17109,9 +17156,9 @@ name = "sc-chain-spec-derive" version = "11.0.0" dependencies = [ "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -17120,7 +17167,7 @@ version = "0.36.0" dependencies = [ "array-bytes", "chrono", - "clap 4.5.11", + "clap 4.5.13", "fdlimit", "futures", "futures-timer", @@ -17356,7 +17403,7 @@ name = "sc-consensus-beefy" version = "13.0.0" dependencies = [ "array-bytes", - "async-channel", + "async-channel 1.9.0", "async-trait", "fnv", "futures", @@ -17623,7 +17670,7 @@ dependencies = [ "substrate-test-runtime", "tempfile", "tracing", - "tracing-subscriber 0.3.18", + "tracing-subscriber", "wat", ] @@ -17661,7 +17708,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "paste", - "rustix 0.36.15", + "rustix 0.36.17", "sc-allocator", "sc-executor-common", "sc-runtime-test", @@ -17737,7 +17784,7 @@ version = "0.34.0" dependencies = [ "array-bytes", "assert_matches", - "async-channel", + "async-channel 1.9.0", "async-trait", "asynchronous-codec", "bytes", @@ -17759,7 +17806,7 @@ dependencies = [ "partial_sort", "pin-project", "prost 0.12.6", - "prost-build 0.12.4", + "prost-build 0.12.6", "rand", "sc-block-builder", "sc-client-api", @@ -17804,7 +17851,7 @@ dependencies = [ "futures", "libp2p-identity", "parity-scale-codec", - "prost-build 0.12.4", + "prost-build 0.12.6", "sc-consensus", "sc-network-types", "sp-consensus", @@ -17841,12 +17888,12 @@ name = "sc-network-light" version = "0.33.0" dependencies = [ "array-bytes", - "async-channel", + "async-channel 1.9.0", "futures", "log", "parity-scale-codec", "prost 0.12.6", - "prost-build 0.12.4", + "prost-build 0.12.6", "sc-client-api", "sc-network", "sc-network-types", @@ -17861,7 +17908,7 @@ name = "sc-network-statement" version = "0.16.0" dependencies = [ "array-bytes", - "async-channel", + "async-channel 1.9.0", "futures", "log", "parity-scale-codec", @@ -17880,7 +17927,7 @@ name = "sc-network-sync" version = "0.33.0" dependencies = [ "array-bytes", - "async-channel", + "async-channel 1.9.0", "async-trait", "fork-tree", "futures", @@ -17890,7 +17937,7 @@ dependencies = [ "mockall 0.11.4", "parity-scale-codec", "prost 0.12.6", - "prost-build 0.12.4", + "prost-build 0.12.6", "quickcheck", "sc-block-builder", "sc-client-api", @@ -17992,7 +18039,7 @@ dependencies = [ "fnv", "futures", "futures-timer", - "hyper 0.14.29", + "hyper 0.14.30", "hyper-rustls 0.24.2", "lazy_static", "log", @@ -18071,7 +18118,7 @@ dependencies = [ "sp-version", "substrate-test-runtime-client", "tokio", - "tracing-subscriber 0.3.18", + "tracing-subscriber", ] [[package]] @@ -18102,7 +18149,7 @@ dependencies = [ "governor", "http 1.1.0", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.1", "ip_network", "jsonrpsee", "log", @@ -18238,7 +18285,7 @@ name = "sc-service-test" version = "2.0.0" dependencies = [ "array-bytes", - "async-channel", + "async-channel 1.9.0", "fdlimit", "futures", "log", @@ -18303,7 +18350,7 @@ dependencies = [ name = "sc-storage-monitor" version = "0.16.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "fs4", "log", "sp-core", @@ -18395,8 +18442,8 @@ dependencies = [ "sp-tracing 16.0.0", "thiserror", "tracing", - "tracing-log 0.2.0", - "tracing-subscriber 0.3.18", + "tracing-log", + "tracing-subscriber", ] [[package]] @@ -18404,9 +18451,9 @@ name = "sc-tracing-proc-macro" version = "11.0.0" dependencies = [ "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -18463,7 +18510,7 @@ dependencies = [ name = "sc-utils" version = "14.0.0" dependencies = [ - "async-channel", + "async-channel 1.9.0", "futures", "futures-timer", "lazy_static", @@ -18518,7 +18565,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -18531,18 +18578,18 @@ checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "schemars" -version = "0.8.13" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "schemars_derive", @@ -18552,21 +18599,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.13" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "schnellru" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" dependencies = [ "ahash 0.8.11", "cfg-if", @@ -18604,7 +18651,7 @@ dependencies = [ "rand_core", "serde_bytes", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -18628,12 +18675,12 @@ checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -18662,7 +18709,7 @@ dependencies = [ "generic-array 0.14.7", "pkcs8", "serdect", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -18704,9 +18751,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", "core-foundation", @@ -18718,9 +18765,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -18789,9 +18836,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -18843,9 +18890,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] @@ -18856,20 +18903,20 @@ version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -18883,11 +18930,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.3.0", "itoa", "memchr", "ryu", @@ -18896,9 +18943,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -18921,7 +18968,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.3.0", "itoa", "ryu", "serde", @@ -18958,9 +19005,9 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -18973,7 +19020,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", ] [[package]] @@ -19001,9 +19048,9 @@ dependencies = [ [[package]] name = "sha1-asm" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba6947745e7f86be3b8af00b7355857085dbdf8901393c89514510eb61f4e21" +checksum = "286acebaf8b67c1130aedffad26f594eff0c1292389158135327d2e23aed582b" dependencies = [ "cc", ] @@ -19018,7 +19065,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", ] [[package]] @@ -19044,9 +19091,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -19093,30 +19140,20 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core", @@ -19188,9 +19225,9 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] @@ -19201,7 +19238,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" dependencies = [ - "async-channel", + "async-channel 1.9.0", "futures-core", "futures-io", ] @@ -19218,7 +19255,7 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" dependencies = [ - "async-channel", + "async-channel 1.9.0", "async-executor", "async-fs", "async-io 1.13.0", @@ -19229,15 +19266,6 @@ dependencies = [ "futures-lite 1.13.0", ] -[[package]] -name = "smol_str" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" -dependencies = [ - "serde", -] - [[package]] name = "smoldot" version = "0.11.0" @@ -19247,7 +19275,7 @@ dependencies = [ "arrayvec 0.7.4", "async-lock 2.8.0", "atomic-take", - "base64 0.21.2", + "base64 0.21.7", "bip39", "blake2-rfc", "bs58 0.5.1", @@ -19260,7 +19288,7 @@ dependencies = [ "fnv", "futures-lite 1.13.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "hmac 0.12.1", "itertools 0.11.0", @@ -19298,9 +19326,9 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "256b5bad1d6b49045e95fe87492ce73d5af81545d8b4d8318a872d2007024c33" dependencies = [ - "async-channel", + "async-channel 1.9.0", "async-lock 2.8.0", - "base64 0.21.2", + "base64 0.21.7", "blake2-rfc", "derive_more", "either", @@ -19309,11 +19337,11 @@ dependencies = [ "futures-channel", "futures-lite 1.13.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "itertools 0.11.0", "log", - "lru 0.11.0", + "lru 0.11.1", "no-std-net", "parking_lot 0.12.3", "pin-project", @@ -19330,9 +19358,9 @@ dependencies = [ [[package]] name = "snap" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "snow" @@ -19345,10 +19373,10 @@ dependencies = [ "chacha20poly1305", "curve25519-dalek", "rand_core", - "ring 0.17.7", + "ring 0.17.8", "rustc_version 0.4.0", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -19673,9 +19701,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -19726,7 +19754,7 @@ dependencies = [ name = "solochain-template-node" version = "0.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "frame-benchmarking-cli", "frame-metadata-hash-extension", "frame-system", @@ -19834,9 +19862,9 @@ dependencies = [ "blake2 0.10.6", "expander", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -19918,7 +19946,7 @@ version = "0.4.2" source = "git+https://github.com/paritytech/arkworks-substrate#caa2eed74beb885dd07c7db5f916f2281dad818f" dependencies = [ "ark-bls12-381-ext", - "sp-crypto-ec-utils 0.4.1", + "sp-crypto-ec-utils 0.10.0 (git+https://github.com/paritytech/polkadot-sdk)", ] [[package]] @@ -19927,7 +19955,7 @@ version = "0.4.2" source = "git+https://github.com/paritytech/arkworks-substrate#caa2eed74beb885dd07c7db5f916f2281dad818f" dependencies = [ "ark-ed-on-bls12-381-bandersnatch-ext", - "sp-crypto-ec-utils 0.4.1", + "sp-crypto-ec-utils 0.10.0 (git+https://github.com/paritytech/polkadot-sdk)", ] [[package]] @@ -20032,7 +20060,7 @@ dependencies = [ "sp-keystore", "sp-mmr-primitives", "sp-runtime", - "strum 0.26.2", + "strum 0.26.3", "w3f-bls", ] @@ -20162,8 +20190,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" -version = "0.4.1" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "0.10.0" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -20176,14 +20203,14 @@ dependencies = [ "ark-ed-on-bls12-377-ext", "ark-ed-on-bls12-381-bandersnatch", "ark-ed-on-bls12-381-bandersnatch-ext", - "ark-scale 0.0.11", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", + "ark-scale", + "sp-runtime-interface 24.0.0", ] [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -20196,8 +20223,8 @@ dependencies = [ "ark-ed-on-bls12-377-ext", "ark-ed-on-bls12-381-bandersnatch", "ark-ed-on-bls12-381-bandersnatch-ext", - "ark-scale 0.0.12", - "sp-runtime-interface 24.0.0", + "ark-scale", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk)", ] [[package]] @@ -20220,7 +20247,7 @@ version = "0.1.0" dependencies = [ "quote 1.0.36", "sp-crypto-hashing", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -20233,41 +20260,40 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "8.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "14.0.0" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "sp-debug-derive" version = "14.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "sp-externalities" -version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "0.25.0" dependencies = [ "environmental", "parity-scale-codec", - "sp-std 8.0.0", - "sp-storage 13.0.0", + "sp-storage 19.0.0", ] [[package]] name = "sp-externalities" version = "0.25.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" dependencies = [ "environmental", "parity-scale-codec", - "sp-storage 19.0.0", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk)", ] [[package]] @@ -20325,7 +20351,7 @@ version = "31.0.0" dependencies = [ "sp-core", "sp-runtime", - "strum 0.26.2", + "strum 0.26.3", ] [[package]] @@ -20402,7 +20428,7 @@ dependencies = [ name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "honggfuzz", "rand", "sp-npos-elections", @@ -20468,24 +20494,6 @@ dependencies = [ "zstd 0.12.4", ] -[[package]] -name = "sp-runtime-interface" -version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" -dependencies = [ - "bytes", - "impl-trait-for-tuples", - "parity-scale-codec", - "primitive-types", - "sp-externalities 0.19.0", - "sp-runtime-interface-proc-macro 11.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", - "sp-tracing 10.0.0", - "sp-wasm-interface 14.0.0", - "static_assertions", -] - [[package]] name = "sp-runtime-interface" version = "24.0.0" @@ -20510,28 +20518,48 @@ dependencies = [ "trybuild", ] +[[package]] +name = "sp-runtime-interface" +version = "24.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "polkavm-derive", + "primitive-types", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-runtime-interface-proc-macro 17.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "static_assertions", +] + [[package]] name = "sp-runtime-interface-proc-macro" -version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "17.0.0" dependencies = [ "Inflector", - "proc-macro-crate 1.3.1", - "proc-macro2 1.0.82", + "expander", + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" dependencies = [ "Inflector", "expander", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -20645,35 +20673,34 @@ dependencies = [ [[package]] name = "sp-std" -version = "8.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "14.0.0" [[package]] name = "sp-std" version = "14.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" [[package]] name = "sp-storage" -version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "19.0.0" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 8.0.0", - "sp-std 8.0.0", + "sp-debug-derive 14.0.0", ] [[package]] name = "sp-storage" version = "19.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 14.0.0", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk)", ] [[package]] @@ -20701,24 +20728,23 @@ dependencies = [ [[package]] name = "sp-tracing" -version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "16.0.0" dependencies = [ "parity-scale-codec", - "sp-std 8.0.0", "tracing", "tracing-core", - "tracing-subscriber 0.2.25", + "tracing-subscriber", ] [[package]] name = "sp-tracing" version = "16.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" dependencies = [ "parity-scale-codec", "tracing", "tracing-core", - "tracing-subscriber 0.3.18", + "tracing-subscriber", ] [[package]] @@ -20790,34 +20816,31 @@ name = "sp-version-proc-macro" version = "13.0.0" dependencies = [ "parity-scale-codec", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "sp-version", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "sp-wasm-interface" -version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +version = "20.0.0" dependencies = [ "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std 8.0.0", "wasmtime", ] [[package]] name = "sp-wasm-interface" version = "20.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#2abd03ef330c8b55e73755a7ef4b43baf1451657" dependencies = [ - "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", - "wasmtime", ] [[package]] @@ -20857,11 +20880,20 @@ dependencies = [ "strum 0.24.1", ] +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -20869,13 +20901,13 @@ dependencies = [ [[package]] name = "ss58-registry" -version = "1.43.0" +version = "1.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6915280e2d0db8911e5032a5c275571af6bdded2916abd691a659be25d3439" +checksum = "4743ce898933fbff7bbf414f497c459a782d496269644b3d650a398ae6a487ba" dependencies = [ "Inflector", "num-format", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "serde", "serde_json", @@ -20900,7 +20932,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f07d54c4d01a1713eb363b55ba51595da15f6f1211435b71466460da022aa140" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -20915,7 +20947,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "staging-chain-spec-builder" version = "1.6.1" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "log", "sc-chain-spec", "serde_json", @@ -20928,7 +20960,7 @@ version = "3.0.0-dev" dependencies = [ "array-bytes", "assert_cmd", - "clap 4.5.11", + "clap 4.5.13", "clap_complete", "criterion", "futures", @@ -20963,7 +20995,7 @@ dependencies = [ name = "staging-node-inspect" version = "0.12.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -21093,7 +21125,7 @@ checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf" dependencies = [ "cfg_aliases", "memchr", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -21125,7 +21157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c6a0d765f5807e98a091107bae0a56ea3799f66a5de47b2c84c94a39c09974e" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] @@ -21143,9 +21175,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "structopt" @@ -21166,7 +21198,7 @@ checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck 0.3.3", "proc-macro-error", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", ] @@ -21182,17 +21214,11 @@ dependencies = [ [[package]] name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - -[[package]] -name = "strum" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ - "strum_macros 0.26.2", + "strum_macros 0.26.4", ] [[package]] @@ -21202,7 +21228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "rustversion", "syn 1.0.109", @@ -21210,35 +21236,22 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2 1.0.82", - "quote 1.0.36", - "rustversion", - "syn 2.0.61", -] - -[[package]] -name = "strum_macros" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", - "proc-macro2 1.0.82", + "heck 0.5.0", + "proc-macro2 1.0.86", "quote 1.0.36", "rustversion", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "subkey" version = "9.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "sc-cli", ] @@ -21322,7 +21335,7 @@ name = "substrate-prometheus-endpoint" version = "0.17.0" dependencies = [ "http-body-util", - "hyper 1.3.1", + "hyper 1.4.1", "hyper-util", "log", "prometheus", @@ -21369,7 +21382,7 @@ dependencies = [ "sp-runtime", "sp-trie", "structopt", - "strum 0.26.2", + "strum 0.26.3", "thiserror", ] @@ -21545,9 +21558,9 @@ dependencies = [ "sp-maybe-compressed-blob", "sp-tracing 16.0.0", "sp-version", - "strum 0.26.2", + "strum 0.26.3", "tempfile", - "toml 0.8.8", + "toml 0.8.19", "walkdir", "wasm-opt", ] @@ -21560,9 +21573,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "subtle-ng" @@ -21572,15 +21585,15 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "sval" -version = "2.6.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" +checksum = "53eb957fbc79a55306d5d25d87daf3627bc3800681491cda0709eef36c748bfe" [[package]] name = "sval_buffer" -version = "2.6.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" +checksum = "96e860aef60e9cbf37888d4953a13445abf523c534640d1f6174d310917c410d" dependencies = [ "sval", "sval_ref", @@ -21588,18 +21601,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.6.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" +checksum = "ea3f2b07929a1127d204ed7cb3905049381708245727680e9139dac317ed556f" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.6.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" +checksum = "c4e188677497de274a1367c4bda15bd2296de4070d91729aac8f0a09c1abf64d" dependencies = [ "itoa", "ryu", @@ -21608,53 +21621,63 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.6.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" +checksum = "32f456c07dae652744781f2245d5e3b78e6a9ebad70790ac11eb15dbdbce5282" dependencies = [ "itoa", "ryu", "sval", ] +[[package]] +name = "sval_nested" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "886feb24709f0476baaebbf9ac10671a50163caa7e439d7a7beb7f6d81d0a6fb" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + [[package]] name = "sval_ref" -version = "2.6.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" +checksum = "be2e7fc517d778f44f8cb64140afa36010999565528d48985f55e64d45f369ce" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.6.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" +checksum = "79bf66549a997ff35cd2114a27ac4b0c2843280f2cfa84b240d169ecaa0add46" dependencies = [ "serde", "sval", - "sval_buffer", - "sval_fmt", + "sval_nested", ] [[package]] name = "symbolic-common" -version = "12.3.0" +version = "12.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167a4ffd7c35c143fd1030aa3c2caf76ba42220bd5a6b5f4781896434723b8c3" +checksum = "16629323a4ec5268ad23a575110a724ad4544aae623451de600c747bf87b36cf" dependencies = [ "debugid", - "memmap2 0.5.10", + "memmap2 0.9.4", "stable_deref_trait", "uuid", ] [[package]] name = "symbolic-demangle" -version = "12.3.0" +version = "12.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e378c50e80686c1c5c205674e1f86a2858bec3d2a7dfdd690331a8a19330f293" +checksum = "48c043a45f08f41187414592b3ceb53fb0687da57209cc77401767fb69d5b596" dependencies = [ "cpp_demangle 0.4.3", "rustc-demangle", @@ -21678,18 +21701,18 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.61" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "unicode-ident", ] @@ -21701,18 +21724,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" dependencies = [ "paste", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "synstructure" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "syn 1.0.109", "unicode-xid 0.2.4", @@ -21724,16 +21753,16 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] name = "sysinfo" -version = "0.30.5" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb4f3438c8f6389c864e61221cbc97e9bca98b4daf39a5beb7bea660f528bb2" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" dependencies = [ "cfg-if", "core-foundation-sys", @@ -21773,9 +21802,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" dependencies = [ "filetime", "libc", @@ -21784,28 +21813,28 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" dependencies = [ "cfg-if", "fastrand 2.1.0", - "redox_syscall 0.4.1", - "rustix 0.38.21", - "windows-sys 0.48.0", + "once_cell", + "rustix 0.38.34", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -21816,7 +21845,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -21832,9 +21861,9 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dffced63c2b5c7be278154d76b479f9f9920ed34e7574201407f0b14e2bbb93" dependencies = [ - "env_logger 0.11.3", + "env_logger 0.11.5", "test-log-macros", - "tracing-subscriber 0.3.18", + "tracing-subscriber", ] [[package]] @@ -21843,9 +21872,9 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -21864,7 +21893,7 @@ dependencies = [ name = "test-parachain-adder-collator" version = "1.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "futures", "futures-timer", "log", @@ -21911,7 +21940,7 @@ dependencies = [ name = "test-parachain-undying-collator" version = "1.0.0" dependencies = [ - "clap 4.5.11", + "clap 4.5.13", "futures", "futures-timer", "log", @@ -21979,48 +22008,48 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-core" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d97345f6437bb2004cd58819d8a9ef8e36cdd7661c2abc4bbde0a7c40d9f497" +checksum = "c001ee18b7e5e3f62cbf58c7fe220119e68d902bb7443179c0c8aef30090e999" dependencies = [ "thiserror-core-impl", ] [[package]] name = "thiserror-core-impl" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ac1c5050e43014d16b2f94d0d2ce79e65ffdd8b38d8048f9c8f6a8a6da62ac" +checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -22031,9 +22060,9 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -22146,9 +22175,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -22161,32 +22190,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -22206,7 +22234,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.12", "tokio", ] @@ -22216,16 +22244,16 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.10", + "rustls 0.23.12", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -22235,9 +22263,9 @@ dependencies = [ [[package]] name = "tokio-test" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b3cbabd3ae862100094ae433e1def582cf86451b4e9bf83aa7ac1d8a7d719" +checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7" dependencies = [ "async-stream", "bytes", @@ -22254,7 +22282,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.7", + "rustls 0.21.12", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", @@ -22286,21 +22314,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -22311,22 +22339,33 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.3.0", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.3.0", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.18", ] [[package]] @@ -22354,7 +22393,7 @@ dependencies = [ "bitflags 2.6.0", "bytes", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", "pin-project-lite", "tower-layer", @@ -22391,9 +22430,9 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -22433,20 +22472,9 @@ dependencies = [ "assert_matches", "expander", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", + "syn 2.0.72", ] [[package]] @@ -22460,38 +22488,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "tracing-serde" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" -dependencies = [ - "ansi_term", - "chrono", - "lazy_static", - "matchers 0.0.1", - "regex", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log 0.1.3", - "tracing-serde", -] - [[package]] name = "tracing-subscriber" version = "0.3.18" @@ -22499,7 +22495,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "chrono", - "matchers 0.1.0", + "matchers", "nu-ansi-term", "once_cell", "parking_lot 0.12.3", @@ -22510,7 +22506,7 @@ dependencies = [ "time", "tracing", "tracing-core", - "tracing-log 0.2.0", + "tracing-log", ] [[package]] @@ -22531,9 +22527,9 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.29.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ed83be775d85ebb0e272914fff6462c39b3ddd6dc67b5c1c41271aad280c69" +checksum = "0c992b4f40c234a074d48a757efeabb1a6be88af84c0c23f7ca158950cb0ae7f" dependencies = [ "hash-db", "log", @@ -22578,7 +22574,7 @@ dependencies = [ "lazy_static", "rand", "smallvec", - "socket2 0.4.9", + "socket2 0.4.10", "thiserror", "tinyvec", "tokio", @@ -22634,24 +22630,23 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.89" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9d3ba662913483d6722303f619e75ea10b7855b0f8e0d72799cf8621bb488f" +checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" dependencies = [ - "basic-toml", "dissimilar", "glob", - "once_cell", "serde", "serde_derive", "serde_json", "termcolor", + "toml 0.8.19", ] [[package]] @@ -22669,11 +22664,11 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 0.2.9", + "http 0.2.12", "httparse", "log", "rand", - "rustls 0.21.7", + "rustls 0.21.12", "sha1", "thiserror", "url", @@ -22698,11 +22693,17 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "typeid" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" + [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -22730,15 +22731,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -22757,9 +22758,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -22780,7 +22781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -22842,15 +22843,15 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.4.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] name = "valuable" @@ -22860,9 +22861,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec26a25bd6fca441cdd0f769fd7f891bae119f996de31f86a5eddccef54c1d" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -22870,9 +22871,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ead5b693d906686203f19a49e88c477fb8c15798b68cf72f60b4b5521b4ad891" +checksum = "ccacf50c5cb077a9abb723c5bcb5e0754c1a433f1e1de89edc328e2760b6328b" dependencies = [ "erased-serde", "serde", @@ -22881,9 +22882,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9d0f4a816370c3a0d7d82d603b62198af17675b12fe5e91de6b47ceb505882" +checksum = "1785bae486022dfb9703915d42287dcb284c1ee37bd1080eeba78cc04721285b" dependencies = [ "sval", "sval_buffer", @@ -22908,9 +22909,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "void" @@ -22920,9 +22921,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "w3f-bls" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7335e4c132c28cc43caef6adb339789e599e39adbe78da0c4d547fad48cbc331" +checksum = "9c5da5fa2c6afa2c9158eaa7cd9aee249765eb32b5fb0c63ad8b9e79336a47ec" dependencies = [ "ark-bls12-377", "ark-bls12-381", @@ -22953,9 +22954,9 @@ dependencies = [ [[package]] name = "waker-fn" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" @@ -22982,6 +22983,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasix" +version = "0.12.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" +dependencies = [ + "wasi", +] + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -23003,17 +23013,17 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -23037,9 +23047,9 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -23052,9 +23062,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-bindgen-test" -version = "0.3.37" +version = "0.3.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" +checksum = "d9bf62a58e0780af3e852044583deee40983e5886da43a271dd772379987667b" dependencies = [ "console_error_panic_hook", "js-sys", @@ -23066,19 +23076,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.37" +version = "0.3.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" +checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", + "syn 2.0.72", ] [[package]] name = "wasm-encoder" -version = "0.31.1" +version = "0.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41763f20eafed1399fff1afb466496d3a959f58241436cfdc17e3f5ca954de16" +checksum = "4fb56df3e06b8e6b77e37d2969a50ba51281029a9aeb3855e76b7f49b6418847" dependencies = [ "leb128", ] @@ -23094,9 +23105,9 @@ dependencies = [ [[package]] name = "wasm-opt" -version = "0.116.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc942673e7684671f0c5708fc18993569d184265fd5223bb51fc8e5b9b6cfd52" +checksum = "2fd87a4c135535ffed86123b6fb0f0a5a0bc89e50416c942c5f0662c645f679c" dependencies = [ "anyhow", "libc", @@ -23190,7 +23201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c128c039340ffd50d4195c3f8ce31aac357f06804cfc494c8b9508d4b30dca4" dependencies = [ "ahash 0.8.11", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "string-interner", ] @@ -23281,12 +23292,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c86437fa68626fe896e5afc69234bb2b5894949083586535f200385adfd71213" dependencies = [ "anyhow", - "base64 0.21.2", + "base64 0.21.7", "bincode", "directories-next", "file-per-thread-logger", "log", - "rustix 0.36.15", + "rustix 0.36.17", "serde", "sha2 0.10.8", "toml 0.5.11", @@ -23382,7 +23393,7 @@ checksum = "6e0554b84c15a27d76281d06838aed94e13a77d7bf604bbbaf548aa20eb93846" dependencies = [ "object 0.30.4", "once_cell", - "rustix 0.36.15", + "rustix 0.36.17", ] [[package]] @@ -23410,10 +23421,10 @@ dependencies = [ "log", "mach", "memfd", - "memoffset 0.8.0", + "memoffset", "paste", "rand", - "rustix 0.36.15", + "rustix 0.36.17", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", @@ -23434,10 +23445,11 @@ dependencies = [ [[package]] name = "wast" -version = "63.0.0" +version = "215.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2560471f60a48b77fccefaf40796fda61c97ce1e790b59dfcec9dc3995c9f63a" +checksum = "1ff1d00d893593249e60720be04a7c1f42f1c4dc3806a2869f4e66ab61eb54cb" dependencies = [ + "bumpalo", "leb128", "memchr", "unicode-width", @@ -23446,18 +23458,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.70" +version = "1.215.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdc306c2c4c2f2bf2ba69e083731d0d2a77437fc6a350a19db139636e7e416c" +checksum = "670bf4d9c8cf76ae242d70ded47c546525b6dafaa6871f9bcb065344bf2b4e3d" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -23469,15 +23481,15 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" @@ -23564,6 +23576,7 @@ dependencies = [ "pallet-session", "pallet-session-benchmarking", "pallet-society", + "pallet-stake-tracker", "pallet-staking", "pallet-staking-runtime-api", "pallet-state-trie-migration", @@ -23650,20 +23663,21 @@ dependencies = [ [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix 0.38.34", ] [[package]] name = "wide" -version = "0.7.11" +version = "0.7.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f" +checksum = "901e8597c777fa042e9e245bd56c0dc4418c5db3f845b6ff94fbac732c6a0692" dependencies = [ "bytemuck", "safe_arch", @@ -23671,9 +23685,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -23693,11 +23707,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -23706,15 +23720,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows" version = "0.51.1" @@ -23732,7 +23737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core 0.52.0", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -23750,7 +23755,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -23792,7 +23797,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -23827,17 +23841,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -23854,9 +23869,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -23872,9 +23887,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -23890,9 +23905,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -23908,9 +23929,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -23926,9 +23947,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -23944,9 +23965,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -23962,15 +23983,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -23996,9 +24026,9 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", "rand_core", @@ -24029,7 +24059,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ - "asn1-rs 0.6.1", + "asn1-rs 0.6.2", "data-encoding", "der-parser 9.0.0", "lazy_static", @@ -24042,11 +24072,13 @@ dependencies = [ [[package]] name = "xattr" -version = "1.0.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", + "linux-raw-sys 0.4.14", + "rustix 0.38.34", ] [[package]] @@ -24136,10 +24168,10 @@ name = "xcm-procedural" version = "7.0.0" dependencies = [ "Inflector", - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", "staging-xcm", - "syn 2.0.61", + "syn 2.0.72", "trybuild", ] @@ -24289,22 +24321,23 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -24322,9 +24355,9 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.82", + "proc-macro2 1.0.86", "quote 1.0.36", - "syn 2.0.61", + "syn 2.0.72", ] [[package]] @@ -24384,11 +24417,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index 7ae7c3bd1811..fbafa55c2d06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -408,6 +408,7 @@ members = [ "substrate/frame/staking/reward-curve", "substrate/frame/staking/reward-fn", "substrate/frame/staking/runtime-api", + "substrate/frame/staking/stake-tracker", "substrate/frame/state-trie-migration", "substrate/frame/statement", "substrate/frame/sudo", @@ -959,6 +960,7 @@ pallet-session = { path = "substrate/frame/session", default-features = false } pallet-session-benchmarking = { path = "substrate/frame/session/benchmarking", default-features = false } pallet-skip-feeless-payment = { path = "substrate/frame/transaction-payment/skip-feeless-payment", default-features = false } pallet-society = { path = "substrate/frame/society", default-features = false } +pallet-stake-tracker = { path = "substrate/frame/staking/stake-tracker", default-features = false } pallet-staking = { path = "substrate/frame/staking", default-features = false } pallet-staking-reward-curve = { path = "substrate/frame/staking/reward-curve", default-features = false } pallet-staking-reward-fn = { path = "substrate/frame/staking/reward-fn", default-features = false } diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index 4226595cd2ff..ea3f0503635b 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -79,6 +79,7 @@ pallet-referenda = { workspace = true } pallet-scheduler = { workspace = true } pallet-session = { workspace = true } pallet-society = { workspace = true } +pallet-stake-tracker = { workspace = true } pallet-staking = { workspace = true } pallet-staking-runtime-api = { workspace = true } pallet-delegated-staking = { workspace = true } @@ -183,6 +184,7 @@ std = [ "pallet-session-benchmarking?/std", "pallet-session/std", "pallet-society/std", + "pallet-stake-tracker/std", "pallet-staking-runtime-api/std", "pallet-staking/std", "pallet-state-trie-migration/std", @@ -269,6 +271,7 @@ runtime-benchmarks = [ "pallet-scheduler/runtime-benchmarks", "pallet-session-benchmarking/runtime-benchmarks", "pallet-society/runtime-benchmarks", + "pallet-stake-tracker/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-state-trie-migration/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", @@ -329,6 +332,7 @@ try-runtime = [ "pallet-scheduler/try-runtime", "pallet-session/try-runtime", "pallet-society/try-runtime", + "pallet-stake-tracker/try-runtime", "pallet-staking/try-runtime", "pallet-state-trie-migration/try-runtime", "pallet-sudo/try-runtime", diff --git a/polkadot/runtime/westend/src/bag_thresholds.rs b/polkadot/runtime/westend/src/bag_thresholds.rs index de28520d4619..ddbcc1b6aae4 100644 --- a/polkadot/runtime/westend/src/bag_thresholds.rs +++ b/polkadot/runtime/westend/src/bag_thresholds.rs @@ -29,8 +29,212 @@ pub const EXISTENTIAL_WEIGHT: u64 = 10_000_000_000; #[allow(unused)] pub const CONSTANT_RATIO: f64 = 1.1131723507077667; -/// Upper thresholds delimiting the bag list. -pub const THRESHOLDS: [u64; 200] = [ +/// Upper thresholds delimiting the voters bag list. +pub const VOTER_THRESHOLDS: [u64; 200] = [ + 10_000_000_000, + 11_131_723_507, + 12_391_526_824, + 13_793_905_044, + 15_354_993_703, + 17_092_754_435, + 19_027_181_634, + 21_180_532_507, + 23_577_583_160, + 26_245_913_670, + 29_216_225_417, + 32_522_694_326, + 36_203_364_094, + 40_300_583_912, + 44_861_495_728, + 49_938_576_656, + 55_590_242_767, + 61_881_521_217, + 68_884_798_439, + 76_680_653_006, + 85_358_782_760, + 95_019_036_859, + 105_772_564_622, + 117_743_094_401, + 131_068_357_174, + 145_901_671_259, + 162_413_706_368, + 180_794_447_305, + 201_255_379_901, + 224_031_924_337, + 249_386_143_848, + 277_609_759_981, + 309_027_509_097, + 344_000_878_735, + 382_932_266_827, + 426_269_611_626, + 474_511_545_609, + 528_213_132_664, + 587_992_254_562, + 654_536_720_209, + 728_612_179_460, + 811_070_932_564, + 902_861_736_593, + 1_005_040_721_687, + 1_118_783_542_717, + 1_245_398_906_179, + 1_386_343_627_960, + 1_543_239_395_225, + 1_717_891_425_287, + 1_912_309_236_147, + 2_128_729_767_682, + 2_369_643_119_512, + 2_637_821_201_686, + 2_936_349_627_828, + 3_268_663_217_709, + 3_638_585_517_729, + 4_050_372_794_022, + 4_508_763_004_364, + 5_019_030_312_352, + 5_587_045_771_074, + 6_219_344_874_498, + 6_923_202_753_807, + 7_706_717_883_882, + 8_578_905_263_043, + 9_549_800_138_161, + 10_630_573_468_586, + 11_833_660_457_397, + 13_172_903_628_838, + 14_663_712_098_160, + 16_323_238_866_411, + 18_170_578_180_087, + 20_226_985_226_447, + 22_516_120_692_255, + 25_064_322_999_817, + 27_900_911_352_605, + 31_058_523_077_268, + 34_573_489_143_434, + 38_486_252_181_966, + 42_841_831_811_331, + 47_690_342_626_046, + 53_087_570_807_094, + 59_095_615_988_698, + 65_783_605_766_662, + 73_228_491_069_308, + 81_515_931_542_404, + 90_741_281_135_191, + 101_010_685_227_495, + 112_442_301_921_293, + 125_167_661_548_718, + 139_333_180_038_781, + 155_101_843_555_358, + 172_655_083_789_626, + 192_194_865_483_744, + 213_946_010_204_502, + 238_158_783_103_893, + 265_111_772_429_462, + 295_115_094_915_607, + 328_513_963_936_552, + 365_692_661_475_578, + 407_078_959_611_349, + 453_149_042_394_237, + 504_432_984_742_966, + 561_520_851_400_862, + 625_069_486_125_324, + 695_810_069_225_823, + 774_556_530_406_243, + 862_214_913_708_369, + 959_793_802_308_039, + 1_068_415_923_109_985, + 1_189_331_064_661_951, + 1_323_930_457_019_515, + 1_473_762_779_014_021, + 1_640_551_977_100_649, + 1_826_217_100_807_404, + 2_032_894_383_008_501, + 2_262_961_819_074_188, + 2_519_066_527_700_738, + 2_804_155_208_229_882, + 3_121_508_044_894_685, + 3_474_776_448_088_622, + 3_868_025_066_902_796, + 4_305_778_556_320_752, + 4_793_073_637_166_665, + 5_335_517_047_800_242, + 5_939_350_054_341_159, + 6_611_520_261_667_250, + 7_359_761_551_432_161, + 8_192_683_066_856_378, + 9_119_868_268_136_230, + 10_151_985_198_186_376, + 11_300_909_227_415_580, + 12_579_859_689_817_292, + 14_003_551_982_487_792, + 15_588_366_878_604_342, + 17_352_539_001_951_086, + 19_316_366_631_550_092, + 21_502_445_250_375_680, + 23_935_927_525_325_748, + 26_644_812_709_737_600, + 29_660_268_798_266_784, + 33_016_991_140_790_860, + 36_753_601_641_491_664, + 40_913_093_136_236_104, + 45_543_324_061_189_736, + 50_697_569_104_240_168, + 56_435_132_174_936_472, + 62_822_028_745_677_552, + 69_931_745_415_056_768, + 77_846_085_432_775_824, + 86_656_109_914_600_688, + 96_463_185_576_826_656, + 107_380_151_045_315_664, + 119_532_615_158_469_088, + 133_060_402_202_199_856, + 148_119_160_705_543_712, + 164_882_154_307_451_552, + 183_542_255_300_186_560, + 204_314_163_786_713_728, + 227_436_877_985_347_776, + 253_176_444_104_585_088, + 281_829_017_427_734_464, + 313_724_269_827_691_328, + 349_229_182_918_168_832, + 388_752_270_484_770_624, + 432_748_278_778_513_664, + 481_723_418_752_617_984, + 536_241_190_443_833_600, + 596_928_866_512_693_376, + 664_484_709_541_257_600, + 739_686_006_129_409_280, + 823_398_010_228_713_984, + 916_583_898_614_395_264, + 1_020_315_853_041_475_584, + 1_135_787_396_594_579_584, + 1_264_327_126_171_442_688, + 1_407_413_999_103_859_968, + 1_566_694_349_801_462_272, + 1_744_000_832_209_069_824, + 1_941_373_506_026_471_680, + 2_161_083_309_305_266_176, + 2_405_658_187_494_662_656, + 2_677_912_179_572_818_944, + 2_980_977_795_924_034_048, + 3_318_342_060_496_414_208, + 3_693_886_631_935_247_360, + 4_111_932_465_319_354_368, + 4_577_289_528_371_127_808, + 5_095_312_144_166_932_480, + 5_671_960_597_112_134_656, + 6_313_869_711_009_142_784, + 7_028_425_188_266_614_784, + 7_823_848_588_596_424_704, + 8_709_291_924_949_524_480, + 9_694_942_965_096_232_960, + 10_792_142_450_433_898_496, + 12_013_514_580_722_579_456, + 13_373_112_266_084_982_784, + 14_886_578_817_516_689_408, + 16_571_327_936_291_497_984, + 18_446_744_073_709_551_615, +]; + +/// Upper thresholds delimiting the targets bag list. +pub const TARGET_THRESHOLDS: [u128; 200] = [ 10_000_000_000, 11_131_723_507, 12_391_526_824, diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index eddb7cbd21ea..9e187441c14d 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -118,7 +118,6 @@ pub use pallet_balances::Call as BalancesCall; pub use pallet_election_provider_multi_phase::{Call as EPMCall, GeometricDepositBase}; #[cfg(feature = "std")] pub use pallet_staking::StakerStatus; -use pallet_staking::UseValidatorsMap; pub use pallet_timestamp::Call as TimestampCall; use sp_runtime::traits::Get; #[cfg(any(feature = "std", test))] @@ -658,7 +657,10 @@ impl pallet_election_provider_multi_phase::Config for Runtime { } parameter_types! { - pub const BagThresholds: &'static [u64] = &bag_thresholds::THRESHOLDS; + pub const VoterBagThresholds: &'static [u64] = &bag_thresholds::VOTER_THRESHOLDS; + pub const TargetBagThresholds: &'static [u128] = &bag_thresholds::TARGET_THRESHOLDS; + + pub const VoterUpdateMode: pallet_stake_tracker::VoterUpdateMode = pallet_stake_tracker::VoterUpdateMode::Lazy; } type VoterBagsListInstance = pallet_bags_list::Instance1; @@ -666,10 +668,27 @@ impl pallet_bags_list::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ScoreProvider = Staking; type WeightInfo = weights::pallet_bags_list::WeightInfo; - type BagThresholds = BagThresholds; + type BagThresholds = VoterBagThresholds; type Score = sp_npos_elections::VoteWeight; } +type TargetBagsListInstance = pallet_bags_list::Instance2; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ScoreProvider = pallet_bags_list::Pallet; + type WeightInfo = weights::pallet_bags_list::WeightInfo; + type BagThresholds = TargetBagThresholds; + type Score = u128; +} + +impl pallet_stake_tracker::Config for Runtime { + type Currency = Balances; + type Staking = Staking; + type VoterList = VoterList; + type TargetList = TargetList; + type VoterUpdateMode = VoterUpdateMode; +} + pub struct EraPayout; impl pallet_staking::EraPayout for EraPayout { fn era_payout( @@ -739,13 +758,13 @@ impl pallet_staking::Config for Runtime { type ElectionProvider = ElectionProviderMultiPhase; type GenesisElectionProvider = onchain::OnChainExecution; type VoterList = VoterList; - type TargetList = UseValidatorsMap; + type TargetList = TargetList; type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>; type MaxUnlockingChunks = frame_support::traits::ConstU32<32>; type HistoryDepth = frame_support::traits::ConstU32<84>; type MaxControllersInDeprecationBatch = MaxControllersInDeprecationBatch; type BenchmarkingConfig = polkadot_runtime_common::StakingBenchmarkingConfig; - type EventListeners = (NominationPools, DelegatedStaking); + type EventListeners = (StakeTracker, NominationPools, DelegatedStaking); type WeightInfo = weights::pallet_staking::WeightInfo; type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; } @@ -1096,6 +1115,7 @@ impl InstanceFilter for ProxyType { RuntimeCall::Slots(..) | RuntimeCall::Auctions(..) | // Specifically omitting the entire XCM Pallet RuntimeCall::VoterList(..) | + RuntimeCall::TargetList(..) | RuntimeCall::NominationPools(..) | RuntimeCall::FastUnstake(..) ), @@ -1106,6 +1126,7 @@ impl InstanceFilter for ProxyType { RuntimeCall::Session(..) | RuntimeCall::Utility(..) | RuntimeCall::FastUnstake(..) | RuntimeCall::VoterList(..) | + RuntimeCall::TargetList(..) | RuntimeCall::NominationPools(..) ) }, @@ -1620,7 +1641,7 @@ mod runtime { #[runtime::pallet_index(24)] pub type ElectionProviderMultiPhase = pallet_election_provider_multi_phase; - // Provides a semi-sorted list of nominators for staking. + // Provides a sorted list of nominators for staking. #[runtime::pallet_index(25)] pub type VoterList = pallet_bags_list; @@ -1728,6 +1749,14 @@ mod runtime { // Pallet for migrating Identity to a parachain. To be removed post-migration. #[runtime::pallet_index(248)] pub type IdentityMigrator = identity_migrator; + + // Provides a sorted list of validators for staking. + #[runtime::pallet_index(249)] + pub type TargetList = pallet_bags_list; + + // Keeps VoterList and TargetList up to date based on staking events. + #[runtime::pallet_index(250)] + pub type StakeTracker = pallet_stake_tracker; } /// The address format for describing accounts. @@ -1798,7 +1827,7 @@ pub mod migrations { Runtime, MaxPoolsToMigrate, >, - pallet_staking::migrations::v15::MigrateV14ToV15, + pallet_staking::migrations::single_block::v15::MigrateV14ToV15, ); } @@ -1841,6 +1870,7 @@ mod benches { [polkadot_runtime_parachains::coretime, Coretime] // Substrate [pallet_bags_list, VoterList] + [pallet_bags_list, TargetList] [pallet_balances, Balances] [pallet_conviction_voting, ConvictionVoting] [pallet_election_provider_multi_phase, ElectionProviderMultiPhase] diff --git a/polkadot/runtime/westend/src/weights/pallet_staking.rs b/polkadot/runtime/westend/src/weights/pallet_staking.rs index 393fa0b37176..6fe38f233a16 100644 --- a/polkadot/runtime/westend/src/weights/pallet_staking.rs +++ b/polkadot/runtime/westend/src/weights/pallet_staking.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_staking` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-06-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-h2rr8wx7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-1pho9goo-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -52,43 +52,57 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn bond() -> Weight { // Proof Size summary in bytes: - // Measured: `1009` + // Measured: `1101` // Estimated: `4764` - // Minimum execution time: 40_585_000 picoseconds. - Weight::from_parts(41_800_000, 0) + // Minimum execution time: 54_820_000 picoseconds. + Weight::from_parts(56_134_000, 0) .saturating_add(Weight::from_parts(0, 4764)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn bond_extra() -> Weight { // Proof Size summary in bytes: - // Measured: `1921` + // Measured: `2629` // Estimated: `8877` - // Minimum execution time: 81_809_000 picoseconds. - Weight::from_parts(84_387_000, 0) + // Minimum execution time: 119_449_000 picoseconds. + Weight::from_parts(122_803_000, 0) .saturating_add(Weight::from_parts(0, 8877)) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(7)) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(8)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -100,23 +114,25 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:3 w:3) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:2 w:2) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) fn unbond() -> Weight { // Proof Size summary in bytes: - // Measured: `2128` - // Estimated: `8877` - // Minimum execution time: 89_419_000 picoseconds. - Weight::from_parts(91_237_000, 0) - .saturating_add(Weight::from_parts(0, 8877)) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `1955` + // Estimated: `4764` + // Minimum execution time: 83_155_000 picoseconds. + Weight::from_parts(85_538_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -124,23 +140,31 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: `DelegatedStaking::Agents` (r:1 w:0) + /// Proof: `DelegatedStaking::Agents` (`max_values`: None, `max_size`: Some(120), added: 2595, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1223` + // Measured: `1379` // Estimated: `4764` - // Minimum execution time: 45_152_000 picoseconds. - Weight::from_parts(46_460_819, 0) + // Minimum execution time: 59_632_000 picoseconds. + Weight::from_parts(61_370_945, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 972 - .saturating_add(Weight::from_parts(55_473, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(6)) + // Standard Error: 939 + .saturating_add(Weight::from_parts(64_163, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -151,22 +175,28 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -174,15 +204,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2127 + s * (4 ±0)` + // Measured: `2786 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 82_762_000 picoseconds. - Weight::from_parts(91_035_077, 0) + // Minimum execution time: 125_060_000 picoseconds. + Weight::from_parts(137_232_931, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_771 - .saturating_add(Weight::from_parts(1_217_871, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(13)) - .saturating_add(T::DbWeight::get().writes(11)) + // Standard Error: 4_487 + .saturating_add(Weight::from_parts(1_363_542, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(15)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -198,8 +228,14 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:1 w:0) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:0) + /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:1 w:1) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:1 w:1) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) @@ -210,42 +246,49 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn validate() -> Weight { // Proof Size summary in bytes: - // Measured: `1301` + // Measured: `1569` // Estimated: `4556` - // Minimum execution time: 50_555_000 picoseconds. - Weight::from_parts(52_052_000, 0) + // Minimum execution time: 71_655_000 picoseconds. + Weight::from_parts(74_791_000, 0) .saturating_add(Weight::from_parts(0, 4556)) - .saturating_add(T::DbWeight::get().reads(11)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(9)) } - /// Storage: `Staking::Ledger` (r:1 w:0) + /// Storage: `Staking::Ledger` (r:129 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) + /// Storage: `Staking::Bonded` (r:129 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:128 w:128) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:128 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:2 w:2) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:34 w:34) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1778 + k * (572 ±0)` - // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 35_037_000 picoseconds. - Weight::from_parts(35_081_878, 0) - .saturating_add(Weight::from_parts(0, 4556)) - // Standard Error: 5_473 - .saturating_add(Weight::from_parts(6_667_924, 0).saturating_mul(k.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) + // Measured: `3591 + k * (747 ±0)` + // Estimated: `33341 + k * (3566 ±0)` + // Minimum execution time: 97_335_000 picoseconds. + Weight::from_parts(117_057_410, 0) + .saturating_add(Weight::from_parts(0, 33341)) + // Standard Error: 32_099 + .saturating_add(Weight::from_parts(36_826_274, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes(15)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) - .saturating_add(Weight::from_parts(0, 3033).saturating_mul(k.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(k.into())) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) + /// Storage: `Staking::Bonded` (r:17 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::MinNominatorBond` (r:1 w:0) /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:1) + /// Storage: `Staking::Nominators` (r:17 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:1 w:0) /// Proof: `Staking::MaxNominatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -253,28 +296,33 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::CounterForNominators` (r:1 w:1) + /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForNominators` (r:1 w:1) - /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:16 w:16) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1797 + n * (102 ±0)` - // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 62_098_000 picoseconds. - Weight::from_parts(60_154_061, 0) + // Measured: `2314 + n * (348 ±0)` + // Estimated: `6248 + n * (3033 ±0)` + // Minimum execution time: 108_483_000 picoseconds. + Weight::from_parts(83_672_983, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 19_257 - .saturating_add(Weight::from_parts(3_839_855, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes(6)) - .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + // Standard Error: 38_048 + .saturating_add(Weight::from_parts(32_268_279, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(8)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -286,6 +334,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) @@ -294,13 +346,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1747` + // Measured: `2373` // Estimated: `6248` - // Minimum execution time: 54_993_000 picoseconds. - Weight::from_parts(56_698_000, 0) + // Minimum execution time: 90_227_000 picoseconds. + Weight::from_parts(94_317_000, 0) .saturating_add(Weight::from_parts(0, 6248)) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(9)) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -310,10 +362,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn set_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `865` + // Measured: `898` // Estimated: `4556` - // Minimum execution time: 18_100_000 picoseconds. - Weight::from_parts(18_547_000, 0) + // Minimum execution time: 18_782_000 picoseconds. + Weight::from_parts(19_664_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -326,10 +378,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `932` + // Measured: `965` // Estimated: `4556` - // Minimum execution time: 23_428_000 picoseconds. - Weight::from_parts(24_080_000, 0) + // Minimum execution time: 24_418_000 picoseconds. + Weight::from_parts(25_314_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -340,10 +392,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) fn set_controller() -> Weight { // Proof Size summary in bytes: - // Measured: `865` + // Measured: `898` // Estimated: `8122` - // Minimum execution time: 21_159_000 picoseconds. - Weight::from_parts(21_706_000, 0) + // Minimum execution time: 22_093_000 picoseconds. + Weight::from_parts(22_653_000, 0) .saturating_add(Weight::from_parts(0, 8122)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -354,8 +406,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_910_000 picoseconds. - Weight::from_parts(2_003_000, 0) + // Minimum execution time: 1_794_000 picoseconds. + Weight::from_parts(1_915_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -365,8 +417,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_076_000 picoseconds. - Weight::from_parts(7_349_000, 0) + // Minimum execution time: 6_918_000 picoseconds. + Weight::from_parts(7_328_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -376,8 +428,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_067_000 picoseconds. - Weight::from_parts(7_389_000, 0) + // Minimum execution time: 6_896_000 picoseconds. + Weight::from_parts(7_363_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -387,8 +439,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_148_000 picoseconds. - Weight::from_parts(7_446_000, 0) + // Minimum execution time: 6_939_000 picoseconds. + Weight::from_parts(7_148_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -399,11 +451,11 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_025_000 picoseconds. - Weight::from_parts(2_229_953, 0) + // Minimum execution time: 2_011_000 picoseconds. + Weight::from_parts(2_237_009, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 67 - .saturating_add(Weight::from_parts(11_785, 0).saturating_mul(v.into())) + // Standard Error: 78 + .saturating_add(Weight::from_parts(11_871, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Staking::Ledger` (r:1502 w:1502) @@ -415,13 +467,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `i` is `[0, 751]`. fn deprecate_controller_batch(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `680 + i * (227 ±0)` + // Measured: `713 + i * (227 ±0)` // Estimated: `990 + i * (7132 ±0)` - // Minimum execution time: 4_321_000 picoseconds. - Weight::from_parts(4_407_000, 0) + // Minimum execution time: 4_165_000 picoseconds. + Weight::from_parts(4_301_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 37_239 - .saturating_add(Weight::from_parts(21_300_598, 0).saturating_mul(i.into())) + // Standard Error: 37_161 + .saturating_add(Weight::from_parts(21_839_803, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 7132).saturating_mul(i.into())) @@ -430,26 +482,32 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:1) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:1) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -457,15 +515,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[0, 100]`. fn force_unstake(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2127 + s * (4 ±0)` + // Measured: `2786 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 78_908_000 picoseconds. - Weight::from_parts(84_886_373, 0) + // Minimum execution time: 120_656_000 picoseconds. + Weight::from_parts(132_995_369, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_376 - .saturating_add(Weight::from_parts(1_217_850, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(13)) - .saturating_add(T::DbWeight::get().writes(12)) + // Standard Error: 4_110 + .saturating_add(Weight::from_parts(1_245_843, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(16)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -474,13 +532,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[1, 1000]`. fn cancel_deferred_slash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `66639` - // Estimated: `70104` - // Minimum execution time: 136_389_000 picoseconds. - Weight::from_parts(1_207_241_524, 0) - .saturating_add(Weight::from_parts(0, 70104)) - // Standard Error: 77_138 - .saturating_add(Weight::from_parts(6_443_948, 0).saturating_mul(s.into())) + // Measured: `66672` + // Estimated: `70137` + // Minimum execution time: 130_000_000 picoseconds. + Weight::from_parts(1_192_933_047, 0) + .saturating_add(Weight::from_parts(0, 70137)) + // Standard Error: 76_645 + .saturating_add(Weight::from_parts(6_458_788, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -498,33 +556,43 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasValidatorReward` (r:1 w:0) /// Proof: `Staking::ErasValidatorReward` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::VirtualStakers` (r:65 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:65 w:65) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:65 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:65 w:65) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) /// Proof: `Staking::ErasRewardPoints` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasValidatorPrefs` (r:1 w:0) /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:65 w:0) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:65 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:65 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:8 w:8) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 64]`. fn payout_stakers_alive_staked(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `8249 + n * (396 ±0)` - // Estimated: `10779 + n * (3774 ±0)` - // Minimum execution time: 130_222_000 picoseconds. - Weight::from_parts(167_236_150, 0) - .saturating_add(Weight::from_parts(0, 10779)) - // Standard Error: 34_051 - .saturating_add(Weight::from_parts(39_899_917, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(14)) - .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `8725 + n * (482 ±0)` + // Estimated: `17769 + n * (3774 ±0)` + // Minimum execution time: 184_524_000 picoseconds. + Weight::from_parts(244_791_126, 0) + .saturating_add(Weight::from_parts(0, 17769)) + // Standard Error: 46_100 + .saturating_add(Weight::from_parts(62_744_799, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(25)) + .saturating_add(T::DbWeight::get().reads((9_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(12)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) } @@ -532,10 +600,18 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) @@ -543,38 +619,44 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1922 + l * (5 ±0)` + // Measured: `2630 + l * (5 ±0)` // Estimated: `8877` - // Minimum execution time: 79_136_000 picoseconds. - Weight::from_parts(82_129_497, 0) + // Minimum execution time: 114_260_000 picoseconds. + Weight::from_parts(118_334_795, 0) .saturating_add(Weight::from_parts(0, 8877)) - // Standard Error: 3_867 - .saturating_add(Weight::from_parts(75_156, 0).saturating_mul(l.into())) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(7)) + // Standard Error: 5_407 + .saturating_add(Weight::from_parts(92_391, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(8)) } + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -582,15 +664,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[1, 100]`. fn reap_stash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2127 + s * (4 ±0)` - // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 89_375_000 picoseconds. - Weight::from_parts(91_224_907, 0) - .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_424 - .saturating_add(Weight::from_parts(1_219_542, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(11)) + // Measured: `2786 + s * (4 ±0)` + // Estimated: `6251 + s * (4 ±0)` + // Minimum execution time: 136_630_000 picoseconds. + Weight::from_parts(139_624_083, 0) + .saturating_add(Weight::from_parts(0, 6251)) + // Standard Error: 4_377 + .saturating_add(Weight::from_parts(1_270_564, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(15)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -600,16 +682,20 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:110 w:0) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:110 w:0) + /// Storage: `Staking::Bonded` (r:111 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:110 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:110 w:0) + /// Storage: `Staking::Nominators` (r:111 w:0) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:11 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForValidators` (r:1 w:0) - /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:0) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:201 w:0) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:11 w:0) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) /// Storage: `Staking::ValidatorCount` (r:1 w:0) /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::MinimumValidatorCount` (r:1 w:0) @@ -632,17 +718,17 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `n` is `[0, 100]`. fn new_era(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (716 ±0) + v * (3594 ±0)` - // Estimated: `456136 + n * (3566 ±4) + v * (3566 ±0)` - // Minimum execution time: 520_905_000 picoseconds. - Weight::from_parts(523_771_000, 0) - .saturating_add(Weight::from_parts(0, 456136)) - // Standard Error: 2_142_714 - .saturating_add(Weight::from_parts(68_631_588, 0).saturating_mul(v.into())) - // Standard Error: 213_509 - .saturating_add(Weight::from_parts(19_343_025, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(184)) - .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + // Measured: `0 + n * (716 ±0) + v * (3772 ±0)` + // Estimated: `516555 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 861_594_000 picoseconds. + Weight::from_parts(870_075_000, 0) + .saturating_add(Weight::from_parts(0, 516555)) + // Standard Error: 2_000_637 + .saturating_add(Weight::from_parts(64_775_296, 0).saturating_mul(v.into())) + // Standard Error: 199_352 + .saturating_add(Weight::from_parts(19_111_894, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(388)) + .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(8)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) @@ -669,15 +755,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `n` is `[500, 1000]`. fn get_npos_voters(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3108 + n * (907 ±0) + v * (391 ±0)` + // Measured: `3175 + n * (907 ±0) + v * (391 ±0)` // Estimated: `456136 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 36_848_619_000 picoseconds. - Weight::from_parts(37_362_442_000, 0) + // Minimum execution time: 37_093_286_000 picoseconds. + Weight::from_parts(37_508_552_000, 0) .saturating_add(Weight::from_parts(0, 456136)) - // Standard Error: 415_031 - .saturating_add(Weight::from_parts(5_204_987, 0).saturating_mul(v.into())) - // Standard Error: 415_031 - .saturating_add(Weight::from_parts(4_132_636, 0).saturating_mul(n.into())) + // Standard Error: 410_759 + .saturating_add(Weight::from_parts(5_517_425, 0).saturating_mul(v.into())) + // Standard Error: 410_759 + .saturating_add(Weight::from_parts(4_236_228, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(179)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -685,23 +771,31 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) } - /// Storage: `Staking::CounterForValidators` (r:1 w:0) - /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:0) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:201 w:0) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1001 w:0) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:1001 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1001 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1001 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// The range of component `v` is `[500, 1000]`. fn get_npos_targets(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `946 + v * (50 ±0)` - // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_512_817_000 picoseconds. - Weight::from_parts(119_401_374, 0) - .saturating_add(Weight::from_parts(0, 3510)) - // Standard Error: 8_463 - .saturating_add(Weight::from_parts(4_860_364, 0).saturating_mul(v.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) - .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) + // Measured: `58138 + v * (323 ±0)` + // Estimated: `516555 + v * (3033 ±0)` + // Minimum execution time: 9_387_999_000 picoseconds. + Weight::from_parts(9_449_117_000, 0) + .saturating_add(Weight::from_parts(0, 516555)) + // Standard Error: 115_623 + .saturating_add(Weight::from_parts(7_439_858, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(206)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(v.into())) } /// Storage: `Staking::MinCommission` (r:0 w:1) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -721,8 +815,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_686_000 picoseconds. - Weight::from_parts(3_881_000, 0) + // Minimum execution time: 3_637_000 picoseconds. + Weight::from_parts(3_844_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -744,8 +838,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_143_000 picoseconds. - Weight::from_parts(3_424_000, 0) + // Minimum execution time: 3_261_000 picoseconds. + Weight::from_parts(3_462_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -765,6 +859,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) @@ -773,13 +871,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill_other() -> Weight { // Proof Size summary in bytes: - // Measured: `1870` + // Measured: `2488` // Estimated: `6248` - // Minimum execution time: 66_946_000 picoseconds. - Weight::from_parts(69_382_000, 0) + // Minimum execution time: 101_110_000 picoseconds. + Weight::from_parts(105_138_000, 0) .saturating_add(Weight::from_parts(0, 6248)) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().reads(15)) + .saturating_add(T::DbWeight::get().writes(9)) } /// Storage: `Staking::MinCommission` (r:1 w:0) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -787,10 +885,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) fn force_apply_min_commission() -> Weight { // Proof Size summary in bytes: - // Measured: `658` + // Measured: `691` // Estimated: `3510` - // Minimum execution time: 11_278_000 picoseconds. - Weight::from_parts(11_603_000, 0) + // Minimum execution time: 11_460_000 picoseconds. + Weight::from_parts(11_842_000, 0) .saturating_add(Weight::from_parts(0, 3510)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -801,11 +899,13 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_963_000 picoseconds. - Weight::from_parts(2_077_000, 0) + // Minimum execution time: 1_866_000 picoseconds. + Weight::from_parts(2_002_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) @@ -816,14 +916,70 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1014` + // Measured: `1132` // Estimated: `4764` - // Minimum execution time: 40_258_000 picoseconds. - Weight::from_parts(41_210_000, 0) + // Minimum execution time: 53_810_000 picoseconds. + Weight::from_parts(54_953_000, 0) .saturating_add(Weight::from_parts(0, 4764)) - .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `Staking::Bonded` (r:3 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:2 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:2 w:1) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::MinNominatorBond` (r:1 w:0) + /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:1 w:1) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn drop_dangling_nomination() -> Weight { + // Proof Size summary in bytes: + // Measured: `1791` + // Estimated: `8631` + // Minimum execution time: 86_529_000 picoseconds. + Weight::from_parts(89_155_000, 0) + .saturating_add(Weight::from_parts(0, 8631)) + .saturating_add(T::DbWeight::get().reads(13)) .saturating_add(T::DbWeight::get().writes(4)) } + /// Storage: `Staking::Nominators` (r:84 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:83 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:21 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1006 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1000 w:78) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:4 w:4) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn v13_mmb_partial_step() -> Weight { + // Proof Size summary in bytes: + // Measured: `167522` + // Estimated: `2645990` + // Minimum execution time: 10_525_342_000 picoseconds. + Weight::from_parts(10_686_750_000, 0) + .saturating_add(Weight::from_parts(0, 2645990)) + .saturating_add(T::DbWeight::get().reads(2199)) + .saturating_add(T::DbWeight::get().writes(83)) + } } diff --git a/prdoc/pr_1933.prdoc b/prdoc/pr_1933.prdoc new file mode 100644 index 000000000000..9ba5762aa0bb --- /dev/null +++ b/prdoc/pr_1933.prdoc @@ -0,0 +1,39 @@ +title: Adds `stake-tracker` pallet and integrates it with the staking pallet + +doc: + - audience: Runtime Dev + description: | + Adds the `stake-tracker` pallet which ensures that the staking system keeps an up-to date + list of targets, *strictly-sorted* by the target's approvals stakes. The `stake-tracker` + pallet implements the `OnStakingUpdate` trait to listen to staking events and handle those + events so that the target list remains strictly-sorted and up-to date. + Other notable changes in this PR are: + * Changes to assumptions of chilled and removed stakers: the target list keeps track + of validators that have been chilled/removed from the system, insofar as there are + nominators nominating them; + * Changes to staking `Call::nominate`: new nominations can only be performed on active + validators or idle stakers; + * Changes to `OnStakingUpdate` trait: new methods for signaling chilling of stakers + (`on_idle`) and refactors trait API for safety of use. + +crates: + - name: pallet-staking + bump: minor + - name: pallet-stake-tracker + bump: major + - name: sp-staking + bump: major + - name: frame-election-provider-support + bump: none + - name: polkadot-sdk + bump: minor + - name: pallet-fast-unstake + bump: none + - name: pallet-bags-list + bump: minor + - name: westend-runtime + bump: minor + - name: pallet-delegated-staking + bump: none + - name: pallet-nomination-pools-benchmarking + bump: minor diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index fd8597563a02..12b9d9ea30e7 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -132,7 +132,7 @@ use constants::{currency::*, time::*}; use sp_runtime::generic::Era; /// Generated voter bag information. -mod voter_bags; +mod voter_target_bags; /// Runtime API definition for assets. pub mod assets_api; @@ -689,18 +689,29 @@ impl pallet_staking::Config for Runtime { type ElectionProvider = ElectionProviderMultiPhase; type GenesisElectionProvider = onchain::OnChainExecution; type VoterList = VoterList; + type TargetList = TargetList; type NominationsQuota = pallet_staking::FixedNominationsQuota; - // This a placeholder, to be introduced in the next PR as an instance of bags-list - type TargetList = pallet_staking::UseValidatorsMap; type MaxUnlockingChunks = ConstU32<32>; type MaxControllersInDeprecationBatch = MaxControllersInDeprecationBatch; type HistoryDepth = HistoryDepth; - type EventListeners = NominationPools; + type EventListeners = (StakeTracker, NominationPools); type WeightInfo = pallet_staking::weights::SubstrateWeight; type BenchmarkingConfig = StakingBenchmarkingConfig; type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; } +parameter_types! { + pub const VoterUpdateMode: pallet_stake_tracker::VoterUpdateMode = pallet_stake_tracker::VoterUpdateMode::Lazy; +} + +impl pallet_stake_tracker::Config for Runtime { + type Currency = Balances; + type Staking = Staking; + type VoterList = VoterList; + type TargetList = TargetList; + type VoterUpdateMode = VoterUpdateMode; +} + impl pallet_fast_unstake::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ControlOrigin = frame_system::EnsureRoot; @@ -865,7 +876,8 @@ impl pallet_election_provider_multi_phase::Config for Runtime { } parameter_types! { - pub const BagThresholds: &'static [u64] = &voter_bags::THRESHOLDS; + pub const VoterBagThresholds: &'static [u64] = &voter_target_bags::VOTER_THRESHOLDS; + pub const TargetBagThresholds: &'static [Balance] = &voter_target_bags::TARGET_THRESHOLDS; } type VoterBagsListInstance = pallet_bags_list::Instance1; @@ -874,11 +886,20 @@ impl pallet_bags_list::Config for Runtime { /// The voter bags-list is loosely kept up to date, and the real source of truth for the score /// of each node is the staking pallet. type ScoreProvider = Staking; - type BagThresholds = BagThresholds; + type BagThresholds = VoterBagThresholds; type Score = VoteWeight; type WeightInfo = pallet_bags_list::weights::SubstrateWeight; } +type TargetBagsListInstance = pallet_bags_list::Instance2; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ScoreProvider = pallet_bags_list::Pallet; + type BagThresholds = TargetBagThresholds; + type Score = Balance; + type WeightInfo = pallet_bags_list::weights::SubstrateWeight; +} + parameter_types! { pub const PostUnbondPoolsWindow: u32 = 4; pub const NominationPoolsPalletId: PalletId = PalletId(*b"py/nopls"); @@ -2469,6 +2490,12 @@ mod runtime { #[runtime::pallet_index(79)] pub type AssetConversionMigration = pallet_asset_conversion_ops::Pallet; + + #[runtime::pallet_index(80)] + pub type TargetList = pallet_bags_list; + + #[runtime::pallet_index(81)] + pub type StakeTracker = pallet_stake_tracker; } /// The address format for describing accounts. @@ -2572,6 +2599,7 @@ mod benches { [pallet_assets, Assets] [pallet_babe, Babe] [pallet_bags_list, VoterList] + [pallet_bags_list, TargetList] [pallet_balances, Balances] [pallet_bounties, Bounties] [pallet_broker, Broker] diff --git a/substrate/bin/node/runtime/src/voter_bags.rs b/substrate/bin/node/runtime/src/voter_target_bags.rs similarity index 53% rename from substrate/bin/node/runtime/src/voter_bags.rs rename to substrate/bin/node/runtime/src/voter_target_bags.rs index bf18097ddf53..151004377410 100644 --- a/substrate/bin/node/runtime/src/voter_bags.rs +++ b/substrate/bin/node/runtime/src/voter_target_bags.rs @@ -33,8 +33,213 @@ pub const EXISTENTIAL_WEIGHT: u64 = 100_000_000_000_000; #[allow(unused)] pub const CONSTANT_RATIO: f64 = 1.0628253590743408; -/// Upper thresholds delimiting the bag list. -pub const THRESHOLDS: [u64; 200] = [ +/// Upper thresholds delimiting the voters bag list. +pub const VOTER_THRESHOLDS: [u64; 200] = [ + 100_000_000_000_000, + 106_282_535_907_434, + 112_959_774_389_150, + 120_056_512_776_105, + 127_599_106_300_477, + 135_615_565_971_369, + 144_135_662_599_590, + 153_191_037_357_827, + 162_815_319_286_803, + 173_044_250_183_800, + 183_915_817_337_347, + 195_470_394_601_017, + 207_750_892_330_229, + 220_802_916_738_890, + 234_674_939_267_673, + 249_418_476_592_914, + 265_088_281_944_639, + 281_742_548_444_211, + 299_443_125_216_738, + 318_255_747_080_822, + 338_250_278_668_647, + 359_500_973_883_001, + 382_086_751_654_776, + 406_091_489_025_036, + 431_604_332_640_068, + 458_720_029_816_222, + 487_539_280_404_019, + 518_169_110_758_247, + 550_723_271_202_866, + 585_322_658_466_782, + 622_095_764_659_305, + 661_179_154_452_653, + 702_717_972_243_610, + 746_866_481_177_808, + 793_788_636_038_393, + 843_658_692_126_636, + 896_661_852_395_681, + 952_994_955_240_703, + 1_012_867_205_499_736, + 1_076_500_951_379_881, + 1_144_132_510_194_192, + 1_216_013_045_975_769, + 1_292_409_502_228_280, + 1_373_605_593_276_862, + 1_459_902_857_901_004, + 1_551_621_779_162_291, + 1_649_102_974_585_730, + 1_752_708_461_114_642, + 1_862_822_999_536_805, + 1_979_855_523_374_646, + 2_104_240_657_545_975, + 2_236_440_332_435_128, + 2_376_945_499_368_703, + 2_526_277_953_866_680, + 2_684_992_273_439_945, + 2_853_677_877_130_641, + 3_032_961_214_443_876, + 3_223_508_091_799_862, + 3_426_026_145_146_232, + 3_641_267_467_913_124, + 3_870_031_404_070_482, + 4_113_167_516_660_186, + 4_371_578_742_827_277, + 4_646_224_747_067_156, + 4_938_125_485_141_739, + 5_248_364_991_899_922, + 5_578_095_407_069_235, + 5_928_541_253_969_291, + 6_301_003_987_036_955, + 6_696_866_825_051_405, + 7_117_599_888_008_300, + 7_564_765_656_719_910, + 8_040_024_775_416_580, + 8_545_142_218_898_723, + 9_081_993_847_142_344, + 9_652_573_371_700_016, + 10_258_999_759_768_490, + 10_903_525_103_419_522, + 11_588_542_983_217_942, + 12_316_597_357_287_042, + 13_090_392_008_832_678, + 13_912_800_587_211_472, + 14_786_877_279_832_732, + 15_715_868_154_526_436, + 16_703_223_214_499_558, + 17_752_609_210_649_358, + 18_867_923_258_814_856, + 20_053_307_312_537_008, + 21_313_163_545_075_252, + 22_652_170_697_804_756, + 24_075_301_455_707_600, + 25_587_840_914_485_432, + 27_195_406_207_875_088, + 28_903_967_368_057_400, + 30_719_869_496_628_636, + 32_649_856_328_471_220, + 34_701_095_276_033_064, + 36_881_204_047_022_752, + 39_198_278_934_370_992, + 41_660_924_883_519_016, + 44_278_287_448_695_240, + 47_060_086_756_856_400, + 50_016_653_605_425_536, + 53_158_967_827_883_320, + 56_498_699_069_691_424, + 60_048_250_125_977_912, + 63_820_803_001_928_304, + 67_830_367_866_937_216, + 72_091_835_084_322_176, + 76_621_030_509_822_880, + 81_434_774_264_248_528, + 86_550_943_198_537_824, + 91_988_537_283_208_848, + 97_767_750_168_749_840, + 103_910_044_178_992_000, + 110_438_230_015_967_792, + 117_376_551_472_255_616, + 124_750_775_465_407_920, + 132_588_287_728_824_640, + 140_918_194_514_440_064, + 149_771_430_684_917_568, + 159_180_874_596_775_264, + 169_181_470_201_085_280, + 179_810_356_815_193_344, + 191_107_007_047_393_216, + 203_113_373_386_768_288, + 215_874_044_002_592_672, + 229_436_408_331_885_600, + 243_850_833_070_063_392, + 259_170_849_218_267_264, + 275_453_350_882_006_752, + 292_758_806_559_399_232, + 311_151_483_703_668_992, + 330_699_687_393_865_920, + 351_476_014_000_157_824, + 373_557_620_785_735_808, + 397_026_512_446_556_096, + 421_969_845_653_044_224, + 448_480_252_724_740_928, + 476_656_185_639_923_904, + 506_602_281_657_757_760, + 538_429_751_910_786_752, + 572_256_794_410_890_176, + 608_209_033_002_485_632, + 646_419_983_893_124_352, + 687_031_551_494_039_552, + 730_194_555_412_054_016, + 776_069_290_549_944_960, + 824_826_122_395_314_176, + 876_646_119_708_695_936, + 931_721_726_960_522_368, + 990_257_479_014_182_144, + 1_052_470_760_709_299_712, + 1_118_592_614_166_106_112, + 1_188_868_596_808_997_376, + 1_263_559_693_295_730_432, + 1_342_943_284_738_898_688, + 1_427_314_178_819_094_784, + 1_516_985_704_615_302_400, + 1_612_290_876_218_400_768, + 1_713_583_629_449_105_408, + 1_821_240_136_273_157_632, + 1_935_660_201_795_120_128, + 2_057_268_749_018_809_600, + 2_186_517_396_888_336_384, + 2_323_886_137_470_138_880, + 2_469_885_118_504_583_168, + 2_625_056_537_947_004_416, + 2_789_976_657_533_970_944, + 2_965_257_942_852_572_160, + 3_151_551_337_860_326_400, + 3_349_548_682_302_620_672, + 3_559_985_281_005_267_968, + 3_783_642_634_583_792_128, + 4_021_351_341_710_503_936, + 4_273_994_183_717_548_544, + 4_542_509_402_991_247_872, + 4_827_894_187_332_742_144, + 5_131_208_373_224_844_288, + 5_453_578_381_757_959_168, + 5_796_201_401_831_965_696, + 6_160_349_836_169_256_960, + 6_547_376_026_650_146_816, + 6_958_717_276_519_173_120, + 7_395_901_188_113_309_696, + 7_860_551_335_934_872_576, + 8_354_393_296_137_270_272, + 8_879_261_054_815_360_000, + 9_437_103_818_898_946_048, + 10_029_993_254_943_105_024, + 10_660_131_182_698_121_216, + 11_329_857_752_030_707_712, + 12_041_660_133_563_240_448, + 12_798_181_755_305_525_248, + 13_602_232_119_581_272_064, + 14_456_797_236_706_498_560, + 15_365_050_714_167_523_328, + 16_330_365_542_480_556_032, + 17_356_326_621_502_140_416, + 18_446_744_073_709_551_615, +]; + +// TODO(gpestana): generate target voter bag list with tooling. +/// Upper thresholds delimiting the targets bag list. +pub const TARGET_THRESHOLDS: [crate::Balance; 200] = [ 100_000_000_000_000, 106_282_535_907_434, 112_959_774_389_150, diff --git a/substrate/frame/Cargo.toml b/substrate/frame/Cargo.toml index 41ece6c9a27f..595fb5a19b04 100644 --- a/substrate/frame/Cargo.toml +++ b/substrate/frame/Cargo.toml @@ -67,6 +67,8 @@ pallet-examples = { workspace = true } default = ["runtime", "std"] experimental = ["frame-support/experimental"] runtime = [ + "frame-executive", + "frame-system-rpc-runtime-api", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -77,9 +79,6 @@ runtime = [ "sp-storage", "sp-transaction-pool", "sp-version", - - "frame-executive", - "frame-system-rpc-runtime-api", ] std = [ "codec/std", diff --git a/substrate/frame/bags-list/src/lib.rs b/substrate/frame/bags-list/src/lib.rs index f6af1da5e7b7..0fc05b2c8255 100644 --- a/substrate/frame/bags-list/src/lib.rs +++ b/substrate/frame/bags-list/src/lib.rs @@ -448,6 +448,15 @@ impl, I: 'static> SortedListProvider for Pallet List::::unsafe_regenerate(all, score_of) } + #[cfg(feature = "try-runtime")] + fn in_position(id: &T::AccountId) -> Result { + List::::get_score(id).and_then(|score| { + Ok(!ListNodes::::try_get(id) + .expect("if score exists, node exists; qed.") + .is_misplaced(score)) + }) + } + #[cfg(feature = "try-runtime")] fn try_state() -> Result<(), TryRuntimeError> { Self::do_try_state() diff --git a/substrate/frame/delegated-staking/Cargo.toml b/substrate/frame/delegated-staking/Cargo.toml index 1bd17c59f1e7..972f552500d6 100644 --- a/substrate/frame/delegated-staking/Cargo.toml +++ b/substrate/frame/delegated-staking/Cargo.toml @@ -24,11 +24,13 @@ sp-core = { workspace = true, default-features = true } sp-io = { workspace = true, default-features = true } substrate-test-utils = { workspace = true } sp-tracing = { workspace = true, default-features = true } +pallet-stake-tracker = { workspace = true, default-features = true } pallet-staking = { workspace = true, default-features = true } pallet-nomination-pools = { workspace = true, default-features = true } pallet-balances = { workspace = true, default-features = true } pallet-timestamp = { workspace = true, default-features = true } pallet-staking-reward-curve = { workspace = true, default-features = true } +pallet-bags-list = { workspace = true, default-features = true } frame-election-provider-support = { workspace = true } [features] @@ -38,8 +40,10 @@ std = [ "frame-election-provider-support/std", "frame-support/std", "frame-system/std", + "pallet-bags-list/std", "pallet-balances/std", "pallet-nomination-pools/std", + "pallet-stake-tracker/std", "pallet-staking/std", "pallet-timestamp/std", "scale-info/std", @@ -52,8 +56,10 @@ runtime-benchmarks = [ "frame-election-provider-support/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-bags-list/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-nomination-pools/runtime-benchmarks", + "pallet-stake-tracker/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "sp-runtime/runtime-benchmarks", @@ -63,8 +69,10 @@ try-runtime = [ "frame-election-provider-support/try-runtime", "frame-support/try-runtime", "frame-system/try-runtime", + "pallet-bags-list/try-runtime", "pallet-balances/try-runtime", "pallet-nomination-pools/try-runtime", + "pallet-stake-tracker/try-runtime", "pallet-staking/try-runtime", "pallet-timestamp/try-runtime", "sp-runtime/try-runtime", diff --git a/substrate/frame/delegated-staking/src/mock.rs b/substrate/frame/delegated-staking/src/mock.rs index 811d5739f4e9..de9ff6f9f6f9 100644 --- a/substrate/frame/delegated-staking/src/mock.rs +++ b/substrate/frame/delegated-staking/src/mock.rs @@ -109,8 +109,34 @@ impl pallet_staking::Config for Runtime { type ElectionProvider = onchain::OnChainExecution; type GenesisElectionProvider = Self::ElectionProvider; type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; - type TargetList = pallet_staking::UseValidatorsMap; - type EventListeners = (Pools, DelegatedStaking); + type TargetList = TargetBagsList; + type EventListeners = (StakeTracker, Pools, DelegatedStaking); +} + +const TARGET_THRESHOLDS: [Balance; 9] = [100, 200, 300, 400, 500, 600, 1_000, 2_000, 10_000]; +parameter_types! { + pub static TargetBagThresholds: &'static [Balance] = &TARGET_THRESHOLDS; +} + +type TargetBagsListInstance = pallet_bags_list::Instance1; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type ScoreProvider = pallet_bags_list::Pallet; + type BagThresholds = TargetBagThresholds; + type Score = Balance; +} + +parameter_types! { + pub static VoterUpdateMode: pallet_stake_tracker::VoterUpdateMode = pallet_stake_tracker::VoterUpdateMode::Lazy; +} + +impl pallet_stake_tracker::Config for Runtime { + type Currency = Balances; + type Staking = Staking; + type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; + type TargetList = TargetBagsList; + type VoterUpdateMode = VoterUpdateMode; } parameter_types! { @@ -168,6 +194,8 @@ frame_support::construct_runtime!( Timestamp: pallet_timestamp, Balances: pallet_balances, Staking: pallet_staking, + TargetBagsList: pallet_bags_list::, + StakeTracker: pallet_stake_tracker, Pools: pallet_nomination_pools, DelegatedStaking: delegated_staking, } @@ -184,6 +212,11 @@ impl ExtBuilder { let _ = pallet_balances::GenesisConfig:: { balances: vec![ + (18, 200), + (19, 200), + (20, 200), + (21, 200), + (22, 200), (GENESIS_VALIDATOR, 10000), (GENESIS_NOMINATOR_ONE, 1000), (GENESIS_NOMINATOR_TWO, 2000), @@ -192,6 +225,11 @@ impl ExtBuilder { .assimilate_storage(&mut storage); let stakers = vec![ + (18, 18, 100, sp_staking::StakerStatus::Validator), + (19, 19, 100, sp_staking::StakerStatus::Validator), + (20, 20, 100, sp_staking::StakerStatus::Validator), + (21, 21, 100, sp_staking::StakerStatus::Validator), + (22, 22, 100, sp_staking::StakerStatus::Validator), ( GENESIS_VALIDATOR, GENESIS_VALIDATOR, @@ -202,13 +240,13 @@ impl ExtBuilder { GENESIS_NOMINATOR_ONE, GENESIS_NOMINATOR_ONE, 100, - sp_staking::StakerStatus::::Nominator(vec![1]), + sp_staking::StakerStatus::::Nominator(vec![GENESIS_VALIDATOR]), ), ( GENESIS_NOMINATOR_TWO, GENESIS_NOMINATOR_TWO, 200, - sp_staking::StakerStatus::::Nominator(vec![1]), + sp_staking::StakerStatus::::Nominator(vec![GENESIS_VALIDATOR]), ), ]; diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml b/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml index 771376e06656..1f397c47ff62 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml @@ -34,6 +34,7 @@ frame-support = { workspace = true, default-features = true } frame-election-provider-support = { workspace = true, default-features = true } pallet-election-provider-multi-phase = { workspace = true, default-features = true } +pallet-stake-tracker = { workspace = true, default-features = true } pallet-staking = { workspace = true, default-features = true } pallet-nomination-pools = { workspace = true, default-features = true } pallet-bags-list = { workspace = true, default-features = true } @@ -51,6 +52,7 @@ try-runtime = [ "pallet-election-provider-multi-phase/try-runtime", "pallet-nomination-pools/try-runtime", "pallet-session/try-runtime", + "pallet-stake-tracker/try-runtime", "pallet-staking/try-runtime", "pallet-timestamp/try-runtime", "sp-runtime/try-runtime", diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs index e45452c1ddf9..315f2876261e 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs @@ -49,6 +49,7 @@ use pallet_election_provider_multi_phase::{ unsigned::MinerConfig, Call, CurrentPhase, ElectionCompute, GeometricDepositBase, QueuedSolution, SolutionAccuracyOf, }; +use pallet_stake_tracker::VoterUpdateMode; use pallet_staking::StakerStatus; use parking_lot::RwLock; use std::sync::Arc; @@ -70,7 +71,9 @@ frame_support::construct_runtime!( Staking: pallet_staking, Pools: pallet_nomination_pools, Balances: pallet_balances, - BagsList: pallet_bags_list, + VoterBagsList: pallet_bags_list::, + TargetBagsList: pallet_bags_list::, + StakeTracker: pallet_stake_tracker, Session: pallet_session, Historical: pallet_session::historical, Timestamp: pallet_timestamp, @@ -80,7 +83,7 @@ frame_support::construct_runtime!( pub(crate) type AccountId = u64; pub(crate) type AccountIndex = u32; pub(crate) type BlockNumber = u32; -pub(crate) type Balance = u64; +pub(crate) type Balance = u128; pub(crate) type VoterIndex = u16; pub(crate) type TargetIndex = u16; pub(crate) type Moment = u32; @@ -103,6 +106,7 @@ parameter_types! { #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Runtime { + type Balance = Balance; type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type MaxFreezes = VariantCountOf; @@ -221,23 +225,47 @@ impl MinerConfig for Runtime { } } -const THRESHOLDS: [VoteWeight; 9] = [10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000]; +const VOTERS_THRESHOLDS: [VoteWeight; 9] = [10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000]; +const TARGETS_THRESHOLDS: [u128; 9] = [10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000]; parameter_types! { - pub static BagThresholds: &'static [sp_npos_elections::VoteWeight] = &THRESHOLDS; + pub static VoterBagThresholds: &'static [VoteWeight] = &VOTERS_THRESHOLDS; + pub static TargetBagThresholds: &'static [u128] = &TARGETS_THRESHOLDS; pub const SessionsPerEra: sp_staking::SessionIndex = 2; pub static BondingDuration: sp_staking::EraIndex = 28; pub const SlashDeferDuration: sp_staking::EraIndex = 7; // 1/4 the bonding duration. } -impl pallet_bags_list::Config for Runtime { +type VoterBagsListInstance = pallet_bags_list::Instance1; +impl pallet_bags_list::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); type ScoreProvider = Staking; - type BagThresholds = BagThresholds; + type BagThresholds = VoterBagThresholds; type Score = VoteWeight; } +type TargetBagsListInstance = pallet_bags_list::Instance2; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type ScoreProvider = pallet_bags_list::Pallet; + type BagThresholds = TargetBagThresholds; + type Score = Balance; +} + +parameter_types! { + pub static UpdateMode: VoterUpdateMode = VoterUpdateMode::Lazy; +} + +impl pallet_stake_tracker::Config for Runtime { + type Currency = Balances; + type Staking = Staking; + type VoterList = VoterBagsList; + type TargetList = TargetBagsList; + type VoterUpdateMode = UpdateMode; +} + pub struct BalanceToU256; impl sp_runtime::traits::Convert for BalanceToU256 { fn convert(n: Balance) -> sp_core::U256 { @@ -274,15 +302,16 @@ impl pallet_nomination_pools::Config for Runtime { type AdminOrigin = frame_system::EnsureRoot; } -parameter_types! { - pub static MaxUnlockingChunks: u32 = 32; -} - /// Upper limit on the number of NPOS nominations. const MAX_QUOTA_NOMINATIONS: u32 = 16; + /// Disabling factor set explicitly to byzantine threshold pub(crate) const SLASHING_DISABLING_FACTOR: usize = 3; +parameter_types! { + pub static MaxUnlockingChunks: u32 = 32; +} + #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Runtime { type Currency = Balances; @@ -298,11 +327,11 @@ impl pallet_staking::Config for Runtime { type MaxExposurePageSize = ConstU32<256>; type ElectionProvider = ElectionProviderMultiPhase; type GenesisElectionProvider = onchain::OnChainExecution; - type VoterList = BagsList; + type VoterList = VoterBagsList; type NominationsQuota = pallet_staking::FixedNominationsQuota; - type TargetList = pallet_staking::UseValidatorsMap; + type TargetList = TargetBagsList; type MaxUnlockingChunks = MaxUnlockingChunks; - type EventListeners = Pools; + type EventListeners = (StakeTracker, Pools); type WeightInfo = pallet_staking::weights::SubstrateWeight; type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; @@ -579,7 +608,7 @@ impl ExtBuilder { let mut ext = sp_io::TestExternalities::from(storage); - // We consider all test to start after timestamp is initialized This must be ensured by + // We consider all test to start after timestamp is initialized. This must be ensured by // having `timestamp::on_initialize` called before `staking::on_initialize`. ext.execute_with(|| { System::set_block_number(1); diff --git a/substrate/frame/election-provider-support/src/lib.rs b/substrate/frame/election-provider-support/src/lib.rs index 394f58a38442..3e72e5462f03 100644 --- a/substrate/frame/election-provider-support/src/lib.rs +++ b/substrate/frame/election-provider-support/src/lib.rs @@ -569,9 +569,19 @@ pub trait SortedListProvider { /// unbounded amount of storage accesses. fn unsafe_clear(); + /// Returns whether the `id` is in the correct bag, given its score. + /// + /// Returns a boolean and it is only available in the context of `try-runtime` checks. + #[cfg(feature = "try-runtime")] + fn in_position(_id: &AccountId) -> Result { + unimplemented!() + } + /// Check internal state of the list. Only meant for debugging. #[cfg(feature = "try-runtime")] - fn try_state() -> Result<(), TryRuntimeError>; + fn try_state() -> Result<(), TryRuntimeError> { + Ok(()) + } /// If `who` changes by the returned amount they are guaranteed to have a worst case change /// in their list position. diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index 757052e230a1..3813e2e3ec14 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -225,6 +225,7 @@ impl ExtBuilder { .map(|(stash, _, balance)| (stash, balance * 2)) .chain(validators_range.clone().map(|x| (x, 7 + 100))) .chain(nominators_range.clone().map(|x| (x, 7 + 100))) + .chain(vec![(42, 100_000)].into_iter()) .collect::>(), } .assimilate_storage(&mut storage); @@ -234,8 +235,10 @@ impl ExtBuilder { .unexposed .into_iter() .map(|(x, y, z)| (x, y, z, pallet_staking::StakerStatus::Nominator(vec![42]))) - .chain(validators_range.map(|x| (x, x, 100, StakerStatus::Validator))) .chain(nominators_range.map(|x| (x, x, 100, StakerStatus::Nominator(vec![x])))) + .chain(validators_range.map(|x| (x, x, 100, StakerStatus::Validator))) + .chain(vec![(42, 42, 107, pallet_staking::StakerStatus::Validator)].into_iter()) + .rev() // validators need to set intention to validate before being nominated. .collect::>(), ..Default::default() } diff --git a/substrate/frame/fast-unstake/src/tests.rs b/substrate/frame/fast-unstake/src/tests.rs index 77128872f285..713d901a27b8 100644 --- a/substrate/frame/fast-unstake/src/tests.rs +++ b/substrate/frame/fast-unstake/src/tests.rs @@ -816,19 +816,19 @@ mod on_idle { CurrentEra::::put(BondingDuration::get()); // create a new validator that 100% not exposed. - Balances::make_free_balance_be(&42, 100 + Deposit::get()); - assert_ok!(Staking::bond(RuntimeOrigin::signed(42), 10, RewardDestination::Staked)); - assert_ok!(Staking::validate(RuntimeOrigin::signed(42), Default::default())); + Balances::make_free_balance_be(&43, 100 + Deposit::get()); + assert_ok!(Staking::bond(RuntimeOrigin::signed(43), 10, RewardDestination::Staked)); + assert_ok!(Staking::validate(RuntimeOrigin::signed(43), Default::default())); // let them register: - assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(42))); + assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(43))); // 2 block's enough to unstake them. next_block(true); assert_eq!( Head::::get(), Some(UnstakeRequest { - stashes: bounded_vec![(42, Deposit::get())], + stashes: bounded_vec![(43, Deposit::get())], checked: bounded_vec![3, 2, 1, 0] }) ); @@ -839,7 +839,7 @@ mod on_idle { fast_unstake_events_since_last_call(), vec![ Event::BatchChecked { eras: vec![3, 2, 1, 0] }, - Event::Unstaked { stash: 42, result: Ok(()) }, + Event::Unstaked { stash: 43, result: Ok(()) }, Event::BatchFinished { size: 1 } ] ); diff --git a/substrate/frame/nomination-pools/benchmarking/src/inner.rs b/substrate/frame/nomination-pools/benchmarking/src/inner.rs index 2a4559425111..28ad3800b5df 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/inner.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/inner.rs @@ -109,6 +109,15 @@ fn create_pool_account( (pool_creator, pool_account) } +// Set an account as validator. +fn add_targets(targets: Vec) { + use frame_election_provider_support::ElectionDataProvider; + + for t in targets.into_iter() { + pallet_staking::Pallet::::add_target(t); + } +} + fn migrate_to_transfer_stake(pool_id: PoolId) { if T::StakeAdapter::strategy_type() == StakeStrategyType::Transfer { // should already be in the correct strategy @@ -185,19 +194,15 @@ impl ListScenario { let (pool_creator1, pool_origin1) = create_pool_account::(USER_SEED + 1, origin_weight, Some(Perbill::from_percent(50))); - T::StakeAdapter::nominate( - Pool::from(pool_origin1.clone()), - // NOTE: these don't really need to be validators. - vec![account("random_validator", 0, USER_SEED)], - )?; + let target: T::AccountId = account("random_validator", 0, USER_SEED); + add_targets::(vec![target.clone()]); + + T::StakeAdapter::nominate(Pool::from(pool_origin1.clone()), vec![target.clone()])?; let (_, pool_origin2) = create_pool_account::(USER_SEED + 2, origin_weight, Some(Perbill::from_percent(50))); - T::StakeAdapter::nominate( - Pool::from(pool_origin2.clone()), - vec![account("random_validator", 0, USER_SEED)].clone(), - )?; + T::StakeAdapter::nominate(Pool::from(pool_origin2.clone()), vec![target.clone()])?; // Find a destination weight that will trigger the worst case scenario let dest_weight_as_vote = ::VoterList::score_update_worst_case( @@ -212,10 +217,7 @@ impl ListScenario { let (_, pool_dest1) = create_pool_account::(USER_SEED + 3, dest_weight, Some(Perbill::from_percent(50))); - T::StakeAdapter::nominate( - Pool::from(pool_dest1.clone()), - vec![account("random_validator", 0, USER_SEED)], - )?; + T::StakeAdapter::nominate(Pool::from(pool_dest1.clone()), vec![target.clone()])?; let weight_of = pallet_staking::Pallet::::weight_of_fn(); assert_eq!(vote_to_balance::(weight_of(&pool_origin1)).unwrap(), origin_weight); @@ -613,12 +615,14 @@ frame_benchmarking::benchmarks! { let min_create_bond = Pools::::depositor_min_bond() * 2u32.into(); let (depositor, pool_account) = create_pool_account::(0, min_create_bond, None); - // Create some accounts to nominate. For the sake of benchmarking they don't need to be - // actual validators + // Create some accounts to nominate. let validators: Vec<_> = (0..n) .map(|i| account("stash", USER_SEED, i)) .collect(); + // Ensure the nominations are all active targets. + add_targets::(validators.clone()); + whitelist_account!(depositor); }:_(RuntimeOrigin::Signed(depositor.clone()), 1, validators) verify { @@ -726,6 +730,9 @@ frame_benchmarking::benchmarks! { .map(|i| account("stash", USER_SEED, i)) .collect(); + // Ensure the nominations are all active targets. + add_targets::(validators.clone()); + assert_ok!(T::StakeAdapter::nominate(Pool::from(pool_account.clone()), validators)); assert!(T::StakeAdapter::nominations(Pool::from(pool_account.clone())).is_some()); diff --git a/substrate/frame/nomination-pools/test-delegate-stake/Cargo.toml b/substrate/frame/nomination-pools/test-delegate-stake/Cargo.toml index 7940caaff775..59ca5a5e5190 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/Cargo.toml +++ b/substrate/frame/nomination-pools/test-delegate-stake/Cargo.toml @@ -31,6 +31,7 @@ frame-election-provider-support = { workspace = true, default-features = true } pallet-timestamp = { workspace = true, default-features = true } pallet-balances = { workspace = true, default-features = true } +pallet-stake-tracker = { workspace = true, default-features = true } pallet-staking = { workspace = true, default-features = true } pallet-delegated-staking = { workspace = true, default-features = true } pallet-bags-list = { workspace = true, default-features = true } diff --git a/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs index 51f6470f90d0..7bdeefff1896 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs @@ -920,9 +920,6 @@ fn pool_migration_e2e() { assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); assert_eq!(LastPoolId::::get(), 1); - // have the pool nominate. - assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); - assert_eq!( staking_events_since_last_call(), vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 50 }] diff --git a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs index ed47932a323b..b4f9330502be 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs @@ -102,10 +102,22 @@ impl pallet_staking::Config for Runtime { type GenesisElectionProvider = Self::ElectionProvider; type VoterList = VoterList; type TargetList = pallet_staking::UseValidatorsMap; - type EventListeners = (Pools, DelegatedStaking); + type EventListeners = (StakeTracker, Pools, DelegatedStaking); type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; } +parameter_types! { + pub static VoterUpdateMode: pallet_stake_tracker::VoterUpdateMode = pallet_stake_tracker::VoterUpdateMode::Lazy; +} + +impl pallet_stake_tracker::Config for Runtime { + type Currency = Balances; + type Staking = Staking; + type VoterList = VoterList; + type TargetList = pallet_staking::UseValidatorsMap; + type VoterUpdateMode = VoterUpdateMode; +} + parameter_types! { pub static BagThresholds: &'static [VoteWeight] = &[10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000]; } @@ -279,6 +291,7 @@ frame_support::construct_runtime!( Balances: pallet_balances, Staking: pallet_staking, VoterList: pallet_bags_list::, + StakeTracker: pallet_stake_tracker, Pools: pallet_nomination_pools, DelegatedStaking: pallet_delegated_staking, } @@ -299,7 +312,18 @@ pub fn new_test_ext() -> sp_io::TestExternalities { .unwrap(); let _ = pallet_balances::GenesisConfig:: { - balances: vec![(10, 100), (20, 100), (21, 100), (22, 100)], + balances: vec![(1, 200), (2, 200), (3, 200), (10, 100), (20, 100), (21, 100), (22, 100)], + } + .assimilate_storage(&mut storage) + .unwrap(); + + let _ = pallet_staking::GenesisConfig:: { + stakers: vec![ + (1, 1, 100, pallet_staking::StakerStatus::Validator), + (2, 2, 100, pallet_staking::StakerStatus::Validator), + (3, 3, 100, pallet_staking::StakerStatus::Validator), + ], + ..Default::default() } .assimilate_storage(&mut storage) .unwrap(); diff --git a/substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml b/substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml index 7398404c2351..b9b3a8b543d8 100644 --- a/substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml +++ b/substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml @@ -31,6 +31,7 @@ frame-election-provider-support = { workspace = true, default-features = true } pallet-timestamp = { workspace = true, default-features = true } pallet-balances = { workspace = true, default-features = true } +pallet-stake-tracker = { workspace = true, default-features = true } pallet-staking = { workspace = true, default-features = true } pallet-bags-list = { workspace = true, default-features = true } pallet-staking-reward-curve = { workspace = true, default-features = true } diff --git a/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs index d913c5fe6948..a1129d62cdf5 100644 --- a/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs @@ -94,10 +94,22 @@ impl pallet_staking::Config for Runtime { type GenesisElectionProvider = Self::ElectionProvider; type VoterList = VoterList; type TargetList = pallet_staking::UseValidatorsMap; - type EventListeners = Pools; + type EventListeners = (StakeTracker, Pools); type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; } +parameter_types! { + pub static VoterUpdateMode: pallet_stake_tracker::VoterUpdateMode = pallet_stake_tracker::VoterUpdateMode::Lazy; +} + +impl pallet_stake_tracker::Config for Runtime { + type Currency = Balances; + type Staking = Staking; + type VoterList = VoterList; + type TargetList = pallet_staking::UseValidatorsMap; + type VoterUpdateMode = VoterUpdateMode; +} + parameter_types! { pub static BagThresholds: &'static [VoteWeight] = &[10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000]; } @@ -156,6 +168,7 @@ frame_support::construct_runtime!( Balances: pallet_balances, Staking: pallet_staking, VoterList: pallet_bags_list::, + StakeTracker: pallet_stake_tracker, Pools: pallet_nomination_pools, } ); @@ -175,7 +188,18 @@ pub fn new_test_ext() -> sp_io::TestExternalities { .unwrap(); let _ = pallet_balances::GenesisConfig:: { - balances: vec![(10, 100), (20, 100), (21, 100), (22, 100)], + balances: vec![(1, 200), (2, 200), (3, 200), (10, 100), (20, 100), (21, 100), (22, 100)], + } + .assimilate_storage(&mut storage) + .unwrap(); + + let _ = pallet_staking::GenesisConfig:: { + stakers: vec![ + (1, 1, 100, pallet_staking::StakerStatus::Validator), + (2, 2, 100, pallet_staking::StakerStatus::Validator), + (3, 3, 100, pallet_staking::StakerStatus::Validator), + ], + ..Default::default() } .assimilate_storage(&mut storage) .unwrap(); diff --git a/substrate/frame/staking/Cargo.toml b/substrate/frame/staking/Cargo.toml index a6a0ccd3b0a7..9da5e8166b2c 100644 --- a/substrate/frame/staking/Cargo.toml +++ b/substrate/frame/staking/Cargo.toml @@ -26,12 +26,12 @@ sp-runtime = { features = ["serde"], workspace = true } sp-staking = { features = ["serde"], workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } -pallet-session = { features = [ - "historical", -], workspace = true } +pallet-session = { features = ["historical"], workspace = true } pallet-authorship = { workspace = true } +pallet-stake-tracker = { workspace = true } +pallet-migrations = { workspace = true } sp-application-crypto = { features = ["serde"], workspace = true } -frame-election-provider-support = { workspace = true } +frame-election-provider-support = { workspace = true, default-features = false, features = ["try-runtime"] } log = { workspace = true } # Optional imports for benchmarking @@ -43,12 +43,12 @@ pallet-balances = { workspace = true, default-features = true } sp-tracing = { workspace = true, default-features = true } sp-core = { workspace = true, default-features = true } sp-npos-elections = { workspace = true, default-features = true } +sp-staking = { features = ["serde", "test-utils"], default-features = false, workspace = true } pallet-timestamp = { workspace = true, default-features = true } pallet-staking-reward-curve = { workspace = true, default-features = true } -pallet-bags-list = { workspace = true, default-features = true } +pallet-bags-list = { workspace = true, default-features = false, features = ["try-runtime"] } substrate-test-utils = { workspace = true } frame-benchmarking = { workspace = true, default-features = true } -frame-election-provider-support = { workspace = true, default-features = true } rand_chacha = { workspace = true, default-features = true } [features] @@ -63,7 +63,9 @@ std = [ "pallet-authorship/std", "pallet-bags-list/std", "pallet-balances/std", + "pallet-migrations/std", "pallet-session/std", + "pallet-stake-tracker/std", "pallet-timestamp/std", "scale-info/std", "serde/std", @@ -82,6 +84,8 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-bags-list/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-migrations/runtime-benchmarks", + "pallet-stake-tracker/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "rand_chacha", "sp-runtime/runtime-benchmarks", @@ -94,7 +98,9 @@ try-runtime = [ "pallet-authorship/try-runtime", "pallet-bags-list/try-runtime", "pallet-balances/try-runtime", + "pallet-migrations/try-runtime", "pallet-session/try-runtime", + "pallet-stake-tracker/try-runtime", "pallet-timestamp/try-runtime", "sp-runtime/try-runtime", ] diff --git a/substrate/frame/staking/src/benchmarking.rs b/substrate/frame/staking/src/benchmarking.rs index 1f8580d7a3e6..7592576d78fd 100644 --- a/substrate/frame/staking/src/benchmarking.rs +++ b/substrate/frame/staking/src/benchmarking.rs @@ -18,25 +18,29 @@ //! Staking pallet benchmarking. use super::*; -use crate::{ConfigOp, Pallet as Staking}; +use crate::{migrations::v13_stake_tracker as v13, ConfigOp, Pallet as Staking}; use testing_utils::*; use codec::Decode; use frame_election_provider_support::{bounds::DataProviderBounds, SortedListProvider}; use frame_support::{ + assert_ok, + migrations::SteppedMigration, pallet_prelude::*, storage::bounded_vec::BoundedVec, traits::{Currency, Get, Imbalance, UnfilteredDispatchable}, + weights::WeightMeter, }; use sp_runtime::{ traits::{Bounded, One, StaticLookup, TrailingZeroInput, Zero}, Perbill, Percent, Saturating, }; -use sp_staking::{currency_to_vote::CurrencyToVote, SessionIndex}; +use sp_staking::{currency_to_vote::CurrencyToVote, SessionIndex, StakingInterface}; pub use frame_benchmarking::v1::{ - account, benchmarks, impl_benchmark_test_suite, whitelist_account, whitelisted_caller, + account, impl_benchmark_test_suite, whitelist_account, whitelisted_caller, BenchmarkError, }; +use frame_benchmarking::v2::*; use frame_system::RawOrigin; const SEED: u32 = 0; @@ -166,21 +170,26 @@ impl ListScenario { fn new(origin_weight: BalanceOf, is_increase: bool) -> Result { ensure!(!origin_weight.is_zero(), "origin weight must be greater than 0"); + // validator to nominate. + let validator = create_validators_with_seed::(1, 100, 42)? + .pop() + .expect("validator should exist"); + // burn the entire issuance. let i = T::Currency::burn(T::Currency::total_issuance()); core::mem::forget(i); // create accounts with the origin weight - let (origin_stash1, origin_controller1) = create_stash_controller_with_balance::( USER_SEED + 2, origin_weight, RewardDestination::Staked, )?; + Staking::::nominate( RawOrigin::Signed(origin_controller1.clone()).into(), - // NOTE: these don't really need to be validators. - vec![T::Lookup::unlookup(account("random_validator", 0, SEED))], + // NOTE: these *do* really need to be validators. + vec![validator.clone()], )?; let (_origin_stash2, origin_controller2) = create_stash_controller_with_balance::( @@ -188,9 +197,10 @@ impl ListScenario { origin_weight, RewardDestination::Staked, )?; + Staking::::nominate( RawOrigin::Signed(origin_controller2).into(), - vec![T::Lookup::unlookup(account("random_validator", 0, SEED))], + vec![validator.clone()], )?; // find a destination weight that will trigger the worst case scenario @@ -208,10 +218,7 @@ impl ListScenario { dest_weight, RewardDestination::Staked, )?; - Staking::::nominate( - RawOrigin::Signed(dest_controller1).into(), - vec![T::Lookup::unlookup(account("random_validator", 0, SEED))], - )?; + Staking::::nominate(RawOrigin::Signed(dest_controller1).into(), vec![validator])?; Ok(ListScenario { origin_stash1, origin_controller1, dest_weight }) } @@ -219,19 +226,26 @@ impl ListScenario { const USER_SEED: u32 = 999666; -benchmarks! { - bond { +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn bond() { let stash = create_funded_user::("stash", USER_SEED, 100); let reward_destination = RewardDestination::Staked; let amount = T::Currency::minimum_balance() * 10u32.into(); whitelist_account!(stash); - }: _(RawOrigin::Signed(stash.clone()), amount, reward_destination) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(stash.clone()), amount, reward_destination); + assert!(Bonded::::contains_key(stash.clone())); assert!(Ledger::::contains_key(stash)); } - bond_extra { + #[benchmark] + fn bond_extra() -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); @@ -246,25 +260,31 @@ benchmarks! { let stash = scenario.origin_stash1.clone(); let controller = scenario.origin_controller1; - let original_bonded: BalanceOf - = Ledger::::get(&controller).map(|l| l.active).ok_or("ledger not created after")?; + let original_bonded: BalanceOf = Ledger::::get(&controller) + .map(|l| l.active) + .ok_or("ledger not created after")?; let _ = T::Currency::deposit_into_existing(&stash, max_additional).unwrap(); whitelist_account!(stash); - }: _(RawOrigin::Signed(stash), max_additional) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(stash), max_additional); + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; let new_bonded: BalanceOf = ledger.active; assert!(original_bonded < new_bonded); + + Ok(()) } - unbond { + #[benchmark] + fn unbond() -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); // setup the worst case list scenario. - let total_issuance = T::Currency::total_issuance(); + let _total_issuance = T::Currency::total_issuance(); // the weight the nominator will start at. The value used here is expected to be // significantly higher than the first position in a list (e.g. the first bag threshold). let origin_weight = BalanceOf::::try_from(952_994_955_240_703u128) @@ -272,24 +292,28 @@ benchmarks! { .unwrap(); let scenario = ListScenario::::new(origin_weight, false)?; - let stash = scenario.origin_stash1.clone(); + let _stash = scenario.origin_stash1.clone(); let controller = scenario.origin_controller1.clone(); let amount = origin_weight - scenario.dest_weight; let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; let original_bonded: BalanceOf = ledger.active; whitelist_account!(controller); - }: _(RawOrigin::Signed(controller.clone()), amount) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller.clone()), amount); + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; let new_bonded: BalanceOf = ledger.active; assert!(original_bonded > new_bonded); + + Ok(()) } // Withdraw only updates the ledger - withdraw_unbonded_update { + #[benchmark] + fn withdraw_unbonded_update(s: Linear<0, MAX_SPANS>) -> Result<(), BenchmarkError> { // Slashing Spans - let s in 0 .. MAX_SPANS; let (stash, controller) = create_stash_controller::(0, 100, RewardDestination::Staked)?; add_slashing_spans::(&stash, s); let amount = T::Currency::minimum_balance() * 5u32.into(); // Half of total @@ -298,17 +322,20 @@ benchmarks! { let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; let original_total: BalanceOf = ledger.total; whitelist_account!(controller); - }: withdraw_unbonded(RawOrigin::Signed(controller.clone()), s) - verify { + + #[extrinsic_call] + withdraw_unbonded(RawOrigin::Signed(controller.clone()), s); + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; let new_total: BalanceOf = ledger.total; assert!(original_total > new_total); + + Ok(()) } // Worst case scenario, everything is removed after the bonding duration - withdraw_unbonded_kill { - // Slashing Spans - let s in 0 .. MAX_SPANS; + #[benchmark] + fn withdraw_unbonded_kill(s: Linear<0, MAX_SPANS>) -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); @@ -329,13 +356,18 @@ benchmarks! { CurrentEra::::put(EraIndex::max_value()); whitelist_account!(controller); - }: withdraw_unbonded(RawOrigin::Signed(controller.clone()), s) - verify { + + #[extrinsic_call] + withdraw_unbonded(RawOrigin::Signed(controller.clone()), s); + assert!(!Ledger::::contains_key(controller)); assert!(!T::VoterList::contains(&stash)); + + Ok(()) } - validate { + #[benchmark] + fn validate() -> Result<(), BenchmarkError> { let (stash, controller) = create_stash_controller::( MaxNominationsOf::::get() - 1, 100, @@ -346,22 +378,26 @@ benchmarks! { let prefs = ValidatorPrefs::default(); whitelist_account!(controller); - }: _(RawOrigin::Signed(controller), prefs) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller), prefs); + assert!(Validators::::contains_key(&stash)); assert!(T::VoterList::contains(&stash)); - } - kick { - // scenario: we want to kick `k` nominators from nominating us (we are a validator). - // we'll assume that `k` is under 128 for the purposes of determining the slope. - // each nominator should have `T::MaxNominations::get()` validators nominated, and our validator - // should be somewhere in there. - let k in 1 .. 128; + Ok(()) + } + // scenario: we want to kick `k` nominators from nominating us (we are a validator). + // we'll assume that `k` is under 128 for the purposes of determining the slope. + // each nominator should have `T::MaxNominations::get()` validators nominated, and our validator + // should be somewhere in there. + #[benchmark] + fn kick(k: Linear<1, 128>) -> Result<(), BenchmarkError> { // these are the other validators; there are `T::MaxNominations::get() - 1` of them, so // there are a total of `T::MaxNominations::get()` validators in the system. - let rest_of_validators = create_validators_with_seed::(MaxNominationsOf::::get() - 1, 100, 415)?; + let rest_of_validators = + create_validators_with_seed::(MaxNominationsOf::::get() - 1, 100, 415)?; // this is the validator that will be kicking. let (stash, controller) = create_stash_controller::( @@ -377,7 +413,7 @@ benchmarks! { // we now create the nominators. there will be `k` of them; each will nominate all // validators. we will then kick each of the `k` nominators from the main validator. let mut nominator_stashes = Vec::with_capacity(k as usize); - for i in 0 .. k { + for i in 0..k { // create a nominator stash. let (n_stash, n_controller) = create_stash_controller::( MaxNominationsOf::::get() + i, @@ -402,49 +438,60 @@ benchmarks! { } // we need the unlookuped version of the nominator stash for the kick. - let kicks = nominator_stashes.iter() + let kicks = nominator_stashes + .iter() .map(|n| T::Lookup::unlookup(n.clone())) .collect::>(); whitelist_account!(controller); - }: _(RawOrigin::Signed(controller), kicks) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller), kicks); + // all nominators now should *not* be nominating our validator... for n in nominator_stashes.iter() { assert!(!Nominators::::get(n).unwrap().targets.contains(&stash)); } + + Ok(()) } // Worst case scenario, T::MaxNominations::get() - nominate { - let n in 1 .. MaxNominationsOf::::get(); - + #[benchmark] + fn nominate(n: Linear<1, { MaxNominationsOf::::get() }>) -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); let origin_weight = MinNominatorBond::::get().max(T::Currency::minimum_balance()); - // setup a worst case list scenario. Note we don't care about the destination position, because - // we are just doing an insert into the origin position. - let scenario = ListScenario::::new(origin_weight, true)?; + // setup a worst case list scenario. Note we don't care about the destination position, + // because we are just doing an insert into the origin position. + let _scenario = ListScenario::::new(origin_weight, true)?; let (stash, controller) = create_stash_controller_with_balance::( - SEED + MaxNominationsOf::::get() + 1, // make sure the account does not conflict with others + SEED + MaxNominationsOf::::get() + 1, /* make sure the account does not conflict + * with others */ origin_weight, RewardDestination::Staked, - ).unwrap(); + ) + .unwrap(); assert!(!Nominators::::contains_key(&stash)); assert!(!T::VoterList::contains(&stash)); let validators = create_validators::(n, 100).unwrap(); whitelist_account!(controller); - }: _(RawOrigin::Signed(controller), validators) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller), validators); + assert!(Nominators::::contains_key(&stash)); - assert!(T::VoterList::contains(&stash)) + assert!(T::VoterList::contains(&stash)); + + Ok(()) } - chill { + #[benchmark] + fn chill() -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); @@ -458,94 +505,130 @@ benchmarks! { assert!(T::VoterList::contains(&stash)); whitelist_account!(controller); - }: _(RawOrigin::Signed(controller)) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller)); + assert!(!T::VoterList::contains(&stash)); + + Ok(()) } - set_payee { - let (stash, controller) = create_stash_controller::(USER_SEED, 100, RewardDestination::Staked)?; + #[benchmark] + fn set_payee() -> Result<(), BenchmarkError> { + let (stash, controller) = + create_stash_controller::(USER_SEED, 100, RewardDestination::Staked)?; assert_eq!(Payee::::get(&stash), Some(RewardDestination::Staked)); whitelist_account!(controller); - }: _(RawOrigin::Signed(controller.clone()), RewardDestination::Account(controller.clone())) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller.clone()), RewardDestination::Account(controller.clone())); + assert_eq!(Payee::::get(&stash), Some(RewardDestination::Account(controller))); + + Ok(()) } - update_payee { - let (stash, controller) = create_stash_controller::(USER_SEED, 100, RewardDestination::Staked)?; + #[benchmark] + fn update_payee() -> Result<(), BenchmarkError> { + let (stash, controller) = + create_stash_controller::(USER_SEED, 100, RewardDestination::Staked)?; Payee::::insert(&stash, { #[allow(deprecated)] RewardDestination::Controller }); whitelist_account!(controller); - }: _(RawOrigin::Signed(controller.clone()), controller.clone()) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller.clone()), controller.clone()); + assert_eq!(Payee::::get(&stash), Some(RewardDestination::Account(controller))); + + Ok(()) } - set_controller { - let (stash, ctlr) = create_unique_stash_controller::(9000, 100, RewardDestination::Staked, false)?; + #[benchmark] + fn set_controller() -> Result<(), BenchmarkError> { + let (stash, ctlr) = + create_unique_stash_controller::(9000, 100, RewardDestination::Staked, false)?; // ensure `ctlr` is the currently stored controller. assert!(!Ledger::::contains_key(&stash)); assert!(Ledger::::contains_key(&ctlr)); assert_eq!(Bonded::::get(&stash), Some(ctlr.clone())); whitelist_account!(stash); - }: _(RawOrigin::Signed(stash.clone())) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(stash.clone())); + assert!(Ledger::::contains_key(&stash)); + + Ok(()) } - set_validator_count { + #[benchmark] + fn set_validator_count() { let validator_count = MaxValidators::::get(); - }: _(RawOrigin::Root, validator_count) - verify { + + #[extrinsic_call] + _(RawOrigin::Root, validator_count); + assert_eq!(ValidatorCount::::get(), validator_count); } - force_no_eras {}: _(RawOrigin::Root) - verify { assert_eq!(ForceEra::::get(), Forcing::ForceNone); } + #[benchmark] + fn force_no_eras() { + #[extrinsic_call] + _(RawOrigin::Root); + assert_eq!(ForceEra::::get(), Forcing::ForceNone); + } - force_new_era {}: _(RawOrigin::Root) - verify { assert_eq!(ForceEra::::get(), Forcing::ForceNew); } + #[benchmark] + fn force_new_era() { + #[extrinsic_call] + _(RawOrigin::Root); + assert_eq!(ForceEra::::get(), Forcing::ForceNew); + } - force_new_era_always {}: _(RawOrigin::Root) - verify { assert_eq!(ForceEra::::get(), Forcing::ForceAlways); } + #[benchmark] + fn force_new_era_always() { + #[extrinsic_call] + _(RawOrigin::Root); + assert_eq!(ForceEra::::get(), Forcing::ForceAlways); + } // Worst case scenario, the list of invulnerables is very long. - set_invulnerables { - let v in 0 .. MaxValidators::::get(); + #[benchmark] + fn set_invulnerables(v: Linear<0, { MaxValidators::::get() }>) { let mut invulnerables = Vec::new(); - for i in 0 .. v { + for i in 0..v { invulnerables.push(account("invulnerable", i, SEED)); } - }: _(RawOrigin::Root, invulnerables) - verify { + + #[extrinsic_call] + _(RawOrigin::Root, invulnerables); + assert_eq!(Invulnerables::::get().len(), v as usize); } - deprecate_controller_batch { - // We pass a dynamic number of controllers to the benchmark, up to - // `MaxControllersInDeprecationBatch`. - let i in 0 .. T::MaxControllersInDeprecationBatch::get(); - + #[benchmark] + fn deprecate_controller_batch( + i: Linear<0, { T::MaxControllersInDeprecationBatch::get() }>, + ) -> Result<(), BenchmarkError> { let mut controllers: Vec<_> = vec![]; let mut stashes: Vec<_> = vec![]; for n in 0..i as u32 { - let (stash, controller) = create_unique_stash_controller::( - n, - 100, - RewardDestination::Staked, - false - )?; + let (stash, controller) = + create_unique_stash_controller::(n, 100, RewardDestination::Staked, false)?; controllers.push(controller); stashes.push(stash); } let bounded_controllers: BoundedVec<_, T::MaxControllersInDeprecationBatch> = BoundedVec::try_from(controllers.clone()).unwrap(); - }: _(RawOrigin::Root, bounded_controllers) - verify { + + #[extrinsic_call] + _(RawOrigin::Root, bounded_controllers); + for n in 0..i as u32 { let stash = &stashes[n as usize]; let controller = &controllers[n as usize]; @@ -556,11 +639,12 @@ benchmarks! { // Ledger is now keyed by stash. assert_eq!(Ledger::::get(stash).unwrap().stash, *stash); } + + Ok(()) } - force_unstake { - // Slashing Spans - let s in 0 .. MAX_SPANS; + #[benchmark] + fn force_unstake(s: Linear<0, MAX_SPANS>) -> Result<(), BenchmarkError> { // Clean up any existing state. clear_validators_and_nominators::(); @@ -574,30 +658,38 @@ benchmarks! { assert!(T::VoterList::contains(&stash)); add_slashing_spans::(&stash, s); - }: _(RawOrigin::Root, stash.clone(), s) - verify { + #[extrinsic_call] + _(RawOrigin::Root, stash.clone(), s); + assert!(!Ledger::::contains_key(&controller)); assert!(!T::VoterList::contains(&stash)); + + Ok(()) } - cancel_deferred_slash { - let s in 1 .. MAX_SLASHES; + #[benchmark] + fn cancel_deferred_slash(s: Linear<1, MAX_SLASHES>) { let mut unapplied_slashes = Vec::new(); let era = EraIndex::one(); let dummy = || T::AccountId::decode(&mut TrailingZeroInput::zeroes()).unwrap(); - for _ in 0 .. MAX_SLASHES { - unapplied_slashes.push(UnappliedSlash::>::default_from(dummy())); + for _ in 0..MAX_SLASHES { + unapplied_slashes + .push(UnappliedSlash::>::default_from(dummy())); } UnappliedSlashes::::insert(era, &unapplied_slashes); - let slash_indices: Vec = (0 .. s).collect(); - }: _(RawOrigin::Root, era, slash_indices) - verify { + let slash_indices: Vec = (0..s).collect(); + + #[extrinsic_call] + _(RawOrigin::Root, era, slash_indices); + assert_eq!(UnappliedSlashes::::get(&era).len(), (MAX_SLASHES - s) as usize); } - payout_stakers_alive_staked { - let n in 0 .. T::MaxExposurePageSize::get() as u32; + #[benchmark] + fn payout_stakers_alive_staked( + n: Linear<0, { T::MaxExposurePageSize::get() }>, + ) -> Result<(), BenchmarkError> { let (validator, nominators) = create_validator_with_nominators::( n, T::MaxExposurePageSize::get() as u32, @@ -608,7 +700,11 @@ benchmarks! { let current_era = CurrentEra::::get().unwrap(); // set the commission for this particular era as well. - >::insert(current_era, validator.clone(), >::validators(&validator)); + >::insert( + current_era, + validator.clone(), + >::validators(&validator), + ); let caller = whitelisted_caller(); let balance_before = T::Currency::free_balance(&validator); @@ -617,25 +713,29 @@ benchmarks! { let balance = T::Currency::free_balance(stash); nominator_balances_before.push(balance); } - }: payout_stakers(RawOrigin::Signed(caller), validator.clone(), current_era) - verify { + + #[extrinsic_call] + payout_stakers(RawOrigin::Signed(caller), validator.clone(), current_era); + let balance_after = T::Currency::free_balance(&validator); ensure!( balance_before < balance_after, "Balance of validator stash should have increased after payout.", ); - for ((stash, _), balance_before) in nominators.iter().zip(nominator_balances_before.iter()) { + for ((stash, _), balance_before) in nominators.iter().zip(nominator_balances_before.iter()) + { let balance_after = T::Currency::free_balance(stash); ensure!( balance_before < &balance_after, "Balance of nominator stash should have increased after payout.", ); } - } - rebond { - let l in 1 .. T::MaxUnlockingChunks::get() as u32; + Ok(()) + } + #[benchmark] + fn rebond(l: Linear<1, { T::MaxUnlockingChunks::get() }>) -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); @@ -658,31 +758,32 @@ benchmarks! { // so the sum of unlocking chunks puts voter into the dest bag. assert!(value * l.into() + origin_weight > origin_weight); assert!(value * l.into() + origin_weight <= dest_weight); - let unlock_chunk = UnlockChunk::> { - value, - era: EraIndex::zero(), - }; + let unlock_chunk = UnlockChunk::> { value, era: EraIndex::zero() }; - let stash = scenario.origin_stash1.clone(); + let _921stash = scenario.origin_stash1.clone(); let controller = scenario.origin_controller1; let mut staking_ledger = Ledger::::get(controller.clone()).unwrap(); - for _ in 0 .. l { + for _ in 0..l { staking_ledger.unlocking.try_push(unlock_chunk.clone()).unwrap() } Ledger::::insert(controller.clone(), staking_ledger.clone()); let original_bonded: BalanceOf = staking_ledger.active; whitelist_account!(controller); - }: _(RawOrigin::Signed(controller.clone()), rebond_amount) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller.clone()), rebond_amount); + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; let new_bonded: BalanceOf = ledger.active; assert!(original_bonded < new_bonded); + + Ok(()) } - reap_stash { - let s in 1 .. MAX_SPANS; + #[benchmark] + fn reap_stash(s: Linear<1, MAX_SPANS>) -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); @@ -695,26 +796,25 @@ benchmarks! { let stash = scenario.origin_stash1; add_slashing_spans::(&stash, s); - let l = StakingLedger::::new( - stash.clone(), - T::Currency::minimum_balance() - One::one(), - ); + let l = StakingLedger::::new(stash.clone(), T::Currency::minimum_balance() - One::one()); Ledger::::insert(&controller, l); assert!(Bonded::::contains_key(&stash)); assert!(T::VoterList::contains(&stash)); whitelist_account!(controller); - }: _(RawOrigin::Signed(controller), stash.clone(), s) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(controller), stash.clone(), s); + assert!(!Bonded::::contains_key(&stash)); assert!(!T::VoterList::contains(&stash)); - } - new_era { - let v in 1 .. 10; - let n in 0 .. 100; + Ok(()) + } + #[benchmark] + fn new_era(v: Linear<1, 10>, n: Linear<0, 100>) -> Result<(), BenchmarkError> { create_validators_with_nominators_for_era::( v, n, @@ -723,16 +823,19 @@ benchmarks! { None, )?; let session_index = SessionIndex::one(); - }: { - let validators = Staking::::try_trigger_new_era(session_index, true) - .ok_or("`new_era` failed")?; - assert!(validators.len() == v as usize); + + #[block] + { + let validators = + Staking::::try_trigger_new_era(session_index, true).ok_or("`new_era` failed")?; + assert!(validators.len() == v as usize); + } + + Ok(()) } - #[extra] - payout_all { - let v in 1 .. 10; - let n in 0 .. 100; + #[benchmark(extra)] + fn payout_all(v: Linear<1, 10>, n: Linear<0, 100>) -> Result<(), BenchmarkError> { create_validators_with_nominators_for_era::( v, n, @@ -769,53 +872,71 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let origin = RawOrigin::Signed(caller); - let calls: Vec<_> = payout_calls_arg.iter().map(|arg| - Call::::payout_stakers_by_page { validator_stash: arg.0.clone(), era: arg.1, page: 0 }.encode() - ).collect(); - }: { - for call in calls { - as Decode>::decode(&mut &*call) - .expect("call is encoded above, encoding must be correct") - .dispatch_bypass_filter(origin.clone().into())?; + let calls: Vec<_> = payout_calls_arg + .iter() + .map(|arg| { + Call::::payout_stakers_by_page { + validator_stash: arg.0.clone(), + era: arg.1, + page: 0, + } + .encode() + }) + .collect(); + + #[block] + { + for call in calls { + as Decode>::decode(&mut &*call) + .expect("call is encoded above, encoding must be correct") + .dispatch_bypass_filter(origin.clone().into())?; + } } + + Ok(()) } - #[extra] - do_slash { - let l in 1 .. T::MaxUnlockingChunks::get() as u32; + #[benchmark(extra)] + fn do_slash(l: Linear<1, { T::MaxUnlockingChunks::get() }>) -> Result<(), BenchmarkError> { let (stash, controller) = create_stash_controller::(0, 100, RewardDestination::Staked)?; let mut staking_ledger = Ledger::::get(controller.clone()).unwrap(); - let unlock_chunk = UnlockChunk::> { - value: 1u32.into(), - era: EraIndex::zero(), - }; - for _ in 0 .. l { + let unlock_chunk = + UnlockChunk::> { value: 1u32.into(), era: EraIndex::zero() }; + for _ in 0..l { staking_ledger.unlocking.try_push(unlock_chunk.clone()).unwrap(); } Ledger::::insert(controller, staking_ledger); let slash_amount = T::Currency::minimum_balance() * 10u32.into(); let balance_before = T::Currency::free_balance(&stash); - }: { - crate::slashing::do_slash::( - &stash, - slash_amount, - &mut BalanceOf::::zero(), - &mut NegativeImbalanceOf::::zero(), - EraIndex::zero() - ); - } verify { + + #[block] + { + crate::slashing::do_slash::( + &stash, + slash_amount, + &mut BalanceOf::::zero(), + &mut NegativeImbalanceOf::::zero(), + EraIndex::zero(), + ); + } + let balance_after = T::Currency::free_balance(&stash); assert!(balance_before > balance_after); - } - get_npos_voters { - // number of validator intention. we will iterate all of them. - let v in (MaxValidators::::get() / 2) .. MaxValidators::::get(); - // number of nominator intention. we will iterate all of them. - let n in (MaxNominators::::get() / 2) .. MaxNominators::::get(); + Ok(()) + } - let validators = create_validators_with_nominators_for_era::( - v, n, MaxNominationsOf::::get() as usize, false, None + #[benchmark] + fn get_npos_voters( + v: Linear<{ MaxValidators::::get() / 2 }, { MaxValidators::::get() }>, + n: Linear<{ MaxNominators::::get() / 2 }, { MaxNominators::::get() }>, + ) -> Result<(), BenchmarkError> { + let _validators = create_validators_with_nominators_for_era::( + v, + n, + MaxNominationsOf::::get() as usize, + false, + None, )? .into_iter() .map(|v| T::Lookup::lookup(v).unwrap()) @@ -825,38 +946,56 @@ benchmarks! { assert_eq!(Nominators::::count(), n); let num_voters = (v + n) as usize; - }: { - // default bounds are unbounded. - let voters = >::get_npos_voters(DataProviderBounds::default()); - assert_eq!(voters.len(), num_voters); + + #[block] + { + // default bounds are unbounded. + let voters = >::get_npos_voters(DataProviderBounds::default()); + assert_eq!(voters.len(), num_voters); + } + + Ok(()) } - get_npos_targets { - // number of validator intention. - let v in (MaxValidators::::get() / 2) .. MaxValidators::::get(); + #[benchmark] + fn get_npos_targets( + v: Linear<{ MaxValidators::::get() / 2 }, { MaxValidators::::get() }>, + ) -> Result<(), BenchmarkError> { // number of nominator intention. let n = MaxNominators::::get(); let _ = create_validators_with_nominators_for_era::( - v, n, MaxNominationsOf::::get() as usize, false, None + v, + n, + MaxNominationsOf::::get() as usize, + false, + None, )?; - }: { - // default bounds are unbounded. - let targets = >::get_npos_targets(DataProviderBounds::default()); - assert_eq!(targets.len() as u32, v); + + #[block] + { + // default bounds are unbounded. + let targets = >::get_npos_targets(DataProviderBounds::default()); + assert_eq!(targets.len() as u32, v); + } + + Ok(()) } - set_staking_configs_all_set { - }: set_staking_configs( - RawOrigin::Root, - ConfigOp::Set(BalanceOf::::max_value()), - ConfigOp::Set(BalanceOf::::max_value()), - ConfigOp::Set(u32::MAX), - ConfigOp::Set(u32::MAX), - ConfigOp::Set(Percent::max_value()), - ConfigOp::Set(Perbill::max_value()), - ConfigOp::Set(Percent::max_value()) - ) verify { + #[benchmark] + fn set_staking_configs_all_set() { + #[extrinsic_call] + set_staking_configs( + RawOrigin::Root, + ConfigOp::Set(BalanceOf::::max_value()), + ConfigOp::Set(BalanceOf::::max_value()), + ConfigOp::Set(u32::MAX), + ConfigOp::Set(u32::MAX), + ConfigOp::Set(Percent::max_value()), + ConfigOp::Set(Perbill::max_value()), + ConfigOp::Set(Percent::max_value()), + ); + assert_eq!(MinNominatorBond::::get(), BalanceOf::::max_value()); assert_eq!(MinValidatorBond::::get(), BalanceOf::::max_value()); assert_eq!(MaxNominatorsCount::::get(), Some(u32::MAX)); @@ -866,17 +1005,20 @@ benchmarks! { assert_eq!(MaxStakedRewards::::get(), Some(Percent::from_percent(100))); } - set_staking_configs_all_remove { - }: set_staking_configs( - RawOrigin::Root, - ConfigOp::Remove, - ConfigOp::Remove, - ConfigOp::Remove, - ConfigOp::Remove, - ConfigOp::Remove, - ConfigOp::Remove, - ConfigOp::Remove - ) verify { + #[benchmark] + fn set_staking_configs_all_remove() { + #[extrinsic_call] + set_staking_configs( + RawOrigin::Root, + ConfigOp::Remove, + ConfigOp::Remove, + ConfigOp::Remove, + ConfigOp::Remove, + ConfigOp::Remove, + ConfigOp::Remove, + ConfigOp::Remove, + ); + assert!(!MinNominatorBond::::exists()); assert!(!MinValidatorBond::::exists()); assert!(!MaxNominatorsCount::::exists()); @@ -886,7 +1028,8 @@ benchmarks! { assert!(!MaxStakedRewards::::exists()); } - chill_other { + #[benchmark] + fn chill_other() -> Result<(), BenchmarkError> { // clean up any existing state. clear_validators_and_nominators::(); @@ -895,7 +1038,7 @@ benchmarks! { // setup a worst case list scenario. Note that we don't care about the setup of the // destination position because we are doing a removal from the list but no insert. let scenario = ListScenario::::new(origin_weight, true)?; - let controller = scenario.origin_controller1.clone(); + let _controller = scenario.origin_controller1.clone(); let stash = scenario.origin_stash1; assert!(T::VoterList::contains(&stash)); @@ -911,18 +1054,22 @@ benchmarks! { )?; let caller = whitelisted_caller(); - }: _(RawOrigin::Signed(caller), stash.clone()) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(caller), stash.clone()); + assert!(!T::VoterList::contains(&stash)); + + Ok(()) } - force_apply_min_commission { + #[benchmark] + fn force_apply_min_commission() -> Result<(), BenchmarkError> { // Clean up any existing state clear_validators_and_nominators::(); // Create a validator with a commission of 50% - let (stash, controller) = - create_stash_controller::(1, 1, RewardDestination::Staked)?; + let (stash, controller) = create_stash_controller::(1, 1, RewardDestination::Staked)?; let validator_prefs = ValidatorPrefs { commission: Perbill::from_percent(50), ..Default::default() }; Staking::::validate(RawOrigin::Signed(controller).into(), validator_prefs)?; @@ -936,29 +1083,135 @@ benchmarks! { // Set the min commission to 75% MinCommission::::set(Perbill::from_percent(75)); let caller = whitelisted_caller(); - }: _(RawOrigin::Signed(caller), stash.clone()) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(caller), stash.clone()); + // The validators commission has been bumped to 75% assert_eq!( Validators::::get(&stash), ValidatorPrefs { commission: Perbill::from_percent(75), ..Default::default() } ); + + Ok(()) } - set_min_commission { + #[benchmark] + fn set_min_commission() { let min_commission = Perbill::max_value(); - }: _(RawOrigin::Root, min_commission) - verify { + + #[extrinsic_call] + _(RawOrigin::Root, min_commission); + assert_eq!(MinCommission::::get(), Perbill::from_percent(100)); } - restore_ledger { + #[benchmark] + fn restore_ledger() -> Result<(), BenchmarkError> { let (stash, controller) = create_stash_controller::(0, 100, RewardDestination::Staked)?; // corrupt ledger. Ledger::::remove(controller); - }: _(RawOrigin::Root, stash.clone(), None, None, None) - verify { + + #[extrinsic_call] + _(RawOrigin::Root, stash.clone(), None, None, None); + assert_eq!(Staking::::inspect_bond_state(&stash), Ok(LedgerIntegrityState::Ok)); + + Ok(()) + } + + #[benchmark] + fn drop_dangling_nomination() -> Result<(), BenchmarkError> { + let caller = account("caller", 0, SEED); + whitelist_account!(caller); + + let mut targets = create_validators_with_nominators_for_era::(2, 1, 2, false, None)?; + let dangling_target = T::Lookup::lookup(targets.pop().expect("target_exists.")) + .map_err(|_| "error looking up validator account")?; + let other_target = T::Lookup::lookup(targets.pop().expect("target_exists.")) + .map_err(|_| "error looking up validator account")?; + let voter = nominators_of::(dangling_target.clone())?.pop().expect("voter exists"); + + assert_eq!(Staking::::status(&dangling_target), Ok(StakerStatus::Validator)); + Pallet::::setup_dangling_target(dangling_target.clone(), voter.clone()); + + // now dangling_target is not validating anymore. + assert!(Staking::::status(&dangling_target).is_err()); + // but the voter is still nominating it. + assert!(nominators_of::(dangling_target.clone())?.contains(&voter)); + // and the target is still part of the TargetList (thus dangling). + assert!(T::TargetList::contains(&dangling_target)); + + assert_eq!( + Staking::::status(&voter), + Ok(StakerStatus::Nominator(vec![other_target.clone(), dangling_target.clone()])) + ); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), voter.clone(), dangling_target.clone()); + + // voter is not nominating validator anymore + assert_eq!(Staking::::status(&voter), Ok(StakerStatus::Nominator(vec![other_target]))); + // target is not in the target list anymore. + assert!(!T::TargetList::contains(&dangling_target)); + + Ok(()) + } + + /// Multi-block (partial) step benchmark for v13 stake-tracker migration. + /// + /// The setup benchmarks the worst case scenario of a *partial-step* of the MMB migration. The + /// partial step of this MMB migration consists of migrating one nominator, i.e. fetch all the + /// nominated targets of one nominator and add them to the target list. + /// The worst case scenario case should consider potential rebaggings done internally by the + /// sorted list provider, thus we populate the target list with 1000 validators before the + /// migration. + /// + /// Note: a MMB migration step may include *several* partial steps, so each block during MMBs + /// progresses as much as possible. + #[benchmark] + fn v13_mmb_partial_step() { + let mut meter = WeightMeter::new(); + + let n_validators = 1000; + let n_nominators = 5; + + let _ = create_validators_with_nominators_for_era::( + n_validators, + n_nominators, + 16, + false, + None, + ) + .unwrap(); + + let targets_count_before = T::TargetList::count(); + + // drop targets from target list nominated by the one nominator to be migrated. + let (_to_migrate, mut nominations) = Nominators::::iter() + .map(|(n, noms)| (n, noms.targets.into_inner())) + .next() + .unwrap(); + + // remove duplicates. + nominations.sort(); + nominations.dedup(); + + // drop targets nominated by the first nominator. + for t in nominations.iter() { + assert_ok!(T::TargetList::on_remove(&t)); + } + + // confirm targets dropped. + assert!(T::TargetList::count() < targets_count_before); + + #[block] + { + v13::MigrationV13::>::step(None, &mut meter) + .unwrap(); + } + + assert_eq!(T::TargetList::count(), targets_count_before); } impl_benchmark_test_suite!( @@ -977,7 +1230,7 @@ mod tests { #[test] fn create_validators_with_nominators_for_era_works() { - ExtBuilder::default().build_and_execute(|| { + ExtBuilder::default().try_state(false).build_and_execute(|| { let v = 10; let n = 100; @@ -1003,7 +1256,7 @@ mod tests { #[test] fn create_validator_with_nominators_works() { - ExtBuilder::default().build_and_execute(|| { + ExtBuilder::default().try_state(false).build_and_execute(|| { let n = 10; let (validator_stash, nominators) = create_validator_with_nominators::( @@ -1034,7 +1287,7 @@ mod tests { #[test] fn add_slashing_spans_works() { - ExtBuilder::default().build_and_execute(|| { + ExtBuilder::default().try_state(false).build_and_execute(|| { let n = 10; let (validator_stash, _nominators) = create_validator_with_nominators::( @@ -1064,25 +1317,4 @@ mod tests { } }); } - - #[test] - fn test_payout_all() { - ExtBuilder::default().build_and_execute(|| { - let v = 10; - let n = 100; - - let selected_benchmark = SelectedBenchmark::payout_all; - let c = vec![ - (frame_benchmarking::BenchmarkParameter::v, v), - (frame_benchmarking::BenchmarkParameter::n, n), - ]; - - assert_ok!( - >::unit_test_instance( - &selected_benchmark, - &c, - ) - ); - }); - } } diff --git a/substrate/frame/staking/src/ledger.rs b/substrate/frame/staking/src/ledger.rs index dc4b4fc326b8..79ce530eb9cc 100644 --- a/substrate/frame/staking/src/ledger.rs +++ b/substrate/frame/staking/src/ledger.rs @@ -35,19 +35,17 @@ use frame_support::{ defensive, ensure, traits::{Defensive, LockableCurrency}, }; -use sp_staking::{StakingAccount, StakingInterface}; +use sp_staking::{OnStakingUpdate, Stake, StakerStatus, StakingAccount, StakingInterface}; use crate::{ BalanceOf, Bonded, Config, Error, Ledger, Pallet, Payee, RewardDestination, StakingLedger, VirtualStakers, STAKING_ID, }; -#[cfg(any(feature = "runtime-benchmarks", test))] -use sp_runtime::traits::Zero; - impl StakingLedger { #[cfg(any(feature = "runtime-benchmarks", test))] pub fn default_from(stash: T::AccountId) -> Self { + use sp_runtime::traits::Zero; Self { stash: stash.clone(), total: Zero::zero(), @@ -77,6 +75,10 @@ impl StakingLedger { } } + pub fn stake(&self) -> Stake> { + Stake { total: self.total, active: self.active } + } + /// Returns the paired account, if any. /// /// A "pair" refers to the tuple (stash, controller). If the input is a @@ -180,6 +182,9 @@ impl StakingLedger { /// Bonds the ledger if it is not bonded yet, signalling that this is a new ledger. The staking /// locks of the stash account are updated accordingly. /// + /// Emits: + /// * [`OnStakeUpdate::on_stake_update`] + /// /// Note: To ensure lock consistency, all the [`Ledger`] storage updates should be made through /// this helper function. pub(crate) fn update(self) -> Result<(), Error> { @@ -187,6 +192,11 @@ impl StakingLedger { return Err(Error::::NotStash) } + let controller = &self.controller().ok_or(Error::::BadState)?; + + // previous stake is the current stake in storage. + let prev_stake = Ledger::::get(&controller).map(|ledger| ledger.stake()); + // We skip locking virtual stakers. if !Pallet::::is_virtual_staker(&self.stash) { // for direct stakers, update lock on stash based on ledger. @@ -206,6 +216,12 @@ impl StakingLedger { &self, ); + // fire `on_stake_update` if there was a stake update. + let new_stake: Stake<_> = self.stake(); + if new_stake != prev_stake.unwrap_or_default() { + T::EventListeners::on_stake_update(&self.stash, prev_stake, new_stake); + } + Ok(()) } @@ -258,9 +274,22 @@ impl StakingLedger { /// Clears all data related to a staking ledger and its bond in both [`Ledger`] and [`Bonded`] /// storage items and updates the stash staking lock. + /// + /// Emits: + /// * [`OnStakingUpdate::on_unstake`] + /// + /// Note: we assume that [`T::EventListeners::on_nominator_remove`] and/or + /// [`T::EventListeners::on_validator_remove`] have been called and the stash is idle, prior to + /// call this method. This can be achieved by calling [`crate::Pallet::::kill_stash`] prior + /// to this call. pub(crate) fn kill(stash: &T::AccountId) -> Result<(), Error> { let controller = >::get(stash).ok_or(Error::::NotStash)?; + debug_assert!( + crate::Pallet::::status(stash) == Ok(StakerStatus::Idle), + "ledger being killed before set as Idle" + ); + >::get(&controller).ok_or(Error::::NotController).map(|ledger| { Ledger::::remove(controller); >::remove(&stash); @@ -272,6 +301,8 @@ impl StakingLedger { T::Currency::remove_lock(STAKING_ID, &ledger.stash); } + T::EventListeners::on_unstake(stash); + Ok(()) })? } diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 9e59cbd3d0cb..56b216eeb6ef 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -291,7 +291,7 @@ pub mod benchmarking; pub mod testing_utils; #[cfg(test)] -pub(crate) mod mock; +pub mod mock; #[cfg(test)] mod tests; @@ -325,7 +325,7 @@ use sp_runtime::{ use sp_staking::{ offence::{Offence, OffenceError, ReportOffence}, EraIndex, ExposurePage, OnStakingUpdate, Page, PagedExposureMetadata, SessionIndex, - StakingAccount, + StakingAccount, StakingInterface, }; pub use sp_staking::{Exposure, IndividualExposure, StakerStatus}; pub use weights::WeightInfo; @@ -587,6 +587,9 @@ impl StakingLedger { /// /// `slash_era` is the era in which the slash (which is being enacted now) actually happened. /// + /// If a slashed staker is a nominator and drops its stake to zero after slash, the staker is + /// chilled to ensure that their nominations are dropped in the stake tracker. + /// /// This calls `Config::OnStakingUpdate::on_slash` with information as to how the slash was /// applied. pub fn slash( @@ -598,7 +601,6 @@ impl StakingLedger { if slash_amount.is_zero() { return Zero::zero() } - use sp_runtime::PerThing as _; let mut remaining_slash = slash_amount; let pre_slash_total = self.total; @@ -705,6 +707,18 @@ impl StakingLedger { self.unlocking.retain(|c| !c.value.is_zero()); let final_slashed_amount = pre_slash_total.saturating_sub(self.total); + + // If the slashed stash is a nominator and it's active stake is zero after the slash is + // applied, chill the staker. this is important in order to ensure that nominations are + // dropped in the stake-tracker. This way, we ensure that in the event of a validator and + // all its nominators are 100% slashed, the target can be reaped/killed without leaving + // nominations behind. + if let (true, Ok(StakerStatus::Nominator(_))) = + (self.active.is_zero(), Pallet::::status(&self.stash)) + { + Pallet::::chill_stash(&self.stash); + }; + T::EventListeners::on_slash( &self.stash, self.active, diff --git a/substrate/frame/staking/src/migrations/mod.rs b/substrate/frame/staking/src/migrations/mod.rs new file mode 100644 index 000000000000..0ce27b99d8e1 --- /dev/null +++ b/substrate/frame/staking/src/migrations/mod.rs @@ -0,0 +1,25 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// Single-block migrations. +pub mod single_block; + +/// v13 MMB stake-tracker migrations. +pub mod v13_stake_tracker; + +/// The unique identifier for the pallet-staking MMBs +pub const PALLET_MIGRATIONS_ID: &[u8; 18] = b"pallet-staking-mmb"; diff --git a/substrate/frame/staking/src/migrations.rs b/substrate/frame/staking/src/migrations/single_block.rs similarity index 97% rename from substrate/frame/staking/src/migrations.rs rename to substrate/frame/staking/src/migrations/single_block.rs index 5c9cf8613213..a43fa30c8c52 100644 --- a/substrate/frame/staking/src/migrations.rs +++ b/substrate/frame/staking/src/migrations/single_block.rs @@ -14,17 +14,26 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and -//! Storage migrations for the Staking pallet. The changelog for this is maintained at +//! Single-block storage migrations for the Staking pallet. The changelog for this is maintained at //! [CHANGELOG.md](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/staking/CHANGELOG.md). -use super::*; +use crate::{ + log, slashing, Config, DisabledValidators, EraIndex, Nominators, Pallet, SessionInterface, + UnappliedSlashes, UpToLimitDisablingStrategy, Validators, +}; use frame_election_provider_support::SortedListProvider; use frame_support::{ migrations::VersionedMigration, - pallet_prelude::ValueQuery, + pallet_prelude::{Get, ValueQuery}, storage_alias, traits::{GetStorageVersion, OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade}, + weights::Weight, }; +use sp_runtime::{traits::Zero, RuntimeDebug}; + +use alloc::vec::Vec; +use codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; #[cfg(feature = "try-runtime")] use frame_support::ensure; diff --git a/substrate/frame/staking/src/migrations/v13_stake_tracker/mod.rs b/substrate/frame/staking/src/migrations/v13_stake_tracker/mod.rs new file mode 100644 index 000000000000..18090e80becc --- /dev/null +++ b/substrate/frame/staking/src/migrations/v13_stake_tracker/mod.rs @@ -0,0 +1,307 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and + +//! # Multi-Block Migration v13 +//! +//! Implements the multi-block migrations to support the `pallet-stake-tracker` and a strictly +//! sorted list of targets with a bags-list. + +use super::PALLET_MIGRATIONS_ID; +use crate::{log, weights, Config, Nominations, Nominators, Pallet, StakerStatus, Validators}; +use alloc::vec::Vec; +use codec::{Decode, Encode, MaxEncodedLen}; +use core::marker::PhantomData; +use frame_election_provider_support::{SortedListProvider, VoteWeight}; +use frame_support::{ + ensure, + migrations::{MigrationId, SteppedMigration, SteppedMigrationError}, + traits::{Defensive, DefensiveSaturating}, +}; +use scale_info::TypeInfo; +use sp_staking::StakingInterface; + +#[cfg(test)] +mod tests; + +#[derive(Encode, Decode, TypeInfo, MaxEncodedLen, PartialEq, Debug, Clone)] +pub enum Processing { + Nominators, + Validators, + Done, +} +impl Default for Processing { + fn default() -> Self { + Processing::Nominators + } +} + +/// V13 Multi-block migration to introduce the stake-tracker pallet. +/// +/// A step of the migration consists of processing one nominator in the [`Nominators`] list or one +/// validators in the [`Validators`] list, depending on the cursor's state. +/// +/// The migration has two phases: +/// * [`Processing::Nominators`]: iterates over the nominators list and updates the approvals stake +/// of the nominated targets associated with each of the nominators. +/// * [`Processing::Validators`]: iterates over the validators list and, if the validator does not +/// exist in the target list, add it with self-stake as score. +/// +/// First, the migration processes all the nominators and then the validators. When a validator is +/// added to the target list during the [`Processing::Validators`], it indicates that the validator +/// has no nominations. +/// +/// The goals of the migration are: +/// * Insert all the nominated targets into the [`SortedListProvider`] target list. +/// * Ensure the target score (total stake) is the sum of the self stake and all its nominations +/// stake. +/// * Ensure the new targets in the list are sorted per total stake (as per the underlying +/// [`SortedListProvider`]). +/// * Ensure that there is no duplicate nominations per nominator. +/// +/// ## Potential changes to nominations state during the migration. +/// +/// When migrating a nominator, we need to ensure that the nominator is not nominating duplicate +/// targets. In addition, this migration also "cleans" the nominations by dropping all nominations +/// of targets that are not active validators. In sum, the following invariants hold true after +/// processing each nominator: +/// +/// 1. A nominator has no duplicate nominations; +/// 2. A nominators is nominating only active validators; +/// 3. A nominator has at least one nomination, otherwise it is chilled. +pub struct MigrationV13(PhantomData<(T, W)>); +impl SteppedMigration for MigrationV13 { + // nominator cursor and validator cursor. + type Cursor = (Option, Processing); + type Identifier = MigrationId<18>; + + /// Identifier of this migration which should be globally unique. + fn id() -> Self::Identifier { + MigrationId { pallet_id: *PALLET_MIGRATIONS_ID, version_from: 12, version_to: 13 } + } + + fn step( + mut cursor: Option, + meter: &mut frame_support::weights::WeightMeter, + ) -> Result, SteppedMigrationError> { + // Worst-case scenario weight required to process one nominator or validator. + let partial_step_weight = W::v13_mmb_partial_step(); + + // If there's no enough weight left in the block for a migration step, return an error. + if meter.remaining().any_lt(partial_step_weight) { + return Err(SteppedMigrationError::InsufficientWeight { required: partial_step_weight }); + } + + // Do as much progress as possible per step. As far as the meter allows, keeps processing + // the partial steps (i.e. migrating one nominator/validator). + while meter.try_consume(partial_step_weight).is_ok() { + let new_cursor = match cursor { + None => { + // start processing first nominator. + if let Some((nominator, nominations)) = Nominators::::iter().next() { + Self::process_nominator(&nominator, nominations)?; + Some((Some(nominator), Processing::Nominators)) + } else { + Some((None, Processing::Validators)) + } + }, + Some((maybe_nominator, Processing::Nominators)) => { + let mut iter = if let Some(last_nominator) = maybe_nominator { + Nominators::::iter_from(Nominators::::hashed_key_for(last_nominator)) + } else { + Nominators::::iter() + }; + + if let Some((nominator, nominations)) = iter.next() { + Self::process_nominator(&nominator, nominations)?; + Some((Some(nominator), Processing::Nominators)) + } else { + // no more nominators to process, go to next phase. + Some((None, Processing::Validators)) + } + }, + Some((maybe_validator, Processing::Validators)) => { + // process validator. + let mut iter = if let Some(last_validator) = maybe_validator { + Validators::::iter_from(Validators::::hashed_key_for(last_validator)) + } else { + Validators::::iter() + }; + + // nominators have been all processed, start processing validators. + if let Some((validator, _)) = iter.next() { + Self::process_validator(&validator); + Some((Some(validator), Processing::Validators)) + } else { + Some((None, Processing::Done)) + } + }, + Some((_, Processing::Done)) => Some((None, Processing::Done)), + }; + + // progress or terminate. + if new_cursor.clone().unwrap_or_default().1 == Processing::Done { + return Ok(None) + } else { + cursor = new_cursor; + } + } + + Ok(cursor) + } +} + +impl MigrationV13 { + fn process_nominator( + nominator: &T::AccountId, + nominations: Nominations, + ) -> Result<(), SteppedMigrationError> { + let nominator_vote = Pallet::::weight_of(nominator); + // clean the nominations before migrating. This will ensure that the voter is not + // nominating duplicate and/or dangling targets. + let nominations = Self::clean_nominations(nominator, nominations)?; + + // iter over up to `MaxNominationsOf` targets of `nominator` and insert or + // update the target's approval's score. + for target in nominations.into_iter() { + if ::TargetList::contains(&target) { + Self::update_target(&target, nominator_vote)?; + } else { + Self::insert_target(&target, nominator_vote)?; + } + } + Ok(()) + } + + fn process_validator(validator: &T::AccountId) { + if !::TargetList::contains(validator) && + as StakingInterface>::status(validator) == Ok(StakerStatus::Validator) + { + let self_stake = Pallet::::weight_of(validator); + ::TargetList::on_insert(validator.clone(), self_stake.into()) + .expect("node does not exist, checked above; qed."); + } + } + + /// Inserts a new target in the list. + /// + /// Note: the caller must ensure that the target node does not exist in the list yet. + /// Oterhwise, use [`Self::update_target`]. + fn insert_target( + who: &T::AccountId, + nomination_stake: VoteWeight, + ) -> Result<(), SteppedMigrationError> { + let init_stake = match as StakingInterface>::status(&who) { + Ok(StakerStatus::Validator) => { + let self_stake = Pallet::::weight_of(&who); + let total_stake = self_stake.defensive_saturating_add(nomination_stake); + total_stake + }, + _ => nomination_stake, + }; + + match ::TargetList::on_insert(who.clone(), init_stake.into()) { + Err(e) => { + log!(error, "inserting {:?} in TL: {:?}", who, e); + Err(SteppedMigrationError::Failed) + }, + Ok(_) => Ok(()), + } + } + + /// Updates the target score in the target list. + /// + /// Note: the caller must ensure that the target node already exists in the list. Otherwise, + /// use [`Self::insert_target`]. + fn update_target( + who: &T::AccountId, + nomination_stake: VoteWeight, + ) -> Result<(), SteppedMigrationError> { + let current_stake = + ::TargetList::get_score(&who).expect("node is in the list"); + + let total_stake = current_stake.defensive_saturating_add(nomination_stake.into()); + let _ = ::TargetList::on_update(&who, total_stake.into()).map_err(|e| { + log!(error, "updating TL score of {:?}: {:?}", who, e); + SteppedMigrationError::Failed + })?; + + Ok(()) + } + + /// Cleans up the nominations of `who`. + /// + /// After calling this method, the following invariants are respected: + /// - `stash` has no duplicate nominations; + /// - `stash` has no dangling nominations (i.e. nomination of non-active validator stashes). + /// + /// If the clean set of nominations is empty, `who` is chilled. + /// + /// When successful, the final nominations of the stash are returned. + pub(crate) fn clean_nominations( + who: &T::AccountId, + raw_nominations: Nominations, + ) -> Result, SteppedMigrationError> { + use alloc::collections::btree_set::BTreeSet; + + ensure!( + Pallet::::status(who).map(|x| x.is_nominator()).unwrap_or(false), + SteppedMigrationError::Failed + ); + + let raw_targets = raw_nominations.targets.into_inner(); + let count_before = raw_targets.len(); + + // remove all non-validator nominations. + let targets: Vec = raw_targets + // dedup nominations. + .into_iter() + .collect::>() + .into_iter() + // remove all non-validator nominations. + .filter(|n| Pallet::::status(n) == Ok(StakerStatus::Validator)) + .collect(); + + if targets.len() == 0 { + // if no nominations are left, chill the nominator. + let _ = as StakingInterface>::chill(&who) + .map_err(|e| { + log!(error, "error when chilling {:?}", who); + e + }) + .defensive(); + } else if count_before > targets.len() { + // force update the nominations. + let bounded_targets = targets + .clone() + .into_iter() + .collect::>() + .try_into() + .expect( + "new bound should be within the existent set of targets, thus it should fit; qed.", + ); + + let nominations = Nominations { + targets: bounded_targets, + submitted_in: raw_nominations.submitted_in, + suppressed: raw_nominations.suppressed, + }; + + >::do_add_nominator(who, nominations); + } + + Ok(targets) + } +} diff --git a/substrate/frame/staking/src/migrations/v13_stake_tracker/tests.rs b/substrate/frame/staking/src/migrations/v13_stake_tracker/tests.rs new file mode 100644 index 000000000000..e8724c835e20 --- /dev/null +++ b/substrate/frame/staking/src/migrations/v13_stake_tracker/tests.rs @@ -0,0 +1,141 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and + +#![cfg(all(test, not(feature = "runtime-benchmarks")))] + +use crate::{ + mock::{ + bond_nominator, bond_validator, run_to_block, AllPalletsWithSystem, ExtBuilder, + MigratorServiceWeight, Staking, System, TargetBagsList, Test as T, + }, + weights::{SubstrateWeight, WeightInfo as _}, + Nominators, +}; +use frame_election_provider_support::SortedListProvider; +use frame_support::traits::OnRuntimeUpgrade; +use pallet_migrations::WeightInfo as _; + +#[test] +fn mb_migration_target_list_simple_works() { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + bond_validator(1, 10); + bond_validator(2, 20); + bond_validator(3, 30); + bond_nominator(4, 40, vec![1, 2]); + bond_nominator(5, 50, vec![2, 3]); + bond_nominator(6, 60, vec![3]); + + TargetBagsList::unsafe_clear(); + assert!(TargetBagsList::count() == 0); + assert!(Staking::do_try_state(System::block_number()).is_err()); + + // allocate 3 steps per block to do the full migration in one step. + let limit = ::WeightInfo::progress_mbms_none() + + pallet_migrations::Pallet::::exec_migration_max_weight() + + SubstrateWeight::::v13_mmb_partial_step() * 3; + MigratorServiceWeight::set(&limit); + + // migrate 3 nominators. + AllPalletsWithSystem::on_runtime_upgrade(); // onboard MBMs + run_to_block(2); + + // stakes of each validators are correct (sum of self_stake and nominations stake). + assert_eq!(TargetBagsList::get_score(&1).unwrap(), 10 + 40); + assert_eq!(TargetBagsList::get_score(&2).unwrap(), 20 + 40 + 50); + assert_eq!(TargetBagsList::get_score(&3).unwrap(), 30 + 50 + 60); + + assert_eq!(TargetBagsList::count(), 3); + + // migration done, try state checks pass. + assert!(Staking::do_try_state(System::block_number()).is_ok()); + }) +} + +#[test] +fn mb_migration_target_list_multiple_steps_works() { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + bond_validator(1, 10); + bond_validator(2, 20); + bond_validator(3, 30); + bond_nominator(4, 40, vec![1, 2]); + bond_nominator(5, 50, vec![2, 3]); + bond_nominator(6, 60, vec![3]); + + TargetBagsList::unsafe_clear(); + assert!(TargetBagsList::count() == 0); + assert!(Staking::do_try_state(System::block_number()).is_err()); + + // allocate 1 step (i.e. 1 nominator) per block. + let limit = ::WeightInfo::progress_mbms_none() + + pallet_migrations::Pallet::::exec_migration_max_weight() + + SubstrateWeight::::v13_mmb_partial_step(); + MigratorServiceWeight::set(&limit); + + AllPalletsWithSystem::on_runtime_upgrade(); // onboard MBMs + + // starts from last bonded nominator (6). + let mut migrating = Nominators::::iter().map(|(n, _)| n); + assert_eq!(migrating.next(), Some(6)); + run_to_block(2); + + // 6 nominates 3, thus target list node 3 has self stake + stake of 6. + assert_eq!(TargetBagsList::get_score(&3).unwrap(), 30 + 60); + assert_eq!(TargetBagsList::count(), 1); + + // next block, migrates nominator 5. + assert_eq!(migrating.next(), Some(5)); + run_to_block(3); + + // 5 nominates 2 and 3. stakes are updated as expected. + assert_eq!(TargetBagsList::get_score(&3).unwrap(), 30 + 60 + 50); + assert_eq!(TargetBagsList::get_score(&2).unwrap(), 20 + 50); + assert_eq!(TargetBagsList::count(), 2); + + // last block, migrates nominator 4. + assert_eq!(migrating.next(), Some(4)); + run_to_block(4); + + // 4 nominates 1 and 2. stakes are updated as expected. + assert_eq!(TargetBagsList::get_score(&2).unwrap(), 20 + 50 + 40); + assert_eq!(TargetBagsList::get_score(&1).unwrap(), 10 + 40); + assert_eq!(TargetBagsList::count(), 3); + + // migration done, try state checks pass. + assert_eq!(migrating.next(), None); + assert!(Staking::do_try_state(System::block_number()).is_ok()); + }) +} + +#[test] +fn mb_migration_target_list_chilled_validator_works() { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + // TODO + }) +} + +#[test] +fn mb_migration_target_list_dangling_validators_works() { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + // TODO + }) +} + +#[test] +fn mb_migration_target_list_duplicate_validators_works() { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + // TODO + }) +} diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 4a0209fc5b08..dae6c7e43108 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -20,22 +20,24 @@ use crate::{self as pallet_staking, *}; use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, - onchain, SequentialPhragmen, VoteWeight, + onchain, SequentialPhragmen, SortedListProvider, VoteWeight, }; use frame_support::{ - assert_ok, derive_impl, ord_parameter_types, parameter_types, + assert_ok, derive_impl, + migrations::MultiStepMigrator, + ord_parameter_types, parameter_types, traits::{ ConstU64, Currency, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, LockableCurrency, OnUnbalanced, OneSessionHandler, WithdrawReasons, }, weights::constants::RocksDbWeight, }; -use frame_system::{EnsureRoot, EnsureSignedBy}; +use frame_system::{limits::BlockWeights, EnsureRoot, EnsureSignedBy}; use sp_io; use sp_runtime::{curve::PiecewiseLinear, testing::UintAuthorityId, traits::Zero, BuildStorage}; use sp_staking::{ offence::{OffenceDetails, OnOffenceHandler}, - OnStakingUpdate, + OnStakingUpdate, OnStakingUpdateEvent, Stake, StakingInterface, }; pub const INIT_TIMESTAMP: u64 = 30_000; @@ -94,7 +96,10 @@ frame_support::construct_runtime!( Staking: pallet_staking, Session: pallet_session, Historical: pallet_session::historical, + StakeTracker: pallet_stake_tracker, VoterBagsList: pallet_bags_list::, + TargetBagsList: pallet_bags_list::, + Migrator: pallet_migrations, } ); @@ -123,6 +128,7 @@ impl frame_system::Config for Test { type DbWeight = RocksDbWeight; type Block = Block; type AccountData = pallet_balances::AccountData; + type MultiBlockMigrator = Migrator; } #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { @@ -195,11 +201,14 @@ impl OnUnbalanced> for RewardRemainderMock { } } -const THRESHOLDS: [sp_npos_elections::VoteWeight; 9] = +const VOTER_THRESHOLDS: [sp_npos_elections::VoteWeight; 9] = [10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000]; +const TARGET_THRESHOLDS: [Balance; 9] = [100, 200, 300, 400, 500, 600, 1_000, 2_000, 10_000]; + parameter_types! { - pub static BagThresholds: &'static [sp_npos_elections::VoteWeight] = &THRESHOLDS; + pub static VoterBagThresholds: &'static [sp_npos_elections::VoteWeight] = &VOTER_THRESHOLDS; + pub static TargetBagThresholds: &'static [Balance] = &TARGET_THRESHOLDS; pub static HistoryDepth: u32 = 80; pub static MaxExposurePageSize: u32 = 64; pub static MaxUnlockingChunks: u32 = 32; @@ -215,10 +224,19 @@ impl pallet_bags_list::Config for Test { type WeightInfo = (); // Staking is the source of truth for voter bags list, since they are not kept up to date. type ScoreProvider = Staking; - type BagThresholds = BagThresholds; + type BagThresholds = VoterBagThresholds; type Score = VoteWeight; } +type TargetBagsListInstance = pallet_bags_list::Instance2; +impl pallet_bags_list::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type ScoreProvider = pallet_bags_list::Pallet; + type BagThresholds = TargetBagThresholds; + type Score = Balance; +} + pub struct OnChainSeqPhragmen; impl onchain::Config for OnChainSeqPhragmen { type System = Test; @@ -240,11 +258,12 @@ parameter_types! { pub static LedgerSlashPerEra: (BalanceOf, BTreeMap>) = (Zero::zero(), BTreeMap::new()); + pub static EventsEmitted: Vec> = vec![]; pub static SlashObserver: BTreeMap> = BTreeMap::new(); } -pub struct EventListenerMock; -impl OnStakingUpdate for EventListenerMock { +pub struct SlashListenerMock; +impl OnStakingUpdate for SlashListenerMock { fn on_slash( pool_account: &AccountId, slashed_bonded: Balance, @@ -258,6 +277,95 @@ impl OnStakingUpdate for EventListenerMock { } } +pub struct EventTracker; +impl OnStakingUpdate for EventTracker { + fn on_stake_update(who: &AccountId, prev_stake: Option>, stake: Stake) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::StakeUpdate { who: *who, prev_stake, stake }); + }) + } + fn on_nominator_add(who: &AccountId, nominations: Vec) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::NominatorAdd { who: *who, nominations }); + }) + } + fn on_nominator_update( + who: &AccountId, + prev_nominations: Vec, + nominations: Vec, + ) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::NominatorUpdate { + who: *who, + prev_nominations, + nominations, + }); + }) + } + fn on_nominator_idle(who: &AccountId, prev_nominations: Vec) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::NominatorIdle { who: *who, prev_nominations }); + }) + } + fn on_nominator_remove(who: &AccountId, nominations: Vec) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::NominatorRemove { who: *who, nominations }); + }) + } + fn on_validator_add(who: &AccountId, self_stake: Stake) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::ValidatorAdd { who: *who, self_stake }); + }) + } + fn on_validator_update(who: &AccountId, self_stake: Option>) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::ValidatorUpdate { who: *who, self_stake }); + }) + } + fn on_validator_idle(who: &AccountId) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::ValidatorIdle { who: *who }); + }) + } + fn on_validator_remove(who: &AccountId) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::ValidatorRemove { who: *who }); + }) + } + fn on_withdraw(who: &AccountId, amount: Balance) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::Withdraw { who: *who, amount }); + }) + } + fn on_unstake(who: &AccountId) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::Unstake { who: *who }); + }) + } + fn on_slash( + who: &AccountId, + slashed_active: Balance, + _slashed_unlocking: &BTreeMap, + slashed_total: Balance, + ) { + EventsEmitted::mutate(|v| { + v.push(OnStakingUpdateEvent::Slash { who: *who, slashed_active, slashed_total }); + }) + } +} + +parameter_types! { + pub static VoterUpdateMode: pallet_stake_tracker::VoterUpdateMode = pallet_stake_tracker::VoterUpdateMode::Lazy; +} + +impl pallet_stake_tracker::Config for Test { + type Currency = Balances; + type Staking = Staking; + type VoterList = VoterBagsList; + type TargetList = TargetBagsList; + type VoterUpdateMode = VoterUpdateMode; +} + // Disabling threshold for `UpToLimitDisablingStrategy` pub(crate) const DISABLING_LIMIT_FACTOR: usize = 3; @@ -276,17 +384,33 @@ impl crate::pallet::pallet::Config for Test { type MaxExposurePageSize = MaxExposurePageSize; type ElectionProvider = onchain::OnChainExecution; type GenesisElectionProvider = Self::ElectionProvider; - // NOTE: consider a macro and use `UseNominatorsAndValidatorsMap` as well. type VoterList = VoterBagsList; - type TargetList = UseValidatorsMap; + type TargetList = TargetBagsList; type NominationsQuota = WeightedNominationsQuota<16>; type MaxUnlockingChunks = MaxUnlockingChunks; type HistoryDepth = HistoryDepth; type MaxControllersInDeprecationBatch = MaxControllersInDeprecationBatch; - type EventListeners = EventListenerMock; + type EventListeners = (StakeTracker, SlashListenerMock, EventTracker); type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; } +parameter_types! { + static BnWeights: BlockWeights = ::BlockWeights::get(); + pub storage MigratorServiceWeight: Weight = BnWeights::get().max_block; +} + +#[derive_impl(pallet_migrations::config_preludes::TestDefaultConfig)] +impl pallet_migrations::Config for Test { + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = crate::migrations::v13_stake_tracker::MigrationV13< + Test, + crate::weights::SubstrateWeight, + >; + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + type MaxServiceWeight = MigratorServiceWeight; +} + pub struct WeightedNominationsQuota; impl NominationsQuota for WeightedNominationsQuota where @@ -427,6 +551,14 @@ impl ExtBuilder { SkipTryStateCheck::set(!enable); self } + pub fn set_voter_list_strict(self) -> Self { + VoterUpdateMode::set(pallet_stake_tracker::VoterUpdateMode::Strict); + self + } + pub fn max_winners(self, max: u32) -> Self { + MaxWinners::set(max); + self + } fn build(self) -> sp_io::TestExternalities { sp_tracing::try_init_simple(); let mut storage = frame_system::GenesisConfig::::default().build_storage().unwrap(); @@ -461,6 +593,8 @@ impl ExtBuilder { (71, self.balance_factor * 2000), (80, self.balance_factor), (81, self.balance_factor * 2000), + (90, self.balance_factor), + (91, self.balance_factor * 2000), // This allows us to have a total_payout different from 0. (999, 1_000_000_000_000), ], @@ -561,7 +695,12 @@ impl ExtBuilder { ext.execute_with(test); ext.execute_with(|| { if !SkipTryStateCheck::get() { - Staking::do_try_state(System::block_number()).unwrap(); + let _ = Staking::do_try_state(System::block_number()) + .map_err(|err| { + println!(" 🕵️‍♂️ try_state failure: {:?}", err); + err + }) + .unwrap(); } }); } @@ -622,9 +761,8 @@ pub(crate) fn run_to_block(n: BlockNumber) { Session::on_initialize(b); >::on_initialize(b); Timestamp::set_timestamp(System::block_number() * BLOCK_TIME + INIT_TIMESTAMP); - if b != n { - Staking::on_finalize(System::block_number()); - } + Staking::on_finalize(System::block_number()); + ::MultiBlockMigrator::step(); } } @@ -878,6 +1016,46 @@ pub(crate) fn setup_double_bonded_ledgers() { assert_eq!(Ledger::::get(777).unwrap().stash, 555); } +pub(crate) fn setup_dangling_target_for_nominators(target: AccountId, nominators: Vec) { + // update nominations. + for n in nominators { + let mut nominations = Staking::nominations(&n).unwrap(); + nominations.push(target); + + let nominations: BoundedVec<_, MaxNominationsOf> = + BoundedVec::truncate_from(nominations); + + // update nominations. + let prev_nominations = Nominators::::get(&n).unwrap(); + Nominators::::insert( + n, + Nominations { targets: nominations.clone(), submitted_in: 0, suppressed: false }, + ); + >::on_nominator_update( + &n, + prev_nominations.targets.to_vec(), + nominations.to_vec(), + ); + } + + // remove self-stake/unbond. + let stake = Staking::stake(&target).unwrap(); + let mut stake_after_unbond = stake; + stake_after_unbond.active -= 10; + stake_after_unbond.total -= 10; + + // now remove all the self-stake score from the validator. + >::on_stake_update( + &target, + Some(stake), + stake_after_unbond, + ); + + Bonded::::remove(target); + Validators::::remove(target); + Nominators::::remove(target); +} + #[macro_export] macro_rules! assert_session_era { ($session:expr, $era:expr) => { @@ -898,6 +1076,13 @@ macro_rules! assert_session_era { }; } +pub(crate) fn nominators_of(t: &AccountId) -> Vec { + Nominators::::iter() + .filter(|(_, n)| n.targets.contains(&t)) + .map(|(v, _)| v) + .collect::>() +} + pub(crate) fn staking_events() -> Vec> { System::events() .into_iter() @@ -928,3 +1113,62 @@ pub(crate) fn staking_events_since_last_call() -> Vec> { pub(crate) fn balances(who: &AccountId) -> (Balance, Balance) { (Balances::free_balance(who), Balances::reserved_balance(who)) } + +// this helper method also cleans the current state of `EventsEmtted`. +pub(crate) fn ensure_on_staking_updates_emitted( + expected: Vec>, +) { + assert_eq!( + EventsEmitted::get(), + expected, + "`OnStakingUpdate` events not as expected: {:?} != {:?}", + EventsEmitted::get(), + expected + ); + + // reset events emitted. + EventsEmitted::set(vec![]); +} + +pub(crate) fn voters_and_targets() -> (Vec<(AccountId, VoteWeight)>, Vec<(AccountId, Balance)>) { + ( + VoterBagsList::iter() + .map(|v| (v, VoterBagsList::get_score(&v).unwrap())) + .collect::>(), + TargetBagsList::iter() + .map(|t| (t, TargetBagsList::get_score(&t).unwrap())) + .collect::>(), + ) +} + +#[allow(dead_code)] +pub(crate) fn print_lists_debug() { + println!("\nVoters:"); + let _ = voters_and_targets() + .0 + .iter() + .map(|v| { + println!(" {:?} -> {:?}", v, Staking::status(&v.0)); + }) + .collect::>(); + + println!("\nTargets:"); + let _ = voters_and_targets() + .1 + .iter() + .map(|v| { + println!(" {:?} -> {:?}", v, Staking::status(&v.0)); + }) + .collect::>(); + println!("\n"); +} + +pub(crate) fn target_bags_events() -> Vec> { + System::events() + .into_iter() + .map(|r| r.event) + .filter_map( + |e| if let RuntimeEvent::TargetBagsList(inner) = e { Some(inner) } else { None }, + ) + .collect::>() +} diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 2df3bc084eb0..4ded21f11135 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -53,7 +53,8 @@ use crate::{ election_size_tracker::StaticTracker, log, slashing, weights::WeightInfo, ActiveEraInfo, BalanceOf, EraInfo, EraPayout, Exposure, ExposureOf, Forcing, IndividualExposure, LedgerIntegrityState, MaxNominationsOf, MaxWinnersOf, Nominations, NominationsQuota, - PositiveImbalanceOf, RewardDestination, SessionInterface, StakingLedger, ValidatorPrefs, + PositiveImbalanceOf, RewardDestination, SessionInterface, StakerStatus, StakingLedger, + ValidatorPrefs, }; use alloc::{boxed::Box, vec, vec::Vec}; @@ -208,7 +209,8 @@ impl Pallet { T::WeightInfo::withdraw_unbonded_kill(num_slashing_spans) } else { - // This was the consequence of a partial unbond. just update the ledger and move on. + // This was the consequence of a partial unbond. just update the ledger and move + // on. ledger.update()?; // This is only an update, so we use less overall weight. @@ -285,14 +287,12 @@ impl Pallet { Err(Error::::NotStash.with_weight(T::WeightInfo::payout_stakers_alive_staked(0))) } })?; + let stash = ledger.stash.clone(); // clean up older claimed rewards ledger .legacy_claimed_rewards .retain(|&x| x >= current_era.saturating_sub(history_depth)); - ledger.clone().update()?; - - let stash = ledger.stash.clone(); if EraInfo::::is_rewards_claimed_with_legacy_fallback(era, &ledger, &stash, page) { return Err(Error::::AlreadyClaimed @@ -306,7 +306,8 @@ impl Pallet { .with_weight(T::WeightInfo::payout_stakers_alive_staked(0)) })?; - // Input data seems good, no errors allowed after this point + // Input data seems good, no errors allowed after the ledger is successfully updated. + ledger.update()?; // Get Era reward points. It has TOTAL and INDIVIDUAL // Find the fraction of the era reward that belongs to the validator @@ -333,7 +334,7 @@ impl Pallet { // This is how much validator + nominators are entitled to. let validator_total_payout = validator_total_reward_part * era_payout; - let validator_commission = EraInfo::::get_validator_commission(era, &ledger.stash); + let validator_commission = EraInfo::::get_validator_commission(era, &stash); // total commission validator takes across all nominator pages let validator_total_commission_payout = validator_commission * validator_total_payout; @@ -393,14 +394,74 @@ impl Pallet { } /// Chill a stash account. + /// + /// Chilling consists of removing the nominator/validator's stash from the corresponding + /// `Nominators` or `Validators` storage map. + /// + /// Note: chilling a staker does not remove its footprint from the voter list or target list. + /// + /// Invariant: upon chilling the status of the stash must be `StakerStatus::Idle`. pub(crate) fn chill_stash(stash: &T::AccountId) { - let chilled_as_validator = Self::do_remove_validator(stash); - let chilled_as_nominator = Self::do_remove_nominator(stash); + let chilled_as_validator = Self::do_chill_validator(stash); + let chilled_as_nominator = Self::do_chill_nominator(stash); if chilled_as_validator || chilled_as_nominator { + debug_assert_eq!(Self::status(stash), Ok(StakerStatus::Idle)); + Self::deposit_event(Event::::Chilled { stash: stash.clone() }); } } + /// Removes dangling nominations from a nominator. + /// + /// If `maybe_target` is `None`, search for *all* dangling nominations and drop them. Otherwise + /// drop only one dangling target. If the new set of nominations without the dangling targets + /// is empry, the `nominator` is chilled. + /// + /// IMPORTANT NOTE: if `maybe_target` is set, it is assumed that the target is indeed dangling. + /// No further checks are performed in this method. + pub(crate) fn do_drop_dangling_nominations( + nominator: &T::AccountId, + target: Option<&T::AccountId>, + ) -> Result>, DispatchError> { + let (size_before, nominations_after) = match (target, Self::status(&nominator)) { + (None, Ok(StakerStatus::Nominator(nominations))) => { + // target not set, filter out all non-validator nominations. + ( + nominations.len(), + nominations + .into_iter() + .filter(|n| Self::status(n) == Ok(StakerStatus::Validator)) + .collect::>(), + ) + }, + (Some(target), Ok(StakerStatus::Nominator(nominations))) => { + debug_assert!(Self::status(&target).is_err() && T::TargetList::contains(&target),); + + ( + nominations.len(), + nominations.iter().cloned().filter(|n| n != target).collect::>(), + ) + }, + // not a nominator, return earlier. + (_, _) => return Err(Error::::NotNominator.into()), + }; + + // no dangling targets after all. + if nominations_after.len() == size_before { + return Err(Error::::NotDanglingTarget.into()); + } + + if nominations_after.len().is_zero() { + // no valid nominations left, chill nominator. + ::chill(nominator)?; + } else { + // update the nominations without the dangling(s) nominations. + ::nominate(nominator, nominations_after.clone())?; + } + + Ok(BoundedVec::truncate_from(nominations_after)) + } + /// Actually make a payment to a staker. This uses the currency's reward function /// to pay the right payee for the given staker account. fn make_payout( @@ -420,7 +481,6 @@ impl Pallet { ledger.active += amount; ledger.total += amount; let r = T::Currency::deposit_into_existing(stash, amount).ok(); - let _ = ledger .update() .defensive_proof("ledger fetched from storage, so it exists; qed."); @@ -790,12 +850,29 @@ impl Pallet { pub(crate) fn kill_stash(stash: &T::AccountId, num_slashing_spans: u32) -> DispatchResult { slashing::clear_stash_metadata::(&stash, num_slashing_spans)?; - // removes controller from `Bonded` and staking ledger from `Ledger`, as well as reward - // setting of the stash in `Payee`. - StakingLedger::::kill(&stash)?; + // note: these must be called *before* cleaning up the staking ledger storage with fn kill. + match Self::status(stash) { + Ok(StakerStatus::Validator) => { + // validator is both a nominator and validator. + Self::do_remove_validator(&stash); + Self::do_remove_nominator(&stash); + }, + Ok(StakerStatus::Nominator(_)) => { + Self::do_remove_nominator(&stash); + }, + Ok(StakerStatus::Idle) => { + // we keep track of chilled (`Idle`) validators in the TargetList as well, so we + // may need to remove them. + Self::do_remove_validator(&stash); + }, + Err(_) => { + // do nothing; it will fail below when trying to kill the stash. + }, + } - Self::do_remove_validator(&stash); - Self::do_remove_nominator(&stash); + // and finally, it removes controller from `Bonded` and staking ledger from `Ledger`, as + // well as reward setting of the stash in `Payee`. + StakingLedger::::kill(&stash)?; frame_system::Pallet::::dec_consumers(&stash); @@ -883,6 +960,44 @@ impl Pallet { SlashRewardFraction::::put(fraction); } + #[cfg(feature = "runtime-benchmarks")] + pub fn setup_dangling_target(target: T::AccountId, nominator: T::AccountId) { + let nominations = Self::nominations(&nominator).unwrap(); + let nominations: BoundedVec<_, MaxNominationsOf> = + BoundedVec::truncate_from(nominations); + + let prev_nominations = Nominators::::get(&nominator).unwrap(); + + Nominators::::insert( + nominator.clone(), + Nominations { targets: nominations.clone(), submitted_in: 0, suppressed: false }, + ); + + T::EventListeners::on_nominator_update( + &nominator, + prev_nominations.targets.into_iter().map(|t| t.into()).collect::>(), + nominations.into_iter().map(|n| n.into()).collect::>(), + ); + + let nominator_stake = Self::stake(&nominator).unwrap(); + + let prev_stake = Self::stake(&target).unwrap(); + let stake_after_unbond = Stake { + total: prev_stake.total - nominator_stake.total, + active: prev_stake.active - nominator_stake.active, + }; + + T::EventListeners::on_stake_update( + &target.clone().into(), + Some(prev_stake), + stake_after_unbond, + ); + + Bonded::::remove(target.clone()); + Validators::::remove(target.clone()); + Nominators::::remove(target); + } + /// Get all of the voters that are eligible for the npos election. /// /// `maybe_max_len` can imposes a cap on the number of voters returned; @@ -1017,7 +1132,13 @@ impl Pallet { let mut all_targets = Vec::::with_capacity(final_predicted_len as usize); let mut targets_seen = 0; - let mut targets_iter = T::TargetList::iter(); + // target list may contain chilled validators, dangling (i.e. unbonded) targets or even + // nominators that have been validators - filter those out. + let mut targets_iter = T::TargetList::iter().filter(|t| match Self::status(&t) { + Ok(StakerStatus::Idle) | Ok(StakerStatus::Nominator(_)) | Err(_) => false, + Ok(StakerStatus::Validator) => true, + }); + while all_targets.len() < final_predicted_len as usize && targets_seen < (NPOS_MAX_ITERATIONS_COEFFICIENT * final_predicted_len as u32) { @@ -1053,43 +1174,65 @@ impl Pallet { /// /// If the nominator already exists, their nominations will be updated. /// - /// NOTE: you must ALWAYS use this function to add nominator or update their targets. Any access - /// to `Nominators` or `VoterList` outside of this function is almost certainly - /// wrong. + /// NOTE: you must ALWAYS use this function to add nominator or update their targets. Any + /// access to `Nominators` or `VoterList` outside of this function is almost certainly wrong. pub fn do_add_nominator(who: &T::AccountId, nominations: Nominations) { - if !Nominators::::contains_key(who) { - // maybe update sorted list. - let _ = T::VoterList::on_insert(who.clone(), Self::weight_of(who)) - .defensive_unwrap_or_default(); + let nomination_accounts = nominations.targets.to_vec(); + + match Self::status(who) { + Ok(StakerStatus::Idle) => { + // new nomination + Nominators::::insert(who, nominations); + T::EventListeners::on_nominator_add(who, nomination_accounts); + }, + Ok(StakerStatus::Nominator(prev_nominations)) => { + // update nominations or un-chill nominator. + Nominators::::insert(who, nominations); + T::EventListeners::on_nominator_update(who, prev_nominations, nomination_accounts); + }, + _ => { + defensive!("calling add_nominator on a validator or unbonded stash."); + }, } - Nominators::::insert(who, nominations); debug_assert_eq!( Nominators::::count() + Validators::::count(), - T::VoterList::count() + T::VoterList::iter() + .filter(|v| Self::status(&v) != Ok(StakerStatus::Idle)) + .filter(|v| !Self::status(&v).is_err()) + .count() as u32, ); } + /// Tries to chill a nominator. + /// + /// A chilled nominator is removed from the `Nominators` map, and the nominator's new state must + /// be signalled to [`T::EventListeners`]. + /// + /// Returns `true` if the nominator was successfully chilled, `false` otherwise. + pub(crate) fn do_chill_nominator(who: &T::AccountId) -> bool { + Nominators::::take(who).map_or(false, |nominations| { + T::EventListeners::on_nominator_remove(who, nominations.clone().targets.into()); + true + }) + } + /// This function will remove a nominator from the `Nominators` storage map, /// and `VoterList`. /// /// Returns true if `who` was removed from `Nominators`, otherwise false. /// - /// NOTE: you must ALWAYS use this function to remove a nominator from the system. Any access to - /// `Nominators` or `VoterList` outside of this function is almost certainly - /// wrong. + /// NOTE: you must ALWAYS use this function to remove a nominator from the system. Any access + /// to `Nominators` or `VoterList` outside of this function is almost certainly wrong. pub fn do_remove_nominator(who: &T::AccountId) -> bool { - let outcome = if Nominators::::contains_key(who) { - Nominators::::remove(who); - let _ = T::VoterList::on_remove(who).defensive(); - true - } else { - false - }; + let outcome = Self::do_chill_nominator(who); debug_assert_eq!( Nominators::::count() + Validators::::count(), - T::VoterList::count() + T::VoterList::iter() + .filter(|v| Self::status(&v) != Ok(StakerStatus::Idle)) + .filter(|v| !Self::status(&v).is_err()) + .count() as u32, ); outcome @@ -1104,18 +1247,38 @@ impl Pallet { /// wrong. pub fn do_add_validator(who: &T::AccountId, prefs: ValidatorPrefs) { if !Validators::::contains_key(who) { - // maybe update sorted list. - let _ = T::VoterList::on_insert(who.clone(), Self::weight_of(who)) - .defensive_unwrap_or_default(); - } + let self_stake = Self::stake(who); + T::EventListeners::on_validator_add( + who, + self_stake.defensive_unwrap_or_default().into(), + ); + }; Validators::::insert(who, prefs); debug_assert_eq!( Nominators::::count() + Validators::::count(), - T::VoterList::count() + T::VoterList::iter() + .filter(|v| Self::status(&v) != Ok(StakerStatus::Idle)) + .filter(|v| !Self::status(&v).is_err()) + .count() as u32, ); } + /// Tries to chill a validator. + /// + /// A chilled validator is removed from the `Validators` map. + /// + /// Returns `true` if the validator was successfully chilled, `false` otherwise. + pub(crate) fn do_chill_validator(who: &T::AccountId) -> bool { + if Validators::::contains_key(who) { + Validators::::remove(who); + T::EventListeners::on_validator_idle(who); + true + } else { + false + } + } + /// This function will remove a validator from the `Validators` storage map. /// /// Returns true if `who` was removed from `Validators`, otherwise false. @@ -1124,17 +1287,15 @@ impl Pallet { /// `Validators` or `VoterList` outside of this function is almost certainly /// wrong. pub fn do_remove_validator(who: &T::AccountId) -> bool { - let outcome = if Validators::::contains_key(who) { - Validators::::remove(who); - let _ = T::VoterList::on_remove(who).defensive(); - true - } else { - false - }; + let outcome = Self::do_chill_validator(who); + T::EventListeners::on_validator_remove(who); debug_assert_eq!( Nominators::::count() + Validators::::count(), - T::VoterList::count() + T::VoterList::iter() + .filter(|v| Self::status(&v) != Ok(StakerStatus::Idle)) + .filter(|v| !Self::status(&v).is_err()) + .count() as u32, ); outcome @@ -1638,16 +1799,17 @@ impl SortedListProvider for UseValidatorsMap { // nothing to do upon regenerate. 0 } - #[cfg(feature = "try-runtime")] - fn try_state() -> Result<(), TryRuntimeError> { - Ok(()) - } - fn unsafe_clear() { #[allow(deprecated)] Validators::::remove_all(); } + #[cfg(feature = "try-runtime")] + fn in_position(_id: &T::AccountId) -> Result { + // No sorting provided by this impl, thus the account is always in position. + Ok(true) + } + #[cfg(feature = "runtime-benchmarks")] fn score_update_worst_case(_who: &T::AccountId, _is_increase: bool) -> Self::Score { unimplemented!() @@ -1714,12 +1876,6 @@ impl SortedListProvider for UseNominatorsAndValidatorsM // nothing to do upon regenerate. 0 } - - #[cfg(feature = "try-runtime")] - fn try_state() -> Result<(), TryRuntimeError> { - Ok(()) - } - fn unsafe_clear() { // NOTE: Caller must ensure this doesn't lead to too many storage accesses. This is a // condition of SortedListProvider::unsafe_clear. @@ -1729,6 +1885,12 @@ impl SortedListProvider for UseNominatorsAndValidatorsM Validators::::remove_all(); } + #[cfg(feature = "try-runtime")] + fn in_position(_id: &T::AccountId) -> Result { + // No sorting provided by this impl, thus the account is always in position. + Ok(true) + } + #[cfg(feature = "runtime-benchmarks")] fn score_update_worst_case(_who: &T::AccountId, _is_increase: bool) -> Self::Score { unimplemented!() @@ -1856,6 +2018,7 @@ impl StakingInterface for Pallet { validator == *who || exposure_page.others.iter().any(|i| i.who == *who) }) } + fn status( who: &Self::AccountId, ) -> Result, DispatchError> { @@ -1866,7 +2029,6 @@ impl StakingInterface for Pallet { let is_validator = Validators::::contains_key(&who); let is_nominator = Nominators::::get(&who); - use sp_staking::StakerStatus; match (is_validator, is_nominator.is_some()) { (false, false) => Ok(StakerStatus::Idle), (true, false) => Ok(StakerStatus::Validator), @@ -1968,10 +2130,11 @@ impl sp_staking::StakingUnchecked for Pallet { #[cfg(any(test, feature = "try-runtime"))] impl Pallet { - pub(crate) fn do_try_state(_: BlockNumberFor) -> Result<(), TryRuntimeError> { + pub fn do_try_state(_: BlockNumberFor) -> Result<(), TryRuntimeError> { ensure!( - T::VoterList::iter() - .all(|x| >::contains_key(&x) || >::contains_key(&x)), + T::VoterList::iter().all(|x| >::contains_key(&x) || + >::contains_key(&x) || + Self::status(&x) == Ok(StakerStatus::Idle)), "VoterList contains non-staker" ); @@ -1982,7 +2145,9 @@ impl Pallet { Self::check_exposures()?; Self::check_paged_exposures()?; Self::check_count()?; - Self::ensure_disabled_validators_sorted() + Self::ensure_disabled_validators_sorted()?; + Self::do_try_state_approvals()?; + Self::do_try_state_target_sorting() } /// Invariants: @@ -2068,13 +2233,16 @@ impl Pallet { /// * Current validator count is bounded by the election provider's max winners. fn check_count() -> Result<(), TryRuntimeError> { ensure!( - ::VoterList::count() == - Nominators::::count() + Validators::::count(), - "wrong external count" + ::VoterList::iter() + .filter(|v| Self::status(&v) != Ok(StakerStatus::Idle)) + .count() as u32 == Nominators::::count() + Validators::::count(), + "wrong external count (VoterList.count != Nominators.count + Validators.count)" ); ensure!( - ::TargetList::count() == Validators::::count(), - "wrong external count" + ::TargetList::iter() + .filter(|t| Self::status(&t) == Ok(StakerStatus::Validator)) + .count() as u32 == Validators::::count(), + "wrong external count (TargetList.count != Validators.count)" ); ensure!( ValidatorCount::::get() <= @@ -2224,7 +2392,10 @@ impl Pallet { /// Invariants: /// * Checks that each nominator has its entire stake correctly distributed. + /// * Nominations do not have duplicate targets. fn check_nominators() -> Result<(), TryRuntimeError> { + use alloc::collections::btree_set::BTreeSet; + // a check per nominator to ensure their entire stake is correctly distributed. Will only // kick-in if the nomination was submitted before the current era. let era = Self::active_era().unwrap().index; @@ -2236,15 +2407,34 @@ impl Pallet { .collect::>(); >::iter() - .filter_map( - |(nominator, nomination)| { + // fails if a nomination vec has duplicate targets. + .map(|nomination| -> Result<(T::AccountId, Nominations), TryRuntimeError> { + let targets = nomination.clone().1.targets; + + let count_before = targets.len(); + let dedup_noms: Vec = targets + .clone() + .drain(..) + .collect::>() + .into_iter() + .collect::>(); + + ensure!( + count_before == dedup_noms.len(), + "A nominator has duplicate nominations; unexpected." + ); + + Ok(nomination) + }) + .filter_map(|n| match n { + Ok((nominator, nomination)) => if nomination.submitted_in < era { Some(nominator) } else { None - } - }, - ) + }, + Err(_) => None, + }) .map(|nominator| -> Result<(), TryRuntimeError> { // must be bonded. Self::ensure_is_stash(&nominator)?; @@ -2304,4 +2494,147 @@ impl Pallet { ); Ok(()) } + + /// Stake-tracker: checks if the approvals stake of the targets in the target list are correct. + /// + /// These try-state checks generate a map with approval stake of all the targets based on + /// the staking state of stakers in the voter and target lists. In doing so, we are able to + /// verify that the current voter and target lists and scores are in sync with the staking + /// data and perform other sanity checks as the approvals map is calculated. + /// + /// NOTE: this is an expensive state check since it iterates over all the nodes in the + /// target and voter list providers. + /// + /// Invariants: + /// + /// * Target List: + /// * The sum of the calculated approvals stake is the same as the current approvals in + /// the target list per target. + /// * The target score of an active validator is the sum of all of its nominators' stake + /// and the self-stake; + /// * The target score of an idle validator (i.e. chilled) is the sum of its nominator's + /// stake. An idle target may not be part of the target list, if it has no nominations. + /// * The target score of a "dangling" target (ie. idle AND unbonded validator) must + /// always be > 0. We expect the stake-tracker to have cleaned up dangling targets with 0 + /// score. + /// * The number of target nodes in the target list matches the number of + /// (active_validators + idle_validators + dangling_targets_score_with_score). + pub fn do_try_state_approvals() -> Result<(), sp_runtime::TryRuntimeError> { + use alloc::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; + let mut approvals_map: BTreeMap = BTreeMap::new(); + + // build map of approvals stakes from the `Nominators` storage map POV. + for (voter, nominations) in Nominators::::iter() { + let vote = Self::weight_of(&voter); + let nominations = nominations.targets; + + // fail if nominator has duplicate nominations, unexpected in the context of + // keeping track of the stake approvals. + let count_before = nominations.len(); + let dedup_noms: Vec = nominations + .clone() + .drain(..) + .collect::>() + .into_iter() + .collect::>(); + + ensure!( + count_before == dedup_noms.len(), + "nominator has duplicate nominations, unexpected." + ); + + for target in nominations.into_iter() { + if let Some(approvals) = approvals_map.get_mut(&target) { + *approvals += vote.into(); + } else { + // new addition to the map. add self-stake if validator is active. + let _ = match Self::status(&target) { + Ok(StakerStatus::Validator) => { + let self_stake = Pallet::::weight_of(&target); + approvals_map.insert(target, vote.saturating_add(self_stake).into()) + }, + _ => approvals_map.insert(target, vote.into()), + }; + } + } + } + + // add active validators without any nominations. + for (validator, _) in Validators::::iter() { + // do not add validator if it is not in a good state. + match Self::inspect_bond_state(&validator) { + Ok(LedgerIntegrityState::Ok) | Err(_) => (), + _ => continue, + } + + if !approvals_map.contains_key(&validator) { + // skip if for some reason there is a nominator being nominated. + match Self::status(&validator) { + Ok(StakerStatus::Nominator(_)) => { + log!( + warn, + "nominated staker {:?} is a nominator, not a validator.", + validator + ); + }, + _ => { + let self_stake = Pallet::::weight_of(&validator); + approvals_map.insert(validator, self_stake.into()); + }, + } + } + } + + let mut mismatch_approvals = 0; + + // compare calculated approvals per target with target list state. + for (target, calculated_stake) in approvals_map.iter() { + let stake_in_list = T::TargetList::get_score(target).unwrap(); + + if *calculated_stake != stake_in_list { + mismatch_approvals += 1; + + log!( + error, + "try-runtime: score of {:?} in `TargetList` list: {:?}, calculated sum of all stake: {:?} -- weight self-stake: {:?}", + target, + stake_in_list, + calculated_stake, + Pallet::::weight_of(&target), + ); + } + } + + frame_support::ensure!( + approvals_map.keys().count() == T::TargetList::iter().count(), + "calculated approvals count is different from total of target list.", + ); + + if !mismatch_approvals.is_zero() { + log!(error, "{} targets with unexpected score in list", mismatch_approvals); + return Err("final calculated approvals != target list scores".into()); + } + + Ok(()) + } + + /// Try-state: checks if targets in the target list are sorted by score. + /// + /// Invariant + /// * All targets in the target list are sorted by their score (approvals). + /// + /// NOTE: unfortunatelly, it is not trivial to check if the sort correctness of the list if + /// the `SortedListProvider` is implemented by bags list due to score bucketing. Thus, we + /// leverage the [`SortedListProvider::in_position`] to verify if the target is in the + /// correct position in the list (bag or otherwise), given its score. + pub fn do_try_state_target_sorting() -> Result<(), sp_runtime::TryRuntimeError> { + for t in T::TargetList::iter() { + frame_support::ensure!( + T::TargetList::in_position(&t).expect("target exists"), + "target list is not sorted" + ); + } + + Ok(()) + } } diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 79f9d298ada7..c83088e3e782 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -37,8 +37,9 @@ use sp_runtime::{ ArithmeticError, Perbill, Percent, }; +use alloc::collections::btree_set::BTreeSet; use sp_staking::{ - EraIndex, Page, SessionIndex, + EraIndex, OnStakingUpdate, Page, SessionIndex, StakingAccount::{self, Controller, Stash}, StakingInterface, }; @@ -51,7 +52,7 @@ use crate::{ slashing, weights::WeightInfo, AccountIdLookupOf, ActiveEraInfo, BalanceOf, DisablingStrategy, EraPayout, EraRewardPoints, Exposure, ExposurePage, Forcing, LedgerIntegrityState, MaxNominationsOf, NegativeImbalanceOf, Nominations, NominationsQuota, PositiveImbalanceOf, - RewardDestination, SessionInterface, StakingLedger, UnappliedSlash, UnlockChunk, + RewardDestination, SessionInterface, StakerStatus, StakingLedger, UnappliedSlash, UnlockChunk, ValidatorPrefs, }; @@ -106,6 +107,7 @@ pub mod pallet { + From + TypeInfo + MaxEncodedLen; + /// Time used for computing era duration. /// /// It is guaranteed to start being called from the first `on_finalize`. Thus value at @@ -232,40 +234,37 @@ pub mod pallet { #[pallet::constant] type MaxExposurePageSize: Get; - /// Something that provides a best-effort sorted list of voters aka electing nominators, - /// used for NPoS election. + /// Something that provides a sorted list of voters (aka electing nominators), used for + /// NPoS election. /// /// The changes to nominators are reported to this. Moreover, each validator's self-vote is /// also reported as one independent vote. /// - /// To keep the load off the chain as much as possible, changes made to the staked amount - /// via rewards and slashes are not reported and thus need to be manually fixed by the - /// staker. In case of `bags-list`, this always means using `rebag` and `putInFrontOf`. + /// Voters will be removed from this list when their ledger is killed or the nominator is + /// chilled. /// - /// Invariant: what comes out of this list will always be a nominator. + /// Invariant: what comes out of this list will always be an active nominator. #[pallet::no_default] type VoterList: SortedListProvider; - /// WIP: This is a noop as of now, the actual business logic that's described below is going - /// to be introduced in a follow-up PR. - /// - /// Something that provides a best-effort sorted list of targets aka electable validators, - /// used for NPoS election. + /// Something that provides a sorted list of targets (aka electable and chilled + /// validators), used for NPoS election. /// - /// The changes to the approval stake of each validator are reported to this. This means any - /// change to: - /// 1. The stake of any validator or nominator. - /// 2. The targets of any nominator - /// 3. The role of any staker (e.g. validator -> chilled, nominator -> validator, etc) + /// The changes to the approval stake of each validator are reported to this list through + /// [`Self::EventListeners`]. The target(s) approval stake in the list should be updated in + /// any of these cases: + /// 1. The stake of a validator or nominator is updated. + /// 2. A nominator or validator is chilled. + /// 3. The nominations of a voter are updated. + /// 4. A nominator or validator ledger is removed from the staking system. /// - /// Unlike `VoterList`, the values in this list are always kept up to date with reward and - /// slash as well, and thus represent the accurate approval stake of all account being - /// nominated by nominators. + /// Chilled validators will *not* be removed from this list. Even when chilled, the target's + /// approval voting must be kept up to date. In case a chilled validator re-validates their + /// intention to be a validator again, their target score is up to date with the nominations + /// in the system. /// - /// Note that while at the time of nomination, all targets are checked to be real - /// validators, they can chill at any point, and their approval stakes will still be - /// recorded. This implies that what comes out of iterating this list MIGHT NOT BE AN ACTIVE - /// VALIDATOR. + /// A target is removed from the list IFF its approval score is zero. This means that the + /// validator must be unbonded *AND* no staker is nominating it. #[pallet::no_default] type TargetList: SortedListProvider>; @@ -287,10 +286,8 @@ pub mod pallet { /// Something that listens to staking updates and performs actions based on the data it /// receives. - /// - /// WARNING: this only reports slashing and withdraw events for the time being. #[pallet::no_default_bounds] - type EventListeners: sp_staking::OnStakingUpdate>; + type EventListeners: OnStakingUpdate>; /// `DisablingStragegy` controls how validators are disabled #[pallet::no_default_bounds] @@ -422,10 +419,9 @@ pub mod pallet { /// The map from nominator stash key to their nomination preferences, namely the validators that /// they wish to support. /// - /// Note that the keys of this storage map might become non-decodable in case the - /// account's [`NominationsQuota::MaxNominations`] configuration is decreased. - /// In this rare case, these nominators - /// are still existent in storage, their key is correct and retrievable (i.e. `contains_key` + /// Note that the keys of this storage map might become non-decodable in case the account's + /// [`NominationsQuota::MaxNominations`] configuration is decreased. In this rare case, these + /// nominators still exist in storage, their key is correct and retrievable (i.e. `contains_key` /// indicates that they exist), but their value cannot be decoded. Therefore, the non-decodable /// nominators will effectively not-exist, until they re-submit their preferences such that it /// is within the bounds of the newly set `Config::MaxNominations`. @@ -863,6 +859,8 @@ pub mod pallet { ForceEra { mode: Forcing }, /// Report of a controller batch deprecation. ControllerBatchDeprecated { failures: u32 }, + /// A set of dangling nominations have been successfully dropped. + DanglingNominationsDropped { nominator: T::AccountId, count: u32 }, } #[pallet::error] @@ -928,6 +926,12 @@ pub mod pallet { ControllerDeprecated, /// Cannot reset a ledger. CannotRestoreLedger, + /// Target is not dangling. + /// + /// A dandling target is a target that is part of the target list but is unbonded. + NotDanglingTarget, + /// Not a nominator. + NotNominator, /// Provided reward destination is not allowed. RewardDestinationRestricted, /// Not enough funds available to withdraw. @@ -1155,14 +1159,8 @@ pub mod pallet { .try_push(UnlockChunk { value, era }) .map_err(|_| Error::::NoMoreChunks)?; }; - // NOTE: ledger must be updated prior to calling `Self::weight_of`. ledger.update()?; - // update this staker in the sorted list, if they exist in it. - if T::VoterList::contains(&stash) { - let _ = T::VoterList::on_update(&stash, Self::weight_of(&stash)).defensive(); - } - Self::deposit_event(Event::::Unbonded { stash, amount: value }); } @@ -1241,7 +1239,7 @@ pub mod pallet { } } - Self::do_remove_nominator(stash); + Self::do_chill_nominator(stash); Self::do_add_validator(stash, prefs.clone()); Self::deposit_event(Event::::ValidatorPrefsSet { stash: ledger.stash, prefs }); @@ -1250,7 +1248,9 @@ pub mod pallet { /// Declare the desire to nominate `targets` for the origin controller. /// - /// Effects will be felt at the beginning of the next era. + /// The duplicate nominations will be implicitly removed. Only validators or idle stakers + /// are valid targets. If successful, the effects of this call will be felt at the + /// beginning of the next era. /// /// The dispatch origin for this call must be _Signed_ by the controller, not the stash. /// @@ -1284,7 +1284,7 @@ pub mod pallet { } } - ensure!(!targets.is_empty(), Error::::EmptyTargets); + // Check if maximum nominations quota is respected. ensure!( targets.len() <= T::NominationsQuota::get_quota(ledger.active) as usize, Error::::TooManyTargets @@ -1297,7 +1297,17 @@ pub mod pallet { .map(|t| T::Lookup::lookup(t).map_err(DispatchError::from)) .map(|n| { n.and_then(|n| { - if old.contains(&n) || !Validators::::get(&n).blocked { + // a good target nomination must be an active validator or a Idle staker. + // The validator must not be blocked. + let validator_or_idle = Self::status(&n) + .map(|status| { + status == StakerStatus::Validator || status == StakerStatus::Idle + }) + .unwrap_or(false); + + if validator_or_idle && + (old.contains(&n) || !Validators::::get(&n).blocked) + { Ok(n) } else { Err(Error::::BadTarget.into()) @@ -1305,9 +1315,17 @@ pub mod pallet { }) }) .collect::, _>>()? + // remove duplicate nominations. + .drain(..) + .collect::>() + .into_iter() + .collect::>() .try_into() .map_err(|_| Error::::TooManyNominators)?; + // Ensure final target vec is not empty. + ensure!(!targets.is_empty(), Error::::EmptyTargets); + let nominations = Nominations { targets, // Initial nominations are considered submitted at era 0. See `Nominations` doc. @@ -1315,8 +1333,9 @@ pub mod pallet { suppressed: false, }; - Self::do_remove_validator(stash); + Self::do_chill_validator(stash); Self::do_add_nominator(stash, nominations); + Ok(()) } @@ -1749,6 +1768,10 @@ pub mod pallet { if let Some(ref mut nom) = maybe_nom { if let Some(pos) = nom.targets.iter().position(|v| v == stash) { nom.targets.swap_remove(pos); + + // update nominations and trickle down to target list score. + Self::do_add_nominator(&nom_stash, nom.clone()); + Self::deposit_event(Event::::Kicked { nominator: nom_stash.clone(), stash: stash.clone(), @@ -2152,6 +2175,41 @@ pub mod pallet { ); Ok(()) } + + /// Removes nomination of a non-active validator. + /// + /// In the case that an unboded target still has nominations lingering, the approvals stake + /// for the "dangling" target needs to remain in the target list. This extrinsic allows + /// nominations of dangling targets to be removed. + /// + /// A dangling nomination may be removed IFF: + /// * The `target` is unbonded and it exists in the target list. + /// * The `voter` is nominating `target`. + #[pallet::call_index(30)] + #[pallet::weight(T::WeightInfo::drop_dangling_nomination())] + pub fn drop_dangling_nomination( + origin: OriginFor, + nominator: T::AccountId, + target: T::AccountId, + ) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin)?; + + ensure!( + Self::status(&target).is_err() && T::TargetList::contains(&target), + Error::::NotDanglingTarget + ); + + Self::do_drop_dangling_nominations(&nominator, Some(&target)) + .map(|_| { + Self::deposit_event(Event::::DanglingNominationsDropped { + nominator, + count: 1, + }); + + Pays::No.into() + }) + .map_err(|err| err.into()) + } } } diff --git a/substrate/frame/staking/src/testing_utils.rs b/substrate/frame/staking/src/testing_utils.rs index 65aaa5f09de4..d79f2a9bccce 100644 --- a/substrate/frame/staking/src/testing_utils.rs +++ b/substrate/frame/staking/src/testing_utils.rs @@ -234,6 +234,18 @@ pub fn create_validators_with_nominators_for_era( Ok(validator_chosen) } +/// Returns all the nominations associated with an account. +pub fn nominators_of( + validator: T::AccountId, +) -> Result, &'static str> { + //let acc = T::Lookup::lookup(validator).map_err(|_| "error looking up validator account")?; + + Ok(Nominators::::iter() + .filter(|(_, noms)| noms.targets.contains(&validator)) + .map(|(n, _)| n) + .collect::>()) +} + /// get the current era. pub fn current_era() -> EraIndex { >::current_era().unwrap_or(0) diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index ab2c00ca9ccc..d48e2b266004 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -39,7 +39,7 @@ use sp_runtime::{ }; use sp_staking::{ offence::{OffenceDetails, OnOffenceHandler}, - SessionIndex, + SessionIndex, StakingInterface, StakingUnchecked, }; use substrate_test_utils::assert_eq_uvec; @@ -144,6 +144,18 @@ fn kill_stash_works() { }); } +#[test] +#[should_panic = "ledger being killed before set as Idle"] +fn kill_ledger_preconditions_works() { + ExtBuilder::default().build_and_execute(|| { + // Account 11 (also controller) is stashed and locked + assert_eq!(Staking::bonded(&11), Some(11)); + // Trying to call `Ledger::kill` directly without chilling the staker before go through but + // raise alert. + assert!(StakingLedger::::kill(&11).is_ok()); + }) +} + #[test] fn basic_setup_works() { // Verifies initial conditions of mock @@ -205,17 +217,17 @@ fn basic_setup_works() { assert_eq!( Staking::eras_stakers(active_era(), &11), Exposure { - total: 1125, + total: 1375, own: 1000, - others: vec![IndividualExposure { who: 101, value: 125 }] + others: vec![IndividualExposure { who: 101, value: 375 }] }, ); assert_eq!( Staking::eras_stakers(active_era(), &21), Exposure { - total: 1375, + total: 1125, own: 1000, - others: vec![IndividualExposure { who: 101, value: 375 }] + others: vec![IndividualExposure { who: 101, value: 125 }] }, ); @@ -342,10 +354,30 @@ fn rewards_should_work() { individual: vec![(11, 100), (21, 50)].into_iter().collect(), } ); - let part_for_11 = Perbill::from_rational::(1000, 1125); - let part_for_21 = Perbill::from_rational::(1000, 1375); - let part_for_101_from_11 = Perbill::from_rational::(125, 1125); - let part_for_101_from_21 = Perbill::from_rational::(375, 1375); + + let exposure_11 = EraInfo::::get_full_exposure(active_era(), &11).total; + let exposure_21 = EraInfo::::get_full_exposure(active_era(), &21).total; + + let exposure_101_to_11 = EraInfo::::get_full_exposure(active_era(), &11) + .others + .iter() + .find(|o| o.who == 101) + .unwrap() + .value; + let exposure_101_to_21 = EraInfo::::get_full_exposure(active_era(), &21) + .others + .iter() + .find(|o| o.who == 101) + .unwrap() + .value; + + assert_eq!(exposure_101_to_11, 375); + assert_eq!(exposure_101_to_21, 125); + + let part_for_11 = Perbill::from_rational(1000, exposure_11); + let part_for_21 = Perbill::from_rational(1000, exposure_21); + let part_for_101_from_11 = Perbill::from_rational::(exposure_101_to_11, exposure_11); + let part_for_101_from_21 = Perbill::from_rational::(exposure_101_to_21, exposure_21); start_session(2); start_session(3); @@ -436,6 +468,7 @@ fn staking_should_work() { start_session(2); // add a new candidate for being a validator. account 3 controlled by 4. assert_ok!(Staking::bond(RuntimeOrigin::signed(3), 1500, RewardDestination::Account(3))); + assert_ok!(Staking::validate(RuntimeOrigin::signed(3), ValidatorPrefs::default())); assert_ok!(Session::set_keys( RuntimeOrigin::signed(3), @@ -462,14 +495,14 @@ fn staking_should_work() { // --- Block 6: the validators will now be changed. start_session(6); - assert_eq_uvec!(validator_controllers(), vec![21, 3]); + assert_eq_uvec!(validator_controllers(), vec![3, 11]); // --- Block 6: Unstake 4 as a validator, freeing up the balance stashed in 3 // 4 will chill Staking::chill(RuntimeOrigin::signed(3)).unwrap(); // --- Block 7: nothing. 3 is still there. start_session(7); - assert_eq_uvec!(validator_controllers(), vec![21, 3]); + assert_eq_uvec!(validator_controllers(), vec![3, 11]); // --- Block 8: start_session(8); @@ -507,6 +540,7 @@ fn blocking_and_kicking_works() { RuntimeOrigin::signed(11), ValidatorPrefs { blocked: true, ..Default::default() } )); + // attempt to nominate from 100/101... assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![11])); // should have worked since we're already nominated them @@ -645,7 +679,7 @@ fn nominating_and_rewards_should_work() { assert_eq!(ErasStakersPaged::::iter_prefix_values((active_era(),)).count(), 2); assert_eq!( - Staking::eras_stakers(active_era(), &11), + Staking::eras_stakers(active_era(), &21), Exposure { total: 1000 + 800, own: 1000, @@ -656,7 +690,7 @@ fn nominating_and_rewards_should_work() { }, ); assert_eq!( - Staking::eras_stakers(active_era(), &21), + Staking::eras_stakers(active_era(), &11), Exposure { total: 1000 + 1200, own: 1000, @@ -680,39 +714,68 @@ fn nominating_and_rewards_should_work() { mock::make_all_reward_payment(1); let payout_for_11 = total_payout_1 / 3; let payout_for_21 = 2 * total_payout_1 / 3; - // Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 21]'s reward. ==> + // Nominator 2: has [400/1800 ~ 2/9 from 21] + [600/2200 ~ 3/11 from 11]'s reward. ==> // 2/9 + 3/11 assert_eq_error_rate!( Balances::total_balance(&1), - initial_balance + (2 * payout_for_11 / 9 + 3 * payout_for_21 / 11), + initial_balance + (2 * payout_for_21 / 9 + 3 * payout_for_11 / 11), 2, ); - // Nominator 3: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 21]'s reward. ==> + // Nominator 3: has [400/1800 ~ 2/9 from 21] + [600/2200 ~ 3/11 from 11]'s reward. ==> // 2/9 + 3/11 assert_eq!(Balances::total_balance(&3), initial_balance); // 333 is the reward destination for 3. assert_eq_error_rate!( Balances::total_balance(&333), - 2 * payout_for_11 / 9 + 3 * payout_for_21 / 11, + 2 * payout_for_21 / 9 + 3 * payout_for_11 / 11, 2 ); - // Validator 11: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 + // Validator 21: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 assert_eq_error_rate!( - Balances::total_balance(&11), - initial_balance + 5 * payout_for_11 / 9, + Balances::total_balance(&21), + initial_balance_21 + 5 * payout_for_21 / 9, 2, ); - // Validator 21: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = + // Validator 11: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = // 5/11 assert_eq_error_rate!( - Balances::total_balance(&21), - initial_balance_21 + 5 * payout_for_21 / 11, + Balances::total_balance(&11), + initial_balance + 5 * payout_for_11 / 11, 2, ); }); } +#[test] +fn nominate_filters_duplicate_targets() { + ExtBuilder::default().build_and_execute(|| { + assert_eq!(Staking::status(&101).unwrap(), StakerStatus::Nominator(vec![11, 21])); + + // re-nominate with duplicates, which are filtered out. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![11, 11, 11, 21, 21, 21])); + assert_eq!(Staking::status(&101).unwrap(), StakerStatus::Nominator(vec![11, 21])); + }) +} + +#[test] +#[should_panic = "called `Result::unwrap()` on an `Err` value: Other(\"nominator has duplicate nominations, unexpected.\")"] +fn nominate_duplicate_targets_try_state_fails() { + ExtBuilder::default().build_and_execute(|| { + let nominations = Nominators::::get(&101).unwrap(); + assert_eq!(nominations.targets, vec![11, 21]); + + let dup_noms = Nominations { + targets: bounded_vec![11, 11, 21], + submitted_in: nominations.submitted_in, + suppressed: nominations.suppressed, + }; + Nominators::::insert(&101, dup_noms); + + assert_eq!(Staking::status(&101).unwrap(), StakerStatus::Nominator(vec![11, 11, 21])); + }); +} + #[test] fn nominators_also_get_slashed_pro_rata() { ExtBuilder::default() @@ -803,11 +866,11 @@ fn double_staking_should_fail() { ); // stash => attempting to nominate should fail. assert_noop!( - Staking::nominate(RuntimeOrigin::signed(stash), vec![1]), + Staking::nominate(RuntimeOrigin::signed(stash), vec![11]), Error::::NotController ); // controller => nominating should work. - assert_ok!(Staking::nominate(RuntimeOrigin::signed(controller), vec![1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(controller), vec![11])); }); } @@ -1915,7 +1978,8 @@ fn reap_stash_works() { // no easy way to cause an account to go below ED, we tweak their staking ledger // instead. - Ledger::::insert(11, StakingLedger::::new(11, 5)); + let ledger = StakingLedger::::new(11, 5); + assert_ok!(ledger.update()); // reap-able assert_ok!(Staking::reap_stash(RuntimeOrigin::signed(20), 11, 0)); @@ -1935,6 +1999,7 @@ fn reap_stash_works_with_existential_deposit_zero() { ExtBuilder::default() .existential_deposit(0) .balance_factor(10) + .try_state(false) .build_and_execute(|| { // given assert_eq!(Balances::balance_locked(STAKING_ID, &11), 10 * 1000); @@ -1987,10 +2052,10 @@ fn switching_roles() { // add 2 nominators assert_ok!(Staking::bond(RuntimeOrigin::signed(1), 2000, RewardDestination::Account(1))); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(1), vec![11, 5])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(1), vec![11, 31])); assert_ok!(Staking::bond(RuntimeOrigin::signed(3), 500, RewardDestination::Account(3))); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![21, 1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![21, 31])); // add a new validator candidate assert_ok!(Staking::bond(RuntimeOrigin::signed(5), 1000, RewardDestination::Account(5))); @@ -2003,16 +2068,19 @@ fn switching_roles() { mock::start_active_era(1); - // with current nominators 11 and 5 have the most stake - assert_eq_uvec!(validator_controllers(), vec![5, 11]); + // with current nominators 11 and 31 have the most stake + assert_eq_uvec!(validator_controllers(), vec![11, 31]); - // 2 decides to be a validator. Consequences: + // 1 decides to be a validator. Consequences: assert_ok!(Staking::validate(RuntimeOrigin::signed(1), ValidatorPrefs::default())); assert_ok!(Session::set_keys( RuntimeOrigin::signed(1), SessionKeys { other: 2.into() }, vec![] )); + + // now that 1 is a validator, 3 updates its nominations. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![21, 1])); // new stakes: // 11: 1000 self vote // 21: 1000 self vote + 250 vote @@ -2027,15 +2095,15 @@ fn switching_roles() { } #[test] -fn wrong_vote_is_moot() { +fn wrong_vote_errors() { ExtBuilder::default() + .nominate(true) .add_staker( 61, 61, 500, StakerStatus::Nominator(vec![ 11, 21, // good votes - 1, 2, 15, 1000, 25, // crap votes. No effect. ]), ) .build_and_execute(|| { @@ -2048,6 +2116,33 @@ fn wrong_vote_is_moot() { // our new voter is taken into account assert!(Staking::eras_stakers(active_era(), &11).others.iter().any(|i| i.who == 61)); assert!(Staking::eras_stakers(active_era(), &21).others.iter().any(|i| i.who == 61)); + + // trying to nominate a non-validator will fail. + assert_noop!( + Staking::nominate(RuntimeOrigin::signed(61), vec![11, 21, 1000]), + Error::::BadTarget + ); + + // nominating a nominator fails. + assert_eq!(Staking::status(&101), Ok(StakerStatus::Nominator(vec![11, 21]))); + assert_noop!( + Staking::nominate(RuntimeOrigin::signed(61), vec![11, 21, 101]), + Error::::BadTarget + ); + + // nominating an `Idle` validator works. + assert_eq!(Staking::status(&41), Ok(StakerStatus::Idle)); + assert_eq!(Staking::status(&31), Ok(StakerStatus::Validator)); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(61), vec![11, 21, 31, 41])); + assert_eq!( + Staking::status(&61).unwrap(), + StakerStatus::Nominator(vec![11, 21, 31, 41]) + ); + + // nominating duplicate targets does not fail, but the final nominations list is + // deduplicated. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(61), vec![11, 21, 11, 11, 21, 21])); + assert_eq!(Staking::status(&61).unwrap(), StakerStatus::Nominator(vec![11, 21])); }); } @@ -2174,6 +2269,7 @@ fn bond_with_duplicate_vote_should_be_ignored_by_election_provider() { .nominate(false) .minimum_validator_count(1) .set_stake(31, 1000) + .try_state(false) .build_and_execute(|| { // ensure all have equal stake. assert_eq!( @@ -2211,8 +2307,8 @@ fn bond_with_duplicate_vote_should_be_ignored_by_election_provider() { assert_eq!( supports, vec![ - (21, Support { total: 1800, voters: vec![(21, 1000), (1, 400), (3, 400)] }), - (31, Support { total: 2200, voters: vec![(31, 1000), (1, 600), (3, 600)] }) + (21, Support { total: 2200, voters: vec![(21, 1000), (1, 600), (3, 600)] }), + (31, Support { total: 1800, voters: vec![(31, 1000), (1, 400), (3, 400)] }), ], ); }); @@ -2226,6 +2322,7 @@ fn bond_with_duplicate_vote_should_be_ignored_by_election_provider_elected() { .nominate(false) .set_stake(31, 1000) .minimum_validator_count(1) + .try_state(false) .build_and_execute(|| { // ensure all have equal stake. assert_eq!( @@ -2284,7 +2381,7 @@ fn new_era_elects_correct_number_of_validators() { #[test] fn phragmen_should_not_overflow() { - ExtBuilder::default().nominate(false).build_and_execute(|| { + ExtBuilder::default().try_state(false).nominate(false).build_and_execute(|| { // This is the maximum value that we can have as the outcome of CurrencyToVote. type Votes = u64; @@ -2309,7 +2406,7 @@ fn phragmen_should_not_overflow() { #[test] fn reward_validator_slashing_validator_does_not_overflow() { - ExtBuilder::default().build_and_execute(|| { + ExtBuilder::default().try_state(false).build_and_execute(|| { let stake = u64::MAX as Balance * 2; let reward_slash = u64::MAX as Balance * 2; @@ -2603,7 +2700,7 @@ fn reporters_receive_their_slice() { // amount. ExtBuilder::default().build_and_execute(|| { // The reporters' reward is calculated from the total exposure. - let initial_balance = 1125; + let initial_balance = 1375; assert_eq!(Staking::eras_stakers(active_era(), &11).total, initial_balance); @@ -2630,7 +2727,7 @@ fn subsequent_reports_in_same_span_pay_out_less() { // amount, but less and less if they submit multiple reports in one span. ExtBuilder::default().build_and_execute(|| { // The reporters' reward is calculated from the total exposure. - let initial_balance = 1125; + let initial_balance = EraInfo::::get_full_exposure(active_era(), &11).total; assert_eq!(Staking::eras_stakers(active_era(), &11).total, initial_balance); @@ -2660,7 +2757,7 @@ fn subsequent_reports_in_same_span_pay_out_less() { // F1 * (reward_proportion * slash - prior_payout) // 50% * (10% * (initial_balance / 2) - prior_payout) let reward = ((initial_balance / 20) - prior_payout) / 2; - assert_eq!(Balances::free_balance(1), 10 + prior_payout + reward); + assert_eq_error_rate!(Balances::free_balance(1), 10 + prior_payout + reward, 2); }); } @@ -2882,13 +2979,13 @@ fn slashing_nominators_by_span_max() { offender: (11, Staking::eras_stakers(active_era(), &11)), reporters: vec![], }], - &[Perbill::from_percent(10)], + &[Perbill::from_percent(5)], 2, ); - assert_eq!(Balances::free_balance(11), 900); + assert_eq!(Balances::free_balance(11), 950); - let slash_1_amount = Perbill::from_percent(10) * nominated_value_11; + let slash_1_amount = Perbill::from_percent(5) * nominated_value_11; assert_eq!(Balances::free_balance(101), 2000 - slash_1_amount); let expected_spans = vec![ @@ -2908,15 +3005,15 @@ fn slashing_nominators_by_span_max() { offender: (21, Staking::eras_stakers(active_era(), &21)), reporters: vec![], }], - &[Perbill::from_percent(30)], + &[Perbill::from_percent(80)], 3, ); // 11 was not further slashed, but 21 and 101 were. - assert_eq!(Balances::free_balance(11), 900); - assert_eq!(Balances::free_balance(21), 1700); + assert_eq!(Balances::free_balance(11), 950); + assert_eq!(Balances::free_balance(21), 1200); - let slash_2_amount = Perbill::from_percent(30) * nominated_value_21; + let slash_2_amount = Perbill::from_percent(80) * nominated_value_21; assert!(slash_2_amount > slash_1_amount); // only the maximum slash in a single span is taken. @@ -2935,7 +3032,7 @@ fn slashing_nominators_by_span_max() { // 11 was further slashed, but 21 and 101 were not. assert_eq!(Balances::free_balance(11), 800); - assert_eq!(Balances::free_balance(21), 1700); + assert_eq!(Balances::free_balance(21), 1200); let slash_3_amount = Perbill::from_percent(20) * nominated_value_21; assert!(slash_3_amount < slash_2_amount); @@ -3051,7 +3148,7 @@ fn deferred_slashes_are_deferred() { Event::StakersElected, .., Event::Slashed { staker: 11, amount: 100 }, - Event::Slashed { staker: 101, amount: 12 } + Event::Slashed { staker: 101, amount: 37 } ] )); }) @@ -3084,7 +3181,7 @@ fn retroactive_deferred_slashes_two_eras_before() { Event::SlashReported { validator: 11, slash_era: 1, .. }, .., Event::Slashed { staker: 11, amount: 100 }, - Event::Slashed { staker: 101, amount: 12 } + Event::Slashed { staker: 101, amount: 37 } ] )); }) @@ -3123,7 +3220,7 @@ fn retroactive_deferred_slashes_one_before() { Event::SlashReported { validator: 11, slash_era: 2, .. }, .., Event::Slashed { staker: 11, amount: 100 }, - Event::Slashed { staker: 101, amount: 12 } + Event::Slashed { staker: 101, amount: 37 } ] )); @@ -3268,7 +3365,7 @@ fn remove_deferred() { Event::SlashReported { validator: 11, slash_era: 1, .. }, .., Event::Slashed { staker: 11, amount: 50 }, - Event::Slashed { staker: 101, amount: 7 } + Event::Slashed { staker: 101, amount: 19 } ] )); @@ -3373,8 +3470,8 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid let exposure_11 = Staking::eras_stakers(active_era(), &11); let exposure_21 = Staking::eras_stakers(active_era(), &21); - assert_eq!(exposure_11.total, 1000 + 125); - assert_eq!(exposure_21.total, 1000 + 375); + assert_eq!(exposure_11.total, 1000 + 375); + assert_eq!(exposure_21.total, 1000 + 125); on_offence_now( &[OffenceDetails { offender: (11, exposure_11.clone()), reporters: vec![] }], @@ -3392,12 +3489,12 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid slash_era: 1 }, Event::Slashed { staker: 11, amount: 100 }, - Event::Slashed { staker: 101, amount: 12 }, + Event::Slashed { staker: 101, amount: 37 }, ] ); // post-slash balance - let nominator_slash_amount_11 = 125 / 10; + let nominator_slash_amount_11 = 375 / 10; assert_eq!(Balances::free_balance(11), 900); assert_eq!(Balances::free_balance(101), 2000 - nominator_slash_amount_11); @@ -3412,11 +3509,11 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid let exposure_21 = Staking::eras_stakers(active_era(), &21); // 11's own expo is reduced. sum of support from 11 is less (448), which is 500 - // 900 + 146 - assert!(matches!(exposure_11, Exposure { own: 900, total: 1046, .. })); - // 1000 + 342 - assert!(matches!(exposure_21, Exposure { own: 1000, total: 1342, .. })); - assert_eq!(500 - 146 - 342, nominator_slash_amount_11); + // 900 + 346 + assert!(matches!(exposure_11, Exposure { own: 900, total: 1036, .. })); + // 1000 + 327 + assert!(matches!(exposure_21, Exposure { own: 1000, total: 1327, .. })); + assert_eq!(500 - 136 - 327, nominator_slash_amount_11); }); } @@ -3469,7 +3566,7 @@ fn non_slashable_offence_disables_validator() { slash_era: 1 }, Event::Slashed { staker: 21, amount: 250 }, - Event::Slashed { staker: 101, amount: 94 } + Event::Slashed { staker: 101, amount: 31 } ] ); @@ -3531,7 +3628,7 @@ fn slashing_independent_of_disabling_validator() { slash_era: 1 }, Event::Slashed { staker: 21, amount: 250 }, - Event::Slashed { staker: 101, amount: 94 } + Event::Slashed { staker: 101, amount: 31 } ] ); @@ -3666,8 +3763,13 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { let init_balance_11 = Balances::total_balance(&11); let init_balance_101 = Balances::total_balance(&101); - let part_for_11 = Perbill::from_rational::(1000, 1125); - let part_for_101 = Perbill::from_rational::(125, 1125); + let exposures = EraInfo::::get_full_exposure(active_era(), &11); + let exposure_11 = exposures.total; + let self_stake_11 = exposures.own; + let exposure_101_for_11 = exposures.others.iter().find(|o| o.who == 101).unwrap().value; + + let part_for_11 = Perbill::from_rational::(self_stake_11, exposure_11); + let part_for_101 = Perbill::from_rational::(exposure_101_for_11, exposure_11); // Check state Payee::::insert(11, RewardDestination::Account(11)); @@ -3727,13 +3829,15 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { // Era 0 can't be rewarded anymore and current era can't be rewarded yet // only era 1 and 2 can be rewarded. - assert_eq!( + assert_eq_error_rate!( Balances::total_balance(&11), init_balance_11 + part_for_11 * (total_payout_1 + total_payout_2), + 2, ); - assert_eq!( + assert_eq_error_rate!( Balances::total_balance(&101), init_balance_101 + part_for_101 * (total_payout_1 + total_payout_2), + 2, ); }); } @@ -5094,6 +5198,124 @@ fn on_finalize_weight_is_nonzero() { }) } +mod sorted_list_provider_integration { + use super::*; + use frame_election_provider_support::ScoreProvider; + use sp_staking::StakingInterface; + + #[test] + fn nominator_bond_unbond_chill_works() { + ExtBuilder::default().set_voter_list_strict().build_and_execute(|| { + Balances::make_free_balance_be(&42, 100); + + // initial stakers. + assert_eq!(VoterBagsList::iter().count(), 4); + assert_eq!(TargetBagsList::iter().count(), 3); + + assert_eq!(TargetBagsList::score(&11), 1500); + assert_eq!(TargetBagsList::score(&21), 1500); + + // bond and nominate (11, 21) with stash 42. + assert_ok!(Staking::bond(RuntimeOrigin::signed(42), 25, RewardDestination::Staked)); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(42), vec![11, 21])); + + // stash 42 is now a voter with a score. + assert_eq!(VoterBagsList::iter().count(), 5); + assert_eq!(VoterBagsList::score(&42), 25); + // but not a target. + assert_eq!(TargetBagsList::iter().count(), 3); + + // targets stake approval updated accordingly. + assert_eq!(TargetBagsList::score(&11), 1525); + assert_eq!(TargetBagsList::score(&21), 1525); + + // let's add more bond to stash and check if the scores have been updated. + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(42), 25)); + assert_eq!(VoterBagsList::score(&42), 50); + assert_eq!(TargetBagsList::score(&11), 1550); + assert_eq!(TargetBagsList::score(&21), 1550); + + // now, let's unbond partially and check if the scores have been upated. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(42), 30)); + assert_eq!(VoterBagsList::score(&42), 20); + assert_eq!(TargetBagsList::score(&11), 1520); + assert_eq!(TargetBagsList::score(&21), 1520); + + // stash 42 chills, but remains bonded. Thus it is in idle state. + assert_ok!(Staking::chill(RuntimeOrigin::signed(42))); + // idle nominators are removed from the voter list. + assert_eq!(!VoterBagsList::contains(&42), true); + assert!(>::get(&42).is_some()); + assert_ok!(>::get(StakingAccount::Stash(42))); + assert_eq!(Staking::status(&42), Ok(StakerStatus::Idle)); + + // scores of previously nominated validators were updated. + assert_eq!(TargetBagsList::score(&11), 1500); + assert_eq!(TargetBagsList::score(&21), 1500); + + // stash 42 unbonds completely by requesting all unbonding rewards and thus its ledger + // is killed. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(42), 20)); + // active bonded is 0, ledger will be killed when all the unlocking funds are withdrawn. + assert_eq!(>::get(StakingAccount::Stash(42)).unwrap().active, 0); + + // roll to block where stash can successfully withdraw unbonding chunks. + start_active_era(current_era() + BondingDuration::get()); + + // after withdrawing, the ledger is killed. + assert_ok!(Staking::withdraw_unbonded(RuntimeOrigin::signed(42), 0)); + assert!(>::get(&42).is_none()); + assert!(>::get(StakingAccount::Stash(42)).is_err()); + assert!(Staking::status(&42).is_err()); + assert_eq!(VoterBagsList::contains(&42), false); + }) + } + + #[test] + fn validator_validate_chill_works() { + ExtBuilder::default().set_voter_list_strict().build_and_execute(|| { + Balances::make_free_balance_be(&42, 100); + + // initial targets. + assert_eq!(TargetBagsList::iter().count(), 3); + assert!(!TargetBagsList::contains(&42)); + + // bond and set intention to validate. stash 42 is both target and voter. + assert_ok!(Staking::bond(RuntimeOrigin::signed(42), 25, RewardDestination::Staked)); + assert_ok!(Staking::validate(RuntimeOrigin::signed(42), Default::default())); + assert_eq!(Staking::status(&42), Ok(StakerStatus::Validator)); + + assert_eq!(TargetBagsList::score(&42), 25); + assert_eq!(VoterBagsList::score(&42), 25); + + // let's add more bond to stash and check if the scores have been updated. + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(42), 25)); + assert_eq!(TargetBagsList::score(&42), 50); + assert_eq!(VoterBagsList::score(&42), 50); + + // now, let's unbond partially and check if the scores have been upated. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(42), 30)); + assert_eq!(VoterBagsList::score(&42), 20); + assert_eq!(TargetBagsList::score(&42), 20); + + // stash 42 chills and no one nominates it, thus its score is 0 and it sis not part of + // the target bags list. In addition, it is not in the voter list. And it is `Idle` + // status. + assert_ok!(Staking::chill(RuntimeOrigin::signed(42))); + assert!(!VoterBagsList::contains(&42)); + assert!(!TargetBagsList::contains(&42)); + assert_eq!(Staking::status(&42), Ok(StakerStatus::Idle)); + // the target score of 42 is 0, since it is chilled and it has no nominations. + assert_eq!(TargetBagsList::score(&42), 0); + + // after killing the stash, the node is removed from the target list. + assert_ok!(Staking::kill_stash(&42, 0)); + assert!(!TargetBagsList::contains(&42)); + assert_eq!(>::score(&42), 0); + }) + } +} + mod election_data_provider { use super::*; use frame_election_provider_support::ElectionDataProvider; @@ -5174,7 +5396,7 @@ mod election_data_provider { assert_eq!(::VoterList::count(), 4); assert_ok!(Staking::bond(RuntimeOrigin::signed(4), 5, RewardDestination::Staked,)); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(4), vec![1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(4), vec![11])); assert_eq!(::VoterList::count(), 5); let voters_before = @@ -5413,11 +5635,11 @@ mod election_data_provider { // nominating with targets below the nomination quota works. assert_ok!(Staking::nominate(RuntimeOrigin::signed(61), vec![11])); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(61), vec![11, 12])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(61), vec![11, 21])); // nominating with targets above the nomination quota returns error. assert_noop!( - Staking::nominate(RuntimeOrigin::signed(61), vec![11, 12, 13]), + Staking::nominate(RuntimeOrigin::signed(61), vec![11, 21, 31]), Error::::TooManyTargets ); }); @@ -5426,12 +5648,14 @@ mod election_data_provider { #[test] fn lazy_quota_npos_voters_works_above_quota() { ExtBuilder::default() + .try_state(false) .nominate(false) + .has_stakers(true) .add_staker( 61, 60, 300, // 300 bond has 16 nomination quota. - StakerStatus::::Nominator(vec![21, 22, 23, 24, 25]), + StakerStatus::::Nominator(vec![11, 21, 31, 41]), ) .build_and_execute(|| { // unbond 78 from stash 60 so that it's bonded balance is 222, which has a lower @@ -5440,14 +5664,16 @@ mod election_data_provider { assert_eq!(Staking::api_nominations_quota(300 - 78), 2); // even through 61 has nomination quota of 2 at the time of the election, all the - // nominations (5) will be used. + // active nominations (4) will be used. + let expected_nominations = Staking::nominations(&61).unwrap_or(vec![]).len(); + assert_eq!( Staking::electing_voters(DataProviderBounds::default()) .unwrap() .iter() .map(|(stash, _, targets)| (*stash, targets.len())) .collect::>(), - vec![(11, 1), (21, 1), (31, 1), (61, 5)], + vec![(11, 1), (21, 1), (31, 1), (61, expected_nominations)], ); }); } @@ -5455,13 +5681,10 @@ mod election_data_provider { #[test] fn nominations_quota_limits_size_work() { ExtBuilder::default() + .try_state(false) .nominate(false) - .add_staker( - 71, - 70, - 333, - StakerStatus::::Nominator(vec![16, 15, 14, 13, 12, 11, 10]), - ) + .has_stakers(true) + .add_staker(71, 70, 333, StakerStatus::::Nominator(vec![11, 21, 31, 41])) .build_and_execute(|| { // nominations of controller 70 won't be added due to voter size limit exceeded. let bounds = ElectionBoundsBuilder::default().voters_size(100.into()).build(); @@ -5488,7 +5711,7 @@ mod election_data_provider { .iter() .map(|(stash, _, targets)| (*stash, targets.len())) .collect::>(), - vec![(11, 1), (21, 1), (31, 1), (71, 7)], + vec![(11, 1), (21, 1), (31, 1), (71, 4)], ); }); } @@ -5616,7 +5839,7 @@ fn min_bond_checks_work() { // 1000 is enough for nominator assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(3), 500)); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![11])); assert_noop!( Staking::validate(RuntimeOrigin::signed(3), ValidatorPrefs::default()), Error::::InsufficientBond, @@ -5624,7 +5847,7 @@ fn min_bond_checks_work() { // 1500 is enough for validator assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(3), 500)); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![11])); assert_ok!(Staking::validate(RuntimeOrigin::signed(3), ValidatorPrefs::default())); // Can't unbond anything as validator @@ -5634,7 +5857,7 @@ fn min_bond_checks_work() { ); // Once they are a nominator, they can unbond 500 - assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(3), vec![11])); assert_ok!(Staking::unbond(RuntimeOrigin::signed(3), 500)); assert_noop!( Staking::unbond(RuntimeOrigin::signed(3), 500), @@ -5667,7 +5890,7 @@ fn chill_other_works() { // Nominator assert_ok!(Staking::bond(RuntimeOrigin::signed(a), 1000, RewardDestination::Stash)); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(a), vec![1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(a), vec![11])); // Validator assert_ok!(Staking::bond(RuntimeOrigin::signed(b), 1500, RewardDestination::Stash)); @@ -5782,13 +6005,13 @@ fn chill_other_works() { assert_ok!(Staking::chill_other(RuntimeOrigin::signed(1337), b)); assert_ok!(Staking::chill_other(RuntimeOrigin::signed(1337), d)); } - // chill a nominator. Limit is not reached, not chill-able assert_eq!(Nominators::::count(), 7); assert_noop!( Staking::chill_other(RuntimeOrigin::signed(1337), 0), Error::::CannotChillOther ); + // chill a validator. Limit is reached, chill-able. assert_eq!(Validators::::count(), 9); assert_ok!(Staking::chill_other(RuntimeOrigin::signed(1337), 2)); @@ -5851,7 +6074,11 @@ fn capped_stakers_works() { RewardDestination::Stash, ) .unwrap(); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(controller), vec![1])); + + assert_ok!(Staking::nominate( + RuntimeOrigin::signed(controller), + vec![some_existing_validator] + )); some_existing_nominator = controller; } @@ -5863,12 +6090,15 @@ fn capped_stakers_works() { ) .unwrap(); assert_noop!( - Staking::nominate(RuntimeOrigin::signed(last_nominator), vec![1]), + Staking::nominate(RuntimeOrigin::signed(last_nominator), vec![some_existing_validator]), Error::::TooManyNominators ); // Re-nominate works fine - assert_ok!(Staking::nominate(RuntimeOrigin::signed(some_existing_nominator), vec![1])); + assert_ok!(Staking::nominate( + RuntimeOrigin::signed(some_existing_nominator), + vec![some_existing_validator] + )); // Re-validate works fine assert_ok!(Staking::validate( RuntimeOrigin::signed(some_existing_validator), @@ -5886,7 +6116,10 @@ fn capped_stakers_works() { ConfigOp::Noop, ConfigOp::Noop, )); - assert_ok!(Staking::nominate(RuntimeOrigin::signed(last_nominator), vec![1])); + assert_ok!(Staking::nominate( + RuntimeOrigin::signed(last_nominator), + vec![some_existing_validator] + )); assert_ok!(Staking::validate( RuntimeOrigin::signed(last_validator), ValidatorPrefs::default() @@ -5951,8 +6184,8 @@ fn min_commission_works() { fn change_of_absolute_max_nominations() { use frame_election_provider_support::ElectionDataProvider; ExtBuilder::default() - .add_staker(61, 61, 10, StakerStatus::Nominator(vec![1])) - .add_staker(71, 71, 10, StakerStatus::Nominator(vec![1, 2, 3])) + .add_staker(61, 61, 10, StakerStatus::Nominator(vec![11])) + .add_staker(71, 71, 10, StakerStatus::Nominator(vec![11, 21, 31])) .balance_factor(10) .build_and_execute(|| { // pre-condition @@ -6028,7 +6261,7 @@ fn change_of_absolute_max_nominations() { assert_eq!(Staking::electing_voters(bounds).unwrap().len(), 3 + 1); // now one of them can revive themselves by re-nominating to a proper value. - assert_ok!(Staking::nominate(RuntimeOrigin::signed(71), vec![1])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(71), vec![11])); assert_eq!( Nominators::::iter() .map(|(k, n)| (k, n.targets.len())) @@ -6049,11 +6282,12 @@ fn change_of_absolute_max_nominations() { fn nomination_quota_max_changes_decoding() { use frame_election_provider_support::ElectionDataProvider; ExtBuilder::default() - .add_staker(60, 61, 10, StakerStatus::Nominator(vec![1])) - .add_staker(70, 71, 10, StakerStatus::Nominator(vec![1, 2, 3])) - .add_staker(30, 330, 10, StakerStatus::Nominator(vec![1, 2, 3, 4])) - .add_staker(50, 550, 10, StakerStatus::Nominator(vec![1, 2, 3, 4])) + .add_staker(60, 61, 10, StakerStatus::Nominator(vec![11])) + .add_staker(70, 71, 10, StakerStatus::Nominator(vec![11, 21, 31])) + .add_staker(30, 330, 10, StakerStatus::Nominator(vec![11, 21, 31, 41])) + .add_staker(50, 550, 10, StakerStatus::Nominator(vec![11, 21, 31, 41])) .balance_factor(10) + .try_state(false) .build_and_execute(|| { // pre-condition. assert_eq!(MaxNominationsOf::::get(), 16); @@ -6097,7 +6331,6 @@ mod sorted_list_provider { ::VoterList::iter().collect::>(), vec![11, 21, 31, 101] ); - // when account 101 renominates assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![41])); @@ -6169,240 +6402,252 @@ fn force_apply_min_commission_works() { #[test] fn proportional_slash_stop_slashing_if_remaining_zero() { - let c = |era, value| UnlockChunk:: { era, value }; + ExtBuilder::default().build_and_execute(|| { + let c = |era, value| UnlockChunk:: { era, value }; - // we have some chunks, but they are not affected. - let unlocking = bounded_vec![c(1, 10), c(2, 10)]; + // we have some chunks, but they are not affected. + let unlocking = bounded_vec![c(1, 10), c(2, 10)]; - // Given - let mut ledger = StakingLedger::::new(123, 20); - ledger.total = 40; - ledger.unlocking = unlocking; + // Given bonded ledger + let mut ledger = Staking::ledger(StakingAccount::Stash(11)).unwrap(); + ledger.total = 40; + ledger.unlocking = unlocking; - assert_eq!(BondingDuration::get(), 3); + assert_eq!(BondingDuration::get(), 3); - // should not slash more than the amount requested, by accidentally slashing the first chunk. - assert_eq!(ledger.slash(18, 1, 0), 18); + // should not slash more than the amount requested, by accidentally slashing the first + // chunk. + assert_eq!(ledger.slash(18, 1, 0), 18); + }) } #[test] fn proportional_ledger_slash_works() { - let c = |era, value| UnlockChunk:: { era, value }; - // Given - let mut ledger = StakingLedger::::new(123, 10); - assert_eq!(BondingDuration::get(), 3); - - // When we slash a ledger with no unlocking chunks - assert_eq!(ledger.slash(5, 1, 0), 5); - // Then - assert_eq!(ledger.total, 5); - assert_eq!(ledger.active, 5); - assert_eq!(LedgerSlashPerEra::get().0, 5); - assert_eq!(LedgerSlashPerEra::get().1, Default::default()); - - // When we slash a ledger with no unlocking chunks and the slash amount is greater then the - // total - assert_eq!(ledger.slash(11, 1, 0), 5); - // Then - assert_eq!(ledger.total, 0); - assert_eq!(ledger.active, 0); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, Default::default()); - - // Given - ledger.unlocking = bounded_vec![c(4, 10), c(5, 10)]; - ledger.total = 2 * 10; - ledger.active = 0; - // When all the chunks overlap with the slash eras - assert_eq!(ledger.slash(20, 0, 0), 20); - // Then - assert_eq!(ledger.unlocking, vec![]); - assert_eq!(ledger.total, 0); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0)])); - - // Given - ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; - ledger.total = 4 * 100; - ledger.active = 0; - // When the first 2 chunks don't overlap with the affected range of unlock eras. - assert_eq!(ledger.slash(140, 0, 3), 140); - // Then - assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 30), c(7, 30)]); - assert_eq!(ledger.total, 4 * 100 - 140); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 30), (7, 30)])); - - // Given - ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; - ledger.total = 4 * 100; - ledger.active = 0; - // When the first 2 chunks don't overlap with the affected range of unlock eras. - assert_eq!(ledger.slash(15, 0, 3), 15); - // Then - assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 100 - 8), c(7, 100 - 7)]); - assert_eq!(ledger.total, 4 * 100 - 15); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 92), (7, 93)])); - - // Given - ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; - ledger.active = 500; - // 900 - ledger.total = 40 + 10 + 100 + 250 + 500; - // When we have a partial slash that touches all chunks - assert_eq!(ledger.slash(900 / 2, 0, 0), 450); - // Then - assert_eq!(ledger.active, 500 / 2); - assert_eq!(ledger.unlocking, vec![c(4, 40 / 2), c(5, 100 / 2), c(6, 10 / 2), c(7, 250 / 2)]); - assert_eq!(ledger.total, 900 / 2); - assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); - assert_eq!( - LedgerSlashPerEra::get().1, - BTreeMap::from([(4, 40 / 2), (5, 100 / 2), (6, 10 / 2), (7, 250 / 2)]) - ); + ExtBuilder::default().build_and_execute(|| { + let c = |era, value| UnlockChunk:: { era, value }; - // slash 1/4th with not chunk. - ledger.unlocking = bounded_vec![]; - ledger.active = 500; - ledger.total = 500; - // When we have a partial slash that touches all chunks - assert_eq!(ledger.slash(500 / 4, 0, 0), 500 / 4); - // Then - assert_eq!(ledger.active, 3 * 500 / 4); - assert_eq!(ledger.unlocking, vec![]); - assert_eq!(ledger.total, ledger.active); - assert_eq!(LedgerSlashPerEra::get().0, 3 * 500 / 4); - assert_eq!(LedgerSlashPerEra::get().1, Default::default()); - - // Given we have the same as above, - ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; - ledger.active = 500; - ledger.total = 40 + 10 + 100 + 250 + 500; // 900 - assert_eq!(ledger.total, 900); - // When we have a higher min balance - assert_eq!( - ledger.slash( - 900 / 2, - 25, /* min balance - chunks with era 0 & 2 will be slashed to <=25, causing it to - * get swept */ - 0 - ), - 450 - ); - assert_eq!(ledger.active, 500 / 2); - // the last chunk was not slashed 50% like all the rest, because some other earlier chunks got - // dusted. - assert_eq!(ledger.unlocking, vec![c(5, 100 / 2), c(7, 150)]); - assert_eq!(ledger.total, 900 / 2); - assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); - assert_eq!( - LedgerSlashPerEra::get().1, - BTreeMap::from([(4, 0), (5, 100 / 2), (6, 0), (7, 150)]) - ); + // Given bonded ledger + let mut ledger = Staking::ledger(StakingAccount::Stash(11)).unwrap(); + assert_eq!(BondingDuration::get(), 3); - // Given - // slash order --------------------NA--------2----------0----------1---- - ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; - ledger.active = 500; - ledger.total = 40 + 10 + 100 + 250 + 500; // 900 - assert_eq!( - ledger.slash( - 500 + 10 + 250 + 100 / 2, // active + era 6 + era 7 + era 5 / 2 - 0, - 3 /* slash era 6 first, so the affected parts are era 6, era 7 and - * ledge.active. This will cause the affected to go to zero, and then we will - * start slashing older chunks */ - ), - 500 + 250 + 10 + 100 / 2 - ); - // Then - assert_eq!(ledger.active, 0); - assert_eq!(ledger.unlocking, vec![c(4, 40), c(5, 100 / 2)]); - assert_eq!(ledger.total, 90); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 100 / 2), (6, 0), (7, 0)])); - - // Given - // iteration order------------------NA---------2----------0----------1---- - ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; - ledger.active = 100; - ledger.total = 5 * 100; - // When - assert_eq!( - ledger.slash( - 351, // active + era 6 + era 7 + era 5 / 2 + 1 - 50, // min balance - everything slashed below 50 will get dusted - 3 /* slash era 3+3 first, so the affected parts are era 6, era 7 and - * ledge.active. This will cause the affected to go to zero, and then we will - * start slashing older chunks */ - ), - 400 - ); - // Then - assert_eq!(ledger.active, 0); - assert_eq!(ledger.unlocking, vec![c(4, 100)]); - assert_eq!(ledger.total, 100); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 0), (6, 0), (7, 0)])); - - // Tests for saturating arithmetic - - // Given - let slash = u64::MAX as Balance * 2; - // The value of the other parts of ledger that will get slashed - let value = slash - (10 * 4); - - ledger.active = 10; - ledger.unlocking = bounded_vec![c(4, 10), c(5, 10), c(6, 10), c(7, value)]; - ledger.total = value + 40; - // When - let slash_amount = ledger.slash(slash, 0, 0); - assert_eq_error_rate!(slash_amount, slash, 5); - // Then - assert_eq!(ledger.active, 0); // slash of 9 - assert_eq!(ledger.unlocking, vec![]); - assert_eq!(ledger.total, 0); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0), (6, 0), (7, 0)])); - - // Given - use sp_runtime::PerThing as _; - let slash = u64::MAX as Balance * 2; - let value = u64::MAX as Balance * 2; - let unit = 100; - // slash * value that will saturate - assert!(slash.checked_mul(value).is_none()); - // but slash * unit won't. - assert!(slash.checked_mul(unit).is_some()); - ledger.unlocking = bounded_vec![c(4, unit), c(5, value), c(6, unit), c(7, unit)]; - //--------------------------------------note value^^^ - ledger.active = unit; - ledger.total = unit * 4 + value; - // When - assert_eq!(ledger.slash(slash, 0, 0), slash); - // Then - // The amount slashed out of `unit` - let affected_balance = value + unit * 4; - let ratio = - Perquintill::from_rational_with_rounding(slash, affected_balance, Rounding::Up).unwrap(); - // `unit` after the slash is applied - let unit_slashed = { - let unit_slash = ratio.mul_ceil(unit); - unit - unit_slash - }; - let value_slashed = { - let value_slash = ratio.mul_ceil(value); - value - value_slash - }; - assert_eq!(ledger.active, unit_slashed); - assert_eq!(ledger.unlocking, vec![c(5, value_slashed), c(7, 32)]); - assert_eq!(ledger.total, value_slashed + 32); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!( - LedgerSlashPerEra::get().1, - BTreeMap::from([(4, 0), (5, value_slashed), (6, 0), (7, 32)]) - ); + assert_eq!(ledger.total, 1000); + + // When we slash a ledger with no unlocking chunks + assert_eq!(ledger.slash(5, 1, 0), 5); + + // Then + assert_eq!(ledger.total, 995); + assert_eq!(ledger.active, 995); + assert_eq!(LedgerSlashPerEra::get().0, 995); + assert_eq!(LedgerSlashPerEra::get().1, Default::default()); + + // When we slash a ledger with no unlocking chunks and the slash amount is greater then the + // total + assert_eq!(ledger.slash(2000, 1, 0), 995); + // Then + assert_eq!(ledger.total, 0); + assert_eq!(ledger.active, 0); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, Default::default()); + + // Given + ledger.unlocking = bounded_vec![c(4, 10), c(5, 10)]; + ledger.total = 2 * 10; + ledger.active = 0; + // When all the chunks overlap with the slash eras + assert_eq!(ledger.slash(20, 0, 0), 20); + // Then + assert_eq!(ledger.unlocking, vec![]); + assert_eq!(ledger.total, 0); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0)])); + + // Given + ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; + ledger.total = 4 * 100; + ledger.active = 0; + // When the first 2 chunks don't overlap with the affected range of unlock eras. + assert_eq!(ledger.slash(140, 0, 3), 140); + // Then + assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 30), c(7, 30)]); + assert_eq!(ledger.total, 4 * 100 - 140); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 30), (7, 30)])); + + // Given + ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; + ledger.total = 4 * 100; + ledger.active = 0; + // When the first 2 chunks don't overlap with the affected range of unlock eras. + assert_eq!(ledger.slash(15, 0, 3), 15); + // Then + assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 100 - 8), c(7, 100 - 7)]); + assert_eq!(ledger.total, 4 * 100 - 15); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 92), (7, 93)])); + + // Given + ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; + ledger.active = 500; + // 900 + ledger.total = 40 + 10 + 100 + 250 + 500; + // When we have a partial slash that touches all chunks + assert_eq!(ledger.slash(900 / 2, 0, 0), 450); + // Then + assert_eq!(ledger.active, 500 / 2); + assert_eq!( + ledger.unlocking, + vec![c(4, 40 / 2), c(5, 100 / 2), c(6, 10 / 2), c(7, 250 / 2)] + ); + assert_eq!(ledger.total, 900 / 2); + assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); + assert_eq!( + LedgerSlashPerEra::get().1, + BTreeMap::from([(4, 40 / 2), (5, 100 / 2), (6, 10 / 2), (7, 250 / 2)]) + ); + + // slash 1/4th with not chunk. + ledger.unlocking = bounded_vec![]; + ledger.active = 500; + ledger.total = 500; + // When we have a partial slash that touches all chunks + assert_eq!(ledger.slash(500 / 4, 0, 0), 500 / 4); + // Then + assert_eq!(ledger.active, 3 * 500 / 4); + assert_eq!(ledger.unlocking, vec![]); + assert_eq!(ledger.total, ledger.active); + assert_eq!(LedgerSlashPerEra::get().0, 3 * 500 / 4); + assert_eq!(LedgerSlashPerEra::get().1, Default::default()); + + // Given we have the same as above, + ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; + ledger.active = 500; + ledger.total = 40 + 10 + 100 + 250 + 500; // 900 + assert_eq!(ledger.total, 900); + // When we have a higher min balance + assert_eq!( + ledger.slash( + 900 / 2, + 25, /* min balance - chunks with era 0 & 2 will be slashed to <=25, causing it + * to get swept */ + 0 + ), + 450 + ); + assert_eq!(ledger.active, 500 / 2); + // the last chunk was not slashed 50% like all the rest, because some other earlier chunks + // got dusted. + assert_eq!(ledger.unlocking, vec![c(5, 100 / 2), c(7, 150)]); + assert_eq!(ledger.total, 900 / 2); + assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); + assert_eq!( + LedgerSlashPerEra::get().1, + BTreeMap::from([(4, 0), (5, 100 / 2), (6, 0), (7, 150)]) + ); + + // Given + // slash order --------------------NA--------2----------0----------1---- + ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; + ledger.active = 500; + ledger.total = 40 + 10 + 100 + 250 + 500; // 900 + assert_eq!( + ledger.slash( + 500 + 10 + 250 + 100 / 2, // active + era 6 + era 7 + era 5 / 2 + 0, + 3 /* slash era 6 first, so the affected parts are era 6, era 7 and + * ledge.active. This will cause the affected to go to zero, and then we will + * start slashing older chunks */ + ), + 500 + 250 + 10 + 100 / 2 + ); + // Then + assert_eq!(ledger.active, 0); + assert_eq!(ledger.unlocking, vec![c(4, 40), c(5, 100 / 2)]); + assert_eq!(ledger.total, 90); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 100 / 2), (6, 0), (7, 0)])); + + // Given + // iteration order------------------NA---------2----------0----------1---- + ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; + ledger.active = 100; + ledger.total = 5 * 100; + // When + assert_eq!( + ledger.slash( + 351, // active + era 6 + era 7 + era 5 / 2 + 1 + 50, // min balance - everything slashed below 50 will get dusted + 3 /* slash era 3+3 first, so the affected parts are era 6, era 7 and + * ledge.active. This will cause the affected to go to zero, and then we + * will start slashing older chunks */ + ), + 400 + ); + // Then + assert_eq!(ledger.active, 0); + assert_eq!(ledger.unlocking, vec![c(4, 100)]); + assert_eq!(ledger.total, 100); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 0), (6, 0), (7, 0)])); + + // Tests for saturating arithmetic + + // Given + let slash = u64::MAX as Balance * 2; + // The value of the other parts of ledger that will get slashed + let value = slash - (10 * 4); + + ledger.active = 10; + ledger.unlocking = bounded_vec![c(4, 10), c(5, 10), c(6, 10), c(7, value)]; + ledger.total = value + 40; + // When + let slash_amount = ledger.slash(slash, 0, 0); + assert_eq_error_rate!(slash_amount, slash, 5); + // Then + assert_eq!(ledger.active, 0); // slash of 9 + assert_eq!(ledger.unlocking, vec![]); + assert_eq!(ledger.total, 0); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0), (6, 0), (7, 0)])); + + // Given + use sp_runtime::PerThing as _; + let slash = u64::MAX as Balance * 2; + let value = u64::MAX as Balance * 2; + let unit = 100; + // slash * value that will saturate + assert!(slash.checked_mul(value).is_none()); + // but slash * unit won't. + assert!(slash.checked_mul(unit).is_some()); + ledger.unlocking = bounded_vec![c(4, unit), c(5, value), c(6, unit), c(7, unit)]; + //--------------------------------------note value^^^ + ledger.active = unit; + ledger.total = unit * 4 + value; + // When + assert_eq!(ledger.slash(slash, 0, 0), slash); + // Then + // The amount slashed out of `unit` + let affected_balance = value + unit * 4; + let ratio = Perquintill::from_rational_with_rounding(slash, affected_balance, Rounding::Up) + .unwrap(); + // `unit` after the slash is applied + let unit_slashed = { + let unit_slash = ratio.mul_ceil(unit); + unit - unit_slash + }; + let value_slashed = { + let value_slash = ratio.mul_ceil(value); + value - value_slash + }; + assert_eq!(ledger.active, unit_slashed); + assert_eq!(ledger.unlocking, vec![c(5, value_slashed), c(7, 32)]); + assert_eq!(ledger.total, value_slashed + 32); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!( + LedgerSlashPerEra::get().1, + BTreeMap::from([(4, 0), (5, value_slashed), (6, 0), (7, 32)]) + ); + }) } #[test] @@ -7150,6 +7395,215 @@ mod staking_unchecked { assert_eq!(VirtualStakers::::contains_key(10), false); }) } +} + +mod on_staking_update_events { + use super::*; + + use sp_staking::{OnStakingUpdateEvent::*, Stake}; + + #[test] + fn on_nominator_lifecycle_emit_works() { + ExtBuilder::default().has_stakers(false).nominate(false).build_and_execute(|| { + // no events yet. + ensure_on_staking_updates_emitted(vec![]); + + // bond validator 11 and 12. + bond_validator(11, 100); + bond_validator(12, 100); + ensure_on_staking_updates_emitted(vec![ + StakeUpdate { who: 11, prev_stake: None, stake: Stake { total: 100, active: 100 } }, + ValidatorAdd { who: 11, self_stake: Stake { total: 100, active: 100 } }, + StakeUpdate { who: 12, prev_stake: None, stake: Stake { total: 100, active: 100 } }, + ValidatorAdd { who: 12, self_stake: Stake { total: 100, active: 100 } }, + ]); + + // bond staker 21. + bond(21, 100); + ensure_on_staking_updates_emitted(vec![StakeUpdate { + who: 21, + prev_stake: None, + stake: Stake { total: 100, active: 100 }, + }]); + + // staker 21 nominates 11. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(21), vec![11])); + ensure_on_staking_updates_emitted(vec![NominatorAdd { + who: 21, + nominations: vec![11], + }]); + + // 21 updates nominations. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(21), vec![12])); + ensure_on_staking_updates_emitted(vec![NominatorUpdate { + who: 21, + prev_nominations: vec![11], + nominations: vec![12], + }]); + + // 21 unbonds half of its stake. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(21), 50)); + ensure_on_staking_updates_emitted(vec![StakeUpdate { + who: 21, + prev_stake: Some(Stake { total: 100, active: 100 }), + // 50 unlocking, 50 active. + stake: Stake { total: 100, active: 50 }, + }]); + + // 21 chills. + assert_ok!(Staking::chill(RuntimeOrigin::signed(21))); + ensure_on_staking_updates_emitted(vec![NominatorRemove { + who: 21, + nominations: vec![12], + }]); + + // 21 unbnonds completely. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(21), 50)); + ensure_on_staking_updates_emitted(vec![StakeUpdate { + who: 21, + prev_stake: Some(Stake { total: 100, active: 50 }), + stake: Stake { total: 100, active: 0 }, + }]); + + // roll to era where full withdraw can happen. + start_active_era(current_era() + BondingDuration::get()); + + // 21 withdraws all unlocked funds to kill the stash/ unstake. + assert_ok!(Staking::withdraw_unbonded(RuntimeOrigin::signed(21), 0)); + ensure_on_staking_updates_emitted(vec![ + ValidatorRemove { who: 21 }, + Unstake { who: 21 }, + Withdraw { who: 21, amount: 100 }, + ]); + }) + } + + #[test] + fn on_validator_lifecycle_emit_works() { + ExtBuilder::default().build_and_execute(|| { + // reset `OnStakingUpdate` events from genesis. + EventsEmitted::set(vec![]); + ensure_on_staking_updates_emitted(vec![]); + + // bond validator 42. + bond_validator(42, 100); + ensure_on_staking_updates_emitted(vec![ + StakeUpdate { who: 42, prev_stake: None, stake: Stake { total: 100, active: 100 } }, + ValidatorAdd { who: 42, self_stake: Stake { total: 100, active: 100 } }, + ]); + + // 42 bonds 50 extra. + let _ = Balances::make_free_balance_be(&42, 500); + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(42), 50)); + ensure_on_staking_updates_emitted(vec![StakeUpdate { + who: 42, + prev_stake: Some(Stake { total: 100, active: 100 }), + stake: Stake { total: 150, active: 150 }, + }]); + + // 42 unbonds 50. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(42), 50)); + ensure_on_staking_updates_emitted(vec![StakeUpdate { + who: 42, + prev_stake: Some(Stake { total: 150, active: 150 }), + stake: Stake { total: 150, active: 100 }, + }]); + + // 101 nominates 42. + let prev_nominations = Staking::nominations(&101).unwrap(); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![42])); + ensure_on_staking_updates_emitted(vec![NominatorUpdate { + who: 101, + prev_nominations, + nominations: vec![42], + }]); + + // 42 chills. + assert_ok!(Staking::chill(RuntimeOrigin::signed(42))); + ensure_on_staking_updates_emitted(vec![ValidatorIdle { who: 42 }]); + + // 42 unbounds completely. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(42), 100)); + ensure_on_staking_updates_emitted(vec![StakeUpdate { + who: 42, + prev_stake: Some(Stake { total: 150, active: 100 }), + stake: Stake { total: 150, active: 0 }, + }]); + + // roll to era where full withdraw can happen. + start_active_era(current_era() + BondingDuration::get()); + + // 11 withdraws all unlocked funds to kill the stash/ unstake. + assert_ok!(Staking::withdraw_unbonded(RuntimeOrigin::signed(42), 0)); + ensure_on_staking_updates_emitted(vec![ + ValidatorRemove { who: 42 }, + Unstake { who: 42 }, + Withdraw { who: 42, amount: 150 }, + ]); + }) + } + + #[test] + fn force_unstake_emit_works() { + ExtBuilder::default().has_stakers(false).nominate(false).build_and_execute(|| { + // set stakers + bond_validator(11, 100); + bond_nominator(101, 100, vec![11]); + + // reset `OnStakingUpdate` events up to now. + EventsEmitted::set(vec![]); + ensure_on_staking_updates_emitted(vec![]); + + // force unstake of a validator. + assert_ok!(Staking::force_unstake(RuntimeOrigin::root(), 11, 0)); + ensure_on_staking_updates_emitted(vec![ + ValidatorIdle { who: 11 }, + ValidatorRemove { who: 11 }, + Unstake { who: 11 }, + ]); + + // force unstake of a nominator. + assert_ok!(Staking::force_unstake(RuntimeOrigin::root(), 101, 0)); + ensure_on_staking_updates_emitted(vec![ + NominatorRemove { who: 101, nominations: vec![11] }, + Unstake { who: 101 }, + ]); + }) + } + + #[test] + fn slash_emit_works() { + ExtBuilder::default().has_stakers(false).nominate(false).build_and_execute(|| { + // set stakers + bond_validator(11, 100); + bond_nominator(101, 100, vec![11]); + + // reset `OnStakingUpdate` events up to now. + EventsEmitted::set(vec![]); + ensure_on_staking_updates_emitted(vec![]); + + // progress a few eras and then slash 11. + start_active_era(5); + add_slash(&11); + + ensure_on_staking_updates_emitted(vec![ + Slash { who: 11, slashed_active: 90, slashed_total: 10 }, + // slash applied on the validator stake. + StakeUpdate { + who: 11, + prev_stake: Some(Stake { total: 100, active: 100 }), + stake: Stake { total: 90, active: 90 }, + }, + Slash { who: 101, slashed_active: 90, slashed_total: 10 }, + // slash applied on the nominator stake. + StakeUpdate { + who: 101, + prev_stake: Some(Stake { total: 100, active: 100 }), + stake: Stake { total: 90, active: 90 }, + }, + ]); + }) + } #[test] fn virtual_staker_cannot_pay_reward_to_self_account() { @@ -7251,6 +7705,7 @@ mod staking_unchecked { let initial_exposure = Staking::eras_stakers(active_era(), &11); // 101 is a nominator for 11 assert_eq!(initial_exposure.others.first().unwrap().who, 101); + // make 101 a virtual nominator ::migrate_to_virtual_staker(&101); // set payee different to self. @@ -7326,6 +7781,7 @@ mod staking_unchecked { let initial_exposure = Staking::eras_stakers(active_era(), &11); // 101 is a nominator for 11 assert_eq!(initial_exposure.others.first().unwrap().who, 101); + // make 101 a virtual nominator ::migrate_to_virtual_staker(&101); // set payee different to self. @@ -7366,6 +7822,7 @@ mod staking_unchecked { // validator can be reaped. assert_ok!(Staking::reap_stash(RuntimeOrigin::signed(10), 11, u32::MAX)); + // nominator is a virtual staker and cannot be reaped. assert_noop!( Staking::reap_stash(RuntimeOrigin::signed(10), 101, u32::MAX), @@ -7399,6 +7856,880 @@ mod staking_unchecked { }) } } + +mod stake_tracker { + use super::*; + use frame_election_provider_support::ScoreProvider; + use pallet_bags_list::Event as BagsEvent; + use sp_staking::{StakingAccount::*, StakingInterface}; + + // keep tests clean; + type A = AccountId; + + #[test] + fn duplicate_nominations_dedup_approvals_works() { + ExtBuilder::default() + .add_staker(100, 100, 1_000, StakerStatus::Nominator(vec![11])) + .build_and_execute(|| { + // 11 is a validator. + assert_eq!(Staking::status(&11), Ok(StakerStatus::Validator)); + + // currently, 101 and 100 nominates 11. + assert_eq!(nominators_of(&11), vec![101, 100]); + + // current approvals is the self stake + 101 + 100 active stakes, as expected. + assert_eq!( + TargetBagsList::score(&11), + Staking::active_stake(&11).unwrap() + + Staking::active_stake(&101).unwrap() + + Staking::active_stake(&100).unwrap() + ); + + // change nominations of 101 to nominate 11 with duplicates. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![11, 11, 11])); + assert_eq!(nominators_of(&11), vec![101, 100]); + + // however, the nominations are dedup. + assert_eq!(Nominators::::get(&101).unwrap().targets, vec![11]); + // the approvals stake of 11 is self_stake + active stake of 101 and 100. duplicate + // nominations in the same voter are dedup. + assert_eq!( + TargetBagsList::score(&11), + Staking::active_stake(&11).unwrap() + + Staking::active_stake(&101).unwrap() + + Staking::active_stake(&100).unwrap() + ); + + // when bonding extra, the dedup nominations are also not counted in the approvals. + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(101), 500)); + assert_eq!( + TargetBagsList::score(&11), + Staking::active_stake(&11).unwrap() + + Staking::active_stake(&101).unwrap() + + Staking::active_stake(&100).unwrap() + ); + + // same when nominator with duplicate nominations unbonds stake. + assert_ok!(Staking::chill(RuntimeOrigin::signed(101))); + assert_eq!(Staking::status(&101), Ok(StakerStatus::Idle)); + + // 101 is not nominator of 11 anymore. + assert_eq!(nominators_of(&11), vec![100]); + assert_eq!( + TargetBagsList::score(&11), + Staking::active_stake(&11).unwrap() + Staking::active_stake(&100).unwrap() + ); + }) + } + + #[test] + fn total_slash_and_reap_target_works() { + // Test case: a validator and *ALL* its nominators are 100% slashed. The target score drops + // to 0. After calling reap_stash on the validator, the target list node is removed and *NO* + // nominations are left behind. + ExtBuilder::default() + // we need enough validators such that disables are allowed. + .validator_count(7) + .set_status(41, StakerStatus::Validator) + .set_status(51, StakerStatus::Validator) + .set_status(201, StakerStatus::Validator) + .set_status(202, StakerStatus::Validator) + .build_and_execute(|| { + // make 101 only nominate 11. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![11])); + mock::start_active_era(1); + + // slash all stake. + let slash_percent = Perbill::from_percent(100); + let initial_exposure = Staking::eras_stakers(active_era(), &11); + // 101 is a nominator for 11 + assert_eq!(initial_exposure.others.first().unwrap().who, 101); + + let validator_balance = Balances::free_balance(&11); + let validator_stake = Staking::ledger(11.into()).unwrap().total; + + // target score is as expected. + assert_eq!( + TargetBagsList::score(&11), + Staking::active_stake(&11).unwrap() + Staking::active_stake(&101).unwrap() + ); + + on_offence_now( + &[OffenceDetails { + offender: (11, initial_exposure.clone()), + reporters: vec![], + }], + &[slash_percent], + ); + + // both stakes must have been decreased to 0. + assert_eq!(Staking::ledger(101.into()).unwrap().active, 0); + assert_eq!(Staking::ledger(11.into()).unwrap().active, 0); + + // all validator stake is slashed + assert_eq_error_rate!( + validator_balance - validator_stake, + Balances::free_balance(&11), + 1 + ); + assert!(is_disabled(11)); + + // target score is decreased as expected, down to 0. + assert_eq!(TargetBagsList::score(&11), 0); + assert_eq!( + TargetBagsList::score(&11), + Staking::active_stake(&11).unwrap() + Staking::active_stake(&101).unwrap() + ); + + // since the active take of the nominator dropped to 0 after the slash,, it has been + // chilled. + assert_eq!(Staking::status(&101), Ok(StakerStatus::Idle)); + + // reap validator stash works. + assert_ok!(Staking::reap_stash(RuntimeOrigin::signed(10), 11, u32::MAX)); + + // 11 is not a nominator/validator anymore. + assert!(Staking::status(&11).is_err()); + assert_eq!(TargetBagsList::score(&11), 0); + }) + } + + #[test] + fn virtual_nomination_works() { + ExtBuilder::default().build_and_execute(|| { + // make 101 only nominate 11. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![11])); + + // make 101 a virtual nominator + ::migrate_to_virtual_staker(&101); + assert_ok!(::set_payee(&101, &102)); + assert_eq!(Pallet::::is_virtual_staker(&101), true); + + // as a virtual nominator, 101 nominates 31 too. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![11, 31])); + + let stake_101 = Staking::active_stake(&101).unwrap(); + + // target score of 11 is the sum of self stake and 101 bond. + assert_eq!(TargetBagsList::score(&11), Staking::active_stake(&11).unwrap() + stake_101); + // same for 31. + assert_eq!(TargetBagsList::score(&31), Staking::active_stake(&31).unwrap() + stake_101); + + assert_ok!(Staking::chill(RuntimeOrigin::signed(101))); + assert_ok!(Staking::kill_stash(&101, 0)); + + // target scores updated once virtual nominator unbonded. + assert_eq!(TargetBagsList::score(&11), Staking::active_stake(&11).unwrap()); + assert_eq!(TargetBagsList::score(&31), Staking::active_stake(&31).unwrap()); + }) + } + + #[test] + fn add_remove_nomination_works() { + // Test case: a new nomination affects the stake behind the target in the target list and + // the sorting of the target list is also updated. Chilling the nomination will update the + // target list scores and rebag back to the original state. + // Call paths covered: + // * Call::validate() + // * Call::nominate() + // * Call::chill() + ExtBuilder::default().has_stakers(false).nominate(false).build_and_execute(|| { + // add validator 12. + let _ = Balances::deposit_creating(&12, 150); + assert_ok!(Staking::bond( + RuntimeOrigin::signed(12), + 150, + RewardDestination::Account(12), + )); + + assert_ok!(Staking::validate(RuntimeOrigin::signed(12), Default::default())); + + // 12 is a validator and has 150 self-vote. + assert_eq!(::status(&12), Ok(StakerStatus::Validator)); + assert_eq!(>::get_score(&12), Ok(150)); + + // add validator 11. + let _ = Balances::deposit_creating(&11, 100); + assert_ok!(Staking::bond( + RuntimeOrigin::signed(11), + 100, + RewardDestination::Account(11), + )); + assert_ok!(Staking::validate(RuntimeOrigin::signed(11), Default::default())); + + // 11 is a validator and has 100 self-vote. + assert_eq!(::status(&11), Ok(StakerStatus::Validator)); + assert_eq!(>::get_score(&11), Ok(100)); + + // the target list is sorted by stake: [(12, 150), (11, 100)] + assert_eq!(voters_and_targets().1, [(12, 150), (11, 100)]); + + // no rebags in the target list so far. + assert!(target_bags_events().is_empty()); + + // add nominator 1, which nominates 11. + let _ = Balances::deposit_creating(&1, 300); + assert_ok!(Staking::bond(RuntimeOrigin::signed(1), 300, RewardDestination::Account(1))); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(1), vec![11])); + + // 1 is a nominator and nominates 11 with 300 stake. + assert_eq!( + ::status(&1), + Ok(StakerStatus::Nominator(vec![11])) + ); + assert_eq!(>::get_score(&1), Ok(300)); + + // rebag in the target list happened as expected. + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 11, from: 100, to: 400 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 400 } + ] + ); + assert_eq!(voters_and_targets().1, [(11, 400), (12, 150)]); + + System::reset_events(); + + // chill nominator 1. + assert_ok!(Staking::chill(RuntimeOrigin::signed(1))); + + // the target list is sorted by stake, similar to before nomination: [(12, 150), (11, + // 100)] + assert_eq!(voters_and_targets().1, [(12, 150), (11, 100)]); + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 11, from: 400, to: 100 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 100 } + ] + ); + + // since 1 was a nominator and it is chilled, it has been removed from the voter list. + assert!(!VoterBagsList::contains(&1)); + assert_eq!(Staking::status(&1), Ok(StakerStatus::Idle)); + + // killing the stash updates the staker's status. + assert_ok!(Staking::kill_stash(&1, 0)); + assert!(Staking::status(&1).is_err()); + }) + } + + #[test] + fn bond_and_unbond_work() { + // Test case: unbond on validator and nominator affects the target list score + // accordingly and rebagging may happen. + // Call paths covered: + // * Call::validate() + // * Call::nominate() + // * Call::bond() + // * Call::unbond() + ExtBuilder::default().build_and_execute(|| { + // bond and nominate with stash 61. + assert_ok!(Staking::bond(RuntimeOrigin::signed(61), 500, RewardDestination::Staked)); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(61), vec![31])); + + let score_31 = >::score(&31); + let self_stake_31 = Staking::ledger(Stash(31)).unwrap().active; + let self_stake_61 = Staking::ledger(Stash(61)).unwrap().active; + + // new score of 31 is the self stake + 61 stake from nomination. + assert_eq!(score_31, self_stake_31 + self_stake_61); + + // 61 nominating 31 reflected as a target list score update and rebag. + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 31, from: 500, to: 1000 }, + BagsEvent::ScoreUpdated { who: 31, new_score: score_31 } + ] + ); + System::reset_events(); + + // now we unbond a portion of the stake of 61. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(61), 250)); + + // score of 61 was updated after unbonding. + assert_eq!(>::score(&31), score_31 - 250); + + // nominator unbonding was not enough to rebag 31 but score was updated, as expected. + assert_eq!( + target_bags_events(), + [BagsEvent::ScoreUpdated { who: 31, new_score: score_31 - 250 }] + ); + }) + } + + #[test] + fn bond_extra_works() { + // Test case: bonding extra on validator and nominator affects the target list score + // accordingly and rebagging may happen. + // Call paths covered: + // * Call::validate() + // * Call::nominate() + // * Call::bond_extra() + ExtBuilder::default() + .add_staker(100, 100, 100, StakerStatus::Nominator(vec![31])) + .build_and_execute(|| { + // target score of 31 is the sum of own stake and nominations stake. + let own_stake = Staking::ledger(Stash(31)).unwrap().active; + let other_stake = Staking::ledger(Stash(100)).unwrap().active; + assert_eq!( + >::get_score(&31), + Ok(own_stake + other_stake) + ); + + // target list is sorted by score. + assert_eq!( + voters_and_targets().1, + [(11, 1500), (21, 1500), (31, own_stake + other_stake)] + ); + + // 100, which nominates 31, bonds 1500 extra. + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(100), 1500)); + assert_eq!(Staking::ledger(Stash(100)).unwrap().active, 1600); + + // target score of 31 has increased by 1500, although own stake remained the same. + assert_eq!(own_stake, Staking::ledger(Stash(31)).unwrap().active); + assert_eq!( + >::get_score(&31), + Ok(own_stake + other_stake + 1500) + ); + + // target score of 31 is higher than the remaining of the targets, rebagging + // happened. + assert_eq!( + voters_and_targets().1, + [(31, own_stake + other_stake + 1500), (11, 1500), (21, 1500)] + ); + + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 31, from: 600, to: 10000 }, + BagsEvent::ScoreUpdated { + who: 31, + new_score: own_stake + other_stake + 1500 + } + ] + ); + System::reset_events(); + + // and now, validator 21 (nominated by 101) also bonds extra self-stake. + let own_stake = Staking::ledger(Stash(21)).unwrap().active; + let other_stake = Staking::ledger(Stash(101)).unwrap().active; + + assert_eq!( + >::get_score(&21), + Ok(own_stake + other_stake) // 1500 + ); + + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(21), 300)); + + // updates to 21 target score are as expected. + assert_eq!(Staking::ledger(Stash(21)).unwrap().active, own_stake + 300); + assert_eq!( + >::get_score(&21), + Ok(own_stake + other_stake + 300) + ); + + // although 21 increased in target score, there was no rebagging due to the new + // score not being high enough to move the the next bag, given thresholds (1_000 + // -> 2_000)). + assert_eq!(voters_and_targets().1, [(31, 2100), (11, 1500), (21, 1800)]); + + assert_eq!( + target_bags_events(), + [BagsEvent::ScoreUpdated { who: 21, new_score: own_stake + other_stake + 300 }] + ); + }) + } + + #[test] + fn chill_works() { + // Test case: kicking and chilling nominators and validators affects the target list score + // and rebagging may happen. + // Call paths covered: + // * Call::validate() + // * Call::nominate() + // * Call::chill() + ExtBuilder::default().build_and_execute(|| { + // bond extra to rebag nominated validator. + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(101), 600)); + System::reset_events(); + + // 101 nominates both 11 and 21. + assert_eq!(Staking::status(&101), Ok(StakerStatus::Nominator(vec!(11, 21)))); + // with score + let nominated_score = Staking::active_stake(&101); + assert_eq!(nominated_score, Ok(1100)); + + let score_11_before = >::score(&11); + let score_21_before = >::score(&21); + + assert_eq!(voters_and_targets().1, [(11, 2100), (21, 2100), (31, 500)]); + + // now chill 101. + assert_ok!(Staking::chill(RuntimeOrigin::signed(101))); + assert_eq!(Staking::status(&101), Ok(StakerStatus::Idle)); + + // the target scores of 11 and 21 are the previous score - the nominated score of the + // chilled nominator. + let score_11_after = >::score(&11); + let score_21_after = >::score(&21); + assert_eq!(score_11_after, score_11_before - nominated_score.unwrap()); + assert_eq!(score_21_after, score_21_before - nominated_score.unwrap()); + + // now the target score of 11 and 21 is only the self-stake. + assert_eq!(voters_and_targets().1, [(11, 1000), (21, 1000), (31, 500)]); + assert_eq!(score_11_after, Staking::ledger(Stash(11)).unwrap().active); + assert_eq!(score_21_after, Staking::ledger(Stash(11)).unwrap().active); + + // and we confirm the rebag happened as expected. + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 11, from: 10000, to: 1000 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 1000 }, + BagsEvent::Rebagged { who: 21, from: 10000, to: 1000 }, + BagsEvent::ScoreUpdated { who: 21, new_score: 1000 }, + ] + ); + System::reset_events(); + + // let's chill a validator now. + assert_ok!(Staking::chill(RuntimeOrigin::signed(11))); + + // the chilled validator score drops to 0, since it had only self-stake before chill. + assert_eq!(>::score(&11), 0); + + // since score of 11 is 0, it is removed from the target list. Since it is idle, it is + // nor part of the nominator and validator lists. + assert_eq!(Staking::status(&11), Ok(StakerStatus::Idle)); + assert_eq!(voters_and_targets().1, [(21, 1000), (31, 500)]); + assert!(!Nominators::::contains_key(&11)); + assert!(!Validators::::contains_key(&11)); + + // now, let's have 101 re-nominate 21. Note that 101 also nominates 11: even + // though 11 is chilled at the moment. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![21, 11])); + assert_eq!(voters_and_targets().1, [(21, 2100), (11, 1100), (31, 500)]); + + // score update and rebag hapened to 21 and 11 (idle) due to nomination of 101. + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 11, from: 100, to: 2000 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 1100 }, + BagsEvent::Rebagged { who: 21, from: 1000, to: 10000 }, + BagsEvent::ScoreUpdated { who: 21, new_score: 2100 }, + ] + ); + + assert_eq!(Staking::status(&21).unwrap(), StakerStatus::Validator); + assert_eq!(Staking::status(&11).unwrap(), StakerStatus::Idle); + }) + } + + #[test] + fn kick_works() { + // Test case: kicking a nominator affects the target list score and rebagging may happen. + // Call paths covered: + // * Call::validate() + // * Call::nominate() + // * Call::kick() + ExtBuilder::default().build_and_execute(|| { + // bond extra to rebag nominated validator. + assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(101), 600)); + System::reset_events(); + + // 101 nominates both 11 and 21. + assert_eq!(Staking::status(&101), Ok(StakerStatus::Nominator(vec!(11, 21)))); + // with score + let nominated_score = Staking::active_stake(&101).unwrap(); + assert_eq!(nominated_score, 1100); + + let score_11_before = >::score(&11); + let score_21_before = >::score(&21); + + assert_eq!( + voters_and_targets().1, + [(11, score_11_before), (21, score_21_before), (31, 500)] + ); + + // kick 101 from nominating 21. + assert_ok!(Staking::kick(RuntimeOrigin::signed(21), vec![101])); + + // target list was updated as expected, rebagging 21. + assert_eq!( + voters_and_targets().1, + [(11, score_11_before), (21, score_21_before - nominated_score), (31, 500)] + ); + + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 21, from: 10000, to: 1000 }, + BagsEvent::ScoreUpdated { who: 21, new_score: 1000 } + ] + ); + }) + } + + #[test] + fn rewards_work() { + // Test case: validator and nominators' rewards are reflected in the target list scores, + // which also may cause rebaging of the target list. + // Call paths covered: + // * Call::validate() + // * Call::nominate() + // * Call::stakers_payout() + ExtBuilder::default().build_and_execute(|| { + // all payee destinations are Staked. + let _ = Payee::::iter() + .map(|(_, dest)| assert_eq!(dest, RewardDestination::Staked)) + .collect::>(); + + // initial state voters. + assert_eq!(voters_and_targets().0, [(11, 1000), (21, 1000), (31, 500), (101, 500)]); + // initial state targets. + assert_eq!(voters_and_targets().1, [(11, 1500), (21, 1500), (31, 500)]); + + // 101 nominates validator 11 and 21. + assert_eq!(Staking::status(&101), Ok(StakerStatus::Nominator(vec![11, 21]))); + let stake_101_before = Staking::ledger(Stash(101)).unwrap().active; + assert_eq!(stake_101_before, 500); + + // add reward points to 11 in era 0. + Staking::reward_by_ids(vec![(11, 1)]); + + mock::start_active_era(1); + + // payout 11 and nominators. + assert_ok!(Staking::payout_stakers(RuntimeOrigin::signed(11), 11, current_era() - 1)); + + // stake of nominator 101 increased since it was exposed to payout. + assert!(Staking::ledger(Stash(101)).unwrap().active > stake_101_before); + + // overview of the target list is as expected: 11 and 21 have increased the score after + // the payout as they were directly and indirectly exposed to the payout. + assert_eq!(voters_and_targets().1, [(11, 12575), (21, 4520), (31, 500)]); + + // rebag happened for both 11 and 21, which indirectly had its score increased. + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 11, from: 2000, to: 10000 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 9555 }, + BagsEvent::Rebagged { who: 11, from: 10000, to: u128::MAX }, + BagsEvent::ScoreUpdated { who: 11, new_score: 12575 }, + BagsEvent::Rebagged { who: 21, from: 2000, to: 10000 }, + BagsEvent::ScoreUpdated { who: 21, new_score: 4520 } + ] + ); + }) + } + + #[test] + fn slashing_works() { + // Test case: slashing a validator affects the target list score of the validator according + // to its slashed self-stake and the slashed stake of its nominators. A slash may cause + // target list rebagging of indirect slashing (targets which were not slashed by their + // nominators but were exposed to a slash from another validator). + // Call paths covered: + // * Call::validate() + // * Call::nominate() + // * OnOffenceHandler::on_offence() + ExtBuilder::default().build_and_execute(|| { + assert_ok!(Staking::nominate(RuntimeOrigin::signed(41), vec![21, 11])); + // unbond 450 from 41 so that the slash will cause the rebag of a validator which + // target score was indirectly affected by the slash. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(41), 450)); + System::reset_events(); + + // checks the current targets' score and list sorting. + assert_eq!(voters_and_targets().1, [(11, 2050), (21, 2050), (31, 500)]); + + // get the bonded stake of the nominators that will be affected by the slash. + let stake_101_before = Staking::ledger(Stash(101)).unwrap().active; + let stake_41_before = Staking::ledger(Stash(41)).unwrap().active; + + // target score of 11 is the sum of self-stake and nominations stake. + let score_11_before = >::score(&11); + assert_eq!(score_11_before, 2050); + + let self_stake_11_before = Staking::ledger(Stash(11)).unwrap().active; + assert_eq!(score_11_before, self_stake_11_before + stake_101_before + stake_41_before,); + + // same for 21. + let score_21_before = >::score(&21); + assert_eq!(score_21_before, 2050); + + let self_stake_21_before = Staking::ledger(Stash(21)).unwrap().active; + assert_eq!(score_21_before, self_stake_21_before + stake_101_before + stake_41_before,); + + // advance one era for the exposures to update given the current nominations. + start_active_era(current_era() + 1); + + // we immediately slash 11 with a 50% slash. + let exposure = Staking::eras_stakers(active_era(), &11); + let slash_percent = Perbill::from_percent(50); + let total_others_stake_to_slash = + exposure.others.iter().fold(0, |acc, s| acc + s.value); + + on_offence_now( + &[OffenceDetails { offender: (11, exposure.clone()), reporters: vec![] }], + &[slash_percent], + ); + + // note: upon slashing, validators are not chilled. + assert!(>::contains(&11)); + assert_eq!(Staking::status(&11), Ok(StakerStatus::Validator)); + // and its balance has been updated based on the slash applied + chilling. + let score_11_after = >::score(&11); + + assert_eq!( + score_11_after, + score_11_before - + slash_percent * (self_stake_11_before + total_others_stake_to_slash), + ); + + // self-stake of 11 has decreased by 50% due to slash. + assert_eq!( + Staking::ledger(Stash(11)).unwrap().active, + slash_percent * self_stake_11_before + ); + + // although 21 was not directly slashed, their nominators were. This will be reflected + // in its current target score. + let score_21_after = >::score(&21); + assert!(score_21_after < score_21_before); + + // slashed amounts from nominators are reflected in the score of 21. + let slashed_101 = stake_101_before - Staking::ledger(Stash(101)).unwrap().active; + let slashed_41 = stake_41_before - Staking::ledger(Stash(41)).unwrap().active; + + assert_eq!( + score_21_after, + Staking::ledger(Stash(21)).unwrap().active + + (stake_101_before - slashed_101) + + (stake_41_before - slashed_41), + ); + + // the target list has been updated accordingly and an indirect rebag of 21 happened. + assert_eq!( + voters_and_targets().1, + [(11, score_11_after), (21, score_21_after), (31, 500)] + ); + assert_eq!( + target_bags_events(), + [ + BagsEvent::Rebagged { who: 11, from: 10000, to: 2000 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 1550 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 1385 }, + BagsEvent::Rebagged { who: 21, from: 10000, to: 2000 }, + BagsEvent::ScoreUpdated { who: 21, new_score: 1885 }, + BagsEvent::ScoreUpdated { who: 11, new_score: 1204 }, + BagsEvent::ScoreUpdated { who: 21, new_score: 1704 } + ] + ); + + // fetching targets sorted and filtered by status works. Validators are not chilled + // upon slashing, thus 11 is part of the set. + assert_eq!( + TargetBagsList::iter() + .filter(|t| Staking::status(&t).unwrap() != StakerStatus::Idle) + .collect::>(), + [11, 21, 31], + ); + }) + } + + #[test] + fn validator_nominator_roles_snip_snap_works() { + // Test case: Validator becomes a nominator and vice-versa. In the process of a nominator + // turning validator, it leaves a target behind even though the staker is a nominator. The + // target is removed from the list once its score drops to 0 (similar to the dangling + // targets). + ExtBuilder::default().build_and_execute(|| { + // 11 and 21 are both validators. + assert_eq!(Staking::status(&11), Ok(StakerStatus::Validator)); + assert_eq!(Staking::status(&21), Ok(StakerStatus::Validator)); + // 101 nominates 11 and 21. + assert_eq!(Staking::status(&101), Ok(StakerStatus::Nominator(vec![11, 21]))); + + // 11 becomes nominator. + assert_ok!(Staking::nominate(RuntimeOrigin::signed(11), vec![21])); + assert_eq!(Staking::status(&11), Ok(StakerStatus::Nominator(vec![21]))); + + // however, since 101 nominates 11 (which now is a nominator), 11 is still in the + // target list even though it is a nominator. + assert_eq!(nominators_of(&11), vec![101]); + assert_eq!(TargetBagsList::score(&11), Staking::active_stake(&101).unwrap()); + + // 101 starts validating. thus, it chills as a nominator. + assert_ok!(Staking::validate(RuntimeOrigin::signed(101), Default::default())); + assert_eq!(Staking::status(&101), Ok(StakerStatus::Validator)); + + // now 11 has no more score in the target list and it is a nominator, thus it is + // removed from the target list. + assert_eq!(nominators_of(&11).len(), 0); + assert!(!TargetBagsList::contains(&11)); + + // stake-tracker try-state will ensure actions above keep the integrity of the target + // and voter list. + }); + } + + #[test] + fn no_redundant_update_ledger_events() { + ExtBuilder::default().build_and_execute(|| { + // 101 nominates 11 and 21. + assert_eq!(Staking::status(&101), Ok(StakerStatus::Nominator(vec![11, 21]))); + + let ledger = Staking::ledger(StakingAccount::Stash(101)).unwrap(); + + // calling update on a ledger with no stake changes will not affect the target's score. + assert_ok!(ledger.update()); + + assert_eq!(target_bags_events(), [],); + + let score_11_before = TargetBagsList::score(&11); + let score_21_before = TargetBagsList::score(&21); + + let extra = 100; + + // however, updating the stake of the nominator will affect the score of its nominated + // targets, as expected. + let mut ledger = Staking::ledger(StakingAccount::Stash(101)).unwrap(); + ledger.active += extra; + ledger.total += extra; + assert_ok!(ledger.update()); + + assert_eq!( + target_bags_events(), + [ + BagsEvent::ScoreUpdated { who: 11, new_score: score_11_before + extra }, + BagsEvent::ScoreUpdated { who: 21, new_score: score_21_before + extra }, + ], + ); + }) + } + + #[test] + fn drop_dangling_nomination_works() { + ExtBuilder::default().try_state(false).build_and_execute(|| { + // setup. + bond_validator(42, 10); + + assert_ok!(Staking::bond(RuntimeOrigin::signed(90), 500, RewardDestination::Staked)); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(90), vec![11])); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(101), vec![11])); + + // target is dangling with nominations from 101 and 90. + setup_dangling_target_for_nominators(42, vec![101, 90]); + + // 101 is now nominating 42.. + assert_ok!(Staking::status(&101), StakerStatus::Nominator(vec![11, 42])); + // .. which is unbonded.. + assert!(Staking::status(&42).is_err()); + // .. and still part of the target list (thus dangling). + assert!(TargetBagsList::contains(&42)); + + // remove 90 as dangling nomination. + assert_ok!(Staking::drop_dangling_nomination(RuntimeOrigin::signed(1), 90, 42)); + + assert_eq!( + *mock::staking_events().last().unwrap(), + Event::::DanglingNominationsDropped { nominator: 90, count: 1 }.into(), + ); + + // now, 90 is not nominating 42 anymore. + assert_ok!(Staking::status(&90), StakerStatus::Nominator(vec![11])); + // but 42 is still dangling because 101 is still nominating it + assert!(TargetBagsList::contains(&42)); + assert_ok!(Staking::status(&101), StakerStatus::Nominator(vec![11, 42])); + + // when the last dangling nomination is removed, the danling target is removed. + assert_ok!(Staking::drop_dangling_nomination(RuntimeOrigin::signed(1), 101, 42)); + + assert_ok!(Staking::status(&101), StakerStatus::Nominator(vec![11])); + assert!(!TargetBagsList::contains(&42)); + + assert_eq!( + *mock::staking_events().last().unwrap(), + Event::::DanglingNominationsDropped { nominator: 101, count: 1 }.into(), + ); + }) + } + + #[test] + fn drop_dangling_nomination_failures_work() { + ExtBuilder::default().try_state(false).build_and_execute(|| { + // target is not dangling since it does not exist in the target list. + assert!(Staking::status(&42).is_err()); + assert!(!TargetBagsList::contains(&42)); + + assert_noop!( + Staking::drop_dangling_nomination(RuntimeOrigin::signed(1), 10, 42), + Error::::NotDanglingTarget, + ); + + // target is not dangling since it is still bonded. + assert_eq!(Staking::status(&31), Ok(StakerStatus::Validator)); + assert_noop!( + Staking::drop_dangling_nomination(RuntimeOrigin::signed(1), 42, 10), + Error::::NotDanglingTarget, + ); + + // target is dangling but voter is not nominating it. + bond_validator(42, 10); + + assert_eq!(Staking::status(&101), Ok(StakerStatus::Nominator(vec![11, 21]))); + setup_dangling_target_for_nominators(42, vec![101]); + assert!(Staking::status(&42).is_err()); + assert_noop!( + Staking::drop_dangling_nomination(RuntimeOrigin::signed(1), 11, 42), + Error::::NotNominator, + ); + }) + } + + #[test] + fn drop_dangling_nominations_chills_works() { + ExtBuilder::default().try_state(false).build_and_execute(|| { + // setup. + bond_validator(42, 10); + + assert_ok!(Staking::bond(RuntimeOrigin::signed(90), 500, RewardDestination::Staked)); + assert_ok!(Staking::nominate(RuntimeOrigin::signed(90), vec![42])); + + // 42 chills & unbonds completely. + assert_ok!(Staking::chill(RuntimeOrigin::signed(42))); + Ledger::::remove(42); + Bonded::::remove(42); + + // 90 is now nominating 42. + assert_ok!(Staking::status(&90), StakerStatus::Nominator(vec![42])); + // 42 is unbonded .. + assert!(Staking::status(&42).is_err()); + // .. and still part of the target list (thus dangling). + assert!(TargetBagsList::contains(&42)); + + // since 90 is *only* nominating a dangling target, it will be chilled after + // calling `drop_danlging_nomination`. + assert_ok!(Staking::drop_dangling_nomination(RuntimeOrigin::signed(1), 90, 42)); + assert_ok!(Staking::status(&90), StakerStatus::Idle); + assert!(!TargetBagsList::contains(&42)); + + assert_eq!( + *mock::staking_events().last().unwrap(), + Event::::DanglingNominationsDropped { nominator: 90, count: 1 }.into(), + ); + }) + } +} + mod ledger { use super::*; diff --git a/substrate/frame/staking/src/weights.rs b/substrate/frame/staking/src/weights.rs index cd4e7f973ce3..dabfba49bdca 100644 --- a/substrate/frame/staking/src/weights.rs +++ b/substrate/frame/staking/src/weights.rs @@ -18,27 +18,25 @@ //! Autogenerated weights for `pallet_staking` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-04-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-05-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-anb7yjbi-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-unxyhko3-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_staking -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/staking/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_staking +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/staking/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -83,6 +81,8 @@ pub trait WeightInfo { fn force_apply_min_commission() -> Weight; fn set_min_commission() -> Weight; fn restore_ledger() -> Weight; + fn drop_dangling_nomination() -> Weight; + fn v13_mmb_partial_step() -> Weight; } /// Weights for `pallet_staking` using the Substrate node and recommended hardware. @@ -92,41 +92,55 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn bond() -> Weight { // Proof Size summary in bytes: - // Measured: `1042` + // Measured: `1134` // Estimated: `4764` - // Minimum execution time: 46_504_000 picoseconds. - Weight::from_parts(48_459_000, 4764) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Minimum execution time: 61_346_000 picoseconds. + Weight::from_parts(63_986_000, 4764) + .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:3 w:3) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:4 w:4) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) fn bond_extra() -> Weight { // Proof Size summary in bytes: - // Measured: `1990` - // Estimated: `8877` - // Minimum execution time: 90_475_000 picoseconds. - Weight::from_parts(93_619_000, 8877) - .saturating_add(T::DbWeight::get().reads(9_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + // Measured: `2742` + // Estimated: `11506` + // Minimum execution time: 133_115_000 picoseconds. + Weight::from_parts(137_389_000, 11506) + .saturating_add(T::DbWeight::get().reads(13_u64)) + .saturating_add(T::DbWeight::get().writes(8_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -138,22 +152,28 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) fn unbond() -> Weight { // Proof Size summary in bytes: - // Measured: `2195` + // Measured: `2738` // Estimated: `8877` - // Minimum execution time: 99_335_000 picoseconds. - Weight::from_parts(101_440_000, 8877) - .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + // Minimum execution time: 130_115_000 picoseconds. + Weight::from_parts(133_942_000, 8877) + .saturating_add(T::DbWeight::get().reads(15_u64)) + .saturating_add(T::DbWeight::get().writes(8_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -161,22 +181,28 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1297` + // Measured: `1415` // Estimated: `4764` - // Minimum execution time: 50_067_000 picoseconds. - Weight::from_parts(52_396_327, 4764) - // Standard Error: 1_419 - .saturating_add(Weight::from_parts(51_406, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(6_u64)) + // Minimum execution time: 61_773_000 picoseconds. + Weight::from_parts(64_531_144, 4764) + // Standard Error: 1_573 + .saturating_add(Weight::from_parts(53_571, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -187,22 +213,26 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -210,14 +240,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` - // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 92_931_000 picoseconds. - Weight::from_parts(101_398_156, 6248) - // Standard Error: 4_180 - .saturating_add(Weight::from_parts(1_377_850, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(11_u64)) + // Measured: `2842 + s * (4 ±0)` + // Estimated: `8877 + s * (4 ±0)` + // Minimum execution time: 134_037_000 picoseconds. + Weight::from_parts(145_678_976, 8877) + // Standard Error: 5_183 + .saturating_add(Weight::from_parts(1_449_480, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(17_u64)) + .saturating_add(T::DbWeight::get().writes(15_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -233,8 +263,14 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:1 w:0) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:0) + /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:1 w:1) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:1 w:1) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) @@ -245,40 +281,47 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn validate() -> Weight { // Proof Size summary in bytes: - // Measured: `1372` + // Measured: `1644` // Estimated: `4556` - // Minimum execution time: 56_291_000 picoseconds. - Weight::from_parts(58_372_000, 4556) - .saturating_add(T::DbWeight::get().reads(11_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + // Minimum execution time: 79_658_000 picoseconds. + Weight::from_parts(81_457_000, 4556) + .saturating_add(T::DbWeight::get().reads(14_u64)) + .saturating_add(T::DbWeight::get().writes(9_u64)) } - /// Storage: `Staking::Ledger` (r:1 w:0) + /// Storage: `Staking::Ledger` (r:129 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) + /// Storage: `Staking::Bonded` (r:129 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:128 w:128) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:128 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:3 w:3) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:12 w:12) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1815 + k * (572 ±0)` - // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 36_218_000 picoseconds. - Weight::from_parts(38_811_308, 4556) - // Standard Error: 8_352 - .saturating_add(Weight::from_parts(6_527_398, 0).saturating_mul(k.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) + // Measured: `3103 + k * (757 ±0)` + // Estimated: `6120 + k * (3566 ±0)` + // Minimum execution time: 78_476_000 picoseconds. + Weight::from_parts(2_780_311, 6120) + // Standard Error: 55_789 + .saturating_add(Weight::from_parts(35_357_040, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(7_u64)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(k.into()))) + .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) - .saturating_add(Weight::from_parts(0, 3033).saturating_mul(k.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(k.into())) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) + /// Storage: `Staking::Bonded` (r:17 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::MinNominatorBond` (r:1 w:0) /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:1) + /// Storage: `Staking::Nominators` (r:17 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:1 w:0) /// Proof: `Staking::MaxNominatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -286,27 +329,32 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::CounterForNominators` (r:1 w:1) + /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForNominators` (r:1 w:1) - /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:16 w:16) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1866 + n * (102 ±0)` - // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 68_607_000 picoseconds. - Weight::from_parts(66_831_185, 6248) - // Standard Error: 14_014 - .saturating_add(Weight::from_parts(4_031_635, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes(6_u64)) - .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + // Measured: `2350 + n * (348 ±0)` + // Estimated: `6248 + n * (3033 ±0)` + // Minimum execution time: 114_109_000 picoseconds. + Weight::from_parts(92_374_250, 6248) + // Standard Error: 40_918 + .saturating_add(Weight::from_parts(32_671_582, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(14_u64)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(8_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -318,20 +366,22 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1816` - // Estimated: `6248` - // Minimum execution time: 60_088_000 picoseconds. - Weight::from_parts(62_471_000, 6248) - .saturating_add(T::DbWeight::get().reads(9_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Measured: `2429` + // Estimated: `8877` + // Minimum execution time: 94_864_000 picoseconds. + Weight::from_parts(97_414_000, 8877) + .saturating_add(T::DbWeight::get().reads(12_u64)) + .saturating_add(T::DbWeight::get().writes(9_u64)) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -341,10 +391,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn set_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `902` + // Measured: `935` // Estimated: `4556` - // Minimum execution time: 19_777_000 picoseconds. - Weight::from_parts(20_690_000, 4556) + // Minimum execution time: 20_223_000 picoseconds. + Weight::from_parts(20_997_000, 4556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -356,10 +406,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `969` + // Measured: `1002` // Estimated: `4556` - // Minimum execution time: 23_705_000 picoseconds. - Weight::from_parts(24_409_000, 4556) + // Minimum execution time: 24_225_000 picoseconds. + Weight::from_parts(24_960_000, 4556) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -369,10 +419,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) fn set_controller() -> Weight { // Proof Size summary in bytes: - // Measured: `902` + // Measured: `935` // Estimated: `8122` - // Minimum execution time: 23_479_000 picoseconds. - Weight::from_parts(24_502_000, 8122) + // Minimum execution time: 24_007_000 picoseconds. + Weight::from_parts(24_897_000, 8122) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -382,8 +432,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_675_000 picoseconds. - Weight::from_parts(2_802_000, 0) + // Minimum execution time: 2_497_000 picoseconds. + Weight::from_parts(2_626_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -392,8 +442,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_067_000 picoseconds. - Weight::from_parts(7_413_000, 0) + // Minimum execution time: 7_896_000 picoseconds. + Weight::from_parts(8_402_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -402,8 +452,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_977_000 picoseconds. - Weight::from_parts(7_353_000, 0) + // Minimum execution time: 8_122_000 picoseconds. + Weight::from_parts(8_432_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -412,8 +462,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_071_000 picoseconds. - Weight::from_parts(7_463_000, 0) + // Minimum execution time: 8_027_000 picoseconds. + Weight::from_parts(8_393_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -423,10 +473,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_833_000 picoseconds. - Weight::from_parts(3_328_130, 0) - // Standard Error: 30 - .saturating_add(Weight::from_parts(10_058, 0).saturating_mul(v.into())) + // Minimum execution time: 2_616_000 picoseconds. + Weight::from_parts(3_281_227, 0) + // Standard Error: 32 + .saturating_add(Weight::from_parts(10_003, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:11800 w:11800) @@ -438,12 +488,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 5900]`. fn deprecate_controller_batch(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1746 + i * (229 ±0)` + // Measured: `1779 + i * (229 ±0)` // Estimated: `990 + i * (7132 ±0)` - // Minimum execution time: 5_300_000 picoseconds. - Weight::from_parts(5_437_000, 990) - // Standard Error: 66_261 - .saturating_add(Weight::from_parts(30_172_457, 0).saturating_mul(i.into())) + // Minimum execution time: 4_905_000 picoseconds. + Weight::from_parts(5_156_000, 990) + // Standard Error: 83_880 + .saturating_add(Weight::from_parts(30_406_155, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 7132).saturating_mul(i.into())) @@ -452,26 +502,30 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:1) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `Staking::Ledger` (r:1 w:1) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -479,14 +533,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[0, 100]`. fn force_unstake(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` - // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 87_677_000 picoseconds. - Weight::from_parts(96_386_462, 6248) - // Standard Error: 3_717 - .saturating_add(Weight::from_parts(1_370_585, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)) + // Measured: `2842 + s * (4 ±0)` + // Estimated: `8877 + s * (4 ±0)` + // Minimum execution time: 130_799_000 picoseconds. + Weight::from_parts(142_508_520, 8877) + // Standard Error: 4_715 + .saturating_add(Weight::from_parts(1_440_259, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(17_u64)) + .saturating_add(T::DbWeight::get().writes(16_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -495,12 +549,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[1, 1000]`. fn cancel_deferred_slash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `66672` - // Estimated: `70137` - // Minimum execution time: 105_086_000 picoseconds. - Weight::from_parts(1_167_895_222, 70137) - // Standard Error: 77_022 - .saturating_add(Weight::from_parts(6_487_305, 0).saturating_mul(s.into())) + // Measured: `66705` + // Estimated: `70170` + // Minimum execution time: 107_433_000 picoseconds. + Weight::from_parts(1_164_974_155, 70170) + // Standard Error: 76_453 + .saturating_add(Weight::from_parts(6_498_608, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -518,81 +572,107 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasValidatorReward` (r:1 w:0) /// Proof: `Staking::ErasValidatorReward` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::VirtualStakers` (r:257 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:257 w:257) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:257 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:257 w:257) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) /// Proof: `Staking::ErasRewardPoints` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasValidatorPrefs` (r:1 w:0) /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:257 w:0) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:257 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:257 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:13 w:13) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:257 w:257) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 256]`. fn payout_stakers_alive_staked(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `33297 + n * (377 ±0)` - // Estimated: `30944 + n * (3774 ±3)` - // Minimum execution time: 154_210_000 picoseconds. - Weight::from_parts(192_836_012, 30944) - // Standard Error: 40_441 - .saturating_add(Weight::from_parts(47_646_642, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(14_u64)) - .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes(4_u64)) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) + // Measured: `34145 + n * (625 ±0)` + // Estimated: `31768 + n * (3774 ±3)` + // Minimum execution time: 256_919_000 picoseconds. + Weight::from_parts(1_131_187_427, 31768) + // Standard Error: 504_022 + .saturating_add(Weight::from_parts(84_568_885, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(34_u64)) + .saturating_add(T::DbWeight::get().reads((10_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(21_u64)) + .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:3 w:3) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:4 w:4) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1991 + l * (7 ±0)` - // Estimated: `8877` - // Minimum execution time: 88_337_000 picoseconds. - Weight::from_parts(91_391_254, 8877) - // Standard Error: 4_485 - .saturating_add(Weight::from_parts(103_443, 0).saturating_mul(l.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + // Measured: `2743 + l * (7 ±0)` + // Estimated: `11506` + // Minimum execution time: 129_295_000 picoseconds. + Weight::from_parts(134_342_502, 11506) + // Standard Error: 6_141 + .saturating_add(Weight::from_parts(203_335, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(13_u64)) + .saturating_add(T::DbWeight::get().writes(8_u64)) } + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -600,14 +680,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[1, 100]`. fn reap_stash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` - // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 98_014_000 picoseconds. - Weight::from_parts(102_537_670, 6248) - // Standard Error: 3_324 - .saturating_add(Weight::from_parts(1_353_142, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().writes(11_u64)) + // Measured: `2842 + s * (4 ±0)` + // Estimated: `8877 + s * (4 ±0)` + // Minimum execution time: 142_841_000 picoseconds. + Weight::from_parts(151_373_760, 8877) + // Standard Error: 4_909 + .saturating_add(Weight::from_parts(1_432_397, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(16_u64)) + .saturating_add(T::DbWeight::get().writes(15_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -617,16 +697,20 @@ impl WeightInfo for SubstrateWeight { /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:110 w:0) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:110 w:0) + /// Storage: `Staking::Bonded` (r:111 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:110 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:110 w:0) + /// Storage: `Staking::Nominators` (r:111 w:0) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:11 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForValidators` (r:1 w:0) - /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:0) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:201 w:0) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:11 w:0) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) /// Storage: `Staking::ValidatorCount` (r:1 w:0) /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::MinimumValidatorCount` (r:1 w:0) @@ -649,16 +733,16 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 100]`. fn new_era(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` - // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 608_575_000 picoseconds. - Weight::from_parts(613_663_000, 512390) - // Standard Error: 2_286_521 - .saturating_add(Weight::from_parts(72_108_001, 0).saturating_mul(v.into())) - // Standard Error: 227_839 - .saturating_add(Weight::from_parts(20_314_085, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(206_u64)) - .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) + // Measured: `0 + n * (720 ±0) + v * (3776 ±0)` + // Estimated: `516555 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 963_499_000 picoseconds. + Weight::from_parts(966_544_000, 516555) + // Standard Error: 2_158_092 + .saturating_add(Weight::from_parts(72_956_282, 0).saturating_mul(v.into())) + // Standard Error: 215_042 + .saturating_add(Weight::from_parts(19_482_545, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(410_u64)) + .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) @@ -685,14 +769,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[500, 1000]`. fn get_npos_voters(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` + // Measured: `3208 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 37_173_756_000 picoseconds. - Weight::from_parts(37_488_937_000, 512390) - // Standard Error: 467_413 - .saturating_add(Weight::from_parts(8_086_367, 0).saturating_mul(v.into())) - // Standard Error: 467_413 - .saturating_add(Weight::from_parts(3_108_193, 0).saturating_mul(n.into())) + // Minimum execution time: 36_355_465_000 picoseconds. + Weight::from_parts(36_660_578_000, 512390) + // Standard Error: 422_770 + .saturating_add(Weight::from_parts(3_407_216, 0).saturating_mul(v.into())) + // Standard Error: 422_770 + .saturating_add(Weight::from_parts(6_173_669, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(201_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -700,22 +784,30 @@ impl WeightInfo for SubstrateWeight { .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) } - /// Storage: `Staking::CounterForValidators` (r:1 w:0) - /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:0) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:201 w:0) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1001 w:0) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:1001 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1001 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1001 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// The range of component `v` is `[500, 1000]`. fn get_npos_targets(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `979 + v * (50 ±0)` - // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_641_258_000 picoseconds. - Weight::from_parts(382_882_595, 3510) - // Standard Error: 11_991 - .saturating_add(Weight::from_parts(4_695_820, 0).saturating_mul(v.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) - .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) + // Measured: `58129 + v * (323 ±0)` + // Estimated: `516555 + v * (3033 ±0)` + // Minimum execution time: 8_890_124_000 picoseconds. + Weight::from_parts(9_016_030_000, 516555) + // Standard Error: 111_852 + .saturating_add(Weight::from_parts(7_039_233, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(206_u64)) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(v.into())) } /// Storage: `Staking::MinCommission` (r:0 w:1) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -735,8 +827,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_753_000 picoseconds. - Weight::from_parts(6_529_000, 0) + // Minimum execution time: 5_627_000 picoseconds. + Weight::from_parts(6_134_000, 0) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) @@ -757,8 +849,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_212_000 picoseconds. - Weight::from_parts(5_451_000, 0) + // Minimum execution time: 4_901_000 picoseconds. + Weight::from_parts(5_209_000, 0) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) @@ -777,20 +869,22 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill_other() -> Weight { // Proof Size summary in bytes: - // Measured: `1939` - // Estimated: `6248` - // Minimum execution time: 73_000_000 picoseconds. - Weight::from_parts(75_184_000, 6248) - .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Measured: `2544` + // Estimated: `8877` + // Minimum execution time: 111_325_000 picoseconds. + Weight::from_parts(114_102_000, 8877) + .saturating_add(T::DbWeight::get().reads(15_u64)) + .saturating_add(T::DbWeight::get().writes(9_u64)) } /// Storage: `Staking::MinCommission` (r:1 w:0) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -798,10 +892,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) fn force_apply_min_commission() -> Weight { // Proof Size summary in bytes: - // Measured: `691` + // Measured: `724` // Estimated: `3510` - // Minimum execution time: 13_056_000 picoseconds. - Weight::from_parts(13_517_000, 3510) + // Minimum execution time: 13_264_000 picoseconds. + Weight::from_parts(13_696_000, 3510) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -811,10 +905,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_201_000 picoseconds. - Weight::from_parts(3_442_000, 0) + // Minimum execution time: 3_052_000 picoseconds. + Weight::from_parts(3_242_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) @@ -825,15 +921,67 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1047` + // Measured: `1165` // Estimated: `4764` - // Minimum execution time: 44_671_000 picoseconds. - Weight::from_parts(45_611_000, 4764) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 61_779_000 picoseconds. + Weight::from_parts(62_484_000, 4764) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } + /// Storage: `Staking::Bonded` (r:3 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:2 w:2) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:2 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:2 w:1) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::MinNominatorBond` (r:1 w:0) + /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:1 w:1) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn drop_dangling_nomination() -> Weight { + // Proof Size summary in bytes: + // Measured: `1973` + // Estimated: `8631` + // Minimum execution time: 101_638_000 picoseconds. + Weight::from_parts(103_488_000, 8631) + .saturating_add(T::DbWeight::get().reads(14_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: `Staking::Nominators` (r:6 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:21 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:21 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:180 w:180) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn v13_mmb_partial_step() -> Weight { + // Proof Size summary in bytes: + // Measured: `70141` + // Estimated: `477090` + // Minimum execution time: 2_703_732_000 picoseconds. + Weight::from_parts(2_779_206_000, 477090) + .saturating_add(T::DbWeight::get().reads(231_u64)) + .saturating_add(T::DbWeight::get().writes(183_u64)) + } } // For backwards compatibility and tests. @@ -842,41 +990,55 @@ impl WeightInfo for () { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn bond() -> Weight { // Proof Size summary in bytes: - // Measured: `1042` + // Measured: `1134` // Estimated: `4764` - // Minimum execution time: 46_504_000 picoseconds. - Weight::from_parts(48_459_000, 4764) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Minimum execution time: 61_346_000 picoseconds. + Weight::from_parts(63_986_000, 4764) + .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:3 w:3) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:4 w:4) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) fn bond_extra() -> Weight { // Proof Size summary in bytes: - // Measured: `1990` - // Estimated: `8877` - // Minimum execution time: 90_475_000 picoseconds. - Weight::from_parts(93_619_000, 8877) - .saturating_add(RocksDbWeight::get().reads(9_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + // Measured: `2742` + // Estimated: `11506` + // Minimum execution time: 133_115_000 picoseconds. + Weight::from_parts(137_389_000, 11506) + .saturating_add(RocksDbWeight::get().reads(13_u64)) + .saturating_add(RocksDbWeight::get().writes(8_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -888,22 +1050,28 @@ impl WeightInfo for () { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) fn unbond() -> Weight { // Proof Size summary in bytes: - // Measured: `2195` + // Measured: `2738` // Estimated: `8877` - // Minimum execution time: 99_335_000 picoseconds. - Weight::from_parts(101_440_000, 8877) - .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + // Minimum execution time: 130_115_000 picoseconds. + Weight::from_parts(133_942_000, 8877) + .saturating_add(RocksDbWeight::get().reads(15_u64)) + .saturating_add(RocksDbWeight::get().writes(8_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -911,22 +1079,28 @@ impl WeightInfo for () { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1297` + // Measured: `1415` // Estimated: `4764` - // Minimum execution time: 50_067_000 picoseconds. - Weight::from_parts(52_396_327, 4764) - // Standard Error: 1_419 - .saturating_add(Weight::from_parts(51_406, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(6_u64)) + // Minimum execution time: 61_773_000 picoseconds. + Weight::from_parts(64_531_144, 4764) + // Standard Error: 1_573 + .saturating_add(Weight::from_parts(53_571, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -937,22 +1111,26 @@ impl WeightInfo for () { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -960,14 +1138,14 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` - // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 92_931_000 picoseconds. - Weight::from_parts(101_398_156, 6248) - // Standard Error: 4_180 - .saturating_add(Weight::from_parts(1_377_850, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(13_u64)) - .saturating_add(RocksDbWeight::get().writes(11_u64)) + // Measured: `2842 + s * (4 ±0)` + // Estimated: `8877 + s * (4 ±0)` + // Minimum execution time: 134_037_000 picoseconds. + Weight::from_parts(145_678_976, 8877) + // Standard Error: 5_183 + .saturating_add(Weight::from_parts(1_449_480, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(17_u64)) + .saturating_add(RocksDbWeight::get().writes(15_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -983,8 +1161,14 @@ impl WeightInfo for () { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:1 w:0) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:0) + /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:1 w:1) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:1 w:1) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) @@ -995,40 +1179,47 @@ impl WeightInfo for () { /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn validate() -> Weight { // Proof Size summary in bytes: - // Measured: `1372` + // Measured: `1644` // Estimated: `4556` - // Minimum execution time: 56_291_000 picoseconds. - Weight::from_parts(58_372_000, 4556) - .saturating_add(RocksDbWeight::get().reads(11_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + // Minimum execution time: 79_658_000 picoseconds. + Weight::from_parts(81_457_000, 4556) + .saturating_add(RocksDbWeight::get().reads(14_u64)) + .saturating_add(RocksDbWeight::get().writes(9_u64)) } - /// Storage: `Staking::Ledger` (r:1 w:0) + /// Storage: `Staking::Ledger` (r:129 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) + /// Storage: `Staking::Bonded` (r:129 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:128 w:128) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:128 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:3 w:3) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:12 w:12) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1815 + k * (572 ±0)` - // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 36_218_000 picoseconds. - Weight::from_parts(38_811_308, 4556) - // Standard Error: 8_352 - .saturating_add(Weight::from_parts(6_527_398, 0).saturating_mul(k.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) + // Measured: `3103 + k * (757 ±0)` + // Estimated: `6120 + k * (3566 ±0)` + // Minimum execution time: 78_476_000 picoseconds. + Weight::from_parts(2_780_311, 6120) + // Standard Error: 55_789 + .saturating_add(Weight::from_parts(35_357_040, 0).saturating_mul(k.into())) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(k.into()))) + .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) - .saturating_add(Weight::from_parts(0, 3033).saturating_mul(k.into())) + .saturating_add(Weight::from_parts(0, 3566).saturating_mul(k.into())) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) + /// Storage: `Staking::Bonded` (r:17 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::MinNominatorBond` (r:1 w:0) /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:1) + /// Storage: `Staking::Nominators` (r:17 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:1 w:0) /// Proof: `Staking::MaxNominatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -1036,27 +1227,32 @@ impl WeightInfo for () { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::CounterForNominators` (r:1 w:1) + /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:2 w:2) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForNominators` (r:1 w:1) - /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:16 w:16) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1866 + n * (102 ±0)` - // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 68_607_000 picoseconds. - Weight::from_parts(66_831_185, 6248) - // Standard Error: 14_014 - .saturating_add(Weight::from_parts(4_031_635, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) - .saturating_add(RocksDbWeight::get().writes(6_u64)) - .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) + // Measured: `2350 + n * (348 ±0)` + // Estimated: `6248 + n * (3033 ±0)` + // Minimum execution time: 114_109_000 picoseconds. + Weight::from_parts(92_374_250, 6248) + // Standard Error: 40_918 + .saturating_add(Weight::from_parts(32_671_582, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(14_u64)) + .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) + .saturating_add(RocksDbWeight::get().writes(8_u64)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -1068,20 +1264,22 @@ impl WeightInfo for () { /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1816` - // Estimated: `6248` - // Minimum execution time: 60_088_000 picoseconds. - Weight::from_parts(62_471_000, 6248) - .saturating_add(RocksDbWeight::get().reads(9_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + // Measured: `2429` + // Estimated: `8877` + // Minimum execution time: 94_864_000 picoseconds. + Weight::from_parts(97_414_000, 8877) + .saturating_add(RocksDbWeight::get().reads(12_u64)) + .saturating_add(RocksDbWeight::get().writes(9_u64)) } /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -1091,10 +1289,10 @@ impl WeightInfo for () { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn set_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `902` + // Measured: `935` // Estimated: `4556` - // Minimum execution time: 19_777_000 picoseconds. - Weight::from_parts(20_690_000, 4556) + // Minimum execution time: 20_223_000 picoseconds. + Weight::from_parts(20_997_000, 4556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1106,10 +1304,10 @@ impl WeightInfo for () { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `969` + // Measured: `1002` // Estimated: `4556` - // Minimum execution time: 23_705_000 picoseconds. - Weight::from_parts(24_409_000, 4556) + // Minimum execution time: 24_225_000 picoseconds. + Weight::from_parts(24_960_000, 4556) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1119,10 +1317,10 @@ impl WeightInfo for () { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) fn set_controller() -> Weight { // Proof Size summary in bytes: - // Measured: `902` + // Measured: `935` // Estimated: `8122` - // Minimum execution time: 23_479_000 picoseconds. - Weight::from_parts(24_502_000, 8122) + // Minimum execution time: 24_007_000 picoseconds. + Weight::from_parts(24_897_000, 8122) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1132,8 +1330,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_675_000 picoseconds. - Weight::from_parts(2_802_000, 0) + // Minimum execution time: 2_497_000 picoseconds. + Weight::from_parts(2_626_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1142,8 +1340,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_067_000 picoseconds. - Weight::from_parts(7_413_000, 0) + // Minimum execution time: 7_896_000 picoseconds. + Weight::from_parts(8_402_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1152,8 +1350,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_977_000 picoseconds. - Weight::from_parts(7_353_000, 0) + // Minimum execution time: 8_122_000 picoseconds. + Weight::from_parts(8_432_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1162,8 +1360,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_071_000 picoseconds. - Weight::from_parts(7_463_000, 0) + // Minimum execution time: 8_027_000 picoseconds. + Weight::from_parts(8_393_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -1173,10 +1371,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_833_000 picoseconds. - Weight::from_parts(3_328_130, 0) - // Standard Error: 30 - .saturating_add(Weight::from_parts(10_058, 0).saturating_mul(v.into())) + // Minimum execution time: 2_616_000 picoseconds. + Weight::from_parts(3_281_227, 0) + // Standard Error: 32 + .saturating_add(Weight::from_parts(10_003, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:11800 w:11800) @@ -1188,12 +1386,12 @@ impl WeightInfo for () { /// The range of component `i` is `[0, 5900]`. fn deprecate_controller_batch(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1746 + i * (229 ±0)` + // Measured: `1779 + i * (229 ±0)` // Estimated: `990 + i * (7132 ±0)` - // Minimum execution time: 5_300_000 picoseconds. - Weight::from_parts(5_437_000, 990) - // Standard Error: 66_261 - .saturating_add(Weight::from_parts(30_172_457, 0).saturating_mul(i.into())) + // Minimum execution time: 4_905_000 picoseconds. + Weight::from_parts(5_156_000, 990) + // Standard Error: 83_880 + .saturating_add(Weight::from_parts(30_406_155, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 7132).saturating_mul(i.into())) @@ -1202,26 +1400,30 @@ impl WeightInfo for () { /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:1) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `Staking::Ledger` (r:1 w:1) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -1229,14 +1431,14 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 100]`. fn force_unstake(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` - // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 87_677_000 picoseconds. - Weight::from_parts(96_386_462, 6248) - // Standard Error: 3_717 - .saturating_add(Weight::from_parts(1_370_585, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(13_u64)) - .saturating_add(RocksDbWeight::get().writes(12_u64)) + // Measured: `2842 + s * (4 ±0)` + // Estimated: `8877 + s * (4 ±0)` + // Minimum execution time: 130_799_000 picoseconds. + Weight::from_parts(142_508_520, 8877) + // Standard Error: 4_715 + .saturating_add(Weight::from_parts(1_440_259, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(17_u64)) + .saturating_add(RocksDbWeight::get().writes(16_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -1245,12 +1447,12 @@ impl WeightInfo for () { /// The range of component `s` is `[1, 1000]`. fn cancel_deferred_slash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `66672` - // Estimated: `70137` - // Minimum execution time: 105_086_000 picoseconds. - Weight::from_parts(1_167_895_222, 70137) - // Standard Error: 77_022 - .saturating_add(Weight::from_parts(6_487_305, 0).saturating_mul(s.into())) + // Measured: `66705` + // Estimated: `70170` + // Minimum execution time: 107_433_000 picoseconds. + Weight::from_parts(1_164_974_155, 70170) + // Standard Error: 76_453 + .saturating_add(Weight::from_parts(6_498_608, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1268,81 +1470,107 @@ impl WeightInfo for () { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasValidatorReward` (r:1 w:0) /// Proof: `Staking::ErasValidatorReward` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::VirtualStakers` (r:257 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:257 w:257) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:257 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:257 w:257) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) /// Proof: `Staking::ErasRewardPoints` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasValidatorPrefs` (r:1 w:0) /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:257 w:0) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:257 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:257 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:13 w:13) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:257 w:257) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 256]`. fn payout_stakers_alive_staked(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `33297 + n * (377 ±0)` - // Estimated: `30944 + n * (3774 ±3)` - // Minimum execution time: 154_210_000 picoseconds. - Weight::from_parts(192_836_012, 30944) - // Standard Error: 40_441 - .saturating_add(Weight::from_parts(47_646_642, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(14_u64)) - .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(n.into()))) - .saturating_add(RocksDbWeight::get().writes(4_u64)) - .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into()))) + // Measured: `34145 + n * (625 ±0)` + // Estimated: `31768 + n * (3774 ±3)` + // Minimum execution time: 256_919_000 picoseconds. + Weight::from_parts(1_131_187_427, 31768) + // Standard Error: 504_022 + .saturating_add(Weight::from_parts(84_568_885, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(34_u64)) + .saturating_add(RocksDbWeight::get().reads((10_u64).saturating_mul(n.into()))) + .saturating_add(RocksDbWeight::get().writes(21_u64)) + .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:3 w:3) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:4 w:4) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Storage: `VoterList::ListBags` (r:1 w:1) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1991 + l * (7 ±0)` - // Estimated: `8877` - // Minimum execution time: 88_337_000 picoseconds. - Weight::from_parts(91_391_254, 8877) - // Standard Error: 4_485 - .saturating_add(Weight::from_parts(103_443, 0).saturating_mul(l.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + // Measured: `2743 + l * (7 ±0)` + // Estimated: `11506` + // Minimum execution time: 129_295_000 picoseconds. + Weight::from_parts(134_342_502, 11506) + // Standard Error: 6_141 + .saturating_add(Weight::from_parts(203_335, 0).saturating_mul(l.into())) + .saturating_add(RocksDbWeight::get().reads(13_u64)) + .saturating_add(RocksDbWeight::get().writes(8_u64)) } + /// Storage: `Staking::VirtualStakers` (r:1 w:1) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::CounterForNominators` (r:1 w:1) /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Staking::SpanSlash` (r:0 w:100) @@ -1350,14 +1578,14 @@ impl WeightInfo for () { /// The range of component `s` is `[1, 100]`. fn reap_stash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` - // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 98_014_000 picoseconds. - Weight::from_parts(102_537_670, 6248) - // Standard Error: 3_324 - .saturating_add(Weight::from_parts(1_353_142, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().writes(11_u64)) + // Measured: `2842 + s * (4 ±0)` + // Estimated: `8877 + s * (4 ±0)` + // Minimum execution time: 142_841_000 picoseconds. + Weight::from_parts(151_373_760, 8877) + // Standard Error: 4_909 + .saturating_add(Weight::from_parts(1_432_397, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(16_u64)) + .saturating_add(RocksDbWeight::get().writes(15_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -1367,16 +1595,20 @@ impl WeightInfo for () { /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:110 w:0) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:110 w:0) + /// Storage: `Staking::Bonded` (r:111 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:110 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:110 w:0) + /// Storage: `Staking::Nominators` (r:111 w:0) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:11 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForValidators` (r:1 w:0) - /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:0) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:201 w:0) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:11 w:0) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) /// Storage: `Staking::ValidatorCount` (r:1 w:0) /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::MinimumValidatorCount` (r:1 w:0) @@ -1399,16 +1631,16 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 100]`. fn new_era(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` - // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 608_575_000 picoseconds. - Weight::from_parts(613_663_000, 512390) - // Standard Error: 2_286_521 - .saturating_add(Weight::from_parts(72_108_001, 0).saturating_mul(v.into())) - // Standard Error: 227_839 - .saturating_add(Weight::from_parts(20_314_085, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(206_u64)) - .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) + // Measured: `0 + n * (720 ±0) + v * (3776 ±0)` + // Estimated: `516555 + n * (3566 ±0) + v * (3566 ±0)` + // Minimum execution time: 963_499_000 picoseconds. + Weight::from_parts(966_544_000, 516555) + // Standard Error: 2_158_092 + .saturating_add(Weight::from_parts(72_956_282, 0).saturating_mul(v.into())) + // Standard Error: 215_042 + .saturating_add(Weight::from_parts(19_482_545, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(410_u64)) + .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(v.into()))) @@ -1435,14 +1667,14 @@ impl WeightInfo for () { /// The range of component `n` is `[500, 1000]`. fn get_npos_voters(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` + // Measured: `3208 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 37_173_756_000 picoseconds. - Weight::from_parts(37_488_937_000, 512390) - // Standard Error: 467_413 - .saturating_add(Weight::from_parts(8_086_367, 0).saturating_mul(v.into())) - // Standard Error: 467_413 - .saturating_add(Weight::from_parts(3_108_193, 0).saturating_mul(n.into())) + // Minimum execution time: 36_355_465_000 picoseconds. + Weight::from_parts(36_660_578_000, 512390) + // Standard Error: 422_770 + .saturating_add(Weight::from_parts(3_407_216, 0).saturating_mul(v.into())) + // Standard Error: 422_770 + .saturating_add(Weight::from_parts(6_173_669, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(201_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -1450,22 +1682,30 @@ impl WeightInfo for () { .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) .saturating_add(Weight::from_parts(0, 3566).saturating_mul(v.into())) } - /// Storage: `Staking::CounterForValidators` (r:1 w:0) - /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:0) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:201 w:0) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:1001 w:0) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:1001 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1001 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1001 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// The range of component `v` is `[500, 1000]`. fn get_npos_targets(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `979 + v * (50 ±0)` - // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_641_258_000 picoseconds. - Weight::from_parts(382_882_595, 3510) - // Standard Error: 11_991 - .saturating_add(Weight::from_parts(4_695_820, 0).saturating_mul(v.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) - .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) + // Measured: `58129 + v * (323 ±0)` + // Estimated: `516555 + v * (3033 ±0)` + // Minimum execution time: 8_890_124_000 picoseconds. + Weight::from_parts(9_016_030_000, 516555) + // Standard Error: 111_852 + .saturating_add(Weight::from_parts(7_039_233, 0).saturating_mul(v.into())) + .saturating_add(RocksDbWeight::get().reads(206_u64)) + .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3033).saturating_mul(v.into())) } /// Storage: `Staking::MinCommission` (r:0 w:1) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -1485,8 +1725,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_753_000 picoseconds. - Weight::from_parts(6_529_000, 0) + // Minimum execution time: 5_627_000 picoseconds. + Weight::from_parts(6_134_000, 0) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) @@ -1507,8 +1747,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_212_000 picoseconds. - Weight::from_parts(5_451_000, 0) + // Minimum execution time: 4_901_000 picoseconds. + Weight::from_parts(5_209_000, 0) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) @@ -1527,20 +1767,22 @@ impl WeightInfo for () { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:2 w:2) + /// Storage: `TargetList::ListNodes` (r:1 w:1) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill_other() -> Weight { // Proof Size summary in bytes: - // Measured: `1939` - // Estimated: `6248` - // Minimum execution time: 73_000_000 picoseconds. - Weight::from_parts(75_184_000, 6248) - .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + // Measured: `2544` + // Estimated: `8877` + // Minimum execution time: 111_325_000 picoseconds. + Weight::from_parts(114_102_000, 8877) + .saturating_add(RocksDbWeight::get().reads(15_u64)) + .saturating_add(RocksDbWeight::get().writes(9_u64)) } /// Storage: `Staking::MinCommission` (r:1 w:0) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -1548,10 +1790,10 @@ impl WeightInfo for () { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) fn force_apply_min_commission() -> Weight { // Proof Size summary in bytes: - // Measured: `691` + // Measured: `724` // Estimated: `3510` - // Minimum execution time: 13_056_000 picoseconds. - Weight::from_parts(13_517_000, 3510) + // Minimum execution time: 13_264_000 picoseconds. + Weight::from_parts(13_696_000, 3510) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1561,10 +1803,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_201_000 picoseconds. - Weight::from_parts(3_442_000, 0) + // Minimum execution time: 3_052_000 picoseconds. + Weight::from_parts(3_242_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: `Staking::VirtualStakers` (r:1 w:0) + /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) @@ -1575,13 +1819,65 @@ impl WeightInfo for () { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1047` + // Measured: `1165` // Estimated: `4764` - // Minimum execution time: 44_671_000 picoseconds. - Weight::from_parts(45_611_000, 4764) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Minimum execution time: 61_779_000 picoseconds. + Weight::from_parts(62_484_000, 4764) + .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } + /// Storage: `Staking::Bonded` (r:3 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:2 w:2) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:2 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:2 w:1) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::MinNominatorBond` (r:1 w:0) + /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:1 w:1) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn drop_dangling_nomination() -> Weight { + // Proof Size summary in bytes: + // Measured: `1973` + // Estimated: `8631` + // Minimum execution time: 101_638_000 picoseconds. + Weight::from_parts(103_488_000, 8631) + .saturating_add(RocksDbWeight::get().reads(14_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `Staking::Nominators` (r:6 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:21 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:21 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListNodes` (r:180 w:180) + /// Proof: `TargetList::ListNodes` (`max_values`: None, `max_size`: Some(170), added: 2645, mode: `MaxEncodedLen`) + /// Storage: `TargetList::ListBags` (r:2 w:2) + /// Proof: `TargetList::ListBags` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) + /// Storage: `TargetList::CounterForListNodes` (r:1 w:1) + /// Proof: `TargetList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn v13_mmb_partial_step() -> Weight { + // Proof Size summary in bytes: + // Measured: `70141` + // Estimated: `477090` + // Minimum execution time: 2_703_732_000 picoseconds. + Weight::from_parts(2_779_206_000, 477090) + .saturating_add(RocksDbWeight::get().reads(231_u64)) + .saturating_add(RocksDbWeight::get().writes(183_u64)) + } } diff --git a/substrate/frame/staking/stake-tracker/Cargo.toml b/substrate/frame/staking/stake-tracker/Cargo.toml new file mode 100644 index 000000000000..dffdb0d037d4 --- /dev/null +++ b/substrate/frame/staking/stake-tracker/Cargo.toml @@ -0,0 +1,80 @@ +[package] +name = "pallet-stake-tracker" +version = "0.1.0" +description = "FRAME stake tracker pallet" +authors = ["Parity Technologies "] +homepage = "https://substrate.io" +edition = "2021" +license = "Apache-2.0" +repository = "https://github.com/paritytech/polkadot-sdk" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { features = [ + "derive", +], workspace = true } + + +scale-info = { features = ["derive", "serde"], workspace = true } + +sp-runtime = { features = ["serde"], workspace = true } +sp-staking = { features = ["serde"], workspace = true } + +sp-npos-elections = { workspace = true, default-features = false } +frame-election-provider-support = { workspace = true, default-features = false } +frame-support = { workspace = true } +frame-system = { workspace = true } + +# Optional imports for benchmarking +frame-benchmarking = { optional = true, workspace = true } + +[dev-dependencies] +sp-core = { workspace = true, default-features = true } +sp-io = { workspace = true } +sp-tracing = { workspace = true, default-features = true } +pallet-bags-list = { workspace = true, default-features = false, features = ["try-runtime"] } +pallet-balances = { workspace = true, default-features = true } +frame-benchmarking = { workspace = true, default-features = true } + +[features] +default = ["std"] + +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-election-provider-support/std", + "frame-support/std", + "frame-system/std", + "pallet-bags-list/std", + "pallet-balances/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-npos-elections/std", + "sp-runtime/std", + "sp-runtime/std", + "sp-staking/std", + "sp-tracing/std", +] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-election-provider-support/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-bags-list/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "sp-staking/runtime-benchmarks", +] + +try-runtime = [ + "frame-election-provider-support/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-bags-list/try-runtime", + "pallet-balances/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/substrate/frame/staking/stake-tracker/src/lib.rs b/substrate/frame/staking/stake-tracker/src/lib.rs new file mode 100644 index 000000000000..48121824fb84 --- /dev/null +++ b/substrate/frame/staking/stake-tracker/src/lib.rs @@ -0,0 +1,522 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! # Stake Tracker Pallet +//! +//! The stake-tracker pallet is responsible to keep track of the voter's stake and target's approval +//! voting in the staking system. +//! +//! ## Overview +//! +//! The stake-tracker pallet listens to staking events through implementing the [`OnStakingUpdate`] +//! trait. Based on the emitted events, the goal of this pallet is to maintain a **strictly** +//! sorted list of targets by approval voting. This pallet may also update a voter list and their +//! scores, based on the [`crate::VoterUpdateMode`] configuration. +//! +//! For the voter list, the [`crate::VoterUpdateMode`] defines the type of sortition of the list, +//! namely: +//! +//! - [`crate::VoterUpdateMode::Lazy`]: will skip the score update in the voter list. +//! - [`crate::VoterUpdateMode::Strict`]: will ensure that the score updates are kept sorted +//! for the corresponding list. In this case, the [`Config::VoterList`] is *strictly* +//! sorted by [`SortedListProvider::Score`] (note: from the time the sorting mode is strict). +//! +//! Note that insertions and removals of voter nodes will be executed regardless of the sorting +//! mode. +//! +//! ## Goals +//! +//! The [`OnStakingUpdate`] implementation (in strict mode) aims to achieve the following goals: +//! +//! * The [`Config::TargetList`] keeps a sorted list of validators, *strictly* sorted by approvals +//! (which include self-vote and nominations' stake). +//! * The [`Config::VoterList`] keeps a list of voters, *stricly* sorted by bonded stake if it has +//! [`crate::VoterUpdateMode::Strict`] mode enabled, otherwise the list is kept lazily sorted. +//! * The [`Config::TargetList`] sorting must be *always* kept up to date, even in the event of new +//! nomination updates, nominator/validator slashes and rewards. This pallet *must* ensure that the +//! scores of the targets and voters are always up to date and thus, that the targets and voters in +//! the lists are sorted by score at all time. +//! +//! Note that from the POV of this pallet, staking actions may result in one or multiple updates to +//! [`Config::VoterList`] and/or [`Config::TargetList`] state. If a set of staking updates require +//! too much weight to execute (e.g. at nominator's rewards payout or at slashes), the event emitter +//! should handle that in some way (e.g. buffering events and implementing a multi-block event +//! emitter). +//! +//! ## Staker status and list invariants +//! +//! * A [`sp_staking::StakerStatus::Nominator`] is part of the voter list and its self-stake is the +//! voter list's score. In addition, if the `VoterList` is in strict mode, the voters' scores are up +//! to date with the current stake returned by [`sp_staking::StakingInterface`]. +//! * A [`sp_staking::StakerStatus::Validator`] is part of both voter and target list. In addition, +//! its approvals score (nominations + self-stake) is kept up to date as the target list's score. +//! * A [`sp_staking::StakerStatus::Idle`] may have a target list's score while other stakers +//! nominate the idle validator. +//! * A "dangling" target, which is not an active staker anymore (i.e. not bonded), may still have +//! an associated target list score. This may happen when active nominators are still nominating +//! the target after the validator unbonded. The target list's node and score will automatically +//! be removed onced all the voters stop nominating the unbonded account (i.e. the target's score +//! drops to 0). +//! +//! ## Expectations +//! +//! For the goals and invariants to be respected, this pallet expects the following: +//! +//! - **Event emitting order**: It is important to ensure that the events are emitted from staking +//! (i.e. the calls into +//! [`OnStakingUpdate`]) *after* the staking ledger has been updated by the caller, since the new +//! state will be fetched and used to update the sorted lists accordingly. +//! - **Deduplicate nominations**: The nominations should be deduplicate. This pallet handles +//! nominations of voters from the underlying staking system. The nominations may be retrieved +//! through the [`sp_staking::StakingInterface`] and/or through the [`sp_staking::OnStakingUpdate`] +//! methods. This pallet expects that there are no duplicate nominations for each voter. + +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +extern crate alloc; + +use alloc::{collections::btree_map::BTreeMap, vec, vec::Vec}; +use frame_election_provider_support::SortedListProvider; +use frame_support::{ + defensive, + pallet_prelude::*, + traits::{fungible::Inspect as FnInspect, Defensive, DefensiveSaturating}, +}; +use sp_runtime::traits::Zero; +use sp_staking::{ + currency_to_vote::CurrencyToVote, OnStakingUpdate, Stake, StakerStatus, StakingInterface, +}; + +#[cfg(test)] +pub(crate) mod mock; +#[cfg(test)] +mod tests; + +/// The balance type of this pallet. +pub type BalanceOf = <::Staking as StakingInterface>::Balance; +/// The account ID of this pallet. +pub type AccountIdOf = ::AccountId; + +/// Represents a stake imbalance to be applied to a staker's score. +#[derive(Copy, Clone, Debug)] +pub enum StakeImbalance { + /// Represents the reduction of stake by `Score`. + Negative(Score), + /// Represents the increase of stake by `Score`. + Positive(Score), +} + +impl StakeImbalance { + /// Constructor for a stake imbalance instance based on the previous and next score. + fn from(prev: Score, new: Score) -> Self { + if prev > new { + StakeImbalance::Negative(prev.defensive_saturating_sub(new)) + } else { + StakeImbalance::Positive(new.defensive_saturating_sub(prev)) + } + } +} + +/// Defines the sorting mode of sorted list providers. +#[derive(Copy, Clone, Debug)] +pub enum VoterUpdateMode { + /// All score update events will be automatically reflected in the sorted list. + Strict, + /// Score update events are *not* be automatically reflected in the sorted list. However, node + /// insertion and removals are reflected in the list. + Lazy, +} + +impl VoterUpdateMode { + fn is_strict_mode(&self) -> bool { + matches!(self, Self::Strict) + } +} + +#[frame_support::pallet] +pub mod pallet { + use crate::*; + use frame_election_provider_support::{ExtendedBalance, VoteWeight}; + + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The stake balance. + type Currency: FnInspect>; + + /// The staking interface. + type Staking: StakingInterface; + + /// A sorted list provider for staking voters that is kept up to date by this pallet. + // [`Self::VoterUpdateMode`] defines whether this pallet will keep the voter list + // *strictly ordered* for every nominator stake updateor lazily ordered. + type VoterList: SortedListProvider; + + /// A sorted list provider for staking targets that is ketp *always* sorted by the target's + /// stake approvals. + type TargetList: SortedListProvider; + + /// The voter list update mode. + type VoterUpdateMode: Get; + } + + impl Pallet { + /// Updates the stake of a voter. + /// + /// NOTE: This method expects `nominations` to be deduplicated, otherwise the approvals + /// stakes of the duplicated target may become higher than expected silently. + pub(crate) fn do_stake_update_voter( + who: &T::AccountId, + prev_stake: Option>>, + stake: Stake>, + nominations: Vec, + ) { + defensive_assert!(!Self::has_duplicate_nominations(nominations.clone())); + + let voter_weight = Self::to_vote(stake.active); + + // if voter list is in strict sorting mode, update the voter score too. + if T::VoterUpdateMode::get().is_strict_mode() { + let _ = T::VoterList::on_update(who, voter_weight).defensive_proof( + "staker should exist in VoterList, as per the contract \ + with staking.", + ); + } + + let stake_imbalance = StakeImbalance::from( + prev_stake.map_or(Default::default(), |s| Self::to_vote(s.active).into()), + voter_weight.into(), + ); + + // updates vote weight of nominated targets accordingly. Note: this will + // update the score of up to `T::MaxNominations` validators. + for target in nominations.into_iter() { + Self::update_target_score(&target, stake_imbalance); + } + } + + /// Updates the stake of a target. + pub(crate) fn do_stake_update_target( + who: &T::AccountId, + prev_stake: Option>>, + stake: Stake>, + ) { + let voter_weight = Self::to_vote(stake.active).into(); + let stake_imbalance = StakeImbalance::from( + prev_stake.map_or(Default::default(), |s| Self::to_vote(s.active).into()), + voter_weight, + ); + + Self::update_target_score(who, stake_imbalance); + + // validator is both a target and a voter. update the voter score if the voter list + // is in strict mode. + if T::VoterUpdateMode::get().is_strict_mode() { + let _ = T::VoterList::on_update(who, Self::to_vote(stake.active)).defensive_proof( + "the staker should exist in VoterList, as per the \ + contract with staking.", + ); + } + } + + /// Updates a target's score by increasing/decreasing an imbalance of the current score in + /// the target list. + pub(crate) fn update_target_score( + who: &T::AccountId, + imbalance: StakeImbalance, + ) { + // if target list does not contain target, add it and proceed. + if !T::TargetList::contains(who) { + let _ = T::TargetList::on_insert(who.clone(), Zero::zero()).defensive_proof( + "staker does not yet exist in the list as per check above; qed.", + ); + } + + // update target score. + match imbalance { + StakeImbalance::Positive(imbalance) => { + let _ = T::TargetList::on_increase(who, imbalance).defensive_proof( + "staker should exist in the list, otherwise returned earlier.", + ); + }, + StakeImbalance::Negative(imbalance) => { + if let Ok(current_score) = T::TargetList::get_score(who) { + let balance = current_score.saturating_sub(imbalance); + + // the target is removed from the list IFF score is 0. + if balance.is_zero() { + let _ = T::TargetList::on_remove(who).defensive_proof( + "staker exists in the list as per the check above; qed.", + ); + } else { + // update the target score without removing it. + let _ = T::TargetList::on_update(who, balance).defensive_proof( + "staker exists in the list as per the check above; qed.", + ); + } + } else { + defensive!("unexpected: unable to fetch score from staking interface of an existent staker"); + } + }, + }; + } + + // ------ Helpers + + /// Helper to convert the balance of a staker into its vote weight. + pub(crate) fn to_vote(balance: BalanceOf) -> VoteWeight { + ::CurrencyToVote::to_vote( + balance, + T::Currency::total_issuance(), + ) + } + + /// Helper to fetch te active stake of a staker and convert it to vote weight. + pub fn vote_of(who: &T::AccountId) -> VoteWeight { + let active = T::Staking::stake(who).map(|s| s.active).defensive_unwrap_or_default(); + Self::to_vote(active) + } + + /// Returns whether a nomination vec has duplicate targets. + /// + /// Used for debug assertions only, since this pallet expects the nominations to be + /// deduplicated at all places. + pub fn has_duplicate_nominations(mut v: Vec) -> bool { + use alloc::collections::btree_set::BTreeSet; + let size_before = v.len(); + let dedup = v.drain(..).collect::>().into_iter().collect::>(); + + size_before != dedup.len() + } + } +} + +impl OnStakingUpdate> for Pallet { + /// When a nominator's stake is updated, all the nominated targets must be updated + /// accordingly. + /// + /// The score of the node associated with `who` in the *VoterList* will be updated if the + /// the mode is [`VoterUpdateMode::Strict`]. The approvals of the nominated targets (by `who`) + /// are always updated. + fn on_stake_update( + who: &T::AccountId, + prev_stake: Option>>, + stake: Stake>, + ) { + match T::Staking::status(who) { + Ok(StakerStatus::Nominator(nominations)) => + Self::do_stake_update_voter(who, prev_stake, stake, nominations), + Ok(StakerStatus::Validator) => Self::do_stake_update_target(who, prev_stake, stake), + Ok(StakerStatus::Idle) => (), // nothing to see here. + Err(_) => { + defensive!( + "staker should exist when calling `on_stake_update` and have a valid status" + ); + }, + } + } + + /// Triggered when a new validator is added to the system. + /// + /// Overview: If `who` is part of the target list, update its score. Otherwise, insert a new + /// node to the target list with self-stake as initial node score. + /// + /// A validator is also considered a voter with self-vote and should be added to + /// [`Config::VoterList`]. + fn on_validator_add(who: &T::AccountId, self_stake: Stake>) { + let self_stake = Self::to_vote(self_stake.active).into(); + + match T::TargetList::on_insert(who.clone(), self_stake) { + Ok(_) => (), + Err(_) => { + // if the target already exists in the list, it means that the target is idle + // and/or is dangling and now it's becoming active again. + defensive_assert!( + T::Staking::status(who) == Ok(StakerStatus::Idle) || + T::Staking::status(who).is_err() + ); + + Self::update_target_score(who, StakeImbalance::Positive(self_stake)); + }, + } + + // a validator is also a nominator. + Self::on_nominator_add(who, vec![who.clone()]) + } + + /// Triggered when a validator is chilled. + /// + /// Overview: When chilled, the target node may not be removed from the target list. The + /// associated target list score is updated so that the self-stake is decreased from itself. + /// + /// This method will not *try* to remove the target from the target list. That is the + /// responsability of [`OnStakingUpdate::on_validator_remove`]. + fn on_validator_idle(who: &T::AccountId) { + // validator is a validator with itself as a nomination. + Self::on_nominator_idle(who, vec![who.clone()]); + } + + /// Triggered when a validator is set as inactive/removed by the staking system. + /// + /// Overview: Updates the target list score so that `who`'s self-vote is decreased from itself. + /// The target node is removed from the target list IFF its score is 0 after update. Otherwise, + /// it means that there are "dangling" nominations to `who`, ie. there are nominators who are + /// nominating `who`. even though it is chilled/removed. + /// + /// Note: `who` *MUST* be either an active validator or chilled staker. + fn on_validator_remove(who: &T::AccountId) { + debug_assert!( + T::Staking::status(who) == Ok(StakerStatus::Validator) || + T::Staking::status(who) == Ok(StakerStatus::Idle) + ); + + if let Ok(score) = T::TargetList::get_score(who) { + // remove from target list IIF score is zero. If `score != 0`, the target still has + // active nominations, thus we keep it in the target list with corresponding approval + // stake. + if score.is_zero() { + let _ = T::TargetList::on_remove(who) + .defensive_proof("target exists as per above; qed"); + } + } else { + // target is not part of the list. Given the contract with staking and the checks above, + // this may actually be called. Do nothing and skip defensive warns. + }; + } + + /// Triggered when a new nominator is added to the system. + /// + /// Overview: Inserts a new node in the voter list with the score being `who`'s bonded stake. + /// The new node is inserted regardless of the [`crate::VoterUpdateMode`] set. + /// + /// Note: this method is also used locally when adding a new target (target is also a voter). + fn on_nominator_add(who: &T::AccountId, nominations: Vec>) { + defensive_assert!(!Self::has_duplicate_nominations(nominations.clone())); + + let nominator_vote = Self::vote_of(who); + + // the new voter node will be added even if the voter is in lazy mode. In lazy mode, we + // ensure that the nodes exist in the voter list, even though they may not have the updated + // score at all times. + let _ = T::VoterList::on_insert(who.clone(), nominator_vote).defensive_proof( + "the nominator must not exist in the list as per the contract with staking.", + ); + + // if `who` is a nominator, update the vote weight of the nominations if they exist. Note: + // this will update the score of up to `T::MaxNominations` validators. Note that `who` may + // be a validator. + match T::Staking::status(who).defensive() { + Ok(StakerStatus::Nominator(_)) => + for t in nominations { + Self::update_target_score(&t, StakeImbalance::Positive(nominator_vote.into())) + }, + Ok(StakerStatus::Idle) | Ok(StakerStatus::Validator) | Err(_) => (), // nada. + }; + } + + /// Triggered when a nominator is chilled. + /// + /// Overview: From this pallet POV, chilling a nominator is the same as removing it, since each + /// nominator only has self-stake as the voter list's node score. + fn on_nominator_idle(who: &T::AccountId, nominations: Vec) { + Self::on_nominator_remove(who, nominations); + } + + /// Triggered when a nominator is removed (or chilled). + /// + /// Overview: for each of `who`'s nomination targets, decrease `who`'s self-stake from their + /// score. In addition, remove `who`'s node from the voter list. + /// + /// Note: the number of nodes that are updated is bounded by the maximum number of + /// nominators, which is defined in the staking pallet. + fn on_nominator_remove(who: &T::AccountId, nominations: Vec) { + defensive_assert!(!Self::has_duplicate_nominations(nominations.clone())); + + let nominator_vote = Self::vote_of(who); + + // updates the nominated target's score. + for t in nominations.iter() { + Self::update_target_score(t, StakeImbalance::Negative(nominator_vote.into())) + } + + let _ = T::VoterList::on_remove(who).defensive_proof( + "the nominator must exist in the list as per the contract with staking.", + ); + } + + /// Triggered when a nominator updates their nominations. + /// + /// Overview: The approval scores of the the targets affected by the nomination updates must be + /// updated accordingly. + /// + /// Note that the nominator's stake remains the same (updates to the nominator's stake should + /// emit [`Self::on_stake_update`] instead). + fn on_nominator_update( + who: &T::AccountId, + prev_nominations: Vec, + nominations: Vec, + ) { + defensive_assert!(!Self::has_duplicate_nominations(nominations.clone())); + + let nominator_vote = Self::vote_of(who); + + // new nominations. + for target in nominations.iter() { + if !prev_nominations.contains(target) { + Self::update_target_score(target, StakeImbalance::Positive(nominator_vote.into())); + } + } + // removed nominations. + for target in prev_nominations.iter() { + if !nominations.contains(target) { + Self::update_target_score(target, StakeImbalance::Negative(nominator_vote.into())); + } + } + } + + // no-op events. + + /// Triggered when a staker (nominator/validator) is slashed. + /// + /// From the stake-tracker POV, no direct updates should be made to the target or voter list in + /// this event handler, since the stake updates from a slash will be indirectly performed + /// through the call to `on_stake_update` resulting from the slash performed at a higher level + /// (i.e. by staking). + fn on_slash( + _stash: &T::AccountId, + _slashed_active: BalanceOf, + _slashed_unlocking: &BTreeMap>, + _slashed_total: BalanceOf, + ) { + } + + /// The score of the staker `who` is updated through the `on_stake_update` calls following the + /// full unstake (ledger kill). + fn on_unstake(_who: &T::AccountId) {} + + /// The score of the staker `who` is updated through the `on_stake_update` calls following the + /// withdraw. + fn on_withdraw(_who: &T::AccountId, _amount: BalanceOf) {} +} diff --git a/substrate/frame/staking/stake-tracker/src/mock.rs b/substrate/frame/staking/stake-tracker/src/mock.rs new file mode 100644 index 000000000000..cd7c6e3eb28c --- /dev/null +++ b/substrate/frame/staking/stake-tracker/src/mock.rs @@ -0,0 +1,526 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +use crate::{self as pallet_stake_tracker, *}; + +use frame_election_provider_support::{ScoreProvider, VoteWeight}; +use frame_support::{derive_impl, parameter_types, traits::ConstU32}; +use sp_runtime::{BuildStorage, DispatchResult, Perbill}; +use sp_staking::{Stake, StakingInterface}; + +pub(crate) type AccountId = u64; +pub(crate) type Balance = u64; + +type Block = frame_system::mocking::MockBlockU32; + +// Configure a mock runtime to test the pallet. +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Test; + + #[runtime::pallet_index(0)] + pub type System = frame_system::Pallet; + + #[runtime::pallet_index(1)] + pub type Balances = pallet_balances::Pallet; + + #[runtime::pallet_index(2)] + pub type StakeTracker = pallet_stake_tracker::Pallet; + + #[runtime::pallet_index(3)] + pub type VoterBagsList = pallet_bags_list::Pallet; + + #[runtime::pallet_index(4)] + pub type TargetBagsList = pallet_bags_list::Pallet; +} + +parameter_types! { + pub static ExistentialDeposit: Balance = 1; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; + type BlockHashCount = ConstU32<10>; + + type AccountData = pallet_balances::AccountData; +} + +impl pallet_balances::Config for Test { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = frame_support::traits::ConstU32<1024>; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type FreezeIdentifier = (); + type RuntimeHoldReason = (); + type RuntimeFreezeReason = (); + type MaxFreezes = (); +} + +const VOTER_THRESHOLDS: [sp_npos_elections::VoteWeight; 9] = + [100, 200, 300, 400, 500, 600, 700, 800, 900]; + +const TARGET_THRESHOLDS: [u128; 9] = [100, 200, 300, 400, 500, 600, 700, 800, 900]; + +parameter_types! { + pub static VoterBagThresholds: &'static [VoteWeight] = &VOTER_THRESHOLDS; + pub static TargetBagThresholds: &'static [u128] = &TARGET_THRESHOLDS; + + pub static VoterUpdateMode: crate::VoterUpdateMode = crate::VoterUpdateMode::Strict; +} + +type VoterBagsListInstance = pallet_bags_list::Instance1; +impl pallet_bags_list::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type ScoreProvider = StakingMock; + type BagThresholds = VoterBagThresholds; + type Score = VoteWeight; +} + +type TargetBagsListInstance = pallet_bags_list::Instance2; +impl pallet_bags_list::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type ScoreProvider = pallet_bags_list::Pallet; + type BagThresholds = TargetBagThresholds; + type Score = u128; +} + +impl pallet_stake_tracker::Config for Test { + type Currency = Balances; + type Staking = StakingMock; + type VoterList = VoterBagsList; + type TargetList = TargetBagsList; + type VoterUpdateMode = VoterUpdateMode; +} + +pub struct StakingMock {} + +impl ScoreProvider for StakingMock { + type Score = VoteWeight; + + fn score(id: &AccountId) -> Self::Score { + let nominators = TestNominators::get(); + nominators.get(id).unwrap().0.active + } + + fn set_score_of(_: &AccountId, _: Self::Score) { + unreachable!(); + } +} + +impl StakingInterface for StakingMock { + type Balance = Balance; + type AccountId = AccountId; + type CurrencyToVote = (); + + fn stake(who: &Self::AccountId) -> Result, sp_runtime::DispatchError> { + let n = TestNominators::get(); + match n.get(who) { + Some(nominator) => Some(nominator.0), + None => { + let v = TestValidators::get(); + v.get(who).copied() + }, + } + .ok_or("not a staker".into()) + } + + fn status( + who: &Self::AccountId, + ) -> Result, sp_runtime::DispatchError> { + let nominators = TestNominators::get(); + + match ( + TestValidators::get().contains_key(who), + nominators.contains_key(who), + Bonded::get().contains(who), + ) { + (true, true, true) => Ok(StakerStatus::Validator), + (false, true, true) => + Ok(StakerStatus::Nominator(nominators.get(who).expect("exists").1.clone())), + (false, false, true) => Ok(StakerStatus::Idle), + (false, false, false) => + if TargetBagsList::contains(who) { + Err("dangling".into()) + } else { + Err("not a staker".into()) + }, + _ => Err("bad state".into()), + } + } + + fn nominations(who: &Self::AccountId) -> Option> { + let n = TestNominators::get(); + n.get(who).map(|nominator| nominator.1.clone()) + } + + fn minimum_nominator_bond() -> Self::Balance { + unreachable!(); + } + + fn minimum_validator_bond() -> Self::Balance { + unreachable!(); + } + + fn stash_by_ctrl( + _controller: &Self::AccountId, + ) -> Result { + unreachable!(); + } + + fn bonding_duration() -> sp_staking::EraIndex { + unreachable!(); + } + + fn current_era() -> sp_staking::EraIndex { + unreachable!(); + } + + fn bond( + _who: &Self::AccountId, + _value: Self::Balance, + _payee: &Self::AccountId, + ) -> sp_runtime::DispatchResult { + unreachable!(); + } + + fn nominate( + who: &Self::AccountId, + validators: Vec, + ) -> sp_runtime::DispatchResult { + update_nominations_of(*who, validators); + + Ok(()) + } + + fn chill(_who: &Self::AccountId) -> sp_runtime::DispatchResult { + unreachable!(); + } + + fn bond_extra(_who: &Self::AccountId, _extra: Self::Balance) -> sp_runtime::DispatchResult { + unreachable!(); + } + + fn withdraw_unbonded( + _stash: Self::AccountId, + _num_slashing_spans: u32, + ) -> Result { + unreachable!(); + } + + fn desired_validator_count() -> u32 { + unreachable!(); + } + + fn election_ongoing() -> bool { + unreachable!(); + } + + fn force_unstake(_who: Self::AccountId) -> sp_runtime::DispatchResult { + unreachable!(); + } + + fn is_exposed_in_era(_who: &Self::AccountId, _era: &sp_staking::EraIndex) -> bool { + unreachable!(); + } + + fn unbond(_stash: &Self::AccountId, _value: Self::Balance) -> sp_runtime::DispatchResult { + unreachable!(); + } + + fn set_payee(_stash: &Self::AccountId, _reward_acc: &Self::AccountId) -> DispatchResult { + unreachable!(); + } + + fn slash_reward_fraction() -> Perbill { + unreachable!(); + } + + fn is_virtual_staker(_who: &Self::AccountId) -> bool { + unreachable!() + } + + #[cfg(feature = "runtime-benchmarks")] + fn add_era_stakers( + _current_era: &sp_staking::EraIndex, + _stash: &Self::AccountId, + _exposures: Vec<(Self::AccountId, Self::Balance)>, + ) { + unimplemented!("method currently not used in testing") + } + + #[cfg(feature = "runtime-benchmarks")] + fn set_current_era(_era: sp_staking::EraIndex) { + unimplemented!("method currently not used in testing") + } + + #[cfg(feature = "runtime-benchmarks")] + fn max_exposure_page_size() -> sp_staking::Page { + unimplemented!("method currently not used in testing") + } +} + +type Nominations = Vec; + +parameter_types! { + pub static TestNominators: BTreeMap, Nominations)> = Default::default(); + pub static TestValidators: BTreeMap> = Default::default(); + pub static Bonded: Vec = Default::default(); +} + +pub(crate) fn target_scores() -> Vec<(AccountId, u128)> { + TargetBagsList::iter() + .map(|e| (e, TargetBagsList::get_score(&e).unwrap())) + .collect::>() +} + +pub(crate) fn voter_scores() -> Vec<(AccountId, Balance)> { + VoterBagsList::iter() + .map(|e| (e, VoterBagsList::get_score(&e).unwrap())) + .collect::>() +} + +pub(crate) fn populate_lists() { + add_validator(10, 100); + add_validator(11, 100); + + add_nominator_with_nominations(1, 100, vec![10]); + add_nominator_with_nominations(2, 100, vec![10, 11]); +} + +pub(crate) fn add_nominator(who: AccountId, stake: Balance) { + Bonded::mutate(|b| { + b.push(who); + }); + + TestNominators::mutate(|n| { + n.insert(who, (Stake:: { active: stake, total: stake }, vec![])); + }); + + // add new nominator (called at `fn bond` in staking) + >::on_nominator_add(&who, vec![]); +} + +pub(crate) fn stake_of(who: AccountId) -> Option> { + StakingMock::stake(&who).ok() +} + +pub(crate) fn score_of_target(who: AccountId) -> Balance { + as ScoreProvider>::score( + &who, + ) + .try_into() + .unwrap() +} + +pub(crate) fn add_nominator_with_nominations( + who: AccountId, + stake: Balance, + nominations: Nominations, +) { + // add new nominator (called at `fn bond` in staking) + add_nominator(who, stake); + + TestNominators::mutate(|n| { + n.insert(who, (Stake:: { active: stake, total: stake }, nominations.clone())); + }); + + >::on_nominator_update( + &who, + vec![], + nominations, + ); +} + +pub(crate) fn update_nominations_of(who: AccountId, new_nominations: Nominations) { + // add nominations (called at `fn nominate` in staking) + let current_nom = TestNominators::get(); + let (current_stake, prev_nominations) = current_nom.get(&who).unwrap(); + + TestNominators::mutate(|n| { + n.insert(who, (*current_stake, new_nominations.clone())); + }); + + >::on_nominator_update( + &who, + prev_nominations.clone(), + new_nominations, + ); +} + +pub(crate) fn add_validator(who: AccountId, self_stake: Balance) { + Bonded::mutate(|b| { + b.push(who); + }); + + let stake = Stake { active: self_stake, total: self_stake }; + + TestValidators::mutate(|v| { + v.insert(who, stake); + }); + // validator is a nominator too. + TestNominators::mutate(|v| { + v.insert(who, (stake, vec![])); + }); + + >::on_validator_add(&who, stake); +} + +pub(crate) fn update_stake(who: AccountId, new: Balance, prev_stake: Option>) { + match StakingMock::status(&who) { + Ok(StakerStatus::Nominator(nominations)) => { + TestNominators::mutate(|n| { + n.insert(who, (Stake { active: new, total: new }, nominations)); + }); + }, + Ok(StakerStatus::Validator) => { + TestValidators::mutate(|v| { + v.insert(who, Stake { active: new, total: new }); + }); + TestNominators::mutate(|n| { + let nominations = n.get(&who).expect("exists").1.clone(); + n.insert(who, (Stake { active: new, total: new }, nominations)); + }) + }, + Ok(StakerStatus::Idle) | Err(_) => panic!("not a staker"), + } + + >::on_stake_update( + &who, + prev_stake, + Stake { total: new, active: new }, + ); +} + +pub(crate) fn chill_staker(who: AccountId) { + if TestNominators::get().contains_key(&who) && !TestValidators::get().contains_key(&who) { + let nominations = ::nominations(&who).unwrap(); + + >::on_nominator_idle(&who, nominations); + TestNominators::mutate(|n| n.remove(&who)); + } else if TestValidators::get().contains_key(&who) { + >::on_validator_idle(&who); + TestValidators::mutate(|v| v.remove(&who)); + TestNominators::mutate(|v| v.remove(&who)); + }; +} + +pub(crate) fn remove_staker(who: AccountId) { + match StakingMock::status(&who) { + Ok(StakerStatus::Nominator(_)) => { + let nominations = ::nominations(&who).unwrap(); + >::on_nominator_remove( + &who, + nominations, + ); + TestNominators::mutate(|n| { + n.remove(&who); + }); + }, + Ok(StakerStatus::Validator) => { + >::on_validator_idle(&who); + >::on_validator_remove(&who); + TestValidators::mutate(|v| v.remove(&who)); + }, + Ok(StakerStatus::Idle) => + if TargetBagsList::contains(&who) { + >::on_validator_remove(&who); + }, + _ => {}, + } + + Bonded::mutate(|b| { + b.retain(|s| s != &who); + }); +} + +pub(crate) fn target_bags_events() -> Vec> { + System::events() + .into_iter() + .map(|r| r.event) + .filter_map( + |e| if let RuntimeEvent::TargetBagsList(inner) = e { Some(inner) } else { None }, + ) + .collect::>() +} + +pub(crate) fn voter_bags_events() -> Vec> { + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| if let RuntimeEvent::VoterBagsList(inner) = e { Some(inner) } else { None }) + .collect::>() +} + +#[derive(Default, Copy, Clone)] +pub struct ExtBuilder { + populate_lists: bool, +} + +impl ExtBuilder { + pub fn populate_lists(mut self) -> Self { + self.populate_lists = true; + self + } + + pub fn voter_update_mode(self, mode: crate::VoterUpdateMode) -> Self { + VoterUpdateMode::set(mode); + self + } + + pub fn build(self) -> sp_io::TestExternalities { + sp_tracing::try_init_simple(); + let storage = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + sp_io::TestExternalities::from(storage) + } + + pub fn build_and_execute(self, test: impl FnOnce()) { + sp_tracing::try_init_simple(); + + let mut ext = self.build(); + ext.execute_with(|| { + if self.populate_lists { + populate_lists(); + } + // move past genesis to register events. + System::set_block_number(1); + }); + ext.execute_with(test); + } +} diff --git a/substrate/frame/staking/stake-tracker/src/tests.rs b/substrate/frame/staking/stake-tracker/src/tests.rs new file mode 100644 index 000000000000..b53c670b0491 --- /dev/null +++ b/substrate/frame/staking/stake-tracker/src/tests.rs @@ -0,0 +1,612 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +use crate::{mock::*, StakeImbalance}; + +use frame_election_provider_support::{ScoreProvider, SortedListProvider}; +use frame_support::assert_ok; +use sp_staking::{OnStakingUpdate, Stake, StakerStatus, StakingInterface}; + +// keeping tests clean. +type A = AccountId; +type B = Balance; + +#[test] +fn setup_works() { + ExtBuilder::default().build_and_execute(|| { + assert!(TestNominators::get().is_empty()); + assert_eq!(VoterBagsList::count(), 0); + + assert!(TestValidators::get().is_empty()); + assert_eq!(TargetBagsList::count(), 0); + }); + + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(!TestNominators::get().is_empty()); + assert_eq!(VoterBagsList::count(), 4); // voter list has 2x nominatiors + 2x validators + + assert!(!TestValidators::get().is_empty()); + assert_eq!(TargetBagsList::count(), 2); + }); +} + +#[test] +fn update_target_score_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(TargetBagsList::contains(&10)); + assert_eq!(TargetBagsList::get_score(&10), Ok(300)); + + crate::Pallet::::update_target_score(&10, StakeImbalance::Negative(100)); + assert_eq!(TargetBagsList::get_score(&10), Ok(200)); + + crate::Pallet::::update_target_score(&10, StakeImbalance::Positive(100)); + assert_eq!(TargetBagsList::get_score(&10), Ok(300)); + + let current_score = TargetBagsList::get_score(&10).unwrap(); + crate::Pallet::::update_target_score(&10, StakeImbalance::Negative(current_score)); + + // score dropped to 0, node is removed. + assert!(!TargetBagsList::contains(&10)); + assert!(TargetBagsList::get_score(&10).is_err()); + }) +} + +// same as test above but does not panic after defensive so we can test invariants. +#[test] +#[cfg(not(debug_assertions))] +fn update_score_below_zero_defensive_no_panic_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(VoterBagsList::contains(&1)); + assert_eq!(VoterBagsList::get_score(&1), Ok(100)); + // updating the score below 0 is unexpected and saturates to 0. + crate::Pallet::::update_score::(&1, StakeImbalance::Negative(500)); + assert!(VoterBagsList::contains(&1)); + assert_eq!(VoterBagsList::get_score(&1), Ok(0)); + + let n = TestNominators::get(); + assert!(n.get(&1).is_some()); + }) +} + +#[test] +fn on_stake_update_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(VoterBagsList::contains(&1)); + let stake_before = stake_of(1); + + let nominations = ::nominations(&1).unwrap(); + assert!(nominations.len() == 1); + let nomination_score_before = TargetBagsList::get_score(&nominations[0]).unwrap(); + + // manually change the stake of the voter. + let new_stake = Stake { total: 10, active: 10 }; + // assert imbalance of the operation is negative. + assert!(stake_before.unwrap().active > new_stake.active); + + TestNominators::mutate(|n| { + n.insert(1, (new_stake, nominations.clone())); + }); + + >::on_stake_update(&1, stake_before, new_stake); + + assert_eq!(VoterBagsList::get_score(&1).unwrap(), new_stake.active); + + // now, the score of the nominated by 1 has `stake_score` less stake than before the + // nominator's stake was updated. + let nomination_score_after = TargetBagsList::get_score(&nominations[0]).unwrap(); + assert_eq!( + nomination_score_after, + nomination_score_before - (stake_before.unwrap().active - new_stake.active) as u128 + ); + }); + + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(TargetBagsList::contains(&10)); + assert!(VoterBagsList::contains(&10)); + let stake_before = stake_of(10); + let target_score_before = TargetBagsList::get_score(&10).unwrap(); + + // validator has no nominations, as expected. + assert!(::nominations(&10).unwrap().is_empty()); + + // manually change the self stake. + let new_stake = Stake { total: 10, active: 10 }; + // assert imbalance of the operation is negative. + assert!(stake_before.unwrap().active > new_stake.active); + TestNominators::mutate(|n| { + n.insert(10, (new_stake, vec![])); + }); + + let stake_imbalance = stake_before.unwrap().active - new_stake.total; + + >::on_stake_update(&10, stake_before, new_stake); + + assert_eq!(VoterBagsList::get_score(&10).unwrap(), new_stake.active); + assert_eq!(StakingMock::stake(&10), Ok(new_stake)); + + // target bags list was updated as expected (new score is difference between previous and + // the stake imbalance of previous and the new stake, in order to not touch the nomination's + // weight in the total target score). + let target_score_after = TargetBagsList::get_score(&10).unwrap(); + assert_eq!(target_score_after, target_score_before - stake_imbalance as u128); + }) +} + +#[test] +fn on_stake_update_lazy_voters_works() { + ExtBuilder::default() + .populate_lists() + .voter_update_mode(crate::VoterUpdateMode::Lazy) + .build_and_execute(|| { + assert!(VoterBagsList::contains(&1)); + let stake_before = stake_of(1); + + let nominations = ::nominations(&1).unwrap(); + assert!(nominations.len() == 1); + + let target_score_before = TargetBagsList::get_score(&10).unwrap(); + + // manually change the stake of the voter. + let new_stake = Stake { total: 10, active: 10 }; + // assert imbalance of the operation is negative. + assert!(stake_before.unwrap().active > new_stake.active); + let stake_imbalance = stake_before.unwrap().active - new_stake.total; + + TestNominators::mutate(|n| { + n.insert(1, (new_stake, nominations.clone())); + }); + + >::on_stake_update(&1, stake_before, new_stake); + + // score of voter did not update, since the voter list is lazily updated. + assert_eq!(VoterBagsList::get_score(&1).unwrap(), stake_before.unwrap().active); + + // however, the target's approvals are *always* updated, regardless of the voter's + // sorting mode. + let target_score_after = TargetBagsList::get_score(&10).unwrap(); + assert_eq!(target_score_after, target_score_before - stake_imbalance as u128); + }); +} + +#[test] +fn on_stake_update_sorting_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + let initial_sort = TargetBagsList::iter().collect::>(); + + // 10 starts with more score than 11. + assert_eq!(score_of_target(10), 300); + assert_eq!(score_of_target(11), 200); + assert!(score_of_target(10) > score_of_target(11)); + assert_eq!(initial_sort, [10, 11]); + + // add new nominator that add +200 score to 11, which reverts the target list order. + add_nominator_with_nominations(5, 200, vec![11]); + assert_eq!(score_of_target(11), 400); + assert!(score_of_target(10) < score_of_target(11)); + // sorting is now reverted as expected. + assert_eq!( + TargetBagsList::iter().collect::>(), + initial_sort.iter().rev().cloned().collect::>() + ); + + // now we remove the staker 5 to get back to the initial state. + remove_staker(5); + assert_eq!(score_of_target(10), 300); + assert_eq!(score_of_target(11), 200); + assert!(score_of_target(10) > score_of_target(11)); + assert_eq!(TargetBagsList::iter().collect::>(), initial_sort); + + // double-check, events from target bags list: scores being updated and rebag. + assert_eq!( + target_bags_events(), + [ + pallet_bags_list::Event::Rebagged { who: 11, from: 200, to: 400 }, + pallet_bags_list::Event::ScoreUpdated { who: 11, new_score: 400 }, + pallet_bags_list::Event::Rebagged { who: 11, from: 400, to: 200 }, + pallet_bags_list::Event::ScoreUpdated { who: 11, new_score: 200 }, + ], + ); + }); + + ExtBuilder::default().populate_lists().build_and_execute(|| { + // [(10, 100), (11, 100), (1, 100), (2, 100)] + let voter_scores_before = voter_scores(); + assert_eq!(voter_scores_before, [(10, 100), (11, 100), (1, 100), (2, 100)]); + + // noop, nothing changes. + let initial_stake = stake_of(11); + >::on_stake_update( + &11, + initial_stake, + initial_stake.unwrap(), + ); + assert_eq!(voter_scores_before, voter_scores()); + + // now let's change the self-vote of 11 and call `on_stake_update` again. + let nominations = ::nominations(&11).unwrap(); + let new_stake = Stake { total: 1, active: 1 }; + TestNominators::mutate(|n| { + n.insert(11, (new_stake, nominations.clone())); + }); + + >::on_stake_update(&11, initial_stake, new_stake); + + // although the voter score of 11 is 1, the voter list sorting has not been updated + // automatically. + assert_eq!(VoterBagsList::get_score(&11), Ok(1)); + // [(10, 100), (11, 1), (1, 100), (2, 100)] + assert_eq!( + voter_scores_before.iter().cloned().map(|(v, _)| v).collect::>(), + VoterBagsList::iter().collect::>() + ); + + // double-check, events from voter bags list: scores being updated but no rebag. + assert_eq!( + voter_bags_events(), + [ + pallet_bags_list::Event::ScoreUpdated { who: 11, new_score: 100 }, + pallet_bags_list::Event::ScoreUpdated { who: 11, new_score: 1 } + ], + ); + }); +} + +#[test] +#[should_panic = "Defensive failure has been triggered!: NodeNotFound: \"staker should exist in VoterList, as per the contract with staking.\""] +fn on_stake_update_defensive_not_in_list_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(VoterBagsList::contains(&1)); + // removes 1 from nominator's list manually, while keeping it as staker. + assert_ok!(VoterBagsList::on_remove(&1)); + + >::on_stake_update(&1, None, Stake::default()); + }) +} + +#[test] +#[should_panic = "Defensive failure has been triggered!: \"staker should exist when calling `on_stake_update` and have a valid status\""] +fn on_stake_update_defensive_not_staker_works() { + ExtBuilder::default().build_and_execute(|| { + assert!(!VoterBagsList::contains(&1)); + + >::on_stake_update(&1, None, Stake::default()); + }) +} + +#[test] +fn on_nominator_add_works() { + ExtBuilder::default().build_and_execute(|| { + let n = TestNominators::get(); + assert!(!VoterBagsList::contains(&5)); + assert_eq!(n.get(&5), None); + + add_nominator(5, 10); + assert!(VoterBagsList::contains(&5)); + }) +} + +#[test] +fn on_validator_add_works() { + ExtBuilder::default().build_and_execute(|| { + let n = TestNominators::get(); + let v = TestValidators::get(); + assert!(!VoterBagsList::contains(&5)); + assert!(!TargetBagsList::contains(&5)); + assert!(n.get(&5).is_none() && v.get(&5).is_none()); + + // add 5 as staker (target and voter). + TestNominators::mutate(|n| { + n.insert(5, Default::default()); + }); + TestValidators::mutate(|n| { + n.insert(5, Default::default()); + }); + }) +} + +#[test] +#[should_panic = "Defensive failure has been triggered!: Duplicate: \"the nominator must not exist in the list as per the contract with staking.\""] +fn on_nominator_add_already_exists_defensive_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(VoterBagsList::contains(&1)); + assert_eq!(VoterBagsList::count(), 4); + assert_eq!(>::score(&1), 100); + + let voter_list_before = VoterBagsList::iter().collect::>(); + let target_list_before = TargetBagsList::iter().collect::>(); + + // noop. + let nominations = ::nominations(&1).unwrap(); + >::on_nominator_add(&1, nominations); + assert!(VoterBagsList::contains(&1)); + assert_eq!(VoterBagsList::count(), 4); + assert_eq!(>::score(&1), 100); + + assert_eq!(VoterBagsList::iter().collect::>(), voter_list_before); + assert_eq!(TargetBagsList::iter().collect::>(), target_list_before); + }); +} + +#[test] +#[should_panic] +fn on_validator_add_already_exists_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(TargetBagsList::contains(&10)); + assert_eq!(TargetBagsList::count(), 2); + assert_eq!(>::score(&10), 300); + + let voter_list_before = VoterBagsList::iter().collect::>(); + let target_list_before = TargetBagsList::iter().collect::>(); + + // noop + >::on_validator_add( + &10, + Stake { total: 300, active: 300 }, + ); + assert!(TargetBagsList::contains(&10)); + assert_eq!(TargetBagsList::count(), 2); + assert_eq!(>::score(&10), 300); + + assert_eq!(VoterBagsList::iter().collect::>(), voter_list_before); + assert_eq!(TargetBagsList::iter().collect::>(), target_list_before); + }); +} + +#[test] +fn on_nominator_remove_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(VoterBagsList::contains(&1)); + let nominator_score = VoterBagsList::get_score(&1).unwrap(); + + let nominations = ::nominations(&1).unwrap(); + assert!(nominations.len() == 1); + let nomination_score_before = TargetBagsList::get_score(&nominations[0]).unwrap(); + + >::on_nominator_remove(&1, nominations.clone()); + + // the nominator was removed from the voter list. + assert!(!VoterBagsList::contains(&1)); + + // now, the score of the nominated by 1 has less `nominator_score` stake than before the + // nominator was removed. + let nomination_score_after = TargetBagsList::get_score(&nominations[0]).unwrap(); + assert!(nomination_score_after == nomination_score_before - nominator_score as u128); + }) +} + +#[test] +#[should_panic = "Defensive failure has been triggered!: NodeNotFound: \"the nominator must exist in the list as per the contract with staking.\""] +fn on_nominator_remove_defensive_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(VoterBagsList::contains(&1)); + + // remove 1 from the voter list to check if the defensive is triggered in the next call, + // while maintaining it as a staker so it does not early exist at the staking mock + // implementation. + assert_ok!(VoterBagsList::on_remove(&1)); + + >::on_nominator_remove(&1, vec![]); + }) +} + +mod staking_integration { + use super::*; + + #[test] + fn staking_interface_works() { + ExtBuilder::default().build_and_execute(|| { + assert_eq!(TestNominators::get().len(), 0); + assert_eq!(TestValidators::get().len(), 0); + + add_nominator(1, 100); + let n = TestNominators::get(); + assert_eq!(n.get(&1).unwrap().0, Stake { active: 100u64, total: 100u64 }); + assert_eq!(StakingMock::status(&1), Ok(StakerStatus::Nominator(vec![]))); + + add_validator(2, 200); + let v = TestValidators::get(); + assert_eq!(v.get(&2).copied().unwrap(), Stake { active: 200u64, total: 200u64 }); + assert_eq!(StakingMock::status(&2), Ok(StakerStatus::Validator)); + + chill_staker(1); + assert_eq!(StakingMock::status(&1), Ok(StakerStatus::Idle)); + // a chilled nominator is removed from the voter list right away. + assert!(!VoterBagsList::contains(&1)); + + remove_staker(1); + assert!(StakingMock::status(&1).is_err()); + assert!(!VoterBagsList::contains(&1)); + + chill_staker(2); + assert_eq!(StakingMock::status(&2), Ok(StakerStatus::Idle)); + // a chilled validator is dropped from the target list if its score is 0. + assert!(!TargetBagsList::contains(&2)); + assert!(!VoterBagsList::contains(&2)); + }) + } + + #[test] + fn on_add_stakers_works() { + ExtBuilder::default().build_and_execute(|| { + add_nominator(1, 100); + assert_eq!(TargetBagsList::count(), 0); + assert_eq!(VoterBagsList::count(), 1); + assert_eq!(VoterBagsList::get_score(&1).unwrap(), 100); + + add_validator(10, 200); + assert_eq!(VoterBagsList::count(), 2); // 1x nominator + 1x validator + assert_eq!(TargetBagsList::count(), 1); + assert_eq!(TargetBagsList::get_score(&10).unwrap(), 200); + }) + } + + #[test] + fn on_update_stake_works() { + ExtBuilder::default().build_and_execute(|| { + add_nominator(1, 100); + assert_eq!(VoterBagsList::get_score(&1).unwrap(), 100); + update_stake(1, 200, stake_of(1)); + assert_eq!(VoterBagsList::get_score(&1).unwrap(), 200); + + add_validator(10, 100); + assert_eq!(TargetBagsList::get_score(&10).unwrap(), 100); + update_stake(10, 200, stake_of(10)); + assert_eq!(TargetBagsList::get_score(&10).unwrap(), 200); + }) + } + + #[test] + fn on_remove_stakers_works() { + ExtBuilder::default().build_and_execute(|| { + add_nominator(1, 100); + assert!(VoterBagsList::contains(&1)); + + remove_staker(1); + assert!(!VoterBagsList::contains(&1)); + + add_validator(10, 100); + assert!(TargetBagsList::contains(&10)); + remove_staker(10); + assert!(!TargetBagsList::contains(&10)); + }) + } + + #[test] + fn on_remove_stakers_with_nominations_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert_eq!(target_scores(), vec![(10, 300), (11, 200)]); + + assert!(VoterBagsList::contains(&1)); + assert_eq!(VoterBagsList::get_score(&1), Ok(100)); + assert_eq!(TargetBagsList::get_score(&10), Ok(300)); + + // remove nominator deletes node from voter list and updates the stake of its + // nominations. + remove_staker(1); + assert!(!VoterBagsList::contains(&1)); + assert_eq!(TargetBagsList::get_score(&10), Ok(200)); + }) + } + + #[test] + fn on_nominator_update_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert_eq!(voter_scores(), vec![(10, 100), (11, 100), (1, 100), (2, 100)]); + assert_eq!(target_scores(), vec![(10, 300), (11, 200)]); + + add_validator(20, 500); + // removes nomination from 10 and adds nomination to new validator, 20. + update_nominations_of(2, vec![11, 20]); + + assert_eq!(voter_scores(), [(20, 500), (10, 100), (11, 100), (1, 100), (2, 100)]); + + // target list has been updated: + assert_eq!(target_scores(), vec![(20, 600), (11, 200), (10, 200)]); + }) + } + + #[test] + fn on_nominator_update_lazy_voter_works() { + ExtBuilder::default() + .populate_lists() + .voter_update_mode(crate::VoterUpdateMode::Lazy) + .build_and_execute(|| { + assert_eq!(voter_scores(), vec![(10, 100), (11, 100), (1, 100), (2, 100)]); + assert_eq!(target_scores(), vec![(10, 300), (11, 200)]); + + add_validator(20, 500); + // removes nomination from 10 and adds nomination to new validator, 20. + update_nominations_of(2, vec![11, 20]); + + // even in lazy mode, the new voter node is inserted. + assert_eq!(voter_scores(), [(20, 500), (10, 100), (11, 100), (1, 100), (2, 100)]); + + // target list has been updated: + assert_eq!(target_scores(), vec![(20, 600), (11, 200), (10, 200)]); + }) + } + + #[test] + fn target_chill_remove_lifecycle_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(TargetBagsList::contains(&10)); + // 10 has 2 nominations from 1 and 2. Each with 100 approvals, so 300 in total (2x + // nominated + // + 1x self-stake). + assert_eq!(>::score(&10), 300); + + // chill validator 10. + chill_staker(10); + assert_eq!(StakingMock::status(&10), Ok(StakerStatus::Idle)); + + // chilling removed the self stake (100) from score, but the nominations approvals + // remain. + assert!(TargetBagsList::contains(&10)); + assert_eq!(>::score(&10), 200); + + // even if the validator is removed, the target node remains in the list since approvals + // score != 0. + remove_staker(10); + assert!(TargetBagsList::contains(&10)); + assert_eq!(>::score(&10), 200); + assert!(StakingMock::status(&10).is_err()); + + // 1 stops nominating 10. + update_nominations_of(1, vec![]); + assert!(TargetBagsList::contains(&10)); + assert_eq!(>::score(&10), 100); + + // 2 stops nominating 10 and its approavals dropped to 0, thus the target node has been + // removed. + update_nominations_of(2, vec![]); + assert!(!TargetBagsList::contains(&10)); + assert_eq!(>::score(&10), 0); + }) + } + + #[test] + fn target_remove_lifecycle_works() { + ExtBuilder::default().populate_lists().build_and_execute(|| { + assert!(TargetBagsList::contains(&10)); + // 10 has 2 nominations from 1 and 2. Each with 100 approvals, so 300 in total (2x + // nominated + // + 1x self-stake). + assert_eq!(>::score(&10), 300); + + // remove validator 10. + remove_staker(10); + + // but the target list keeps track of the remaining approvals of 10, without the self + // stake. + assert!(TargetBagsList::contains(&10)); + assert_eq!(>::score(&10), 200); + + // 1 stops nominating 10. + update_nominations_of(1, vec![]); + assert!(TargetBagsList::contains(&10)); + assert_eq!(>::score(&10), 100); + + // 2 stops nominating 10. Since approvals of 10 drop to 0, the target list node is + // removed. + update_nominations_of(2, vec![]); + assert!(!TargetBagsList::contains(&10)); + assert_eq!(>::score(&10), 0); + }) + } +} diff --git a/substrate/primitives/staking/Cargo.toml b/substrate/primitives/staking/Cargo.toml index 35e7e4f60413..aeffff693c17 100644 --- a/substrate/primitives/staking/Cargo.toml +++ b/substrate/primitives/staking/Cargo.toml @@ -34,3 +34,4 @@ std = [ "sp-runtime/std", ] runtime-benchmarks = ["sp-runtime/runtime-benchmarks"] +test-utils = [] diff --git a/substrate/primitives/staking/src/lib.rs b/substrate/primitives/staking/src/lib.rs index 03c1af50240b..cd0a21178d41 100644 --- a/substrate/primitives/staking/src/lib.rs +++ b/substrate/primitives/staking/src/lib.rs @@ -73,6 +73,12 @@ pub enum StakerStatus { Nominator(Vec), } +impl StakerStatus { + pub fn is_nominator(&self) -> bool { + matches!(self, Self::Nominator(_)) + } +} + /// A struct that reflects stake that an account has in the staking system. Provides a set of /// methods to operate on it's properties. Aimed at making `StakingInterface` more concise. #[derive(RuntimeDebug, Clone, Copy, Eq, PartialEq, Default)] @@ -92,6 +98,12 @@ pub struct Stake { pub active: Balance, } +impl From for Stake { + fn from(balance: Balance) -> Self { + Self { total: balance, active: balance } + } +} + /// A generic staking event listener. /// /// Note that the interface is designed in a way that the events are fired post-action, so any @@ -103,19 +115,34 @@ pub trait OnStakingUpdate { /// /// This is effectively any changes to the bond amount, such as bonding more funds, and /// unbonding. - fn on_stake_update(_who: &AccountId, _prev_stake: Option>) {} + fn on_stake_update( + _who: &AccountId, + _prev_stake: Option>, + _stake: Stake, + ) { + } /// Fired when someone sets their intention to nominate. /// /// This should never be fired for existing nominators. - fn on_nominator_add(_who: &AccountId) {} + fn on_nominator_add(_who: &AccountId, _nominations: Vec) {} /// Fired when an existing nominator updates their nominations. /// /// Note that this is not fired when a nominator changes their stake. For that, /// `on_stake_update` should be used, followed by querying whether `who` was a validator or a /// nominator. - fn on_nominator_update(_who: &AccountId, _prev_nominations: Vec) {} + fn on_nominator_update( + _who: &AccountId, + _prev_nominations: Vec, + _nominations: Vec, + ) { + } + + /// Fired when an existng nominator becomes idle. + /// + /// An idle nominator stops nominating but its stake state should not be removed. + fn on_nominator_idle(_who: &AccountId, _prev_nominations: Vec) {} /// Fired when someone removes their intention to nominate, either due to chill or validating. /// @@ -126,16 +153,24 @@ pub trait OnStakingUpdate { /// Fired when someone sets their intention to validate. /// /// Note validator preference changes are not communicated, but could be added if needed. - fn on_validator_add(_who: &AccountId) {} + fn on_validator_add(_who: &AccountId, _self_stake: Stake) {} /// Fired when an existing validator updates their preferences. /// /// Note validator preference changes are not communicated, but could be added if needed. - fn on_validator_update(_who: &AccountId) {} + fn on_validator_update(_who: &AccountId, _self_stake: Option>) {} + + /// Fired when an existing validator becomes idle. + /// + /// An idle validator stops validating but its stake state should not be removed. + fn on_validator_idle(_who: &AccountId) {} /// Fired when someone removes their intention to validate, either due to chill or nominating. fn on_validator_remove(_who: &AccountId) {} + /// Fired when a portion of a staker's balance has been withdrawn. + fn on_withdraw(_stash: &AccountId, _amount: Balance) {} + /// Fired when someone is fully unstaked. fn on_unstake(_who: &AccountId) {} @@ -153,9 +188,65 @@ pub trait OnStakingUpdate { _slashed_total: Balance, ) { } +} - /// Fired when a portion of a staker's balance has been withdrawn. - fn on_withdraw(_stash: &AccountId, _amount: Balance) {} +/// Representation of the `OnStakingUpdate` events. +/// +/// Represents the events that may be emitted by the `OnStakingUpdate` trait, maps 1-1 to the +/// trait's method signatures. +/// +/// Only used for testing in external crates. +#[cfg(feature = "test-utils")] +#[derive(PartialEq, Clone, Debug)] +pub enum OnStakingUpdateEvent { + StakeUpdate { + who: AccountId, + prev_stake: Option>, + stake: Stake, + }, + NominatorAdd { + who: AccountId, + nominations: Vec, + }, + NominatorUpdate { + who: AccountId, + prev_nominations: Vec, + nominations: Vec, + }, + NominatorIdle { + who: AccountId, + prev_nominations: Vec, + }, + NominatorRemove { + who: AccountId, + nominations: Vec, + }, + ValidatorAdd { + who: AccountId, + self_stake: Stake, + }, + ValidatorUpdate { + who: AccountId, + self_stake: Option>, + }, + ValidatorIdle { + who: AccountId, + }, + ValidatorRemove { + who: AccountId, + }, + Withdraw { + who: AccountId, + amount: Balance, + }, + Unstake { + who: AccountId, + }, + Slash { + who: AccountId, + slashed_active: Balance, + slashed_total: Balance, + }, } /// A generic representation of a staking implementation. @@ -172,6 +263,7 @@ pub trait StakingInterface { + MaxEncodedLen + FullCodec + TypeInfo + + Zero + Saturating; /// AccountId type used by the staking system. diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 8d85e26d8fe7..e96371b1822b 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -141,6 +141,7 @@ std = [ "pallet-session?/std", "pallet-skip-feeless-payment?/std", "pallet-society?/std", + "pallet-stake-tracker?/std", "pallet-staking-reward-fn?/std", "pallet-staking-runtime-api?/std", "pallet-staking?/std", @@ -324,6 +325,7 @@ runtime-benchmarks = [ "pallet-session-benchmarking?/runtime-benchmarks", "pallet-skip-feeless-payment?/runtime-benchmarks", "pallet-society?/runtime-benchmarks", + "pallet-stake-tracker?/runtime-benchmarks", "pallet-staking?/runtime-benchmarks", "pallet-state-trie-migration?/runtime-benchmarks", "pallet-sudo?/runtime-benchmarks", @@ -454,6 +456,7 @@ try-runtime = [ "pallet-session?/try-runtime", "pallet-skip-feeless-payment?/try-runtime", "pallet-society?/try-runtime", + "pallet-stake-tracker?/try-runtime", "pallet-staking?/try-runtime", "pallet-state-trie-migration?/try-runtime", "pallet-statement?/try-runtime", @@ -675,6 +678,7 @@ runtime = [ "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", + "pallet-stake-tracker", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", @@ -1463,6 +1467,11 @@ path = "../substrate/frame/society" default-features = false optional = true +[dependencies.pallet-stake-tracker] +path = "../substrate/frame/staking/stake-tracker" +default-features = false +optional = true + [dependencies.pallet-staking] path = "../substrate/frame/staking" default-features = false diff --git a/umbrella/src/lib.rs b/umbrella/src/lib.rs index 58a5691961d9..6364cb3d0622 100644 --- a/umbrella/src/lib.rs +++ b/umbrella/src/lib.rs @@ -661,6 +661,10 @@ pub use pallet_skip_feeless_payment; #[cfg(feature = "pallet-society")] pub use pallet_society; +/// FRAME stake tracker pallet. +#[cfg(feature = "pallet-stake-tracker")] +pub use pallet_stake_tracker; + /// FRAME pallet staking. #[cfg(feature = "pallet-staking")] pub use pallet_staking;