diff --git a/Cargo.lock b/Cargo.lock index f38e66034..2628af084 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,11 +23,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ - "gimli 0.27.2", + "gimli 0.27.3", ] [[package]] @@ -90,9 +90,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", "cipher 0.4.4", @@ -115,12 +115,12 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" dependencies = [ "aead 0.5.2", - "aes 0.8.2", + "aes 0.8.3", "cipher 0.4.4", "ctr 0.9.2", "ghash 0.5.0", @@ -153,7 +153,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.9", + "getrandom 0.2.10", "once_cell", "version_check", ] @@ -165,7 +165,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", - "getrandom 0.2.9", + "getrandom 0.2.10", "once_cell", "version_check", ] @@ -181,13 +181,19 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -223,15 +229,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -296,9 +302,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "asn1-rs" @@ -313,7 +319,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.20", + "time 0.3.22", ] [[package]] @@ -329,7 +335,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.20", + "time 0.3.22", ] [[package]] @@ -387,9 +393,9 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.18", + "rustix 0.37.22", "slab", - "socket2", + "socket2 0.4.9", "waker-fn", ] @@ -410,7 +416,7 @@ checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", ] [[package]] @@ -421,18 +427,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -445,17 +451,14 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", ] [[package]] name = "atomic" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg 1.1.0", -] +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" [[package]] name = "atomic-waker" @@ -503,16 +506,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ - "addr2line 0.19.0", + "addr2line 0.20.0", "cc", "cfg-if", "libc", - "miniz_oxide 0.6.2", - "object 0.30.3", + "miniz_oxide", + "object 0.31.1", "rustc-demangle", ] @@ -542,9 +545,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "base64ct" @@ -601,6 +604,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + [[package]] name = "bitvec" version = "1.0.1" @@ -619,7 +628,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -629,7 +638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "constant_time_eq", ] @@ -640,18 +649,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "constant_time_eq", ] [[package]] name = "blake3" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "cc", "cfg-if", "constant_time_eq", @@ -715,9 +724,9 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "bounded-collections" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3888522b497857eb606bf51695988dba7096941822c1bcf676e3a929a9ae7a0" +checksum = "eb5b05133427c07c4776906f673ccf36c21b102c9829c641a5b56bd151d44fd6" dependencies = [ "log", "parity-scale-codec", @@ -733,9 +742,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" +checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5" dependencies = [ "memchr", "serde", @@ -766,9 +775,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "byte-slice-cast" @@ -924,13 +933,13 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "time 0.1.45", "wasm-bindgen", @@ -993,16 +1002,16 @@ version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "textwrap 0.11.0", "unicode-width", ] [[package]] name = "clap" -version = "4.2.7" +version = "4.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a" dependencies = [ "clap_builder", "clap_derive", @@ -1011,34 +1020,33 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.7" +version = "4.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +checksum = "ef137bbe35aab78bdb468ccfba75a5f4d8321ae011d34063770780545176af2d" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "cloudabi" @@ -1046,7 +1054,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1067,9 +1075,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "comfy-table" -version = "6.1.4" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7b787b0dc42e8111badfdbe4c3059158ccb2db8780352fa1b01e8ccf45cc4d" +checksum = "7e959d788268e3bf9d35ace83e81b124190378e4c91c9067524675e33394b8ba" dependencies = [ "strum 0.24.1", "strum_macros 0.24.3", @@ -1098,15 +1106,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" [[package]] name = "constant_time_eq" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" [[package]] name = "convert_case" @@ -1150,9 +1158,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] @@ -1172,7 +1180,7 @@ version = "0.93.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "253531aca9b6f56103c9420369db3263e784df39aa1c90685a1f69cfbba0623e" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", @@ -1303,22 +1311,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg 1.1.0", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -1488,9 +1496,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.94" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +checksum = "e88abab2f5abbe4c56e8f1fb431b784d710b709888f35755a160e62e33fe38e8" dependencies = [ "cc", "cxxbridge-flags", @@ -1500,9 +1508,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.94" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +checksum = "5c0c11acd0e63bae27dcd2afced407063312771212b7a823b4fd72d633be30fb" dependencies = [ "cc", "codespan-reporting", @@ -1510,24 +1518,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] name = "cxxbridge-flags" -version = "1.0.94" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" +checksum = "8d3816ed957c008ccd4728485511e3d9aaf7db419aa321e3d2c5a2f3411e36c8" [[package]] name = "cxxbridge-macro" -version = "1.0.94" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -1567,15 +1575,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "data-encoding-macro" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" +checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -1583,9 +1591,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" +checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" dependencies = [ "data-encoding", "syn 1.0.109", @@ -1722,9 +1730,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", @@ -1774,13 +1782,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", ] [[package]] @@ -1876,7 +1884,7 @@ dependencies = [ "sp-runtime", "tokio", "tokio-util", - "toml 0.7.3", + "toml 0.7.5", "uuid", ] @@ -1885,7 +1893,7 @@ name = "dkg-primitives" version = "0.0.1" dependencies = [ "chacha20poly1305", - "clap 4.2.7", + "clap 4.3.10", "curv-kzen", "dkg-runtime-primitives", "hex", @@ -1929,7 +1937,7 @@ dependencies = [ name = "dkg-standalone-node" version = "3.0.0" dependencies = [ - "clap 4.2.7", + "clap 4.3.10", "dkg-gadget", "dkg-logging", "dkg-primitives", @@ -2054,7 +2062,7 @@ dependencies = [ "sp-trie", "structopt", "tokio", - "toml 0.7.3", + "toml 0.7.5", "uuid", ] @@ -2072,9 +2080,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "dtoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65d09067bfacaa79114679b279d7f5885b53295b1e2cfb4e79c8e4bd3d633169" +checksum = "519b83cd10f5f6e969625a409f735182bea5558cd8b64c655806ceaae36f1999" [[package]] name = "dyn-clonable" @@ -2167,7 +2175,7 @@ dependencies = [ "base16ct", "crypto-bigint", "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array 0.14.7", "group", @@ -2209,7 +2217,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -2244,6 +2252,12 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "errno" version = "0.3.1" @@ -2292,7 +2306,7 @@ dependencies = [ "parity-scale-codec", "rlp", "scale-info", - "sha3 0.10.7", + "sha3 0.10.8", "triehash", ] @@ -2462,7 +2476,7 @@ checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "libz-sys", - "miniz_oxide 0.7.1", + "miniz_oxide", ] [[package]] @@ -2490,9 +2504,9 @@ dependencies = [ [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -2536,7 +2550,7 @@ dependencies = [ "Inflector", "array-bytes", "chrono", - "clap 4.2.7", + "clap 4.3.10", "comfy-table", "frame-benchmarking", "frame-support", @@ -2636,7 +2650,7 @@ name = "frame-support" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.39#8c4b84520cee2d7de53cc33cb67605ce4efefba8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "frame-metadata", "frame-support-procedural", "impl-trait-for-tuples", @@ -2824,7 +2838,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "waker-fn", ] @@ -2836,7 +2850,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -2881,7 +2895,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "pin-utils", "slab", ] @@ -2937,9 +2951,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -2963,7 +2977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" dependencies = [ "opaque-debug 0.3.0", - "polyval 0.6.0", + "polyval 0.6.1", ] [[package]] @@ -2973,15 +2987,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" dependencies = [ "fallible-iterator", - "indexmap", + "indexmap 1.9.3", "stable_deref_trait", ] [[package]] name = "gimli" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "globset" @@ -3009,9 +3023,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -3019,7 +3033,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -3028,9 +3042,9 @@ dependencies = [ [[package]] name = "handlebars" -version = "4.3.6" +version = "4.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035ef95d03713f2c347a72547b7cd38cbc9af7cd51e6099fb62d586d4a6dee3a" +checksum = "83c3372087601b532857d332f5957cbae686da52bb7810bf038c3e3c3cc2fa0d" dependencies = [ "log", "pest", @@ -3073,6 +3087,12 @@ dependencies = [ "ahash 0.8.3", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.3.3" @@ -3097,15 +3117,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.1" @@ -3162,7 +3173,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -3206,7 +3217,7 @@ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", ] [[package]] @@ -3245,9 +3256,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -3259,8 +3270,8 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.9", - "socket2", + "pin-project-lite 0.2.10", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -3284,9 +3295,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3298,12 +3309,11 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -3325,9 +3335,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -3411,6 +3421,16 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "inout" version = "0.1.3" @@ -3459,9 +3479,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", @@ -3476,31 +3496,30 @@ checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" [[package]] name = "ipconfig" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2", + "socket2 0.5.3", "widestring", - "winapi", + "windows-sys 0.48.0", "winreg", ] [[package]] name = "ipnet" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" dependencies = [ "hermit-abi 0.3.1", - "io-lifetimes", - "rustix 0.37.18", + "rustix 0.38.2", "windows-sys 0.48.0", ] @@ -3530,9 +3549,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "jobserver" @@ -3545,9 +3564,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -3572,7 +3591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" dependencies = [ "anyhow", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "async-trait", "beef", "futures-channel", @@ -3649,14 +3668,14 @@ dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "sha2 0.10.7", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -3699,9 +3718,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libm" @@ -3711,9 +3730,9 @@ checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" [[package]] name = "libm" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libp2p" @@ -3724,7 +3743,7 @@ dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.9", + "getrandom 0.2.10", "instant", "libp2p-core 0.38.0", "libp2p-dns", @@ -3775,7 +3794,7 @@ dependencies = [ "rand 0.8.5", "rw-stream-sink", "sec1", - "sha2 0.10.6", + "sha2 0.10.7", "smallvec", "thiserror", "unsigned-varint", @@ -3859,7 +3878,7 @@ dependencies = [ "multihash 0.17.0", "quick-protobuf", "rand 0.8.5", - "sha2 0.10.6", + "sha2 0.10.7", "thiserror", "zeroize", ] @@ -3870,7 +3889,7 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2766dcd2be8c87d5e1f35487deb22d765f49c6ae1251b3633efe3b25698bd3d2" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "asynchronous-codec", "bytes", "either", @@ -3884,7 +3903,7 @@ dependencies = [ "prost", "prost-build", "rand 0.8.5", - "sha2 0.10.6", + "sha2 0.10.7", "smallvec", "thiserror", "uint", @@ -3906,7 +3925,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2", + "socket2 0.4.9", "tokio", "trust-dns-proto", "void", @@ -3959,7 +3978,7 @@ dependencies = [ "prost", "prost-build", "rand 0.8.5", - "sha2 0.10.6", + "sha2 0.10.7", "snow", "static_assertions", "thiserror", @@ -4067,7 +4086,7 @@ dependencies = [ "libc", "libp2p-core 0.38.0", "log", - "socket2", + "socket2 0.4.9", "tokio", ] @@ -4229,9 +4248,9 @@ dependencies = [ [[package]] name = "link-cplusplus" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" dependencies = [ "cc", ] @@ -4268,15 +4287,21 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.3.6" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg 1.1.0", "scopeguard", @@ -4284,12 +4309,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "lru" @@ -4384,7 +4406,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -4399,7 +4421,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" dependencies = [ - "rustix 0.37.18", + "rustix 0.37.22", ] [[package]] @@ -4431,9 +4453,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg 1.1.0", ] @@ -4512,15 +4534,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -4532,14 +4545,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -4646,10 +4658,10 @@ dependencies = [ "blake2s_simd", "blake3", "core2", - "digest 0.10.6", + "digest 0.10.7", "multihash-derive", - "sha2 0.10.6", - "sha3 0.10.7", + "sha2 0.10.7", + "sha3 0.10.8", "unsigned-varint", ] @@ -4753,7 +4765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" dependencies = [ "anyhow", - "bitflags", + "bitflags 1.3.2", "byteorder", "libc", "netlink-packet-core", @@ -4806,7 +4818,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.6.5", @@ -4818,7 +4830,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", @@ -4895,7 +4907,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "itoa", ] @@ -4932,11 +4944,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.1", "libc", ] @@ -4948,15 +4960,15 @@ checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "crc32fast", "hashbrown 0.12.3", - "indexmap", + "indexmap 1.9.3", "memchr", ] [[package]] name = "object" -version = "0.30.3" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] @@ -4981,9 +4993,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -5023,7 +5035,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "sha2 0.10.7", ] [[package]] @@ -5034,7 +5046,7 @@ checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" dependencies = [ "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "sha2 0.10.7", ] [[package]] @@ -5603,9 +5615,9 @@ dependencies = [ [[package]] name = "parity-db" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd4572a52711e2ccff02b4973ec7e4a5b5c23387ebbfbd6cd42b34755714cefc" +checksum = "0dab3ac198341b2f0fec6e7f8a6eeed07a41201d98a124260611598c142e76df" dependencies = [ "blake2", "crc32fast", @@ -5623,11 +5635,11 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.4.0" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" +checksum = "756d439303e94fae44f288ba881ad29670c65b0c4b0e05674ca81061bb65f2c5" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "bitvec", "byte-slice-cast", "bytes", @@ -5638,9 +5650,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.4" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" +checksum = "9d884d78fcf214d70b1e239fcd1c6e5e95aa3be1881918da2e488cc946c7a476" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5684,7 +5696,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.7", + "parking_lot_core 0.9.8", ] [[package]] @@ -5703,18 +5715,18 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "backtrace", "cfg-if", "libc", "petgraph", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "smallvec", "thread-id", - "windows-sys 0.45.0", + "windows-targets 0.48.1", ] [[package]] @@ -5738,7 +5750,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -5761,15 +5773,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" +checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9" dependencies = [ "thiserror", "ucd-trie", @@ -5777,9 +5789,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" +checksum = "aef623c9bbfa0eedf5a0efba11a5ee83209c326653ca31ff019bec3a95bfff2b" dependencies = [ "pest", "pest_generator", @@ -5787,26 +5799,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" +checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] name = "pest_meta" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" +checksum = "a01f71cb40bd8bb94232df14b946909e14660e33fc05db3e50ae2a82d7ea0ca0" dependencies = [ "once_cell", "pest", - "sha2 0.10.6", + "sha2 0.10.7", ] [[package]] @@ -5816,27 +5828,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 1.9.3", ] [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", ] [[package]] @@ -5847,9 +5859,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -5947,12 +5959,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg 1.1.0", - "bitflags", + "bitflags 1.3.2", "cfg-if", "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "windows-sys 0.48.0", ] @@ -5981,14 +5993,14 @@ dependencies = [ [[package]] name = "polyval" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" dependencies = [ "cfg-if", "cpufeatures", "opaque-debug 0.3.0", - "universal-hash 0.5.0", + "universal-hash 0.5.1", ] [[package]] @@ -6087,9 +6099,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] @@ -6253,9 +6265,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -6382,7 +6394,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.9", + "getrandom 0.2.10", ] [[package]] @@ -6510,7 +6522,7 @@ checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", - "time 0.3.20", + "time 0.3.22", "x509-parser 0.13.2", "yasna", ] @@ -6523,7 +6535,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time 0.3.20", + "time 0.3.22", "yasna", ] @@ -6542,7 +6554,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -6551,7 +6563,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -6560,29 +6572,29 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.9", + "getrandom 0.2.10", "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43faa91b1c8b36841ee70e97188a869d37ae21759da6846d4be66de5bf7b12c" +checksum = "85d07b1a5f16b5548f4255a978c94259971aff73f39e8d67e8250e8b2f6667c3" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7" +checksum = "a930b010d9effee5834317bb7ff406b76af7724348fd572b38705b4bd099fa92" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -6599,13 +6611,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ - "aho-corasick 1.0.1", + "aho-corasick 1.0.2", "memchr", - "regex-syntax 0.7.1", + "regex-syntax 0.7.2", ] [[package]] @@ -6625,9 +6637,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "region" @@ -6635,7 +6647,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" dependencies = [ - "bitflags", + "bitflags 1.3.2", "libc", "mach", "winapi", @@ -6844,11 +6856,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.13" +version = "0.36.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a38f9520be93aba504e8ca974197f46158de5dcaa9fa04b57c57cd6a679d658" +checksum = "14e4d67015953998ad0eb82887a0eb0129e18a7e2f3b7b0f6c422fddcd503d62" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", @@ -6858,15 +6870,28 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.18" +version = "0.37.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" +checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys 0.3.6", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] @@ -6897,9 +6922,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -6909,11 +6934,11 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.0", + "base64 0.21.2", ] [[package]] @@ -6935,9 +6960,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "safe-mix" @@ -6950,9 +6975,9 @@ dependencies = [ [[package]] name = "safe_arch" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529" +checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f" dependencies = [ "bytemuck", ] @@ -7049,7 +7074,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.39#8c dependencies = [ "array-bytes", "chrono", - "clap 4.2.7", + "clap 4.3.10", "fdlimit", "futures", "libp2p", @@ -7270,7 +7295,7 @@ dependencies = [ "libc", "log", "once_cell", - "rustix 0.36.13", + "rustix 0.36.14", "sc-allocator", "sc-executor-common", "sp-runtime-interface", @@ -7416,7 +7441,7 @@ version = "0.10.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.39#8c4b84520cee2d7de53cc33cb67605ce4efefba8" dependencies = [ "async-trait", - "bitflags", + "bitflags 1.3.2", "bytes", "futures", "futures-timer", @@ -7781,7 +7806,7 @@ name = "sc-storage-monitor" version = "0.1.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.39#8c4b84520cee2d7de53cc33cb67605ce4efefba8" dependencies = [ - "clap 4.2.7", + "clap 4.3.10", "futures", "log", "nix 0.26.2", @@ -7929,9 +7954,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfdef77228a4c05dc94211441595746732131ad7f6530c6c18f045da7b7ab937" +checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" dependencies = [ "bitvec", "cfg-if", @@ -7943,9 +7968,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53012eae69e5aa5c14671942a5dd47de59d4cdcff8532a6dd0e081faf1119482" +checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7955,11 +7980,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -8122,11 +8147,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -8135,9 +8160,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -8178,31 +8203,31 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.160" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +checksum = "f3c5113243e4a3a1c96587342d067f3e6b0f50790b6cf40d2868eb647a3eef0e" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -8218,9 +8243,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" dependencies = [ "itoa", "ryu", @@ -8229,9 +8254,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -8257,7 +8282,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -8287,13 +8312,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -8310,11 +8335,11 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "keccak", ] @@ -8342,7 +8367,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -8376,9 +8401,9 @@ dependencies = [ [[package]] name = "slice-group-by" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" @@ -8411,7 +8436,7 @@ dependencies = [ "rand_core 0.6.4", "ring", "rustc_version 0.4.0", - "sha2 0.10.6", + "sha2 0.10.7", "subtle", ] @@ -8425,6 +8450,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "soketto" version = "0.7.1" @@ -8652,7 +8687,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.39#8c dependencies = [ "array-bytes", "base58", - "bitflags", + "bitflags 1.3.2", "blake2", "bounded-collections", "dyn-clonable", @@ -8695,9 +8730,9 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.39#8c dependencies = [ "blake2", "byteorder", - "digest 0.10.6", - "sha2 0.10.6", - "sha3 0.10.7", + "digest 0.10.7", + "sha2 0.10.7", + "sha3 0.10.8", "sp-std", "twox-hash", ] @@ -9166,9 +9201,9 @@ dependencies = [ [[package]] name = "ss58-registry" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47a8ad42e5fc72d5b1eb104a5546937eaf39843499948bb666d6e93c62423b" +checksum = "bfc443bad666016e012538782d9e3006213a7db43e9fb1dda91657dc06a6fa08" dependencies = [ "Inflector", "num-format", @@ -9197,7 +9232,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a2a1c578e98c1c16fc3b8ec1328f7659a500737d7a0c6d625e73e830ff9c1f6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg_aliases", "libc", "parking_lot 0.11.2", @@ -9524,9 +9559,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -9553,11 +9588,11 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75182f12f490e953596550b65ee31bda7c8e043d9386174b353bda50838c3fd" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] @@ -9580,21 +9615,22 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.7" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" +checksum = "1b1c7f239eb94671427157bd93b3694320f3668d4e1eff08c7285366fd777fac" [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg 1.1.0", "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.18", - "windows-sys 0.45.0", + "rustix 0.37.22", + "windows-sys 0.48.0", ] [[package]] @@ -9659,7 +9695,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -9670,9 +9706,9 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" [[package]] name = "thread-id" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fdfe0627923f7411a43ec9ec9c39c3a9b4151be313e0922042581fb6c9b717f" +checksum = "3ee93aa2b8331c0fec9091548843f2c90019571814057da3b783f9de09349d73" dependencies = [ "libc", "redox_syscall 0.2.16", @@ -9711,9 +9747,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "itoa", "serde", @@ -9723,15 +9759,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ "time-core", ] @@ -9748,7 +9784,7 @@ dependencies = [ "pbkdf2 0.11.0", "rand 0.8.5", "rustc-hash", - "sha2 0.10.6", + "sha2 0.10.7", "thiserror", "unicode-normalization", "wasm-bindgen", @@ -9791,19 +9827,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg 1.1.0", + "backtrace", "bytes", "libc", "mio", "num_cpus", "parking_lot 0.12.1", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "signal-hook-registry", - "socket2", + "socket2 0.4.9", "tokio-macros", "windows-sys 0.48.0", ] @@ -9816,7 +9853,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] @@ -9837,7 +9874,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tokio", "tokio-util", ] @@ -9852,7 +9889,7 @@ dependencies = [ "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tokio", "tracing", ] @@ -9868,9 +9905,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" dependencies = [ "serde", "serde_spanned", @@ -9880,20 +9917,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.8" +version = "0.19.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", @@ -9917,14 +9954,14 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytes", "futures-core", "futures-util", "http", "http-body", "http-range-header", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tower-layer", "tower-service", ] @@ -9949,27 +9986,27 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "log", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -10118,7 +10155,7 @@ dependencies = [ "lazy_static", "rand 0.8.5", "smallvec", - "socket2", + "socket2 0.4.9", "thiserror", "tinyvec", "tokio", @@ -10184,16 +10221,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", - "digest 0.10.6", + "digest 0.10.7", "rand 0.8.5", "static_assertions", ] [[package]] name = "typed-builder" -version = "0.10.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +checksum = "64cba322cb9b7bc6ca048de49e83918223f35e7a86311267013afff257004870" dependencies = [ "proc-macro2", "quote", @@ -10232,9 +10269,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-linebreak" @@ -10285,9 +10322,9 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", "subtle", @@ -10313,12 +10350,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", - "idna 0.3.0", + "idna 0.4.0", "percent-encoding", ] @@ -10330,11 +10367,11 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" dependencies = [ - "getrandom 0.2.9", + "getrandom 0.2.10", "serde", ] @@ -10389,11 +10426,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -10417,9 +10453,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -10427,24 +10463,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -10454,9 +10490,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10464,22 +10500,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-instrument" @@ -10573,7 +10609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57d20cb3c59b788653d99541c646c561c9dd26506f25c0cebfe810659c54c6d7" dependencies = [ "downcast-rs", - "libm 0.2.6", + "libm 0.2.7", "memory_units", "num-rational", "num-traits", @@ -10586,7 +10622,7 @@ version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64b20236ab624147dfbb62cf12a19aaf66af0e41b8398838b66e997d07d269d4" dependencies = [ - "indexmap", + "indexmap 1.9.3", "url", ] @@ -10599,7 +10635,7 @@ dependencies = [ "anyhow", "bincode", "cfg-if", - "indexmap", + "indexmap 1.9.3", "libc", "log", "object 0.29.0", @@ -10639,9 +10675,9 @@ dependencies = [ "directories-next", "file-per-thread-logger", "log", - "rustix 0.36.13", + "rustix 0.36.14", "serde", - "sha2 0.10.6", + "sha2 0.10.7", "toml 0.5.11", "windows-sys 0.42.0", "zstd", @@ -10677,7 +10713,7 @@ dependencies = [ "anyhow", "cranelift-entity", "gimli 0.26.2", - "indexmap", + "indexmap 1.9.3", "log", "object 0.29.0", "serde", @@ -10719,7 +10755,7 @@ checksum = "eed41cbcbf74ce3ff6f1d07d1b707888166dc408d1a880f651268f4f7c9194b2" dependencies = [ "object 0.29.0", "once_cell", - "rustix 0.36.13", + "rustix 0.36.14", ] [[package]] @@ -10742,7 +10778,7 @@ dependencies = [ "anyhow", "cc", "cfg-if", - "indexmap", + "indexmap 1.9.3", "libc", "log", "mach", @@ -10750,7 +10786,7 @@ dependencies = [ "memoffset 0.6.5", "paste", "rand 0.8.5", - "rustix 0.36.13", + "rustix 0.36.14", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", @@ -10771,9 +10807,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -10781,8 +10817,8 @@ dependencies = [ [[package]] name = "webb-proposals" -version = "0.5.22" -source = "git+https://github.com/webb-tools/webb-rs#ce757c52c404c4ebe1499712429ca858bff200f0" +version = "0.5.23" +source = "git+https://github.com/webb-tools/webb-rs#fab9cc6c627b34c7880841e62cc527495fe5ffc6" dependencies = [ "frame-support", "hex", @@ -10847,10 +10883,10 @@ dependencies = [ "sdp", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.7", "stun", "thiserror", - "time 0.3.20", + "time 0.3.22", "tokio", "turn", "url", @@ -10887,7 +10923,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942be5bd85f072c3128396f6e5a9bfb93ca8c1939ded735d177b7bcba9a13d05" dependencies = [ "aes 0.6.0", - "aes-gcm 0.10.1", + "aes-gcm 0.10.2", "async-trait", "bincode", "block-modes", @@ -10910,7 +10946,7 @@ dependencies = [ "sec1", "serde", "sha1", - "sha2 0.10.6", + "sha2 0.10.7", "signature", "subtle", "thiserror", @@ -10952,7 +10988,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" dependencies = [ "log", - "socket2", + "socket2 0.4.9", "thiserror", "tokio", "webrtc-util", @@ -11019,7 +11055,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" dependencies = [ "async-trait", - "bitflags", + "bitflags 1.3.2", "bytes", "cc", "ipnet", @@ -11046,9 +11082,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b689b6c49d6549434bf944e6b0f39238cf63693cb7a147e9d887507fffa3b223" +checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728" dependencies = [ "bytemuck", "safe_arch", @@ -11056,9 +11092,9 @@ dependencies = [ [[package]] name = "widestring" -version = "0.5.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" [[package]] name = "winapi" @@ -11110,7 +11146,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -11143,7 +11179,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -11163,9 +11199,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", @@ -11292,20 +11328,21 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] @@ -11355,7 +11392,7 @@ dependencies = [ "ring", "rusticata-macros", "thiserror", - "time 0.3.20", + "time 0.3.22", ] [[package]] @@ -11373,7 +11410,7 @@ dependencies = [ "oid-registry 0.6.1", "rusticata-macros", "thiserror", - "time 0.3.20", + "time 0.3.22", ] [[package]] @@ -11422,7 +11459,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.20", + "time 0.3.22", ] [[package]] @@ -11442,7 +11479,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.23", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 2a8b1e941..5ffbb14b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ 'dkg-mock-blockchain', 'dkg-test-orchestrator' ] +resolver = "2" [workspace.dependencies] # Local dependencies diff --git a/dkg-gadget/src/async_protocols/blockchain_interface.rs b/dkg-gadget/src/async_protocols/blockchain_interface.rs index dfa9ffff1..444fe13d4 100644 --- a/dkg-gadget/src/async_protocols/blockchain_interface.rs +++ b/dkg-gadget/src/async_protocols/blockchain_interface.rs @@ -220,7 +220,7 @@ where let mut lock = self.vote_results.write(); let proposals_for_this_batch = lock.entry(batch_key).or_default(); - if let Ok(Some(proposal)) = get_signed_proposal::( + if let Ok(Some(proposal)) = get_signed_proposal::( &self.backend, finished_round, payload_key, @@ -237,7 +237,7 @@ where metrics.dkg_signed_proposal_counter.inc_by(proposals.len() as u64); } - save_signed_proposals_in_storage::( + save_signed_proposals_in_storage::( &self.get_authority_public_key(), &self.current_validator_set, &self.latest_header, @@ -262,7 +262,7 @@ where fn gossip_public_key(&self, key: DKGPublicKeyMessage) -> Result<(), DKGError> { let public_key = key.pub_key.clone(); - gossip_public_key::( + gossip_public_key::( &self.keystore, self.gossip_engine.clone(), &mut self.aggregated_public_keys.write(), diff --git a/dkg-gadget/src/async_protocols/keygen/handler.rs b/dkg-gadget/src/async_protocols/keygen/handler.rs index afc3d54a6..7abe705c5 100644 --- a/dkg-gadget/src/async_protocols/keygen/handler.rs +++ b/dkg-gadget/src/async_protocols/keygen/handler.rs @@ -24,7 +24,8 @@ use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::key use std::fmt::Debug; -use dkg_primitives::types::{DKGError, DKGMsgStatus}; +use crate::async_protocols::remote::ShutdownReason; +use dkg_primitives::types::DKGError; use dkg_runtime_primitives::MaxAuthorities; use futures::FutureExt; @@ -36,7 +37,8 @@ where pub fn setup_keygen( params: AsyncProtocolParameters, threshold: u16, - status: DKGMsgStatus, + status: KeygenRound, + keygen_protocol_hash: [u8; 32], ) -> Result, DKGError> { let status_handle = params.handle.clone(); let mut stop_rx = @@ -65,7 +67,8 @@ where // Set status of the handle params.handle.set_status(MetaHandlerStatus::Keygen); // Execute the keygen - GenericAsyncHandler::new_keygen(params.clone(), t, n, status)?.await?; + GenericAsyncHandler::new_keygen(params.clone(), t, n, status, keygen_protocol_hash)? + .await?; params.logger.debug_keygen("Keygen stage complete!"); Ok(()) @@ -78,7 +81,7 @@ where logger0.info_keygen("🕸️ Keygen GenericAsyncHandler completed".to_string()); }, Err(ref err) => { - // Do not update the status here, evetually the Keygen will fail and timeout. + // Do not update the status here, eventually the Keygen will fail and timeout. logger0.error_keygen(format!("Keygen failed with error: {err:?}")); }, }; @@ -90,7 +93,15 @@ where res0 = protocol => res0, res1 = stop_rx.recv() => { logger1.info_keygen(format!("Stopper has been called {res1:?}")); - Ok(()) + if let Some(res1) = res1 { + if res1 == ShutdownReason::DropCode { + Ok(()) + } else { + Err(DKGError::GenericError { reason: "Keygen has stalled".into() }) + } + } else { + Ok(()) + } } } }); @@ -102,24 +113,27 @@ where params: AsyncProtocolParameters, t: u16, n: u16, - status: DKGMsgStatus, + ty: KeygenRound, + keygen_protocol_hash: [u8; 32], ) -> Result>::Return>, DKGError> { - let ty = match status { - DKGMsgStatus::ACTIVE => KeygenRound::ACTIVE, - DKGMsgStatus::QUEUED => KeygenRound::QUEUED, - }; let i = params.party_i; let associated_round_id = params.associated_block_id; let channel_type: ProtocolType<::MaxProposalLength> = - ProtocolType::Keygen { ty, i, t, n, associated_block_id: associated_round_id }; + ProtocolType::Keygen { + ty, + i, + t, + n, + associated_block_id: associated_round_id, + keygen_protocol_hash, + }; new_inner( (), Keygen::new(*i.as_ref(), t, n) .map_err(|err| Self::map_keygen_error_to_dkg_error_keygen(err))?, params, channel_type, - status, ) } diff --git a/dkg-gadget/src/async_protocols/mod.rs b/dkg-gadget/src/async_protocols/mod.rs index 399e2b8ac..d6c8ead3f 100644 --- a/dkg-gadget/src/async_protocols/mod.rs +++ b/dkg-gadget/src/async_protocols/mod.rs @@ -26,10 +26,7 @@ pub mod test_utils; use curv::elliptic::curves::Secp256k1; use dkg_primitives::{ crypto::Public, - types::{ - DKGError, DKGKeygenMessage, DKGMessage, DKGMsgPayload, DKGMsgStatus, DKGOfflineMessage, - SessionId, - }, + types::{DKGError, DKGKeygenMessage, DKGMessage, DKGMsgPayload, DKGOfflineMessage, SessionId}, AuthoritySet, }; use dkg_runtime_primitives::{MaxAuthorities, UnsignedProposal}; @@ -76,7 +73,6 @@ pub struct AsyncProtocolParameters< pub authority_public_key: Arc, pub party_i: KeygenPartyId, pub associated_block_id: u64, - pub retry_id: u16, pub batch_id_gen: Arc, pub handle: AsyncProtocolRemote, pub session_id: SessionId, @@ -145,7 +141,6 @@ impl< handle: self.handle.clone(), local_key: self.local_key.clone(), db: self.db.clone(), - retry_id: self.retry_id, logger: self.logger.clone(), } } @@ -274,14 +269,12 @@ impl OfflinePartyId { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum KeygenRound { - /// Keygen round is active - ACTIVE, - /// Keygen round is queued - QUEUED, - /// UNKNOWN - UNKNOWN, + /// Executed at the beginning of session 0 + Genesis, + /// Executed at the beginning of each session i > 0 + Next, } #[derive(Clone)] @@ -293,6 +286,7 @@ pub enum ProtocolType + Clone + Send + Sync + std::f t: u16, n: u16, associated_block_id: u64, + keygen_protocol_hash: [u8; 32], }, Offline { unsigned_proposal: Arc>, @@ -338,6 +332,14 @@ impl + Clone + Send + Sync + std::fmt::Debug + 'stat pub fn get_unsigned_proposal_hash(&self) -> Option<[u8; 32]> { self.get_unsigned_proposal().and_then(|x| x.hash()) } + + pub fn get_keygen_hash(&self) -> Option<[u8; 32]> { + if let Self::Keygen { keygen_protocol_hash, .. } = self { + Some(*keygen_protocol_hash) + } else { + None + } + } } impl + Clone + Send + Sync + std::fmt::Debug + 'static + Debug> Debug @@ -345,13 +347,20 @@ impl + Clone + Send + Sync + std::fmt::Debug + 'stat { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - ProtocolType::Keygen { ty, i, t, n, associated_block_id: associated_round_id } => { + ProtocolType::Keygen { + ty, + i, + t, + n, + associated_block_id: associated_round_id, + keygen_protocol_hash, + } => { let ty = match ty { - KeygenRound::ACTIVE => "ACTIVE", - KeygenRound::QUEUED => "QUEUED", - KeygenRound::UNKNOWN => "UNKNOWN", + KeygenRound::Genesis => "GENESIS", + KeygenRound::Next => "NEXT", }; - write!(f, "{ty} | Keygen: (i, t, n, r) = ({i}, {t}, {n}, {associated_round_id:?})") + let keygen_protocol_hash = hex::encode(keygen_protocol_hash); + write!(f, "{ty} | Keygen: (i, t, n, r) | hash: {keygen_protocol_hash} = ({i}, {t}, {n}, {associated_round_id:?})") }, ProtocolType::Offline { i, unsigned_proposal, .. } => { write!(f, "Offline: (i, proposal) = ({}, {:?})", i, &unsigned_proposal.proposal) @@ -391,7 +400,6 @@ pub fn new_inner + 'static, BI: BlockchainInterface sm: SM, params: AsyncProtocolParameters, channel_type: ProtocolType<::MaxProposalLength>, - status: DKGMsgStatus, ) -> Result, DKGError> where ::Err: Send + Debug, @@ -477,12 +485,8 @@ where // For taking all unsigned messages generated by the AsyncProtocols, signing them, // and thereafter sending them outbound - let outgoing_to_wire = generate_outgoing_to_wire_fn::( - params.clone(), - outgoing_rx, - channel_type.clone(), - status, - ); + let outgoing_to_wire = + generate_outgoing_to_wire_fn::(params.clone(), outgoing_rx, channel_type.clone()); // For taking raw inbound signed messages, mapping them to unsigned messages, then // sending to the appropriate AsyncProtocol @@ -526,7 +530,6 @@ fn generate_outgoing_to_wire_fn< params: AsyncProtocolParameters, outgoing_rx: UnboundedReceiver::MessageBody>>, proto_ty: ProtocolType<::MaxProposalLength>, - status: DKGMsgStatus, ) -> impl SendFuture<'static, ()> where ::MessageBody: Serialize + Send + MessageRoundID, @@ -536,6 +539,7 @@ where Box::pin(async move { let mut outgoing_rx = outgoing_rx.fuse(); let unsigned_proposal_hash = proto_ty.get_unsigned_proposal_hash(); + let keygen_protocol_hash = proto_ty.get_keygen_hash(); // take all unsigned messages, then sign them and send outbound loop { // Here is a few explanations about the next few lines: @@ -598,6 +602,7 @@ where ProtocolType::Keygen { .. } => DKGMsgPayload::Keygen(DKGKeygenMessage { sender_id: party_id, keygen_msg: serialized_body, + keygen_protocol_hash: keygen_protocol_hash.expect("This value should be set"), }), ProtocolType::Offline { unsigned_proposal, .. } => DKGMsgPayload::Offline(DKGOfflineMessage { @@ -622,10 +627,8 @@ where associated_block_id: params.associated_block_id, sender_id: id, recipient_id: maybe_recipient_id, - status, payload, session_id: params.session_id, - retry_id: params.retry_id, }; if let Err(err) = params.engine.sign_and_send_msg(unsigned_dkg_message) { params diff --git a/dkg-gadget/src/async_protocols/remote.rs b/dkg-gadget/src/async_protocols/remote.rs index deb74027e..5537456a7 100644 --- a/dkg-gadget/src/async_protocols/remote.rs +++ b/dkg-gadget/src/async_protocols/remote.rs @@ -29,15 +29,14 @@ pub struct AsyncProtocolRemote { pub(crate) rx_voting: MessageReceiverHandle, start_tx: Arc>>>, pub(crate) start_rx: Arc>>>, - stop_tx: Arc>>>, - pub(crate) stop_rx: Arc>>>, + stop_tx: Arc>>>, + pub(crate) stop_rx: Arc>>>, pub(crate) started_at: C, pub(crate) is_primary_remote: bool, current_round_blame: tokio::sync::watch::Receiver, pub(crate) current_round_blame_tx: Arc>, pub(crate) session_id: SessionId, pub(crate) associated_block_id: u64, - pub(crate) retry_id: u16, pub(crate) logger: DebugLogger, status_history: Arc>>, } @@ -65,7 +64,6 @@ impl Clone for AsyncProtocolRemote { logger: self.logger.clone(), status_history: self.status_history.clone(), associated_block_id: self.associated_block_id, - retry_id: self.retry_id, } } } @@ -80,6 +78,12 @@ pub enum MetaHandlerStatus { Terminated, } +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum ShutdownReason { + Stalled, + DropCode, +} + impl AsyncProtocolRemote { /// Create at the beginning of each meta handler instantiation pub fn new( @@ -87,7 +91,6 @@ impl AsyncProtocolRemote { session_id: SessionId, logger: DebugLogger, associated_block_id: u64, - retry_id: u16, ) -> Self { let (stop_tx, stop_rx) = tokio::sync::mpsc::unbounded_channel(); let (tx_keygen_signing, rx_keygen_signing) = tokio::sync::mpsc::unbounded_channel(); @@ -143,7 +146,6 @@ impl AsyncProtocolRemote { is_primary_remote: false, session_id, associated_block_id, - retry_id, } } @@ -228,11 +230,10 @@ impl AsyncProtocolRemote { self.tx_keygen_signing.send(msg) } } else { - // do not forward the message (TODO: Consider enqueuing messages for rounds not yet - // active other nodes may be active, but this node is still in the process of "waking - // up"). Thus, by not delivering a message here, we may be preventing this node from - // joining. - self.logger.warn(format!("Did not deliver message {:?}", msg.msg.payload)); + self.logger.warn(format!( + "Did not deliver message due to state {status:?} {:?}", + msg.msg.payload + )); Ok(()) } } @@ -248,7 +249,7 @@ impl AsyncProtocolRemote { } /// Stops the execution of the meta handler, including all internal asynchronous subroutines - pub fn shutdown>(&self, reason: R) -> Result<(), DKGError> { + pub fn shutdown(&self, reason: ShutdownReason) -> Result<(), DKGError> { // check the state if it is active so that we can send a shutdown signal. let tx = match self.stop_tx.lock().take() { Some(tx) => tx, @@ -260,8 +261,8 @@ impl AsyncProtocolRemote { return Ok(()) }, }; - self.logger.warn(format!("Shutting down meta handler: {}", reason.as_ref())); - tx.send(()).map_err(|_| DKGError::GenericError { + self.logger.warn(format!("Shutting down meta handler: {reason:?}")); + tx.send(reason).map_err(|_| DKGError::GenericError { reason: "Unable to send shutdown signal (already shut down?)".to_string(), }) } @@ -270,6 +271,10 @@ impl AsyncProtocolRemote { self.is_completed() } + pub fn has_started(&self) -> bool { + self.get_status() != MetaHandlerStatus::Beginning + } + pub fn is_signing_finished(&self) -> bool { self.is_completed() } @@ -309,7 +314,7 @@ impl Drop for AsyncProtocolRemote { } } - let _ = self.shutdown("drop code"); + let _ = self.shutdown(ShutdownReason::DropCode); } } } diff --git a/dkg-gadget/src/async_protocols/sign/handler.rs b/dkg-gadget/src/async_protocols/sign/handler.rs index 296eafc31..0814c6756 100644 --- a/dkg-gadget/src/async_protocols/sign/handler.rs +++ b/dkg-gadget/src/async_protocols/sign/handler.rs @@ -20,16 +20,20 @@ use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::{ sign::{CompletedOfflineStage, OfflineStage, PartialSignature, SignManual}, }; -use std::{collections::HashSet, fmt::Debug, sync::Arc, time::Duration}; +use std::{collections::HashSet, fmt::Debug, sync::Arc}; use crate::async_protocols::{ - blockchain_interface::BlockchainInterface, incoming::IncomingAsyncProtocolWrapper, new_inner, - remote::MetaHandlerStatus, state_machine::StateMachineHandler, AsyncProtocolParameters, - BatchKey, GenericAsyncHandler, KeygenPartyId, OfflinePartyId, ProtocolType, Threshold, + blockchain_interface::BlockchainInterface, + incoming::IncomingAsyncProtocolWrapper, + new_inner, + remote::{MetaHandlerStatus, ShutdownReason}, + state_machine::StateMachineHandler, + AsyncProtocolParameters, BatchKey, GenericAsyncHandler, KeygenPartyId, OfflinePartyId, + ProtocolType, Threshold, }; use dkg_logging::debug_logger::RoundsEventType; use dkg_primitives::types::{ - DKGError, DKGMessage, DKGMsgPayload, DKGMsgStatus, DKGVoteMessage, SignedDKGMessage, + DKGError, DKGMessage, DKGMsgPayload, DKGVoteMessage, SignedDKGMessage, }; use dkg_runtime_primitives::{crypto::Public, MaxAuthorities}; use futures::FutureExt; @@ -123,7 +127,15 @@ where res0 = protocol => res0, res1 = stop_rx.recv() => { logger2.info_signing(format!("Stopper has been called {res1:?}")); - Ok(()) + if let Some(res1) = res1 { + if res1 == ShutdownReason::DropCode { + Ok(()) + } else { + Err(DKGError::GenericError { reason: "Signing has stalled".into() }) + } + } else { + Ok(()) + } } } }); @@ -158,7 +170,6 @@ where .map_err(|err| DKGError::CriticalError { reason: err.to_string() })?, params, channel_type, - DKGMsgStatus::ACTIVE, ) } @@ -221,6 +232,7 @@ where unsigned_proposal_hash, }); + // TODO: Get latest pub key let id = params.authority_public_key.as_ref().clone(); // now, broadcast the data let unsigned_dkg_message = DKGMessage { @@ -228,19 +240,11 @@ where sender_id: id, // No recipient for this message, it is broadcasted recipient_id: None, - status: DKGMsgStatus::ACTIVE, payload, session_id: params.session_id, - retry_id: 0, }; - // we have no synchronization mechanism post-offline stage. Sometimes, messages - // don't get delivered. Thus, we sent multiple messages, and, wait for a while to let - // other nodes "show up" - for _ in 0..3 { - params.engine.sign_and_send_msg(unsigned_dkg_message.clone())?; - tokio::time::sleep(Duration::from_millis(100)).await; - } + params.engine.sign_and_send_msg(unsigned_dkg_message.clone())?; // we only need a threshold count of sigs let number_of_partial_sigs = threshold as usize; diff --git a/dkg-gadget/src/gossip_engine/network.rs b/dkg-gadget/src/gossip_engine/network.rs index 6a2bf69ae..e69db349c 100644 --- a/dkg-gadget/src/gossip_engine/network.rs +++ b/dkg-gadget/src/gossip_engine/network.rs @@ -531,8 +531,8 @@ impl GossipHandler { // Check behavior of the peer. let now = self.get_latest_block_number(); self.logger.debug(format!( - "{:?} session {:?} | Received a signed DKG messages from {} @ block {:?}, ", - message.msg.status, message.msg.session_id, who, now + "session {:?} | Received a signed DKG messages from {} @ block {:?}, ", + message.msg.session_id, who, now )); if let Some(metrics) = self.metrics.as_ref() { diff --git a/dkg-gadget/src/gossip_messages/misbehaviour_report.rs b/dkg-gadget/src/gossip_messages/misbehaviour_report.rs index a1d170a27..754a9607e 100644 --- a/dkg-gadget/src/gossip_messages/misbehaviour_report.rs +++ b/dkg-gadget/src/gossip_messages/misbehaviour_report.rs @@ -20,7 +20,7 @@ use crate::{ }; use codec::Encode; use dkg_primitives::types::{ - DKGError, DKGMessage, DKGMisbehaviourMessage, DKGMsgPayload, DKGMsgStatus, SignedDKGMessage, + DKGError, DKGMessage, DKGMisbehaviourMessage, DKGMsgPayload, SignedDKGMessage, }; use dkg_runtime_primitives::{ crypto::AuthorityId, AggregatedMisbehaviourReports, DKGApi, MaxAuthorities, MaxProposalLength, @@ -56,8 +56,8 @@ where dkg_worker.logger.debug("Received misbehaviour report".to_string()); let is_main_round = { - if let Some(round) = dkg_worker.rounds.read().as_ref() { - msg.session_id == round.session_id + if let Some(session_id) = dkg_worker.keygen_manager.get_latest_executed_session_id() { + msg.session_id == session_id } else { false } @@ -108,7 +108,7 @@ where reports.clone() }; - try_store_offchain(dkg_worker, &reports).await?; + let _ = try_store_offchain(dkg_worker, &reports).await?; } Ok(()) @@ -145,16 +145,12 @@ where ..report.clone() }); - let status = - if report.session_id == 0 { DKGMsgStatus::ACTIVE } else { DKGMsgStatus::QUEUED }; let message = DKGMessage:: { associated_block_id: 0, sender_id: public.clone(), // We need to gossip this misbehaviour, so no specific recipient. recipient_id: None, - status, session_id: report.session_id, - retry_id: 0, payload, }; let encoded_dkg_message = message.encode(); @@ -210,7 +206,7 @@ where }; // Try to store reports offchain - if try_store_offchain(dkg_worker, &reports).await.is_ok() { + if try_store_offchain(dkg_worker, &reports).await? { // remove the report from the queue dkg_worker.aggregated_misbehaviour_reports.write().remove(&( report.misbehaviour_type, @@ -228,7 +224,7 @@ where pub(crate) async fn try_store_offchain( dkg_worker: &DKGWorker, reports: &AggregatedMisbehaviourReports, -) -> Result<(), DKGError> +) -> Result where B: Block, BE: Backend + Unpin + 'static, @@ -246,16 +242,18 @@ where threshold, reports.reporters.len() )); + + let perform_store = reports.reporters.len() > threshold; match &reports.misbehaviour_type { MisbehaviourType::Keygen => - if reports.reporters.len() > threshold { + if perform_store { store_aggregated_misbehaviour_reports(dkg_worker, reports)?; }, MisbehaviourType::Sign => - if reports.reporters.len() >= threshold { + if perform_store { store_aggregated_misbehaviour_reports(dkg_worker, reports)?; }, - }; + } - Ok(()) + Ok(perform_store) } diff --git a/dkg-gadget/src/gossip_messages/public_key_gossip.rs b/dkg-gadget/src/gossip_messages/public_key_gossip.rs index 68a8aa51e..b3a5b4cd4 100644 --- a/dkg-gadget/src/gossip_messages/public_key_gossip.rs +++ b/dkg-gadget/src/gossip_messages/public_key_gossip.rs @@ -21,8 +21,7 @@ use crate::{ }; use codec::Encode; use dkg_primitives::types::{ - DKGError, DKGMessage, DKGMsgPayload, DKGMsgStatus, DKGPublicKeyMessage, SessionId, - SignedDKGMessage, + DKGError, DKGMessage, DKGMsgPayload, DKGPublicKeyMessage, SessionId, SignedDKGMessage, }; use dkg_runtime_primitives::{ crypto::{AuthorityId, Public}, @@ -55,13 +54,17 @@ where } if let DKGMsgPayload::PublicKeyBroadcast(msg) = dkg_msg.payload { + let is_genesis_round = msg.session_id == 0; + + let tag = if is_genesis_round { "CURRENT" } else { "NEXT" }; + dkg_worker .logger - .debug(format!("SESSION {} | Received public key broadcast", msg.session_id)); + .debug(format!("SESSION {}={tag} | Received public key broadcast", msg.session_id)); let is_main_round = { - if let Some(rounds) = dkg_worker.rounds.read().as_ref() { - msg.session_id == rounds.session_id + if let Some(session_id) = dkg_worker.keygen_manager.get_latest_executed_session_id() { + msg.session_id == session_id } else { false } @@ -80,9 +83,8 @@ where let key_and_sig = (msg.pub_key, msg.signature); let session_id = msg.session_id; - // Fetch the current threshold for the DKG. We will use the - // current threshold to determine if we have enough signatures - // to submit the next DKG public key. + // Whether this generated key was for genesis or next, we always use the next since + // the threshold is the same for both. let threshold = dkg_worker.get_next_signature_threshold(header).await as usize; let mut lock = dkg_worker.aggregated_public_keys.write(); @@ -93,24 +95,25 @@ where } dkg_worker.logger.debug(format!( - "SESSION {} | Threshold {} | Aggregated pubkeys {}", + "SESSION {}={tag} | Threshold {} | Aggregated pubkeys {} | is_main_round {}", msg.session_id, threshold, - aggregated_public_keys.keys_and_signatures.len() + aggregated_public_keys.keys_and_signatures.len(), + is_main_round )); if aggregated_public_keys.keys_and_signatures.len() > threshold { - store_aggregated_public_keys::( + store_aggregated_public_keys::( &dkg_worker.backend, &mut lock, - is_main_round, + is_genesis_round, session_id, current_block_number, &dkg_worker.logger, )?; } else { dkg_worker.logger.debug(format!( - "SESSION {} | Need more signatures to submit next DKG public key, needs {} more", + "SESSION {}={tag} | Need more signatures to submit next DKG public key, needs {} more", msg.session_id, (threshold + 1) - aggregated_public_keys.keys_and_signatures.len() )); @@ -120,25 +123,15 @@ where Ok(()) } -pub(crate) fn gossip_public_key( +pub(crate) fn gossip_public_key( key_store: &DKGKeystore, gossip_engine: Arc, aggregated_public_keys: &mut HashMap, msg: DKGPublicKeyMessage, ) where - B: Block, - BE: Backend, GE: GossipEngineIface, - C: Client, MaxProposalLength: Get + Clone + Send + Sync + 'static + std::fmt::Debug, MaxAuthorities: Get + Clone + Send + Sync + 'static + std::fmt::Debug, - C::Api: DKGApi< - B, - AuthorityId, - <::Header as Header>::Number, - MaxProposalLength, - MaxAuthorities, - >, { let public = key_store.get_authority_public_key(); @@ -149,17 +142,13 @@ pub(crate) fn gossip_public_key( ..msg.clone() }); - let status = - if msg.session_id == 0u64 { DKGMsgStatus::ACTIVE } else { DKGMsgStatus::QUEUED }; let message = DKGMessage:: { associated_block_id: 0, // we don't need to associate this message with a block sender_id: public.clone(), // we need to gossip the final public key to all parties, so no specific recipient in // this case. recipient_id: None, - status, session_id: msg.session_id, - retry_id: 0, payload, }; let encoded_dkg_message = message.encode(); diff --git a/dkg-gadget/src/keygen_manager/mod.rs b/dkg-gadget/src/keygen_manager/mod.rs new file mode 100644 index 000000000..d35fb8efd --- /dev/null +++ b/dkg-gadget/src/keygen_manager/mod.rs @@ -0,0 +1,495 @@ +#![allow(clippy::needless_return)] + +use crate::{ + async_protocols::{remote::AsyncProtocolRemote, KeygenPartyId, KeygenRound}, + gossip_engine::GossipEngineIface, + signing_manager::work_manager::{JobMetadata, PollMethod, WorkManager}, + utils::SendFuture, + worker::{ + AnticipatedKeygenExecutionStatus, DKGWorker, HasLatestHeader, KeystoreExt, ProtoStageType, + }, + Client, +}; +use atomic::Atomic; +use dkg_logging::debug_logger::DebugLogger; +use dkg_primitives::types::{DKGError, SignedDKGMessage}; +use dkg_runtime_primitives::{ + crypto::{AuthorityId, Public}, + keccak_256, DKGApi, MaxAuthorities, MaxProposalLength, SessionId, GENESIS_AUTHORITY_SET_ID, +}; +use sc_client_api::Backend; +use sp_arithmetic::traits::SaturatedConversion; +use sp_runtime::traits::{Block, Header, NumberFor}; +use std::{ + marker::PhantomData, + pin::Pin, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, +}; + +/// The KeygenManager is an abstraction that manages the lifecycle for executing and maintaining +/// keygen protocols. Code for this use to previously live in the DKGWorker, but has now been moved +/// here for readability and maintainability. +pub struct KeygenManager { + // governs the workload for each node + work_manager: WorkManager, + active_keygen_retry_id: Arc, + keygen_state: Arc>, + latest_executed_session_id: Arc>>, + pub finished_count: Arc, + _pd: PhantomData<(B, BE, C, GE)>, +} + +impl Clone for KeygenManager { + fn clone(&self) -> Self { + Self { + work_manager: self.work_manager.clone(), + _pd: self._pd, + active_keygen_retry_id: self.active_keygen_retry_id.clone(), + keygen_state: self.keygen_state.clone(), + latest_executed_session_id: self.latest_executed_session_id.clone(), + finished_count: self.finished_count.clone(), + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +/// State of the KeygenManager +pub enum KeygenState { + Uninitialized, + RunningKeygen, + RunningGenesisKeygen, + // session_completed denotes the session that executed the keygen, NOT + // the generated DKG public key for the next session + KeygenCompleted { session_completed: u64 }, + Failed { session_id: u64 }, +} + +/// only 1 task at a time may run for keygen +const MAX_RUNNING_TASKS: usize = 1; + +impl KeygenManager +where + B: Block, + BE: Backend + Unpin + 'static, + GE: GossipEngineIface + 'static, + C: Client + 'static, + C::Api: DKGApi, MaxProposalLength, MaxAuthorities>, +{ + pub fn new(logger: DebugLogger, clock: impl HasLatestHeader) -> Self { + Self { + work_manager: WorkManager::::new( + logger, + clock, + MAX_RUNNING_TASKS, + PollMethod::Manual, + ), + active_keygen_retry_id: Arc::new(AtomicUsize::new(0)), + keygen_state: Arc::new(Atomic::new(KeygenState::Uninitialized)), + latest_executed_session_id: Arc::new(Atomic::new(None)), + finished_count: Arc::new(AtomicUsize::new(0)), + _pd: Default::default(), + } + } + + pub fn deliver_message(&self, message: SignedDKGMessage) { + let message_task_hash = + *message.msg.payload.keygen_protocol_hash().expect("Bad message type"); + self.work_manager.deliver_message(message, message_task_hash) + } + + pub fn session_id_of_active_keygen(&self, now: NumberFor) -> Option { + self.work_manager.get_active_sessions_metadata(now).pop() + } + + pub fn get_latest_executed_session_id(&self) -> Option { + self.latest_executed_session_id.load(Ordering::SeqCst) + } + + fn state(&self) -> KeygenState { + self.keygen_state.load(Ordering::SeqCst) + } + + pub fn set_state(&self, state: KeygenState) { + self.keygen_state.store(state, Ordering::SeqCst); + } + + /// GENERAL WORKFLOW for Keygen + /// + /// Session 0 (beginning): immediately run genesis + /// Session 0 (ending): run keygen for session 1 + /// Session 1 (ending): run keygen for session 2 + /// Session 2 (ending): run keygen for session 3 + /// Session 3 (ending): run keygen for session 4 + #[allow(clippy::needless_return)] + pub async fn on_block_finalized( + &self, + header: &B::Header, + dkg_worker: &DKGWorker, + ) { + if let Some((active, _queued)) = dkg_worker.validator_set(header).await { + // Poll to clear any tasks that have finished and to make room for a new potential + // keygen + self.work_manager.poll(); + let now_n = *header.number(); + let block_id: u64 = now_n.saturated_into(); + let session_id = active.id; + let current_protocol = self.session_id_of_active_keygen(now_n); + let state = self.state(); + let anticipated_execution_status = dkg_worker.should_execute_new_keygen(header).await; + let executed_count = self.finished_count.load(Ordering::SeqCst); + + dkg_worker.logger.debug(format!( + "*** KeygenManager on_block_finalized: session={session_id},block={block_id}, state={state:?}, current_protocol={current_protocol:?} | total executed: {executed_count}", + )); + dkg_worker + .logger + .debug(format!("*** Should execute new keygen? {anticipated_execution_status:?}")); + + // Always perform pre-checks + if self + .pre_checks( + session_id, + state, + header, + dkg_worker, + ¤t_protocol, + &anticipated_execution_status, + ) + .await + { + return + } + + if session_id == GENESIS_AUTHORITY_SET_ID { + self.genesis_checks(state, header, dkg_worker, &anticipated_execution_status) + .await; + } else { + self.next_checks( + session_id, + state, + header, + dkg_worker, + &anticipated_execution_status, + ) + .await; + } + } + } + + /// Check to see if a genesis keygen failed, or, if we are already running a non-stalled + /// protocol + async fn pre_checks( + &self, + session_id: u64, + state: KeygenState, + header: &B::Header, + dkg_worker: &DKGWorker, + current_protocol: &Option, + anticipated_execution: &AnticipatedKeygenExecutionStatus, + ) -> bool { + if anticipated_execution.force_execute { + // Unconditionally execute another keygen, overwriting the previous one if necessary + let stage = if session_id == GENESIS_AUTHORITY_SET_ID && + self.finished_count.load(Ordering::SeqCst) == 0 + { + KeygenRound::Genesis + } else { + KeygenRound::Next + }; + + self.maybe_start_keygen_for_stage(stage, header, dkg_worker, anticipated_execution) + .await; + + return true + } + + // It's possible genesis failed and we need to retry + if session_id == GENESIS_AUTHORITY_SET_ID && + matches!(state, KeygenState::Failed { session_id: 0 }) && + dkg_worker.dkg_pub_key_is_unset(header).await + { + dkg_worker + .logger + .warn("We will trigger another genesis keygen because the previous one failed"); + self.maybe_start_keygen_for_stage( + KeygenRound::Genesis, + header, + dkg_worker, + anticipated_execution, + ) + .await; + return true + } + + // If a keygen is already running (and isn't stalled), don't start another one + if let Some(current_protocol) = current_protocol.as_ref() { + if current_protocol.is_active && !current_protocol.is_stalled { + dkg_worker.logger.info("Will not trigger a keygen since one is already running"); + return true + } + } + + false + } + + /// Check to see if we need to run a genesis keygen (session = 0), or, a keygen for session 1 + async fn genesis_checks( + &self, + state: KeygenState, + header: &B::Header, + dkg_worker: &DKGWorker, + anticipated_execution: &AnticipatedKeygenExecutionStatus, + ) { + if state == KeygenState::Uninitialized { + // If we are at genesis, and there is no active keygen, create and immediately + // start() one + return self + .maybe_start_keygen_for_stage( + KeygenRound::Genesis, + header, + dkg_worker, + anticipated_execution, + ) + .await + } + + if state == KeygenState::RunningGenesisKeygen { + // If we are at genesis, and a genesis keygen is running, do nothing + return + } + + if state == KeygenState::RunningKeygen { + // If we are at genesis, and there is a next keygen running, do nothing + return + } + + if matches!(state, KeygenState::KeygenCompleted { session_completed: 0 }) { + // If we are at genesis, and we have completed keygen, we may need to begin a keygen + // for session 1 + return self + .maybe_start_keygen_for_stage( + KeygenRound::Next, + header, + dkg_worker, + anticipated_execution, + ) + .await + } + } + + /// Check to see if we need to run a keygen for session 2, 3, 4, .., etc. + async fn next_checks( + &self, + session_id: u64, + state: KeygenState, + header: &B::Header, + dkg_worker: &DKGWorker, + anticipated_execution: &AnticipatedKeygenExecutionStatus, + ) { + // Check bad states. These should never happen in a well-behaved program + if state == KeygenState::RunningGenesisKeygen { + dkg_worker.logger.error(format!("Invalid keygen manager state: {session_id} > GENESIS_AUTHORITY_SET_ID && {state:?} == KeygenState::GenesisKeygenCompleted || {state:?} == KeygenState::RunningGenesisKeygen")); + return + } + + if state == KeygenState::Uninitialized { + // We joined the network after genesis. We need to start a keygen for session `now`, + // so long as the next pub key isn't already on chain + if dkg_worker.get_next_dkg_pub_key(header).await.is_none() { + self.maybe_start_keygen_for_stage( + KeygenRound::Next, + header, + dkg_worker, + anticipated_execution, + ) + .await; + return + } + } + + if state == KeygenState::RunningKeygen { + // We are in the middle of a keygen. Do nothing + return + } + + if matches!(state, KeygenState::KeygenCompleted { .. }) { + // We maybe need to start a keygen for session `session_id`: + return self + .maybe_start_keygen_for_stage( + KeygenRound::Next, + header, + dkg_worker, + anticipated_execution, + ) + .await + } + } + + async fn maybe_start_keygen_for_stage( + &self, + stage: KeygenRound, + header: &B::Header, + dkg_worker: &DKGWorker, + anticipated_execution_status: &AnticipatedKeygenExecutionStatus, + ) { + let authority_set = if let Some((active, queued)) = dkg_worker.validator_set(header).await { + match stage { + KeygenRound::Genesis => active, + KeygenRound::Next => queued, + } + } else { + return + }; + + let session_id = authority_set.id; + dkg_worker + .logger + .debug(format!("Will attempt to start keygen for session {session_id}")); + + if stage != KeygenRound::Genesis { + // We need to ensure session progress is close enough to the end to begin execution + if !anticipated_execution_status.execute && !anticipated_execution_status.force_execute + { + dkg_worker.logger.debug("🕸️ Not executing new keygen protocol"); + return + } + + if dkg_worker.get_next_dkg_pub_key(header).await.is_some() && + !anticipated_execution_status.force_execute + { + dkg_worker.logger.debug("🕸Not executing new keygen protocol because we already have a next DKG public key"); + return + } + + if self.finished_count.load(Ordering::SeqCst) != session_id as usize { + dkg_worker.logger.warn("We have already run this protocol, is this a re-try?"); + } + } else { + // if we are in genesis, make sure that the current public key isn't already on-chain + if !dkg_worker.dkg_pub_key_is_unset(header).await { + dkg_worker.logger.debug( + "🕸️ Not executing new keygen protocol because we already have a DKG public key", + ); + return + } + } + + let party_idx = match stage { + KeygenRound::Genesis => dkg_worker.get_party_index(header).await, + KeygenRound::Next => dkg_worker.get_next_party_index(header).await, + }; + + let threshold = match stage { + KeygenRound::Genesis => dkg_worker.get_signature_threshold(header).await, + KeygenRound::Next => dkg_worker.get_next_signature_threshold(header).await, + }; + + // Check whether the worker is in the best set or return + let party_i = match party_idx { + Some(party_index) => { + dkg_worker.logger.info(format!("🕸️ PARTY {party_index} | SESSION {session_id} | IN THE SET OF BEST AUTHORITIES: session: {session_id} | threshold: {threshold}")); + if let Ok(res) = KeygenPartyId::try_from(party_index) { + res + } else { + return + } + }, + None => { + dkg_worker + .logger + .info(format!("🕸️ NOT IN THE SET OF BEST AUTHORITIES: session: {session_id}")); + return + }, + }; + + let best_authorities = match stage { + KeygenRound::Genesis => dkg_worker.get_best_authorities(header).await, + KeygenRound::Next => dkg_worker.get_next_best_authorities(header).await, + }; + + let best_authorities = best_authorities + .into_iter() + .flat_map(|(i, p)| KeygenPartyId::try_from(i).map(|i| (i, p))) + .collect(); + + let authority_public_key = dkg_worker.get_authority_public_key(); + let proto_stage_ty = if stage == KeygenRound::Genesis { + ProtoStageType::KeygenGenesis + } else { + ProtoStageType::KeygenStandard + }; + + dkg_worker.logger.debug(format!("🕸️ PARTY {party_i} | SPAWNING KEYGEN SESSION {session_id} | BEST AUTHORITIES: {best_authorities:?}")); + + let keygen_protocol_hash = get_keygen_protocol_hash( + session_id, + self.active_keygen_retry_id.load(Ordering::SeqCst), + ); + + if let Some((handle, task)) = dkg_worker + .initialize_keygen_protocol( + best_authorities, + authority_public_key, + party_i, + session_id, + *header.number(), + threshold, + proto_stage_ty, + keygen_protocol_hash, + ) + .await + { + // Before sending the task, force clear all previous tasks to allow the new one + // the immediately run + if anticipated_execution_status.force_execute { + dkg_worker.logger.debug( + "🕸️ PARTY {party_i} | SPAWNING KEYGEN SESSION {session_id} | FORCE EXECUTE", + ); + self.work_manager.force_shutdown_all(); + } + + if let Err(err) = self.push_task(handle, task) { + dkg_worker.logger.error(format!( + "🕸️ PARTY {party_i} | SPAWNING KEYGEN SESSION {session_id} | ERROR: {err}" + )); + + dkg_worker.handle_dkg_error(err).await; + } else { + // update states + match stage { + KeygenRound::Genesis => self.set_state(KeygenState::RunningGenesisKeygen), + KeygenRound::Next => self.set_state(KeygenState::RunningKeygen), + } + + self.latest_executed_session_id.store(Some(session_id), Ordering::Relaxed); + } + } + } + + /// Pushes a task to the work manager, manually polling and starting the keygen protocol + pub fn push_task( + &self, + handle: AsyncProtocolRemote>, + task: Pin>>, + ) -> Result<(), DKGError> { + let task_hash = get_keygen_protocol_hash( + handle.session_id, + self.active_keygen_retry_id.load(Ordering::Relaxed), + ); + self.work_manager.push_task(task_hash, handle, task)?; + // poll to start the task + self.work_manager.poll(); + Ok(()) + } +} + +/// Computes keccak_256(session ID || retry_id) +fn get_keygen_protocol_hash(session_id: u64, active_keygen_retry_id: usize) -> [u8; 32] { + let mut session_id_bytes = session_id.to_be_bytes().to_vec(); + let retry_id_bytes = active_keygen_retry_id.to_be_bytes(); + session_id_bytes.extend_from_slice(&retry_id_bytes); + keccak_256(&session_id_bytes) +} diff --git a/dkg-gadget/src/keystore.rs b/dkg-gadget/src/keystore.rs index f7fb49e8b..ece9503b8 100644 --- a/dkg-gadget/src/keystore.rs +++ b/dkg-gadget/src/keystore.rs @@ -23,6 +23,7 @@ use dkg_runtime_primitives::{ crypto::{Public, Signature}, KEY_TYPE, }; +use itertools::Itertools; use sc_keystore::LocalKeystore; use std::sync::Arc; @@ -57,10 +58,11 @@ impl DKGKeystore { let store = self.0.clone()?; // we do check for multiple private keys as a key store sanity check. - let public: Vec = keys + let mut public: Vec = keys .iter() .filter(|k| SyncCryptoStore::has_keys(&*store, &[(k.to_raw_vec(), KEY_TYPE)])) .cloned() + .unique() .collect(); if public.len() > 1 { @@ -71,7 +73,7 @@ impl DKGKeystore { )); } - public.get(0).cloned() + public.pop() } /// Check if the keystore contains a private key for one of the sr25519 public keys diff --git a/dkg-gadget/src/lib.rs b/dkg-gadget/src/lib.rs index 92635b66d..ca2d98252 100644 --- a/dkg-gadget/src/lib.rs +++ b/dkg-gadget/src/lib.rs @@ -33,6 +33,7 @@ pub mod keyring; pub mod keystore; pub mod gossip_engine; +mod keygen_manager; mod signing_manager; // mod meta_async_rounds; pub mod db; diff --git a/dkg-gadget/src/proposal.rs b/dkg-gadget/src/proposal.rs index e894f24f0..f3830724e 100644 --- a/dkg-gadget/src/proposal.rs +++ b/dkg-gadget/src/proposal.rs @@ -13,21 +13,20 @@ use std::sync::Arc; // See the License for the specific language governing permissions and // limitations under the License. // -use crate::{debug_logger::DebugLogger, Client}; +use crate::debug_logger::DebugLogger; use codec::Encode; use dkg_primitives::types::{DKGError, DKGSignedPayload}; use dkg_runtime_primitives::{ - crypto::AuthorityId, offchain::storage_keys::OFFCHAIN_PUBLIC_KEY_SIG, DKGApi, DKGPayloadKey, - RefreshProposalSigned, + offchain::storage_keys::OFFCHAIN_PUBLIC_KEY_SIG, DKGPayloadKey, RefreshProposalSigned, }; use sc_client_api::Backend; use sp_api::offchain::STORAGE_PREFIX; use sp_core::offchain::OffchainStorage; -use sp_runtime::traits::{Block, Get, Header}; +use sp_runtime::traits::{Block, Get}; use webb_proposals::{Proposal, ProposalKind}; /// Get signed proposal -pub(crate) fn get_signed_proposal( +pub(crate) fn get_signed_proposal( backend: &Arc, finished_round: DKGSignedPayload, payload_key: DKGPayloadKey, @@ -36,16 +35,7 @@ pub(crate) fn get_signed_proposal( where B: Block, BE: Backend, - C: Client, MaxProposalLength: Get + Clone + Send + Sync + 'static + std::fmt::Debug, - MaxAuthorities: Get + Clone + Send + Sync + 'static + std::fmt::Debug, - C::Api: DKGApi< - B, - AuthorityId, - <::Header as Header>::Number, - MaxProposalLength, - MaxAuthorities, - >, { match payload_key { DKGPayloadKey::RefreshVote(nonce) => { diff --git a/dkg-gadget/src/signing_manager/mod.rs b/dkg-gadget/src/signing_manager/mod.rs index b0be2677a..7d85a6f7c 100644 --- a/dkg-gadget/src/signing_manager/mod.rs +++ b/dkg-gadget/src/signing_manager/mod.rs @@ -10,6 +10,7 @@ use crate::{ async_protocols::{remote::AsyncProtocolRemote, GenericAsyncHandler, KeygenPartyId}, gossip_engine::GossipEngineIface, metric_inc, + signing_manager::work_manager::PollMethod, utils::SendFuture, worker::{DKGWorker, HasLatestHeader, KeystoreExt, ProtoStageType}, *, @@ -18,7 +19,10 @@ use codec::Encode; use dkg_primitives::{utils::select_random_set, SessionId}; use dkg_runtime_primitives::crypto::Public; use sp_api::HeaderT; -use std::pin::Pin; +use std::{ + pin::Pin, + sync::atomic::{AtomicBool, Ordering}, +}; /// For balancing the amount of work done by each node pub mod work_manager; @@ -39,17 +43,20 @@ pub mod work_manager; pub struct SigningManager { // governs the workload for each node work_manager: WorkManager, + lock: Arc, _pd: PhantomData<(B, BE, C, GE)>, } impl Clone for SigningManager { fn clone(&self) -> Self { - Self { work_manager: self.work_manager.clone(), _pd: self._pd } + Self { work_manager: self.work_manager.clone(), _pd: self._pd, lock: self.lock.clone() } } } // the maximum number of tasks that the work manager tries to assign const MAX_RUNNING_TASKS: usize = 4; +// How often to poll the jobs to check completion status +const JOB_POLL_INTERVAL_IN_MILLISECONDS: u64 = 500; impl SigningManager where @@ -61,22 +68,52 @@ where { pub fn new(logger: DebugLogger, clock: impl HasLatestHeader) -> Self { Self { - work_manager: WorkManager::::new(logger, clock, MAX_RUNNING_TASKS), + work_manager: WorkManager::::new( + logger, + clock, + MAX_RUNNING_TASKS, + PollMethod::Interval { millis: JOB_POLL_INTERVAL_IN_MILLISECONDS }, + ), + lock: Arc::new(AtomicBool::new(false)), _pd: Default::default(), } } pub fn deliver_message(&self, message: SignedDKGMessage) { - self.work_manager.deliver_message(message) + let message_task_hash = + *message.msg.payload.unsigned_proposal_hash().expect("Bad message type"); + self.work_manager.deliver_message(message, message_task_hash) + } + + // prevents on_block_finalized from executing + pub fn keygen_lock(&self) { + self.lock.store(true, Ordering::SeqCst); + } + + // allows the on_block_finalized task to be executed + pub fn keygen_unlock(&self) { + self.lock.store(false, Ordering::SeqCst); } /// This function is called each time a new block is finalized. /// It will then start a signing process for each of the proposals. + #[allow(clippy::let_underscore_future)] pub async fn on_block_finalized( &self, header: &B::Header, dkg_worker: &DKGWorker, ) -> Result<(), DKGError> { + let header = &header; + let dkg_worker = &dkg_worker; + // if a keygen is running, don't start any new signing tasks + // until later + if self.lock.load(Ordering::SeqCst) { + dkg_worker + .logger + .debug("Will skip handling block finalized event because keygen is running"); + return Ok(()) + } + let on_chain_dkg = dkg_worker.get_dkg_pub_key(header).await; let session_id = on_chain_dkg.0; let dkg_pub_key = on_chain_dkg.1; @@ -84,7 +121,7 @@ where // Check whether the worker is in the best set or return let party_i = match dkg_worker.get_party_index(header).await { Some(party_index) => { - dkg_worker.logger.info(format!("🕸️ PARTY {party_index} | SESSION {session_id} | IN THE SET OF BEST AUTHORITIES")); + dkg_worker.logger.info(format!("🕸️ SIGNING PARTY {party_index} | SESSION {session_id} | IN THE SET OF BEST AUTHORITIES")); KeygenPartyId::try_from(party_index)? }, None => { @@ -156,7 +193,7 @@ where let concat_data = dkg_pub_key .clone() .into_iter() - .chain(at.encode()) + //.chain(at.encode()) .chain(unsigned_proposal_bytes) .collect::>(); let seed = sp_core::keccak_256(&concat_data); @@ -231,6 +268,7 @@ where associated_block_id: NumberFor, ) -> Result<(AsyncProtocolRemote>, Pin>>), DKGError> { + dkg_worker.logger.debug(format!("{party_i:?} All Parameters: {best_authorities:?} | authority_pub_key: {authority_public_key:?} | session_id: {session_id:?} | threshold: {threshold:?} | stage: {stage:?} | unsigned_proposal: {unsigned_proposal:?} | signing_set: {signing_set:?} | associated_block_id: {associated_block_id:?}")); let async_proto_params = dkg_worker.generate_async_proto_params( best_authorities, authority_public_key, diff --git a/dkg-gadget/src/signing_manager/work_manager.rs b/dkg-gadget/src/signing_manager/work_manager.rs index aa514564b..dfe790696 100644 --- a/dkg-gadget/src/signing_manager/work_manager.rs +++ b/dkg-gadget/src/signing_manager/work_manager.rs @@ -1,12 +1,15 @@ use crate::{ - async_protocols::remote::AsyncProtocolRemote, debug_logger::DebugLogger, utils::SendFuture, - worker::HasLatestHeader, NumberFor, + async_protocols::remote::{AsyncProtocolRemote, ShutdownReason}, + debug_logger::DebugLogger, + utils::SendFuture, + worker::HasLatestHeader, + NumberFor, }; use dkg_primitives::{ crypto::Public, types::{DKGError, SignedDKGMessage}, }; -use dkg_runtime_primitives::associated_block_id_acceptable; +use dkg_runtime_primitives::{associated_block_id_acceptable, SessionId}; use parking_lot::RwLock; use sp_api::BlockT; use std::{ @@ -17,8 +20,11 @@ use std::{ }; use sync_wrapper::SyncWrapper; -// How often to poll the jobs to check completion status -const JOB_POLL_INTERVAL_IN_MILLISECONDS: u64 = 500; +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum PollMethod { + Interval { millis: u64 }, + Manual, +} #[derive(Clone)] pub struct WorkManager { @@ -27,6 +33,7 @@ pub struct WorkManager { // for now, use a hard-coded value for the number of tasks max_tasks: usize, logger: DebugLogger, + poll_method: Arc, to_handler: tokio::sync::mpsc::UnboundedSender<[u8; 32]>, } @@ -36,8 +43,22 @@ pub struct WorkManagerInner { pub enqueued_messages: HashMap<[u8; 32], VecDeque>>, } +#[derive(Debug)] +pub struct JobMetadata { + pub session_id: SessionId, + pub is_stalled: bool, + pub is_finished: bool, + pub has_started: bool, + pub is_active: bool, +} + impl WorkManager { - pub fn new(logger: DebugLogger, clock: impl HasLatestHeader, max_tasks: usize) -> Self { + pub fn new( + logger: DebugLogger, + clock: impl HasLatestHeader, + max_tasks: usize, + poll_method: PollMethod, + ) -> Self { let (to_handler, mut rx) = tokio::sync::mpsc::unbounded_channel(); let this = Self { inner: Arc::new(RwLock::new(WorkManagerInner { @@ -49,43 +70,45 @@ impl WorkManager { max_tasks, logger, to_handler, + poll_method: Arc::new(poll_method), }; - let this_worker = this.clone(); - let handler = async move { - let job_receiver_worker = this_worker.clone(); - let logger = job_receiver_worker.logger.clone(); - - let job_receiver = async move { - while let Some(task_hash) = rx.recv().await { - job_receiver_worker - .logger - .info_signing(format!("[worker] Received job {task_hash:?}",)); - job_receiver_worker.poll(); - } - }; + if let PollMethod::Interval { millis } = poll_method { + let this_worker = this.clone(); + let handler = async move { + let job_receiver_worker = this_worker.clone(); + let logger = job_receiver_worker.logger.clone(); + + let job_receiver = async move { + while let Some(task_hash) = rx.recv().await { + job_receiver_worker + .logger + .info_signing(format!("[worker] Received job {task_hash:?}",)); + job_receiver_worker.poll(); + } + }; - let periodic_poller = async move { - let mut interval = tokio::time::interval(std::time::Duration::from_millis( - JOB_POLL_INTERVAL_IN_MILLISECONDS, - )); - loop { - interval.tick().await; - this_worker.poll(); - } - }; + let periodic_poller = async move { + let mut interval = + tokio::time::interval(std::time::Duration::from_millis(millis)); + loop { + interval.tick().await; + this_worker.poll(); + } + }; - tokio::select! { - _ = job_receiver => { - logger.error_signing("[worker] job_receiver exited"); - }, - _ = periodic_poller => { - logger.error_signing("[worker] periodic_poller exited"); + tokio::select! { + _ = job_receiver => { + logger.error_signing("[worker] job_receiver exited"); + }, + _ = periodic_poller => { + logger.error_signing("[worker] periodic_poller exited"); + } } - } - }; + }; - tokio::task::spawn(handler); + tokio::task::spawn(handler); + } this } @@ -108,12 +131,29 @@ impl WorkManager { }; lock.enqueued_tasks.push_back(job); - self.to_handler.send(task_hash).map_err(|_| DKGError::GenericError { - reason: "Failed to send job to worker".to_string(), - }) + if *self.poll_method != PollMethod::Manual { + self.to_handler.send(task_hash).map_err(|_| DKGError::GenericError { + reason: "Failed to send job to worker".to_string(), + }) + } else { + Ok(()) + } + } + + // Only relevant for keygen + pub fn get_active_sessions_metadata(&self, now: NumberFor) -> Vec { + self.inner.read().active_tasks.iter().map(|r| r.metadata(now)).collect() } - fn poll(&self) { + // This will shutdown and drop all tasks and enqueued messages + pub fn force_shutdown_all(&self) { + let mut lock = self.inner.write(); + lock.active_tasks.clear(); + lock.enqueued_tasks.clear(); + lock.enqueued_messages.clear(); + } + + pub fn poll(&self) { // go through each task and see if it's done // finally, see if we can start a new task let now = self.clock.get_latest_block_number(); @@ -131,18 +171,13 @@ impl WorkManager { )); // the task is stalled, lets be pedantic and shutdown - let _ = job.handle.shutdown("Stalled!"); + let _ = job.handle.shutdown(ShutdownReason::Stalled); // return false so that the proposals are released from the currently signing // proposals return false } let is_done = job.handle.is_done(); - /*self.logger.info_signing(format!( - "[worker] Job {:?} is done: {}", - hex::encode(job.task_hash), - is_done - ));*/ !is_done }); @@ -177,11 +212,15 @@ impl WorkManager { hex::encode(job.task_hash) )); while let Some(message) = enqueued_messages.pop_front() { - if let Err(err) = job.handle.deliver_message(message) { - self.logger.error_signing(format!( - "Unable to deliver message for job {:?}: {err:?}", - hex::encode(job.task_hash) - )); + if should_deliver(&job, &message, job.task_hash) { + if let Err(err) = job.handle.deliver_message(message) { + self.logger.error_signing(format!( + "Unable to deliver message for job {:?}: {err:?}", + hex::encode(job.task_hash) + )); + } + } else { + self.logger.warn("Will not deliver enqueued message to async protocol since the message is no longer acceptable") } } } @@ -207,24 +246,16 @@ impl WorkManager { lock.active_tasks.contains(job) || lock.enqueued_tasks.iter().any(|j| &j.task_hash == job) } - pub fn deliver_message(&self, msg: SignedDKGMessage) { + pub fn deliver_message(&self, msg: SignedDKGMessage, message_task_hash: [u8; 32]) { self.logger.debug_signing(format!( "Delivered message is intended for session_id = {}", msg.msg.session_id )); let mut lock = self.inner.write(); - let msg_unsigned_proposal_hash = - msg.msg.payload.unsigned_proposal_hash().expect("Bad message type"); - // check the enqueued for task in lock.enqueued_tasks.iter() { - if task.handle.session_id == msg.msg.session_id && - &task.task_hash == msg_unsigned_proposal_hash && - associated_block_id_acceptable( - task.handle.associated_block_id, - msg.msg.associated_block_id, - ) { + if should_deliver(task, &msg, message_task_hash) { self.logger.debug(format!( "Message is for this ENQUEUED signing execution in session: {}", task.handle.session_id @@ -239,12 +270,7 @@ impl WorkManager { // check the currently signing for task in lock.active_tasks.iter() { - if task.handle.session_id == msg.msg.session_id && - &task.task_hash == msg_unsigned_proposal_hash && - associated_block_id_acceptable( - task.handle.associated_block_id, - msg.msg.associated_block_id, - ) { + if should_deliver(task, &msg, message_task_hash) { self.logger.debug(format!( "Message is for this signing CURRENT execution in session: {}", task.handle.session_id @@ -259,14 +285,13 @@ impl WorkManager { // if the protocol is neither started nor enqueued, then, this message may be for a future // async protocol. Store the message - self.logger.info_signing(format!( - "Enqueuing message for {:?}", - hex::encode(msg_unsigned_proposal_hash) - )); - lock.enqueued_messages - .entry(*msg_unsigned_proposal_hash) - .or_default() - .push_back(msg) + let current_running_session_ids: Vec = + lock.active_tasks.iter().map(|job| job.handle.session_id).collect(); + let enqueued_session_ids: Vec = + lock.enqueued_tasks.iter().map(|job| job.handle.session_id).collect(); + self.logger + .info_signing(format!("Enqueuing message for {:?} | current_running_session_ids: {current_running_session_ids:?} | enqueued_session_ids: {enqueued_session_ids:?}", hex::encode(message_task_hash))); + lock.enqueued_messages.entry(message_task_hash).or_default().push_back(msg) } } @@ -278,6 +303,18 @@ pub struct Job { task: Arc>>>, } +impl Job { + fn metadata(&self, now: NumberFor) -> JobMetadata { + JobMetadata { + session_id: self.handle.session_id, + is_stalled: self.handle.keygen_has_stalled(now), + is_finished: self.handle.is_keygen_finished(), + has_started: self.handle.has_started(), + is_active: self.handle.is_active(), + } + } +} + pub type SyncFuture = SyncWrapper>>>; impl std::borrow::Borrow<[u8; 32]> for Job { @@ -306,6 +343,19 @@ impl Drop for Job { "Will remove job {:?} from currently_signing_proposals", hex::encode(self.task_hash) )); - let _ = self.handle.shutdown("shutdown from Job::drop"); + let _ = self.handle.shutdown(ShutdownReason::DropCode); } } + +fn should_deliver( + task: &Job, + msg: &SignedDKGMessage, + message_task_hash: [u8; 32], +) -> bool { + task.handle.session_id == msg.msg.session_id && + task.task_hash == message_task_hash && + associated_block_id_acceptable( + task.handle.associated_block_id, + msg.msg.associated_block_id, + ) +} diff --git a/dkg-gadget/src/storage/proposals.rs b/dkg-gadget/src/storage/proposals.rs index a6aee6415..90440127f 100644 --- a/dkg-gadget/src/storage/proposals.rs +++ b/dkg-gadget/src/storage/proposals.rs @@ -15,13 +15,12 @@ use crate::{ debug_logger::DebugLogger, utils::find_index, worker::{MAX_SUBMISSION_DELAY, STORAGE_SET_RETRY_NUM}, - Client, }; use codec::{Decode, Encode}; use dkg_runtime_primitives::{ crypto::{AuthorityId, Public}, offchain::storage_keys::OFFCHAIN_SIGNED_PROPOSALS, - AuthoritySet, DKGApi, OffchainSignedProposals, + AuthoritySet, OffchainSignedProposals, }; use parking_lot::RwLock; use rand::Rng; @@ -32,7 +31,7 @@ use std::sync::Arc; use webb_proposals::Proposal; /// processes signed proposals and puts them in storage -pub(crate) fn save_signed_proposals_in_storage( +pub(crate) fn save_signed_proposals_in_storage( authority_public_key: &Public, current_validator_set: &Arc>>, latest_header: &Arc>>, @@ -42,17 +41,8 @@ pub(crate) fn save_signed_proposals_in_storage, - C: Client, - MaxProposalLength: - Get + Clone + Send + Sync + 'static + std::fmt::Debug + std::cmp::PartialEq, - MaxAuthorities: Get + Clone + Send + Sync + 'static + std::fmt::Debug, - C::Api: DKGApi< - B, - AuthorityId, - <::Header as Header>::Number, - MaxProposalLength, - MaxAuthorities, - >, + MaxAuthorities: Get, + MaxProposalLength: Get + Clone, { if signed_proposals.is_empty() { return diff --git a/dkg-gadget/src/storage/public_keys.rs b/dkg-gadget/src/storage/public_keys.rs index 60d633598..36e712f8e 100644 --- a/dkg-gadget/src/storage/public_keys.rs +++ b/dkg-gadget/src/storage/public_keys.rs @@ -14,25 +14,24 @@ use crate::{ debug_logger::DebugLogger, storage::proposals::generate_delayed_submit_at, - worker::MAX_SUBMISSION_DELAY, Client, + worker::MAX_SUBMISSION_DELAY, }; use codec::Encode; use dkg_primitives::types::{DKGError, SessionId}; use dkg_runtime_primitives::{ - crypto::AuthorityId, offchain::storage_keys::{ AGGREGATED_PUBLIC_KEYS, AGGREGATED_PUBLIC_KEYS_AT_GENESIS, SUBMIT_GENESIS_KEYS_AT, SUBMIT_KEYS_AT, }, - AggregatedPublicKeys, DKGApi, MaxAuthorities, + AggregatedPublicKeys, }; use sc_client_api::Backend; use sp_api::offchain::{OffchainStorage, STORAGE_PREFIX}; -use sp_runtime::traits::{Block, Get, Header, NumberFor}; +use sp_runtime::traits::{Block, NumberFor}; use std::{collections::HashMap, sync::Arc}; /// stores genesis or next aggregated public keys offchain -pub(crate) fn store_aggregated_public_keys( +pub(crate) fn store_aggregated_public_keys( backend: &Arc, aggregated_public_keys: &mut HashMap, is_genesis_round: bool, @@ -43,15 +42,6 @@ pub(crate) fn store_aggregated_public_keys( where B: Block, BE: Backend, - C: Client, - MaxProposalLength: Get + Clone + Send + Sync + 'static + std::fmt::Debug, - C::Api: DKGApi< - B, - AuthorityId, - <::Header as Header>::Number, - MaxProposalLength, - MaxAuthorities, - >, { let maybe_offchain = backend.offchain_storage(); if maybe_offchain.is_none() { diff --git a/dkg-gadget/src/utils.rs b/dkg-gadget/src/utils.rs index 2f0ce35c9..51c491253 100644 --- a/dkg-gadget/src/utils.rs +++ b/dkg-gadget/src/utils.rs @@ -91,14 +91,6 @@ pub(crate) fn inspect_outbound(ty: &'static str, serialized_len: usize) { #[cfg(not(feature = "outbound-inspection"))] pub(crate) fn inspect_outbound(_ty: &str, _serialized_len: usize) {} -pub fn convert_u16_vec_to_usize_vec(input: Vec) -> Vec { - let mut usize_vec: Vec = vec![]; - for item in input { - usize_vec.push(usize::try_from(item).unwrap_or_default()); - } - usize_vec -} - use futures::task::Context; use tokio::{ macros::support::{Pin, Poll}, diff --git a/dkg-gadget/src/worker.rs b/dkg-gadget/src/worker.rs index 15be015cb..ff40d5ac5 100644 --- a/dkg-gadget/src/worker.rs +++ b/dkg-gadget/src/worker.rs @@ -17,7 +17,6 @@ use crate::{ async_protocols::{blockchain_interface::DKGProtocolEngine, KeygenPartyId}, debug_logger::DebugLogger, - utils::convert_u16_vec_to_usize_vec, }; use codec::{Codec, Encode}; use curv::elliptic::curves::Secp256k1; @@ -27,26 +26,23 @@ use sp_consensus::SyncOracle; use crate::signing_manager::SigningManager; use futures::StreamExt; use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::keygen::LocalKey; -use parking_lot::{Mutex, RwLock}; +use parking_lot::RwLock; use sc_client_api::{Backend, FinalityNotification}; use sc_keystore::LocalKeystore; use sp_arithmetic::traits::SaturatedConversion; use sp_core::ecdsa; use sp_runtime::traits::{Block, Get, Header, NumberFor}; use std::{ - collections::{BTreeSet, HashMap, HashSet, VecDeque}, + collections::{BTreeSet, HashMap}, marker::PhantomData, - sync::{ - atomic::{AtomicU16, Ordering}, - Arc, - }, + pin::Pin, + sync::{atomic::Ordering, Arc}, }; use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender}; use dkg_primitives::{ types::{ - DKGError, DKGMessage, DKGMisbehaviourMessage, DKGMsgPayload, DKGMsgStatus, SessionId, - SignedDKGMessage, + DKGError, DKGMessage, DKGMisbehaviourMessage, DKGMsgPayload, SessionId, SignedDKGMessage, }, AuthoritySetId, DKGReport, MisbehaviourType, }; @@ -54,21 +50,24 @@ use dkg_runtime_primitives::{ crypto::{AuthorityId, Public}, utils::to_slice_33, AggregatedMisbehaviourReports, AggregatedPublicKeys, AuthoritySet, DKGApi, MaxAuthorities, - MaxProposalLength, MaxReporters, MaxSignatureLength, GENESIS_AUTHORITY_SET_ID, KEYGEN_TIMEOUT, + MaxProposalLength, MaxReporters, MaxSignatureLength, GENESIS_AUTHORITY_SET_ID, }; use crate::{ - async_protocols::{remote::AsyncProtocolRemote, AsyncProtocolParameters, GenericAsyncHandler}, + async_protocols::{ + remote::AsyncProtocolRemote, AsyncProtocolParameters, GenericAsyncHandler, KeygenRound, + }, error, gossip_engine::GossipEngineIface, gossip_messages::{ misbehaviour_report::{gossip_misbehaviour_report, handle_misbehaviour_report}, public_key_gossip::handle_public_key_broadcast, }, + keygen_manager::{KeygenManager, KeygenState}, keystore::DKGKeystore, metric_inc, metric_set, metrics::Metrics, - utils::find_authorities_change, + utils::{find_authorities_change, SendFuture}, Client, }; @@ -119,10 +118,6 @@ where pub signing_gossip_engine: Arc, pub db: Arc, pub metrics: Arc>, - // Genesis keygen and rotated round - pub rounds: Shared>>>, - // Next keygen round, always taken and restarted each session - pub next_rounds: Shared>>>, /// Cached best authorities pub best_authorities: Shared>, /// Cached next best authorities @@ -138,28 +133,20 @@ where /// Tracking for the misbehaviour reports pub aggregated_misbehaviour_reports: Shared, pub misbehaviour_tx: Option>, - /// A HashSet of the currently being signed proposals. - /// Note: we only store the hash of the proposal here, not the full proposal. - pub currently_signing_proposals: Shared>, /// Concrete type that points to the actual local keystore if it exists pub local_keystore: Shared>>, /// For transmitting errors from parallel threads to the DKGWorker pub error_handler: tokio::sync::broadcast::Sender, - /// Keep track of the number of how many times we have tried the keygen protocol. - pub keygen_retry_count: Arc, /// Used to keep track of network status pub network: Option>>, pub test_bundle: Option, pub logger: DebugLogger, pub signing_manager: SigningManager, - pub keygen_enqueued_messages: KeygenEnqueuedMessages, + pub keygen_manager: KeygenManager, // keep rustc happy _backend: PhantomData<(BE, MaxProposalLength)>, } -type KeygenEnqueuedMessages = - Arc>>>>>; - /// Used only for tests #[derive(Clone)] pub struct TestBundle { @@ -186,8 +173,6 @@ where keygen_gossip_engine: self.keygen_gossip_engine.clone(), signing_gossip_engine: self.signing_gossip_engine.clone(), metrics: self.metrics.clone(), - rounds: self.rounds.clone(), - next_rounds: self.next_rounds.clone(), best_authorities: self.best_authorities.clone(), next_best_authorities: self.next_best_authorities.clone(), latest_header: self.latest_header.clone(), @@ -196,15 +181,13 @@ where aggregated_public_keys: self.aggregated_public_keys.clone(), aggregated_misbehaviour_reports: self.aggregated_misbehaviour_reports.clone(), misbehaviour_tx: self.misbehaviour_tx.clone(), - currently_signing_proposals: self.currently_signing_proposals.clone(), local_keystore: self.local_keystore.clone(), error_handler: self.error_handler.clone(), test_bundle: self.test_bundle.clone(), - keygen_retry_count: self.keygen_retry_count.clone(), network: self.network.clone(), logger: self.logger.clone(), signing_manager: self.signing_manager.clone(), - keygen_enqueued_messages: self.keygen_enqueued_messages.clone(), + keygen_manager: self.keygen_manager.clone(), _backend: PhantomData, } } @@ -247,18 +230,20 @@ where let (error_handler, _) = tokio::sync::broadcast::channel(1024); let clock = Clock { latest_header: latest_header.clone() }; - let signing_manager = SigningManager::::new(logger.clone(), clock); + let signing_manager = SigningManager::::new(logger.clone(), clock.clone()); + // 2 tasks max: 1 for current, 1 for queued + let keygen_manager = KeygenManager::new(logger.clone(), clock); + DKGWorker { client, misbehaviour_tx: None, backend, key_store, db: db_backend, + keygen_manager, keygen_gossip_engine: Arc::new(keygen_gossip_engine), signing_gossip_engine: Arc::new(signing_gossip_engine), metrics: Arc::new(metrics), - rounds: Arc::new(RwLock::new(None)), - next_rounds: Arc::new(RwLock::new(None)), best_authorities: Arc::new(RwLock::new(vec![])), next_best_authorities: Arc::new(RwLock::new(vec![])), current_validator_set: Arc::new(RwLock::new(AuthoritySet::empty())), @@ -266,12 +251,9 @@ where latest_header, aggregated_public_keys: Arc::new(RwLock::new(HashMap::new())), aggregated_misbehaviour_reports: Arc::new(RwLock::new(HashMap::new())), - currently_signing_proposals: Arc::new(RwLock::new(HashSet::new())), local_keystore: Arc::new(RwLock::new(local_keystore)), - keygen_enqueued_messages: Arc::new(Mutex::new(Default::default())), test_bundle, error_handler, - keygen_retry_count: Arc::new(AtomicU16::new(0)), logger, network, signing_manager, @@ -282,11 +264,17 @@ where #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum ProtoStageType { - Genesis, - Queued, + KeygenGenesis, + KeygenStandard, Signing { unsigned_proposal_hash: [u8; 32] }, } +#[derive(Debug, Copy, Clone)] +pub struct AnticipatedKeygenExecutionStatus { + pub execute: bool, + pub force_execute: bool, +} + impl DKGWorker where B: Block, @@ -320,26 +308,18 @@ where let now = self.get_latest_block_number(); let associated_block_id: u64 = associated_block.saturated_into(); + let status_handle = + AsyncProtocolRemote::new(now, session_id, self.logger.clone(), associated_block_id); // Fetch the active key. This requires rotating the key to have happened with // full certainty in order to ensure the right key is being used to make signatures. - let keygen_retry_id = self.keygen_retry_count.load(Ordering::Relaxed); - let (active_local_key, retry_id) = match stage { - ProtoStageType::Genesis => (None, keygen_retry_id), - ProtoStageType::Queued => (None, keygen_retry_id), + let active_local_key = match stage { + ProtoStageType::KeygenGenesis => None, + ProtoStageType::KeygenStandard => None, ProtoStageType::Signing { .. } => { - let optional_session_id = Some(session_id); - let (active_local_key, _) = self.fetch_local_keys(optional_session_id); - (active_local_key, 0) + let (active_local_key, _) = self.fetch_local_keys(session_id); + active_local_key }, }; - let mut status_handle = AsyncProtocolRemote::new( - now, - session_id, - self.logger.clone(), - associated_block_id, - retry_id, - ); - self.logger.debug(format!( "Active local key enabled for stage {:?}? {}", stage, @@ -360,7 +340,7 @@ where current_validator_set: self.current_validator_set.clone(), local_keystore: self.local_keystore.clone(), vote_results: Arc::new(Default::default()), - is_genesis: stage == ProtoStageType::Genesis, + is_genesis: stage == ProtoStageType::KeygenGenesis, metrics: self.metrics.clone(), test_bundle: self.test_bundle.clone(), logger: self.logger.clone(), @@ -374,53 +354,25 @@ where party_i, authority_public_key, batch_id_gen: Arc::new(Default::default()), - handle: status_handle.clone(), + handle: status_handle, logger: self.logger.clone(), local_key: active_local_key, associated_block_id, - retry_id, }; - if let ProtoStageType::Signing { unsigned_proposal_hash } = &stage { - self.logger.debug(format!("Signing protocol for proposal hash {unsigned_proposal_hash:?} will start later in the work manager")); - return Ok(params) - } - - // Set the status handle as primary, implying that once it drops, it will stop the async - // protocol - status_handle.set_as_primary(); - // Cache the rounds, respectively - match stage { - ProtoStageType::Genesis => { - self.logger.debug("Starting genesis protocol (obtaining the lock)".to_string()); - let mut lock = self.rounds.write(); - self.logger.debug("Starting genesis protocol (got the lock)".to_string()); - if lock.is_some() { - self.logger.warn( - "Overwriting rounds will result in termination of previous rounds!" - .to_string(), - ); - } - *lock = Some(status_handle); - }, - ProtoStageType::Queued => { - self.logger.debug("Starting queued protocol (obtaining the lock)".to_string()); - let mut lock = self.next_rounds.write(); - self.logger.debug("Starting queued protocol (got the lock)".to_string()); - if lock.is_some() { - self.logger.warn( - "Overwriting rounds will result in termination of previous rounds!" - .to_string(), - ); - } - *lock = Some(status_handle); + match &stage { + ProtoStageType::Signing { unsigned_proposal_hash } => { + self.logger.debug(format!("Signing protocol for proposal hash {unsigned_proposal_hash:?} will start later in the signing manager")); + Ok(params) }, - ProtoStageType::Signing { .. } => { - unreachable!("Signing stage should not be handled here!") + + ProtoStageType::KeygenGenesis | ProtoStageType::KeygenStandard => { + self.logger.debug(format!( + "Protocol for stage {stage:?} will start later in the keygen manager" + )); + Ok(params) }, } - - Ok(params) } /// Returns the gossip engine based on the protocol_name @@ -433,7 +385,7 @@ where } #[allow(clippy::too_many_arguments)] - async fn spawn_keygen_protocol( + pub(crate) async fn initialize_keygen_protocol( &self, best_authorities: Vec<(KeygenPartyId, Public)>, authority_public_key: Public, @@ -442,7 +394,8 @@ where associated_block: NumberFor, threshold: u16, stage: ProtoStageType, - ) { + keygen_protocol_hash: [u8; 32], + ) -> Option<(AsyncProtocolRemote>, Pin>>)> { match self.generate_async_proto_params( best_authorities, authority_public_key, @@ -454,78 +407,58 @@ where ) { Ok(async_proto_params) => { let err_handler_tx = self.error_handler.clone(); - // Check first from the rounds object, if any. - let status = if let Some(rounds) = self.rounds.read().as_ref() { - if rounds.session_id == session_id { - DKGMsgStatus::ACTIVE - } else { - DKGMsgStatus::QUEUED - } - } else if session_id == GENESIS_AUTHORITY_SET_ID { - // We are likely crashed and restarted, so we do not have the rounds object, - // yet. We can safely assume that we are in the genesis stage since we are - // session 0. - DKGMsgStatus::ACTIVE - } else { - // We are likely crashed and restarted, and we are not in the genesis stage, - // so we can safely assume that we are in the queued state. - DKGMsgStatus::QUEUED + + let remote = async_proto_params.handle.clone(); + let keygen_manager = self.keygen_manager.clone(); + let status = match stage { + ProtoStageType::KeygenGenesis => KeygenRound::Genesis, + ProtoStageType::KeygenStandard => KeygenRound::Next, + ProtoStageType::Signing { .. } => { + unreachable!("Should not happen here") + }, }; - let start_handle = async_proto_params.handle.clone(); - let retry_id = start_handle.retry_id; - - let mut enqueued_messages = self - .keygen_enqueued_messages - .lock() - .entry(session_id) - .or_default() - .remove(&retry_id) - .unwrap_or_default(); - - match GenericAsyncHandler::setup_keygen(async_proto_params, threshold, status) { + + match GenericAsyncHandler::setup_keygen( + async_proto_params, + threshold, + status, + keygen_protocol_hash, + ) { Ok(meta_handler) => { let logger = self.logger.clone(); + let signing_manager = self.signing_manager.clone(); + signing_manager.keygen_lock(); let task = async move { - if let Err(err) = start_handle.start() { - logger.error_keygen(format!( - "Error starting keygen protocol: {err:?}" - )); - return - } - - // deliver any enqueued messages - while let Some(msg) = enqueued_messages.pop_front() { - logger.debug_keygen(format!( - "Delivering enqueued message: session={}, retry_id={}", - msg.msg.session_id, msg.msg.retry_id - )); - - if let Err(err) = start_handle.deliver_message(msg) { - logger.error_keygen(format!( - "Error delivering enqueued message: {err:?}" - )); - } - } - match meta_handler.await { Ok(_) => { + keygen_manager.set_state(KeygenState::KeygenCompleted { + session_completed: session_id, + }); + let _ = keygen_manager + .finished_count + .fetch_add(1, Ordering::SeqCst); + signing_manager.keygen_unlock(); logger.info( - "The meta handler has executed successfully".to_string(), + "The keygen meta handler has executed successfully" + .to_string(), ); + + Ok(()) }, Err(err) => { logger .error(format!("Error executing meta handler {:?}", &err)); - let _ = err_handler_tx.send(err); + keygen_manager.set_state(KeygenState::Failed { session_id }); + signing_manager.keygen_unlock(); + let _ = err_handler_tx.send(err.clone()); + Err(err) }, } }; - self.logger.debug(format!("Started Keygen Protocol for session {session_id} with status {status:?}")); - // spawn on parallel thread - self.logger.info("Started a new thread for task".to_string()); - let _handle = tokio::task::spawn(task); + self.logger.debug(format!("Created Keygen Protocol task for session {session_id} with status {status:?}")); + return Some((remote, Box::pin(task))) }, Err(err) => { @@ -539,27 +472,18 @@ where self.handle_dkg_error(err).await; }, } + + None } /// Fetch the stored local keys if they exist. - /// - /// The `optional_session_id` is used to fetch the keys for a specific session, only in case - /// if `self.rounds` is `None`. This is useful when the node is restarted and we need to fetch - /// the keys for the current session. fn fetch_local_keys( &self, - optional_session_id: Option, + current_session_id: SessionId, ) -> (Option>, Option>) { - let current_session_id = if let Some(sid) = optional_session_id { - Some(sid) - } else { - self.rounds.read().as_ref().map(|r| r.session_id).or(optional_session_id) - }; - - let next_session_id = current_session_id.map(|s| s + 1); - let active_local_key = - current_session_id.and_then(|s| self.db.get_local_key(s).ok().flatten()); - let next_local_key = next_session_id.and_then(|s| self.db.get_local_key(s).ok().flatten()); + let next_session_id = current_session_id + 1; + let active_local_key = self.db.get_local_key(current_session_id).ok().flatten(); + let next_local_key = self.db.get_local_key(next_session_id).ok().flatten(); (active_local_key, next_local_key) } @@ -620,6 +544,10 @@ where .await } + pub async fn dkg_pub_key_is_unset(&self, header: &B::Header) -> bool { + self.get_dkg_pub_key(header).await.1.is_empty() + } + /// Get the next DKG public key pub async fn get_next_dkg_pub_key( &self, @@ -739,162 +667,6 @@ where Ok(()) } - async fn handle_genesis_dkg_setup( - &self, - header: &B::Header, - genesis_authority_set: AuthoritySet, - ) -> Result<(), DKGError> { - // Check if the authority set is empty or if this authority set isn't actually the genesis - // set - if genesis_authority_set.authorities.is_empty() { - return Err(DKGError::StartKeygen { - reason: String::from("Empty Genesis authority set"), - }) - } - // If the rounds is none and we are not using the genesis authority set ID - // there is a critical error. I'm not sure how this can happen but it should - // prevent an edge case. - match self.rounds.read().as_ref() { - None if genesis_authority_set.id != GENESIS_AUTHORITY_SET_ID => { - self.logger.error( - "🕸️ Rounds is None and authority set is not genesis set ID 0".to_string(), - ); - return Err(DKGError::StartKeygen { - reason: String::from( - "Rounds is None and authority set is not genesis set ID 0", - ), - }) - }, - _ => {}, - } - - let latest_block_num = self.get_latest_block_number(); - - // Check if we've already set up the DKG for this authority set - // if the active is currently running, and, the keygen has stalled, create one anew - match self.rounds.read().as_ref() { - Some(rounds) if rounds.is_active() && !rounds.keygen_has_stalled(latest_block_num) => { - self.logger.debug(format!( - "🕸️ Rounds exists and is active, latest block number: {latest_block_num:?}" - )); - return Ok(()) - }, - // For when we already completed the DKG, no need to do it again. - Some(rounds) if rounds.is_completed() => { - self.logger.debug(format!( - "🕸️ Rounds exists and is completed, latest block number: {latest_block_num:?}" - )); - return Ok(()) - }, - _ => {}, - } - - // DKG keygen authorities are always taken from the best set of authorities - let session_id = genesis_authority_set.id; - // Check whether the worker is in the best set or return - let party_i = match self.get_party_index(header).await { - Some(party_index) => { - self.logger.info(format!("🕸️ PARTY {party_index} | SESSION {session_id} | IN THE SET OF BEST GENESIS AUTHORITIES: session: {session_id}")); - KeygenPartyId::try_from(party_index)? - }, - None => { - self.logger.info(format!( - "🕸️ NOT IN THE SET OF BEST GENESIS AUTHORITIES: session: {session_id}" - )); - *self.rounds.write() = None; - return Ok(()) - }, - }; - - let best_authorities = self - .get_best_authorities(header) - .await - .into_iter() - .flat_map(|(i, p)| KeygenPartyId::try_from(i).map(|i| (i, p))) - .collect(); - let threshold = self.get_signature_threshold(header).await; - let authority_public_key = self.get_authority_public_key(); - self.logger.debug(format!("🕸️ PARTY {party_i} | SPAWNING KEYGEN SESSION {session_id} | BEST AUTHORITIES: {best_authorities:?}")); - self.spawn_keygen_protocol( - best_authorities, - authority_public_key, - party_i, - session_id, - *header.number(), - threshold, - ProtoStageType::Genesis, - ) - .await; - Ok(()) - } - - async fn handle_queued_dkg_setup( - &self, - header: &B::Header, - queued: AuthoritySet, - ) -> Result<(), DKGError> { - // Check if the authority set is empty, return or proceed - if queued.authorities.is_empty() { - self.logger.debug("🕸️ queued authority set is empty".to_string()); - return Err(DKGError::StartKeygen { reason: String::from("Empty queued authority set") }) - } - // Handling edge cases when the rounds exists, is currently active, and not stalled - if let Some(rounds) = self.next_rounds.read().as_ref() { - // Check if the next rounds exists and has processed for this next queued round id - if rounds.is_active() && !rounds.keygen_has_stalled(*header.number()) { - self.logger.debug(format!( - "🕸️ Next rounds exists and is active, latest block number: {:?}", - *header.number() - )); - return Ok(()) - } else { - // Proceed to clear the next rounds. - self.logger - .debug(" Next rounds keygen has stalled, creating new rounds...".to_string()); - } - } - // Get the best next authorities using the keygen threshold - let session_id = queued.id; - // Check whether the worker is in the best set or return - let party_i = match self.get_next_party_index(header).await { - Some(party_index) => { - self.logger.info(format!("🕸️ PARTY {party_index} | SESSION {session_id} | IN THE SET OF BEST NEXT AUTHORITIES")); - KeygenPartyId::try_from(party_index)? - }, - None => { - self.logger.info(format!( - "🕸️ NOT IN THE SET OF BEST NEXT AUTHORITIES: session {session_id:?}" - )); - *self.next_rounds.write() = None; - return Ok(()) - }, - }; - - *self.next_best_authorities.write() = self.get_next_best_authorities(header).await; - let next_best_authorities = self - .get_next_best_authorities(header) - .await - .into_iter() - .flat_map(|(i, p)| KeygenPartyId::try_from(i).map(|i| (i, p))) - .collect(); - let threshold = self.get_next_signature_threshold(header).await; - - let authority_public_key = self.get_authority_public_key(); - // spawn the Keygen protocol for the Queued DKG. - self.logger.debug(format!("🕸️ PARTY {party_i} | SPAWNING KEYGEN SESSION {session_id} | BEST AUTHORITIES: {next_best_authorities:?}")); - self.spawn_keygen_protocol( - next_best_authorities, - authority_public_key, - party_i, - session_id, - *header.number(), - threshold, - ProtoStageType::Queued, - ) - .await; - Ok(()) - } - // *** Block notifications *** async fn process_block_notification(&self, header: &B::Header) { if let Some(latest_header) = self.latest_header.read().clone() { @@ -929,15 +701,18 @@ where // 2. if yes, we start enacting authorities on genesis flow. // 3. if no, we start enacting authorities on queued flow and submit any unsigned // proposals. - if self.get_dkg_pub_key(header).await.1.is_empty() { + if self.dkg_pub_key_is_unset(header).await { self.logger .debug("🕸️ Maybe enacting genesis authorities since dkg pub key is empty"); self.maybe_enact_genesis_authorities(header).await; + self.keygen_manager.on_block_finalized(header, self).await; } else { - self.maybe_enact_next_authorities(header).await; - self.maybe_rotate_local_sessions(header).await; - if let Err(e) = self.handle_unsigned_proposals(header).await { - self.logger.error(format!("🕸️ Error running handle_unsigned_proposals: {e:?}")); + // maybe update the internal state of the worker + self.maybe_update_worker_state(header).await; + self.keygen_manager.on_block_finalized(header, self).await; + if let Err(e) = self.signing_manager.on_block_finalized(header, self).await { + self.logger + .error(format!("🕸️ Error running signing_manager.on_block_finalized: {e:?}")); } } } @@ -955,10 +730,6 @@ where *self.current_validator_set.write() = active.clone(); *self.best_authorities.write() = self.get_best_authorities(header).await; *self.next_best_authorities.write() = self.get_next_best_authorities(header).await; - // Setting up the DKG - if let Err(e) = self.handle_genesis_dkg_setup(header, active).await { - self.logger.error(format!("🕸️ Error handling genesis DKG setup: {e:?}")); - } } else { self.logger.debug(format!("🕸️ NOT IN GENESIS SESSION ID {:?}", active.id)); } @@ -967,156 +738,7 @@ where } } - /// Should enact next authorities will check for the follwoing situations: - /// - /// If the session period has not elapsed, we will return early. - /// - /// 1. If we detect a change in the best authorities, we should enact the next authorities with - /// the new ones. - /// 2. If the session progress is greater than the threshold, we should enact the next - /// authorities. - /// - /// Edge cases: - /// 1. If we already running a keygen protocol, and we detected that we are stalled, this - /// method will try to restart the keygen protocol. - async fn maybe_enact_next_authorities(&self, header: &B::Header) { - let (execute_keygen, force_execute_keygen) = self.should_execute_new_keygen(header).await; - - if !execute_keygen { - self.logger.debug("🕸️ Not executing new keygen protocol"); - return - } - - self.logger.debug("Running maybe_enact_next_authorities"); - - // Get the active and queued validators to check for updates - if let Some((_active, queued)) = self.validator_set(header).await { - self.logger - .debug("🕸️ should_execute_new_keygen is true, proceed with enact new authorities"); - - // for force_execute_keygen, bypass all checks and regenerate the keygen - if force_execute_keygen { - self.logger - .debug("🕸️ force_execute_keygen is true, executing new keygen protocol"); - // Start the queued DKG setup for the new queued authorities - if let Err(e) = self.handle_queued_dkg_setup(header, queued).await { - self.logger.error(format!("🕸️ Error handling queued DKG setup: {e:?}")); - } - // Reset the Retry counter. - self.keygen_retry_count.store(0, Ordering::SeqCst); - return - } - - // Check if there is a keygen is finished: - let queued_keygen_finished = self - .next_rounds - .read() - .as_ref() - .map(|r| r.is_keygen_finished()) - .unwrap_or(false); - self.logger - .debug(format!("🕸️ QUEUED KEYGEN FINISHED: {queued_keygen_finished:?}")); - self.logger.debug(format!( - "🕸️ QUEUED DKG STATUS: {:?}", - self.next_rounds.read().as_ref().map(|r| r.status.clone()) - )); - let test_harness_mode = self.test_bundle.is_some(); - - if queued_keygen_finished && !test_harness_mode { - self.logger.debug("🕸️ QUEUED KEYGEN FINISHED: EXITING".to_string()); - return - } - - let has_next_rounds = self.next_rounds.read().is_some(); - self.logger.debug(format!("🕸️ HAS NEXT ROUND KEYGEN: {has_next_rounds:?}")); - // Check if there is a next DKG Key on-chain. - let next_dkg_key = self.get_next_dkg_pub_key(header).await; - - self.logger - .debug(format!("🕸️ NEXT DKG KEY ON CHAIN: {}", next_dkg_key.is_some())); - // Start a keygen if we don't have one OR if there is no queued key on chain. - if (!has_next_rounds && next_dkg_key.is_none()) || test_harness_mode { - self.logger.debug(format!( - "🕸️ NO NEXT ROUND KEYGEN AND NO NEXT DKG | STARTING A NEW QUEUED DKG: {}", - next_dkg_key.is_some() - )); - // Start the queued DKG setup for the new queued authorities - if let Err(e) = self.handle_queued_dkg_setup(header, queued).await { - self.logger.error(format!("🕸️ Error handling queued DKG setup: {e:?}")); - } - // Reset the Retry counter. - self.keygen_retry_count.store(0, Ordering::SeqCst); - return - } else { - self.logger.debug( - "🕸️ NEXT ROUND KEYGEN OR NEXT DKG KEY ON CHAIN | NOT STARTING A NEW QUEUED DKG", - ); - } - - // Check if we are stalled: - // a read only clone, to avoid holding the lock for the whole duration of the function - let next_rounds_clone = { - let lock = self.next_rounds.read(); - (*lock).clone() - }; - - if let Some(ref rounds) = next_rounds_clone { - self.logger.debug(format!( - "🕸️ Status: {:?}, Now: {:?}, Started At: {:?}, Timeout length: {:?}", - rounds.status, - header.number(), - rounds.started_at, - KEYGEN_TIMEOUT, - )); - let keygen_stalled = rounds.keygen_has_stalled(*header.number()); - let (current_attmp, max, should_retry) = { - // check how many authorities are in the next best authorities - // and then check the signature threshold `t`, if `t+1` is greater than the - // number of authorities and we still have not reached the maximum number of - // retries, we should retry the keygen - let next_best = self.get_next_best_authorities(header).await; - let n = next_best.len(); - let t = self.get_next_signature_threshold(header).await as usize; - // in this case, if t + 1 is equal to n, we should retry the keygen - // indefinitely. - // For example, if we are running a 3 node network, with 1-of-2 DKG, it will not - // be possible to successfully report the DKG Misbehavior on chain. - let max_retries = if t + 1 == n { 0 } else { MAX_KEYGEN_RETRIES }; - let v = self.keygen_retry_count.load(Ordering::SeqCst) as usize; - let should_retry = v < max_retries || max_retries == 0; - if keygen_stalled { - self.logger.debug(format!( - "🕸️ Keygen has stalled, retry conditions => n: {n}, t: {t}, current_attempt: {v}/{max_retries}, should_retry: {should_retry}" - )); - } - (v, max_retries, should_retry) - }; - if keygen_stalled && should_retry { - self.logger.debug(format!( - "🕸️ Queued Keygen has stalled, retrying (attempt: {current_attmp}/{max})" - )); - metric_inc!(self, dkg_keygen_retry_counter); - // Start the queued Keygen protocol again. - if let Err(e) = self.handle_queued_dkg_setup(header, queued).await { - self.logger.error(format!("🕸️ Error handling queued DKG setup: {e:?}")); - } - // Increment the retry count - self.keygen_retry_count.fetch_add(1, Ordering::SeqCst); - } else if keygen_stalled && !should_retry { - self.logger.debug("🕸️ Queued Keygen has stalled, but we have reached the maximum number of retries will report bad actors."); - self.handle_dkg_error(DKGError::KeygenTimeout { - bad_actors: convert_u16_vec_to_usize_vec( - rounds.current_round_blame().blamed_parties, - ), - session_id: rounds.session_id, - }) - .await - } - } - } - } - - async fn maybe_rotate_local_sessions(&self, header: &B::Header) { + async fn maybe_update_worker_state(&self, header: &B::Header) { if let Some((active, queued)) = self.validator_set(header).await { self.logger.debug(format!("🕸️ ACTIVE SESSION ID {:?}", active.id)); metric_set!(self, dkg_validator_set_id, active.id); @@ -1135,35 +757,16 @@ where // Update the validator sets *self.current_validator_set.write() = active; *self.queued_validator_set.write() = queued; - self.logger.debug("🕸️ Rotating next round this will result in a drop/termination of the current rounds!"); - match self.rounds.read().as_ref() { - Some(r) if r.is_active() => { - self.logger.warn( - "🕸️ Current rounds is active, rotating next round will terminate it!!" - .to_string(), - ); - }, - Some(_) | None => { - self.logger.warn( - "🕸️ Current rounds is not active, rotating next rounds is okay".to_string(), - ); - }, - }; - *self.rounds.write() = self.next_rounds.write().take(); // We also rotate the best authority caches *self.best_authorities.write() = self.next_best_authorities.read().clone(); *self.next_best_authorities.write() = self.get_next_best_authorities(header).await; - // since we just rotate, we reset the keygen retry counter - self.keygen_retry_count.store(0, Ordering::Relaxed); - // clear the currently being signing proposals cache. - self.currently_signing_proposals.write().clear(); // Reset per session metrics if let Some(metrics) = self.metrics.as_ref() { metrics.reset_session_metrics(); } } else { self.logger.info( - "🕸️ No update to local session found, not rotation local session".to_string(), + "🕸️ No update to local session found, not rotating local sessions".to_string(), ); } } @@ -1309,79 +912,17 @@ where dkg_msg: SignedDKGMessage, ) -> Result<(), DKGError> { metric_inc!(self, dkg_inbound_messages); - let rounds = self.rounds.read().clone(); - let next_rounds = self.next_rounds.read().clone(); - let is_keygen_type = matches!(dkg_msg.msg.payload, DKGMsgPayload::Keygen { .. }); - self.logger.info(format!( - "Processing incoming DKG message: {:?} | {:?}", - dkg_msg.msg.session_id, - rounds.as_ref().map(|x| x.session_id) - )); - - // discard the message if from previous round (keygen checking only. SigningManagerV2 - // internally handles session checks) - if let Some(current_round) = &rounds { - if dkg_msg.msg.session_id < current_round.session_id && is_keygen_type { - self.logger.warn(format!( - "Message is for already completed round: {}, Discarding message", - dkg_msg.msg.session_id - )); - return Ok(()) - } - } - - let is_delivery_type = matches!( - dkg_msg.msg.payload, - DKGMsgPayload::Keygen(..) | DKGMsgPayload::Offline(..) | DKGMsgPayload::Vote(..) - ); + self.logger + .info(format!("Processing incoming DKG message: {:?}", dkg_msg.msg.session_id,)); - let res = match &dkg_msg.msg.payload { + match &dkg_msg.msg.payload { DKGMsgPayload::Keygen(_) => { - if let Some(rounds) = &rounds { - if rounds.session_id == dkg_msg.msg.session_id && - rounds.retry_id == dkg_msg.msg.retry_id - { - if let Err(err) = rounds.deliver_message(dkg_msg) { - self.handle_dkg_error(DKGError::CriticalError { - reason: err.to_string(), - }) - .await - } - return Ok(()) - } - } - - if let Some(next_rounds) = next_rounds { - if next_rounds.session_id == dkg_msg.msg.session_id && - next_rounds.retry_id == dkg_msg.msg.retry_id - { - if let Err(err) = next_rounds.deliver_message(dkg_msg) { - self.handle_dkg_error(DKGError::CriticalError { - reason: err.to_string(), - }) - .await - } - return Ok(()) - } - } - - // Message belongs to neither. Enqueue it - self.logger.debug(format!( - "Enqueueing keygen message for later processing: session={}, retry_id={}", - dkg_msg.msg.session_id, dkg_msg.msg.retry_id - )); - let mut lock = self.keygen_enqueued_messages.lock(); - lock.entry(dkg_msg.msg.session_id) - .or_default() - .entry(dkg_msg.msg.retry_id) - .or_default() - .push_back(dkg_msg); - + self.keygen_manager.deliver_message(dkg_msg); Ok(()) }, DKGMsgPayload::Offline(..) | DKGMsgPayload::Vote(..) => { self.signing_manager.deliver_message(dkg_msg); - return Ok(()) + Ok(()) }, DKGMsgPayload::PublicKeyBroadcast(_) => { match self.verify_signature_against_authorities(dkg_msg).await { @@ -1418,13 +959,7 @@ where Ok(()) }, - }; - - if is_delivery_type { - self.logger.warn(format!("Did not deliver message! res: {res:?}")); } - - res } async fn handle_dkg_report(&self, dkg_report: DKGReport) { @@ -1493,10 +1028,6 @@ where Ok(Public::from(signer)) } - async fn handle_unsigned_proposals(&self, header: &B::Header) -> Result<(), DKGError> { - self.signing_manager.on_block_finalized(header, self).await - } - fn get_jailed_signers_inner( &self, best_authorities: &[Public], @@ -1538,13 +1069,19 @@ where .collect()) } - async fn should_execute_new_keygen(&self, header: &B::Header) -> (bool, bool) { + pub async fn should_execute_new_keygen( + &self, + header: &B::Header, + ) -> AnticipatedKeygenExecutionStatus { // query runtime api to check if we should execute new keygen. let at = header.hash(); - self.exec_client_function(move |client| { - client.runtime_api().should_execute_new_keygen(at).unwrap_or_default() - }) - .await + let (execute, force_execute) = self + .exec_client_function(move |client| { + client.runtime_api().should_execute_new_keygen(at).unwrap_or_default() + }) + .await; + + AnticipatedKeygenExecutionStatus { execute, force_execute } } /// Wraps the call in a SpawnBlocking task @@ -1755,6 +1292,12 @@ pub struct Clock { pub latest_header: Arc>>, } +impl Clone for Clock { + fn clone(&self) -> Self { + Self { latest_header: self.latest_header.clone() } + } +} + impl HasLatestHeader for Clock { fn get_latest_header(&self) -> &Arc>> { &self.latest_header diff --git a/dkg-mock-blockchain/src/server.rs b/dkg-mock-blockchain/src/server.rs index 998843ac3..afecdd294 100644 --- a/dkg-mock-blockchain/src/server.rs +++ b/dkg-mock-blockchain/src/server.rs @@ -4,7 +4,7 @@ use crate::{ }; use atomic::Atomic; use dkg_logging::debug_logger::DebugLogger; -use dkg_runtime_primitives::UnsignedProposal; +use dkg_runtime_primitives::{MaxProposalLength, UnsignedProposal}; use futures::{SinkExt, StreamExt}; use sc_client_api::FinalizeSummary; use sp_runtime::app_crypto::sp_core::hashing::sha2_256; @@ -32,6 +32,7 @@ pub struct MockBlockchain { // the orchestrator receives updates from its client sub-tasks from this receiver orchestrator_rx: Arc>>>, orchestrator_state: Arc>, + blocks_per_session: Arc, blockchain: T, logger: DebugLogger, } @@ -85,6 +86,7 @@ impl MockBlockchain { config: MockBlockchainConfig, blockchain: T, logger: DebugLogger, + blocks_per_session: u64, ) -> std::io::Result { let listener = TcpListener::bind(&config.bind).await?; let clients = Arc::new(RwLock::new(HashMap::new())); @@ -100,6 +102,7 @@ impl MockBlockchain { orchestrator_rx: Arc::new(Mutex::new(Some(orchestrator_rx))), blockchain, logger, + blocks_per_session: Arc::new(blocks_per_session), }) } @@ -125,6 +128,10 @@ impl MockBlockchain { tokio::try_join!(listener_task, orchestrator_task).map(|_| ()) } + fn block_id_to_session_id(&self, block_id: u64) -> u64 { + (block_id as f64 / *self.blocks_per_session as f64).floor() as u64 + } + /// For debugging purposes, everything will get unwrapped here async fn handle_stream(self, stream: TcpStream, addr: SocketAddr) { let (mut tx, mut rx) = bind_transport::(stream); @@ -276,7 +283,6 @@ impl MockBlockchain { TestResult::Keygen { result, pub_key } => { // set the public key that way other nodes can verify that // the public key was submitted - // TODO: Make sure that we set_next_public key based on input self.blockchain.set_pub_key( intra_test_phase.round_number(), pub_key.clone(), @@ -293,6 +299,13 @@ impl MockBlockchain { // regardless of success, increment completed count for the current // round + if let TestResult::Keygen { pub_key, .. } = result { + self.blockchain.set_pub_key( + intra_test_phase.round_number() + 1, + pub_key.clone(), + ); + } + if matches!(result, TestResult::Keygen { .. }) && matches!(intra_test_phase, IntraTestPhase::Keygen { .. }) { @@ -331,6 +344,7 @@ impl MockBlockchain { // at the end, check if the round is complete let keygen_complete = current_round_completed_count_keygen == self.config.n_clients; + if keygen_complete && matches!(intra_test_phase, IntraTestPhase::Keygen { .. }) { // keygen is complete, and, we are ready to rotate into either the next @@ -483,8 +497,9 @@ impl MockBlockchain { IntraTestPhase::Signing { .. } => "SIGNING", }; + let session_id = self.block_id_to_session_id(test_round); for x in (1..=3).rev() { - log::info!(target: "dkg", "[Orchestrator] Beginning next {test_phase} test for session {test_round} in {x}"); + log::info!(target: "dkg", "[Orchestrator] Beginning next {test_phase} test for session {session_id} in {x}"); tokio::time::sleep(Duration::from_millis(1000)).await } } @@ -506,6 +521,7 @@ impl MockBlockchain { IntraTestPhase::Keygen { trace_id, .. } => { client.outstanding_tasks_keygen.insert(*trace_id, next_case.clone()); // always set the unsigned props to empty to ensure no signing protocol executes + self.blockchain.set_should_execute_keygen(true); self.blockchain.set_unsigned_proposals(vec![]); }, IntraTestPhase::Signing { trace_id, queued_unsigned_proposals, .. } => { @@ -517,6 +533,7 @@ impl MockBlockchain { .or_default() .push(next_case.clone()); } + self.blockchain.set_should_execute_keygen(false); self.blockchain.set_unsigned_proposals(unsigned_propos); } }, @@ -560,25 +577,21 @@ fn create_mocked_finality_blockchain_event(block_number: u64) -> MockBlockchainE } pub trait MutableBlockchain: Clone + Send + 'static { - fn set_unsigned_proposals( - &self, - propos: Vec<(UnsignedProposal>, u64)>, - ); - fn set_pub_key(&self, session: u64, key: Vec); + fn set_unsigned_proposals(&self, propos: Vec<(UnsignedProposal, u64)>); + fn set_pub_key(&self, block_id: u64, key: Vec); + fn set_should_execute_keygen(&self, should_execute: bool); } enum IntraTestPhase { Keygen { trace_id: Uuid, - queued_unsigned_proposals: - Option>>>, + queued_unsigned_proposals: Option>>, round_number: u64, test_case: Option, }, Signing { trace_id: Uuid, - queued_unsigned_proposals: - Option>, u64)>>, + queued_unsigned_proposals: Option, u64)>>, round_number: u64, test_case: TestCase, }, @@ -599,7 +612,7 @@ impl IntraTestPhase { { let queued_unsigned_proposals = queued_unsigned_proposals.take(); let mut queued_unsigned_proposals_with_expiry: Vec<( - UnsignedProposal>, + UnsignedProposal, u64, )> = Default::default(); for prop in queued_unsigned_proposals.iter() { @@ -621,9 +634,7 @@ impl IntraTestPhase { fn session_init( &mut self, - unsigned_proposals: Option< - Vec>>, - >, + unsigned_proposals: Option>>, test_case: TestCase, ) { // rotate signing into keygen, or keygen into keygen if there are no signing tests. diff --git a/dkg-primitives/src/keys.rs b/dkg-primitives/src/keys.rs index aff9e9721..084f8bd29 100644 --- a/dkg-primitives/src/keys.rs +++ b/dkg-primitives/src/keys.rs @@ -16,14 +16,10 @@ use crate::types::{FE, GE}; use curv::{arithmetic::Converter, BigInt}; use hex::{self}; use libsecp256k1::curve::{Affine, Field}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::party_i::SignatureRecid; use sha3::{Digest, Keccak256}; use std::convert::TryInto; -pub use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::{ - party_i::*, - state_machine::{keygen::*, sign::*}, -}; - pub fn recover_pub_key(sig: &SignatureRecid, message: &BigInt) -> Result { recover_pub_key_raw(message, sig.recid, sig.r.clone(), sig.s.clone()) } diff --git a/dkg-primitives/src/types.rs b/dkg-primitives/src/types.rs index 9fa51ff13..709ec95dd 100644 --- a/dkg-primitives/src/types.rs +++ b/dkg-primitives/src/types.rs @@ -55,10 +55,6 @@ pub struct DKGMessage { pub payload: DKGMsgPayload, /// Identifier for the message pub session_id: SessionId, - /// For identifying the retry count associated with the protocol - pub retry_id: u16, - /// enum for active or queued - pub status: DKGMsgStatus, /// The round ID pub associated_block_id: u64, } @@ -130,6 +126,14 @@ impl DKGMsgPayload { _ => None, } } + + pub fn keygen_protocol_hash(&self) -> Option<&[u8; 32]> { + if let DKGMsgPayload::Keygen(msg) = self { + Some(&msg.keygen_protocol_hash) + } else { + None + } + } /// NOTE: this is hacky /// TODO: Change enums for keygen, offline, vote pub fn async_proto_only_get_sender_id(&self) -> Option { @@ -159,6 +163,8 @@ pub struct DKGKeygenMessage { pub sender_id: u16, /// Serialized keygen msg pub keygen_msg: Vec, + /// Unique identification for this keygen protocol (hash of session id + retry count) + pub keygen_protocol_hash: [u8; 32], } #[derive(Debug, Clone, Decode, Encode)] diff --git a/dkg-runtime-primitives/src/lib.rs b/dkg-runtime-primitives/src/lib.rs index d4830788d..03ca84a6b 100644 --- a/dkg-runtime-primitives/src/lib.rs +++ b/dkg-runtime-primitives/src/lib.rs @@ -29,14 +29,12 @@ pub use ethereum_types::*; use frame_support::{pallet_prelude::Get, BoundedVec, RuntimeDebug}; pub use proposal::*; use scale_info::TypeInfo; -use sp_core::H256; use sp_runtime::{ traits::{IdentifyAccount, Verify}, MultiSignature, }; use sp_std::{fmt::Debug, prelude::*, vec::Vec}; use tiny_keccak::{Hasher, Keccak}; -use webb_proposals::Proposal; /// A custom get Struct to allow to import runtime values into the dkg gadget #[derive( @@ -278,7 +276,6 @@ impl + Clone> UnsignedProposal { } sp_api::decl_runtime_apis! { - pub trait DKGApi where AuthorityId: Codec + PartialEq, MaxProposalLength: Get + Clone, diff --git a/dkg-test-orchestrator/config/test_n3t2.toml b/dkg-test-orchestrator/config/test_n3t2.toml index 92edf21c8..96825c637 100644 --- a/dkg-test-orchestrator/config/test_n3t2.toml +++ b/dkg-test-orchestrator/config/test_n3t2.toml @@ -9,4 +9,4 @@ threshold = 2 min_simulated_latency = "0ms" # The number of positive cases to run positive_cases = 10 -unsigned_proposals_per_session = 10 +unsigned_proposals_per_session = 0 diff --git a/dkg-test-orchestrator/src/dummy_api.rs b/dkg-test-orchestrator/src/dummy_api.rs index e262ccb91..2234cee67 100644 --- a/dkg-test-orchestrator/src/dummy_api.rs +++ b/dkg-test-orchestrator/src/dummy_api.rs @@ -1,6 +1,6 @@ use dkg_gadget::debug_logger::DebugLogger; use dkg_mock_blockchain::{MutableBlockchain, TestBlock}; -use dkg_runtime_primitives::{crypto::AuthorityId, UnsignedProposal}; +use dkg_runtime_primitives::{crypto::AuthorityId, MaxProposalLength, UnsignedProposal}; use hash_db::HashDB; use parking_lot::RwLock; use sp_api::*; @@ -30,20 +30,25 @@ pub struct DummyApiInner { pub authority_sets: HashMap>>, pub dkg_keys: HashMap>, - pub unsigned_proposals: - Vec<(UnsignedProposal>, u64)>, + pub unsigned_proposals: Vec<(UnsignedProposal, u64)>, + pub should_execute_keygen: bool, + pub blocks_per_session: u64, } impl MutableBlockchain for DummyApi { - fn set_unsigned_proposals( - &self, - propos: Vec<(UnsignedProposal>, u64)>, - ) { + fn set_unsigned_proposals(&self, propos: Vec<(UnsignedProposal, u64)>) { self.inner.write().unsigned_proposals = propos; } - fn set_pub_key(&self, session: u64, key: Vec) { - self.inner.write().dkg_keys.insert(session, key); + fn set_pub_key(&self, block_id: u64, key: Vec) { + let header = sp_runtime::generic::Header::::new_from_number(block_id); + let hash = header.hash(); + let session_id = self.block_id_to_session_id(&hash); + self.inner.write().dkg_keys.insert(session_id, key); + } + + fn set_should_execute_keygen(&self, should_execute: bool) { + self.inner.write().should_execute_keygen = should_execute; } } @@ -53,16 +58,12 @@ impl DummyApi { keygen_n: u16, signing_t: u16, signing_n: u16, - n_sessions: usize, logger: DebugLogger, + blocks_per_session: u64, ) -> Self { let mut dkg_keys = HashMap::new(); // add a empty-key for the genesis block to drive the DKG forward dkg_keys.insert(0 as _, vec![]); - for x in 1..=(n_sessions + 1) { - // add dummy keys for all other sessions - dkg_keys.insert(x as _, vec![0, 1, 2, 3, 4, 5]); - } Self { inner: Arc::new(RwLock::new(DummyApiInner { @@ -73,18 +74,28 @@ impl DummyApi { authority_sets: HashMap::new(), dkg_keys, unsigned_proposals: vec![], + should_execute_keygen: false, + blocks_per_session, })), logger, } } - fn block_id_to_u64(&self, input: &H256) -> u64 { + fn block_id_to_session_id(&self, input: &H256) -> u64 { // this is hacky, but, it should suffice for now for x in 0..=u64::MAX { let header = sp_runtime::generic::Header::::new_from_number(x); let hash = header.hash(); if &hash == input { - return x + // take x and divide by blocks_per_session + let blocks_per_session = self.inner.read().blocks_per_session as f64; + // if bps = 2 + // x = 0 => 0 + // x = 1 => 0 + // x = 2 => 1 + // x = 3 => 1 + // thus: floor(x / bps) + return (x as f64 / blocks_per_session).floor() as u64 } } @@ -529,7 +540,7 @@ impl TestBlock, AuthorityId, sp_api::NumberFor, - dkg_runtime_primitives::CustomU32Getter<10000>, + MaxProposalLength, dkg_runtime_primitives::CustomU32Getter<100>, > for DummyApi { @@ -553,8 +564,8 @@ impl dkg_runtime_primitives::CustomU32Getter<100>, >, > { - let number = self.block_id_to_u64(&block); - self.logger.info(format!("Getting authority set for block {number}")); + let number = self.block_id_to_session_id(&block); + self.logger.info(format!("Getting authority set for session_id = {number}")); let authorities = self.inner.read().authority_sets.get(&number).unwrap().clone(); let authority_set_id = number; @@ -570,9 +581,13 @@ impl dkg_runtime_primitives::CustomU32Getter<100>, >, > { - let header = - sp_runtime::generic::Header::::new_from_number(self.block_id_to_u64(&id) + 1); - self.authority_set(header.hash()) + let next_session_id = self.block_id_to_session_id(&id) + 1; + self.logger + .info(format!("Getting queued authority set for session_id = {next_session_id}")); + let authorities = self.inner.read().authority_sets.get(&next_session_id).unwrap().clone(); + let authority_set_id = next_session_id; + + Ok(dkg_runtime_primitives::AuthoritySet { authorities, id: authority_set_id }) } fn signature_threshold(&self, _: H256) -> ApiResult { @@ -599,9 +614,14 @@ impl &self, id: H256, ) -> ApiResult)>> { - let header = - sp_runtime::generic::Header::::new_from_number(self.block_id_to_u64(&id) + 1); - self.dkg_pub_key(header.hash()).map(Some) + let number = self.block_id_to_session_id(&id) + 1; + self.logger.info(format!("Getting next authority set for block {number}")); + if let Some(pub_key) = self.inner.read().dkg_keys.get(&number).cloned() { + let authority_set_id = number; + Ok(Some((authority_set_id, pub_key))) + } else { + Ok(None) + } } fn next_pub_key_sig(&self, _: H256) -> ApiResult>> { @@ -613,16 +633,16 @@ impl &self, block: H256, ) -> ApiResult<(dkg_runtime_primitives::AuthoritySetId, Vec)> { - let number = self.block_id_to_u64(&block); - self.logger.info(format!("Getting authority set for block {number}")); + let number = self.block_id_to_session_id(&block); + self.logger.info(format!("Getting pub key for session_id = {number}")); let pub_key = self.inner.read().dkg_keys.get(&number).unwrap().clone(); let authority_set_id = number; Ok((authority_set_id, pub_key)) } fn get_best_authorities(&self, id: H256) -> ApiResult> { + let id = self.block_id_to_session_id(&id); let read = self.inner.read(); - let id = self.block_id_to_u64(&id); Ok(read .authority_sets .get(&id) @@ -634,9 +654,16 @@ impl } fn get_next_best_authorities(&self, id: H256) -> ApiResult> { - let header = - sp_runtime::generic::Header::::new_from_number(self.block_id_to_u64(&id) + 1); - self.get_best_authorities(header.hash()) + let next_session_id = self.block_id_to_session_id(&id) + 1; + let read = self.inner.read(); + Ok(read + .authority_sets + .get(&next_session_id) + .unwrap() + .iter() + .enumerate() + .map(|(idx, auth)| (idx as u16 + 1, auth.clone())) + .collect()) } fn get_current_session_progress( @@ -650,7 +677,7 @@ impl fn get_unsigned_proposals( &self, _hash: H256, - ) -> ApiResult>, u64)>> { + ) -> ApiResult, u64)>> { Ok(self.inner.read().unsigned_proposals.clone()) } @@ -692,6 +719,6 @@ impl } fn should_execute_new_keygen(&self, _: H256) -> ApiResult<(bool, bool)> { - Ok((true, true)) + Ok((self.inner.read().should_execute_keygen, false)) } } diff --git a/dkg-test-orchestrator/src/main.rs b/dkg-test-orchestrator/src/main.rs index 0909a4f66..83dd1f5ae 100644 --- a/dkg-test-orchestrator/src/main.rs +++ b/dkg-test-orchestrator/src/main.rs @@ -76,6 +76,7 @@ async fn main() -> Result<(), Box> { let keygen_n = n_clients as u16; let signing_t = t as u16; let signing_n = n_clients as u16; + let blocks_per_session = 2; // do NOT change this value (for now) // logging for the dummy api only let output = args.tmp_path.join("dummy_api.log"); @@ -87,14 +88,15 @@ async fn main() -> Result<(), Box> { keygen_n, signing_t, signing_n, - n_blocks, dummy_api_logger.clone(), + blocks_per_session, ); // first, spawn the orchestrator/mock-blockchain - let orchestrator_task = MockBlockchain::new(config, api.clone(), dummy_api_logger.clone()) - .await? - .execute(); + let orchestrator_task = + MockBlockchain::new(config, api.clone(), dummy_api_logger.clone(), blocks_per_session) + .await? + .execute(); let orchestrator_handle = tokio::task::spawn(orchestrator_task); // give time for the orchestrator to bind tokio::time::sleep(std::time::Duration::from_millis(1000)).await; diff --git a/parachain/runtime/rococo/src/lib.rs b/parachain/runtime/rococo/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/insert_keys.sh b/scripts/insert_keys.sh index 0d6031efa..219568dff 100755 --- a/scripts/insert_keys.sh +++ b/scripts/insert_keys.sh @@ -123,6 +123,7 @@ echo "\n ****************** NODE-3 KEY INSERTION ******************" --suri "gown surprise mirror hotel cash alarm raccoon you frog rose midnight enter//webb//2//dkg" \ --key-type wdkg +echo "node-3 keys inserted into path: ./tmp/standalone3 \n" echo "\n ****************** NODE-4 KEY INSERTION ******************" @@ -162,6 +163,8 @@ echo "\n ****************** NODE-4 KEY INSERTION ******************" --suri "gown surprise mirror hotel cash alarm raccoon you frog rose midnight enter//webb//3//dkg" \ --key-type wdkg +echo "node-4 keys inserted into path: ./tmp/standalone4 \n" + echo "\n ****************** NODE-5 KEY INSERTION ******************" ./target/release/dkg-standalone-node key insert --base-path ./tmp/standalone5 \ @@ -199,3 +202,5 @@ echo "\n ****************** NODE-5 KEY INSERTION ******************" --scheme Ecdsa \ --suri "gown surprise mirror hotel cash alarm raccoon you frog rose midnight enter//webb//4//dkg" \ --key-type wdkg + +echo "node-5 keys inserted into path: ./tmp/standalone5 \n" \ No newline at end of file