diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 3eb1e6e25..98c6e1e46 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -16,22 +16,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - + - name: Check markdown links uses: gaurav-nelson/github-action-markdown-link-check@v1 with: use-quiet-mode: 'yes' config-file: '.github/workflows/mlc_config.json' - # ensures proper license header - license-check: - name: license - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Check License Header - uses: apache/skywalking-eyes@main - with: - config: .licenserc.yaml # ensures build succeeds without warnings cargo-check: name: build @@ -46,7 +36,7 @@ jobs: - uses: actions/checkout@v2 - uses: hecrj/setup-rust-action@v1 - - run: cargo check --workspace --all-targets --verbose --no-default-features + - run: cargo check --workspace --verbose --no-default-features # ensures proper formatting and clippy lint lint-check: name: lint @@ -70,4 +60,4 @@ jobs: - name: Run Linters run: | cargo +nightly fmt --all -- --check - cargo clippy --workspace --all-targets --verbose --no-default-features -- -D warnings \ No newline at end of file + cargo clippy -Zunstable-options -- -D warnings diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 01cc5264b..a46da85cd 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -36,9 +36,6 @@ jobs: profile: minimal toolchain: nightly - - name: Build Standalone Node for Integration Tests (Release) - run: cargo build --release -p dkg-standalone-node --features integration-tests - - name: Install Nodejs uses: actions/setup-node@v2 with: @@ -49,6 +46,14 @@ jobs: - name: Install Packages run: cd dkg-test-suite && yarn + - name: Build Standalone Node for E2E Tests (Release) + run: cargo build --release -p dkg-standalone-node + - name: Run E2E Tests - run: cd dkg-test-suite && yarn test + run: cd dkg-test-suite && yarn test:e2e + + - name: Build Standalone Node for Integration Tests (Release) + run: cargo build --release -p dkg-standalone-node --features integration-tests + - name: Run Proposals E2E Tests + run: cd dkg-test-suite && yarn test:proposals diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 01c4a27fd..c3fd21312 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,14 +19,14 @@ jobs: uses: styfle/cancel-workflow-action@0.9.1 with: access_token: ${{ github.token }} - + - name: Checkout Sources uses: actions/checkout@v2 - name: Clear up disk space run: | sudo rm -rf "/usr/local/share/boost" - sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" sudo apt-get clean - name: Install cargo-nextest @@ -38,12 +38,14 @@ jobs: - name: Install Toolchain uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: nightly-2022-04-20 + components: rustfmt, clippy target: wasm32-unknown-unknown override: true + default: true - name: Rust Cache uses: Swatinem/rust-cache@v1.3.0 - name: Run tests - run: cargo nextest run \ No newline at end of file + run: cargo nextest run diff --git a/.gitignore b/.gitignore index e5b0a8e6e..492621830 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # These are backup files generated by rustfmt **/*.rs.bk +.idea .DS_Store # The cache for docker container dependency @@ -20,6 +21,11 @@ local-test **/node_modules/ para-2074-genesis para-2074-wasm +**/.idea/ +/.idea/ +/dkg-gadget/.idea/ +/DKG.iml + /scripts/seed-arana-testnet.sh *.txt diff --git a/Cargo.lock b/Cargo.lock index 29cf8f756..b4a8e049f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,9 +42,9 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cipher", - "cpufeatures 0.2.2", + "cpufeatures", "opaque-debug 0.3.0", ] @@ -68,7 +68,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.7", "once_cell", "version_check", ] @@ -82,26 +82,20 @@ dependencies = [ "memchr", ] -[[package]] -name = "always-assert" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf688625d06217d5b1bb0ea9d9c44a1635fd0ee3534466388d18203174f4d11" - [[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" [[package]] name = "approx" @@ -151,16 +145,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "async-channel" version = "1.6.1" @@ -188,14 +172,14 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.0.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026b7e44f1316b567ee750fea85103f87fcb80792b860e979f221259796ca0a" +checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" dependencies = [ "async-channel", "async-executor", "async-io", - "async-mutex", + "async-lock", "blocking", "futures-lite", "num_cpus", @@ -204,9 +188,9 @@ dependencies = [ [[package]] name = "async-io" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" +checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" dependencies = [ "concurrent-queue", "futures-lite", @@ -216,9 +200,9 @@ dependencies = [ "parking", "polling", "slab", - "socket2 0.4.4", + "socket2", "waker-fn", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -230,39 +214,29 @@ dependencies = [ "event-listener", ] -[[package]] -name = "async-mutex" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" -dependencies = [ - "event-listener", -] - [[package]] name = "async-process" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" +checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" dependencies = [ "async-io", "blocking", - "cfg-if 1.0.0", + "cfg-if", "event-listener", "futures-lite", "libc", "once_cell", "signal-hook", - "winapi 0.3.9", + "winapi", ] [[package]] name = "async-std" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ - "async-attributes", "async-channel", "async-global-executor", "async-io", @@ -277,9 +251,8 @@ dependencies = [ "kv-log-macro", "log", "memchr", - "num_cpus", "once_cell", - "pin-project-lite 0.2.8", + "pin-project-lite 0.2.9", "pin-utils", "slab", "wasm-bindgen-futures", @@ -287,23 +260,24 @@ dependencies = [ [[package]] name = "async-std-resolver" -version = "0.20.4" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf3e776afdf3a2477ef4854b85ba0dff3bd85792f685fb3c68948b4d304e4f0" +checksum = "0f2f8a4a203be3325981310ab243a28e6e4ea55b6519bffce05d41ab60e09ad8" dependencies = [ "async-std", "async-trait", "futures-io", "futures-util", "pin-utils", + "socket2", "trust-dns-resolver", ] [[package]] name = "async-stream" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" +checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" dependencies = [ "async-stream-impl", "futures-core", @@ -311,9 +285,9 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" +checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" dependencies = [ "proc-macro2", "quote", @@ -328,39 +302,26 @@ checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" [[package]] name = "async-trait" -version = "0.1.52" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "asynchronous-codec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4401f0a3622dad2e0763fa79e0eb328bc70fb7dccfdd645341f00d671247d6" -dependencies = [ - "bytes 1.1.0", - "futures-sink", - "futures-util", - "memchr", - "pin-project-lite 0.2.8", -] - [[package]] name = "asynchronous-codec" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0de5164e5edbf51c45fb8c2d9664ae1c095cce1b265ecf7569093c0d66ef690" dependencies = [ - "bytes 1.1.0", + "bytes", "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.8", + "pin-project-lite 0.2.9", ] [[package]] @@ -386,7 +347,19 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "auto_impl" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -406,24 +379,24 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" +checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.28.4", "rustc-demangle", ] [[package]] name = "base-x" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" [[package]] name = "base16ct" @@ -445,80 +418,23 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "base64ct" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71acf5509fc522cce1b100ac0121c635129bfd4d91cdf036bcc9b9935f97ccf5" +checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" [[package]] name = "beef" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bed554bd50246729a1ec158d08aa3235d1b69d94ad120ebe187e28894787e736" -dependencies = [ - "serde", -] - -[[package]] -name = "beefy-gadget" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "beefy-primitives", - "fnv", - "futures 0.3.21", - "log", - "parity-scale-codec", - "parking_lot 0.11.2", - "sc-chain-spec", - "sc-client-api", - "sc-keystore", - "sc-network", - "sc-network-gossip", - "sc-utils", - "sp-api", - "sp-application-crypto", - "sp-arithmetic", - "sp-blockchain", - "sp-core", - "sp-keystore", - "sp-runtime", - "substrate-prometheus-endpoint", - "thiserror", - "wasm-timer", -] - -[[package]] -name = "beefy-gadget-rpc" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" dependencies = [ - "beefy-gadget", - "beefy-primitives", - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "jsonrpc-pubsub", - "log", - "parity-scale-codec", - "parking_lot 0.11.2", - "sc-rpc", - "sc-utils", "serde", - "sp-core", - "sp-runtime", - "thiserror", ] -[[package]] -name = "beefy-merkle-tree" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" - [[package]] name = "beefy-primitives" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "scale-info", @@ -577,9 +493,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitvec" -version = "0.20.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" dependencies = [ "funty", "radium", @@ -589,13 +505,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.9.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest 0.10.3", ] [[package]] @@ -610,39 +524,37 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "0.5.11" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" dependencies = [ "arrayref", - "arrayvec 0.5.2", + "arrayvec 0.7.2", "constant_time_eq", ] [[package]] name = "blake2s_simd" -version = "0.5.11" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" +checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" dependencies = [ "arrayref", - "arrayvec 0.5.2", + "arrayvec 0.7.2", "constant_time_eq", ] [[package]] name = "blake3" -version = "0.3.8" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" +checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" dependencies = [ "arrayref", - "arrayvec 0.5.2", + "arrayvec 0.7.2", "cc", - "cfg-if 0.1.10", + "cfg-if", "constant_time_eq", - "crypto-mac 0.8.0", - "digest 0.9.0", ] [[package]] @@ -693,9 +605,9 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" +checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" dependencies = [ "async-channel", "async-task", @@ -705,165 +617,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "bounded-vec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b47cca82fca99417fe405f09d93bb8fff90bdd03d13c631f18096ee123b4281c" -dependencies = [ - "thiserror", -] - -[[package]] -name = "bp-header-chain" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "finality-grandpa", - "frame-support", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-finality-grandpa", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "bp-message-dispatch" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bp-runtime", - "frame-support", - "parity-scale-codec", - "scale-info", - "sp-std", -] - -[[package]] -name = "bp-messages" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bitvec", - "bp-runtime", - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "parity-scale-codec", - "scale-info", - "serde", - "sp-std", -] - -[[package]] -name = "bp-polkadot-core" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bp-messages", - "bp-runtime", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-core", - "sp-runtime", - "sp-std", - "sp-version", -] - -[[package]] -name = "bp-rococo" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bp-messages", - "bp-polkadot-core", - "bp-runtime", - "frame-support", - "parity-scale-codec", - "smallvec", - "sp-api", - "sp-runtime", - "sp-std", - "sp-version", -] - -[[package]] -name = "bp-runtime" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "frame-support", - "hash-db", - "num-traits", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", -] - -[[package]] -name = "bp-test-utils" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bp-header-chain", - "ed25519-dalek", - "finality-grandpa", - "parity-scale-codec", - "sp-application-crypto", - "sp-finality-grandpa", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "bp-wococo" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bp-messages", - "bp-polkadot-core", - "bp-rococo", - "bp-runtime", - "parity-scale-codec", - "sp-api", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "bridge-runtime-common" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bp-message-dispatch", - "bp-messages", - "bp-runtime", - "frame-support", - "hash-db", - "pallet-bridge-dispatch", - "pallet-bridge-grandpa", - "pallet-bridge-messages", - "pallet-transaction-payment", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", -] - [[package]] name = "bs58" version = "0.4.0" @@ -904,9 +657,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] name = "byte-slice-cast" @@ -928,19 +681,20 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "0.4.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] -name = "bytes" -version = "1.1.0" +name = "bzip2-sys" +version = "0.1.11+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] [[package]] name = "cache-padded" @@ -950,9 +704,9 @@ checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "camino" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23" +checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" dependencies = [ "serde", ] @@ -974,7 +728,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.6", + "semver 1.0.10", "serde", "serde_json", ] @@ -1012,58 +766,21 @@ dependencies = [ "nom", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - -[[package]] -name = "chacha20" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee7ad89dc1128635074c268ee661f90c3f7e83d9fd12910608c36b47d6c3412" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures 0.1.5", - "zeroize", -] - [[package]] name = "chacha20" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures 0.2.2", - "zeroize", -] - -[[package]] -name = "chacha20poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580317203210c517b6d44794abfbe600698276db18127e37ad3e69bf5e848e5" -dependencies = [ - "aead", - "chacha20 0.7.1", + "cfg-if", "cipher", - "poly1305", + "cpufeatures", "zeroize", ] @@ -1074,7 +791,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" dependencies = [ "aead", - "chacha20 0.8.1", + "chacha20", "cipher", "poly1305", "zeroize", @@ -1090,18 +807,20 @@ dependencies = [ "num-integer", "num-traits", "time", - "winapi 0.3.9", + "winapi", ] [[package]] name = "cid" -version = "0.6.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff0e3bc0b6446b3f9663c1a6aba6ef06c5aeaa1bc92bd18077be337198ab9768" +checksum = "fc949bff6704880faf064c42a4854032ab07bfcf3a4fcb82a57470acededb69c" dependencies = [ + "core2", "multibase", - "multihash 0.13.2", - "unsigned-varint 0.5.1", + "multihash", + "serde", + "unsigned-varint", ] [[package]] @@ -1113,20 +832,11 @@ dependencies = [ "generic-array 0.14.5", ] -[[package]] -name = "ckb-merkle-mountain-range" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f061f97d64fd1822664bdfb722f7ae5469a97b77567390f7442be5b5dc82a5b" -dependencies = [ - "cfg-if 0.1.10", -] - [[package]] name = "clang-sys" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" dependencies = [ "glob", "libc", @@ -1135,16 +845,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.6" +version = "3.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +checksum = "5b7b16274bb247b45177db843202209b12191b631a14a9d06e41b3777d6ecf14" dependencies = [ "atty", "bitflags", "clap_derive", + "clap_lex", "indexmap", - "lazy_static", - "os_str_bytes", + "once_cell", "strsim", "termcolor", "textwrap", @@ -1152,9 +862,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.4" +version = "3.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16" +checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -1163,6 +873,15 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -1172,6 +891,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "cmake" +version = "0.1.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +dependencies = [ + "cc", +] + +[[package]] +name = "comfy-table" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b103d85ca6e209388771bfb7aa6b68a7aeec4afbf6f0a0264bfbf50360e5212e" +dependencies = [ + "strum 0.23.0", + "strum_macros 0.23.1", + "unicode-width", +] + [[package]] name = "concurrent-queue" version = "1.2.2" @@ -1199,12 +938,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "core-foundation" version = "0.9.3" @@ -1222,21 +955,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] -name = "cpp_demangle" -version = "0.3.5" +name = "core2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" dependencies = [ - "cfg-if 1.0.0", + "memchr", ] [[package]] -name = "cpufeatures" -version = "0.1.5" +name = "cpp_demangle" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" dependencies = [ - "libc", + "cfg-if", ] [[package]] @@ -1250,18 +983,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62fc68cdb867b7d27b5f33cd65eb11376dfb41a2d09568a1a2c2bc1dc204f4ef" +checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31253a44ab62588f8235a996cc9b0636d98a299190069ced9628b8547329b47a" +checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" dependencies = [ "cranelift-bforest", "cranelift-codegen-meta", @@ -1276,33 +1009,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a20ab4627d30b702fb1b8a399882726d216b8164d3b3fa6189e3bf901506afe" +checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6687d9668dacfed4468361f7578d86bded8ca4db978f734d9b631494bebbb5b8" +checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" [[package]] name = "cranelift-entity" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77c5d72db97ba2cb36f69037a709edbae0d29cb25503775891e7151c5c874bf" +checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "426dca83f63c7c64ea459eb569aadc5e0c66536c0042ed5d693f91830e8750d0" +checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" dependencies = [ "cranelift-codegen", "log", @@ -1312,9 +1045,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8007864b5d0c49b026c861a15761785a2871124e401630c03ef1426e6d0d559e" +checksum = "501241b0cdf903412ec9075385ac9f2b1eb18a89044d1538e97fab603231f70c" dependencies = [ "cranelift-codegen", "libc", @@ -1323,9 +1056,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.80.1" +version = "0.82.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cf12c071415ba261d897387ae5350c4d83c238376c8c5a96514ecfa2ea66a3" +checksum = "16d9e4211bbc3268042a96dd4de5bd979cda22434991d035f5f8eacba987fad2" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1343,16 +1076,16 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -1362,32 +1095,33 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.7" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" dependencies = [ - "cfg-if 1.0.0", + "autocfg 1.1.0", + "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.7" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83" dependencies = [ - "cfg-if 1.0.0", - "lazy_static", + "cfg-if", + "once_cell", ] [[package]] @@ -1466,20 +1200,11 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e35f15e1a0699dd988fed910dd78fdc6407f44654cd12589c91fa44ea67d9159" -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct 0.6.1", -] - [[package]] name = "ctor" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" dependencies = [ "quote", "syn", @@ -1506,6756 +1231,4023 @@ dependencies = [ ] [[package]] -name = "cumulus-client-cli" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "curv-kzen" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc25c87ebf29b249e801de5eed820f0c9ba001054bf73008df884690a03e6eb" dependencies = [ - "clap", - "sc-cli", - "sc-service", + "cryptoxide", + "curve25519-dalek 3.2.0", + "digest 0.9.0", + "ff-zeroize", + "generic-array 0.14.5", + "hex", + "hmac 0.11.0", + "lazy_static", + "merkle-cbt", + "num-integer", + "num-traits", + "p256", + "pairing-plus", + "rand 0.6.5", + "rand 0.7.3", + "rust-gmp-kzen", + "secp256k1 0.20.3", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.8.2", + "sha2 0.9.9", + "sha3 0.9.1", + "thiserror", + "typenum", + "zeroize", ] [[package]] -name = "cumulus-client-collator" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" dependencies = [ - "cumulus-client-consensus-common", - "cumulus-client-network", - "cumulus-primitives-core", - "cumulus-relay-chain-interface", - "futures 0.3.21", - "parity-scale-codec", - "parking_lot 0.10.2", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-overseer", - "polkadot-primitives", - "sc-client-api", - "sp-api", - "sp-consensus", - "sp-core", - "sp-runtime", - "tracing", + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", ] [[package]] -name = "cumulus-client-consensus-aura" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ - "async-trait", - "cumulus-client-consensus-common", - "cumulus-primitives-core", - "futures 0.3.21", - "parity-scale-codec", - "sc-client-api", - "sc-consensus", - "sc-consensus-aura", - "sc-consensus-slots", - "sc-telemetry", - "sp-api", - "sp-application-crypto", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-keystore", - "sp-runtime", - "substrate-prometheus-endpoint", - "tracing", + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", ] [[package]] -name = "cumulus-client-consensus-common" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "curve25519-dalek" +version = "4.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4033478fbf70d6acf2655ac70da91ee65852d69daf7a67bf7a2f518fb47aafcf" dependencies = [ - "async-trait", - "cumulus-relay-chain-interface", - "dyn-clone", - "futures 0.3.21", - "parity-scale-codec", - "polkadot-primitives", - "sc-client-api", - "sc-consensus", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-runtime", - "sp-trie", - "tracing", + "byteorder", + "digest 0.9.0", + "rand_core 0.6.3", + "subtle 2.4.1", + "zeroize", ] [[package]] -name = "cumulus-client-network" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "data-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" + +[[package]] +name = "data-encoding-macro" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" dependencies = [ - "async-trait", - "cumulus-relay-chain-interface", - "derive_more", - "futures 0.3.21", - "futures-timer", - "parity-scale-codec", - "parking_lot 0.12.0", - "polkadot-node-primitives", - "polkadot-parachain", - "polkadot-primitives", - "sc-client-api", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", - "tracing", + "data-encoding", + "data-encoding-macro-internal", ] [[package]] -name = "cumulus-client-pov-recovery" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "data-encoding-macro-internal" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" dependencies = [ - "cumulus-primitives-core", - "cumulus-relay-chain-interface", - "futures 0.3.21", - "futures-timer", - "parity-scale-codec", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-overseer", - "polkadot-primitives", - "rand 0.8.5", - "sc-client-api", - "sc-consensus", - "sp-api", - "sp-consensus", - "sp-maybe-compressed-blob", - "sp-runtime", - "tracing", + "data-encoding", + "syn", ] [[package]] -name = "cumulus-client-service" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "der" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" dependencies = [ - "cumulus-client-collator", - "cumulus-client-consensus-common", - "cumulus-client-pov-recovery", - "cumulus-primitives-core", - "cumulus-relay-chain-interface", - "parity-scale-codec", - "parking_lot 0.12.0", - "polkadot-overseer", - "polkadot-primitives", - "sc-chain-spec", - "sc-client-api", - "sc-consensus", - "sc-consensus-babe", - "sc-service", - "sc-telemetry", - "sc-tracing", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-runtime", - "tracing", + "const-oid 0.6.2", ] [[package]] -name = "cumulus-pallet-aura-ext" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" -dependencies = [ - "frame-executive", - "frame-support", - "frame-system", - "pallet-aura", - "parity-scale-codec", - "scale-info", - "serde", - "sp-application-crypto", - "sp-consensus-aura", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "cumulus-pallet-dmp-queue" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ - "cumulus-primitives-core", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", - "xcm-executor", + "const-oid 0.7.1", ] [[package]] -name = "cumulus-pallet-parachain-system" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "cumulus-pallet-parachain-system-proc-macro", - "cumulus-primitives-core", - "cumulus-primitives-parachain-inherent", - "environmental", - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "log", - "pallet-balances", - "parity-scale-codec", - "polkadot-parachain", - "scale-info", - "serde", - "sp-core", - "sp-externalities", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", - "sp-version", - "xcm", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "cumulus-pallet-parachain-system-proc-macro" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ - "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn", ] [[package]] -name = "cumulus-pallet-xcm" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "cumulus-primitives-core", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "serde", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", + "generic-array 0.12.4", ] [[package]] -name = "cumulus-pallet-xcmp-queue" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "cumulus-primitives-core", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "rand_chacha 0.3.1", - "scale-info", - "sp-runtime", - "sp-std", - "xcm", - "xcm-executor", + "generic-array 0.14.5", ] [[package]] -name = "cumulus-primitives-core" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "frame-support", - "parity-scale-codec", - "polkadot-core-primitives", - "polkadot-parachain", - "polkadot-primitives", - "sp-api", - "sp-runtime", - "sp-std", - "sp-trie", + "block-buffer 0.10.2", + "crypto-common", + "subtle 2.4.1", ] [[package]] -name = "cumulus-primitives-parachain-inherent" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" dependencies = [ - "async-trait", - "cumulus-primitives-core", - "cumulus-relay-chain-interface", - "cumulus-test-relay-sproof-builder", - "parity-scale-codec", - "sc-client-api", - "scale-info", - "sp-api", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-storage", - "sp-trie", - "tracing", + "dirs-sys", ] [[package]] -name = "cumulus-primitives-timestamp" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" dependencies = [ - "cumulus-primitives-core", - "sp-inherents", - "sp-std", - "sp-timestamp", + "cfg-if", + "dirs-sys-next", ] [[package]] -name = "cumulus-primitives-utility" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ - "cumulus-primitives-core", - "frame-support", - "parity-scale-codec", - "polkadot-core-primitives", - "polkadot-parachain", - "polkadot-primitives", - "sp-runtime", - "sp-std", - "sp-trie", - "xcm", + "libc", + "redox_users", + "winapi", ] [[package]] -name = "cumulus-relay-chain-interface" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dkg-gadget" +version = "0.0.1" dependencies = [ "async-trait", - "cumulus-primitives-core", - "derive_more", - "futures 0.3.21", - "parking_lot 0.12.0", - "polkadot-overseer", + "atomic", + "auto_impl", + "curv-kzen", + "dkg-primitives", + "dkg-runtime-primitives", + "env_logger", + "fnv", + "futures", + "hex", + "itertools 0.10.3", + "libsecp256k1 0.3.5", + "linked-hash-map", + "log", + "lru", + "multi-party-ecdsa", + "parity-scale-codec", + "parking_lot 0.11.2", + "rand 0.8.5", + "round-based", + "rstest", "sc-client-api", + "sc-keystore", + "sc-network", + "sc-network-test", + "sc-peerset", "sc-service", + "scale-info", + "serde", + "serde_json", + "sha3 0.9.1", "sp-api", + "sp-application-crypto", + "sp-arithmetic", "sp-blockchain", "sp-core", + "sp-io", + "sp-keystore", "sp-runtime", - "sp-state-machine", + "strum 0.21.0", + "substrate-prometheus-endpoint", "thiserror", + "tokio", + "tokio-stream", + "wasm-timer", ] [[package]] -name = "cumulus-relay-chain-local" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "dkg-primitives" +version = "0.0.1" dependencies = [ - "async-trait", - "cumulus-primitives-core", - "cumulus-relay-chain-interface", - "futures 0.3.21", - "futures-timer", - "parking_lot 0.12.0", - "polkadot-client", - "polkadot-service", - "sc-client-api", - "sc-consensus-babe", - "sc-network", + "chacha20poly1305", + "curv-kzen", + "dkg-runtime-primitives", + "fnv", + "futures", + "hex", + "libsecp256k1 0.3.5", + "log", + "multi-party-ecdsa", + "parity-scale-codec", + "parking_lot 0.11.2", + "rand 0.8.5", + "round-based", + "sc-keystore", "sc-service", - "sc-telemetry", - "sc-tracing", - "sp-api", - "sp-blockchain", - "sp-consensus", + "serde", + "serde_json", + "sha3 0.9.1", "sp-core", + "sp-keyring", + "sp-keystore", "sp-runtime", - "sp-state-machine", - "tracing", + "thiserror", + "typed-builder 0.9.1", + "wasm-timer", ] [[package]] -name = "cumulus-test-relay-sproof-builder" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "dkg-runtime-primitives" +version = "0.0.1" dependencies = [ - "cumulus-primitives-core", + "ethereum", + "ethereum-types", + "frame-support", + "frame-system", + "hex", + "impl-trait-for-tuples", "parity-scale-codec", - "polkadot-primitives", + "scale-info", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-io", "sp-runtime", - "sp-state-machine", "sp-std", + "tiny-keccak", + "webb-proposals", ] [[package]] -name = "curv-kzen" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc25c87ebf29b249e801de5eed820f0c9ba001054bf73008df884690a03e6eb" +name = "dkg-standalone-node" +version = "3.0.0" dependencies = [ - "cryptoxide", - "curve25519-dalek 3.2.0", - "digest 0.9.0", - "ff-zeroize", - "generic-array 0.14.5", - "hex", - "hmac 0.11.0", - "lazy_static", - "merkle-cbt", - "num-integer", - "num-traits", - "p256", - "pairing-plus", - "rand 0.6.5", + "clap", + "dkg-gadget", + "dkg-primitives", + "dkg-runtime-primitives", + "dkg-standalone-runtime", + "frame-benchmarking", + "frame-benchmarking-cli", + "frame-system", + "futures", + "hex-literal", + "jsonrpsee", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc", + "parity-scale-codec", "rand 0.7.3", - "rust-gmp-kzen", - "secp256k1", - "serde", - "serde_bytes", - "serde_derive", - "sha2 0.8.2", - "sha2 0.9.9", - "sha3", - "thiserror", - "typenum", - "zeroize", + "sc-basic-authorship", + "sc-cli", + "sc-client-api", + "sc-consensus", + "sc-consensus-aura", + "sc-consensus-manual-seal", + "sc-executor", + "sc-finality-grandpa", + "sc-keystore", + "sc-network", + "sc-rpc", + "sc-rpc-api", + "sc-service", + "sc-telemetry", + "sc-transaction-pool", + "sc-transaction-pool-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-aura", + "sp-core", + "sp-finality-grandpa", + "sp-inherents", + "sp-keyring", + "sp-keystore", + "sp-runtime", + "sp-timestamp", + "substrate-build-script-utils", + "substrate-frame-rpc-system", ] [[package]] -name = "curve25519-dalek" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +name = "dkg-standalone-runtime" +version = "3.0.0" dependencies = [ - "byteorder", - "digest 0.8.1", - "rand_core 0.5.1", - "subtle 2.4.1", - "zeroize", + "dkg-runtime-primitives", + "frame-benchmarking", + "frame-election-provider-support", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "hex-literal", + "pallet-aura", + "pallet-bags-list", + "pallet-balances", + "pallet-dkg-metadata", + "pallet-dkg-proposal-handler", + "pallet-dkg-proposals", + "pallet-election-provider-multi-phase", + "pallet-grandpa", + "pallet-indices", + "pallet-nomination-pools", + "pallet-randomness-collective-flip", + "pallet-session", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-block-builder", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-io", + "sp-npos-elections", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder", ] [[package]] -name = "curve25519-dalek" -version = "3.2.0" +name = "dns-parser" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" dependencies = [ "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle 2.4.1", - "zeroize", + "quick-error", ] [[package]] -name = "data-encoding" -version = "2.3.2" +name = "downcast-rs" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] -name = "data-encoding-macro" -version = "0.1.12" +name = "dtoa" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" -dependencies = [ - "data-encoding", - "data-encoding-macro-internal", -] +checksum = "5caaa75cbd2b960ff1e5392d2cfb1f44717fffe12fc1f32b7b5d1267f99732a6" [[package]] -name = "data-encoding-macro-internal" -version = "0.1.10" +name = "dyn-clonable" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" dependencies = [ - "data-encoding", - "syn", + "dyn-clonable-impl", + "dyn-clone", ] [[package]] -name = "der" -version = "0.4.5" +name = "dyn-clonable-impl" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" dependencies = [ - "const-oid 0.6.2", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "der" -version = "0.5.1" +name = "dyn-clone" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid 0.7.1", -] +checksum = "140206b78fb2bc3edbcfc9b5ccbd0b30699cfe8d348b8b31b330e47df5291a5a" [[package]] -name = "derivative" -version = "2.2.0" +name = "ecdsa" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" dependencies = [ - "proc-macro2", - "quote", - "syn", + "der 0.4.5", + "elliptic-curve 0.10.6", + "hmac 0.11.0", + "signature", ] [[package]] -name = "derive_more" -version = "0.99.17" +name = "ecdsa" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn", + "der 0.5.1", + "elliptic-curve 0.11.12", + "rfc6979", + "signature", ] [[package]] -name = "digest" -version = "0.8.1" +name = "ed25519" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" dependencies = [ - "generic-array 0.12.4", + "signature", ] [[package]] -name = "digest" -version = "0.9.0" +name = "ed25519-dalek" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "generic-array 0.14.5", + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", ] [[package]] -name = "digest" -version = "0.10.3" +name = "either" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer 0.10.2", - "crypto-common", -] +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] -name = "directories" -version = "4.0.1" +name = "elliptic-curve" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" dependencies = [ - "dirs-sys", + "crypto-bigint 0.2.11", + "ff 0.10.1", + "generic-array 0.14.5", + "group 0.10.0", + "pkcs8 0.7.6", + "rand_core 0.6.3", + "subtle 2.4.1", + "zeroize", ] [[package]] -name = "directories-next" -version = "2.0.0" +name = "elliptic-curve" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", + "base16ct", + "crypto-bigint 0.3.2", + "der 0.5.1", + "ff 0.11.1", + "generic-array 0.14.5", + "group 0.11.0", + "rand_core 0.6.3", + "sec1", + "subtle 2.4.1", + "zeroize", ] [[package]] -name = "dirs-sys" -version = "0.3.6" +name = "enum-as-inner" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" dependencies = [ - "libc", - "redox_users", - "winapi 0.3.9", + "heck 0.4.0", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi 0.3.9", -] - -[[package]] -name = "dkg-gadget" -version = "0.0.1" -dependencies = [ - "curv-kzen", - "dkg-primitives", - "dkg-runtime-primitives", - "fnv", - "futures 0.3.21", - "hex", - "libsecp256k1 0.3.5", - "log", - "multi-party-ecdsa", - "parity-scale-codec", - "parking_lot 0.11.2", - "rand 0.8.5", - "round-based", - "sc-client-api", - "sc-keystore", - "sc-network", - "sc-network-gossip", - "sc-network-test", - "sc-service", - "scale-info", - "serde", - "sha3", - "sp-api", - "sp-application-crypto", - "sp-arithmetic", - "sp-blockchain", - "sp-core", - "sp-io", - "sp-keystore", - "sp-runtime", - "strum 0.21.0", - "substrate-prometheus-endpoint", - "thiserror", - "wasm-timer", -] - -[[package]] -name = "dkg-node" -version = "3.0.0" -dependencies = [ - "clap", - "cumulus-client-cli", - "cumulus-client-collator", - "cumulus-client-consensus-aura", - "cumulus-client-consensus-common", - "cumulus-client-network", - "cumulus-client-service", - "cumulus-primitives-core", - "cumulus-primitives-parachain-inherent", - "cumulus-relay-chain-interface", - "cumulus-relay-chain-local", - "derive_more", - "dkg-gadget", - "dkg-primitives", - "dkg-runtime", - "dkg-runtime-primitives", - "frame-benchmarking", - "frame-benchmarking-cli", - "hex-literal", - "jsonrpc-core", - "log", - "pallet-collator-selection", - "pallet-transaction-payment-rpc", - "parity-scale-codec", - "polkadot-cli", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-service", - "polkadot-test-service", - "sc-basic-authorship", - "sc-chain-spec", - "sc-cli", - "sc-client-api", - "sc-consensus", - "sc-executor", - "sc-keystore", - "sc-network", - "sc-rpc", - "sc-rpc-api", - "sc-service", - "sc-telemetry", - "sc-tracing", - "sc-transaction-pool", - "serde", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-keystore", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-timestamp", - "sp-transaction-pool", - "substrate-build-script-utils", - "substrate-frame-rpc-system", - "substrate-prometheus-endpoint", -] - -[[package]] -name = "dkg-primitives" -version = "0.0.1" -dependencies = [ - "chacha20poly1305 0.9.0", - "curv-kzen", - "dkg-runtime-primitives", - "fnv", - "futures 0.3.21", - "hex", - "libsecp256k1 0.3.5", - "log", - "multi-party-ecdsa", - "parity-scale-codec", - "parking_lot 0.11.2", - "rand 0.8.5", - "round-based", - "sc-keystore", - "sc-service", - "serde", - "serde_json", - "sha3", - "sp-core", - "sp-keyring", - "sp-keystore", - "sp-runtime", - "thiserror", - "typed-builder", - "wasm-timer", -] - -[[package]] -name = "dkg-runtime" -version = "3.0.0" -dependencies = [ - "cumulus-pallet-aura-ext", - "cumulus-pallet-dmp-queue", - "cumulus-pallet-parachain-system", - "cumulus-pallet-xcm", - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-core", - "cumulus-primitives-timestamp", - "cumulus-primitives-utility", - "dkg-runtime-primitives", - "frame-benchmarking", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "hex-literal", - "log", - "pallet-aura", - "pallet-authorship", - "pallet-balances", - "pallet-collator-selection", - "pallet-dkg-metadata", - "pallet-dkg-proposal-handler", - "pallet-dkg-proposals", - "pallet-randomness-collective-flip", - "pallet-session", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-xcm", - "parachain-info", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-runtime-common", - "scale-info", - "serde", - "smallvec", - "sp-api", - "sp-block-builder", - "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-io", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-executor", -] - -[[package]] -name = "dkg-runtime-primitives" -version = "0.0.1" -dependencies = [ - "ethereum", - "ethereum-types", - "frame-support", - "frame-system", - "hex", - "impl-trait-for-tuples", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "tiny-keccak", - "webb-proposals", -] - -[[package]] -name = "dkg-standalone-node" -version = "3.0.0" -dependencies = [ - "clap", - "dkg-gadget", - "dkg-primitives", - "dkg-runtime-primitives", - "dkg-standalone-runtime", - "frame-benchmarking", - "frame-benchmarking-cli", - "futures 0.3.21", - "hex-literal", - "jsonrpc-core", - "pallet-transaction-payment-rpc", - "parity-scale-codec", - "rand 0.7.3", - "sc-basic-authorship", - "sc-cli", - "sc-client-api", - "sc-consensus", - "sc-consensus-aura", - "sc-consensus-manual-seal", - "sc-executor", - "sc-finality-grandpa", - "sc-keystore", - "sc-network", - "sc-rpc", - "sc-rpc-api", - "sc-service", - "sc-telemetry", - "sc-transaction-pool", - "sc-transaction-pool-api", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-consensus-aura", - "sp-core", - "sp-finality-grandpa", - "sp-inherents", - "sp-keystore", - "sp-runtime", - "sp-timestamp", - "substrate-build-script-utils", - "substrate-frame-rpc-system", -] - -[[package]] -name = "dkg-standalone-runtime" -version = "3.0.0" -dependencies = [ - "dkg-runtime-primitives", - "frame-benchmarking", - "frame-election-provider-support", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "hex-literal", - "pallet-aura", - "pallet-balances", - "pallet-dkg-metadata", - "pallet-dkg-proposal-handler", - "pallet-dkg-proposals", - "pallet-election-provider-multi-phase", - "pallet-grandpa", - "pallet-randomness-collective-flip", - "pallet-session", - "pallet-staking", - "pallet-staking-reward-curve", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-block-builder", - "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-io", - "sp-npos-elections", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", -] - -[[package]] -name = "dns-parser" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" -dependencies = [ - "byteorder", - "quick-error 1.2.3", -] - -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - -[[package]] -name = "dyn-clonable" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" -dependencies = [ - "dyn-clonable-impl", - "dyn-clone", -] - -[[package]] -name = "dyn-clonable-impl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dyn-clone" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" - -[[package]] -name = "ecdsa" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" -dependencies = [ - "der 0.4.5", - "elliptic-curve 0.10.6", - "hmac 0.11.0", - "signature", -] - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der 0.5.1", - "elliptic-curve 0.11.12", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d5c4b5e5959dc2c2b89918d8e2cc40fcdd623cef026ed09d2f0ee05199dc8e4" -dependencies = [ - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek 3.2.0", - "ed25519", - "rand 0.7.3", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" -dependencies = [ - "crypto-bigint 0.2.11", - "ff 0.10.1", - "generic-array 0.14.5", - "group 0.10.0", - "pkcs8 0.7.6", - "rand_core 0.6.3", - "subtle 2.4.1", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint 0.3.2", - "der 0.5.1", - "ff 0.11.0", - "generic-array 0.14.5", - "group 0.11.0", - "rand_core 0.6.3", - "sec1", - "subtle 2.4.1", - "zeroize", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570d109b813e904becc80d8d5da38376818a143348413f7149f1340fe04754d4" -dependencies = [ - "heck 0.4.0", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "enumflags2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" -dependencies = [ - "enumflags2_derive", -] - -[[package]] -name = "enumflags2_derive" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "enumn" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e58b112d5099aa0857c5d05f0eacab86406dd8c0f85fe5d320a13256d29ecf4" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "environmental" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" - -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "ethbloom" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb684ac8fa8f6c5759f788862bb22ec6fe3cb392f6bfd08e3c64b603661e3f8" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-codec", - "impl-rlp", - "scale-info", - "tiny-keccak", -] - -[[package]] -name = "ethereum" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a67be3eaf296ef668733f54c637e84d0ca34eaf194f0077455135981ad464c3" -dependencies = [ - "bytes 1.1.0", - "ethereum-types", - "hash-db", - "hash256-std-hasher", - "parity-scale-codec", - "rlp", - "rlp-derive", - "sha3", - "triehash", -] - -[[package]] -name = "ethereum-types" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05136f7057fe789f06e6d41d07b34e6f70d8c86e5693b60f97aaa6553553bdaf" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-codec", - "impl-rlp", - "primitive-types", - "scale-info", - "uint", -] - -[[package]] -name = "event-listener" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" - -[[package]] -name = "exit-future" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" -dependencies = [ - "futures 0.3.21", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "fdlimit" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" -dependencies = [ - "libc", -] - -[[package]] -name = "ff" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" -dependencies = [ - "rand_core 0.6.3", - "subtle 2.4.1", -] - -[[package]] -name = "ff" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" -dependencies = [ - "rand_core 0.6.3", - "subtle 2.4.1", -] - -[[package]] -name = "ff-zeroize" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02169a2e8515aa316ce516eaaf6318a76617839fbf904073284bc2576b029ee" -dependencies = [ - "byteorder", - "ff_derive-zeroize", - "rand_core 0.5.1", - "zeroize", -] - -[[package]] -name = "ff_derive-zeroize" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24d4059bc0d0a0bf26b740aa21af1f96a984f0ab7a21356d00b32475388b53a" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "file-per-thread-logger" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e16290574b39ee41c71aeb90ae960c504ebaf1e2a1c87bd52aa56ed6e1a02f" -dependencies = [ - "env_logger", - "log", -] - -[[package]] -name = "finality-grandpa" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ac3ff5224ef91f3c97e03eb1de2db82743427e91aaa5ac635f454f0b164f5a" -dependencies = [ - "either", - "futures 0.3.21", - "futures-timer", - "log", - "num-traits", - "parity-scale-codec", - "parking_lot 0.11.2", - "scale-info", -] - -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fixedbitset" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "libz-sys", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "fork-tree" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding 2.1.0", -] - -[[package]] -name = "frame-benchmarking" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-support", - "frame-system", - "linregress", - "log", - "parity-scale-codec", - "paste", - "scale-info", - "serde", - "sp-api", - "sp-application-crypto", - "sp-io", - "sp-runtime", - "sp-runtime-interface", - "sp-std", - "sp-storage", -] - -[[package]] -name = "frame-benchmarking-cli" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "Inflector", - "chrono", - "clap", - "frame-benchmarking", - "frame-support", - "handlebars", - "linked-hash-map", - "log", - "parity-scale-codec", - "sc-cli", - "sc-client-db", - "sc-executor", - "sc-service", - "serde", - "serde_json", - "sp-core", - "sp-externalities", - "sp-keystore", - "sp-runtime", - "sp-state-machine", -] - -[[package]] -name = "frame-election-provider-support" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-arithmetic", - "sp-npos-elections", - "sp-std", -] - -[[package]] -name = "frame-executive" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", -] - -[[package]] -name = "frame-metadata" -version = "14.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ed5e5c346de62ca5c184b4325a6600d1eaca210666e4606fe4e449574978d0" -dependencies = [ - "cfg-if 1.0.0", - "parity-scale-codec", - "scale-info", - "serde", -] - -[[package]] -name = "frame-support" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "bitflags", - "frame-metadata", - "frame-support-procedural", - "impl-trait-for-tuples", - "log", - "once_cell", - "parity-scale-codec", - "paste", - "scale-info", - "serde", - "smallvec", - "sp-arithmetic", - "sp-core", - "sp-core-hashing-proc-macro", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-state-machine", - "sp-std", - "sp-tracing", - "tt-call", -] - -[[package]] -name = "frame-support-procedural" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "Inflector", - "frame-support-procedural-tools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "frame-support-procedural-tools" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-support-procedural-tools-derive", - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "frame-support-procedural-tools-derive" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "frame-system" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-support", - "log", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-version", -] - -[[package]] -name = "frame-system-benchmarking" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "frame-system-rpc-runtime-api" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "parity-scale-codec", - "sp-api", -] - -[[package]] -name = "frame-try-runtime" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-support", - "sp-api", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "fs-err" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd79fa345a495d3ae89fb7165fec01c0e72f41821d642dda363a1e97975652e" - -[[package]] -name = "fs-swap" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d47dad3685eceed8488986cad3d5027165ea5edb164331770e2059555f10a5" -dependencies = [ - "lazy_static", - "libc", - "libloading 0.5.2", - "winapi 0.3.9", -] - -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - -[[package]] -name = "futures" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-executor" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" - -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite 0.2.8", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-rustls" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1387e07917c711fb4ee4f48ea0adb04a3c9739e53ef85bf43ae1edc2937a8b" -dependencies = [ - "futures-io", - "rustls 0.19.1", - "webpki 0.21.4", -] - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-timer" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures 0.1.31", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite 0.2.8", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", -] - -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug 0.3.0", - "polyval", -] - -[[package]] -name = "gimli" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" -dependencies = [ - "fallible-iterator", - "indexmap", - "stable_deref_trait", -] - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "globset" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" -dependencies = [ - "aho-corasick", - "bstr", - "fnv", - "log", - "regex", -] - -[[package]] -name = "gloo-timers" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d12a7f4e95cfe710f1d624fb1210b7d961a5fb05c4fd942f4feab06e61f590e" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "group" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" -dependencies = [ - "ff 0.10.1", - "rand_core 0.6.3", - "subtle 2.4.1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff 0.11.0", - "rand_core 0.6.3", - "subtle 2.4.1", -] - -[[package]] -name = "h2" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62eeb471aa3e3c9197aa4bfeabfe02982f6dc96f750486c0bb0009ac58b26d2b" -dependencies = [ - "bytes 1.1.0", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "handlebars" -version = "4.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d6a30320f094710245150395bc763ad23128d6a1ebbad7594dc4164b62c56b" -dependencies = [ - "log", - "pest", - "pest_derive", - "quick-error 2.0.1", - "serde", - "serde_json", -] - -[[package]] -name = "hash-db" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" - -[[package]] -name = "hash256-std-hasher" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" -dependencies = [ - "crunchy", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c21d40587b92fa6a6c6e3c1bdbf87d75511db5672f9c93175574b3a00df1758" -dependencies = [ - "ahash", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hex-literal" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" - -[[package]] -name = "hex_fmt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" - -[[package]] -name = "hmac" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -dependencies = [ - "crypto-mac 0.7.0", - "digest 0.8.1", -] - -[[package]] -name = "hmac" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.1", - "digest 0.9.0", -] - -[[package]] -name = "hmac-drbg" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" -dependencies = [ - "digest 0.8.1", - "generic-array 0.12.4", - "hmac 0.7.1", -] - -[[package]] -name = "hmac-drbg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" -dependencies = [ - "digest 0.9.0", - "generic-array 0.14.5", - "hmac 0.8.1", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - -[[package]] -name = "http" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" -dependencies = [ - "bytes 1.1.0", - "fnv", - "itoa 1.0.1", -] - -[[package]] -name = "http-body" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" -dependencies = [ - "bytes 1.1.0", - "http", - "pin-project-lite 0.2.8", -] - -[[package]] -name = "httparse" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043f0e083e9901b6cc658a77d1eb86f4fc650bbb977a4337dd63192826aa85dd" -dependencies = [ - "bytes 1.1.0", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa 1.0.1", - "pin-project-lite 0.2.8", - "socket2 0.4.4", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" -dependencies = [ - "ct-logs", - "futures-util", - "hyper", - "log", - "rustls 0.19.1", - "rustls-native-certs 0.5.0", - "tokio", - "tokio-rustls 0.22.0", - "webpki 0.21.4", -] - -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "if-addrs" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2273e421f7c4f0fc99e1934fe4776f59d8df2972f4199d703fc0da9f2a9f73de" -dependencies = [ - "if-addrs-sys", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "if-addrs-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de74b9dd780476e837e5eb5ab7c88b49ed304126e412030a0adba99c8efe79ea" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "if-watch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8ab7f67bad3240049cb24fb9cb0b4c2c6af4c245840917fbbdededeee91179" -dependencies = [ - "async-io", - "futures 0.3.21", - "futures-lite", - "if-addrs", - "ipnet", - "libc", - "log", - "winapi 0.3.9", -] - -[[package]] -name = "impl-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "indexmap" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" -dependencies = [ - "autocfg 1.1.0", - "hashbrown 0.11.2", - "serde", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "integer-encoding" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e85a1509a128c855368e135cffcde7eac17d8e1083f41e2b98c58bc1a5074be" - -[[package]] -name = "integer-sqrt" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" -dependencies = [ - "num-traits", -] - -[[package]] -name = "io-lifetimes" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ef6787e7f0faedc040f95716bdd0e62bcfcf4ba93da053b62dea2691c13864" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ip_network" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" - -[[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2 0.3.19", - "widestring", - "winapi 0.3.9", - "winreg", -] - -[[package]] -name = "ipnet" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e70ee094dc02fd9c13fdad4940090f22dbd6ac7c9e7094a46cf0232a50bc7c" - -[[package]] -name = "itertools" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "jobserver" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpc-client-transports" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a" -dependencies = [ - "derive_more", - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-pubsub", - "log", - "serde", - "serde_json", - "url 1.7.2", -] - -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures 0.3.21", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "jsonrpc-core-client" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0" -dependencies = [ - "futures 0.3.21", - "jsonrpc-client-transports", -] - -[[package]] -name = "jsonrpc-derive" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2" -dependencies = [ - "proc-macro-crate 0.1.5", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "jsonrpc-http-server" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1dea6e07251d9ce6a552abfb5d7ad6bc290a4596c8dcc3d795fae2bbdc1f3ff" -dependencies = [ - "futures 0.3.21", - "hyper", - "jsonrpc-core", - "jsonrpc-server-utils", - "log", - "net2", - "parking_lot 0.11.2", - "unicase", -] - -[[package]] -name = "jsonrpc-ipc-server" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845" -dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-server-utils", - "log", - "parity-tokio-ipc", - "parking_lot 0.11.2", - "tower-service", -] - -[[package]] -name = "jsonrpc-pubsub" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011" -dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "lazy_static", - "log", - "parking_lot 0.11.2", - "rand 0.7.3", - "serde", -] - -[[package]] -name = "jsonrpc-server-utils" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4" -dependencies = [ - "bytes 1.1.0", - "futures 0.3.21", - "globset", - "jsonrpc-core", - "lazy_static", - "log", - "tokio", - "tokio-stream", - "tokio-util", - "unicase", -] - -[[package]] -name = "jsonrpc-ws-server" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f892c7d766369475ab7b0669f417906302d7c0fb521285c0a0c92e52e7c8e946" -dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-server-utils", - "log", - "parity-ws", - "parking_lot 0.11.2", - "slab", -] - -[[package]] -name = "jsonrpsee" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373a33d987866ccfe1af4bc11b089dce941764313f9fd8b7cf13fcb51b72dc5" -dependencies = [ - "jsonrpsee-types 0.4.1", - "jsonrpsee-utils", - "jsonrpsee-ws-client 0.4.1", -] - -[[package]] -name = "jsonrpsee" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05fd8cd6c6b1bbd06881d2cf88f1fc83cc36c98f2219090f839115fb4a956cb9" -dependencies = [ - "jsonrpsee-core", - "jsonrpsee-proc-macros", - "jsonrpsee-types 0.8.0", - "jsonrpsee-ws-client 0.8.0", -] - -[[package]] -name = "jsonrpsee-client-transport" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3303cdf246e6ab76e2866fb3d9acb6c76a068b1b28bd923a1b7a8122257ad7b5" -dependencies = [ - "futures 0.3.21", - "http", - "jsonrpsee-core", - "jsonrpsee-types 0.8.0", - "pin-project 1.0.10", - "rustls-native-certs 0.6.1", - "soketto", - "thiserror", - "tokio", - "tokio-rustls 0.23.3", - "tokio-util", - "tracing", - "webpki-roots 0.22.2", -] - -[[package]] -name = "jsonrpsee-core" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f220b5a238dc7992b90f1144fbf6eaa585872c9376afe6fe6863ffead6191bf3" -dependencies = [ - "anyhow", - "arrayvec 0.7.2", - "async-trait", - "beef", - "futures-channel", - "futures-util", - "hyper", - "jsonrpsee-types 0.8.0", - "rustc-hash", - "serde", - "serde_json", - "soketto", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "jsonrpsee-proc-macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4299ebf790ea9de1cb72e73ff2ae44c723ef264299e5e2d5ef46a371eb3ac3d8" -dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "jsonrpsee-types" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f778cf245158fbd8f5d50823a2e9e4c708a40be164766bd35e9fb1d86715b2" -dependencies = [ - "anyhow", - "async-trait", - "beef", - "futures-channel", - "futures-util", - "hyper", - "log", - "serde", - "serde_json", - "soketto", - "thiserror", -] - -[[package]] -name = "jsonrpsee-types" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b3f601bbbe45cd63f5407b6f7d7950e08a7d4f82aa699ff41a4a5e9e54df58" -dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", - "tracing", -] - -[[package]] -name = "jsonrpsee-utils" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0109c4f972058f3b1925b73a17210aff7b63b65967264d0045d15ee88fe84f0c" -dependencies = [ - "arrayvec 0.7.2", - "beef", - "jsonrpsee-types 0.4.1", -] - -[[package]] -name = "jsonrpsee-ws-client" -version = "0.4.1" +name = "env_logger" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559aa56fc402af206c00fc913dc2be1d9d788dcde045d14df141a535245d35ef" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ - "arrayvec 0.7.2", - "async-trait", - "fnv", - "futures 0.3.21", - "http", - "jsonrpsee-types 0.4.1", + "atty", + "humantime", "log", - "pin-project 1.0.10", - "rustls-native-certs 0.5.0", - "serde", - "serde_json", - "soketto", - "thiserror", - "tokio", - "tokio-rustls 0.22.0", - "tokio-util", + "regex", + "termcolor", ] [[package]] -name = "jsonrpsee-ws-client" -version = "0.8.0" +name = "environmental" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aff425cee7c779e33920913bc695447416078ee6d119f443f3060feffa4e86b5" -dependencies = [ - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types 0.8.0", -] +checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" [[package]] -name = "k256" -version = "0.10.2" +name = "errno" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cc5937366afd3b38071f400d1ce5bd8b1d40b5083cc14e6f8dbcc4032a7f5bb" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" dependencies = [ - "cfg-if 1.0.0", - "ecdsa 0.13.4", - "elliptic-curve 0.11.12", - "sec1", + "errno-dragonfly", + "libc", + "winapi", ] [[package]] -name = "keccak" -version = "0.1.0" +name = "errno-dragonfly" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] [[package]] -name = "kernel32-sys" -version = "0.2.2" +name = "ethbloom" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "scale-info", + "tiny-keccak", ] [[package]] -name = "kusama-runtime" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "ethereum" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23750149fe8834c0e24bb9adcbacbe06c45b9861f15df53e09f26cb7c4ab91ef" dependencies = [ - "beefy-primitives", - "bitvec", - "frame-benchmarking", - "frame-election-provider-support", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "frame-try-runtime", - "hex-literal", - "kusama-runtime-constants", - "log", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-bags-list", - "pallet-balances", - "pallet-bounties", - "pallet-collective", - "pallet-democracy", - "pallet-election-provider-multi-phase", - "pallet-elections-phragmen", - "pallet-gilt", - "pallet-grandpa", - "pallet-identity", - "pallet-im-online", - "pallet-indices", - "pallet-membership", - "pallet-mmr-primitives", - "pallet-multisig", - "pallet-nicks", - "pallet-offences", - "pallet-offences-benchmarking", - "pallet-preimage", - "pallet-proxy", - "pallet-recovery", - "pallet-scheduler", - "pallet-session", - "pallet-session-benchmarking", - "pallet-society", - "pallet-staking", - "pallet-staking-reward-fn", - "pallet-timestamp", - "pallet-tips", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-treasury", - "pallet-utility", - "pallet-vesting", - "pallet-xcm", + "bytes", + "ethereum-types", + "hash-db", + "hash256-std-hasher", "parity-scale-codec", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "rustc-hex", + "rlp", + "rlp-derive", "scale-info", - "serde", - "serde_derive", - "smallvec", - "sp-api", - "sp-arithmetic", - "sp-authority-discovery", - "sp-block-builder", - "sp-consensus-babe", - "sp-core", - "sp-inherents", - "sp-io", - "sp-npos-elections", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-transaction-pool", - "sp-version", - "static_assertions", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-executor", + "sha3 0.10.1", + "triehash", ] [[package]] -name = "kusama-runtime-constants" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "ethereum-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" dependencies = [ - "frame-support", - "polkadot-primitives", - "polkadot-runtime-common", - "smallvec", - "sp-runtime", + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "primitive-types", + "scale-info", + "uint", ] [[package]] -name = "kv-log-macro" -version = "1.0.7" +name = "event-listener" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" [[package]] -name = "kvdb" -version = "0.10.0" +name = "exit-future" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a3f58dc069ec0e205a27f5b45920722a46faed802a0541538241af6228f512" +checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "parity-util-mem", - "smallvec", + "futures", ] [[package]] -name = "kvdb-memorydb" -version = "0.10.0" +name = "fake-simd" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b6b85fc643f5acd0bffb2cc8a6d150209379267af0d41db72170021841f9f5" -dependencies = [ - "kvdb", - "parity-util-mem", - "parking_lot 0.11.2", -] +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] -name = "kvdb-rocksdb" -version = "0.14.0" +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fastrand" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1b6ea8f2536f504b645ad78419c8246550e19d2c3419a167080ce08edee35a" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ - "fs-swap", - "kvdb", - "log", - "num_cpus", - "owning_ref", - "parity-util-mem", - "parking_lot 0.11.2", - "regex", - "rocksdb", - "smallvec", + "instant", ] [[package]] -name = "kzen-paillier" -version = "0.4.2" +name = "fdlimit" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2331394a15a3c06d7ddd931c083c96ab30ea20490899354f486891b9570f87b5" +checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" dependencies = [ - "curv-kzen", - "rayon", - "serde", + "libc", ] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "ff" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core 0.6.3", + "subtle 2.4.1", +] [[package]] -name = "lazycell" -version = "1.3.0" +name = "ff" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +dependencies = [ + "rand_core 0.6.3", + "subtle 2.4.1", +] [[package]] -name = "libc" -version = "0.2.121" +name = "ff-zeroize" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "c02169a2e8515aa316ce516eaaf6318a76617839fbf904073284bc2576b029ee" +dependencies = [ + "byteorder", + "ff_derive-zeroize", + "rand_core 0.5.1", + "zeroize", +] [[package]] -name = "libloading" -version = "0.5.2" +name = "ff_derive-zeroize" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" +checksum = "b24d4059bc0d0a0bf26b740aa21af1f96a984f0ab7a21356d00b32475388b53a" dependencies = [ - "cc", - "winapi 0.3.9", + "num-bigint", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "libloading" -version = "0.7.3" +name = "file-per-thread-logger" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "21e16290574b39ee41c71aeb90ae960c504ebaf1e2a1c87bd52aa56ed6e1a02f" dependencies = [ - "cfg-if 1.0.0", - "winapi 0.3.9", + "env_logger", + "log", ] [[package]] -name = "libm" -version = "0.2.2" +name = "finality-grandpa" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" +checksum = "d9def033d8505edf199f6a5d07aa7e6d2d6185b164293b77f0efd108f4f3e11d" +dependencies = [ + "either", + "futures", + "futures-timer", + "log", + "num-traits", + "parity-scale-codec", + "parking_lot 0.11.2", + "scale-info", +] [[package]] -name = "libp2p" -version = "0.40.0" +name = "fixed-hash" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bec54343492ba5940a6c555e512c6721139835d28c59bc22febece72dfd0d9d" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" dependencies = [ - "atomic", - "bytes 1.1.0", - "futures 0.3.21", - "lazy_static", - "libp2p-core", - "libp2p-deflate", - "libp2p-dns", - "libp2p-floodsub", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-kad", - "libp2p-mdns", - "libp2p-metrics", - "libp2p-mplex", - "libp2p-noise", - "libp2p-ping", - "libp2p-plaintext", - "libp2p-pnet", - "libp2p-relay", - "libp2p-rendezvous", - "libp2p-request-response", - "libp2p-swarm", - "libp2p-swarm-derive", - "libp2p-tcp", - "libp2p-uds", - "libp2p-wasm-ext", - "libp2p-websocket", - "libp2p-yamux", - "multiaddr", - "parking_lot 0.11.2", - "pin-project 1.0.10", - "smallvec", - "wasm-timer", + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", ] [[package]] -name = "libp2p-core" -version = "0.30.2" +name = "fixedbitset" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" + +[[package]] +name = "flate2" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86aad7d54df283db817becded03e611137698a6509d4237a96881976a162340c" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "asn1_der", - "bs58", - "ed25519-dalek", - "either", - "fnv", - "futures 0.3.21", - "futures-timer", - "instant", - "lazy_static", - "libsecp256k1 0.7.0", - "log", - "multiaddr", - "multihash 0.14.0", - "multistream-select", - "parking_lot 0.11.2", - "pin-project 1.0.10", - "prost", - "prost-build", - "rand 0.8.5", - "ring", - "rw-stream-sink", - "sha2 0.9.9", - "smallvec", - "thiserror", - "unsigned-varint 0.7.1", - "void", - "zeroize", + "crc32fast", + "libz-sys", + "miniz_oxide", ] [[package]] -name = "libp2p-deflate" -version = "0.30.0" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51a800adb195f33de63f4b17b63fe64cfc23bf2c6a0d3d0d5321328664e65197" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fork-tree" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "flate2", - "futures 0.3.21", - "libp2p-core", + "parity-scale-codec", ] [[package]] -name = "libp2p-dns" -version = "0.30.0" +name = "form_urlencoded" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8f89d15cb6e3c5bc22afff7513b11bab7856f2872d3cfba86f7f63a06bc498" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ - "async-std-resolver", - "futures 0.3.21", - "libp2p-core", - "log", - "smallvec", - "trust-dns-resolver", + "matches", + "percent-encoding", ] [[package]] -name = "libp2p-floodsub" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aab3d7210901ea51b7bae2b581aa34521797af8c4ec738c980bda4a06434067f" +name = "frame-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "cuckoofilter", - "fnv", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", + "frame-support", + "frame-system", + "linregress", "log", - "prost", - "prost-build", - "rand 0.7.3", - "smallvec", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-io", + "sp-runtime", + "sp-runtime-interface", + "sp-std", + "sp-storage", ] [[package]] -name = "libp2p-gossipsub" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeead619eb5dac46e65acc78c535a60aaec803d1428cca6407c3a4fc74d698d" +name = "frame-benchmarking-cli" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "asynchronous-codec 0.6.0", - "base64", - "byteorder", - "bytes 1.1.0", - "fnv", - "futures 0.3.21", - "hex_fmt", - "libp2p-core", - "libp2p-swarm", + "Inflector", + "chrono", + "clap", + "comfy-table", + "frame-benchmarking", + "frame-support", + "frame-system", + "handlebars", + "hash-db", + "hex", + "itertools 0.10.3", + "kvdb", + "lazy_static", + "linked-hash-map", "log", - "prost", - "prost-build", - "rand 0.7.3", - "regex", - "sha2 0.9.9", - "smallvec", - "unsigned-varint 0.7.1", - "wasm-timer", + "memory-db", + "parity-scale-codec", + "rand 0.8.5", + "rand_pcg 0.3.1", + "sc-block-builder", + "sc-cli", + "sc-client-api", + "sc-client-db", + "sc-executor", + "sc-service", + "sc-sysinfo", + "serde", + "serde_json", + "serde_nanos", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-database", + "sp-externalities", + "sp-inherents", + "sp-keystore", + "sp-runtime", + "sp-state-machine", + "sp-storage", + "sp-trie", + "tempfile", + "thiserror", + "thousands", ] [[package]] -name = "libp2p-identify" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca1275574183f288ff8b72d535d5ffa5ea9292ef7829af8b47dcb197c7b0dcd" +name = "frame-election-provider-solution-type" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "lru 0.6.6", - "prost", - "prost-build", - "smallvec", - "wasm-timer", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "libp2p-kad" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2297dc0ca285f3a09d1368bde02449e539b46f94d32d53233f53f6625bcd3ba" +name = "frame-election-provider-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "arrayvec 0.5.2", - "asynchronous-codec 0.6.0", - "bytes 1.1.0", - "either", - "fnv", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "prost", - "prost-build", - "rand 0.7.3", - "sha2 0.9.9", - "smallvec", - "uint", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", + "frame-election-provider-solution-type", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-arithmetic", + "sp-npos-elections", + "sp-runtime", + "sp-std", ] [[package]] -name = "libp2p-mdns" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c864b64bdc8a84ff3910a0df88e6535f256191a450870f1e7e10cbf8e64d45" +name = "frame-executive" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "async-io", - "data-encoding", - "dns-parser", - "futures 0.3.21", - "if-watch", - "lazy_static", - "libp2p-core", - "libp2p-swarm", - "log", - "rand 0.8.5", - "smallvec", - "socket2 0.4.4", - "void", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", ] [[package]] -name = "libp2p-metrics" -version = "0.1.0" +name = "frame-metadata" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af432fcdd2f8ba4579b846489f8f0812cfd738ced2c0af39df9b1c48bbb6ab2" +checksum = "df6bb8542ef006ef0de09a5c4420787d79823c0ed7924225822362fd2bf2ff2d" dependencies = [ - "libp2p-core", - "libp2p-identify", - "libp2p-kad", - "libp2p-ping", - "libp2p-swarm", - "open-metrics-client", + "cfg-if", + "parity-scale-codec", + "scale-info", + "serde", ] [[package]] -name = "libp2p-mplex" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2cd64ef597f40e14bfce0497f50ecb63dd6d201c61796daeb4227078834fbf" +name = "frame-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "asynchronous-codec 0.6.0", - "bytes 1.1.0", - "futures 0.3.21", - "libp2p-core", + "bitflags", + "frame-metadata", + "frame-support-procedural", + "impl-trait-for-tuples", + "k256", "log", - "nohash-hasher", - "parking_lot 0.11.2", - "rand 0.7.3", + "once_cell", + "parity-scale-codec", + "paste", + "scale-info", + "serde", "smallvec", - "unsigned-varint 0.7.1", + "sp-arithmetic", + "sp-core", + "sp-core-hashing-proc-macro", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-state-machine", + "sp-std", + "sp-tracing", + "tt-call", ] [[package]] -name = "libp2p-noise" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8772c7a99088221bb7ca9c5c0574bf55046a7ab4c319f3619b275f28c8fb87a" +name = "frame-support-procedural" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "bytes 1.1.0", - "curve25519-dalek 3.2.0", - "futures 0.3.21", - "lazy_static", - "libp2p-core", - "log", - "prost", - "prost-build", - "rand 0.8.5", - "sha2 0.9.9", - "snow", - "static_assertions", - "x25519-dalek", - "zeroize", + "Inflector", + "frame-support-procedural-tools", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "libp2p-ping" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80ef7b0ec5cf06530d9eb6cf59ae49d46a2c45663bde31c25a12f682664adbcf" +name = "frame-support-procedural-tools" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "rand 0.7.3", - "void", - "wasm-timer", + "frame-support-procedural-tools-derive", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "frame-support-procedural-tools-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "libp2p-plaintext" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fba1a6ff33e4a274c89a3b1d78b9f34f32af13265cc5c46c16938262d4e945a" +name = "frame-system" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "asynchronous-codec 0.6.0", - "bytes 1.1.0", - "futures 0.3.21", - "libp2p-core", + "frame-support", "log", - "prost", - "prost-build", - "unsigned-varint 0.7.1", - "void", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", ] [[package]] -name = "libp2p-pnet" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1a458bbda880107b5b36fcb9b5a1ef0c329685da0e203ed692a8ebe64cc92c" +name = "frame-system-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "log", - "pin-project 1.0.10", - "rand 0.7.3", - "salsa20", - "sha3", + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] -name = "libp2p-relay" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2852b61c90fa8ce3c8fcc2aba76e6cefc20d648f9df29157d6b3a916278ef3e3" +name = "frame-system-rpc-runtime-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "asynchronous-codec 0.6.0", - "bytes 1.1.0", - "futures 0.3.21", - "futures-timer", - "libp2p-core", - "libp2p-swarm", - "log", - "pin-project 1.0.10", - "prost", - "prost-build", - "rand 0.7.3", - "smallvec", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", + "parity-scale-codec", + "sp-api", ] [[package]] -name = "libp2p-rendezvous" -version = "0.1.0" +name = "fs-swap" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a6d2b9e7677eff61dc3d2854876aaf3976d84a01ef6664b610c77a0c9407c5" +checksum = "03d47dad3685eceed8488986cad3d5027165ea5edb164331770e2059555f10a5" dependencies = [ - "asynchronous-codec 0.6.0", - "bimap", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "prost", - "prost-build", - "rand 0.8.5", - "sha2 0.9.9", - "thiserror", - "unsigned-varint 0.7.1", - "void", - "wasm-timer", + "lazy_static", + "libc", + "libloading 0.5.2", + "winapi", ] [[package]] -name = "libp2p-request-response" -version = "0.13.0" +name = "fs2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a877a4ced6d46bf84677e1974e8cf61fb434af73b2e96fb48d6cb6223a4634d8" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ - "async-trait", - "bytes 1.1.0", - "futures 0.3.21", - "libp2p-core", - "libp2p-swarm", - "log", - "lru 0.7.3", - "rand 0.7.3", - "smallvec", - "unsigned-varint 0.7.1", - "wasm-timer", + "libc", + "winapi", ] [[package]] -name = "libp2p-swarm" -version = "0.31.0" +name = "fs_extra" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f5184a508f223bc100a12665517773fb8730e9f36fc09eefb670bf01b107ae9" -dependencies = [ - "either", - "futures 0.3.21", - "libp2p-core", - "log", - "rand 0.7.3", - "smallvec", - "void", - "wasm-timer", -] +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] -name = "libp2p-swarm-derive" -version = "0.25.0" +name = "fuchsia-cprng" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "072c290f727d39bdc4e9d6d1c847978693d25a673bd757813681e33e5f6c00c2" -dependencies = [ - "quote", - "syn", -] +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] -name = "libp2p-tcp" -version = "0.30.0" +name = "funty" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7399c5b6361ef525d41c11fcf51635724f832baf5819b30d3d873eabb4fbae4b" -dependencies = [ - "async-io", - "futures 0.3.21", - "futures-timer", - "if-watch", - "ipnet", - "libc", - "libp2p-core", - "log", - "socket2 0.4.4", -] +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] -name = "libp2p-uds" -version = "0.30.0" +name = "futures" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7563e46218165dfd60f64b96f7ce84590d75f53ecbdc74a7dd01450dc5973" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ - "async-std", - "futures 0.3.21", - "libp2p-core", - "log", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "libp2p-wasm-ext" -version = "0.30.0" +name = "futures-channel" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1008a302b73c5020251f9708c653f5ed08368e530e247cc9cd2f109ff30042cf" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ - "futures 0.3.21", - "js-sys", - "libp2p-core", - "parity-send-wrapper", - "wasm-bindgen", - "wasm-bindgen-futures", + "futures-core", + "futures-sink", ] [[package]] -name = "libp2p-websocket" -version = "0.31.0" +name = "futures-core" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e12df82d1ed64969371a9e65ea92b91064658604cc2576c2757f18ead9a1cf" -dependencies = [ - "either", - "futures 0.3.21", - "futures-rustls", - "libp2p-core", - "log", - "quicksink", - "rw-stream-sink", - "soketto", - "url 2.2.2", - "webpki-roots 0.21.1", -] +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] -name = "libp2p-yamux" -version = "0.34.0" +name = "futures-executor" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7362abb8867d7187e7e93df17f460d554c997fc5c8ac57dc1259057f6889af" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ - "futures 0.3.21", - "libp2p-core", - "parking_lot 0.11.2", - "thiserror", - "yamux", + "futures-core", + "futures-task", + "futures-util", + "num_cpus", ] [[package]] -name = "librocksdb-sys" -version = "6.20.3" +name = "futures-io" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c309a9d2470844aceb9a4a098cf5286154d20596868b75a6b36357d2bb9ca25d" -dependencies = [ - "bindgen", - "cc", - "glob", - "libc", -] +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] -name = "libsecp256k1" -version = "0.3.5" +name = "futures-lite" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" dependencies = [ - "arrayref", - "crunchy", - "digest 0.8.1", - "hmac-drbg 0.2.0", - "rand 0.7.3", - "sha2 0.8.2", - "subtle 2.4.1", - "typenum", + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite 0.2.9", + "waker-fn", ] [[package]] -name = "libsecp256k1" -version = "0.7.0" +name = "futures-macro" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0452aac8bab02242429380e9b2f94ea20cea2b37e2c1777a1358799bbe97f37" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "arrayref", - "base64", - "digest 0.9.0", - "hmac-drbg 0.3.0", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand 0.8.5", - "serde", - "sha2 0.9.9", - "typenum", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "libsecp256k1-core" -version = "0.3.0" +name = "futures-rustls" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +checksum = "e01fe9932a224b72b45336d96040aa86386d674a31d0af27d800ea7bc8ca97fe" dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle 2.4.1", + "futures-io", + "rustls", + "webpki", ] [[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.3.0" +name = "futures-sink" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" -dependencies = [ - "libsecp256k1-core", -] +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] -name = "libsecp256k1-gen-genmult" -version = "0.3.0" +name = "futures-task" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" -dependencies = [ - "libsecp256k1-core", -] +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] -name = "libz-sys" -version = "1.1.5" +name = "futures-timer" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f35facd4a5673cb5a48822be2be1d4236c1c99cb4113cab7061ac720d5bf859" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] -name = "linked-hash-map" -version = "0.5.4" +name = "futures-util" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite 0.2.9", + "pin-utils", + "slab", +] [[package]] -name = "linked_hash_set" -version = "0.1.4" +name = "generic-array" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" dependencies = [ - "linked-hash-map", + "typenum", ] [[package]] -name = "linregress" -version = "0.4.4" +name = "generic-array" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c601a85f5ecd1aba625247bca0031585fb1c446461b142878a16f8245ddeb8" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ - "nalgebra", - "statrs", + "typenum", + "version_check", ] [[package]] -name = "linux-raw-sys" -version = "0.0.36" +name = "getrandom" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a261afc61b7a5e323933b402ca6a1765183687c614789b1e4db7762ed4230bca" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] [[package]] -name = "lock_api" -version = "0.3.4" +name = "getrandom" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ - "scopeguard", + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] -name = "lock_api" -version = "0.4.6" +name = "ghash" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" dependencies = [ - "scopeguard", + "opaque-debug 0.3.0", + "polyval", ] [[package]] -name = "log" -version = "0.4.14" +name = "gimli" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" dependencies = [ - "cfg-if 1.0.0", - "value-bag", + "fallible-iterator", + "indexmap", + "stable_deref_trait", ] [[package]] -name = "lru" -version = "0.6.6" +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "globset" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ea2d928b485416e8908cff2d97d621db22b27f7b3b6729e438bcf42c671ba91" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" dependencies = [ - "hashbrown 0.11.2", + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", ] [[package]] -name = "lru" -version = "0.7.3" +name = "gloo-timers" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb87f3080f6d1d69e8c564c0fcfde1d7aa8cc451ce40cae89479111f03bc0eb" +checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" dependencies = [ - "hashbrown 0.11.2", + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "lru-cache" -version = "0.1.2" +name = "group" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ - "linked-hash-map", + "ff 0.10.1", + "rand_core 0.6.3", + "subtle 2.4.1", ] [[package]] -name = "lz4" -version = "1.23.3" +name = "group" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edcb94251b1c375c459e5abe9fb0168c1c826c3370172684844f8f3f8d1a885" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ - "libc", - "lz4-sys", + "ff 0.11.1", + "rand_core 0.6.3", + "subtle 2.4.1", ] [[package]] -name = "lz4-sys" -version = "1.9.3" +name = "h2" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7be8908e2ed6f31c02db8a9fa962f03e36c53fbfde437363eae3306b85d7e17" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" dependencies = [ - "cc", - "libc", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] -name = "mach" -version = "0.3.2" +name = "handlebars" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +checksum = "b66d0c1b6e3abfd1e72818798925e16e02ed77e1b47f6c25a95a23b377ee4299" dependencies = [ - "libc", + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", ] [[package]] -name = "maplit" -version = "1.0.2" +name = "hash-db" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" [[package]] -name = "match_cfg" -version = "0.1.0" +name = "hash256-std-hasher" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] [[package]] -name = "matchers" -version = "0.0.1" +name = "hashbrown" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "regex-automata", + "ahash", ] [[package]] -name = "matches" -version = "0.1.9" +name = "hashbrown" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +dependencies = [ + "ahash", +] [[package]] -name = "matrixmultiply" -version = "0.3.2" +name = "heck" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ - "rawpointer", + "unicode-segmentation", ] [[package]] -name = "memchr" -version = "2.4.1" +name = "heck" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] -name = "memmap2" -version = "0.2.3" +name = "hermit-abi" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] -name = "memmap2" -version = "0.5.3" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" dependencies = [ - "libc", + "serde", ] [[package]] -name = "memoffset" -version = "0.6.5" +name = "hex-literal" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" dependencies = [ - "autocfg 1.1.0", + "crypto-mac 0.7.0", + "digest 0.8.1", ] [[package]] -name = "memory-db" -version = "0.27.0" +name = "hmac" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de006e09d04fc301a5f7e817b75aa49801c4479a8af753764416b085337ddcc5" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "hash-db", - "hashbrown 0.11.2", - "parity-util-mem", + "crypto-mac 0.8.0", + "digest 0.9.0", ] [[package]] -name = "memory-db" -version = "0.28.0" +name = "hmac" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d505169b746dacf02f7d14d8c80b34edfd8212159c63d23c977739a0d960c626" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ - "hash-db", - "hashbrown 0.11.2", - "parity-util-mem", + "crypto-mac 0.11.1", + "digest 0.9.0", ] [[package]] -name = "memory-lru" -version = "0.1.0" +name = "hmac-drbg" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beeb98b3d1ed2c0054bd81b5ba949a0243c3ccad751d45ea898fa8059fa2860a" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" dependencies = [ - "lru 0.6.6", + "digest 0.8.1", + "generic-array 0.12.4", + "hmac 0.7.1", ] [[package]] -name = "memory_units" +name = "hmac-drbg" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array 0.14.5", + "hmac 0.8.1", +] [[package]] -name = "merkle-cbt" -version = "0.3.2" +name = "hostname" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171d2f700835121c3b04ccf0880882987a050fd5c7ae88148abf537d33dd3a56" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ - "cfg-if 1.0.0", + "libc", + "match_cfg", + "winapi", ] [[package]] -name = "merlin" -version = "2.0.1" +name = "http" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ - "byteorder", - "keccak", - "rand_core 0.5.1", - "zeroize", + "bytes", + "fnv", + "itoa 1.0.2", ] [[package]] -name = "metered-channel" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "derive_more", - "futures 0.3.21", - "futures-timer", - "thiserror", - "tracing", + "bytes", + "http", + "pin-project-lite 0.2.9", ] [[package]] -name = "mick-jaeger" -version = "0.1.8" +name = "httparse" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69672161530e8aeca1d1400fbf3f1a1747ff60ea604265a4e906c2442df20532" -dependencies = [ - "futures 0.3.21", - "rand 0.8.5", - "thrift", -] +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "httpdate" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] -name = "miniz_oxide" -version = "0.4.4" +name = "humantime" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg 1.1.0", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] -name = "mio" -version = "0.6.23" +name = "hyper" +version = "0.14.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow 0.2.2", - "net2", - "slab", - "winapi 0.2.8", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 1.0.2", + "pin-project-lite 0.2.9", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", ] [[package]] -name = "mio" -version = "0.8.1" +name = "hyper-rustls" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba42135c6a5917b9db9cd7b293e5409e1c6b041e6f9825e92e55a894c63b6f8" +checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" dependencies = [ - "libc", + "http", + "hyper", "log", - "miow 0.3.7", - "ntapi", - "wasi 0.11.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", ] [[package]] -name = "mio-extras" -version = "2.0.6" +name = "idna" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ - "lazycell", - "log", - "mio 0.6.23", - "slab", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "miow" -version = "0.2.2" +name = "if-addrs" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "libc", + "winapi", ] [[package]] -name = "miow" -version = "0.3.7" +name = "if-watch" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +checksum = "015a7df1eb6dda30df37f34b63ada9b7b352984b0e84de2a20ed526345000791" dependencies = [ - "winapi 0.3.9", + "async-io", + "core-foundation", + "fnv", + "futures", + "if-addrs", + "ipnet", + "log", + "rtnetlink", + "system-configuration", + "windows", ] [[package]] -name = "more-asserts" -version = "0.2.2" +name = "impl-codec" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] [[package]] -name = "multi-party-ecdsa" -version = "0.8.1" -source = "git+https://github.com/webb-tools/multi-party-ecdsa.git#7d471657772f99c6c7c65426b5a0c957ecef09eb" +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" dependencies = [ - "centipede", - "curv-kzen", - "derivative", - "kzen-paillier", - "libsecp256k1 0.3.5", - "round-based", - "serde", - "sha2 0.9.9", - "subtle 2.4.1", - "thiserror", - "zeroize", - "zk-paillier", + "rlp", ] [[package]] -name = "multiaddr" -version = "0.13.0" +name = "impl-serde" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ee4ea82141951ac6379f964f71b20876d43712bea8faf6dd1a375e08a46499" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" dependencies = [ - "arrayref", - "bs58", - "byteorder", - "data-encoding", - "multihash 0.14.0", - "percent-encoding 2.1.0", "serde", - "static_assertions", - "unsigned-varint 0.7.1", - "url 2.2.2", ] [[package]] -name = "multibase" -version = "0.8.0" +name = "impl-trait-for-tuples" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b78c60039650ff12e140ae867ef5299a58e19dded4d334c849dc7177083667e2" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "multihash" -version = "0.13.2" +name = "indexmap" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dac63698b887d2d929306ea48b63760431ff8a24fac40ddb22f9c7f49fb7cab" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ - "blake2b_simd", - "blake2s_simd", - "blake3", - "digest 0.9.0", - "generic-array 0.14.5", - "multihash-derive", - "sha2 0.9.9", - "sha3", - "unsigned-varint 0.5.1", + "autocfg 1.1.0", + "hashbrown 0.12.1", + "serde", ] [[package]] -name = "multihash" -version = "0.14.0" +name = "instant" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "752a61cd890ff691b4411423d23816d5866dd5621e4d1c5687a53b94b5a979d8" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "digest 0.9.0", - "generic-array 0.14.5", - "multihash-derive", - "sha2 0.9.9", - "unsigned-varint 0.7.1", + "cfg-if", ] [[package]] -name = "multihash-derive" -version = "0.7.2" +name = "integer-sqrt" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424f6e86263cd5294cbd7f1e95746b95aca0e0d66bff31e5a40d6baa87b4aa99" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", - "synstructure", + "num-traits", ] [[package]] -name = "multimap" -version = "0.8.3" +name = "io-lifetimes" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "ec58677acfea8a15352d42fc87d11d63596ade9239e0a7c9352914417515dbe6" [[package]] -name = "multistream-select" -version = "0.10.4" +name = "ip_network" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56a336acba8bc87c8876f6425407dbbe6c417bf478b22015f8fb0994ef3bc0ab" -dependencies = [ - "bytes 1.1.0", - "futures 0.3.21", - "log", - "pin-project 1.0.10", - "smallvec", - "unsigned-varint 0.7.1", -] +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" [[package]] -name = "nalgebra" -version = "0.27.1" +name = "ipconfig" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120" +checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98" dependencies = [ - "approx", - "matrixmultiply", - "nalgebra-macros", - "num-complex", - "num-rational 0.4.0", - "num-traits", - "rand 0.8.5", - "rand_distr", - "simba", - "typenum", + "socket2", + "widestring", + "winapi", + "winreg", ] [[package]] -name = "nalgebra-macros" -version = "0.1.0" +name = "ipnet" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] -name = "names" -version = "0.12.0" +name = "itertools" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a8690bf09abf659851e58cd666c3d37ac6af07c2bd7a9e332cfba471715775" +checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" dependencies = [ - "rand 0.8.5", + "either", ] [[package]] -name = "net2" -version = "0.2.37" +name = "itertools" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "either", ] [[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "nohash-hasher" -version = "0.2.0" +name = "itoa" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] -name = "nom" -version = "7.1.0" +name = "itoa" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" -dependencies = [ - "memchr", - "minimal-lexical", - "version_check", -] +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] -name = "ntapi" -version = "0.3.7" +name = "jobserver" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" dependencies = [ - "winapi 0.3.9", + "libc", ] [[package]] -name = "num-bigint" -version = "0.2.6" +name = "js-sys" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" dependencies = [ - "autocfg 1.1.0", - "num-integer", - "num-traits", + "wasm-bindgen", ] [[package]] -name = "num-complex" -version = "0.4.0" +name = "jsonrpsee" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +checksum = "a1f2ab5a60e558e74ea93bcf5164ebc47939a7fff8938fa9b5233bbc63e16061" dependencies = [ - "num-traits", + "jsonrpsee-core", + "jsonrpsee-http-server", + "jsonrpsee-proc-macros", + "jsonrpsee-types", + "jsonrpsee-ws-server", + "tracing", ] [[package]] -name = "num-integer" -version = "0.1.44" +name = "jsonrpsee-core" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "6e27462b21279edf9a6a91f46ffbe125e9cdc58b901d2e08bf59b31a47d7d0ab" dependencies = [ - "autocfg 1.1.0", - "num-traits", + "anyhow", + "arrayvec 0.7.2", + "async-trait", + "beef", + "futures-channel", + "futures-util", + "hyper", + "jsonrpsee-types", + "parking_lot 0.12.1", + "rand 0.8.5", + "rustc-hash", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tracing", ] [[package]] -name = "num-rational" -version = "0.2.4" +name = "jsonrpsee-http-server" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +checksum = "7178f16eabd7154c094e24d295b9ee355ec1e5f24c328759c56255ff7bbd4548" dependencies = [ - "autocfg 1.1.0", - "num-bigint", - "num-integer", - "num-traits", + "futures-channel", + "futures-util", + "globset", + "hyper", + "jsonrpsee-core", + "jsonrpsee-types", + "lazy_static", + "serde_json", + "tokio", + "tracing", + "unicase", ] [[package]] -name = "num-rational" -version = "0.4.0" +name = "jsonrpsee-proc-macros" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +checksum = "8b8d7f449cab3b747f12c3efc27f5cad537f3b597c6a3838b0fac628f4bf730a" dependencies = [ - "autocfg 1.1.0", - "num-integer", - "num-traits", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "num-traits" -version = "0.2.14" +name = "jsonrpsee-types" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "8fd11763134104122ddeb0f97e4bbe393058017dfb077db63fbf44b4dd0dd86e" dependencies = [ - "autocfg 1.1.0", - "libm", + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", ] [[package]] -name = "num_cpus" -version = "1.13.1" +name = "jsonrpsee-ws-server" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "dfb6c21556c551582b56e4e8e6e6249b0bbdb69bb7fa39efe9b9a6b54af9f206" dependencies = [ - "hermit-abi", - "libc", + "futures-channel", + "futures-util", + "jsonrpsee-core", + "jsonrpsee-types", + "serde_json", + "soketto", + "tokio", + "tokio-util", + "tracing", ] [[package]] -name = "object" -version = "0.27.1" +name = "k256" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" dependencies = [ - "crc32fast", - "indexmap", - "memchr", + "cfg-if", + "ecdsa 0.13.4", + "elliptic-curve 0.11.12", + "sec1", ] [[package]] -name = "once_cell" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" - -[[package]] -name = "opaque-debug" -version = "0.2.3" +name = "keccak" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" [[package]] -name = "opaque-debug" -version = "0.3.0" +name = "kv-log-macro" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] [[package]] -name = "open-metrics-client" -version = "0.12.0" +name = "kvdb" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7337d80c23c2d8b1349563981bc4fb531220733743ba8115454a67b181173f0d" +checksum = "a301d8ecb7989d4a6e2c57a49baca77d353bdbf879909debe3f375fe25d61f86" dependencies = [ - "dtoa", - "itoa 0.4.8", - "open-metrics-client-derive-text-encode", - "owning_ref", + "parity-util-mem", + "smallvec", ] [[package]] -name = "open-metrics-client-derive-text-encode" -version = "0.1.1" +name = "kvdb-memorydb" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c83b586f00268c619c1cb3340ec1a6f59dd9ba1d9833a273a68e6d5cd8ffc" +checksum = "ece7e668abd21387aeb6628130a6f4c802787f014fa46bc83221448322250357" dependencies = [ - "proc-macro2", - "quote", - "syn", + "kvdb", + "parity-util-mem", + "parking_lot 0.12.1", ] [[package]] -name = "openssl-probe" -version = "0.1.5" +name = "kvdb-rocksdb" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "ca7fbdfd71cd663dceb0faf3367a99f8cf724514933e9867cec4995b6027cbc1" +dependencies = [ + "fs-swap", + "kvdb", + "log", + "num_cpus", + "owning_ref", + "parity-util-mem", + "parking_lot 0.12.1", + "regex", + "rocksdb", + "smallvec", +] [[package]] -name = "ordered-float" -version = "1.1.1" +name = "kzen-paillier" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7" +checksum = "2331394a15a3c06d7ddd931c083c96ab30ea20490899354f486891b9570f87b5" dependencies = [ - "num-traits", + "curv-kzen", + "rayon", + "serde", ] [[package]] -name = "os_str_bytes" -version = "6.0.0" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "owning_ref" -version = "0.4.1" +name = "lazycell" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" -dependencies = [ - "stable_deref_trait", -] +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] -name = "p256" -version = "0.9.0" +name = "libc" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" -dependencies = [ - "ecdsa 0.12.4", - "elliptic-curve 0.10.6", - "sha2 0.9.9", -] +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] -name = "pairing-plus" -version = "0.19.0" +name = "libloading" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cda4f22e8e6720f3c254049960c8cc4f93cb82b5ade43bddd2622b5f39ea62" +checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" dependencies = [ - "byteorder", - "digest 0.8.1", - "ff-zeroize", - "rand 0.4.6", - "rand_core 0.5.1", - "rand_xorshift 0.2.0", - "zeroize", + "cc", + "winapi", ] [[package]] -name = "pallet-aura" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ - "frame-support", - "frame-system", - "pallet-timestamp", - "parity-scale-codec", - "scale-info", - "sp-application-crypto", - "sp-consensus-aura", - "sp-runtime", - "sp-std", + "cfg-if", + "winapi", ] [[package]] -name = "pallet-authority-discovery" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-support", - "frame-system", - "pallet-session", - "parity-scale-codec", - "scale-info", - "sp-application-crypto", - "sp-authority-discovery", - "sp-runtime", - "sp-std", -] +name = "libm" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" [[package]] -name = "pallet-authorship" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41726ee8f662563fafba2d2d484b14037cc8ecb8c953fbfc8439d4ce3a0a9029" dependencies = [ - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "parity-scale-codec", - "scale-info", - "sp-authorship", - "sp-runtime", - "sp-std", + "bytes", + "futures", + "futures-timer", + "getrandom 0.2.7", + "instant", + "lazy_static", + "libp2p-autonat", + "libp2p-core 0.33.0", + "libp2p-deflate", + "libp2p-dns", + "libp2p-floodsub", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-kad", + "libp2p-mdns", + "libp2p-metrics", + "libp2p-mplex", + "libp2p-noise", + "libp2p-ping", + "libp2p-plaintext", + "libp2p-pnet", + "libp2p-relay", + "libp2p-rendezvous", + "libp2p-request-response", + "libp2p-swarm", + "libp2p-swarm-derive", + "libp2p-tcp", + "libp2p-uds", + "libp2p-wasm-ext", + "libp2p-websocket", + "libp2p-yamux", + "multiaddr", + "parking_lot 0.12.1", + "pin-project 1.0.10", + "rand 0.7.3", + "smallvec", ] [[package]] -name = "pallet-babe" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "pallet-authorship", - "pallet-session", - "pallet-timestamp", - "parity-scale-codec", - "scale-info", - "sp-application-crypto", - "sp-consensus-babe", - "sp-consensus-vrf", - "sp-io", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", +name = "libp2p-autonat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d45945fd2f96c4b133c23d5c28a8b7fc8d7138e6dd8d5a8cd492dd384f888e3" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.33.0", + "libp2p-request-response", + "libp2p-swarm", + "log", + "prost 0.10.4", + "prost-build 0.10.4", + "rand 0.8.5", ] [[package]] -name = "pallet-bags-list" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-core" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db5b02602099fb75cb2d16f9ea860a320d6eb82ce41e95ab680912c454805cd5" dependencies = [ - "frame-benchmarking", - "frame-election-provider-support", - "frame-support", - "frame-system", + "asn1_der", + "bs58", + "ed25519-dalek", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "lazy_static", "log", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "multiaddr", + "multihash", + "multistream-select", + "parking_lot 0.12.1", + "pin-project 1.0.10", + "prost 0.9.0", + "prost-build 0.9.0", + "rand 0.8.5", + "ring", + "rw-stream-sink 0.2.1", + "sha2 0.10.2", + "smallvec", + "thiserror", + "unsigned-varint", + "void", + "zeroize", ] [[package]] -name = "pallet-balances" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-core" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d46fca305dee6757022e2f5a4f6c023315084d0ed7441c3ab244e76666d979" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "asn1_der", + "bs58", + "ed25519-dalek", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "lazy_static", + "libsecp256k1 0.7.0", "log", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-std", + "multiaddr", + "multihash", + "multistream-select", + "parking_lot 0.12.1", + "pin-project 1.0.10", + "prost 0.10.4", + "prost-build 0.10.4", + "rand 0.8.5", + "ring", + "rw-stream-sink 0.3.0", + "sha2 0.10.2", + "smallvec", + "thiserror", + "unsigned-varint", + "void", + "zeroize", ] [[package]] -name = "pallet-beefy" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-deflate" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86adefc55ea4ed8201149f052fb441210727481dff1fb0b8318460206a79f5fb" dependencies = [ - "beefy-primitives", - "frame-support", - "frame-system", - "pallet-session", - "parity-scale-codec", - "scale-info", - "serde", - "sp-runtime", - "sp-std", + "flate2", + "futures", + "libp2p-core 0.33.0", ] [[package]] -name = "pallet-beefy-mmr" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-dns" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb462ec3a51fab457b4b44ac295e8b0a4b04dc175127e615cf996b1f0f1a268" dependencies = [ - "beefy-merkle-tree", - "beefy-primitives", - "frame-support", - "frame-system", - "hex", - "libsecp256k1 0.7.0", + "async-std-resolver", + "futures", + "libp2p-core 0.33.0", "log", - "pallet-beefy", - "pallet-mmr", - "pallet-mmr-primitives", - "pallet-session", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "parking_lot 0.12.1", + "smallvec", + "trust-dns-resolver", ] [[package]] -name = "pallet-bounties" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-floodsub" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a505d0c6f851cbf2919535150198e530825def8bd3757477f13dc3a57f46cbcc" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "cuckoofilter", + "fnv", + "futures", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "pallet-treasury", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "prost 0.10.4", + "prost-build 0.10.4", + "rand 0.7.3", + "smallvec", ] [[package]] -name = "pallet-bridge-dispatch" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "libp2p-gossipsub" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e064ba4d7832e01c738626c6b274ae100baba05f5ffcc7b265c2a3ed398108" dependencies = [ - "bp-message-dispatch", - "bp-runtime", - "frame-support", - "frame-system", + "asynchronous-codec", + "base64", + "byteorder", + "bytes", + "fnv", + "futures", + "hex_fmt", + "instant", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "prometheus-client", + "prost 0.10.4", + "prost-build 0.10.4", + "rand 0.7.3", + "regex", + "sha2 0.10.2", + "smallvec", + "unsigned-varint", + "wasm-timer", ] [[package]] -name = "pallet-bridge-grandpa" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "libp2p-identify" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84b53490442d086db1fa5375670c9666e79143dccadef3f7c74a4346899a984" dependencies = [ - "bp-header-chain", - "bp-runtime", - "bp-test-utils", - "finality-grandpa", - "frame-support", - "frame-system", + "asynchronous-codec", + "futures", + "futures-timer", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "num-traits", - "parity-scale-codec", - "scale-info", - "serde", - "sp-finality-grandpa", - "sp-runtime", - "sp-std", - "sp-trie", + "lru", + "prost 0.10.4", + "prost-build 0.10.4", + "prost-codec", + "smallvec", + "thiserror", + "void", ] [[package]] -name = "pallet-bridge-messages" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "libp2p-kad" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6b5d4de90fcd35feb65ea6223fd78f3b747a64ca4b65e0813fbe66a27d56aa" dependencies = [ - "bitvec", - "bp-message-dispatch", - "bp-messages", - "bp-runtime", - "frame-support", - "frame-system", + "arrayvec 0.7.2", + "asynchronous-codec", + "bytes", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "num-traits", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-runtime", - "sp-std", + "prost 0.10.4", + "prost-build 0.10.4", + "rand 0.7.3", + "sha2 0.10.2", + "smallvec", + "thiserror", + "uint", + "unsigned-varint", + "void", ] [[package]] -name = "pallet-collator-selection" -version = "3.0.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "libp2p-mdns" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4783f8cf00c7b6c1ff0f1870b4fcf50b042b45533d2e13b6fb464caf447a6951" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "async-io", + "data-encoding", + "dns-parser", + "futures", + "if-watch", + "lazy_static", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "pallet-authorship", - "pallet-session", - "parity-scale-codec", "rand 0.8.5", - "scale-info", - "serde", - "sp-runtime", - "sp-staking", - "sp-std", + "smallvec", + "socket2", + "void", ] [[package]] -name = "pallet-collective" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-metrics" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "564a7e5284d7d9b3140fdfc3cb6567bc32555e86a21de5604c2ec85da05cf384" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "libp2p-core 0.33.0", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-kad", + "libp2p-ping", + "libp2p-relay", + "libp2p-swarm", + "prometheus-client", +] + +[[package]] +name = "libp2p-mplex" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ff9c893f2367631a711301d703c47432af898c9bb8253bea0e2c051a13f7640" +dependencies = [ + "asynchronous-codec", + "bytes", + "futures", + "libp2p-core 0.33.0", "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "nohash-hasher", + "parking_lot 0.12.1", + "rand 0.7.3", + "smallvec", + "unsigned-varint", ] [[package]] -name = "pallet-democracy" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-noise" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2cee1dad1c83325bbd182a8e94555778699cec8a9da00086efb7522c4c15ad" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "serde", - "sp-io", - "sp-runtime", - "sp-std", + "bytes", + "curve25519-dalek 3.2.0", + "futures", + "lazy_static", + "libp2p-core 0.33.0", + "log", + "prost 0.10.4", + "prost-build 0.10.4", + "rand 0.8.5", + "sha2 0.10.2", + "snow", + "static_assertions", + "x25519-dalek", + "zeroize", ] [[package]] -name = "pallet-dkg-metadata" -version = "0.1.0" +name = "libp2p-ping" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41516c82fe8dd148ec925eead0c5ec08a0628f7913597e93e126e4dfb4e0787" dependencies = [ - "dkg-runtime-primitives", - "frame-benchmarking", - "frame-support", - "frame-system", - "hex", - "libsecp256k1 0.7.0", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "pallet-session", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-staking", - "sp-std", + "rand 0.7.3", + "void", ] [[package]] -name = "pallet-dkg-proposal-handler" -version = "0.1.0" +name = "libp2p-plaintext" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db007e737adc5d28b2e03223b0210164928ad742591127130796a72aa8eaf54f" dependencies = [ - "dkg-runtime-primitives", - "frame-benchmarking", - "frame-support", - "frame-system", - "hex-literal", - "pallet-aura", - "pallet-balances", - "pallet-dkg-metadata", - "pallet-dkg-proposals", - "pallet-session", - "pallet-timestamp", - "parity-scale-codec", - "scale-info", - "serde", - "sp-consensus-aura", - "sp-core", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-staking", - "sp-std", + "asynchronous-codec", + "bytes", + "futures", + "libp2p-core 0.33.0", + "log", + "prost 0.10.4", + "prost-build 0.10.4", + "unsigned-varint", + "void", ] [[package]] -name = "pallet-dkg-proposals" -version = "1.0.0" +name = "libp2p-pnet" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1a458bbda880107b5b36fcb9b5a1ef0c329685da0e203ed692a8ebe64cc92c" dependencies = [ - "dkg-runtime-primitives", - "frame-benchmarking", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "hex", - "k256", + "futures", "log", - "pallet-aura", - "pallet-balances", - "pallet-collator-selection", - "pallet-dkg-metadata", - "pallet-dkg-proposal-handler", - "pallet-session", - "pallet-timestamp", - "parity-scale-codec", - "scale-info", - "sp-consensus-aura", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "pin-project 1.0.10", + "rand 0.7.3", + "salsa20", + "sha3 0.9.1", ] [[package]] -name = "pallet-election-provider-multi-phase" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-relay" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624ead3406f64437a0d4567c31bd128a9a0b8226d5f16c074038f5d0fc32f650" dependencies = [ - "frame-benchmarking", - "frame-election-provider-support", - "frame-support", - "frame-system", + "asynchronous-codec", + "bytes", + "either", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "parity-scale-codec", - "rand 0.7.3", - "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-npos-elections", - "sp-runtime", - "sp-std", + "pin-project 1.0.10", + "prost 0.10.4", + "prost-build 0.10.4", + "prost-codec", + "rand 0.8.5", + "smallvec", "static_assertions", - "strum 0.23.0", + "thiserror", + "void", ] [[package]] -name = "pallet-elections-phragmen" -version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-rendezvous" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59967ea2db2c7560f641aa58ac05982d42131863fcd3dd6dcf0dd1daf81c60c" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "asynchronous-codec", + "bimap", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.33.0", + "libp2p-swarm", "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-npos-elections", - "sp-runtime", - "sp-std", + "prost 0.10.4", + "prost-build 0.10.4", + "rand 0.8.5", + "sha2 0.10.2", + "thiserror", + "unsigned-varint", + "void", ] [[package]] -name = "pallet-gilt" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-request-response" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b02e0acb725e5a757d77c96b95298fd73a7394fe82ba7b8bbeea510719cbe441" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-arithmetic", - "sp-runtime", - "sp-std", + "async-trait", + "bytes", + "futures", + "instant", + "libp2p-core 0.33.0", + "libp2p-swarm", + "log", + "rand 0.7.3", + "smallvec", + "unsigned-varint", ] [[package]] -name = "pallet-grandpa" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-swarm" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4bb21c5abadbf00360c734f16bf87f1712ed4f23cd46148f625d2ddb867346" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.33.0", "log", - "pallet-authorship", - "pallet-session", - "parity-scale-codec", - "scale-info", - "sp-application-crypto", - "sp-core", - "sp-finality-grandpa", - "sp-io", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", + "pin-project 1.0.10", + "rand 0.7.3", + "smallvec", + "thiserror", + "void", ] [[package]] -name = "pallet-identity" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-swarm-derive" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f693c8c68213034d472cbb93a379c63f4f307d97c06f1c41e4985de481687a5" dependencies = [ - "enumflags2", - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "quote", + "syn", ] [[package]] -name = "pallet-im-online" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-tcp" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4933e38ef21b50698aefc87799c24f2a365c9d3f6cf50471f3f6a0bc410892" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "async-io", + "futures", + "futures-timer", + "if-watch", + "ipnet", + "libc", + "libp2p-core 0.33.0", "log", - "pallet-authorship", - "parity-scale-codec", - "scale-info", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", + "socket2", ] [[package]] -name = "pallet-indices" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-uds" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24bdab114f7f2701757d6541266e1131b429bbae382008f207f2114ee4222dcb" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-keyring", - "sp-runtime", - "sp-std", + "async-std", + "futures", + "libp2p-core 0.32.1", + "log", ] [[package]] -name = "pallet-membership" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-wasm-ext" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f066f2b8b1a1d64793f05da2256e6842ecd0293d6735ca2e9bda89831a1bdc06" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "futures", + "js-sys", + "libp2p-core 0.33.0", + "parity-send-wrapper", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "libp2p-websocket" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39d398fbb29f432c4128fabdaac2ed155c3bcaf1b9bd40eeeb10a471eefacbf5" +dependencies = [ + "either", + "futures", + "futures-rustls", + "libp2p-core 0.33.0", "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "parking_lot 0.12.1", + "quicksink", + "rw-stream-sink 0.3.0", + "soketto", + "url", + "webpki-roots", ] [[package]] -name = "pallet-mmr" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libp2p-yamux" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fe653639ad74877c759720febb0cbcbf4caa221adde4eed2d3126ce5c6f381f" dependencies = [ - "ckb-merkle-mountain-range", - "frame-benchmarking", - "frame-support", - "frame-system", - "pallet-mmr-primitives", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "futures", + "libp2p-core 0.33.0", + "parking_lot 0.12.1", + "thiserror", + "yamux", ] [[package]] -name = "pallet-mmr-primitives" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "librocksdb-sys" +version = "0.6.1+6.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc587013734dadb7cf23468e531aa120788b87243648be42e2d3a072186291" dependencies = [ - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "serde", - "sp-api", - "sp-core", - "sp-runtime", - "sp-std", + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "tikv-jemalloc-sys", ] [[package]] -name = "pallet-mmr-rpc" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libsecp256k1" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" dependencies = [ - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "pallet-mmr-primitives", - "parity-scale-codec", - "serde", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-runtime", + "arrayref", + "crunchy", + "digest 0.8.1", + "hmac-drbg 0.2.0", + "rand 0.7.3", + "sha2 0.8.2", + "subtle 2.4.1", + "typenum", ] [[package]] -name = "pallet-multisig" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libsecp256k1" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0452aac8bab02242429380e9b2f94ea20cea2b37e2c1777a1358799bbe97f37" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "arrayref", + "base64", + "digest 0.9.0", + "hmac-drbg 0.3.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.8.5", + "serde", + "sha2 0.9.9", + "typenum", ] [[package]] -name = "pallet-nicks" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "crunchy", + "digest 0.9.0", + "subtle 2.4.1", ] [[package]] -name = "pallet-offences" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" dependencies = [ - "frame-support", - "frame-system", - "log", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "serde", - "sp-runtime", - "sp-staking", - "sp-std", + "libsecp256k1-core", ] [[package]] -name = "pallet-offences-benchmarking" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" dependencies = [ - "frame-benchmarking", - "frame-election-provider-support", - "frame-support", - "frame-system", - "pallet-babe", - "pallet-balances", - "pallet-grandpa", - "pallet-im-online", - "pallet-offences", - "pallet-session", - "pallet-staking", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-staking", - "sp-std", + "libsecp256k1-core", ] [[package]] -name = "pallet-preimage" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "cc", + "pkg-config", + "vcpkg", ] [[package]] -name = "pallet-proxy" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linked_hash_set" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "linked-hash-map", ] [[package]] -name = "pallet-randomness-collective-flip" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "linregress" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c601a85f5ecd1aba625247bca0031585fb1c446461b142878a16f8245ddeb8" dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "safe-mix", - "scale-info", - "sp-runtime", - "sp-std", + "nalgebra", + "statrs", ] [[package]] -name = "pallet-recovery" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "linux-raw-sys" +version = "0.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5284f00d480e1c39af34e72f8ad60b94f47007e3481cd3b731c1d67190ddc7b7" + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "autocfg 1.1.0", + "scopeguard", ] [[package]] -name = "pallet-scheduler" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "cfg-if", + "value-bag", ] [[package]] -name = "pallet-session" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "lru" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84e6fe5655adc6ce00787cf7dcaf8dc4f998a0565d23eafc207a8b08ca3349a" dependencies = [ - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "log", - "pallet-timestamp", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-trie", + "hashbrown 0.11.2", ] [[package]] -name = "pallet-session-benchmarking" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "pallet-session", - "pallet-staking", - "rand 0.7.3", - "sp-runtime", - "sp-session", - "sp-std", + "linked-hash-map", ] [[package]] -name = "pallet-society" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "lz4" +version = "1.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4edcb94251b1c375c459e5abe9fb0168c1c826c3370172684844f8f3f8d1a885" dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "rand_chacha 0.2.2", - "scale-info", - "sp-runtime", - "sp-std", + "libc", + "lz4-sys", ] [[package]] -name = "pallet-staking" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "lz4-sys" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7be8908e2ed6f31c02db8a9fa962f03e36c53fbfde437363eae3306b85d7e17" dependencies = [ - "frame-benchmarking", - "frame-election-provider-support", - "frame-support", - "frame-system", - "log", - "pallet-authorship", - "pallet-session", - "parity-scale-codec", - "rand_chacha 0.2.2", - "scale-info", - "serde", - "sp-application-crypto", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", + "cc", + "libc", ] [[package]] -name = "pallet-staking-reward-curve" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn", + "libc", ] [[package]] -name = "pallet-staking-reward-fn" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" dependencies = [ - "log", - "sp-arithmetic", + "regex-automata", ] [[package]] -name = "pallet-sudo" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "matrixmultiply" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "rawpointer", ] [[package]] -name = "pallet-timestamp" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memfd" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6627dc657574b49d6ad27105ed671822be56e0d2547d413bfbf3e8d8fa92e7a" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", - "sp-timestamp", + "libc", ] [[package]] -name = "pallet-tips" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "memmap2" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "pallet-treasury", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "libc", ] [[package]] -name = "pallet-transaction-payment" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "memmap2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae" dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "serde", - "smallvec", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "libc", ] [[package]] -name = "pallet-transaction-payment-rpc" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "pallet-transaction-payment-rpc-runtime-api", - "parity-scale-codec", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-rpc", - "sp-runtime", + "autocfg 1.1.0", ] [[package]] -name = "pallet-transaction-payment-rpc-runtime-api" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "memory-db" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6566c70c1016f525ced45d7b7f97730a2bafb037c788211d0c186ef5b2189f0a" dependencies = [ - "pallet-transaction-payment", - "parity-scale-codec", - "sp-api", - "sp-runtime", + "hash-db", + "hashbrown 0.12.1", + "parity-util-mem", ] [[package]] -name = "pallet-treasury" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merkle-cbt" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171d2f700835121c3b04ccf0880882987a050fd5c7ae88148abf537d33dd3a56" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "serde", - "sp-runtime", - "sp-std", + "cfg-if", ] [[package]] -name = "pallet-utility" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", ] [[package]] -name = "pallet-vesting" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-std", + "adler", ] [[package]] -name = "pallet-xcm" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ - "frame-support", - "frame-system", + "libc", "log", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-runtime", - "sp-std", - "xcm", - "xcm-executor", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", ] [[package]] -name = "pallet-xcm-benchmarks" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "more-asserts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" + +[[package]] +name = "multi-party-ecdsa" +version = "0.8.1" +source = "git+https://github.com/webb-tools/multi-party-ecdsa.git#90bba3013e169c5cd039bfd8b2b98fab53f75cfa" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-std", - "xcm", - "xcm-executor", + "centipede", + "curv-kzen", + "derivative", + "kzen-paillier", + "round-based", + "serde", + "sha2 0.9.9", + "subtle 2.4.1", + "thiserror", + "zeroize", + "zk-paillier", ] [[package]] -name = "parachain-info" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.17#76479e7fef3af7c8828a44647847b01afd5fefe5" +name = "multiaddr" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c580bfdd8803cce319b047d239559a22f809094aaea4ac13902a1fdcfcd4261" dependencies = [ - "cumulus-primitives-core", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", + "arrayref", + "bs58", + "byteorder", + "data-encoding", + "multihash", + "percent-encoding", "serde", + "static_assertions", + "unsigned-varint", + "url", ] [[package]] -name = "parity-db" -version = "0.3.8" +name = "multibase" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "865edee5b792f537356d9e55cbc138e7f4718dc881a7ea45a18b37bf61c21e3d" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" dependencies = [ - "blake2-rfc", - "crc32fast", - "fs2", - "hex", - "libc", - "log", - "lz4", - "memmap2 0.2.3", - "parking_lot 0.11.2", - "rand 0.8.5", - "snap", + "base-x", + "data-encoding", + "data-encoding-macro", ] [[package]] -name = "parity-scale-codec" -version = "2.3.1" +name = "multihash" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +checksum = "e3db354f401db558759dfc1e568d010a5d4146f4d3f637be1275ec4a3cf09689" dependencies = [ - "arrayvec 0.7.2", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest 0.10.3", + "multihash-derive", + "sha2 0.10.2", + "sha3 0.10.1", + "unsigned-varint", ] [[package]] -name = "parity-scale-codec-derive" -version = "2.3.1" +name = "multihash-derive" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate", + "proc-macro-error", "proc-macro2", "quote", "syn", + "synstructure", ] [[package]] -name = "parity-send-wrapper" -version = "0.1.0" +name = "multimap" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] -name = "parity-tokio-ipc" -version = "0.9.0" +name = "multistream-select" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" +checksum = "363a84be6453a70e63513660f4894ef815daf88e3356bffcda9ca27d810ce83b" dependencies = [ - "futures 0.3.21", - "libc", + "bytes", + "futures", "log", - "rand 0.7.3", - "tokio", - "winapi 0.3.9", + "pin-project 1.0.10", + "smallvec", + "unsigned-varint", ] [[package]] -name = "parity-util-mem" -version = "0.10.2" +name = "nalgebra" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4cb4e169446179cbc6b8b6320cc9fca49bd2e94e8db25f25f200a8ea774770" +checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120" dependencies = [ - "cfg-if 1.0.0", - "hashbrown 0.11.2", - "impl-trait-for-tuples", - "parity-util-mem-derive", - "parking_lot 0.11.2", - "primitive-types", - "smallvec", - "winapi 0.3.9", + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational 0.4.1", + "num-traits", + "rand 0.8.5", + "rand_distr", + "simba", + "typenum", ] [[package]] -name = "parity-util-mem-derive" +name = "nalgebra-macros" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" dependencies = [ "proc-macro2", + "quote", "syn", - "synstructure", ] [[package]] -name = "parity-wasm" -version = "0.32.0" +name = "names" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" +checksum = "e7d66043b25d4a6cccb23619d10c19c25304b355a7dccd4a8e11423dd2382146" dependencies = [ - "byteorder", + "rand 0.8.5", ] [[package]] -name = "parity-wasm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" - -[[package]] -name = "parity-ws" -version = "0.11.1" +name = "netlink-packet-core" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5983d3929ad50f12c3eb9a6743f19d691866ecd44da74c0a3308c3f8a56df0c6" +checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" dependencies = [ + "anyhow", "byteorder", - "bytes 0.4.12", - "httparse", - "log", - "mio 0.6.23", - "mio-extras", - "rand 0.7.3", - "sha-1 0.8.2", - "slab", - "url 2.2.2", + "libc", + "netlink-packet-utils", ] [[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] -name = "parking_lot" -version = "0.10.2" +name = "netlink-packet-route" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.7.2", + "anyhow", + "bitflags", + "byteorder", + "libc", + "netlink-packet-core", + "netlink-packet-utils", ] [[package]] -name = "parking_lot" -version = "0.11.2" +name = "netlink-packet-utils" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e" dependencies = [ - "instant", - "lock_api 0.4.6", - "parking_lot_core 0.8.5", + "anyhow", + "byteorder", + "paste", + "thiserror", ] [[package]] -name = "parking_lot" -version = "0.12.0" +name = "netlink-proto" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ - "lock_api 0.4.6", - "parking_lot_core 0.9.1", + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror", + "tokio", ] [[package]] -name = "parking_lot_core" -version = "0.7.2" +name = "netlink-sys" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +checksum = "92b654097027250401127914afb37cb1f311df6610a9891ff07a757e94199027" dependencies = [ - "cfg-if 0.1.10", - "cloudabi", + "async-io", + "bytes", + "futures", "libc", - "redox_syscall 0.1.57", - "smallvec", - "winapi 0.3.9", + "log", ] [[package]] -name = "parking_lot_core" -version = "0.8.5" +name = "nix" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9" dependencies = [ - "cfg-if 1.0.0", - "instant", + "bitflags", + "cfg-if", "libc", - "redox_syscall 0.2.11", - "smallvec", - "winapi 0.3.9", ] [[package]] -name = "parking_lot_core" -version = "0.9.1" +name = "nodrop" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.2.11", - "smallvec", - "windows-sys", -] +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] -name = "paste" -version = "1.0.6" +name = "nohash-hasher" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] -name = "pbkdf2" -version = "0.4.0" +name = "nom" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ - "crypto-mac 0.8.0", + "memchr", + "minimal-lexical", ] [[package]] -name = "pbkdf2" -version = "0.8.0" +name = "num-bigint" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "crypto-mac 0.11.1", + "autocfg 1.1.0", + "num-integer", + "num-traits", ] [[package]] -name = "peeking_take_while" -version = "0.1.2" +name = "num-complex" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" +dependencies = [ + "num-traits", +] [[package]] -name = "percent-encoding" -version = "1.0.1" +name = "num-format" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" +dependencies = [ + "arrayvec 0.4.12", + "itoa 0.4.8", +] [[package]] -name = "percent-encoding" -version = "2.1.0" +name = "num-integer" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg 1.1.0", + "num-traits", +] [[package]] -name = "pest" -version = "2.1.3" +name = "num-rational" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ - "ucd-trie", + "autocfg 1.1.0", + "num-bigint", + "num-integer", + "num-traits", ] [[package]] -name = "pest_derive" -version = "2.1.0" +name = "num-rational" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ - "pest", - "pest_generator", + "autocfg 1.1.0", + "num-integer", + "num-traits", ] [[package]] -name = "pest_generator" -version = "2.1.3" +name = "num-traits" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", + "autocfg 1.1.0", + "libm", ] [[package]] -name = "pest_meta" -version = "2.1.3" +name = "num_cpus" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "maplit", - "pest", - "sha-1 0.8.2", + "hermit-abi", + "libc", ] [[package]] -name = "petgraph" -version = "0.6.0" +name = "object" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" dependencies = [ - "fixedbitset", + "crc32fast", "indexmap", + "memchr", ] [[package]] -name = "pin-project" -version = "0.4.29" +name = "object" +version = "0.28.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909" +checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" dependencies = [ - "pin-project-internal 0.4.29", + "memchr", ] [[package]] -name = "pin-project" -version = "1.0.10" +name = "once_cell" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" -dependencies = [ - "pin-project-internal 1.0.10", -] +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] -name = "pin-project-internal" -version = "0.4.29" +name = "opaque-debug" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] -name = "pin-project-internal" -version = "1.0.10" +name = "opaque-debug" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "pin-project-lite" -version = "0.1.12" +name = "openssl-probe" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] -name = "pin-project-lite" -version = "0.2.8" +name = "os_str_bytes" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" [[package]] -name = "pin-utils" -version = "0.1.0" +name = "owning_ref" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" +dependencies = [ + "stable_deref_trait", +] [[package]] -name = "pkcs8" -version = "0.7.6" +name = "p256" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" dependencies = [ - "der 0.4.5", - "spki 0.4.1", + "ecdsa 0.12.4", + "elliptic-curve 0.10.6", + "sha2 0.9.9", ] [[package]] -name = "pkcs8" -version = "0.8.0" +name = "pairing-plus" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "58cda4f22e8e6720f3c254049960c8cc4f93cb82b5ade43bddd2622b5f39ea62" dependencies = [ - "der 0.5.1", - "spki 0.5.4", + "byteorder", + "digest 0.8.1", + "ff-zeroize", + "rand 0.4.6", + "rand_core 0.5.1", + "rand_xorshift 0.2.0", "zeroize", ] [[package]] -name = "pkg-config" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +name = "pallet-aura" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +dependencies = [ + "frame-support", + "frame-system", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-consensus-aura", + "sp-runtime", + "sp-std", +] [[package]] -name = "platforms" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" +name = "pallet-authorship" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "sp-authorship", + "sp-runtime", + "sp-std", +] [[package]] -name = "polkadot-approval-distribution" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-babe" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "tracing", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-application-crypto", + "sp-consensus-babe", + "sp-consensus-vrf", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", ] [[package]] -name = "polkadot-availability-bitfield-distribution" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-bags-list" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "polkadot-node-network-protocol", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "tracing", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", ] [[package]] -name = "polkadot-availability-distribution" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-balances" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "derive_more", - "futures 0.3.21", - "lru 0.7.3", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", "parity-scale-codec", - "polkadot-erasure-coding", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "rand 0.8.5", - "sp-core", - "sp-keystore", - "thiserror", - "tracing", + "scale-info", + "sp-runtime", + "sp-std", ] [[package]] -name = "polkadot-availability-recovery" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-collator-selection" +version = "3.0.0" +source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.24#95ca5a085727c1494ddeeae4a2b2e69c4ee1933b" dependencies = [ - "futures 0.3.21", - "lru 0.7.3", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", "parity-scale-codec", - "polkadot-erasure-coding", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", "rand 0.8.5", - "sc-network", - "thiserror", - "tracing", + "scale-info", + "serde", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] -name = "polkadot-cli" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-dkg-metadata" +version = "0.1.0" dependencies = [ - "clap", - "frame-benchmarking-cli", - "futures 0.3.21", + "dkg-runtime-primitives", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex", + "libsecp256k1 0.7.0", "log", - "polkadot-node-core-pvf", - "polkadot-node-metrics", - "polkadot-performance-test", - "polkadot-service", - "sc-cli", - "sc-service", - "sc-tracing", + "pallet-session", + "parity-scale-codec", + "scale-info", + "serde", "sp-core", - "sp-trie", - "substrate-build-script-utils", - "thiserror", - "try-runtime-cli", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] -name = "polkadot-client" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-dkg-proposal-handler" +version = "0.1.0" dependencies = [ - "beefy-primitives", + "dkg-runtime-primitives", "frame-benchmarking", - "frame-system-rpc-runtime-api", - "pallet-mmr-primitives", - "pallet-transaction-payment-rpc-runtime-api", - "polkadot-primitives", - "polkadot-runtime", - "rococo-runtime", - "sc-client-api", - "sc-consensus", - "sc-executor", - "sc-service", - "sp-api", - "sp-authority-discovery", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-consensus-babe", - "sp-finality-grandpa", - "sp-offchain", + "frame-support", + "frame-system", + "hex-literal", + "pallet-aura", + "pallet-balances", + "pallet-dkg-metadata", + "pallet-dkg-proposals", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "serde", + "sp-consensus-aura", + "sp-core", + "sp-io", + "sp-keystore", "sp-runtime", - "sp-session", - "sp-storage", - "sp-transaction-pool", + "sp-staking", + "sp-std", ] [[package]] -name = "polkadot-collator-protocol" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-dkg-proposals" +version = "1.0.0" dependencies = [ - "always-assert", - "derive_more", - "futures 0.3.21", - "futures-timer", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", + "dkg-runtime-primitives", + "frame-benchmarking", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "hex", + "k256", + "log", + "pallet-aura", + "pallet-balances", + "pallet-collator-selection", + "pallet-dkg-metadata", + "pallet-dkg-proposal-handler", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-consensus-aura", "sp-core", - "sp-keystore", + "sp-io", "sp-runtime", - "thiserror", - "tracing", + "sp-std", ] [[package]] -name = "polkadot-core-primitives" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-election-provider-multi-phase" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ + "frame-benchmarking", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", "parity-scale-codec", - "parity-util-mem", + "rand 0.7.3", "scale-info", + "sp-arithmetic", "sp-core", + "sp-io", + "sp-npos-elections", "sp-runtime", "sp-std", + "static_assertions", + "strum 0.23.0", ] [[package]] -name = "polkadot-dispute-distribution" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-grandpa" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "derive_more", - "futures 0.3.21", - "lru 0.7.3", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", "parity-scale-codec", - "polkadot-erasure-coding", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "sc-network", + "scale-info", "sp-application-crypto", - "sp-keystore", - "thiserror", - "tracing", + "sp-core", + "sp-finality-grandpa", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", ] [[package]] -name = "polkadot-erasure-coding" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-indices" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ + "frame-support", + "frame-system", "parity-scale-codec", - "polkadot-node-primitives", - "polkadot-primitives", - "reed-solomon-novelpoly", + "scale-info", "sp-core", - "sp-trie", - "thiserror", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-std", ] [[package]] -name = "polkadot-gossip-support" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-nomination-pools" +version = "1.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "futures-timer", - "polkadot-node-network-protocol", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "rand 0.8.5", - "rand_chacha 0.3.1", - "sc-network", - "sp-application-crypto", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", "sp-core", - "sp-keystore", - "tracing", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] -name = "polkadot-network-bridge" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-randomness-collective-flip" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "async-trait", - "futures 0.3.21", + "frame-support", + "frame-system", "parity-scale-codec", - "parking_lot 0.11.2", - "polkadot-node-network-protocol", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-overseer", - "polkadot-primitives", - "sc-network", - "sp-consensus", - "tracing", + "safe-mix", + "scale-info", + "sp-runtime", + "sp-std", ] [[package]] -name = "polkadot-node-collation-generation" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-session" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "pallet-timestamp", "parity-scale-codec", - "polkadot-erasure-coding", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", + "scale-info", "sp-core", - "sp-maybe-compressed-blob", - "thiserror", - "tracing", + "sp-io", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-trie", ] [[package]] -name = "polkadot-node-core-approval-voting" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-staking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "bitvec", - "derive_more", - "futures 0.3.21", - "futures-timer", - "kvdb", - "lru 0.7.3", - "merlin", + "frame-election-provider-support", + "frame-support", + "frame-system", + "log", + "pallet-authorship", + "pallet-session", "parity-scale-codec", - "polkadot-node-jaeger", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-overseer", - "polkadot-primitives", - "sc-keystore", - "schnorrkel", + "scale-info", + "serde", "sp-application-crypto", - "sp-consensus", - "sp-consensus-slots", + "sp-io", "sp-runtime", - "tracing", -] - -[[package]] -name = "polkadot-node-core-av-store" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bitvec", - "futures 0.3.21", - "futures-timer", - "kvdb", - "parity-scale-codec", - "polkadot-erasure-coding", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-overseer", - "polkadot-primitives", - "thiserror", - "tracing", -] - -[[package]] -name = "polkadot-node-core-backing" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bitvec", - "futures 0.3.21", - "polkadot-erasure-coding", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "polkadot-statement-table", - "sp-keystore", - "thiserror", - "tracing", -] - -[[package]] -name = "polkadot-node-core-bitfield-signing" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "futures 0.3.21", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "sp-keystore", - "thiserror", - "tracing", - "wasm-timer", -] - -[[package]] -name = "polkadot-node-core-candidate-validation" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "async-trait", - "futures 0.3.21", - "parity-scale-codec", - "polkadot-node-core-pvf", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-parachain", - "polkadot-primitives", - "sp-maybe-compressed-blob", - "tracing", + "sp-staking", + "sp-std", ] [[package]] -name = "polkadot-node-core-chain-api" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-staking-reward-curve" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "sc-client-api", - "sc-consensus-babe", - "sp-blockchain", - "tracing", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "polkadot-node-core-chain-selection" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-sudo" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "futures-timer", - "kvdb", + "frame-support", + "frame-system", "parity-scale-codec", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "thiserror", - "tracing", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] -name = "polkadot-node-core-dispute-coordinator" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-timestamp" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "kvdb", - "lru 0.7.3", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", "parity-scale-codec", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "sc-keystore", - "thiserror", - "tracing", -] - -[[package]] -name = "polkadot-node-core-parachains-inherent" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "async-trait", - "futures 0.3.21", - "futures-timer", - "polkadot-node-subsystem", - "polkadot-primitives", - "sp-blockchain", + "scale-info", "sp-inherents", + "sp-io", "sp-runtime", - "thiserror", - "tracing", -] - -[[package]] -name = "polkadot-node-core-provisioner" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "bitvec", - "futures 0.3.21", - "futures-timer", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "rand 0.8.5", - "thiserror", - "tracing", + "sp-std", + "sp-timestamp", ] [[package]] -name = "polkadot-node-core-pvf" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-transaction-payment" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "always-assert", - "assert_matches", - "async-process", - "async-std", - "futures 0.3.21", - "futures-timer", + "frame-support", + "frame-system", "parity-scale-codec", - "pin-project 1.0.10", - "polkadot-core-primitives", - "polkadot-node-subsystem-util", - "polkadot-parachain", - "rand 0.8.5", - "sc-executor", - "sc-executor-common", - "sc-executor-wasmtime", - "slotmap", + "scale-info", + "serde", "sp-core", - "sp-externalities", "sp-io", - "sp-maybe-compressed-blob", - "sp-tracing", - "sp-wasm-interface", - "tracing", -] - -[[package]] -name = "polkadot-node-core-pvf-checker" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "futures 0.3.21", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-overseer", - "polkadot-primitives", - "sp-keystore", - "thiserror", - "tracing", -] - -[[package]] -name = "polkadot-node-core-runtime-api" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "futures 0.3.21", - "memory-lru", - "parity-util-mem", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "sp-api", - "sp-authority-discovery", - "sp-consensus-babe", - "sp-core", - "tracing", + "sp-runtime", + "sp-std", ] [[package]] -name = "polkadot-node-jaeger" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-transaction-payment-rpc" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "async-std", - "lazy_static", - "log", - "mick-jaeger", + "jsonrpsee", + "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", - "parking_lot 0.11.2", - "polkadot-node-primitives", - "polkadot-primitives", - "sc-network", + "sp-api", + "sp-blockchain", "sp-core", - "thiserror", + "sp-rpc", + "sp-runtime", ] [[package]] -name = "polkadot-node-metrics" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pallet-transaction-payment-rpc-runtime-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "bs58", - "futures 0.3.21", - "futures-timer", - "log", - "metered-channel", + "pallet-transaction-payment", "parity-scale-codec", - "polkadot-primitives", - "sc-cli", - "sc-service", - "sc-tracing", - "substrate-prometheus-endpoint", - "tracing", + "sp-api", + "sp-runtime", ] [[package]] -name = "polkadot-node-network-protocol" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parity-db" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "966eb23bd3a09758b8dac09f82b9d417c00f14e5d46171bf04cffdd9cb2e1eb1" dependencies = [ - "async-trait", - "derive_more", - "futures 0.3.21", - "parity-scale-codec", - "polkadot-node-jaeger", - "polkadot-node-primitives", - "polkadot-primitives", - "sc-authority-discovery", - "sc-network", - "strum 0.23.0", - "thiserror", + "blake2-rfc", + "crc32fast", + "fs2", + "hex", + "libc", + "log", + "lz4", + "memmap2 0.2.3", + "parking_lot 0.11.2", + "rand 0.8.5", + "snap", ] [[package]] -name = "polkadot-node-primitives" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parity-scale-codec" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182e4a71cae089267ab03e67c99368db7cd877baf50f931e5d6d4b71e195ac0" dependencies = [ - "bounded-vec", - "futures 0.3.21", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-primitives", - "schnorrkel", + "arrayvec 0.7.2", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", "serde", - "sp-application-crypto", - "sp-consensus-babe", - "sp-consensus-vrf", - "sp-core", - "sp-keystore", - "sp-maybe-compressed-blob", - "thiserror", - "zstd", ] [[package]] -name = "polkadot-node-subsystem" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parity-scale-codec-derive" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" dependencies = [ - "polkadot-node-jaeger", - "polkadot-node-subsystem-types", - "polkadot-overseer", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "polkadot-node-subsystem-types" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parity-send-wrapper" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" + +[[package]] +name = "parity-util-mem" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c32561d248d352148124f036cac253a644685a21dc9fea383eb4907d7bd35a8f" dependencies = [ - "derive_more", - "futures 0.3.21", - "polkadot-node-jaeger", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-overseer-gen", - "polkadot-primitives", - "polkadot-statement-table", - "sc-network", + "cfg-if", + "hashbrown 0.12.1", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "parking_lot 0.12.1", + "primitive-types", "smallvec", - "substrate-prometheus-endpoint", - "thiserror", + "winapi", ] [[package]] -name = "polkadot-node-subsystem-util" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ - "async-trait", - "derive_more", - "futures 0.3.21", - "itertools 0.10.3", - "lru 0.7.3", - "metered-channel", - "parity-scale-codec", - "pin-project 1.0.10", - "polkadot-node-jaeger", - "polkadot-node-metrics", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-overseer", - "polkadot-primitives", - "rand 0.8.5", - "sp-application-crypto", - "sp-core", - "sp-keystore", - "thiserror", - "tracing", + "proc-macro2", + "syn", + "synstructure", ] [[package]] -name = "polkadot-overseer" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parity-wasm" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" dependencies = [ - "futures 0.3.21", - "futures-timer", - "lru 0.7.3", - "parity-util-mem", - "parking_lot 0.11.2", - "polkadot-node-metrics", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem-types", - "polkadot-overseer-gen", - "polkadot-primitives", - "sc-client-api", - "sp-api", - "tracing", + "byteorder", ] [[package]] -name = "polkadot-overseer-gen" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "async-trait", - "futures 0.3.21", - "futures-timer", - "metered-channel", - "pin-project 1.0.10", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-overseer-gen-proc-macro", - "thiserror", - "tracing", -] +name = "parity-wasm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" [[package]] -name = "polkadot-overseer-gen-proc-macro" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn", + "instant", + "lock_api", + "parking_lot_core 0.8.5", ] [[package]] -name = "polkadot-parachain" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "derive_more", - "frame-support", - "parity-scale-codec", - "parity-util-mem", - "polkadot-core-primitives", - "scale-info", - "serde", - "sp-core", - "sp-runtime", - "sp-std", + "lock_api", + "parking_lot_core 0.9.3", ] [[package]] -name = "polkadot-performance-test" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "env_logger", - "kusama-runtime", - "log", - "polkadot-erasure-coding", - "polkadot-node-core-pvf", - "polkadot-node-primitives", - "quote", - "thiserror", + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", ] [[package]] -name = "polkadot-primitives" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ - "bitvec", - "frame-system", - "hex-literal", - "parity-scale-codec", - "parity-util-mem", - "polkadot-core-primitives", - "polkadot-parachain", - "scale-info", - "serde", - "sp-api", - "sp-application-crypto", - "sp-arithmetic", - "sp-authority-discovery", - "sp-consensus-slots", - "sp-core", - "sp-inherents", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-staking", - "sp-std", - "sp-trie", - "sp-version", + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", ] [[package]] -name = "polkadot-rpc" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "paste" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" dependencies = [ - "beefy-gadget", - "beefy-gadget-rpc", - "jsonrpc-core", - "pallet-mmr-rpc", - "pallet-transaction-payment-rpc", - "polkadot-primitives", - "sc-chain-spec", - "sc-client-api", - "sc-consensus-babe", - "sc-consensus-babe-rpc", - "sc-consensus-epochs", - "sc-finality-grandpa", - "sc-finality-grandpa-rpc", - "sc-rpc", - "sc-sync-state-rpc", - "sc-transaction-pool-api", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-consensus-babe", - "sp-keystore", - "sp-runtime", - "substrate-frame-rpc-system", + "crypto-mac 0.8.0", ] [[package]] -name = "polkadot-runtime" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "beefy-primitives", - "bitvec", - "frame-benchmarking", - "frame-election-provider-support", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "frame-try-runtime", - "hex-literal", - "log", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-bags-list", - "pallet-balances", - "pallet-bounties", - "pallet-collective", - "pallet-democracy", - "pallet-election-provider-multi-phase", - "pallet-elections-phragmen", - "pallet-grandpa", - "pallet-identity", - "pallet-im-online", - "pallet-indices", - "pallet-membership", - "pallet-mmr-primitives", - "pallet-multisig", - "pallet-nicks", - "pallet-offences", - "pallet-offences-benchmarking", - "pallet-preimage", - "pallet-proxy", - "pallet-scheduler", - "pallet-session", - "pallet-session-benchmarking", - "pallet-staking", - "pallet-staking-reward-curve", - "pallet-timestamp", - "pallet-tips", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-treasury", - "pallet-utility", - "pallet-vesting", - "pallet-xcm", - "parity-scale-codec", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-constants", - "polkadot-runtime-parachains", - "rustc-hex", - "scale-info", - "serde", - "serde_derive", - "smallvec", - "sp-api", - "sp-authority-discovery", - "sp-block-builder", - "sp-consensus-babe", - "sp-core", - "sp-inherents", - "sp-io", - "sp-npos-elections", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-transaction-pool", - "sp-version", - "static_assertions", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-executor", +name = "pbkdf2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +dependencies = [ + "crypto-mac 0.11.1", ] [[package]] -name = "polkadot-runtime-common" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" dependencies = [ - "beefy-primitives", - "bitvec", - "frame-benchmarking", - "frame-election-provider-support", - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "libsecp256k1 0.7.0", - "log", - "pallet-authorship", - "pallet-babe", - "pallet-bags-list", - "pallet-balances", - "pallet-beefy-mmr", - "pallet-election-provider-multi-phase", - "pallet-session", - "pallet-staking", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-treasury", - "pallet-vesting", - "parity-scale-codec", - "polkadot-primitives", - "polkadot-runtime-parachains", - "rustc-hex", - "scale-info", - "serde", - "serde_derive", - "slot-range-helper", - "sp-api", - "sp-core", - "sp-inherents", - "sp-io", - "sp-npos-elections", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "static_assertions", - "xcm", + "ucd-trie", ] [[package]] -name = "polkadot-runtime-constants" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" dependencies = [ - "frame-support", - "polkadot-primitives", - "polkadot-runtime-common", - "smallvec", - "sp-runtime", + "pest", + "pest_generator", ] [[package]] -name = "polkadot-runtime-metrics" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ - "bs58", - "parity-scale-codec", - "polkadot-primitives", - "sp-std", - "sp-tracing", + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "polkadot-runtime-parachains" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" dependencies = [ - "bitflags", - "bitvec", - "derive_more", - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-balances", - "pallet-session", - "pallet-staking", - "pallet-timestamp", - "pallet-vesting", - "parity-scale-codec", - "polkadot-primitives", - "polkadot-runtime-metrics", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rustc-hex", - "scale-info", - "serde", - "sp-api", - "sp-core", - "sp-inherents", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "static_assertions", - "xcm", - "xcm-executor", + "maplit", + "pest", + "sha-1 0.8.2", ] [[package]] -name = "polkadot-service" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "petgraph" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" dependencies = [ - "async-trait", - "beefy-gadget", - "beefy-primitives", - "frame-system-rpc-runtime-api", - "futures 0.3.21", - "hex-literal", - "kusama-runtime", - "kvdb", - "kvdb-rocksdb", - "lru 0.7.3", - "pallet-babe", - "pallet-im-online", - "pallet-mmr-primitives", - "pallet-staking", - "pallet-transaction-payment-rpc-runtime-api", - "polkadot-approval-distribution", - "polkadot-availability-bitfield-distribution", - "polkadot-availability-distribution", - "polkadot-availability-recovery", - "polkadot-client", - "polkadot-collator-protocol", - "polkadot-dispute-distribution", - "polkadot-gossip-support", - "polkadot-network-bridge", - "polkadot-node-collation-generation", - "polkadot-node-core-approval-voting", - "polkadot-node-core-av-store", - "polkadot-node-core-backing", - "polkadot-node-core-bitfield-signing", - "polkadot-node-core-candidate-validation", - "polkadot-node-core-chain-api", - "polkadot-node-core-chain-selection", - "polkadot-node-core-dispute-coordinator", - "polkadot-node-core-parachains-inherent", - "polkadot-node-core-provisioner", - "polkadot-node-core-pvf-checker", - "polkadot-node-core-runtime-api", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-overseer", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-rpc", - "polkadot-runtime", - "polkadot-runtime-constants", - "polkadot-runtime-parachains", - "polkadot-statement-distribution", - "rococo-runtime", - "rococo-runtime-constants", - "sc-authority-discovery", - "sc-basic-authorship", - "sc-block-builder", - "sc-chain-spec", - "sc-client-api", - "sc-client-db", - "sc-consensus", - "sc-consensus-babe", - "sc-consensus-slots", - "sc-consensus-uncles", - "sc-executor", - "sc-finality-grandpa", - "sc-keystore", - "sc-network", - "sc-offchain", - "sc-service", - "sc-sync-state-rpc", - "sc-telemetry", - "sc-transaction-pool", - "serde", - "sp-api", - "sp-authority-discovery", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-consensus-babe", - "sp-core", - "sp-finality-grandpa", - "sp-inherents", - "sp-io", - "sp-keystore", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-state-machine", - "sp-storage", - "sp-timestamp", - "sp-transaction-pool", - "sp-trie", - "substrate-prometheus-endpoint", - "thiserror", - "tracing", - "westend-runtime", + "fixedbitset", + "indexmap", ] [[package]] -name = "polkadot-statement-distribution" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pin-project" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909" dependencies = [ - "arrayvec 0.5.2", - "derive_more", - "futures 0.3.21", - "indexmap", - "parity-scale-codec", - "polkadot-node-network-protocol", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-node-subsystem-util", - "polkadot-primitives", - "sp-keystore", - "sp-staking", - "thiserror", - "tracing", + "pin-project-internal 0.4.29", ] [[package]] -name = "polkadot-statement-table" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" dependencies = [ - "parity-scale-codec", - "polkadot-primitives", - "sp-core", + "pin-project-internal 1.0.10", ] [[package]] -name = "polkadot-test-runtime" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pin-project-internal" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a" dependencies = [ - "beefy-primitives", - "bitvec", - "frame-election-provider-support", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-rpc-runtime-api", - "log", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-balances", - "pallet-grandpa", - "pallet-indices", - "pallet-mmr-primitives", - "pallet-nicks", - "pallet-offences", - "pallet-session", - "pallet-staking", - "pallet-staking-reward-curve", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-vesting", - "pallet-xcm", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "rustc-hex", - "scale-info", - "serde", - "serde_derive", - "smallvec", - "sp-api", - "sp-authority-discovery", - "sp-block-builder", - "sp-consensus-babe", - "sp-core", - "sp-inherents", - "sp-io", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", - "test-runtime-constants", - "xcm", - "xcm-builder", - "xcm-executor", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der 0.4.5", + "spki 0.4.1", ] [[package]] -name = "polkadot-test-service" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ - "frame-benchmarking", - "frame-system", - "futures 0.1.31", - "futures 0.3.21", - "hex", - "pallet-balances", - "pallet-staking", - "pallet-transaction-payment", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-overseer", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-rpc", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "polkadot-service", - "polkadot-test-runtime", - "rand 0.8.5", - "sc-authority-discovery", - "sc-chain-spec", - "sc-cli", - "sc-client-api", - "sc-consensus", - "sc-consensus-babe", - "sc-executor", - "sc-finality-grandpa", - "sc-network", - "sc-service", - "sc-tracing", - "sc-transaction-pool", - "sp-arithmetic", - "sp-authority-discovery", - "sp-blockchain", - "sp-consensus", - "sp-consensus-babe", - "sp-core", - "sp-finality-grandpa", - "sp-inherents", - "sp-keyring", - "sp-runtime", - "sp-state-machine", - "substrate-test-client", - "tempfile", - "test-runtime-constants", - "tokio", - "tracing", + "der 0.5.1", + "spki 0.5.4", + "zeroize", ] +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "platforms" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" + [[package]] name = "polling" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "log", "wepoll-ffi", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -8264,7 +5256,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ - "cpufeatures 0.2.2", + "cpufeatures", "opaque-debug 0.3.0", "universal-hash", ] @@ -8275,8 +5267,8 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cfg-if", + "cpufeatures", "opaque-debug 0.3.0", "universal-hash", ] @@ -8289,9 +5281,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "primitive-types" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" dependencies = [ "fixed-hash", "impl-codec", @@ -8301,15 +5293,6 @@ dependencies = [ "uint", ] -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - [[package]] name = "proc-macro-crate" version = "1.1.3" @@ -8346,35 +5329,68 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "prometheus" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f64969ffd5dd8f39bd57a68ac53c163a095ed9d0fb707146da1b27025a3504" +checksum = "cface98dfa6d645ea4c789839f176e4b072265d085bfcc48eaa8d137f58d3c39" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "fnv", "lazy_static", "memchr", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "thiserror", ] +[[package]] +name = "prometheus-client" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1abe0255c04d15f571427a2d1e00099016506cf3297b53853acd2b7eb87825" +dependencies = [ + "dtoa", + "itoa 1.0.2", + "owning_ref", + "prometheus-client-derive-text-encode", +] + +[[package]] +name = "prometheus-client-derive-text-encode" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8e12d01b9d66ad9eb4529c57666b6263fc1993cb30261d83ead658fdd932652" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "prost" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" dependencies = [ - "bytes 1.1.0", - "prost-derive", + "bytes", + "prost-derive 0.9.0", +] + +[[package]] +name = "prost" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" +dependencies = [ + "bytes", + "prost-derive 0.10.1", ] [[package]] @@ -8383,20 +5399,55 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" dependencies = [ - "bytes 1.1.0", + "bytes", "heck 0.3.3", "itertools 0.10.3", "lazy_static", "log", "multimap", "petgraph", - "prost", - "prost-types", + "prost 0.9.0", + "prost-types 0.9.0", + "regex", + "tempfile", + "which", +] + +[[package]] +name = "prost-build" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae5a4388762d5815a9fc0dea33c56b021cdc8dde0c55e0c9ca57197254b0cab" +dependencies = [ + "bytes", + "cfg-if", + "cmake", + "heck 0.4.0", + "itertools 0.10.3", + "lazy_static", + "log", + "multimap", + "petgraph", + "prost 0.10.4", + "prost-types 0.10.1", "regex", "tempfile", "which", ] +[[package]] +name = "prost-codec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00af1e92c33b4813cc79fda3f2dbf56af5169709be0202df730e9ebc3e4cd007" +dependencies = [ + "asynchronous-codec", + "bytes", + "prost 0.10.4", + "thiserror", + "unsigned-varint", +] + [[package]] name = "prost-derive" version = "0.9.0" @@ -8410,21 +5461,44 @@ dependencies = [ "syn", ] +[[package]] +name = "prost-derive" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" +dependencies = [ + "anyhow", + "itertools 0.10.3", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "prost-types" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" dependencies = [ - "bytes 1.1.0", - "prost", + "bytes", + "prost 0.9.0", +] + +[[package]] +name = "prost-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" +dependencies = [ + "bytes", + "prost 0.10.4", ] [[package]] name = "psm" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eca0fa5dd7c4c96e184cec588f0b1db1ee3165e678db21c09793105acb17e6f" +checksum = "871372391786ccec00d3c5d3d6608905b3d4db263639cfe075d3b60a736d115a" dependencies = [ "cc", ] @@ -8435,12 +5509,6 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -[[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - [[package]] name = "quicksink" version = "0.1.2" @@ -8454,18 +5522,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.15" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ "proc-macro2", ] [[package]] name = "radium" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" @@ -8477,7 +5545,7 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -8496,7 +5564,7 @@ dependencies = [ "rand_os", "rand_pcg 0.1.2", "rand_xorshift 0.1.1", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -8584,7 +5652,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.5", + "getrandom 0.2.7", ] [[package]] @@ -8632,7 +5700,7 @@ checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" dependencies = [ "libc", "rand_core 0.4.2", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -8646,7 +5714,7 @@ dependencies = [ "libc", "rand_core 0.4.2", "rdrand", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -8668,6 +5736,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core 0.6.3", +] + [[package]] name = "rand_xorshift" version = "0.1.1" @@ -8694,9 +5771,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg 1.1.0", "crossbeam-deque", @@ -8706,14 +5783,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] @@ -8728,56 +5804,38 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" -dependencies = [ - "getrandom 0.2.5", - "redox_syscall 0.2.11", -] - -[[package]] -name = "reed-solomon-novelpoly" -version = "1.0.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd8f48b2066e9f69ab192797d66da804d1935bf22763204ed3675740cb0f221" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "derive_more", - "fs-err", - "itertools 0.10.3", - "static_init", + "getrandom 0.2.7", + "redox_syscall", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +checksum = "685d58625b6c2b83e4cc88a27c4bf65adb7b6b16dbdc413e515c9405b47432ab" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +checksum = "a043824e29c94169374ac5183ac0ed43f5724dc4556b19568007486bd840fa1f" dependencies = [ "proc-macro2", "quote", @@ -8786,9 +5844,9 @@ dependencies = [ [[package]] name = "regalloc" -version = "0.0.33" +version = "0.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d808cff91dfca7b239d40b972ba628add94892b1d9e19a842aedc5cfae8ab1a" +checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" dependencies = [ "log", "rustc-hash", @@ -8797,9 +5855,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.5" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", @@ -8817,9 +5875,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "region" @@ -8830,24 +5888,7 @@ dependencies = [ "bitflags", "libc", "mach", - "winapi 0.3.9", -] - -[[package]] -name = "remote-externalities" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "env_logger", - "jsonrpsee 0.8.0", - "log", - "parity-scale-codec", - "serde", - "serde_json", - "sp-core", - "sp-io", - "sp-runtime", - "sp-version", + "winapi", ] [[package]] @@ -8856,7 +5897,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -8866,14 +5907,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" dependencies = [ "hostname", - "quick-error 1.2.3", + "quick-error", ] [[package]] name = "retain_mut" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" [[package]] name = "rfc6979" @@ -8898,7 +5939,7 @@ dependencies = [ "spin", "untrusted", "web-sys", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -8907,7 +5948,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "999508abb0ae792aabed2460c45b89106d97fe4adac593bdaef433c2605847b5" dependencies = [ - "bytes 1.1.0", + "bytes", "rustc-hex", ] @@ -8924,123 +5965,64 @@ dependencies = [ [[package]] name = "rocksdb" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a62eca5cacf2c8261128631bed9f045598d40bfbe4b29f5163f0f802f8f44a7" +checksum = "620f4129485ff1a7128d184bc687470c21c7951b64779ebc9cfdad3dcd920290" dependencies = [ "libc", "librocksdb-sys", ] [[package]] -name = "rococo-runtime" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "round-based" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61d7da583ffbf4d938fb9dc60871b51769ff47e9836e323668fe2d791ca2fa06" dependencies = [ - "beefy-primitives", - "bp-messages", - "bp-rococo", - "bp-runtime", - "bp-wococo", - "bridge-runtime-common", - "frame-benchmarking", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-rpc-runtime-api", - "hex-literal", + "async-stream", + "futures", "log", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-balances", - "pallet-beefy", - "pallet-beefy-mmr", - "pallet-bridge-dispatch", - "pallet-bridge-grandpa", - "pallet-bridge-messages", - "pallet-collective", - "pallet-grandpa", - "pallet-im-online", - "pallet-indices", - "pallet-membership", - "pallet-mmr", - "pallet-mmr-primitives", - "pallet-multisig", - "pallet-offences", - "pallet-proxy", - "pallet-session", - "pallet-staking", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-utility", - "pallet-xcm", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "rococo-runtime-constants", - "scale-info", "serde", - "serde_derive", - "smallvec", - "sp-api", - "sp-authority-discovery", - "sp-block-builder", - "sp-consensus-babe", - "sp-core", - "sp-inherents", - "sp-io", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-executor", + "thiserror", + "tokio", ] [[package]] -name = "rococo-runtime-constants" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" +name = "rpassword" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" dependencies = [ - "frame-support", - "polkadot-primitives", - "polkadot-runtime-common", - "smallvec", - "sp-runtime", + "libc", + "winapi", ] [[package]] -name = "round-based" -version = "0.1.6" +name = "rstest" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "691944449a819eb32e9db18240a8c0e0d35da3849d2938a4290a21862a42bf07" +checksum = "d912f35156a3f99a66ee3e11ac2e0b3f34ac85a07e05263d05a7e2c8810d616f" dependencies = [ - "async-stream", - "futures 0.3.21", - "log", - "serde", - "thiserror", - "tokio", + "cfg-if", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", ] [[package]] -name = "rpassword" -version = "5.0.1" +name = "rtnetlink" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" +checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" dependencies = [ - "libc", - "winapi 0.3.9", + "async-global-executor", + "futures", + "log", + "netlink-packet-route", + "netlink-proto", + "nix", + "thiserror", ] [[package]] @@ -9081,80 +6063,46 @@ dependencies = [ "semver 0.9.0", ] -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.6", + "semver 1.0.10", ] [[package]] name = "rustix" -version = "0.31.3" +version = "0.33.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2dcfc2778a90e38f56a708bfc90572422e11d6c7ee233d053d1f782cf9df6d2" +checksum = "938a344304321a9da4973b9ff4f9f8db9caf4597dfd9dda6a60b523340a0fff0" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "winapi 0.3.9", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64", - "log", - "ring", - "sct 0.6.1", - "webpki 0.21.4", + "winapi", ] [[package]] name = "rustls" -version = "0.20.4" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" dependencies = [ "log", "ring", - "sct 0.7.0", - "webpki 0.22.0", -] - -[[package]] -name = "rustls-native-certs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" -dependencies = [ - "openssl-probe", - "rustls 0.19.1", - "schannel", - "security-framework", + "sct", + "webpki", ] [[package]] name = "rustls-native-certs" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca9ebdfa27d3fc180e42879037b5338ab1c040c06affd00d8338598e7800943" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -9164,18 +6112,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "0.2.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" dependencies = [ "base64", ] [[package]] name = "rustversion" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf" [[package]] name = "rw-stream-sink" @@ -9183,16 +6131,27 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.21", + "futures", "pin-project 0.4.29", "static_assertions", ] +[[package]] +name = "rw-stream-sink" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" +dependencies = [ + "futures", + "pin-project 1.0.10", + "static_assertions", +] + [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "safe-mix" @@ -9224,7 +6183,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "log", "sp-core", @@ -9232,39 +6191,12 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sc-authority-discovery" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "async-trait", - "futures 0.3.21", - "futures-timer", - "ip_network", - "libp2p", - "log", - "parity-scale-codec", - "prost", - "prost-build", - "rand 0.7.3", - "sc-client-api", - "sc-network", - "sp-api", - "sp-authority-discovery", - "sp-blockchain", - "sp-core", - "sp-keystore", - "sp-runtime", - "substrate-prometheus-endpoint", - "thiserror", -] - [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "futures-timer", "log", "parity-scale-codec", @@ -9285,7 +6217,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -9301,10 +6233,10 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "impl-trait-for-tuples", - "memmap2 0.5.3", + "memmap2 0.5.4", "parity-scale-codec", "sc-chain-spec-derive", "sc-network", @@ -9318,9 +6250,9 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -9329,12 +6261,12 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "chrono", "clap", "fdlimit", - "futures 0.3.21", + "futures", "hex", "libp2p", "log", @@ -9344,6 +6276,7 @@ dependencies = [ "regex", "rpassword", "sc-client-api", + "sc-client-db", "sc-keystore", "sc-network", "sc-service", @@ -9367,14 +6300,14 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "fnv", - "futures 0.3.21", + "futures", "hash-db", "log", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sc-executor", "sc-transaction-pool-api", "sc-utils", @@ -9395,7 +6328,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "hash-db", "kvdb", @@ -9405,7 +6338,7 @@ dependencies = [ "log", "parity-db", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sc-client-api", "sc-state-db", "sp-arithmetic", @@ -9420,14 +6353,14 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", - "futures 0.3.21", + "futures", "futures-timer", "libp2p", "log", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sc-client-api", "sc-utils", "serde", @@ -9444,10 +6377,10 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", - "futures 0.3.21", + "futures", "log", "parity-scale-codec", "sc-block-builder", @@ -9473,18 +6406,18 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "fork-tree", - "futures 0.3.21", + "futures", "log", "merlin", "num-bigint", "num-rational 0.2.4", "num-traits", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rand 0.7.3", "retain_mut", "sc-client-api", @@ -9513,34 +6446,10 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sc-consensus-babe-rpc" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "sc-consensus-babe", - "sc-consensus-epochs", - "sc-rpc-api", - "serde", - "sp-api", - "sp-application-crypto", - "sp-blockchain", - "sp-consensus", - "sp-consensus-babe", - "sp-core", - "sp-keystore", - "sp-runtime", - "thiserror", -] - [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "fork-tree", "parity-scale-codec", @@ -9553,14 +6462,12 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "assert_matches", "async-trait", - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", + "futures", + "jsonrpsee", "log", "parity-scale-codec", "sc-client-api", @@ -9589,10 +6496,10 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", - "futures 0.3.21", + "futures", "futures-timer", "log", "parity-scale-codec", @@ -9611,28 +6518,15 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sc-consensus-uncles" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "sc-client-api", - "sp-authorship", - "sp-runtime", - "thiserror", -] - [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "lazy_static", - "libsecp256k1 0.7.0", - "log", - "lru 0.6.6", + "lru", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sc-executor-common", "sc-executor-wasmi", "sc-executor-wasmtime", @@ -9647,19 +6541,20 @@ dependencies = [ "sp-trie", "sp-version", "sp-wasm-interface", + "tracing", "wasmi", ] [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "environmental", "parity-scale-codec", "sc-allocator", - "sp-core", "sp-maybe-compressed-blob", + "sp-sandbox", "sp-serializer", "sp-wasm-interface", "thiserror", @@ -9670,15 +6565,14 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "log", "parity-scale-codec", "sc-allocator", "sc-executor-common", - "scoped-tls", - "sp-core", "sp-runtime-interface", + "sp-sandbox", "sp-wasm-interface", "wasmi", ] @@ -9686,17 +6580,17 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "log", "parity-scale-codec", "parity-wasm 0.42.2", "sc-allocator", "sc-executor-common", - "sp-core", "sp-runtime-interface", + "sp-sandbox", "sp-wasm-interface", "wasmtime", ] @@ -9704,17 +6598,19 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ + "ahash", "async-trait", "dyn-clone", "finality-grandpa", "fork-tree", - "futures 0.3.21", + "futures", "futures-timer", + "hex", "log", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rand 0.8.5", "sc-block-builder", "sc-chain-spec", @@ -9739,37 +6635,13 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sc-finality-grandpa-rpc" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "finality-grandpa", - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "jsonrpc-pubsub", - "log", - "parity-scale-codec", - "sc-client-api", - "sc-finality-grandpa", - "sc-rpc", - "serde", - "serde_json", - "sp-blockchain", - "sp-core", - "sp-runtime", - "thiserror", -] - [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "ansi_term", - "futures 0.3.21", + "futures", "futures-timer", "log", "parity-util-mem", @@ -9783,11 +6655,11 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "hex", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "serde_json", "sp-application-crypto", "sp-core", @@ -9798,18 +6670,17 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "async-std", "async-trait", - "asynchronous-codec 0.5.0", + "asynchronous-codec", "bitflags", - "bytes 1.1.0", + "bytes", "cid", "either", "fnv", "fork-tree", - "futures 0.3.21", + "futures", "futures-timer", "hex", "ip_network", @@ -9817,16 +6688,19 @@ dependencies = [ "linked-hash-map", "linked_hash_set", "log", - "lru 0.7.3", + "lru", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "pin-project 1.0.10", - "prost", - "prost-build", + "prost 0.10.4", + "prost-build 0.9.0", "rand 0.7.3", "sc-block-builder", "sc-client-api", "sc-consensus", + "sc-network-common", + "sc-network-light", + "sc-network-sync", "sc-peerset", "sc-utils", "serde", @@ -9840,44 +6714,108 @@ dependencies = [ "sp-runtime", "substrate-prometheus-endpoint", "thiserror", - "unsigned-varint 0.6.0", + "unsigned-varint", "void", "zeroize", ] +[[package]] +name = "sc-network-common" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +dependencies = [ + "futures", + "libp2p", + "parity-scale-codec", + "prost-build 0.9.0", + "sc-peerset", + "smallvec", +] + [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "ahash", + "futures", "futures-timer", "libp2p", "log", - "lru 0.7.3", + "lru", "sc-network", "sp-runtime", "substrate-prometheus-endpoint", "tracing", ] +[[package]] +name = "sc-network-light" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +dependencies = [ + "futures", + "libp2p", + "log", + "parity-scale-codec", + "prost 0.10.4", + "prost-build 0.9.0", + "sc-client-api", + "sc-network-common", + "sc-peerset", + "sp-blockchain", + "sp-core", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sc-network-sync" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +dependencies = [ + "bitflags", + "either", + "fork-tree", + "futures", + "libp2p", + "log", + "lru", + "parity-scale-codec", + "prost 0.10.4", + "prost-build 0.9.0", + "sc-client-api", + "sc-consensus", + "sc-network-common", + "sc-peerset", + "smallvec", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-finality-grandpa", + "sp-runtime", + "thiserror", +] + [[package]] name = "sc-network-test" version = "0.8.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-std", "async-trait", - "futures 0.3.21", + "futures", "futures-timer", "libp2p", "log", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rand 0.7.3", "sc-block-builder", "sc-client-api", "sc-consensus", "sc-network", + "sc-network-common", "sc-service", "sp-blockchain", "sp-consensus", @@ -9892,11 +6830,11 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "bytes 1.1.0", + "bytes", "fnv", - "futures 0.3.21", + "futures", "futures-timer", "hex", "hyper", @@ -9904,7 +6842,7 @@ dependencies = [ "num_cpus", "once_cell", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rand 0.7.3", "sc-client-api", "sc-network", @@ -9920,9 +6858,9 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "libp2p", "log", "sc-utils", @@ -9933,7 +6871,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -9942,15 +6880,14 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "hash-db", - "jsonrpc-core", - "jsonrpc-pubsub", + "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -9973,18 +6910,16 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "jsonrpc-pubsub", + "futures", + "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sc-chain-spec", "sc-transaction-pool-api", + "scale-info", "serde", "serde_json", "sp-core", @@ -9998,14 +6933,10 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-http-server", - "jsonrpc-ipc-server", - "jsonrpc-pubsub", - "jsonrpc-ws-server", + "futures", + "jsonrpsee", "log", "serde_json", "substrate-prometheus-endpoint", @@ -10015,20 +6946,19 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "directories", "exit-future", - "futures 0.3.21", + "futures", "futures-timer", "hash-db", - "jsonrpc-core", - "jsonrpc-pubsub", + "jsonrpsee", "log", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "pin-project 1.0.10", "rand 0.7.3", "sc-block-builder", @@ -10040,9 +6970,11 @@ dependencies = [ "sc-informant", "sc-keystore", "sc-network", + "sc-network-common", "sc-offchain", "sc-rpc", "sc-rpc-server", + "sc-sysinfo", "sc-telemetry", "sc-tracing", "sc-transaction-pool", @@ -10079,49 +7011,46 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "log", "parity-scale-codec", "parity-util-mem", "parity-util-mem-derive", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sc-client-api", "sp-core", ] [[package]] -name = "sc-sync-state-rpc" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +name = "sc-sysinfo" +version = "6.0.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", - "parity-scale-codec", - "sc-chain-spec", - "sc-client-api", - "sc-consensus-babe", - "sc-consensus-epochs", - "sc-finality-grandpa", - "sc-rpc-api", + "futures", + "libc", + "log", + "rand 0.7.3", + "rand_pcg 0.2.1", + "regex", + "sc-telemetry", "serde", "serde_json", - "sp-blockchain", - "sp-runtime", - "thiserror", + "sp-core", + "sp-io", + "sp-std", ] [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "chrono", - "futures 0.3.21", + "futures", "libp2p", "log", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "pin-project 1.0.10", "rand 0.7.3", "serde", @@ -10133,7 +7062,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "ansi_term", "atty", @@ -10142,7 +7071,7 @@ dependencies = [ "libc", "log", "once_cell", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "regex", "rustc-hash", "sc-client-api", @@ -10164,9 +7093,9 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -10175,15 +7104,15 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "futures-timer", "linked-hash-map", "log", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "retain_mut", "sc-client-api", "sc-transaction-pool-api", @@ -10202,9 +7131,9 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "log", "serde", "sp-blockchain", @@ -10215,23 +7144,24 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "futures-timer", "lazy_static", - "parking_lot 0.11.2", + "log", + "parking_lot 0.12.1", "prometheus", ] [[package]] name = "scale-info" -version = "1.0.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" +checksum = "c46be926081c9f4dd5dd9b6f1d3e3229f2360bc6502dd8836f84a93b7c75e99a" dependencies = [ "bitvec", - "cfg-if 1.0.0", + "cfg-if", "derive_more", "parity-scale-codec", "scale-info-derive", @@ -10240,11 +7170,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "1.0.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baeb2780690380592f86205aa4ee49815feb2acad8c2f59e6dd207148c3f1fcd" +checksum = "50e334bb10a245e28e5fd755cabcafd96cfcd167c99ae63a46924ca8d8703a3c" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -10252,12 +7182,12 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "winapi 0.3.9", + "windows-sys", ] [[package]] @@ -10278,28 +7208,12 @@ dependencies = [ "zeroize", ] -[[package]] -name = "scoped-tls" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" - [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sct" version = "0.7.0" @@ -10334,6 +7248,15 @@ dependencies = [ "serde", ] +[[package]] +name = "secp256k1" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c42e6f1735c5f00f51e43e28d6634141f2bcad10931b2609ddd74a86d751260" +dependencies = [ + "secp256k1-sys", +] + [[package]] name = "secp256k1-sys" version = "0.4.2" @@ -10381,7 +7304,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" dependencies = [ - "semver-parser 0.7.0", + "semver-parser", ] [[package]] @@ -10390,23 +7313,14 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser 0.10.2", + "semver-parser", ] [[package]] name = "semver" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" +checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" dependencies = [ "serde", ] @@ -10417,38 +7331,29 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -10456,13 +7361,22 @@ dependencies = [ ] [[package]] -name = "serde_json" -version = "1.0.79" +name = "serde_json" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +dependencies = [ + "itoa 1.0.2", + "ryu", + "serde", +] + +[[package]] +name = "serde_nanos" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "e44969a61f5d316be20a42ff97816efb3b407a924d06824c3d8a49fa8450de0e" dependencies = [ - "itoa 1.0.1", - "ryu", "serde", ] @@ -10485,8 +7399,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cfg-if", + "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", ] @@ -10510,8 +7424,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cfg-if", + "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", ] @@ -10522,8 +7436,8 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures 0.2.2", + "cfg-if", + "cpufeatures", "digest 0.10.3", ] @@ -10539,6 +7453,16 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha3" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881bf8156c87b6301fc5ca6b27f11eeb2761224c7081e69b409d5a1951a70c86" +dependencies = [ + "digest 0.10.3", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -10556,9 +7480,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signal-hook" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" dependencies = [ "libc", "signal-hook-registry", @@ -10597,36 +7521,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" - -[[package]] -name = "slot-range-helper" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "enumn", - "parity-scale-codec", - "paste", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "slotmap" -version = "1.0.6" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" -dependencies = [ - "version_check", -] +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "smallvec" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2" [[package]] name = "snap" @@ -10636,31 +7539,19 @@ checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451" [[package]] name = "snow" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6142f7c25e94f6fd25a32c3348ec230df9109b463f59c8c7acc4bd34936babb7" +checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d" dependencies = [ "aes-gcm", "blake2", - "chacha20poly1305 0.8.0", - "rand 0.8.5", + "chacha20poly1305", + "curve25519-dalek 4.0.0-pre.1", "rand_core 0.6.3", "ring", - "rustc_version 0.3.3", - "sha2 0.9.9", + "rustc_version 0.4.0", + "sha2 0.10.2", "subtle 2.4.1", - "x25519-dalek", -] - -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi 0.3.9", ] [[package]] @@ -10670,7 +7561,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -10680,9 +7571,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64", - "bytes 1.1.0", + "bytes", "flate2", - "futures 0.3.21", + "futures", "httparse", "log", "rand 0.8.5", @@ -10692,7 +7583,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "hash-db", "log", @@ -10709,10 +7600,10 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "blake2-rfc", - "proc-macro-crate 1.1.3", + "blake2", + "proc-macro-crate", "proc-macro2", "quote", "syn", @@ -10720,8 +7611,8 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "scale-info", @@ -10733,8 +7624,8 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "integer-sqrt", "num-traits", @@ -10746,23 +7637,10 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "sp-authority-discovery" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-application-crypto", - "sp-runtime", - "sp-std", -] - [[package]] name = "sp-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "parity-scale-codec", @@ -10774,7 +7652,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "sp-api", @@ -10786,13 +7664,13 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "log", - "lru 0.7.3", + "lru", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "sp-api", "sp-consensus", "sp-database", @@ -10804,10 +7682,10 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", - "futures 0.3.21", + "futures", "futures-timer", "log", "parity-scale-codec", @@ -10823,7 +7701,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "parity-scale-codec", @@ -10841,7 +7719,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "merlin", @@ -10864,21 +7742,24 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "scale-info", "serde", "sp-arithmetic", "sp-runtime", + "sp-std", + "sp-timestamp", ] [[package]] name = "sp-consensus-vrf" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", + "scale-info", "schnorrkel", "sp-core", "sp-runtime", @@ -10887,8 +7768,8 @@ dependencies = [ [[package]] name = "sp-core" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "base58", "bitflags", @@ -10896,7 +7777,7 @@ dependencies = [ "byteorder", "dyn-clonable", "ed25519-dalek", - "futures 0.3.21", + "futures", "hash-db", "hash256-std-hasher", "hex", @@ -10908,15 +7789,15 @@ dependencies = [ "num-traits", "parity-scale-codec", "parity-util-mem", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "primitive-types", "rand 0.7.3", "regex", "scale-info", "schnorrkel", + "secp256k1 0.21.3", "secrecy", "serde", - "sha2 0.10.2", "sp-core-hashing", "sp-debug-derive", "sp-externalities", @@ -10927,8 +7808,6 @@ dependencies = [ "substrate-bip39", "thiserror", "tiny-bip39", - "tiny-keccak", - "twox-hash", "wasmi", "zeroize", ] @@ -10936,20 +7815,21 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "blake2-rfc", + "blake2", "byteorder", + "digest 0.10.3", "sha2 0.10.2", + "sha3 0.10.1", "sp-std", - "tiny-keccak", "twox-hash", ] [[package]] name = "sp-core-hashing-proc-macro" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "proc-macro2", "quote", @@ -10960,16 +7840,16 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "kvdb", - "parking_lot 0.11.2", + "parking_lot 0.12.1", ] [[package]] name = "sp-debug-derive" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "proc-macro2", "quote", @@ -10978,8 +7858,8 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.11.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "0.12.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "environmental", "parity-scale-codec", @@ -10990,7 +7870,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "finality-grandpa", "log", @@ -11008,7 +7888,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -11021,15 +7901,16 @@ dependencies = [ [[package]] name = "sp-io" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "hash-db", "libsecp256k1 0.7.0", "log", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", + "secp256k1 0.21.3", "sp-core", "sp-externalities", "sp-keystore", @@ -11045,8 +7926,8 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "lazy_static", "sp-core", @@ -11056,14 +7937,14 @@ dependencies = [ [[package]] name = "sp-keystore" -version = "0.11.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "0.12.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", - "futures 0.3.21", + "futures", "merlin", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "schnorrkel", "serde", "sp-core", @@ -11074,7 +7955,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "thiserror", "zstd", @@ -11083,33 +7964,21 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "scale-info", "serde", "sp-arithmetic", "sp-core", - "sp-npos-elections-solution-type", "sp-runtime", "sp-std", ] -[[package]] -name = "sp-npos-elections-solution-type" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "proc-macro-crate 1.1.3", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "sp-api", "sp-core", @@ -11119,7 +7988,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "backtrace", "lazy_static", @@ -11128,8 +7997,8 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "rustc-hash", "serde", @@ -11138,8 +8007,8 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "either", "hash256-std-hasher", @@ -11160,8 +8029,8 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -11177,20 +8046,34 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "Inflector", - "proc-macro-crate 1.1.3", + "proc-macro-crate", "proc-macro2", "quote", "syn", ] +[[package]] +name = "sp-sandbox" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" +dependencies = [ + "log", + "parity-scale-codec", + "sp-core", + "sp-io", + "sp-std", + "sp-wasm-interface", + "wasmi", +] + [[package]] name = "sp-serializer" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "serde", "serde_json", @@ -11199,7 +8082,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "scale-info", @@ -11213,7 +8096,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "scale-info", @@ -11223,14 +8106,14 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.11.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "0.12.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "hash-db", "log", "num-traits", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rand 0.7.3", "smallvec", "sp-core", @@ -11240,19 +8123,18 @@ dependencies = [ "sp-trie", "thiserror", "tracing", - "trie-db", "trie-root", ] [[package]] name = "sp-std" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" [[package]] name = "sp-storage" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "impl-serde", "parity-scale-codec", @@ -11265,7 +8147,7 @@ dependencies = [ [[package]] name = "sp-tasks" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "log", "sp-core", @@ -11278,7 +8160,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "futures-timer", @@ -11293,8 +8175,8 @@ dependencies = [ [[package]] name = "sp-tracing" -version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "sp-std", @@ -11306,7 +8188,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "sp-api", "sp-runtime", @@ -11315,7 +8197,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", "log", @@ -11330,23 +8212,24 @@ dependencies = [ [[package]] name = "sp-trie" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "hash-db", - "memory-db 0.28.0", + "memory-db", "parity-scale-codec", "scale-info", "sp-core", "sp-std", + "thiserror", "trie-db", "trie-root", ] [[package]] name = "sp-version" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "5.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "impl-serde", "parity-scale-codec", @@ -11363,7 +8246,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -11373,8 +8256,8 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "5.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +version = "6.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "impl-trait-for-tuples", "log", @@ -11411,11 +8294,12 @@ dependencies = [ [[package]] name = "ss58-registry" -version = "1.15.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9799e6d412271cb2414597581128b03f3285f260ea49f5363d07df6a332b3e" +checksum = "77ef98aedad3dc52e10995e7ed15f1279e11d4da35795f5dac7305742d0feb66" dependencies = [ "Inflector", + "num-format", "proc-macro2", "quote", "serde", @@ -11435,31 +8319,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "static_init" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b73400442027c4adedda20a9f9b7945234a5bd8d5f7e86da22bd5d0622369c" -dependencies = [ - "cfg_aliases", - "libc", - "parking_lot 0.11.2", - "static_init_macro", -] - -[[package]] -name = "static_init_macro" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2261c91034a1edc3fc4d1b80e89d82714faede0515c14a75da10cb941546bbf" -dependencies = [ - "cfg_aliases", - "memchr", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "statrs" version = "0.15.0" @@ -11538,7 +8397,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "platforms", ] @@ -11546,18 +8405,17 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "frame-system-rpc-runtime-api", - "futures 0.3.21", - "jsonrpc-core", - "jsonrpc-core-client", - "jsonrpc-derive", + "futures", + "jsonrpsee", "log", "parity-scale-codec", "sc-client-api", "sc-rpc-api", "sc-transaction-pool-api", + "serde_json", "sp-api", "sp-block-builder", "sp-blockchain", @@ -11568,9 +8426,8 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "async-std", "futures-util", "hyper", "log", @@ -11582,10 +8439,10 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.1" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "async-trait", - "futures 0.3.21", + "futures", "hex", "parity-scale-codec", "sc-client-api", @@ -11608,14 +8465,15 @@ dependencies = [ [[package]] name = "substrate-test-runtime" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "cfg-if 1.0.0", + "beefy-primitives", + "cfg-if", "frame-support", "frame-system", "frame-system-rpc-runtime-api", "log", - "memory-db 0.27.0", + "memory-db", "pallet-babe", "pallet-timestamp", "parity-scale-codec", @@ -11650,9 +8508,9 @@ dependencies = [ [[package]] name = "substrate-test-runtime-client" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ - "futures 0.3.21", + "futures", "parity-scale-codec", "sc-block-builder", "sc-client-api", @@ -11669,7 +8527,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.24#814752f60ab8cce7e2ece3ce0c1b10799b4eab28" dependencies = [ "ansi_term", "build-helper", @@ -11696,13 +8554,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.86" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -11717,6 +8575,27 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "system-configuration" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75182f12f490e953596550b65ee31bda7c8e043d9386174b353bda50838c3fd" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -11725,9 +8604,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1" +checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" [[package]] name = "tempfile" @@ -11735,12 +8614,12 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "fastrand", "libc", - "redox_syscall 0.2.11", + "redox_syscall", "remove_dir_all", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -11752,18 +8631,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "test-runtime-constants" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "frame-support", - "polkadot-primitives", - "polkadot-runtime-common", - "smallvec", - "sp-runtime", -] - [[package]] name = "textwrap" version = "0.15.0" @@ -11772,24 +8639,30 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + [[package]] name = "thread_local" version = "1.1.4" @@ -11809,16 +8682,14 @@ dependencies = [ ] [[package]] -name = "thrift" -version = "0.15.0" +name = "tikv-jemalloc-sys" +version = "0.4.3+5.2.1-patched.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b82ca8f46f95b3ce96081fe3dd89160fdea970c254bb72925255d1b62aae692e" +checksum = "a1792ccb507d955b46af42c123ea8863668fae24d03721e40cad6a41773dbb49" dependencies = [ - "byteorder", - "integer-encoding", - "log", - "ordered-float", - "threadpool", + "cc", + "fs_extra", + "libc", ] [[package]] @@ -11829,7 +8700,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -11862,9 +8733,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -11877,28 +8748,29 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.17.0" +version = "1.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" dependencies = [ - "bytes 1.1.0", + "bytes", "libc", "memchr", - "mio 0.8.1", + "mio", "num_cpus", "once_cell", - "pin-project-lite 0.2.8", + "parking_lot 0.12.1", + "pin-project-lite 0.2.9", "signal-hook-registry", - "socket2 0.4.4", + "socket2", "tokio-macros", - "winapi 0.3.9", + "winapi", ] [[package]] name = "tokio-macros" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ "proc-macro2", "quote", @@ -11907,84 +8779,74 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls 0.19.1", - "tokio", - "webpki 0.21.4", -] - -[[package]] -name = "tokio-rustls" -version = "0.23.3" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4151fda0cf2798550ad0b34bcfc9b9dcc2a9d2471c895c68f3a8818e54f2389e" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.4", + "rustls", "tokio", - "webpki 0.22.0", + "webpki", ] [[package]] name = "tokio-stream" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" +checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" dependencies = [ "futures-core", - "pin-project-lite 0.2.8", + "pin-project-lite 0.2.9", "tokio", + "tokio-util", ] [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" dependencies = [ - "bytes 1.1.0", + "bytes", "futures-core", "futures-io", "futures-sink", - "log", - "pin-project-lite 0.2.8", + "pin-project-lite 0.2.9", "tokio", + "tracing", ] [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.32" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ - "cfg-if 1.0.0", - "pin-project-lite 0.2.8", + "cfg-if", + "pin-project-lite 0.2.9", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" dependencies = [ "proc-macro2", "quote", @@ -11993,11 +8855,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.23" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" +checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" dependencies = [ - "lazy_static", + "once_cell", "valuable", ] @@ -12013,12 +8875,14 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ + "ahash", "lazy_static", "log", + "lru", "tracing-core", ] @@ -12062,7 +8926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d32d034c0d3db64b43c31de38e945f15b40cd4ca6d2dcfc26d4798ce8de4ab83" dependencies = [ "hash-db", - "hashbrown 0.12.0", + "hashbrown 0.12.1", "log", "rustc-hex", "smallvec", @@ -12089,18 +8953,18 @@ dependencies = [ [[package]] name = "trust-dns-proto" -version = "0.20.4" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca94d4e9feb6a181c690c4040d7a24ef34018d8313ac5044a61d21222ae24e31" +checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" dependencies = [ "async-trait", - "cfg-if 1.0.0", + "cfg-if", "data-encoding", "enum-as-inner", "futures-channel", "futures-io", "futures-util", - "idna 0.2.3", + "idna", "ipnet", "lazy_static", "log", @@ -12108,59 +8972,34 @@ dependencies = [ "smallvec", "thiserror", "tinyvec", - "url 2.2.2", + "url", ] [[package]] name = "trust-dns-resolver" -version = "0.20.4" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecae383baad9995efaa34ce8e57d12c3f305e545887472a492b838f4b5cfb77a" +checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "futures-util", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "parking_lot 0.11.2", - "resolv-conf", - "smallvec", - "thiserror", - "trust-dns-proto", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "try-runtime-cli" -version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.17#22d40c761a985482f93bbbea5ba4199bdba74f8e" -dependencies = [ - "clap", - "jsonrpsee 0.4.1", - "log", - "parity-scale-codec", - "remote-externalities", - "sc-chain-spec", - "sc-cli", - "sc-executor", - "sc-service", - "serde", - "sp-core", - "sp-externalities", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-state-machine", - "sp-version", - "zstd", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "parking_lot 0.12.1", + "resolv-conf", + "smallvec", + "thiserror", + "trust-dns-proto", ] +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + [[package]] name = "tt-call" version = "1.0.8" @@ -12169,11 +9008,12 @@ checksum = "5e66dcbec4290c69dd03c57e76c2469ea5c7ce109c6dd4351c13055cf71ea055" [[package]] name = "twox-hash" -version = "1.6.2" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", + "digest 0.10.3", "rand 0.8.5", "static_assertions", ] @@ -12189,6 +9029,17 @@ dependencies = [ "syn", ] +[[package]] +name = "typed-builder" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "typenum" version = "1.15.0" @@ -12224,15 +9075,21 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd" dependencies = [ "tinyvec", ] @@ -12243,11 +9100,17 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "universal-hash" @@ -12259,32 +9122,14 @@ dependencies = [ "subtle 2.4.1", ] -[[package]] -name = "unsigned-varint" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35" - -[[package]] -name = "unsigned-varint" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35581ff83d4101e58b582e607120c7f5ffb17e632a980b1f38334d76b36908b2" -dependencies = [ - "asynchronous-codec 0.5.0", - "bytes 1.1.0", - "futures-io", - "futures-util", -] - [[package]] name = "unsigned-varint" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" dependencies = [ - "asynchronous-codec 0.6.0", - "bytes 1.1.0", + "asynchronous-codec", + "bytes", "futures-io", "futures-util", ] @@ -12295,17 +9140,6 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - [[package]] name = "url" version = "2.2.2" @@ -12313,9 +9147,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", - "idna 0.2.3", + "idna", "matches", - "percent-encoding 2.1.0", + "percent-encoding", ] [[package]] @@ -12326,9 +9160,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.0.0-alpha.8" +version = "1.0.0-alpha.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" dependencies = [ "ctor", "version_check", @@ -12365,7 +9199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", - "winapi 0.3.9", + "winapi", "winapi-util", ] @@ -12399,19 +9233,19 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ "bumpalo", "lazy_static", @@ -12424,11 +9258,11 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.29" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" +checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -12436,9 +9270,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12446,9 +9280,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ "proc-macro2", "quote", @@ -12459,9 +9293,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" [[package]] name = "wasm-gc-api" @@ -12489,7 +9323,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" dependencies = [ - "futures 0.3.21", + "futures", "js-sys", "parking_lot 0.11.2", "pin-utils", @@ -12506,6 +9340,7 @@ checksum = "ca00c5147c319a8ec91ec1a0edbec31e566ce2c9cc93b3f9bb86a9efd0eb795d" dependencies = [ "downcast-rs", "libc", + "libm", "memory_units", "num-rational 0.2.4", "num-traits", @@ -12524,31 +9359,30 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.81.0" +version = "0.83.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc" +checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wasmtime" -version = "0.33.1" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9c724da92e39a85d2231d4c2a942c8be295211441dbca581c6c3f3f45a9f00" +checksum = "21ffb4705016d5ca91e18a72ed6822dab50e6d5ddd7045461b17ef19071cdef1" dependencies = [ "anyhow", "backtrace", "bincode", - "cfg-if 1.0.0", - "cpp_demangle", + "cfg-if", "indexmap", "lazy_static", "libc", "log", - "object", + "object 0.27.1", + "once_cell", "paste", "psm", "rayon", "region", - "rustc-demangle", "serde", "target-lexicon", "wasmparser", @@ -12557,14 +9391,14 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit", "wasmtime-runtime", - "winapi 0.3.9", + "winapi", ] [[package]] name = "wasmtime-cache" -version = "0.33.1" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4439d99100298344567c0eb6916ad5864e99e54760b8177c427e529077fb30" +checksum = "85c6ab24291fa7cb3a181f5669f6c72599b7ef781669759b45c7828c5999d0c0" dependencies = [ "anyhow", "base64", @@ -12576,15 +9410,15 @@ dependencies = [ "serde", "sha2 0.9.9", "toml", - "winapi 0.3.9", + "winapi", "zstd", ] [[package]] name = "wasmtime-cranelift" -version = "0.33.1" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1762765dd69245f00e5d9783b695039e449a7be0f9c5383e4c78465dd6131aeb" +checksum = "f04c810078a491b7bc4866ebe045f714d2b95e6b539e1f64009a4a7606be11de" dependencies = [ "anyhow", "cranelift-codegen", @@ -12595,7 +9429,7 @@ dependencies = [ "gimli", "log", "more-asserts", - "object", + "object 0.27.1", "target-lexicon", "thiserror", "wasmparser", @@ -12604,9 +9438,9 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "0.33.1" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4468301d95ec71710bb6261382efe27d1296447711645e3dbabaea6e4de3504" +checksum = "61448266ea164b1ac406363cdcfac81c7c44db4d94c7a81c8620ac6c5c6cdf59" dependencies = [ "anyhow", "cranelift-entity", @@ -12614,7 +9448,7 @@ dependencies = [ "indexmap", "log", "more-asserts", - "object", + "object 0.27.1", "serde", "target-lexicon", "thiserror", @@ -12624,41 +9458,56 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "0.33.1" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab0ae6e581ff014b470ec35847ea3c0b4c3ace89a55df5a04c802a11f4574e7d" +checksum = "156b4623c6b0d4b8c24afb846c20525922f538ef464cc024abab7ea8de2109a2" dependencies = [ "addr2line", "anyhow", "bincode", - "cfg-if 1.0.0", + "cfg-if", + "cpp_demangle", "gimli", - "object", + "log", + "object 0.27.1", "region", + "rustc-demangle", "rustix", "serde", "target-lexicon", "thiserror", "wasmtime-environ", + "wasmtime-jit-debug", "wasmtime-runtime", - "winapi 0.3.9", + "winapi", +] + +[[package]] +name = "wasmtime-jit-debug" +version = "0.35.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5dc31f811760a6c76b2672c404866fd19b75e5fb3b0075a3e377a6846490654" +dependencies = [ + "lazy_static", + "object 0.27.1", + "rustix", ] [[package]] name = "wasmtime-runtime" -version = "0.33.1" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9c28877ae37a367cda7b52b8887589816152e95dde9b7c80cc686f52761961" +checksum = "f907beaff69d4d920fa4688411ee4cc75c0f01859e424677f9e426e2ef749864" dependencies = [ "anyhow", "backtrace", "cc", - "cfg-if 1.0.0", + "cfg-if", "indexmap", - "lazy_static", "libc", "log", "mach", + "memfd", "memoffset", "more-asserts", "rand 0.8.5", @@ -12666,14 +9515,15 @@ dependencies = [ "rustix", "thiserror", "wasmtime-environ", - "winapi 0.3.9", + "wasmtime-jit-debug", + "winapi", ] [[package]] name = "wasmtime-types" -version = "0.33.1" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395726e8f5dd8c57cb0db445627b842343f7e29ed7489467fdf7953ed9d3cd4f" +checksum = "514ef0e5fd197b9609dc9eb74beba0c84d5a12b2417cbae55534633329ba4852" dependencies = [ "cranelift-entity", "serde", @@ -12683,9 +9533,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" dependencies = [ "js-sys", "wasm-bindgen", @@ -12693,23 +9543,14 @@ dependencies = [ [[package]] name = "webb-proposals" -version = "0.2.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e819886dd31a2710cfaa4c6fb986d25e4bc3c9ea064307e77f63d7d989b3e14" +checksum = "c4244d4a8178f5a3906f11845c37c8acdad5f07526d578110d840e71991e2a14" dependencies = [ "num-traits", "parity-scale-codec", "scale-info", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", + "typed-builder 0.10.0", ] [[package]] @@ -12724,20 +9565,11 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki 0.21.4", -] - -[[package]] -name = "webpki-roots" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449" +checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" dependencies = [ - "webpki 0.22.0", + "webpki", ] [[package]] @@ -12749,109 +9581,11 @@ dependencies = [ "cc", ] -[[package]] -name = "westend-runtime" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "beefy-primitives", - "bitvec", - "frame-benchmarking", - "frame-election-provider-support", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "frame-try-runtime", - "hex-literal", - "log", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-bags-list", - "pallet-balances", - "pallet-collective", - "pallet-democracy", - "pallet-election-provider-multi-phase", - "pallet-elections-phragmen", - "pallet-grandpa", - "pallet-identity", - "pallet-im-online", - "pallet-indices", - "pallet-membership", - "pallet-mmr-primitives", - "pallet-multisig", - "pallet-nicks", - "pallet-offences", - "pallet-offences-benchmarking", - "pallet-preimage", - "pallet-proxy", - "pallet-recovery", - "pallet-scheduler", - "pallet-session", - "pallet-session-benchmarking", - "pallet-society", - "pallet-staking", - "pallet-staking-reward-curve", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-treasury", - "pallet-utility", - "pallet-vesting", - "pallet-xcm", - "pallet-xcm-benchmarks", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "rustc-hex", - "scale-info", - "serde", - "serde_derive", - "smallvec", - "sp-api", - "sp-authority-discovery", - "sp-block-builder", - "sp-consensus-babe", - "sp-core", - "sp-inherents", - "sp-io", - "sp-npos-elections", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", - "westend-runtime-constants", - "xcm", - "xcm-builder", - "xcm-executor", -] - -[[package]] -name = "westend-runtime-constants" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "frame-support", - "polkadot-primitives", - "polkadot-runtime-common", - "smallvec", - "sp-runtime", -] - [[package]] name = "which" -version = "4.2.4" +version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" dependencies = [ "either", "lazy_static", @@ -12860,15 +9594,9 @@ dependencies = [ [[package]] name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "winapi" -version = "0.2.8" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" [[package]] name = "winapi" @@ -12880,12 +9608,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -12898,7 +9620,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -12907,73 +9629,109 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" +dependencies = [ + "windows_aarch64_msvc 0.34.0", + "windows_i686_gnu 0.34.0", + "windows_i686_msvc 0.34.0", + "windows_x86_64_gnu 0.34.0", + "windows_x86_64_msvc 0.34.0", +] + [[package]] name = "windows-sys" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] [[package]] name = "windows_aarch64_msvc" -version = "0.32.0" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_i686_gnu" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_msvc" -version = "0.32.0" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_x86_64_gnu" -version = "0.32.0" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_msvc" -version = "0.32.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" [[package]] -name = "winreg" -version = "0.6.2" +name = "windows_x86_64_msvc" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] -name = "ws2_32-sys" -version = "0.2.1" +name = "winreg" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi", ] [[package]] name = "wyz" -version = "0.2.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +dependencies = [ + "tap", +] [[package]] name = "x25519-dalek" @@ -12986,78 +9744,16 @@ dependencies = [ "zeroize", ] -[[package]] -name = "xcm" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "derivative", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "scale-info", - "xcm-procedural", -] - -[[package]] -name = "xcm-builder" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "frame-support", - "frame-system", - "log", - "pallet-transaction-payment", - "parity-scale-codec", - "polkadot-parachain", - "scale-info", - "sp-arithmetic", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", - "xcm-executor", -] - -[[package]] -name = "xcm-executor" -version = "0.9.17" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "frame-benchmarking", - "frame-support", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", -] - -[[package]] -name = "xcm-procedural" -version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.17#de0ecd4760b146ecf33f5e867d707d789e21e060" -dependencies = [ - "Inflector", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "yamux" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d9028f208dd5e63c614be69f115c1b53cacc1111437d4c765185856666c107" +checksum = "0c0608f53c1dc0bad505d03a34bbd49fbf2ad7b51eb036123e896365532745a1" dependencies = [ - "futures 0.3.21", + "futures", "log", "nohash-hasher", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rand 0.8.5", "static_assertions", ] @@ -13102,18 +9798,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.9.2+zstd.1.5.1" +version = "0.10.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2390ea1bf6c038c39674f22d95f0564725fc06034a47129179810b2fc58caa54" +checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "4.1.3+zstd.1.5.1" +version = "4.1.6+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e99d81b99fb3c2c2c794e3fe56c305c63d5173a16a46b5850b07c935ffc7db79" +checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb" dependencies = [ "libc", "zstd-sys", @@ -13121,9 +9817,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "1.6.2+zstd.1.5.1" +version = "1.6.3+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2daf2f248d9ea44454bfcb2516534e8b8ad2fc91bf818a1885495fc42bc8ac9f" +checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8" dependencies = [ "cc", "libc", diff --git a/Cargo.toml b/Cargo.toml index 3104c7e67..7e1f27a4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,7 @@ panic = 'unwind' [workspace] members = [ - 'node', 'pallets/*', - 'runtime', 'standalone/*', 'dkg-primitives', 'dkg-runtime-primitives', diff --git a/dkg-gadget/Cargo.toml b/dkg-gadget/Cargo.toml index 5993b511a..f1c0fc466 100644 --- a/dkg-gadget/Cargo.toml +++ b/dkg-gadget/Cargo.toml @@ -5,10 +5,13 @@ authors = ["Parity Technologies "] edition = "2021" license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +[features] +outbound-inspection = [] + [dependencies] fnv = "1.0.6" futures = "0.3" -log = "0.4" +log = { version = "0.4" } parking_lot = "0.11" thiserror = "1.0" wasm-timer = "0.2.5" @@ -17,38 +20,47 @@ sha3 = "0.9" hex = "0.4" rand = "0.8.4" strum = { version = "0.21", features = ["derive"] } +linked-hash-map = "0.5.4" +lru = "0.7.0" curv = { package = "curv-kzen", version = "0.9", default-features = false } -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } -scale-info = { version = "1.0", default-features = false, features = ["derive"] } -prometheus = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -#sc-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } - -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sc-network-gossip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } - -round-based = { version = "0.1.4", features = [] } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } +prometheus = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } + +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +#sc-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } + +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sc-peerset = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } + +round-based = { version = "0.1.7", features = [] } serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.59" multi-party-ecdsa = { git = "https://github.com/webb-tools/multi-party-ecdsa.git" } +tokio = { version = "1.17.0", default-features = false, features = ["sync", "macros"] } +tokio-stream = { version = "0.1.8", features = ["sync"] } +atomic = "0.5.1" +async-trait = "0.1.53" +auto_impl = "1.0.0" +itertools = "0.10.3" # Local dependencies dkg-runtime-primitives = { path = "../dkg-runtime-primitives", default-features = false } dkg-primitives = { path = "../dkg-primitives", default-features = false } [dev-dependencies] -sc-network-test = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } - -[features] +sc-network-test = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +rstest = "0.12.0" +env_logger = "0.9.0" diff --git a/dkg-gadget/meta_handler.md b/dkg-gadget/meta_handler.md new file mode 100644 index 000000000..c0f257cca --- /dev/null +++ b/dkg-gadget/meta_handler.md @@ -0,0 +1,33 @@ +# MetaAsyncProtocolHandler documentation + +The purpose of the ``MetaAsyncProtocolHandler`` is to easily and conveniently +spawn and execute keygen, offline, and voting stages **asynchronously** and in **parallel**. Prior to this addition, we used a ``MultiPartyECDSARounds`` +structure to poll **synchronously** and **serially**. This implies each dkg node, after this addition, has higher throughput than the previous method of ``MultiPartyECDSARounds``. + +In order to run each task in parallel, various fields inside the ``DKGWorker`` require ``Arc>`` or ``Arc>``. These fields are necessary for the +meta handler, since it must access various fields inside the DKGWorker from a parallel thread. + +Inside src/worker.rs, there is a function ``spawn_async_protocol``. This code is called in place of ``MultiPartyECDSARounds::builder()``. +Inside ``spawn_async_protocol``, the function ``generate_async_proto_params`` is called. Here, the ``rounds`` or ``next_rounds`` field is set, leaving in its place a ``MetaAsyncProtocolRemote``. This remote +allows control over the meta handler, **including the submission of unsigned proposals**, checking the status, and, turning it off. + +When a meta handler spawns, it immediately begins the keygen stage. After finishing keygen, the meta handler awaits patiently until it receives unsigned proposals. For each batch of unsigned proposals, +the meta handler automatically spawns multiple offline stages **concurrently**. Immediately after the conclusion of each individual offline stage, a consequent voting stage proceeds, allowing for concurrent offline->voting stages. +Once all the voting stages are complete, the meta handler will keep patiently awaiting for the next batch of unsigned proposals, unless, the respective meta remote calls ``shutdown``. + +Inside src/worker.rs, the ``process_incoming_dkg_message`` function now properly broadcasts messages to the appropriate meta handlers. Each meta handler will automatically +discard any messages that are not meant for it, while processing those messages that are indeed meant for it. + +### BlockChainIface +The ``BlockChainIface`` (short for BlockChainInterface) is used to interface the meta handlers with the blockchain. This is where the fields stored in the DKGWorker are shared. + +### Testing +For most effective feedback for debugging, these commands should be used to inspect the DKGWorker and meta handlers +``` +./target/release/dkg-standalone-node --tmp --alice +./target/release/dkg-standalone-node --tmp --bob +./target/release/dkg-standalone-node --tmp --charlie +``` + +### TODO +- Improve internal routing of messages to meta handlers (will speed up performance under heavy loads) diff --git a/dkg-gadget/src/async_protocols/blockchain_interface.rs b/dkg-gadget/src/async_protocols/blockchain_interface.rs new file mode 100644 index 000000000..ba734457a --- /dev/null +++ b/dkg-gadget/src/async_protocols/blockchain_interface.rs @@ -0,0 +1,221 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ + async_protocols::BatchKey, + gossip_engine::GossipEngineIface, + gossip_messages::{dkg_message::sign_and_send_messages, public_key_gossip::gossip_public_key}, + persistence::store_localkey, + proposal::get_signed_proposal, + storage::proposals::save_signed_proposals_in_storage, + worker::{DKGWorker, HasLatestHeader, KeystoreExt}, + Client, DKGApi, DKGKeystore, +}; +use codec::Encode; +use curv::{elliptic::curves::Secp256k1, BigInt}; +use dkg_primitives::{ + types::{ + DKGError, DKGMessage, DKGPublicKeyMessage, DKGSignedPayload, RoundId, SignedDKGMessage, + }, + utils::convert_signature, +}; +use dkg_runtime_primitives::{ + crypto::{AuthorityId, Public}, + AggregatedPublicKeys, AuthoritySet, Proposal, UnsignedProposal, +}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::{ + party_i::SignatureRecid, state_machine::keygen::LocalKey, +}; +use parking_lot::{Mutex, RwLock}; +use sc_client_api::Backend; +use sc_keystore::LocalKeystore; +use sp_arithmetic::traits::AtLeast32BitUnsigned; +use sp_runtime::traits::{Block, NumberFor}; +use std::{collections::HashMap, fmt::Debug, marker::PhantomData, path::PathBuf, sync::Arc}; + +#[auto_impl::auto_impl(Arc,&,&mut)] +pub trait BlockchainInterface: Send + Sync { + type Clock: Debug + AtLeast32BitUnsigned + Copy + Send + Sync; + type GossipEngine: GossipEngineIface; + + fn verify_signature_against_authorities( + &self, + message: Arc>, + ) -> Result, DKGError>; + fn sign_and_send_msg(&self, unsigned_msg: DKGMessage) -> Result<(), DKGError>; + fn process_vote_result( + &self, + signature: SignatureRecid, + unsigned_proposal: UnsignedProposal, + round_id: RoundId, + batch_key: BatchKey, + message: BigInt, + ) -> Result<(), DKGError>; + fn gossip_public_key(&self, key: DKGPublicKeyMessage) -> Result<(), DKGError>; + fn store_public_key(&self, key: LocalKey, round_id: RoundId) + -> Result<(), DKGError>; + fn get_authority_set(&self) -> &Vec; + fn get_gossip_engine(&self) -> Option<&Self::GossipEngine>; + /// Returns the present time + fn now(&self) -> Self::Clock; +} + +pub struct DKGProtocolEngine { + pub backend: Arc, + pub latest_header: Arc>>, + pub client: Arc, + pub keystore: DKGKeystore, + pub gossip_engine: Arc, + pub aggregated_public_keys: Arc>>, + pub best_authorities: Arc>, + pub authority_public_key: Arc, + pub vote_results: Arc>>>, + pub is_genesis: bool, + pub _pd: PhantomData, + pub current_validator_set: Arc>>, + pub local_keystore: Option>, + pub local_key_path: Option, +} + +impl KeystoreExt for DKGProtocolEngine { + fn get_keystore(&self) -> &DKGKeystore { + &self.keystore + } +} + +impl HasLatestHeader for DKGProtocolEngine +where + B: Block, + BE: Backend, + GE: GossipEngineIface, + C: Client, +{ + fn get_latest_header(&self) -> &Arc>> { + &self.latest_header + } +} + +impl BlockchainInterface for DKGProtocolEngine +where + B: Block, + C: Client + 'static, + C::Api: DKGApi>, + BE: Backend + 'static, + GE: GossipEngineIface + 'static, +{ + type Clock = NumberFor; + type GossipEngine = Arc; + + fn verify_signature_against_authorities( + &self, + msg: Arc>, + ) -> Result, DKGError> { + let client = &self.client; + + DKGWorker::<_, _, _, GE>::verify_signature_against_authorities_inner( + (&*msg).clone(), + &self.latest_header, + client, + ) + } + + fn sign_and_send_msg(&self, unsigned_msg: DKGMessage) -> Result<(), DKGError> { + sign_and_send_messages(self.gossip_engine.clone(), &self.keystore, unsigned_msg); + Ok(()) + } + + fn process_vote_result( + &self, + signature: SignatureRecid, + unsigned_proposal: UnsignedProposal, + round_id: RoundId, + batch_key: BatchKey, + _message: BigInt, + ) -> Result<(), DKGError> { + // Call worker.rs: handle_finished_round -> Proposal + // aggregate Proposal into Vec + let payload_key = unsigned_proposal.key; + let signature = convert_signature(&signature).ok_or_else(|| DKGError::CriticalError { + reason: "Unable to serialize signature".to_string(), + })?; + + let finished_round = DKGSignedPayload { + key: round_id.encode(), + payload: unsigned_proposal.data().clone(), + signature: signature.encode(), + }; + + let mut lock = self.vote_results.lock(); + let proposals_for_this_batch = lock.entry(batch_key).or_default(); + + if let Some(proposal) = + get_signed_proposal::(&self.backend, finished_round, payload_key) + { + proposals_for_this_batch.push(proposal); + + if proposals_for_this_batch.len() == batch_key.len { + log::info!(target: "dkg", "All proposals have resolved for batch {:?}", batch_key); + let proposals = lock.remove(&batch_key).unwrap(); // safe unwrap since lock is held + std::mem::drop(lock); + save_signed_proposals_in_storage::( + &self.get_authority_public_key(), + &self.current_validator_set, + &self.latest_header, + &self.backend, + proposals, + ); + } else { + log::info!(target: "dkg", "{}/{} proposals have resolved for batch {:?}", proposals_for_this_batch.len(), batch_key.len, batch_key); + } + } + + Ok(()) + } + + fn gossip_public_key(&self, key: DKGPublicKeyMessage) -> Result<(), DKGError> { + gossip_public_key::( + &self.keystore, + self.gossip_engine.clone(), + &mut *self.aggregated_public_keys.lock(), + key, + ); + Ok(()) + } + + fn store_public_key( + &self, + key: LocalKey, + round_id: RoundId, + ) -> Result<(), DKGError> { + let sr_pub = self.get_sr25519_public_key(); + if let Some(path) = self.local_key_path.clone() { + store_localkey(key, round_id, Some(path), self.local_keystore.as_ref(), sr_pub) + .map_err(|err| DKGError::GenericError { reason: err.to_string() })?; + } + + Ok(()) + } + + fn get_authority_set(&self) -> &Vec { + &*self.best_authorities + } + + fn get_gossip_engine(&self) -> Option<&Self::GossipEngine> { + Some(&self.gossip_engine) + } + + fn now(&self) -> Self::Clock { + self.get_latest_block_number() + } +} diff --git a/dkg-gadget/src/async_protocols/incoming.rs b/dkg-gadget/src/async_protocols/incoming.rs new file mode 100644 index 000000000..cb29630da --- /dev/null +++ b/dkg-gadget/src/async_protocols/incoming.rs @@ -0,0 +1,134 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use dkg_primitives::types::{DKGError, DKGMessage, DKGMsgPayload, RoundId, SignedDKGMessage}; +use dkg_runtime_primitives::crypto::Public; +use futures::Stream; +use round_based::Msg; +use std::{ + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; +use tokio_stream::wrappers::BroadcastStream; + +use super::{blockchain_interface::BlockchainInterface, AsyncProtocolParameters, ProtocolType}; + +/// Used to filter and transform incoming messages from the DKG worker +pub struct IncomingAsyncProtocolWrapper { + pub receiver: BroadcastStream, + round_id: RoundId, + engine: Arc, + ty: ProtocolType, +} + +impl IncomingAsyncProtocolWrapper { + pub fn new( + receiver: tokio::sync::broadcast::Receiver, + ty: ProtocolType, + params: &AsyncProtocolParameters, + ) -> Self { + Self { + receiver: BroadcastStream::new(receiver), + round_id: params.round_id, + engine: params.engine.clone(), + ty, + } + } +} + +pub trait TransformIncoming: Clone + Send + 'static { + type IncomingMapped; + fn transform( + self, + verify: &BI, + stream_type: &ProtocolType, + this_round_id: RoundId, + ) -> Result>, DKGError> + where + Self: Sized; +} + +impl TransformIncoming for Arc> { + type IncomingMapped = DKGMessage; + fn transform( + self, + verify: &BI, + stream_type: &ProtocolType, + this_round_id: RoundId, + ) -> Result>, DKGError> + where + Self: Sized, + { + match (stream_type, &self.msg.payload) { + (ProtocolType::Keygen { .. }, DKGMsgPayload::Keygen(..)) | + (ProtocolType::Offline { .. }, DKGMsgPayload::Offline(..)) | + (ProtocolType::Voting { .. }, DKGMsgPayload::Vote(..)) => { + // only clone if the downstream receiver expects this type + let sender = self.msg.payload.async_proto_only_get_sender_id().unwrap(); + if sender != stream_type.get_i() { + if self.msg.round_id == this_round_id { + verify + .verify_signature_against_authorities(self) + .map(|body| Some(Msg { sender, receiver: None, body })) + } else { + Ok(None) + } + } else { + //log::info!(target: "dkg", "Will skip passing message to state machine since + // loopback (loopback_id={})", sender); + Ok(None) + } + }, + + (_l, _r) => { + //log::warn!("Received message for mixed stage: Local: {:?}, payload: {:?}", l, r); + Ok(None) + }, + } + } +} + +impl Stream for IncomingAsyncProtocolWrapper +where + T: TransformIncoming, + BI: BlockchainInterface, +{ + type Item = Msg; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let Self { receiver, ty, engine, round_id } = &mut *self; + let mut receiver = Pin::new(receiver); + + loop { + match futures::ready!(receiver.as_mut().poll_next(cx)) { + Some(Ok(msg)) => match msg.transform(&**engine, &*ty, *round_id) { + Ok(Some(msg)) => return Poll::Ready(Some(msg)), + + Ok(None) => continue, + + Err(err) => { + log::warn!(target: "dkg", "While mapping signed message, received an error: {:?}", err); + continue + }, + }, + Some(Err(err)) => { + log::error!(target: "dkg", "Stream RECV error: {:?}", err); + continue + }, + None => return Poll::Ready(None), + } + } + } +} diff --git a/dkg-gadget/src/async_protocols/keygen/handler.rs b/dkg-gadget/src/async_protocols/keygen/handler.rs new file mode 100644 index 000000000..4ae77ac76 --- /dev/null +++ b/dkg-gadget/src/async_protocols/keygen/handler.rs @@ -0,0 +1,106 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::async_protocols::{ + blockchain_interface::BlockchainInterface, get_party_round_id, new_inner, + remote::MetaHandlerStatus, state_machine::StateMachineHandler, AsyncProtocolParameters, + GenericAsyncHandler, ProtocolType, +}; + +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::keygen::Keygen; + +use std::fmt::Debug; + +use dkg_primitives::types::DKGError; +use futures::FutureExt; + +impl<'a, Out: Send + Debug + 'a> GenericAsyncHandler<'a, Out> +where + (): Extend, +{ + /// Top-level function used to begin the execution of async protocols + pub fn setup_keygen( + params: AsyncProtocolParameters, + threshold: u16, + ) -> Result, DKGError> { + let status_handle = params.handle.clone(); + let mut stop_rx = + status_handle.stop_rx.lock().take().ok_or_else(|| DKGError::GenericError { + reason: "execute called twice with the same AsyncProtocol Parameters".to_string(), + })?; + + let start_rx = + status_handle.start_rx.lock().take().ok_or_else(|| DKGError::GenericError { + reason: "execute called twice with the same AsyncProtocol Parameters".to_string(), + })?; + + let protocol = async move { + let params = params; + let (keygen_id, _b, _c) = get_party_round_id(¶ms); + if let Some(keygen_id) = keygen_id { + log::info!(target: "dkg", "Will execute keygen since local is in best authority set"); + let t = threshold; + let n = params.best_authorities.len() as u16; + // wait for the start signal + start_rx + .await + .map_err(|err| DKGError::StartKeygen { reason: err.to_string() })?; + // Set status of the handle + params.handle.set_status(MetaHandlerStatus::Keygen); + // Execute the keygen + GenericAsyncHandler::new_keygen(params.clone(), keygen_id, t, n, 0)?.await?; + log::debug!(target: "dkg", "Keygen stage complete!"); + } else { + log::info!(target: "dkg", "Will skip keygen since local is NOT in best authority set"); + } + + Ok(()) + } + .then(|res| async move { + status_handle.set_status(MetaHandlerStatus::Complete); + log::info!(target: "dkg", "🕸️ Keygen GenericAsyncHandler completed"); + res + }); + + let protocol = Box::pin(async move { + tokio::select! { + res0 = protocol => res0, + res1 = stop_rx.recv() => { + log::info!(target: "dkg", "Stopper has been called {:?}", res1); + Ok(()) + } + } + }); + + Ok(GenericAsyncHandler { protocol }) + } + + fn new_keygen( + params: AsyncProtocolParameters, + i: u16, + t: u16, + n: u16, + async_index: u8, + ) -> Result::Return>, DKGError> { + let channel_type = ProtocolType::Keygen { i, t, n }; + new_inner( + (), + Keygen::new(i, t, n) + .map_err(|err| DKGError::CriticalError { reason: err.to_string() })?, + params, + channel_type, + async_index, + ) + } +} diff --git a/node/src/lib.rs b/dkg-gadget/src/async_protocols/keygen/mod.rs similarity index 93% rename from node/src/lib.rs rename to dkg-gadget/src/async_protocols/keygen/mod.rs index 54a283dd1..82ecb0339 100644 --- a/node/src/lib.rs +++ b/dkg-gadget/src/async_protocols/keygen/mod.rs @@ -11,6 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -pub mod chain_spec; -pub mod service; + +pub mod handler; +pub mod state_machine; diff --git a/dkg-gadget/src/async_protocols/keygen/state_machine.rs b/dkg-gadget/src/async_protocols/keygen/state_machine.rs new file mode 100644 index 000000000..67d96f79c --- /dev/null +++ b/dkg-gadget/src/async_protocols/keygen/state_machine.rs @@ -0,0 +1,89 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::async_protocols::{ + blockchain_interface::BlockchainInterface, get_party_round_id, + state_machine::StateMachineHandler, AsyncProtocolParameters, ProtocolType, +}; +use async_trait::async_trait; +use dkg_primitives::types::{DKGError, DKGMessage, DKGMsgPayload, DKGPublicKeyMessage}; +use dkg_runtime_primitives::crypto::Public; +use futures::channel::mpsc::UnboundedSender; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::keygen::{ + Keygen, ProtocolMessage, +}; +use round_based::{containers::StoreErr, Msg, StateMachine}; + +#[async_trait] +impl StateMachineHandler for Keygen { + type AdditionalReturnParam = (); + type Return = ::Output; + + fn handle_unsigned_message( + to_async_proto: &UnboundedSender>, + msg: Msg>, + local_ty: &ProtocolType, + ) -> Result<(), ::Err> { + let DKGMessage { payload, .. } = msg.body; + // Send the payload to the appropriate AsyncProtocols + match payload { + DKGMsgPayload::Keygen(msg) => { + log::info!(target: "dkg", "Handling Keygen inbound message from id={}", msg.sender_id); + use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::keygen::Error as Error; + let message: Msg = + serde_json::from_slice(msg.keygen_msg.as_slice()) + .map_err(|_err| Error::HandleMessage(StoreErr::NotForMe))?; + + if let Some(recv) = message.receiver.as_ref() { + if *recv != local_ty.get_i() { + log::info!("Skipping passing of message to async proto since not intended for local"); + return Ok(()) + } + } + to_async_proto + .unbounded_send(message) + .map_err(|_| Error::HandleMessage(StoreErr::NotForMe))?; + }, + + err => log::debug!(target: "dkg", "Invalid payload received: {:?}", err), + } + + Ok(()) + } + + async fn on_finish( + local_key: ::Output, + params: AsyncProtocolParameters, + _: Self::AdditionalReturnParam, + _: u8, + ) -> Result<::Output, DKGError> { + log::info!(target: "dkg", "Completed keygen stage successfully!"); + // PublicKeyGossip (we need meta handler to handle this) + // when keygen finishes, we gossip the signed key to peers. + // [1] create the message, call the "public key gossip" in + // public_key_gossip.rs:gossip_public_key [2] store public key locally (public_keys.rs: + // store_aggregated_public_keys) + let round_id = get_party_round_id(¶ms).1; + let pub_key_msg = DKGPublicKeyMessage { + round_id, + pub_key: local_key.public_key().to_bytes(true).to_vec(), + signature: vec![], + }; + + params.engine.gossip_public_key(pub_key_msg)?; + params.engine.store_public_key(local_key.clone(), round_id)?; + + Ok(local_key) + } +} diff --git a/dkg-gadget/src/async_protocols/misbehaviour_monitor.rs b/dkg-gadget/src/async_protocols/misbehaviour_monitor.rs new file mode 100644 index 000000000..c774b5935 --- /dev/null +++ b/dkg-gadget/src/async_protocols/misbehaviour_monitor.rs @@ -0,0 +1,123 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::async_protocols::{ + blockchain_interface::BlockchainInterface, remote::MetaHandlerStatus, AsyncProtocolRemote, +}; +use dkg_primitives::{ + crypto::Public, + types::{DKGError, DKGMisbehaviourMessage, RoundId}, +}; +use dkg_runtime_primitives::MisbehaviourType; +use futures::StreamExt; +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, + time::Duration, +}; +use tokio::sync::mpsc::UnboundedSender; + +/// The purpose of the misbehaviour monitor is to periodically check +/// the Meta handler to ensure that there are no misbehaving clients +pub struct MisbehaviourMonitor { + inner: Pin> + Send>>, +} + +/// How frequently the misbehaviour monitor checks for misbehaving peers +pub const MISBEHAVIOUR_MONITOR_CHECK_INTERVAL: Duration = Duration::from_millis(2000); + +impl MisbehaviourMonitor { + pub fn new( + remote: AsyncProtocolRemote, + bc_iface: BI, + misbehaviour_tx: UnboundedSender, + ) -> Self + where + BI::Clock: 'static, + { + Self { + inner: Box::pin(async move { + let mut ticker = tokio_stream::wrappers::IntervalStream::new( + tokio::time::interval(MISBEHAVIOUR_MONITOR_CHECK_INTERVAL), + ); + + while let Some(_tick) = ticker.next().await { + log::debug!("[MisbehaviourMonitor] Performing periodic check ..."); + log::debug!("[MisbehaviourMonitor] Remote status {:?}", remote.get_status()); + log::debug!( + "[MisbehaviourMonitor] Unreceived messages: {:?}", + remote.current_round_blame() + ); + match remote.get_status() { + MetaHandlerStatus::Keygen => + if remote.keygen_has_stalled(bc_iface.now()) { + on_keygen_timeout::( + &remote, + bc_iface.get_authority_set().as_slice(), + &misbehaviour_tx, + remote.round_id, + )? + }, + MetaHandlerStatus::OfflineAndVoting => {}, + _ => { + // TODO: handle monitoring other stages + }, + } + } + + Err(DKGError::CriticalError { + reason: "Misbehaviour monitor ended prematurely".to_string(), + }) + }), + } + } +} + +pub fn on_keygen_timeout( + remote: &AsyncProtocolRemote, + authority_set: &[Public], + misbehaviour_tx: &UnboundedSender, + round_id: RoundId, +) -> Result<(), DKGError> { + log::warn!("[MisbehaviourMonitor] Keygen has stalled! Will determine which authorities are misbehaving ..."); + let round_blame = remote.current_round_blame(); + for party_i in round_blame.blamed_parties { + // get the authority from the party index. + authority_set + .get(usize::from(party_i - 1)) + .cloned() + .map(|offender| DKGMisbehaviourMessage { + misbehaviour_type: MisbehaviourType::Keygen, + round_id, + offender, + signature: vec![], + }) + .and_then(|report| misbehaviour_tx.send(report).ok()) + .ok_or_else(|| DKGError::CriticalError { + reason: format!("failed to report {party_i}"), + })?; + log::warn!("Blamed {party_i} for keygen stalled!"); + } + + Ok(()) +} + +impl Future for MisbehaviourMonitor { + type Output = Result<(), DKGError>; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.inner.as_mut().poll(cx) + } +} diff --git a/dkg-gadget/src/async_protocols/mod.rs b/dkg-gadget/src/async_protocols/mod.rs new file mode 100644 index 000000000..5495f8a51 --- /dev/null +++ b/dkg-gadget/src/async_protocols/mod.rs @@ -0,0 +1,365 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod blockchain_interface; +pub mod incoming; +pub mod keygen; +pub mod misbehaviour_monitor; +pub mod remote; +pub mod sign; +pub mod state_machine; +pub mod state_machine_wrapper; + +#[cfg(test)] +pub mod test_utils; + +use curv::elliptic::curves::Secp256k1; +use dkg_primitives::{ + crypto::{AuthorityId, Public}, + types::{DKGError, DKGKeygenMessage, DKGMessage, DKGMsgPayload, DKGOfflineMessage, RoundId}, + AuthoritySet, AuthoritySetId, +}; +use dkg_runtime_primitives::UnsignedProposal; +use futures::{ + channel::mpsc::{UnboundedReceiver, UnboundedSender}, + Future, StreamExt, +}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::{ + keygen::LocalKey, sign::CompletedOfflineStage, +}; +use parking_lot::RwLock; +use round_based::{async_runtime::watcher::StderrWatcher, AsyncProtocol, Msg, StateMachine}; +use serde::Serialize; +use std::{ + fmt::{Debug, Formatter}, + pin::Pin, + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, + }, + task::{Context, Poll}, +}; + +use self::{ + blockchain_interface::BlockchainInterface, remote::AsyncProtocolRemote, + state_machine::StateMachineHandler, state_machine_wrapper::StateMachineWrapper, +}; +use crate::{ + utils::{find_index, SendFuture}, + worker::KeystoreExt, + DKGKeystore, +}; +use incoming::IncomingAsyncProtocolWrapper; + +pub struct AsyncProtocolParameters { + pub engine: Arc, + pub keystore: DKGKeystore, + pub current_validator_set: Arc>>, + pub best_authorities: Arc>, + pub authority_public_key: Arc, + pub batch_id_gen: Arc, + pub handle: AsyncProtocolRemote, + pub round_id: RoundId, + pub local_key: Option>, +} + +impl KeystoreExt for AsyncProtocolParameters { + fn get_keystore(&self) -> &DKGKeystore { + &self.keystore + } +} + +impl AsyncProtocolParameters { + pub fn get_next_batch_key(&self, batch: &[UnsignedProposal]) -> BatchKey { + BatchKey { id: self.batch_id_gen.fetch_add(1, Ordering::SeqCst), len: batch.len() } + } +} + +// Manual implementation of Clone due to https://stegosaurusdormant.com/understanding-derive-clone/ +impl Clone for AsyncProtocolParameters { + fn clone(&self) -> Self { + Self { + round_id: self.round_id, + engine: self.engine.clone(), + keystore: self.keystore.clone(), + current_validator_set: self.current_validator_set.clone(), + best_authorities: self.best_authorities.clone(), + authority_public_key: self.authority_public_key.clone(), + batch_id_gen: self.batch_id_gen.clone(), + handle: self.handle.clone(), + local_key: self.local_key.clone(), + } + } +} + +#[derive(Debug, Clone, Default)] +pub struct CurrentRoundBlame { + /// a numbers of messages yet to recieve + pub unreceived_messages: u16, + /// a list of uncorporative parties + pub blamed_parties: Vec, +} + +impl CurrentRoundBlame { + pub fn empty() -> Self { + Self::default() + } +} + +#[derive(Clone)] +pub enum ProtocolType { + Keygen { + i: u16, + t: u16, + n: u16, + }, + Offline { + unsigned_proposal: Arc, + i: u16, + s_l: Vec, + local_key: Arc>, + }, + Voting { + offline_stage: Arc, + unsigned_proposal: Arc, + i: u16, + }, +} + +impl ProtocolType { + pub fn get_i(&self) -> PartyIndex { + match self { + Self::Keygen { i, .. } | Self::Offline { i, .. } | Self::Voting { i, .. } => *i, + } + } + + pub fn get_unsigned_proposal(&self) -> Option<&UnsignedProposal> { + match self { + Self::Offline { unsigned_proposal, .. } | Self::Voting { unsigned_proposal, .. } => + Some(&*unsigned_proposal), + _ => None, + } + } +} + +impl Debug for ProtocolType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + ProtocolType::Keygen { i, t, n } => { + write!(f, "Keygen: (i, t, n) = ({}, {}, {})", i, t, n) + }, + ProtocolType::Offline { i, unsigned_proposal, .. } => { + write!(f, "Offline: (i, proposal) = ({}, {:?})", i, &unsigned_proposal.proposal) + }, + ProtocolType::Voting { unsigned_proposal, .. } => { + write!(f, "Voting: proposal = {:?}", &unsigned_proposal.proposal) + }, + } + } +} + +pub type PartyIndex = u16; +pub type Threshold = u16; +pub type BatchId = u64; + +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +pub struct BatchKey { + pub len: usize, + pub id: BatchId, +} + +pub struct GenericAsyncHandler<'a, Out> { + pub protocol: Pin>>, +} + +impl Unpin for GenericAsyncHandler<'_, Out> {} +impl Future for GenericAsyncHandler<'_, Out> { + type Output = Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.protocol.as_mut().poll(cx) + } +} + +pub fn new_inner<'a, SM: StateMachineHandler + 'static, BI: BlockchainInterface + 'a>( + additional_param: SM::AdditionalReturnParam, + sm: SM, + params: AsyncProtocolParameters, + channel_type: ProtocolType, + async_index: u8, +) -> Result, DKGError> +where + ::Err: Send + Debug, + ::MessageBody: Send, + ::MessageBody: Serialize, + ::Output: Send, +{ + let (incoming_tx_proto, incoming_rx_proto) = SM::generate_channel(); + let (outgoing_tx, outgoing_rx) = futures::channel::mpsc::unbounded(); + + let sm = StateMachineWrapper::new(sm, params.handle.current_round_blame_tx.clone()); + + let mut async_proto = AsyncProtocol::new( + sm, + incoming_rx_proto.map(Ok::<_, ::Err>), + outgoing_tx, + ) + .set_watcher(StderrWatcher); + + let params_for_end_of_proto = params.clone(); + + let async_proto = Box::pin(async move { + let res = async_proto + .run() + .await + .map_err(|err| DKGError::GenericError { reason: format!("{:?}", err) })?; + + SM::on_finish(res, params_for_end_of_proto, additional_param, async_index).await + }); + + // 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(), + async_index, + ); + + // For taking raw inbound signed messages, mapping them to unsigned messages, then + // sending to the appropriate AsyncProtocol + let inbound_signed_message_receiver = generate_inbound_signed_message_receiver_fn::( + params, + channel_type.clone(), + incoming_tx_proto, + ); + + // Combine all futures into a concurrent select subroutine + let protocol = async move { + tokio::select! { + proto_res = async_proto => { + log::info!(target: "dkg", "🕸️ Protocol {:?} Ended: {:?}", channel_type.clone(), proto_res); + proto_res + }, + + outgoing_res = outgoing_to_wire => { + log::error!(target: "dkg", "🕸️ Outbound Sender Ended: {:?}", outgoing_res); + Err(DKGError::GenericError { reason: "Outbound sender ended".to_string() }) + }, + + incoming_res = inbound_signed_message_receiver => { + log::error!(target: "dkg", "🕸️ Inbound Receiver Ended: {:?}", incoming_res); + Err(DKGError::GenericError { reason: "Incoming receiver ended".to_string() }) + } + } + }; + + Ok(GenericAsyncHandler { protocol: Box::pin(protocol) }) +} + +fn get_party_round_id<'a, BI: BlockchainInterface + 'a>( + params: &AsyncProtocolParameters, +) -> (Option, AuthoritySetId, Public) { + let party_ind = + find_index::(¶ms.best_authorities, ¶ms.authority_public_key) + .map(|r| r as u16 + 1); + let round_id = params.round_id; + let id = params.get_authority_public_key(); + + (party_ind, round_id, id) +} + +fn generate_outgoing_to_wire_fn<'a, SM: StateMachineHandler + 'a, BI: BlockchainInterface + 'a>( + params: AsyncProtocolParameters, + mut outgoing_rx: UnboundedReceiver::MessageBody>>, + proto_ty: ProtocolType, + async_index: u8, +) -> impl SendFuture<'a, ()> +where + ::MessageBody: Serialize, + ::MessageBody: Send, + ::Output: Send, +{ + Box::pin(async move { + // take all unsigned messages, then sign them and send outbound + while let Some(unsigned_message) = outgoing_rx.next().await { + log::info!(target: "dkg", "Async proto sent outbound request on node={:?} to: {:?} |(ty: {:?})", unsigned_message.sender, unsigned_message.receiver, &proto_ty); + let party_id = unsigned_message.sender; + let serialized_body = serde_json::to_vec(&unsigned_message) + .map_err(|err| DKGError::GenericError { reason: err.to_string() })?; + let (_, round_id, id) = get_party_round_id(¶ms); + + let payload = match &proto_ty { + ProtocolType::Keygen { .. } => DKGMsgPayload::Keygen(DKGKeygenMessage { + sender_id: party_id, + keygen_msg: serialized_body, + }), + ProtocolType::Offline { unsigned_proposal, .. } => + DKGMsgPayload::Offline(DKGOfflineMessage { + key: Vec::from(&unsigned_proposal.hash().unwrap() as &[u8]), + signer_set_id: party_id as u64, + offline_msg: serialized_body, + async_index, + }), + _ => { + unreachable!( + "Should not happen since voting is handled with a custom subroutine" + ) + }, + }; + + let unsigned_dkg_message = DKGMessage { id, payload, round_id }; + params.engine.sign_and_send_msg(unsigned_dkg_message)?; + log::info!(target: "dkg", "🕸️ Async proto sent outbound message: {:?}", &proto_ty); + } + + Err(DKGError::CriticalError { + reason: "Outbound stream stopped producing items".to_string(), + }) + }) +} + +pub fn generate_inbound_signed_message_receiver_fn< + 'a, + SM: StateMachineHandler + 'a, + BI: BlockchainInterface + 'a, +>( + params: AsyncProtocolParameters, + channel_type: ProtocolType, + to_async_proto: UnboundedSender::MessageBody>>, +) -> impl SendFuture<'a, ()> +where + ::MessageBody: Send, + ::Output: Send, +{ + Box::pin(async move { + // the below wrapper will map signed messages into unsigned messages + let incoming = params.handle.broadcaster.subscribe(); + let mut incoming_wrapper = + IncomingAsyncProtocolWrapper::new(incoming, channel_type.clone(), ¶ms); + + while let Some(unsigned_message) = incoming_wrapper.next().await { + if SM::handle_unsigned_message(&to_async_proto, unsigned_message, &channel_type) + .is_err() + { + log::error!(target: "dkg", "Error handling unsigned inbound message. Returning"); + break + } + } + + Err::<(), _>(DKGError::CriticalError { + reason: "Inbound stream stopped producing items".to_string(), + }) + }) +} diff --git a/dkg-gadget/src/async_protocols/remote.rs b/dkg-gadget/src/async_protocols/remote.rs new file mode 100644 index 000000000..c8625f289 --- /dev/null +++ b/dkg-gadget/src/async_protocols/remote.rs @@ -0,0 +1,168 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::async_protocols::CurrentRoundBlame; +use atomic::Atomic; +use dkg_primitives::types::{DKGError, RoundId, SignedDKGMessage}; +use dkg_runtime_primitives::{crypto::Public, KEYGEN_TIMEOUT}; +use parking_lot::Mutex; +use sp_arithmetic::traits::AtLeast32BitUnsigned; +use std::sync::{atomic::Ordering, Arc}; + +#[derive(Clone)] +pub struct AsyncProtocolRemote { + pub(crate) status: Arc>, + pub(crate) broadcaster: tokio::sync::broadcast::Sender>>, + start_tx: Arc>>>, + pub(crate) start_rx: Arc>>>, + stop_tx: Arc>>>, + pub(crate) stop_rx: Arc>>>, + pub(crate) started_at: C, + is_primary_remote: bool, + current_round_blame: tokio::sync::watch::Receiver, + pub(crate) current_round_blame_tx: Arc>, + pub(crate) round_id: RoundId, +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum MetaHandlerStatus { + Beginning, + Keygen, + AwaitingProposals, + OfflineAndVoting, + Complete, + Terminated, +} + +impl AsyncProtocolRemote { + /// Create at the beginning of each meta handler instantiation + pub fn new(at: C, round_id: RoundId) -> Self { + let (stop_tx, stop_rx) = tokio::sync::mpsc::unbounded_channel(); + let (broadcaster, _) = tokio::sync::broadcast::channel(4096); + let (start_tx, start_rx) = tokio::sync::oneshot::channel(); + + let (current_round_blame_tx, current_round_blame) = + tokio::sync::watch::channel(CurrentRoundBlame::empty()); + + Self { + status: Arc::new(Atomic::new(MetaHandlerStatus::Beginning)), + broadcaster, + started_at: at, + start_tx: Arc::new(Mutex::new(Some(start_tx))), + start_rx: Arc::new(Mutex::new(Some(start_rx))), + stop_tx: Arc::new(Mutex::new(Some(stop_tx))), + stop_rx: Arc::new(Mutex::new(Some(stop_rx))), + current_round_blame, + current_round_blame_tx: Arc::new(current_round_blame_tx), + is_primary_remote: false, + round_id, + } + } + + pub fn keygen_has_stalled(&self, now: C) -> bool { + self.keygen_is_not_complete() && (now - self.started_at > KEYGEN_TIMEOUT.into()) + } + + pub fn keygen_is_not_complete(&self) -> bool { + self.get_status() != MetaHandlerStatus::Complete || + self.get_status() == MetaHandlerStatus::Terminated + } +} + +impl AsyncProtocolRemote { + pub fn get_status(&self) -> MetaHandlerStatus { + self.status.load(Ordering::SeqCst) + } + + pub fn set_status(&self, status: MetaHandlerStatus) { + self.status.store(status, Ordering::SeqCst) + } + + pub fn is_active(&self) -> bool { + let status = self.get_status(); + status != MetaHandlerStatus::Beginning && + status != MetaHandlerStatus::Complete && + status != MetaHandlerStatus::Terminated + } + + pub fn deliver_message( + &self, + msg: Arc>, + ) -> Result<(), tokio::sync::broadcast::error::SendError>>> { + if self.broadcaster.receiver_count() != 0 { + self.broadcaster.send(msg).map(|_| ()) + } else { + // do not forward the message + Ok(()) + } + } + + /// Determines if there are any active listeners + #[allow(dead_code)] + pub fn is_receiving(&self) -> bool { + self.broadcaster.receiver_count() != 0 + } + + /// Stops the execution of the meta handler, including all internal asynchronous subroutines + pub fn start(&self) -> Result<(), DKGError> { + let tx = self.start_tx.lock().take().ok_or_else(|| DKGError::GenericError { + reason: "Start has already been called".to_string(), + })?; + tx.send(()).map_err(|_| DKGError::GenericError { + reason: "Unable to send start signal (already shut down?)".to_string(), + }) + } + + /// Stops the execution of the meta handler, including all internal asynchronous subroutines + pub fn shutdown(&self) -> Result<(), DKGError> { + let tx = self.stop_tx.lock().take().ok_or_else(|| DKGError::GenericError { + reason: "Shutdown has already been called".to_string(), + })?; + tx.send(()).map_err(|_| DKGError::GenericError { + reason: "Unable to send shutdown signal (already shut down?)".to_string(), + }) + } + + pub fn is_keygen_finished(&self) -> bool { + let state = self.get_status(); + matches!(state, MetaHandlerStatus::Complete) + } + + pub fn current_round_blame(&self) -> CurrentRoundBlame { + self.current_round_blame.borrow().clone() + } + + /// Setting this as the primary remote + pub fn into_primary_remote(mut self) -> Self { + self.is_primary_remote = true; + self + } +} + +impl Drop for AsyncProtocolRemote { + fn drop(&mut self) { + if Arc::strong_count(&self.status) == 2 || self.is_primary_remote { + // at this point, the only instances of this arc are this one, and, + // presumably the one in the DKG worker. This one is asserted to be the one + // belonging to the async proto. Signal as complete to allow the DKG worker to move + // forward + if self.get_status() != MetaHandlerStatus::Complete { + log::info!(target: "dkg", "[drop code] MetaAsyncProtocol is ending: {:?}", self.get_status()); + self.set_status(MetaHandlerStatus::Terminated); + } + + let _ = self.shutdown(); + } + } +} diff --git a/dkg-gadget/src/async_protocols/sign/handler.rs b/dkg-gadget/src/async_protocols/sign/handler.rs new file mode 100644 index 000000000..4de5826e1 --- /dev/null +++ b/dkg-gadget/src/async_protocols/sign/handler.rs @@ -0,0 +1,292 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use curv::{arithmetic::Converter, elliptic::curves::Secp256k1, BigInt}; +use dkg_runtime_primitives::UnsignedProposal; +use futures::{stream::FuturesUnordered, StreamExt, TryStreamExt}; + +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::{ + keygen::LocalKey, + sign::{CompletedOfflineStage, OfflineStage, PartialSignature, SignManual}, +}; +use std::{fmt::Debug, sync::Arc}; +use tokio::sync::broadcast::Receiver; + +use crate::async_protocols::{ + blockchain_interface::BlockchainInterface, get_party_round_id, + incoming::IncomingAsyncProtocolWrapper, new_inner, remote::MetaHandlerStatus, + state_machine::StateMachineHandler, AsyncProtocolParameters, BatchKey, GenericAsyncHandler, + PartyIndex, ProtocolType, Threshold, +}; +use dkg_primitives::types::{ + DKGError, DKGMessage, DKGMsgPayload, DKGVoteMessage, SignedDKGMessage, +}; +use dkg_runtime_primitives::crypto::Public; +use futures::FutureExt; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::party_i::verify; + +impl<'a, Out: Send + Debug + 'a> GenericAsyncHandler<'a, Out> +where + (): Extend, +{ + /// Top level function for setting up signing + pub fn setup_signing( + params: AsyncProtocolParameters, + threshold: u16, + unsigned_proposals: Vec, + signing_set: Vec, + async_index: u8, + ) -> Result, DKGError> { + assert!( + threshold + 1 == signing_set.len() as u16, + "Signing set must be of size threshold + 1" + ); + let status_handle = params.handle.clone(); + let mut stop_rx = + status_handle.stop_rx.lock().take().ok_or_else(|| DKGError::GenericError { + reason: "execute called twice with the same AsyncProtocol Parameters".to_string(), + })?; + + let start_rx = + status_handle.start_rx.lock().take().ok_or_else(|| DKGError::GenericError { + reason: "execute called twice with the same AsyncProtocol Parameters".to_string(), + })?; + + let protocol = async move { + let params = params; + let maybe_local_key = params.local_key.clone(); + let (keygen_id, _b, _c) = get_party_round_id(¶ms); + if let (Some(keygen_id), Some(local_key)) = (keygen_id, maybe_local_key) { + let t = threshold; + + start_rx + .await + .map_err(|err| DKGError::StartOffline { reason: err.to_string() })?; + + params.handle.set_status(MetaHandlerStatus::OfflineAndVoting); + let count_in_batch = unsigned_proposals.len(); + let batch_key = params.get_next_batch_key(&unsigned_proposals); + + log::debug!(target: "dkg", "Got unsigned proposals count {}", unsigned_proposals.len()); + + if let Some(offline_i) = Self::get_offline_stage_index(&signing_set, keygen_id) { + log::info!(target: "dkg", "Offline stage index: {}", offline_i); + + // create one offline stage for each unsigned proposal + let futures = FuturesUnordered::new(); + for unsigned_proposal in unsigned_proposals { + futures.push(Box::pin(GenericAsyncHandler::new_offline( + params.clone(), + unsigned_proposal, + offline_i, + signing_set.clone(), + local_key.clone(), + t, + batch_key, + async_index, + )?)); + } + + // NOTE: this will block at each batch of unsigned proposals. + // TODO: Consider not blocking here and allowing processing of + // each batch of unsigned proposals concurrently + futures.try_collect::<()>().await.map(|_| ())?; + log::info!( + target: "dkg", + "Concluded all Offline->Voting stages ({} total) for this batch for this node", + count_in_batch + ); + } else { + log::warn!(target: "dkg", "🕸️ We are not among signers, skipping"); + return Err(DKGError::GenericError { + reason: "We are not among signers, skipping".to_string(), + }) + } + } else { + log::info!(target: "dkg", "Will skip keygen since local is NOT in best authority set"); + } + + Ok(()) + } + .then(|res| async move { + status_handle.set_status(MetaHandlerStatus::Complete); + log::info!(target: "dkg", "🕸️ Offline GenericAsyncHandler completed"); + res + }); + + let protocol = Box::pin(async move { + tokio::select! { + res0 = protocol => res0, + res1 = stop_rx.recv() => { + log::info!(target: "dkg", "Stopper has been called {:?}", res1); + Ok(()) + } + } + }); + + Ok(GenericAsyncHandler { protocol }) + } + + #[allow(clippy::too_many_arguments)] + fn new_offline( + params: AsyncProtocolParameters, + unsigned_proposal: UnsignedProposal, + i: u16, + s_l: Vec, + local_key: LocalKey, + threshold: u16, + batch_key: BatchKey, + async_index: u8, + ) -> Result::Return>, DKGError> { + let channel_type = ProtocolType::Offline { + unsigned_proposal: Arc::new(unsigned_proposal.clone()), + i, + s_l: s_l.clone(), + local_key: Arc::new(local_key.clone()), + }; + let early_handle = params.handle.broadcaster.subscribe(); + new_inner( + (unsigned_proposal, i, early_handle, threshold, batch_key), + OfflineStage::new(i, s_l, local_key) + .map_err(|err| DKGError::CriticalError { reason: err.to_string() })?, + params, + channel_type, + async_index, + ) + } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn new_voting( + params: AsyncProtocolParameters, + completed_offline_stage: CompletedOfflineStage, + unsigned_proposal: UnsignedProposal, + party_ind: PartyIndex, + rx: Receiver>>, + threshold: Threshold, + batch_key: BatchKey, + async_index: u8, + ) -> Result, DKGError> { + let protocol = Box::pin(async move { + let ty = ProtocolType::Voting { + offline_stage: Arc::new(completed_offline_stage.clone()), + unsigned_proposal: Arc::new(unsigned_proposal.clone()), + i: party_ind, + }; + + // the below wrapper will map signed messages into unsigned messages + let incoming = rx; + let incoming_wrapper = &mut IncomingAsyncProtocolWrapper::new(incoming, ty, ¶ms); + let (_, round_id, id) = get_party_round_id(¶ms); + // the first step is to generate the partial sig based on the offline stage + let number_of_parties = params.best_authorities.len(); + + log::info!(target: "dkg", "Will now begin the voting stage with n={} parties for idx={}", number_of_parties, party_ind); + + let hash_of_proposal = unsigned_proposal.hash().ok_or_else(|| DKGError::Vote { + reason: "The unsigned proposal for this stage is invalid".to_string(), + })?; + + let message = BigInt::from_bytes(&hash_of_proposal); + let offline_stage_pub_key = &completed_offline_stage.public_key().clone(); + + let (signing, partial_signature) = + SignManual::new(message.clone(), completed_offline_stage) + .map_err(|err| DKGError::Vote { reason: err.to_string() })?; + + let partial_sig_bytes = serde_json::to_vec(&partial_signature).unwrap(); + + let payload = DKGMsgPayload::Vote(DKGVoteMessage { + party_ind, + // use the hash of proposal as "round key" ONLY for purposes of ensuring + // uniqueness We only want voting to happen amongst voters under the SAME + // proposal, not different proposals This is now especially necessary since we + // are allowing for parallelism now + round_key: Vec::from(&hash_of_proposal as &[u8]), + partial_signature: partial_sig_bytes, + async_index, + }); + + // now, broadcast the data + let unsigned_dkg_message = DKGMessage { id, payload, round_id }; + params.engine.sign_and_send_msg(unsigned_dkg_message)?; + + // we only need a threshold count of sigs + let number_of_partial_sigs = threshold as usize; + let mut sigs = Vec::with_capacity(number_of_partial_sigs); + + log::info!(target: "dkg", "Must obtain {} partial sigs to continue ...", number_of_partial_sigs); + + while let Some(msg) = incoming_wrapper.next().await { + if let DKGMsgPayload::Vote(dkg_vote_msg) = msg.body.payload { + // only process messages which are from the respective proposal + if dkg_vote_msg.round_key.as_slice() == hash_of_proposal { + log::info!(target: "dkg", "Found matching round key!"); + let partial = serde_json::from_slice::( + &dkg_vote_msg.partial_signature, + ) + .map_err(|err| DKGError::GenericError { reason: err.to_string() })?; + sigs.push(partial); + log::info!(target: "dkg", "There are now {} partial sigs ...", sigs.len()); + if sigs.len() == number_of_partial_sigs { + break + } + } else { + //log::info!(target: "dkg", "Skipping DKG vote message since round + // keys did not match"); + } + } + } + + log::info!("RD0 on {} for {:?}", party_ind, hash_of_proposal); + + if sigs.len() != number_of_partial_sigs { + log::error!(target: "dkg", "Received number of signs not equal to expected (received: {} | expected: {})", sigs.len(), number_of_partial_sigs); + return Err(DKGError::Vote { + reason: "Invalid number of received partial sigs".to_string(), + }) + } + + log::info!("RD1"); + let signature = signing + .complete(&sigs) + .map_err(|err| DKGError::GenericError { reason: err.to_string() })?; + + log::info!("RD2"); + verify(&signature, offline_stage_pub_key, &message).map_err(|_err| DKGError::Vote { + reason: "Verification of voting stage failed".to_string(), + })?; + log::info!("RD3"); + + params.engine.process_vote_result( + signature, + unsigned_proposal, + round_id, + batch_key, + message, + ) + }); + + Ok(GenericAsyncHandler { protocol }) + } + + /// Returns our party's index in signers vec if any. + /// Indexing starts from 1. + /// OfflineStage must be created using this index if present (not the original keygen index) + fn get_offline_stage_index(s_l: &[u16], keygen_party_idx: u16) -> Option { + (1..) + .zip(s_l) + .find(|(_i, keygen_i)| keygen_party_idx == **keygen_i) + .map(|r| r.0) + } +} diff --git a/dkg-primitives/src/rounds/mod.rs b/dkg-gadget/src/async_protocols/sign/mod.rs similarity index 88% rename from dkg-primitives/src/rounds/mod.rs rename to dkg-gadget/src/async_protocols/sign/mod.rs index b50166311..82ecb0339 100644 --- a/dkg-primitives/src/rounds/mod.rs +++ b/dkg-gadget/src/async_protocols/sign/mod.rs @@ -11,10 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -pub mod dkg; -pub mod keygen; -pub mod offline; -pub mod sign; -pub use dkg::*; +pub mod handler; +pub mod state_machine; diff --git a/dkg-gadget/src/async_protocols/sign/state_machine.rs b/dkg-gadget/src/async_protocols/sign/state_machine.rs new file mode 100644 index 000000000..e228e7fc1 --- /dev/null +++ b/dkg-gadget/src/async_protocols/sign/state_machine.rs @@ -0,0 +1,106 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::async_protocols::{ + blockchain_interface::BlockchainInterface, state_machine::StateMachineHandler, + AsyncProtocolParameters, BatchKey, GenericAsyncHandler, PartyIndex, ProtocolType, Threshold, +}; +use async_trait::async_trait; +use dkg_primitives::types::{DKGError, DKGMessage, DKGMsgPayload, SignedDKGMessage}; +use dkg_runtime_primitives::{crypto::Public, UnsignedProposal}; +use futures::channel::mpsc::UnboundedSender; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::sign::{ + OfflineProtocolMessage, OfflineStage, +}; +use round_based::{containers::StoreErr, Msg, StateMachine}; +use std::sync::Arc; +use tokio::sync::broadcast::Receiver; + +#[async_trait] +impl StateMachineHandler for OfflineStage { + type AdditionalReturnParam = ( + UnsignedProposal, + PartyIndex, + Receiver>>, + Threshold, + BatchKey, + ); + type Return = (); + + fn handle_unsigned_message( + to_async_proto: &UnboundedSender>, + msg: Msg>, + local_ty: &ProtocolType, + ) -> Result<(), ::Err> { + let DKGMessage { payload, .. } = msg.body; + + // Send the payload to the appropriate AsyncProtocols + match payload { + DKGMsgPayload::Offline(msg) => { + use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::sign::Error; + let message: Msg = + serde_json::from_slice(msg.offline_msg.as_slice()) + .map_err(|_err| Error::HandleMessage(StoreErr::NotForMe))?; + if let Some(recv) = message.receiver.as_ref() { + if *recv != local_ty.get_i() { + //log::info!("Skipping passing of message to async proto since not + // intended for local"); + return Ok(()) + } + } + + if local_ty.get_unsigned_proposal().unwrap().hash().unwrap() != msg.key.as_slice() { + //log::info!("Skipping passing of message to async proto since not correct + // unsigned proposal"); + return Ok(()) + } + + to_async_proto + .unbounded_send(message) + .map_err(|_| Error::HandleMessage(StoreErr::NotForMe))?; + }, + + err => log::debug!(target: "dkg", "Invalid payload received: {:?}", err), + } + + Ok(()) + } + + async fn on_finish( + offline_stage: ::Output, + params: AsyncProtocolParameters, + unsigned_proposal: Self::AdditionalReturnParam, + async_index: u8, + ) -> Result<(), DKGError> { + log::info!(target: "dkg", "Completed offline stage successfully!"); + // Take the completed offline stage and immediately execute the corresponding voting + // stage (this will allow parallelism between offline stages executing across the + // network) + // + // NOTE: we pass the generated offline stage id for the i in voting to keep + // consistency + GenericAsyncHandler::new_voting( + params, + offline_stage, + unsigned_proposal.0, + unsigned_proposal.1, + unsigned_proposal.2, + unsigned_proposal.3, + unsigned_proposal.4, + async_index, + )? + .await?; + Ok(()) + } +} diff --git a/dkg-gadget/src/async_protocols/state_machine.rs b/dkg-gadget/src/async_protocols/state_machine.rs new file mode 100644 index 000000000..853a734c5 --- /dev/null +++ b/dkg-gadget/src/async_protocols/state_machine.rs @@ -0,0 +1,56 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use async_trait::async_trait; +use dkg_primitives::types::{DKGError, DKGMessage}; +use dkg_runtime_primitives::crypto::Public; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::traits::RoundBlame; +use round_based::{Msg, StateMachine}; +use std::fmt::Debug; + +use super::{blockchain_interface::BlockchainInterface, AsyncProtocolParameters, ProtocolType}; + +pub(crate) type StateMachineTxRx = ( + futures::channel::mpsc::UnboundedSender>, + futures::channel::mpsc::UnboundedReceiver>, +); + +#[async_trait] +/// Trait for interfacing between the meta handler and the individual state machines +pub trait StateMachineHandler: StateMachine + RoundBlame + Send +where + ::Output: Send, +{ + type AdditionalReturnParam: Debug + Send; + type Return: Debug + Send; + + fn generate_channel() -> StateMachineTxRx<::MessageBody> { + futures::channel::mpsc::unbounded() + } + + fn handle_unsigned_message( + to_async_proto: &futures::channel::mpsc::UnboundedSender< + Msg<::MessageBody>, + >, + msg: Msg>, + local_ty: &ProtocolType, + ) -> Result<(), ::Err>; + + async fn on_finish( + result: ::Output, + params: AsyncProtocolParameters, + additional_param: Self::AdditionalReturnParam, + async_index: u8, + ) -> Result; +} diff --git a/dkg-gadget/src/async_protocols/state_machine_wrapper.rs b/dkg-gadget/src/async_protocols/state_machine_wrapper.rs new file mode 100644 index 000000000..2527a11e1 --- /dev/null +++ b/dkg-gadget/src/async_protocols/state_machine_wrapper.rs @@ -0,0 +1,113 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::traits::RoundBlame; +use round_based::{Msg, StateMachine}; +use std::sync::Arc; + +use super::CurrentRoundBlame; + +pub(crate) struct StateMachineWrapper { + sm: T, + current_round_blame: Arc>, +} + +impl StateMachineWrapper { + pub fn new( + sm: T, + current_round_blame: Arc>, + ) -> Self { + Self { sm, current_round_blame } + } + + fn collect_round_blame(&self) { + let (unreceived_messages, blamed_parties) = self.round_blame(); + let _ = self + .current_round_blame + .send(CurrentRoundBlame { unreceived_messages, blamed_parties }); + } +} + +impl StateMachine for StateMachineWrapper +where + T: StateMachine + RoundBlame, +{ + type Err = T::Err; + type Output = T::Output; + type MessageBody = T::MessageBody; + + fn handle_incoming(&mut self, msg: Msg) -> Result<(), Self::Err> { + let result = self.sm.handle_incoming(msg); + self.collect_round_blame(); + result + } + + fn message_queue(&mut self) -> &mut Vec> { + self.sm.message_queue() + } + + fn wants_to_proceed(&self) -> bool { + self.sm.wants_to_proceed() + } + + fn proceed(&mut self) -> Result<(), Self::Err> { + log::debug!( + "Trying to proceed: round {:?}, blame: {:?}", + self.current_round(), + self.round_blame(), + ); + let result = self.sm.proceed(); + log::debug!("Proceeded: round {:?}, blame: {:?}", self.current_round(), self.round_blame(),); + self.collect_round_blame(); + result + } + + fn round_timeout(&self) -> Option { + self.sm.round_timeout() + } + + fn round_timeout_reached(&mut self) -> Self::Err { + self.sm.round_timeout_reached() + } + + fn is_finished(&self) -> bool { + self.sm.is_finished() + } + + fn pick_output(&mut self) -> Option> { + self.sm.pick_output() + } + + fn current_round(&self) -> u16 { + self.sm.current_round() + } + + fn total_rounds(&self) -> Option { + self.sm.total_rounds() + } + + fn party_ind(&self) -> u16 { + self.sm.party_ind() + } + + fn parties(&self) -> u16 { + self.sm.parties() + } +} + +impl RoundBlame for StateMachineWrapper { + fn round_blame(&self) -> (u16, Vec) { + self.sm.round_blame() + } +} diff --git a/dkg-gadget/src/async_protocols/test_utils.rs b/dkg-gadget/src/async_protocols/test_utils.rs new file mode 100644 index 000000000..d0c09f067 --- /dev/null +++ b/dkg-gadget/src/async_protocols/test_utils.rs @@ -0,0 +1,103 @@ +use crate::{ + async_protocols::{blockchain_interface::BlockchainInterface, BatchKey}, + proposal::make_signed_proposal, +}; +use codec::Encode; +use curv::{elliptic::curves::Secp256k1, BigInt}; +use dkg_primitives::{ + types::{ + DKGError, DKGMessage, DKGPublicKeyMessage, DKGSignedPayload, RoundId, SignedDKGMessage, + }, + utils::convert_signature, +}; +use dkg_runtime_primitives::{crypto::Public, Proposal, ProposalKind, UnsignedProposal}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::{ + party_i::SignatureRecid, state_machine::keygen::LocalKey, +}; +use parking_lot::Mutex; +use std::{collections::HashMap, sync::Arc}; + +pub(crate) type VoteResults = + Arc>>>; + +#[derive(Clone)] +pub struct TestDummyIface { + pub sender: tokio::sync::mpsc::UnboundedSender>, + pub best_authorities: Arc>, + pub authority_public_key: Arc, + // key is party_index, hash of data. Needed especially for local unit tests + pub vote_results: VoteResults, + pub keygen_key: Arc>>>, +} + +impl BlockchainInterface for TestDummyIface { + type Clock = u32; + type GossipEngine = (); + + fn verify_signature_against_authorities( + &self, + message: Arc>, + ) -> Result, DKGError> { + Ok(message.msg.clone()) + } + + fn sign_and_send_msg(&self, unsigned_msg: DKGMessage) -> Result<(), DKGError> { + log::info!( + "Sending message through iface id={}", + unsigned_msg.payload.async_proto_only_get_sender_id().unwrap() + ); + let faux_signed_message = SignedDKGMessage { msg: unsigned_msg, signature: None }; + self.sender + .send(faux_signed_message) + .map_err(|err| DKGError::GenericError { reason: err.to_string() })?; + Ok(()) + } + + fn process_vote_result( + &self, + signature_rec: SignatureRecid, + unsigned_proposal: UnsignedProposal, + round_id: RoundId, + batch_key: BatchKey, + message: BigInt, + ) -> Result<(), DKGError> { + let mut lock = self.vote_results.lock(); + let _payload_key = unsigned_proposal.key; + let signature = convert_signature(&signature_rec).ok_or_else(|| { + DKGError::CriticalError { reason: "Unable to serialize signature".to_string() } + })?; + + let finished_round = DKGSignedPayload { + key: round_id.encode(), + payload: "Webb".encode(), + signature: signature.encode(), + }; + + let prop = make_signed_proposal(ProposalKind::EVM, finished_round).unwrap(); + lock.entry(batch_key).or_default().push((prop, signature_rec, message)); + + Ok(()) + } + + fn gossip_public_key(&self, _key: DKGPublicKeyMessage) -> Result<(), DKGError> { + // we do not gossip the public key in the test interface + Ok(()) + } + + fn store_public_key(&self, key: LocalKey, _: RoundId) -> Result<(), DKGError> { + *self.keygen_key.lock() = Some(key); + Ok(()) + } + + fn get_authority_set(&self) -> &Vec { + &*self.best_authorities + } + + fn get_gossip_engine(&self) -> Option<&Self::GossipEngine> { + None + } + + fn now(&self) -> Self::Clock { + 0 + } +} diff --git a/dkg-gadget/src/gossip.rs b/dkg-gadget/src/gossip.rs deleted file mode 100644 index b30f509df..000000000 --- a/dkg-gadget/src/gossip.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use codec::Encode; -use parking_lot::RwLock; -use sc_network::PeerId; -use sc_network_gossip::{ValidationResult, Validator, ValidatorContext}; -use sp_core::keccak_256; -use sp_runtime::traits::Block; -use std::collections::BTreeMap; - -use codec::Decode; -use log::{error, trace}; - -use crate::types::dkg_topic; -use dkg_primitives::types::SignedDKGMessage; -use dkg_runtime_primitives::crypto::Public; - -pub const MAX_LIVE_GOSSIP_ROUNDS: u8 = 3; - -struct Seen { - seen: BTreeMap<[u8; 32], u8>, -} - -impl Seen { - pub fn new() -> Self { - Self { seen: BTreeMap::new() } - } - - /// Create new seen entry. - fn insert(&mut self, hash: [u8; 32]) { - self.seen.entry(hash).or_insert(1); - } - - /// Increment new seen count - fn increment(&mut self, hash: [u8; 32]) { - #[allow(clippy::map_entry)] - if self.seen.contains_key(&hash) { - // Mutate if exists - let count = self.get_seen_count(&hash); - self.seen.insert(hash, count + 1); - } else { - // Insert if doesn't exist - self.insert(hash); - } - } - - /// Return true if `hash` has been seen `MAX_LIVE_GOSSIP_ROUNDS` times. - fn is_valid(&self, hash: &[u8]) -> bool { - self.get_seen_count(hash) <= MAX_LIVE_GOSSIP_ROUNDS - } - - /// Check if `hash` is already part of seen messages - fn get_seen_count(&self, hash: &[u8]) -> u8 { - self.seen.get(hash).copied().unwrap_or(0) - } -} - -/// DKG gossip validator -/// -/// Validate DKG gossip messages and limit the number of live DKG voting rounds. -/// -/// Allows messages from last [`MAX_LIVE_GOSSIP_ROUNDS`] to flow, everything else gets -/// rejected/expired. -/// -/// All messaging is handled in a single DKG global topic. -pub(crate) struct GossipValidator -where - B: Block, -{ - _phantom: std::marker::PhantomData, - seen: RwLock, -} - -impl GossipValidator -where - B: Block, -{ - pub fn new() -> GossipValidator { - GossipValidator { seen: RwLock::new(Seen::new()), _phantom: Default::default() } - } -} - -impl Validator for GossipValidator -where - B: Block, -{ - fn validate( - &self, - _context: &mut dyn ValidatorContext, - sender: &PeerId, - data: &[u8], - ) -> ValidationResult { - let mut data_copy = data; - match SignedDKGMessage::::decode(&mut data_copy) { - Ok(msg) => { - trace!(target: "dkg", "🕸️ Got a signed dkg message: {:?}, from: {:?}", msg, sender); - let hash = keccak_256(&msg.encode()); - if self.seen.read().is_valid(&hash) { - log::debug!(target: "dkg", "🕸️ Seen message: ({:?} times)", self.seen.read().get_seen_count(&hash)); - self.seen.write().increment(hash); - return ValidationResult::ProcessAndKeep(dkg_topic::()) - } else { - return ValidationResult::ProcessAndDiscard(dkg_topic::()) - } - }, - Err(e) => { - error!(target: "dkg", "🕸️ Got invalid signed dkg message: {:?}, from: {:?}", e, sender); - }, - } - - ValidationResult::Discard - } -} diff --git a/dkg-gadget/src/gossip_engine/mod.rs b/dkg-gadget/src/gossip_engine/mod.rs new file mode 100644 index 000000000..ad1976fe7 --- /dev/null +++ b/dkg-gadget/src/gossip_engine/mod.rs @@ -0,0 +1,70 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Webb Custom DKG Gossip Engine. + +use auto_impl::auto_impl; +use dkg_primitives::types::{DKGError, SignedDKGMessage}; +use dkg_runtime_primitives::crypto::AuthorityId; +use futures::{Stream, StreamExt}; +use sc_network::PeerId; +use sp_arithmetic::traits::AtLeast32BitUnsigned; +use std::pin::Pin; + +/// A Gossip Engine for DKG, that uses [`sc_network::NetworkService`] as a backend. +mod network; + +pub use network::{GossipHandler, GossipHandlerController, NetworkGossipEngineBuilder}; + +/// A GossipEngine that can be used to send DKG messages. +/// +/// in the core it is very simple, just two methods: +/// - `send` which will send a DKG message to a specific peer. +/// - `gossip` which will send a DKG message to all peers. +/// - `stream` which will return a stream of DKG messages. +#[auto_impl(Arc,Box,&)] +pub trait GossipEngineIface: Send + Sync { + type Clock: AtLeast32BitUnsigned + Send + Sync; + /// Send a DKG message to a specific peer. + fn send( + &self, + recipient: PeerId, + message: SignedDKGMessage, + ) -> Result<(), DKGError>; + /// Send a DKG message to all peers. + fn gossip(&self, message: SignedDKGMessage) -> Result<(), DKGError>; + /// Returns a stream of DKG messages, that are received from the network. + fn stream(&self) -> Pin> + Send>>; +} + +/// A Stub implementation of the GossipEngineIface. +impl GossipEngineIface for () { + type Clock = u32; + + fn send( + &self, + _recipient: PeerId, + _message: SignedDKGMessage, + ) -> Result<(), DKGError> { + Ok(()) + } + + fn gossip(&self, _message: SignedDKGMessage) -> Result<(), DKGError> { + Ok(()) + } + + fn stream(&self) -> Pin> + Send>> { + futures::stream::pending().boxed() + } +} diff --git a/dkg-gadget/src/gossip_engine/network.rs b/dkg-gadget/src/gossip_engine/network.rs new file mode 100644 index 000000000..890786c3b --- /dev/null +++ b/dkg-gadget/src/gossip_engine/network.rs @@ -0,0 +1,558 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A DKG Gossip Engine that uses [`sc_network::NetworkService`] as a backend. +//! +//! In a nutshell, it works as follows: +//! +//! 1. You create a new [`NetworkGossipEngineBuilder`] which does not require any setup for now, +//! 2. You call [`NetworkGossipEngineBuilder::build`] to get two things: +//! - a [`GossipHandler`] that is a simple background task that should run indefinitely, and +//! - a [`GossipHandlerController`] that can be used to control that background task. +//! +//! The background task ([`GossipHandler`]) role is to listen, and gossip (if enabled) all the +//! DKG messages. +//! +//! From the [`GossipHandlerController`] which implements [`super::GossipEngineIface`], you can: +//! - send a DKG message to a specific peer. +//! - send a DKG message to all peers. +//! - get a stream of DKG messages. +//! +//! +//! ### The Lifetime of the DKG Message: +//! +//! The DKG message is a [`SignedDKGMessage`] that is signed by the DKG authority, first it get +//! sent to the Gossip Engine either by calling [`GossipHandlerController::send`] or +//! [`GossipHandlerController::gossip`], depending on the call, the message will be sent to all +//! peers or only to a specific peer. on the other end, the DKG message is received by the DKG +//! engine, and it is verified then it will be added to the Engine's internal stream of DKG +//! messages, later the DKG Gadget will read this stream and process the DKG message. + +use crate::{metrics::Metrics, worker::HasLatestHeader}; +use codec::{Decode, Encode}; +use dkg_primitives::types::{DKGError, SignedDKGMessage}; +use dkg_runtime_primitives::crypto::AuthorityId; +use futures::{FutureExt, Stream, StreamExt}; +use linked_hash_map::LinkedHashMap; +use log::{debug, warn}; +use parking_lot::RwLock; +use sc_network::{config, error, multiaddr, Event, NetworkService, PeerId}; +use sp_runtime::traits::{Block, NumberFor}; +use std::{ + borrow::Cow, + collections::{hash_map::Entry, HashMap, HashSet}, + hash::Hash, + iter, + marker::PhantomData, + num::NonZeroUsize, + pin::Pin, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; +use tokio::sync::broadcast; + +#[derive(Debug, Clone, Copy)] +pub struct NetworkGossipEngineBuilder; + +impl NetworkGossipEngineBuilder { + /// Create a new network gossip engine. + pub fn new() -> Self { + Self + } + + /// Returns the configuration of the set to put in the network configuration. + pub fn set_config() -> config::NonDefaultSetConfig { + config::NonDefaultSetConfig { + notifications_protocol: crate::DKG_PROTOCOL_NAME.into(), + fallback_names: Vec::new(), + max_notification_size: MAX_MESSAGE_SIZE, + set_config: config::SetConfig { + in_peers: 0, + out_peers: 0, + reserved_nodes: Vec::new(), + non_reserved_mode: config::NonReservedPeerMode::Deny, + }, + } + } + + /// Turns the builder into the actual handler. Returns a controller that allows controlling + /// the behaviour of the handler while it's running. + /// + /// Important: the gossip mechanism is initially disabled and doesn't gossip messages. + /// You must call [`GossipHandlerController::set_gossip_enabled`] to enable it. + /// + /// The returned values are: + /// - a [`GossipHandler`] that is a simple background task that should run indefinitely, and + /// - a [`GossipHandlerController`] that can be used to control that background task. + pub(crate) fn build( + self, + service: Arc>, + metrics: Option, + latest_header: Arc>>, + ) -> error::Result<(GossipHandler, GossipHandlerController)> { + let event_stream = service.event_stream("dkg-handler").boxed(); + // Here we need to create few channels to communicate back and forth between the + // background task and the controller. + // since we have two things here we will need two channels: + // 1. a channel to send commands to the background task (Controller -> Background). + // 2. a channel to send DKG Messages back from the background task to the controller + // (Background -> Controller). + let (handler_channel, _) = broadcast::channel(MAX_PENDING_MESSAGES); + let (controller_channel, _) = broadcast::channel(MAX_PENDING_MESSAGES); + + let gossip_enabled = Arc::new(AtomicBool::new(false)); + + let handler = GossipHandler { + latest_header, + protocol_name: crate::DKG_PROTOCOL_NAME.into(), + my_channel: handler_channel.clone(), + controller_channel: controller_channel.clone(), + pending_messages_peers: HashMap::new(), + gossip_enabled: gossip_enabled.clone(), + service, + event_stream, + peers: HashMap::new(), + metrics, + }; + + let controller = GossipHandlerController { + my_channel: controller_channel, + handler_channel, + gossip_enabled, + _pd: Default::default(), + }; + + Ok((handler, controller)) + } +} + +/// Maximum number of known messages hashes to keep for a peer. +const MAX_KNOWN_MESSAGES: usize = 10240; // ~300kb per peer + overhead. + +/// Maximum allowed size for a DKG Signed Message notification. +const MAX_MESSAGE_SIZE: u64 = 16 * 1024 * 1024; + +/// Maximum number of messages request we keep at any moment. +const MAX_PENDING_MESSAGES: usize = 8192; + +/// Maximum number of duplicate messages that a single peer can send us. +/// +/// This is to prevent a malicious peer from spamming us with messages. +const MAX_DUPLICATED_MESSAGES_PER_PEER: usize = 5; + +#[allow(unused)] +mod rep { + use sc_peerset::ReputationChange as Rep; + /// Reputation change when a peer sends us a message that we didn't know about. + pub const GOOD_MESSAGE: Rep = Rep::new(1 << 7, "Good message"); + /// We received an unexpected message packet. + pub const UNEXPECTED_MESSAGE: Rep = Rep::new_fatal("Unexpected message packet"); + /// Reputation change when a peer sends us the same message over and over. + pub const DUPLICATE_MESSAGE: Rep = Rep::new(-(1 << 12), "Duplicate message"); +} + +/// Controls the behaviour of a [`GossipHandler`] it is connected to. +#[derive(Clone)] +pub struct GossipHandlerController { + /// a channel to send commands to the background task (Controller -> Background). + handler_channel: broadcast::Sender, + /// a channel to send DKG Messages back from the background task to the controller + /// + /// Technically, we do not need to hold a reference to this channel, but we do it + /// here to make this controller (**Clone-able**), meaning that we can clone it and + /// still be able to receive messages from the background task. + /// + /// Besides that, in the [`super::GossipEngineIface`] whenever we want to get the stream + /// of the DKG messages (which requires the stream is Owned value), here + /// we just create a new receiver of this channel, and since it is a broadcast channel, + /// we can receive messages from all the clones of this controller. + /// + /// See: [`GossipHandlerController::stream`] below. + my_channel: broadcast::Sender>, + /// Whether the gossip mechanism is enabled or not. + gossip_enabled: Arc, + /// Used to keep type information about the block. May + /// be useful for the future, so keeping it here + _pd: PhantomData, +} + +impl super::GossipEngineIface for GossipHandlerController { + type Clock = NumberFor; + + fn send( + &self, + recipient: PeerId, + message: SignedDKGMessage, + ) -> Result<(), DKGError> { + debug!(target: "dkg", "Sending message to {}", recipient); + self.handler_channel + .send(ToHandler::SendMessage { recipient, message }) + .map(|_| ()) + .map_err(|_| DKGError::GenericError { + reason: "Failed to send message to handler".into(), + }) + } + + fn gossip(&self, message: SignedDKGMessage) -> Result<(), DKGError> { + debug!(target: "dkg", "Sending message to all peers"); + self.handler_channel.send(ToHandler::Gossip(message)).map(|_| ()).map_err(|_| { + DKGError::GenericError { reason: "Failed to send message to handler".into() } + }) + } + + fn stream(&self) -> Pin> + Send>> { + // We need to create a new receiver of the channel, so that we can receive messages + // from anywhere, without actually fight the rustc borrow checker. + let stream = self.my_channel.subscribe(); + tokio_stream::wrappers::BroadcastStream::new(stream) + .inspect( + |msg| debug!(target: "dkg", "Streaming message from the Gossip Engine (is okay? {})", msg.is_ok()), + ) + .filter_map(|m| futures::future::ready(m.ok())) + .boxed() + } +} +/// an Enum Representing the commands that can be sent to the background task. +#[derive(Clone, Debug)] +enum ToHandler { + /// Send a DKG message to a peer. + SendMessage { recipient: PeerId, message: SignedDKGMessage }, + /// Gossip a DKG message to all peers. + Gossip(SignedDKGMessage), +} + +impl GossipHandlerController { + /// Controls whether messages are being gossiped on the network. + pub fn set_gossip_enabled(&self, enabled: bool) { + self.gossip_enabled.store(enabled, Ordering::Relaxed); + } +} + +/// Handler for gossiping messages. Call [`GossipHandler::run`] to start the processing. +/// +/// This is a background task that handles all the DKG messages. +pub struct GossipHandler { + /// The Protocol Name, should be unique. + /// + /// Used as an identifier for the gossip protocol. + protocol_name: Cow<'static, str>, + latest_header: Arc>>, + /// Pending Messages to be sent to the [`GossipHandlerController`]. + controller_channel: broadcast::Sender>, + /// As multiple peers can send us the same message, we group + /// these peers using the message hash while the message is + /// received. This prevents that we receive the same message + /// multiple times concurrently. + pending_messages_peers: HashMap>, + /// Network service to use to send messages and manage peers. + service: Arc>, + /// Stream of networking events. + event_stream: Pin + Send>>, + // All connected peers + peers: HashMap>, + /// Whether the gossip mechanism is enabled or not. + gossip_enabled: Arc, + /// A Channel to receive commands from the controller. + my_channel: broadcast::Sender, + /// Prometheus metrics. + metrics: Option, +} + +impl HasLatestHeader for GossipHandler +where + B: Block, +{ + fn get_latest_header(&self) -> &Arc>> { + &self.latest_header + } +} + +/// Peer information +#[derive(Debug)] +struct Peer { + /// Holds a set of messages known to this peer. + known_messages: LruHashSet, + /// a counter of the messages that are received from this peer. + /// + /// Implemented as a HashMap/LruHashMap with the message hash as the key, + /// This is used to track the frequency of the messages received from this peer. + /// If the same message is received from this peer more than + /// `MAX_DUPLICATED_MESSAGES_PER_PEER`, we will flag this peer as malicious. + message_counter: LruHashMap, +} + +impl GossipHandler { + /// Turns the [`GossipHandler`] into a future that should run forever and not be + /// interrupted. + pub async fn run(mut self) { + let stream = self.my_channel.subscribe(); + let mut incoming_messages = tokio_stream::wrappers::BroadcastStream::new(stream); + debug!(target: "dkg", "Starting the DKG Gossip Handler"); + loop { + futures::select! { + network_event = self.event_stream.next().fuse() => { + if let Some(network_event) = network_event { + self.handle_network_event(network_event).await; + } else { + // Networking has seemingly closed. Closing as well. + return; + } + }, + message = incoming_messages.next().fuse() => { + match message { + Some(Ok(ToHandler::SendMessage { recipient, message })) => self.send_signed_dkg_message(recipient, message), + Some(Ok(ToHandler::Gossip(v))) => self.gossip_message(v), + None => { + // The broadcast stream has been closed. + return; + }, + _ => {}, + } + }, + } + } + } + + async fn handle_network_event(&mut self, event: Event) { + match event { + Event::Dht(_) => {}, + Event::SyncConnected { remote } => { + let addr = iter::once(multiaddr::Protocol::P2p(remote.into())) + .collect::(); + let result = self + .service + .add_peers_to_reserved_set(self.protocol_name.clone(), HashSet::from([addr])); + if let Err(err) = result { + log::error!(target: "dkg-gossip", "Add reserved peer failed: {}", err); + } + }, + Event::SyncDisconnected { remote } => { + self.service.remove_peers_from_reserved_set( + self.protocol_name.clone(), + iter::once(remote).collect(), + ); + }, + + Event::NotificationStreamOpened { remote, protocol, .. } + if protocol == self.protocol_name => + { + debug!(target: "dkg", "Peer {} connected to gossip protocol", remote); + let _was_in = self.peers.insert( + remote, + Peer { + known_messages: LruHashSet::new( + NonZeroUsize::new(MAX_KNOWN_MESSAGES).expect("Constant is nonzero"), + ), + message_counter: LruHashMap::new( + NonZeroUsize::new(MAX_KNOWN_MESSAGES).expect("Constant is nonzero"), + ), + }, + ); + debug_assert!(_was_in.is_none()); + }, + Event::NotificationStreamClosed { remote, protocol } + if protocol == self.protocol_name => + { + let _peer = self.peers.remove(&remote); + debug!(target: "dkg", "Peer {} disconnected from gossip protocol", remote); + debug_assert!(_peer.is_some()); + }, + + Event::NotificationsReceived { remote, messages } => { + for (protocol, message) in messages { + if protocol != self.protocol_name { + continue + } + debug!(target: "dkg", "Received message from {} from gossiping", remote); + + if let Ok(m) = + as Decode>::decode(&mut message.as_ref()) + { + self.on_signed_dkg_message(remote, m).await; + } else { + warn!(target: "dkg", "Failed to decode signed DKG message"); + self.service.report_peer(remote, rep::UNEXPECTED_MESSAGE); + } + } + }, + Event::NotificationStreamOpened { .. } => {}, + Event::NotificationStreamClosed { .. } => {}, + } + } + + /// Called when peer sends us new signed DKG message. + async fn on_signed_dkg_message(&mut self, who: PeerId, message: SignedDKGMessage) { + // Check behavior of the peer. + let now = self.get_latest_block_number(); + debug!(target: "dkg", "Received a signed DKG messages from {} @ block {:?}, round {:?}", who, now, message.msg.round_id); + if let Some(ref mut peer) = self.peers.get_mut(&who) { + peer.known_messages.insert(message.message_hash::()); + match self.pending_messages_peers.entry(message.message_hash::()) { + Entry::Vacant(entry) => { + log::debug!(target: "dkg", "NEW DKG MESSAGE FROM {}", who); + let recv_count = self.controller_channel.receiver_count(); + if recv_count == 0 { + log::warn!(target: "dkg", "No one is going to process the message!!!"); + } + if let Err(e) = self.controller_channel.send(message.clone()) { + log::error!(target: "dkg", "Failed to send message to DKG controller: {:?}", e); + } else { + log::debug!(target: "dkg", "Message sent to {recv_count} DKG controller listeners"); + } + entry.insert(HashSet::from([who])); + // This good, this peer is good, they sent us a message we didn't know about. + // we should add some good reputation to them. + self.service.report_peer(who, rep::GOOD_MESSAGE); + }, + Entry::Occupied(mut entry) => { + log::debug!(target: "dkg", "OLD DKG MESSAGE FROM {}", who); + // if we are here, that means this peer sent us a message we already know. + let inserted = entry.get_mut().insert(who); + // and if inserted is `false` that means this peer was already in the set + // hence this not the first time we received this message from the exact same + // peer. + if !inserted { + // we will increment the counter for this message. + let old = peer + .message_counter + .get(&message.message_hash::()) + .cloned() + .unwrap_or(0); + peer.message_counter.insert(message.message_hash::(), old + 1); + // and if we have received this message from the same peer more than + // `MAX_DUPLICATED_MESSAGES_PER_PEER` times, we should report this peer + // as malicious. + if old >= MAX_DUPLICATED_MESSAGES_PER_PEER { + self.service.report_peer(who, rep::DUPLICATE_MESSAGE); + } + } + }, + } + } + + // if the gossip is enabled, we send the message to the gossiping peers + if self.gossip_enabled.load(Ordering::Relaxed) { + self.gossip_message(message); + } + } + + pub fn send_signed_dkg_message( + &mut self, + to_who: PeerId, + message: SignedDKGMessage, + ) { + let message_hash = message.message_hash::(); + if let Some(ref mut peer) = self.peers.get_mut(&to_who) { + let already_propagated = peer.known_messages.insert(message_hash); + if already_propagated { + return + } + self.service.write_notification( + to_who, + self.protocol_name.clone(), + Encode::encode(&message), + ); + debug!(target: "dkg", "Sending a signed DKG messages to {}", to_who); + } else { + debug!(target: "dkg", "Peer {} does not exist in known peers", to_who); + } + } + + fn gossip_message(&mut self, message: SignedDKGMessage) { + let mut propagated_messages = 0; + let message_hash = message.message_hash::(); + if self.peers.is_empty() { + warn!(target: "dkg", "No peers to gossip message {}", message_hash); + } + for (who, peer) in self.peers.iter_mut() { + let new_to_them = peer.known_messages.insert(message_hash); + if !new_to_them { + continue + } + self.service.write_notification( + *who, + self.protocol_name.clone(), + Encode::encode(&message), + ); + propagated_messages += 1; + } + if let Some(ref metrics) = self.metrics { + metrics.propagated_messages.inc_by(propagated_messages as _) + } + } +} + +/// Wrapper around `LinkedHashMap` with bounded growth. +/// +/// In the limit, for each element inserted the oldest existing element will be removed. +#[derive(Debug, Clone)] +pub struct LruHashMap { + inner: LinkedHashMap, + limit: NonZeroUsize, +} + +impl LruHashMap { + /// Create a new `LruHashMap` with the given (exclusive) limit. + pub fn new(limit: NonZeroUsize) -> Self { + Self { inner: LinkedHashMap::new(), limit } + } + + /// Insert element into the map. + /// + /// Returns `true` if this is a new element to the map, `false` otherwise. + /// Maintains the limit of the map by removing the oldest entry if necessary. + /// Inserting the same element will update its LRU position. + pub fn insert(&mut self, k: K, v: V) -> bool { + if self.inner.insert(k, v).is_none() { + if self.inner.len() == usize::from(self.limit) { + // remove oldest entry + self.inner.pop_front(); + } + return true + } + false + } + + /// Get an element from the map. + /// Returns `None` if the element is not in the map. + pub fn get(&self, k: &K) -> Option<&V> { + self.inner.get(k) + } +} + +/// Wrapper around `LruHashMap` with bounded growth. +/// +/// In the limit, for each element inserted the oldest existing element will be removed. +#[derive(Debug, Clone)] +pub struct LruHashSet { + set: LruHashMap, +} + +impl LruHashSet { + /// Create a new `LruHashSet` with the given (exclusive) limit. + pub fn new(limit: NonZeroUsize) -> Self { + Self { set: LruHashMap::new(limit) } + } + + /// Insert element into the set. + /// + /// Returns `true` if this is a new element to the set, `false` otherwise. + /// Maintains the limit of the set by removing the oldest entry if necessary. + /// Inserting the same element will update its LRU position. + pub fn insert(&mut self, e: T) -> bool { + self.set.insert(e, ()) + } +} diff --git a/dkg-gadget/src/gossip_messages/dkg_message.rs b/dkg-gadget/src/gossip_messages/dkg_message.rs new file mode 100644 index 000000000..256cdfd42 --- /dev/null +++ b/dkg-gadget/src/gossip_messages/dkg_message.rs @@ -0,0 +1,98 @@ +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::gossip_engine::GossipEngineIface; +use std::sync::Arc; +// Copyright 2022 Webb Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +use crate::{worker::KeystoreExt, DKGKeystore}; +use codec::Encode; +use dkg_primitives::types::{DKGMessage, SignedDKGMessage}; +use dkg_runtime_primitives::crypto::AuthorityId; +use log::trace; + +pub(crate) fn sign_and_send_messages( + gossip_engine: Arc, + dkg_keystore: &DKGKeystore, + dkg_messages: impl Into, +) where + GE: GossipEngineIface, +{ + let dkg_messages = dkg_messages.into(); + let public = dkg_keystore.get_authority_public_key(); + + for dkg_message in dkg_messages { + match dkg_keystore.sign(&public, &dkg_message.encode()) { + Ok(sig) => { + let ty = dkg_message.payload.get_type(); + let signed_dkg_message = + SignedDKGMessage { msg: dkg_message.clone(), signature: Some(sig.encode()) }; + let encoded_signed_dkg_message = signed_dkg_message.encode(); + + crate::utils::inspect_outbound(ty, encoded_signed_dkg_message.len()); + + if let Err(e) = gossip_engine.gossip(signed_dkg_message) { + log::error!(target: "dkg", "Error sending message: {:?}", e); + } + }, + Err(e) => trace!( + target: "dkg", + "🕸️ Error signing DKG message: {:?}", + e + ), + }; + + trace!(target: "dkg", "🕸️ Sent DKG Message of len {}", dkg_message.encoded_size()); + } +} + +pub(crate) enum UnsignedMessages { + Single(Option>), + Multiple(Vec>), +} + +impl From> for UnsignedMessages { + fn from(item: DKGMessage) -> Self { + UnsignedMessages::Single(Some(item)) + } +} + +impl From>> for UnsignedMessages { + fn from(messages: Vec>) -> Self { + UnsignedMessages::Multiple(messages) + } +} + +impl Iterator for UnsignedMessages { + type Item = DKGMessage; + + fn next(&mut self) -> Option { + match self { + Self::Single(msg) => msg.take(), + Self::Multiple(messages) => messages.pop(), + } + } +} diff --git a/dkg-gadget/src/messages/misbehaviour_report.rs b/dkg-gadget/src/gossip_messages/misbehaviour_report.rs similarity index 67% rename from dkg-gadget/src/messages/misbehaviour_report.rs rename to dkg-gadget/src/gossip_messages/misbehaviour_report.rs index 9fa31d848..88f91afac 100644 --- a/dkg-gadget/src/messages/misbehaviour_report.rs +++ b/dkg-gadget/src/gossip_messages/misbehaviour_report.rs @@ -13,8 +13,10 @@ // limitations under the License. // use crate::{ - storage::misbehaviour_reports::store_aggregated_misbehaviour_reports, types::dkg_topic, - worker::DKGWorker, Client, + gossip_engine::GossipEngineIface, + storage::misbehaviour_reports::store_aggregated_misbehaviour_reports, + worker::{DKGWorker, KeystoreExt}, + Client, }; use codec::Encode; use dkg_primitives::types::{ @@ -25,20 +27,21 @@ use dkg_runtime_primitives::{ }; use log::{debug, error}; use sc_client_api::Backend; -use sp_runtime::traits::{Block, Header}; +use sp_runtime::traits::{Block, NumberFor}; -pub(crate) fn handle_misbehaviour_report( - dkg_worker: &mut DKGWorker, +pub(crate) fn handle_misbehaviour_report( + dkg_worker: &mut DKGWorker, dkg_msg: DKGMessage, ) -> Result<(), DKGError> where B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, + BE: Backend + 'static, + GE: GossipEngineIface + 'static, + C: Client + 'static, + C::Api: DKGApi>, { // Get authority accounts - let header = dkg_worker.latest_header.as_ref().ok_or(DKGError::NoHeader)?; + let header = &(dkg_worker.latest_header.read().clone().ok_or(DKGError::NoHeader)?); let authorities = dkg_worker.validator_set(header).map(|a| (a.0.authorities, a.1.authorities)); if authorities.is_none() { return Err(DKGError::NoAuthorityAccounts) @@ -49,11 +52,12 @@ where let is_main_round = { if dkg_worker.rounds.is_some() { - msg.round_id == dkg_worker.rounds.as_ref().unwrap().get_id() + msg.round_id == dkg_worker.rounds.as_ref().unwrap().round_id } else { false } }; + debug!(target: "dkg", "Is main round: {}", is_main_round); // Create packed message let mut signed_payload = Vec::new(); signed_payload.extend_from_slice(&match msg.misbehaviour_type { @@ -69,45 +73,41 @@ where &signed_payload, &msg.signature, )?; + debug!(target: "dkg", "Reporter: {:?}", reporter); // Add new report to the aggregated reports - let mut reports = match dkg_worker.aggregated_misbehaviour_reports.get(&( - msg.misbehaviour_type, - msg.round_id, - msg.offender.clone(), - )) { - Some(r) => r.clone(), - None => AggregatedMisbehaviourReports { + let reports = dkg_worker + .aggregated_misbehaviour_reports + .entry((msg.misbehaviour_type, msg.round_id, msg.offender.clone())) + .or_insert_with(|| AggregatedMisbehaviourReports { misbehaviour_type: msg.misbehaviour_type, round_id: msg.round_id, offender: msg.offender.clone(), reporters: Vec::new(), signatures: Vec::new(), - }, - }; - + }); + debug!(target: "dkg", "Reports: {:?}", reports); if !reports.reporters.contains(&reporter) { reports.reporters.push(reporter); reports.signatures.push(msg.signature); - dkg_worker - .aggregated_misbehaviour_reports - .insert((msg.misbehaviour_type, msg.round_id, msg.offender), reports.clone()); } // Try to store reports offchain - try_store_offchain(dkg_worker, reports)?; + let reports = reports.clone(); + try_store_offchain(dkg_worker, &reports)?; } Ok(()) } -pub(crate) fn gossip_misbehaviour_report( - dkg_worker: &mut DKGWorker, +pub(crate) fn gossip_misbehaviour_report( + dkg_worker: &mut DKGWorker, report: DKGMisbehaviourMessage, ) where B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, + BE: Backend + 'static, + GE: GossipEngineIface + 'static, + C: Client + 'static, + C::Api: DKGApi>, { let public = dkg_worker.get_authority_public_key(); @@ -138,11 +138,9 @@ pub(crate) fn gossip_misbehaviour_report( let encoded_signed_dkg_message = signed_dkg_message.encode(); log::debug!(target: "dkg", "💀 (Round: {:?}) Sending Misbehaviour message: ({:?} bytes)", report.round_id, encoded_signed_dkg_message.len()); - dkg_worker.gossip_engine.lock().gossip_message( - dkg_topic::(), - encoded_signed_dkg_message, - true, - ); + if let Err(e) = dkg_worker.gossip_engine.gossip(signed_dkg_message) { + log::error!(target: "dkg", "💀 (Round: {:?}) Failed to gossip misbehaviour message: {:?}", report.round_id, e); + } }, Err(e) => error!( target: "dkg", @@ -151,20 +149,16 @@ pub(crate) fn gossip_misbehaviour_report( ), } - let mut reports = match dkg_worker.aggregated_misbehaviour_reports.get(&( - report.misbehaviour_type, - report.round_id, - report.offender.clone(), - )) { - Some(reports) => reports.clone(), - None => AggregatedMisbehaviourReports { + let reports = dkg_worker + .aggregated_misbehaviour_reports + .entry((report.misbehaviour_type, report.round_id, report.offender.clone())) + .or_insert_with(|| AggregatedMisbehaviourReports { misbehaviour_type: report.misbehaviour_type, round_id: report.round_id, offender: report.offender.clone(), reporters: Vec::new(), signatures: Vec::new(), - }, - }; + }); if reports.reporters.contains(&public) { return @@ -173,41 +167,41 @@ pub(crate) fn gossip_misbehaviour_report( reports.reporters.push(public); reports.signatures.push(encoded_signature); - dkg_worker - .aggregated_misbehaviour_reports - .insert((report.misbehaviour_type, report.round_id, report.offender), reports.clone()); debug!(target: "dkg", "Gossiping misbehaviour report and signature"); // Try to store reports offchain - let _ = try_store_offchain(dkg_worker, reports); + let reports = reports.clone(); + let _ = try_store_offchain(dkg_worker, &reports); } else { error!(target: "dkg", "Could not sign public key"); } } -pub(crate) fn try_store_offchain( - dkg_worker: &mut DKGWorker, - reports: AggregatedMisbehaviourReports, +pub(crate) fn try_store_offchain( + dkg_worker: &mut DKGWorker, + reports: &AggregatedMisbehaviourReports, ) -> Result<(), DKGError> where B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, + BE: Backend + 'static, + GE: GossipEngineIface + 'static, + C: Client + 'static, + C::Api: DKGApi>, { - let header = dkg_worker.latest_header.as_ref().ok_or(DKGError::NoHeader)?; + let header = &(dkg_worker.latest_header.read().clone().ok_or(DKGError::NoHeader)?); // 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. let threshold = dkg_worker.get_signature_threshold(header) as usize; - match reports.misbehaviour_type { + debug!(target: "dkg", "DKG threshold: {}, reports: {}", threshold, reports.reporters.len()); + match &reports.misbehaviour_type { MisbehaviourType::Keygen => if reports.reporters.len() > threshold { - store_aggregated_misbehaviour_reports(dkg_worker, &reports)?; + store_aggregated_misbehaviour_reports(dkg_worker, reports)?; }, MisbehaviourType::Sign => if reports.reporters.len() >= threshold { - store_aggregated_misbehaviour_reports(dkg_worker, &reports)?; + store_aggregated_misbehaviour_reports(dkg_worker, reports)?; }, }; diff --git a/dkg-gadget/src/messages/mod.rs b/dkg-gadget/src/gossip_messages/mod.rs similarity index 100% rename from dkg-gadget/src/messages/mod.rs rename to dkg-gadget/src/gossip_messages/mod.rs diff --git a/dkg-gadget/src/messages/public_key_gossip.rs b/dkg-gadget/src/gossip_messages/public_key_gossip.rs similarity index 59% rename from dkg-gadget/src/messages/public_key_gossip.rs rename to dkg-gadget/src/gossip_messages/public_key_gossip.rs index b65968a54..51aefda2c 100644 --- a/dkg-gadget/src/messages/public_key_gossip.rs +++ b/dkg-gadget/src/gossip_messages/public_key_gossip.rs @@ -1,3 +1,4 @@ +use crate::gossip_engine::GossipEngineIface; // Copyright 2022 Webb Technologies Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,36 +15,40 @@ // // Handles non-dkg messages use crate::{ - storage::public_keys::store_aggregated_public_keys, types::dkg_topic, worker::DKGWorker, Client, + storage::public_keys::store_aggregated_public_keys, + worker::{DKGWorker, KeystoreExt}, + Client, DKGKeystore, }; use codec::Encode; -use dkg_primitives::{ - crypto::Public, - types::{DKGError, DKGMessage, DKGMsgPayload, DKGPublicKeyMessage, SignedDKGMessage}, +use dkg_primitives::types::{ + DKGError, DKGMessage, DKGMsgPayload, DKGPublicKeyMessage, RoundId, SignedDKGMessage, +}; +use dkg_runtime_primitives::{ + crypto::{AuthorityId, Public}, + AggregatedPublicKeys, DKGApi, }; -use dkg_runtime_primitives::{crypto::AuthorityId, AggregatedPublicKeys, DKGApi}; use log::{debug, error}; use sc_client_api::Backend; -use sp_runtime::traits::{Block, Header}; +use sp_runtime::traits::{Block, Header, NumberFor}; +use std::{collections::HashMap, sync::Arc}; -pub(crate) fn handle_public_key_broadcast( - dkg_worker: &mut DKGWorker, +pub(crate) fn handle_public_key_broadcast( + dkg_worker: &mut DKGWorker, dkg_msg: DKGMessage, ) -> Result<(), DKGError> where B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, + BE: Backend + 'static, + GE: GossipEngineIface + 'static, + C: Client + 'static, + C::Api: DKGApi>, { - if !dkg_worker.dkg_state.listening_for_pub_key && - !dkg_worker.dkg_state.listening_for_active_pub_key - { + if dkg_worker.rounds.is_none() { return Ok(()) } // Get authority accounts - let header = dkg_worker.latest_header.as_ref().ok_or(DKGError::NoHeader)?; + let header = &dkg_worker.latest_header.read().clone().ok_or(DKGError::NoHeader)?; let current_block_number = *header.number(); let authorities = dkg_worker.validator_set(header).map(|a| (a.0.authorities, a.1.authorities)); if authorities.is_none() { @@ -55,7 +60,7 @@ where let is_main_round = { if dkg_worker.rounds.is_some() { - msg.round_id == dkg_worker.rounds.as_ref().unwrap().get_id() + msg.round_id == dkg_worker.rounds.as_ref().unwrap().round_id } else { false } @@ -70,16 +75,11 @@ where let key_and_sig = (msg.pub_key, msg.signature); let round_id = msg.round_id; - let mut aggregated_public_keys = match dkg_worker.aggregated_public_keys.get(&round_id) { - Some(keys) => keys.clone(), - None => AggregatedPublicKeys::default(), - }; + let mut lock = dkg_worker.aggregated_public_keys.lock(); + let aggregated_public_keys = lock.entry(round_id).or_default(); if !aggregated_public_keys.keys_and_signatures.contains(&key_and_sig) { aggregated_public_keys.keys_and_signatures.push(key_and_sig); - dkg_worker - .aggregated_public_keys - .insert(round_id, aggregated_public_keys.clone()); } // Fetch the current threshold for the DKG. We will use the // current threshold to determine if we have enough signatures @@ -92,11 +92,11 @@ where aggregated_public_keys.keys_and_signatures.len() ); if aggregated_public_keys.keys_and_signatures.len() > threshold { - store_aggregated_public_keys( - dkg_worker, + store_aggregated_public_keys::( + &dkg_worker.backend, + &mut *lock, is_main_round, round_id, - &aggregated_public_keys, current_block_number, )?; } @@ -105,17 +105,21 @@ where Ok(()) } -pub(crate) fn gossip_public_key( - dkg_worker: &mut DKGWorker, +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, C::Api: DKGApi::Header as Header>::Number>, { - let public = dkg_worker.get_authority_public_key(); - if let Ok(signature) = dkg_worker.key_store.sign(&public, &msg.pub_key) { + let public = key_store.get_authority_public_key(); + + if let Ok(signature) = key_store.sign(&public, &msg.pub_key) { let encoded_signature = signature.encode(); let payload = DKGMsgPayload::PublicKeyBroadcast(DKGPublicKeyMessage { signature: encoded_signature.clone(), @@ -126,18 +130,15 @@ pub(crate) fn gossip_public_key( DKGMessage:: { id: public.clone(), round_id: msg.round_id, payload }; let encoded_dkg_message = message.encode(); - match dkg_worker.key_store.sign(&public, &encoded_dkg_message) { + crate::utils::inspect_outbound("pub_key", encoded_dkg_message.len()); + + match key_store.sign(&public, &encoded_dkg_message) { Ok(sig) => { let signed_dkg_message = SignedDKGMessage { msg: message, signature: Some(sig.encode()) }; - let encoded_signed_dkg_message = signed_dkg_message.encode(); - - log::debug!(target: "dkg", "🔑 (Round: {:?}) Sending Public key gossip message: ({:?} bytes)", msg.round_id, encoded_signed_dkg_message.len()); - dkg_worker.gossip_engine.lock().gossip_message( - dkg_topic::(), - encoded_signed_dkg_message, - true, - ); + if let Err(e) = gossip_engine.gossip(signed_dkg_message) { + error!(target: "dkg", "Failed to gossip DKG public key: {:?}", e); + } }, Err(e) => error!( target: "dkg", @@ -146,20 +147,13 @@ pub(crate) fn gossip_public_key( ), } - let mut aggregated_public_keys = - if dkg_worker.aggregated_public_keys.get(&msg.round_id).is_some() { - dkg_worker.aggregated_public_keys.get(&msg.round_id).unwrap().clone() - } else { - AggregatedPublicKeys::default() - }; - aggregated_public_keys + .entry(msg.round_id) + .or_default() .keys_and_signatures .push((msg.pub_key.clone(), encoded_signature)); - dkg_worker.aggregated_public_keys.insert(msg.round_id, aggregated_public_keys); - - debug!(target: "dkg", "Gossiping local node {:?} public key and signature", public) + debug!(target: "dkg", "Gossiping local node {} public key and signature", public) } else { error!(target: "dkg", "Could not sign public key"); } diff --git a/dkg-gadget/src/keyring.rs b/dkg-gadget/src/keyring.rs index 400a74926..e1fe7d2ff 100644 --- a/dkg-gadget/src/keyring.rs +++ b/dkg-gadget/src/keyring.rs @@ -20,7 +20,7 @@ use dkg_runtime_primitives::crypto; /// Set of test accounts using [`dkg_primitives::crypto`] types. #[allow(missing_docs)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::Display, strum::EnumIter)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::EnumIter)] pub enum Keyring { Alice, Bob, @@ -30,6 +30,7 @@ pub enum Keyring { Ferdie, One, Two, + Custom(u128), } impl Keyring { @@ -53,7 +54,7 @@ impl Keyring { /// Return seed string. pub fn to_seed(self) -> String { - format!("//{}", self) + format!("//{:?}", self) } /// Iterator over all test accounts diff --git a/dkg-gadget/src/keystore.rs b/dkg-gadget/src/keystore.rs index d0dc3a584..cdf4f8b25 100644 --- a/dkg-gadget/src/keystore.rs +++ b/dkg-gadget/src/keystore.rs @@ -112,7 +112,7 @@ impl DKGKeystore { let pk: Vec = SyncCryptoStore::ecdsa_public_keys(&*store, KEY_TYPE) .iter() - .map(|k| Public::from(k.clone())) + .map(|k| Public::from(*k)) .collect(); Ok(pk) @@ -123,8 +123,7 @@ impl DKGKeystore { pub fn sr25519_public_keys(&self) -> Result, error::Error> { let store = self.0.clone().ok_or_else(|| error::Error::Keystore("no Keystore".into()))?; - let pk: Vec = - SyncCryptoStore::sr25519_public_keys(&*store, ACCOUNT).iter().copied().collect(); + let pk: Vec = SyncCryptoStore::sr25519_public_keys(&*store, ACCOUNT); Ok(pk) } @@ -322,7 +321,7 @@ mod tests { let keys = store.public_keys().ok().unwrap(); - assert!(keys.len() == 4); + assert_eq!(keys.len(), 4); assert!(keys.contains(&Keyring::Dave.public())); assert!(keys.contains(&Keyring::Eve.public())); assert!(keys.contains(&key1)); diff --git a/dkg-gadget/src/lib.rs b/dkg-gadget/src/lib.rs index 4c063a961..bedfbb8ad 100644 --- a/dkg-gadget/src/lib.rs +++ b/dkg-gadget/src/lib.rs @@ -12,36 +12,42 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::HashMap, path::PathBuf, sync::Arc}; +extern crate core; + +use std::{marker::PhantomData, path::PathBuf, sync::Arc}; -use dkg_primitives::rounds::DKGState; use log::debug; +use parking_lot::RwLock; use prometheus::Registry; use sc_client_api::{Backend, BlockchainEvents, Finalizer}; -use sc_network_gossip::{GossipEngine, Network as GossipNetwork}; -use sp_api::ProvideRuntimeApi; +use sc_network::{ExHashT, NetworkService}; +use sp_api::{NumberFor, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; -use sp_runtime::traits::{Block, Header}; +use sp_runtime::traits::Block; use dkg_runtime_primitives::{crypto::AuthorityId, DKGApi}; use sc_keystore::LocalKeystore; use sp_keystore::SyncCryptoStorePtr; mod error; -mod gossip; mod keyring; mod keystore; -pub mod messages; + +mod gossip_engine; +// mod meta_async_rounds; mod metrics; mod persistence; mod proposal; -pub mod storage; -mod types; mod utils; mod worker; +pub mod async_protocols; +pub mod gossip_messages; +pub mod storage; + +use gossip_engine::NetworkGossipEngineBuilder; pub use keystore::DKGKeystore; pub const DKG_PROTOCOL_NAME: &str = "/webb-tools/dkg/1"; @@ -49,10 +55,7 @@ pub const DKG_PROTOCOL_NAME: &str = "/webb-tools/dkg/1"; /// Returns the configuration value to put in /// [`sc_network::config::NetworkConfiguration::extra_sets`]. pub fn dkg_peers_set_config() -> sc_network::config::NonDefaultSetConfig { - let mut cfg = - sc_network::config::NonDefaultSetConfig::new(DKG_PROTOCOL_NAME.into(), 1024 * 1024); - cfg.allow_non_reserved(25, 25); - cfg + NetworkGossipEngineBuilder::set_config() } /// A convenience DKG client trait that defines all the type bounds a DKG client @@ -65,7 +68,6 @@ where B: Block, BE: Backend, { - // empty } impl Client for T @@ -83,13 +85,13 @@ where } /// DKG gadget initialization parameters. -pub struct DKGParams +pub struct DKGParams where B: Block, + ::Hash: ExHashT, BE: Backend, C: Client, - C::Api: DKGApi::Header as Header>::Number>, - N: GossipNetwork + Clone + Send + 'static, + C::Api: DKGApi>, { /// DKG client pub client: Arc, @@ -100,26 +102,25 @@ where /// Concrete local key store pub local_keystore: Option>, /// Gossip network - pub network: N, + pub network: Arc>, /// Prometheus metric registry pub prometheus_registry: Option, /// Path to the persistent keystore directory for DKG data pub base_path: Option, /// Phantom block type - pub _block: std::marker::PhantomData, + pub _block: PhantomData, } /// Start the DKG gadget. /// /// This is a thin shim around running and awaiting a DKG worker. -pub async fn start_dkg_gadget(dkg_params: DKGParams) +pub async fn start_dkg_gadget(dkg_params: DKGParams) where B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, - N: GossipNetwork + Clone + Send + 'static, + BE: Backend + 'static, + C: Client + 'static, + C::Api: DKGApi>, { let DKGParams { client, @@ -132,9 +133,7 @@ where _block, } = dkg_params; - let gossip_validator = Arc::new(gossip::GossipValidator::new()); - let gossip_engine = - GossipEngine::new(network, DKG_PROTOCOL_NAME, gossip_validator.clone(), None); + let network_gossip_engine = NetworkGossipEngineBuilder::new(); let metrics = prometheus_registry.as_ref().map(metrics::Metrics::register).and_then( @@ -150,7 +149,15 @@ where }, ); + let latest_header = Arc::new(RwLock::new(None)); + let (gossip_handler, gossip_engine) = network_gossip_engine + .build(network.clone(), metrics.clone(), latest_header.clone()) + .expect("Failed to build gossip engine"); + // enable the gossip + gossip_engine.set_gossip_enabled(true); + let handle = tokio::spawn(gossip_handler.run()); let worker_params = worker::WorkerParams { + latest_header, client, backend, key_store: key_store.into(), @@ -158,15 +165,11 @@ where metrics, base_path, local_keystore, - dkg_state: DKGState { - accepted: false, - listening_for_pub_key: false, - listening_for_active_pub_key: false, - created_offlinestage_at: HashMap::new(), - }, + _marker: PhantomData::default(), }; - let worker = worker::DKGWorker::<_, _, _>::new(worker_params); + let worker = worker::DKGWorker::<_, _, _, _>::new(worker_params); - worker.run().await + worker.run().await; + handle.abort(); } diff --git a/dkg-gadget/src/messages/dkg_message.rs b/dkg-gadget/src/messages/dkg_message.rs deleted file mode 100644 index 124ace33b..000000000 --- a/dkg-gadget/src/messages/dkg_message.rs +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use crate::{ - messages::public_key_gossip::gossip_public_key, persistence::store_localkey, types::dkg_topic, - worker::DKGWorker, Client, -}; -use codec::Encode; -use dkg_primitives::{ - crypto::Public, - rounds::MultiPartyECDSARounds, - types::{ - DKGError, DKGMessage, DKGMsgPayload, DKGPublicKeyMessage, DKGResult, SignedDKGMessage, - }, - GOSSIP_MESSAGE_RESENDING_LIMIT, -}; -use dkg_runtime_primitives::{crypto::AuthorityId, DKGApi}; -use log::{error, info, trace}; -use sc_client_api::Backend; -use sp_runtime::traits::{Block, Header, NumberFor}; - -/// Sends outgoing dkg messages -pub(crate) fn send_outgoing_dkg_messages(mut dkg_worker: &mut DKGWorker) -where - B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, -{ - let mut keys_to_gossip = Vec::new(); - let mut rounds_send_result = vec![]; - let mut next_rounds_send_result = vec![]; - - if let Some(mut rounds) = dkg_worker.rounds.take() { - if let Some(id) = - dkg_worker.key_store.authority_id(&dkg_worker.current_validator_set.authorities) - { - rounds_send_result = - send_messages(dkg_worker, &mut rounds, id, dkg_worker.get_latest_block_number()); - } else { - error!("No local accounts available. Consider adding one via `author_insertKey` RPC."); - } - - if dkg_worker.active_keygen_in_progress { - let is_keygen_finished = rounds.is_keygen_finished(); - if is_keygen_finished { - dkg_worker.active_keygen_in_progress = false; - let pub_key = rounds.get_public_key().unwrap().to_bytes(true).to_vec(); - info!(target: "dkg", "🕸️ Genesis DKGs keygen has completed: {:?}", pub_key); - let round_id = rounds.get_id(); - keys_to_gossip.push((round_id, pub_key)); - } - } - - dkg_worker.rounds = Some(rounds); - } - - // Check if a there's a key gen process running for the queued authority set - if dkg_worker.queued_keygen_in_progress { - if let Some(id) = dkg_worker - .key_store - .authority_id(dkg_worker.queued_validator_set.authorities.as_slice()) - { - if let Some(mut next_rounds) = dkg_worker.next_rounds.take() { - next_rounds_send_result = send_messages( - dkg_worker, - &mut next_rounds, - id, - dkg_worker.get_latest_block_number(), - ); - - let is_keygen_finished = next_rounds.is_keygen_finished(); - if is_keygen_finished { - dkg_worker.queued_keygen_in_progress = false; - let pub_key = next_rounds.get_public_key().unwrap().to_bytes(true).to_vec(); - info!(target: "dkg", "🕸️ Queued DKGs keygen has completed: {:?}", pub_key); - keys_to_gossip.push((next_rounds.get_id(), pub_key)); - } - dkg_worker.next_rounds = Some(next_rounds); - } - } else { - error!("No local accounts available. Consider adding one via `author_insertKey` RPC."); - } - } - - for (round_id, pub_key) in &keys_to_gossip { - let pub_key_msg = DKGPublicKeyMessage { - round_id: *round_id, - pub_key: pub_key.clone(), - signature: vec![], - }; - let hash = sp_core::blake2_128(&pub_key_msg.encode()); - let count = *dkg_worker.has_sent_gossip_msg.get(&hash).unwrap_or(&0u8); - if count > GOSSIP_MESSAGE_RESENDING_LIMIT { - return - } - gossip_public_key(dkg_worker, pub_key_msg); - dkg_worker.has_sent_gossip_msg.insert(hash, count + 1); - } - - for res in &rounds_send_result { - if let Err(err) = res { - dkg_worker.handle_dkg_error(err.clone()); - } - } - - for res in &next_rounds_send_result { - if let Err(err) = res { - dkg_worker.handle_dkg_error(err.clone()); - } - } -} - -/// send actual messages -fn send_messages( - dkg_worker: &mut DKGWorker, - rounds: &mut MultiPartyECDSARounds>, - authority_id: Public, - at: NumberFor, -) -> Vec> -where - B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, -{ - let results = rounds.proceed(at); - - for result in &results { - if let Ok(DKGResult::KeygenFinished { round_id, local_key }) = result.clone() { - let _ = store_localkey(*local_key, round_id, rounds.get_local_key_path(), dkg_worker); - } - } - - for message in rounds.get_outgoing_messages() { - let dkg_message = - DKGMessage { id: authority_id.clone(), payload: message, round_id: rounds.get_id() }; - - sign_and_send_message(dkg_worker, &dkg_message); - } - results -} - -fn sign_and_send_message( - dkg_worker: &mut DKGWorker, - dkg_message: &DKGMessage, -) where - B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, -{ - let public = dkg_worker.get_authority_public_key(); - match dkg_worker.key_store.sign(&public, &dkg_message.encode()) { - Ok(sig) => { - let signed_dkg_message = - SignedDKGMessage { msg: dkg_message.clone(), signature: Some(sig.encode()) }; - let encoded_signed_dkg_message = signed_dkg_message.encode(); - - match dkg_message.payload { - DKGMsgPayload::Keygen(_) => { - log::debug!( - target: "dkg", - "📤 (Round: {:?}) Sending signed DKG keygen message: ({:?} bytes)", - dkg_message.round_id, encoded_signed_dkg_message.len() - ); - }, - DKGMsgPayload::Offline(_) => { - log::debug!( - target: "dkg", - "📤 (Round: {:?}) Sending signed DKG offline message: ({:?} bytes)", - dkg_message.round_id, encoded_signed_dkg_message.len() - ); - }, - DKGMsgPayload::Vote(_) => { - log::debug!( - target: "dkg", - "📤 (Round: {:?}) Sending signed DKG vote message: ({:?} bytes)", - dkg_message.round_id, encoded_signed_dkg_message.len() - ); - }, - _ => {}, - }; - - dkg_worker.gossip_engine.lock().gossip_message( - dkg_topic::(), - encoded_signed_dkg_message, - true, - ); - }, - Err(e) => trace!( - target: "dkg", - "🕸️ Error signing DKG message: {:?}", - e - ), - }; -} diff --git a/dkg-gadget/src/metrics.rs b/dkg-gadget/src/metrics.rs index 4ea90a653..440282948 100644 --- a/dkg-gadget/src/metrics.rs +++ b/dkg-gadget/src/metrics.rs @@ -13,16 +13,14 @@ // limitations under the License. //! DKG Prometheus metrics definition -use prometheus::{register, Gauge, PrometheusError, Registry, U64}; +use prometheus::{register, Counter, Gauge, PrometheusError, Registry, U64}; /// DKG metrics exposed through Prometheus +#[derive(Clone)] pub(crate) struct Metrics { + pub propagated_messages: Counter, /// Current active validator set id pub dkg_validator_set_id: Gauge, - /// Total number of votes sent by this node - pub dkg_votes_sent: Gauge, - /// Most recent concluded voting round - pub dkg_round_concluded: Gauge, } impl Metrics { @@ -32,12 +30,8 @@ impl Metrics { Gauge::new("dkg_validator_set_id", "Current DKG active validator set id.")?, registry, )?, - dkg_votes_sent: register( - Gauge::new("dkg_votes_sent", "Number of votes sent by this node")?, - registry, - )?, - dkg_round_concluded: register( - Gauge::new("dkg_round_concluded", "Voting round, that has been concluded")?, + propagated_messages: register( + Counter::new("dkg_propagated_messages", "Number of DKG messages propagated.")?, registry, )?, }) diff --git a/dkg-gadget/src/persistence.rs b/dkg-gadget/src/persistence.rs index fa94d2f38..08d552382 100644 --- a/dkg-gadget/src/persistence.rs +++ b/dkg-gadget/src/persistence.rs @@ -11,59 +11,37 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -use crate::{worker::DKGWorker, Client}; + use curv::elliptic::curves::Secp256k1; use dkg_primitives::{ - crypto::AuthorityId, - rounds::{LocalKey, MultiPartyECDSARounds}, serde_json, types::RoundId, - utils::{ - decrypt_data, encrypt_data, StoredLocalKey, DKG_LOCAL_KEY_FILE, QUEUED_DKG_LOCAL_KEY_FILE, - }, -}; -use dkg_runtime_primitives::{ - offchain::crypto::{Pair as AppPair, Public}, - DKGApi, + utils::{decrypt_data, encrypt_data, StoredLocalKey}, }; +use dkg_runtime_primitives::offchain::crypto::{Pair as AppPair, Public}; use log::debug; -use sc_client_api::Backend; -use sp_api::{BlockT as Block, HeaderT as Header}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::keygen::LocalKey; +use sc_keystore::LocalKeystore; use sp_core::Pair; use std::{ fs, io::{Error, ErrorKind}, path::PathBuf, + sync::Arc, }; -pub struct DKGPersistenceState { - pub initial_check: bool, -} - -impl DKGPersistenceState { - pub fn new() -> Self { - Self { initial_check: false } - } -} - -pub(crate) fn store_localkey( +pub(crate) fn store_localkey( key: LocalKey, round_id: RoundId, path: Option, - worker: &mut DKGWorker, -) -> std::io::Result<()> -where - B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, -{ + local_keystore: Option<&Arc>, + sr25519_public_key: sp_core::sr25519::Public, +) -> std::io::Result<()> { if let Some(path) = path { - if let Some(local_keystore) = worker.local_keystore.clone() { + if let Some(local_keystore) = local_keystore { debug!(target: "dkg_persistence", "Storing local key for {:?}", &path); - let key_pair = local_keystore.as_ref().key_pair::( - &Public::try_from(&worker.get_sr25519_public_key().0[..]) + let key_pair = local_keystore.key_pair::( + &Public::try_from(&sr25519_public_key.0[..]) .unwrap_or_else(|_| panic!("Could not find keypair in local key store")), ); if let Ok(Some(key_pair)) = key_pair { @@ -99,20 +77,15 @@ where /// /// Uses the raw keypair as a seed for a secret key input to the XChaCha20Poly1305 /// encryption cipher. -pub(crate) fn load_stored_key( +#[allow(dead_code)] +pub(crate) fn load_stored_key( path: PathBuf, - worker: &mut DKGWorker, -) -> std::io::Result -where - B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, -{ - if let Some(local_keystore) = worker.local_keystore.clone() { - debug!(target: "dkg_persistence", "Loading local key for {:?}", &path); + local_keystore: Option<&Arc>, + sr25519_public_key: sp_core::sr25519::Public, +) -> std::io::Result { + if let Some(local_keystore) = local_keystore { let key_pair = local_keystore.as_ref().key_pair::( - &Public::try_from(&worker.get_sr25519_public_key().0[..]) + &Public::try_from(&sr25519_public_key.0[..]) .unwrap_or_else(|_| panic!("Could not find keypair in local key store")), ); @@ -135,155 +108,3 @@ where Err(Error::new(ErrorKind::Other, "Local keystore doesn't exist".to_string())) } } - -/// We only try to resume the dkg once, if we can find any data for the completed offline stage for -/// the current round -pub(crate) fn try_resume_dkg(worker: &mut DKGWorker, header: &B::Header) -where - B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, -{ - // We only try to resume the dkg once even if there is no data to recover - if worker.dkg_persistence.initial_check { - return - } - // Set initial check to prevent re-running resuming the dkg - worker.dkg_persistence.initial_check = true; - - // If the rounds are already set, we return - if worker.rounds.is_some() || worker.next_rounds.is_some() { - return - } - - // If there is no base path or local keystore then there is no DKG to resume. - // We return in this case. - if worker.local_keystore.is_none() || worker.base_path.is_none() { - return - } - - debug!(target: "dkg_persistence", "Trying to restore key gen data"); - if let Some((active, queued)) = worker.validator_set(header) { - worker.current_validator_set = active.clone(); - worker.queued_validator_set = queued.clone(); - // Set local key paths - let base_path = worker.base_path.as_ref().unwrap(); - let local_key_path = base_path.join(DKG_LOCAL_KEY_FILE); - let queued_local_key_path = base_path.join(QUEUED_DKG_LOCAL_KEY_FILE); - // Set round IDs - let round_id = active.id; - let queued_round_id = queued.id; - // Get the stored keys and check whether their rounds match any of the authority set IDs - let mut local_key = load_stored_key(local_key_path.clone(), worker).ok(); - let mut queued_local_key = load_stored_key(queued_local_key_path.clone(), worker).ok(); - // Check if active key is outdated - if let Some(active_key) = local_key.clone() { - if active_key.round_id < round_id { - local_key = None; - } - } - // Swap the queued local key with the active local key if it matches active round ID - if let Some(queued_key) = queued_local_key.clone() { - if queued_key.round_id == round_id { - local_key = queued_local_key; - queued_local_key = None; - } - if queued_key.round_id < round_id { - local_key = None; - queued_local_key = None; - } - } - // Get the best active authorities for setting up rounds - let maybe_party_index = worker.get_party_index(header); - // Create the active rounds only if the authority is selected in the best set - if let Some(party_index) = maybe_party_index { - let best_authorities: Vec = - worker.get_best_authorities(header).iter().map(|x| x.1.clone()).collect(); - let jailed_signers = worker.get_signing_jailed(header, &best_authorities); - let mut rounds = MultiPartyECDSARounds::builder() - .round_id(round_id) - .party_index(party_index) - .threshold(worker.get_signature_threshold(header)) - .parties(worker.get_keygen_threshold(header)) - .local_key_path(Some(local_key_path)) - .authorities(best_authorities.clone()) - .jailed_signers(worker.get_signing_jailed(header, &best_authorities)) - .build(); - - if let Some(key) = local_key { - debug!(target: "dkg_persistence", "Local key set"); - // Set the local key - rounds.set_local_key(key.local_key); - // Once local key is set, we can set the jailed signers which also - // generates the next signing set. - rounds.set_jailed_signers(jailed_signers); - worker.rounds = Some(rounds); - } - } - - // Get the best queued authorities for setting up next rounds - let maybe_next_party_index = worker.get_next_party_index(header); - // Create the active rounds only if the authority is selected in the best set - if let Some(party_index) = maybe_next_party_index { - let best_authorities: Vec = - worker.get_next_best_authorities(header).iter().map(|x| x.1.clone()).collect(); - let jailed_signers = worker.get_signing_jailed(header, &best_authorities); - let mut rounds = MultiPartyECDSARounds::builder() - .round_id(queued_round_id) - .party_index(party_index) - .threshold(worker.get_next_signature_threshold(header)) - .parties(worker.get_next_keygen_threshold(header)) - .local_key_path(Some(queued_local_key_path)) - .authorities(best_authorities.clone()) - .jailed_signers(worker.get_signing_jailed(header, &best_authorities)) - .build(); - - if let Some(key) = queued_local_key { - debug!(target: "dkg_persistence", "Queued local key set"); - // Set the local key - rounds.set_local_key(key.local_key); - // Once local key is set, we can set the jailed signers which also - // generates the next signing set. - rounds.set_jailed_signers(jailed_signers); - worker.next_rounds = Some(rounds); - } - } - } -} - -/// To determine if the protocol should be restarted, we check if the -/// protocol is stuck at the keygen stage -#[allow(dead_code)] -pub(crate) fn should_restart_dkg(worker: &mut DKGWorker) -> (bool, bool) -where - B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, -{ - let rounds = worker.rounds.take(); - let next_rounds = worker.next_rounds.take(); - - let should_restart_rounds = { - if let Some(rounds) = rounds { - let stalled = rounds.has_stalled(); - worker.rounds = Some(rounds); - stalled - } else { - false - } - }; - - let should_restart_next_rounds = { - if let Some(next_round) = next_rounds { - let stalled = next_round.has_stalled(); - worker.next_rounds = Some(next_round); - stalled - } else { - false - } - }; - - (should_restart_rounds, should_restart_next_rounds) -} diff --git a/dkg-gadget/src/proposal.rs b/dkg-gadget/src/proposal.rs index 4ea801647..0e2cefbea 100644 --- a/dkg-gadget/src/proposal.rs +++ b/dkg-gadget/src/proposal.rs @@ -1,3 +1,4 @@ +use std::sync::Arc; // Copyright 2022 Webb Technologies Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -use crate::{worker::DKGWorker, Client}; +use crate::Client; use codec::Encode; use dkg_primitives::types::DKGSignedPayload; use dkg_runtime_primitives::{ @@ -27,7 +28,7 @@ use sp_runtime::traits::{Block, Header}; /// Get signed proposal pub(crate) fn get_signed_proposal( - dkg_worker: &mut DKGWorker, + backend: &Arc, finished_round: DKGSignedPayload, payload_key: DKGPayloadKey, ) -> Option @@ -40,7 +41,7 @@ where let signed_proposal = match payload_key { DKGPayloadKey::RefreshVote(nonce) => { info!(target: "dkg", "🕸️ Refresh vote with nonce {:?} received", nonce); - let offchain = dkg_worker.backend.offchain_storage(); + let offchain = backend.offchain_storage(); if let Some(mut offchain) = offchain { let refresh_proposal = @@ -86,7 +87,10 @@ where } /// make an unsigned proposal a signed one -fn make_signed_proposal(kind: ProposalKind, finished_round: DKGSignedPayload) -> Option { +pub(crate) fn make_signed_proposal( + kind: ProposalKind, + finished_round: DKGSignedPayload, +) -> Option { Some(Proposal::Signed { kind, data: finished_round.payload, diff --git a/dkg-gadget/src/storage/clear.rs b/dkg-gadget/src/storage/clear.rs index 169f1dd43..323073897 100644 --- a/dkg-gadget/src/storage/clear.rs +++ b/dkg-gadget/src/storage/clear.rs @@ -14,7 +14,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use crate::{worker::DKGWorker, Client}; + +use crate::{gossip_engine::GossipEngineIface, worker::DKGWorker, Client}; use dkg_runtime_primitives::{ crypto::AuthorityId, offchain::storage_keys::{ @@ -28,18 +29,19 @@ use sc_client_api::Backend; use sp_application_crypto::sp_core::offchain::{OffchainStorage, STORAGE_PREFIX}; use sp_runtime::{ generic::BlockId, - traits::{Block, Header}, + traits::{Block, Header, NumberFor}, }; /// cleans offchain storage at interval -pub(crate) fn listen_and_clear_offchain_storage( - dkg_worker: &mut DKGWorker, +pub(crate) fn listen_and_clear_offchain_storage( + dkg_worker: &mut DKGWorker, header: &B::Header, ) where B: Block, + GE: GossipEngineIface + 'static, BE: Backend, C: Client, - C::Api: DKGApi::Header as Header>::Number>, + C::Api: DKGApi>, { let at: BlockId = BlockId::hash(header.hash()); let next_dkg_public_key = dkg_worker.client.runtime_api().next_dkg_pub_key(&at); diff --git a/dkg-gadget/src/storage/misbehaviour_reports.rs b/dkg-gadget/src/storage/misbehaviour_reports.rs index bf526b9e5..642e3aeab 100644 --- a/dkg-gadget/src/storage/misbehaviour_reports.rs +++ b/dkg-gadget/src/storage/misbehaviour_reports.rs @@ -14,7 +14,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use crate::{worker::DKGWorker, Client}; +use crate::{gossip_engine::GossipEngineIface, worker::DKGWorker, Client}; use codec::Encode; use dkg_primitives::types::DKGError; use dkg_runtime_primitives::{ @@ -24,18 +24,19 @@ use dkg_runtime_primitives::{ use log::trace; use sc_client_api::Backend; use sp_application_crypto::sp_core::offchain::{OffchainStorage, STORAGE_PREFIX}; -use sp_runtime::traits::{Block, Header}; +use sp_runtime::traits::{Block, NumberFor}; /// stores aggregated misbehaviour reports offchain -pub(crate) fn store_aggregated_misbehaviour_reports( - dkg_worker: &mut DKGWorker, +pub(crate) fn store_aggregated_misbehaviour_reports( + dkg_worker: &mut DKGWorker, reports: &AggregatedMisbehaviourReports, ) -> Result<(), DKGError> where B: Block, + GE: GossipEngineIface + 'static, BE: Backend, C: Client, - C::Api: DKGApi::Header as Header>::Number>, + C::Api: DKGApi>, { let maybe_offchain = dkg_worker.backend.offchain_storage(); if maybe_offchain.is_none() { diff --git a/dkg-gadget/src/storage/proposals.rs b/dkg-gadget/src/storage/proposals.rs index c6d90c44b..5a6df8c4a 100644 --- a/dkg-gadget/src/storage/proposals.rs +++ b/dkg-gadget/src/storage/proposals.rs @@ -1,13 +1,10 @@ -// This file is part of Webb. - -// Copyright (C) 2021 Webb Technologies Inc. -// SPDX-License-Identifier: Apache-2.0 - +// Copyright 2022 Webb Technologies Inc. +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -16,22 +13,29 @@ // limitations under the License. use crate::{ utils::find_index, - worker::{DKGWorker, MAX_SUBMISSION_DELAY, STORAGE_SET_RETRY_NUM}, + worker::{MAX_SUBMISSION_DELAY, STORAGE_SET_RETRY_NUM}, Client, }; use codec::{Decode, Encode}; use dkg_runtime_primitives::{ - crypto::AuthorityId, offchain::storage_keys::OFFCHAIN_SIGNED_PROPOSALS, DKGApi, - OffchainSignedProposals, Proposal, + crypto::{AuthorityId, Public}, + offchain::storage_keys::OFFCHAIN_SIGNED_PROPOSALS, + AuthoritySet, DKGApi, OffchainSignedProposals, Proposal, }; use log::debug; +use parking_lot::RwLock; +use rand::Rng; use sc_client_api::Backend; use sp_application_crypto::sp_core::offchain::{OffchainStorage, STORAGE_PREFIX}; use sp_runtime::traits::{Block, Header, NumberFor}; +use std::sync::Arc; /// processes signed proposals and puts them in storage pub(crate) fn save_signed_proposals_in_storage( - dkg_worker: &mut DKGWorker, + authority_public_key: &Public, + current_validator_set: &Arc>>, + latest_header: &Arc>>, + backend: &Arc, signed_proposals: Vec, ) where B: Block, @@ -45,25 +49,28 @@ pub(crate) fn save_signed_proposals_in_storage( debug!(target: "dkg", "🕸️ saving signed proposal in offchain storage"); - let public = dkg_worker.get_authority_public_key(); - - if find_index::(&dkg_worker.current_validator_set.authorities[..], &public) - .is_none() + if find_index::( + ¤t_validator_set.read().authorities[..], + authority_public_key, + ) + .is_none() { return } + let latest_header = latest_header.read().clone(); + // If the header is none, it means no block has been imported yet, so we can exit - if dkg_worker.latest_header.is_none() { + if latest_header.is_none() { return } let current_block_number = { - let header = dkg_worker.latest_header.as_ref().unwrap(); + let header = latest_header.as_ref().unwrap(); header.number() }; - if let Some(mut offchain) = dkg_worker.backend.offchain_storage() { + if let Some(mut offchain) = backend.offchain_storage() { let old_val = offchain.get(STORAGE_PREFIX, OFFCHAIN_SIGNED_PROPOSALS); let mut prop_wrapper = match old_val.clone() { @@ -76,7 +83,7 @@ pub(crate) fn save_signed_proposals_in_storage( // duplicate submissions as much as we can, we add a random submission delay to each // batch stored in offchain storage let submit_at = - dkg_worker.generate_delayed_submit_at(*current_block_number, MAX_SUBMISSION_DELAY); + generate_delayed_submit_at::(*current_block_number, MAX_SUBMISSION_DELAY); if let Some(submit_at) = submit_at { prop_wrapper.proposals.push((signed_proposals, submit_at)) @@ -95,3 +102,14 @@ pub(crate) fn save_signed_proposals_in_storage( } } } + +/// Generate a random delay to wait before taking an action. +/// The delay is generated from a random number between 0 and `max_delay`. +pub fn generate_delayed_submit_at( + start: NumberFor, + max_delay: u32, +) -> Option<::Number> { + let mut rng = rand::thread_rng(); + let submit_at = start + rng.gen_range(0u32..=max_delay).into(); + Some(submit_at) +} diff --git a/dkg-gadget/src/storage/public_keys.rs b/dkg-gadget/src/storage/public_keys.rs index 979f3b24e..bcb3f9e68 100644 --- a/dkg-gadget/src/storage/public_keys.rs +++ b/dkg-gadget/src/storage/public_keys.rs @@ -1,23 +1,18 @@ -// This file is part of Webb. - -// Copyright (C) 2021 Webb Technologies Inc. -// SPDX-License-Identifier: Apache-2.0 - +// Copyright 2022 Webb Technologies Inc. +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use crate::{ - worker::{DKGWorker, MAX_SUBMISSION_DELAY}, - Client, -}; + +use crate::{storage::proposals::generate_delayed_submit_at, worker::MAX_SUBMISSION_DELAY, Client}; use codec::Encode; use dkg_primitives::types::{DKGError, RoundId}; use dkg_runtime_primitives::{ @@ -31,13 +26,14 @@ use dkg_runtime_primitives::{ use sc_client_api::Backend; use sp_api::offchain::{OffchainStorage, STORAGE_PREFIX}; use sp_runtime::traits::{Block, Header, NumberFor}; +use std::{collections::HashMap, sync::Arc}; /// stores genesis or next aggregated public keys offchain pub(crate) fn store_aggregated_public_keys( - mut dkg_worker: &mut DKGWorker, + backend: &Arc, + aggregated_public_keys: &mut HashMap, is_genesis_round: bool, round_id: RoundId, - keys: &AggregatedPublicKeys, current_block_number: NumberFor, ) -> Result<(), DKGError> where @@ -46,15 +42,17 @@ where C: Client, C::Api: DKGApi::Header as Header>::Number>, { - let maybe_offchain = dkg_worker.backend.offchain_storage(); + let maybe_offchain = backend.offchain_storage(); if maybe_offchain.is_none() { return Err(DKGError::GenericError { reason: "No offchain storage available".to_string() }) } let offchain = maybe_offchain.unwrap(); + let keys = aggregated_public_keys.get(&round_id).ok_or_else(|| DKGError::CriticalError { + reason: format!("Aggregated public key for round {} does not exist in map", round_id), + })?; if is_genesis_round { - dkg_worker.dkg_state.listening_for_active_pub_key = false; - perform_storing_of_aggregated_public_keys( - dkg_worker, + //dkg_worker.dkg_state.listening_for_active_pub_key = false; + perform_storing_of_aggregated_public_keys::( offchain, keys, current_block_number, @@ -62,24 +60,22 @@ where SUBMIT_GENESIS_KEYS_AT, ); } else { - dkg_worker.dkg_state.listening_for_pub_key = false; - perform_storing_of_aggregated_public_keys( - dkg_worker, + //dkg_worker.dkg_state.listening_for_pub_key = false; + perform_storing_of_aggregated_public_keys::( offchain, keys, current_block_number, AGGREGATED_PUBLIC_KEYS, SUBMIT_KEYS_AT, ); - let _ = dkg_worker.aggregated_public_keys.remove(&round_id); + let _ = aggregated_public_keys.remove(&round_id); } Ok(()) } /// stores the aggregated public keys -fn perform_storing_of_aggregated_public_keys( - dkg_worker: &mut DKGWorker, +fn perform_storing_of_aggregated_public_keys( mut offchain: >::OffchainStorage, keys: &AggregatedPublicKeys, current_block_number: NumberFor, @@ -88,12 +84,9 @@ fn perform_storing_of_aggregated_public_keys( ) where B: Block, BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, { offchain.set(STORAGE_PREFIX, aggregated_keys, &keys.encode()); - let submit_at = - dkg_worker.generate_delayed_submit_at(current_block_number, MAX_SUBMISSION_DELAY); + let submit_at = generate_delayed_submit_at::(current_block_number, MAX_SUBMISSION_DELAY); if let Some(submit_at) = submit_at { offchain.set(STORAGE_PREFIX, submit_keys, &submit_at.encode()); } diff --git a/dkg-gadget/src/types.rs b/dkg-gadget/src/types.rs deleted file mode 100644 index 1ccdc097e..000000000 --- a/dkg-gadget/src/types.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use sp_runtime::traits::{Block, Hash, Header}; - -/// Gossip engine dkg messages topic -pub(crate) fn dkg_topic() -> B::Hash -where - B: Block, -{ - <::Hashing as Hash>::hash(b"dkg") -} diff --git a/dkg-gadget/src/utils.rs b/dkg-gadget/src/utils.rs index 715663be5..479d8c2a8 100644 --- a/dkg-gadget/src/utils.rs +++ b/dkg-gadget/src/utils.rs @@ -13,59 +13,20 @@ // limitations under the License. // use crate::worker::ENGINE_ID; -use dkg_primitives::{ - crypto::AuthorityId, rounds::MultiPartyECDSARounds, types::RoundId, AuthoritySet, ConsensusLog, -}; +use dkg_primitives::{crypto::AuthorityId, types::DKGError, AuthoritySet, ConsensusLog}; use sp_api::{BlockT as Block, HeaderT}; -use sp_arithmetic::traits::AtLeast32BitUnsigned; use sp_runtime::generic::OpaqueDigestItemId; -use std::path::PathBuf; +use std::{fmt::Debug, future::Future, path::PathBuf}; -/// Finds the index of a value in a vector. Returns None if the value is not found. -pub fn find_index(queue: &[B], value: &B) -> Option { - for (i, v) in queue.iter().enumerate() { - if value == v { - return Some(i) - } - } - None +pub trait SendFuture<'a, Out: 'a>: Future> + Send + 'a {} +impl<'a, T, Out: Debug + Send + 'a> SendFuture<'a, Out> for T where + T: Future> + Send + 'a +{ } -/// Sets up the Multi-party ECDSA rounds struct used to receive, process, and handle -/// incoming and outgoing DKG related messages for key generation, offline stage creation, -/// and signing. The rounds struct is used to handle the execution of a single round of the DKG -/// and should be created for each session. -/// -/// The rounds are intended to be run only by `best_authorities` that are selected from -/// an externally provided set of reputations. Rounds are parameterized for a `t-of-n` threshold -/// - `signature_threshold` represents `t` -/// - `keygen_threshold` represents `n` -/// -/// We provide an optional `local_key_path` to this struct so that it may save the generated -/// DKG public / local key to disk. Caching of this key is critical to persistent storage and -/// resuming the worker from a machine failure. -#[allow(clippy::too_many_arguments)] -#[allow(dead_code)] -pub fn set_up_rounds( - best_authorities: &[AuthorityId], - authority_set_id: RoundId, - public: &AuthorityId, - signature_threshold: u16, - keygen_threshold: u16, - local_key_path: Option, - jailed_signers: &[AuthorityId], -) -> MultiPartyECDSARounds { - let party_inx = find_index::(best_authorities, public).unwrap() + 1; - // Generate the rounds object - MultiPartyECDSARounds::builder() - .round_id(authority_set_id) - .party_index(u16::try_from(party_inx).unwrap()) - .threshold(signature_threshold) - .parties(keygen_threshold) - .local_key_path(local_key_path) - .authorities(best_authorities.to_vec()) - .jailed_signers(jailed_signers.to_vec()) - .build() +/// Finds the index of a value in a vector. Returns None if the value is not found. +pub fn find_index(queue: &[B], value: &B) -> Option { + queue.iter().position(|v| value == v) } /// Scan the `header` digest log for a DKG validator set change. Return either the new @@ -99,3 +60,38 @@ fn match_consensus_log( pub fn get_key_path(base_path: &Option, path_str: &str) -> Option { base_path.as_ref().map(|path| path.join(path_str)) } + +#[cfg(feature = "outbound-inspection")] +pub(crate) fn inspect_outbound(ty: &'static str, serialized_len: usize) { + use parking_lot::Mutex; + use std::collections::HashMap; + + static MAP: Mutex>>> = parking_lot::const_mutex(None); + let mut lock = MAP.lock(); + + if lock.is_none() { + *lock = Some(HashMap::new()) + } + + let map = lock.as_mut().unwrap(); + + map.entry(ty).or_default().push(serialized_len as u32); + + for (ty, history) in map.iter() { + log::debug!(target: "dkg", "History for {}: \ + total count={}, \ + first={:?}, \ + latest={:?}, \ + lifetime_delta={:?}, \ + max={:?}", + ty, + history.len(), + history.first(), + history.last(), + history.last().and_then(|latest| history.first().map(|first| *latest as i64 - *first as i64)), + history.iter().max()); + } +} + +#[cfg(not(feature = "outbound-inspection"))] +pub(crate) fn inspect_outbound(_ty: &str, _serialized_len: usize) {} diff --git a/dkg-gadget/src/worker.rs b/dkg-gadget/src/worker.rs index 8b6d53f1a..d7fc25e02 100644 --- a/dkg-gadget/src/worker.rs +++ b/dkg-gadget/src/worker.rs @@ -14,151 +14,163 @@ #![allow(clippy::collapsible_match)] +use crate::async_protocols::blockchain_interface::DKGProtocolEngine; +use codec::{Codec, Encode}; +use dkg_primitives::utils::select_random_set; +use dkg_runtime_primitives::KEYGEN_TIMEOUT; +use futures::{FutureExt, StreamExt}; +use itertools::Itertools; +use log::{debug, error, info, trace}; use sc_keystore::LocalKeystore; use sp_core::ecdsa; use std::{ - collections::{hash_map::RandomState, BTreeSet, HashMap, HashSet}, + collections::{BTreeSet, HashMap, HashSet}, + future::Future, marker::PhantomData, path::PathBuf, + pin::Pin, sync::Arc, }; -use codec::{Codec, Decode, Encode}; -use futures::{future, FutureExt, StreamExt}; -use log::{debug, error, info, trace}; -use parking_lot::Mutex; +use parking_lot::{Mutex, RwLock}; use sc_client_api::{ Backend, BlockImportNotification, FinalityNotification, FinalityNotifications, ImportNotifications, }; -use sc_network_gossip::GossipEngine; -use rand::Rng; use sp_api::BlockId; use sp_runtime::traits::{Block, Header, NumberFor}; +use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender}; -use crate::{ - keystore::DKGKeystore, - persistence::{try_resume_dkg, DKGPersistenceState}, -}; +use crate::keystore::DKGKeystore; -use crate::messages::{ - dkg_message::send_outgoing_dkg_messages, - misbehaviour_report::{gossip_misbehaviour_report, handle_misbehaviour_report}, - public_key_gossip::handle_public_key_broadcast, +use crate::gossip_messages::misbehaviour_report::{ + gossip_misbehaviour_report, handle_misbehaviour_report, }; -use crate::storage::{ - clear::listen_and_clear_offchain_storage, proposals::save_signed_proposals_in_storage, -}; +use crate::{gossip_engine::GossipEngineIface, storage::clear::listen_and_clear_offchain_storage}; use dkg_primitives::{ types::{DKGError, DKGMisbehaviourMessage, RoundId}, - AuthoritySetId, DKGReport, MisbehaviourType, Proposal, GOSSIP_MESSAGE_RESENDING_LIMIT, + utils::StoredLocalKey, + AuthoritySetId, DKGReport, MisbehaviourType, GOSSIP_MESSAGE_RESENDING_LIMIT, }; use dkg_runtime_primitives::{ crypto::{AuthorityId, Public}, utils::to_slice_33, - AggregatedMisbehaviourReports, AggregatedPublicKeys, TypedChainId, GENESIS_AUTHORITY_SET_ID, + AggregatedMisbehaviourReports, AggregatedPublicKeys, UnsignedProposal, + GENESIS_AUTHORITY_SET_ID, }; use crate::{ error, metric_set, metrics::Metrics, - proposal::get_signed_proposal, - types::dkg_topic, + persistence::load_stored_key, utils::{find_authorities_change, get_key_path}, Client, }; +use crate::gossip_messages::public_key_gossip::handle_public_key_broadcast; use dkg_primitives::{ - rounds::{DKGState, MultiPartyECDSARounds}, - types::{DKGMessage, DKGPayloadKey, DKGSignedPayload, SignedDKGMessage}, + types::{DKGMessage, DKGMsgPayload, SignedDKGMessage}, utils::{cleanup, DKG_LOCAL_KEY_FILE, QUEUED_DKG_LOCAL_KEY_FILE}, }; use dkg_runtime_primitives::{AuthoritySet, DKGApi}; +use crate::async_protocols::{ + misbehaviour_monitor::MisbehaviourMonitor, remote::AsyncProtocolRemote, + AsyncProtocolParameters, GenericAsyncHandler, +}; + pub const ENGINE_ID: sp_runtime::ConsensusEngineId = *b"WDKG"; pub const STORAGE_SET_RETRY_NUM: usize = 5; pub const MAX_SUBMISSION_DELAY: u32 = 3; -pub(crate) struct WorkerParams +pub const MAX_SIGNING_SETS: u64 = 16; + +pub(crate) struct WorkerParams where B: Block, + GE: GossipEngineIface, { pub client: Arc, pub backend: Arc, pub key_store: DKGKeystore, - pub gossip_engine: GossipEngine, + pub gossip_engine: GE, pub metrics: Option, pub base_path: Option, pub local_keystore: Option>, - pub dkg_state: DKGState>, + pub latest_header: Arc>>, + pub _marker: PhantomData, } /// A DKG worker plays the DKG protocol -pub(crate) struct DKGWorker +pub(crate) struct DKGWorker where B: Block, BE: Backend, C: Client, + GE: GossipEngineIface, { pub client: Arc, pub backend: Arc, pub key_store: DKGKeystore, - pub gossip_engine: Arc>>, + pub gossip_engine: Arc, pub metrics: Option, - pub rounds: Option>>, - pub next_rounds: Option>>, + // Genesis keygen and rotated round + pub rounds: Option>>, + // Next keygen round, always taken and restarted each session + pub next_rounds: Option>>, + // Signing rounds, created everytime there are unique unsigned proposals + pub signing_rounds: Vec>>>, pub finality_notifications: FinalityNotifications, pub import_notifications: ImportNotifications, - pub votes_sent: u64, /// Best block a DKG voting round has been concluded for pub best_dkg_block: Option>, + /// Cached best authorities + pub best_authorities: Vec<(u16, Public)>, + /// Cached next best authorities + pub best_next_authorities: Vec<(u16, Public)>, /// Latest block header - pub latest_header: Option, + pub latest_header: Arc>>, /// Current validator set - pub current_validator_set: AuthoritySet, + pub current_validator_set: Arc>>, /// Queued validator set pub queued_validator_set: AuthoritySet, - /// Msg cache for startup if authorities aren't set - pub msg_cache: Vec>, /// Tracking for the broadcasted public keys and signatures - pub aggregated_public_keys: HashMap, + pub aggregated_public_keys: Arc>>, /// Tracking for the misbehaviour reports - pub aggregated_misbehaviour_reports: HashMap< - (MisbehaviourType, RoundId, AuthorityId), - AggregatedMisbehaviourReports, - >, + pub aggregated_misbehaviour_reports: AggregatedMisbehaviourReportStore, + pub misbehaviour_tx: Option>, /// Tracking for sent gossip messages: using blake2_128 for message hashes /// The value is the number of times the message has been sent. pub has_sent_gossip_msg: HashMap<[u8; 16], u8>, - /// dkg state - pub dkg_state: DKGState>, - /// Setting up keygen for current authorities - pub active_keygen_in_progress: bool, - /// setting up queued authorities keygen - pub queued_keygen_in_progress: bool, - /// Track DKG Persistence state - pub dkg_persistence: DKGPersistenceState, /// Local keystore for DKG data pub base_path: Option, /// Concrete type that points to the actual local keystore if it exists pub local_keystore: Option>, - /// keep rustc happy + /// For transmitting errors from parallel threads to the DKGWorker + pub error_handler_tx: UnboundedSender, + /// For use in the run() function only + pub error_handler_rx: Option>, + // keep rustc happy _backend: PhantomData, } -impl DKGWorker +pub type AggregatedMisbehaviourReportStore = + HashMap<(MisbehaviourType, RoundId, AuthorityId), AggregatedMisbehaviourReports>; + +impl DKGWorker where B: Block + Codec, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, + BE: Backend + 'static, + GE: GossipEngineIface + 'static, + C: Client + 'static, + C::Api: DKGApi>, { /// Return a new DKG worker instance. /// @@ -166,55 +178,260 @@ where /// DKG pallet has been deployed on-chain. /// /// The DKG pallet is needed in order to keep track of the DKG authority set. - pub(crate) fn new(worker_params: WorkerParams) -> Self { + pub(crate) fn new(worker_params: WorkerParams) -> Self { let WorkerParams { client, backend, key_store, gossip_engine, metrics, - dkg_state, base_path, local_keystore, + latest_header, + .. } = worker_params; + // we drop the rx handle since we can call tx.subscribe() every time we need to fire up + // a new AsyncProto + // let (to_async_proto, _) = tokio::sync::broadcast::channel(1024); + let (error_handler_tx, error_handler_rx) = tokio::sync::mpsc::unbounded_channel(); + DKGWorker { client: client.clone(), + misbehaviour_tx: None, backend, key_store, - gossip_engine: Arc::new(Mutex::new(gossip_engine)), + gossip_engine: Arc::new(gossip_engine), metrics, - votes_sent: 0, rounds: None, next_rounds: None, + signing_rounds: vec![None; 16], finality_notifications: client.finality_notification_stream(), import_notifications: client.import_notification_stream(), best_dkg_block: None, - current_validator_set: AuthoritySet::empty(), + best_authorities: Vec::new(), + best_next_authorities: Vec::new(), + current_validator_set: Arc::new(RwLock::new(AuthoritySet::empty())), queued_validator_set: AuthoritySet::empty(), - latest_header: None, - dkg_state, - queued_keygen_in_progress: false, - active_keygen_in_progress: false, - msg_cache: Vec::new(), - aggregated_public_keys: HashMap::new(), + latest_header, + aggregated_public_keys: Arc::new(Mutex::new(HashMap::new())), aggregated_misbehaviour_reports: HashMap::new(), has_sent_gossip_msg: HashMap::new(), - dkg_persistence: DKGPersistenceState::new(), base_path, local_keystore, + error_handler_tx, + error_handler_rx: Some(error_handler_rx), _backend: PhantomData, } } } -impl DKGWorker +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +enum ProtoStageType { + Genesis, + Queued, + Signing, +} + +impl DKGWorker where B: Block, - BE: Backend, - C: Client, - C::Api: DKGApi::Header as Header>::Number>, + BE: Backend + 'static, + GE: GossipEngineIface + 'static, + C: Client + 'static, + C::Api: DKGApi>, { + // NOTE: This must be ran at the start of each epoch since best_authorities may change + // if "current" is true, this will set the "rounds" field in the dkg worker, otherwise, + // it well set the "next_rounds" field + fn generate_async_proto_params( + &mut self, + best_authorities: Vec, + authority_public_key: Public, + round_id: RoundId, + local_key_path: Option, + stage: ProtoStageType, + async_index: u8, + ) -> Result>, DKGError> { + let best_authorities = Arc::new(best_authorities); + let authority_public_key = Arc::new(authority_public_key); + + let now = self.get_latest_block_number(); + let status_handle = AsyncProtocolRemote::new(now, round_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 (active_local_key, _) = self.fetch_local_keys(); + let params = AsyncProtocolParameters { + engine: Arc::new(DKGProtocolEngine { + backend: self.backend.clone(), + latest_header: self.latest_header.clone(), + client: self.client.clone(), + keystore: self.key_store.clone(), + gossip_engine: self.gossip_engine.clone(), + aggregated_public_keys: self.aggregated_public_keys.clone(), + best_authorities: best_authorities.clone(), + authority_public_key: authority_public_key.clone(), + current_validator_set: self.current_validator_set.clone(), + local_keystore: self.local_keystore.clone(), + vote_results: Arc::new(Default::default()), + local_key_path, + is_genesis: stage == ProtoStageType::Genesis, + _pd: Default::default(), + }), + round_id, + keystore: self.key_store.clone(), + current_validator_set: self.current_validator_set.clone(), + best_authorities, + authority_public_key, + batch_id_gen: Arc::new(Default::default()), + handle: status_handle.clone(), + local_key: active_local_key.map(|k| k.local_key), + }; + // Start the respective protocol + status_handle.start()?; + // Cache the rounds, respectively + match stage { + ProtoStageType::Genesis => { + debug!(target: "dkg", "Starting genesis protocol"); + self.rounds = Some(status_handle.into_primary_remote()) + }, + ProtoStageType::Queued => { + debug!(target: "dkg", "Starting queued protocol"); + self.next_rounds = Some(status_handle.into_primary_remote()) + }, + // When we are at signing stage, it is using the active rounds. + ProtoStageType::Signing => { + debug!(target: "dkg", "Starting signing protocol"); + self.signing_rounds[async_index as usize] = + Some(status_handle.into_primary_remote()) + }, + } + + Ok(params) + } + + fn spawn_keygen_protocol( + &mut self, + best_authorities: Vec, + authority_public_key: Public, + round_id: RoundId, + threshold: u16, + local_key_path: Option, + stage: ProtoStageType, + ) { + match self.generate_async_proto_params( + best_authorities, + authority_public_key, + round_id, + local_key_path, + stage, + 0u8, + ) { + Ok(async_proto_params) => { + let err_handler_tx = self.error_handler_tx.clone(); + let misbehaviour_tx = + self.misbehaviour_tx.clone().expect("Misbehaviour TX not loaded"); + let remote = async_proto_params.handle.clone(); + let engine = async_proto_params.engine.clone(); + + match GenericAsyncHandler::setup_keygen(async_proto_params, threshold) { + Ok(meta_handler) => { + let task = async move { + let misbehaviour_monitor = + MisbehaviourMonitor::new(remote, engine, misbehaviour_tx); + + let res = tokio::select! { + res0 = meta_handler => res0, + res1 = misbehaviour_monitor => Err(DKGError::CriticalError { reason: format!("Misbehaviour monitor should not finish before meta handler. Reason for exit: {:?}", res1)}) + }; + + match res { + Ok(_) => { + log::info!(target: "dkg", "The meta handler has executed successfully"); + }, + + Err(err) => { + error!(target: "dkg", "Error executing meta handler {:?}", &err); + let _ = err_handler_tx.send(err); + }, + } + }; + + // spawn on parallel thread + let _handle = tokio::task::spawn(task); + }, + + Err(err) => { + error!(target: "dkg", "Error starting meta handler {:?}", &err); + self.handle_dkg_error(err); + }, + } + }, + + Err(err) => self.handle_dkg_error(err), + } + } + + #[allow(clippy::too_many_arguments, clippy::type_complexity)] + fn create_signing_protocol( + &mut self, + best_authorities: Vec, + authority_public_key: Public, + round_id: RoundId, + threshold: u16, + local_key_path: Option, + stage: ProtoStageType, + unsigned_proposals: Vec, + signing_set: Vec, + async_index: u8, + ) -> Result> + Send + 'static>>, DKGError> { + let async_proto_params = self.generate_async_proto_params( + best_authorities, + authority_public_key, + round_id, + local_key_path, + stage, + async_index, + )?; + + let err_handler_tx = self.error_handler_tx.clone(); + let misbehaviour_tx = self.misbehaviour_tx.clone().expect("Misbehaviour TX not loaded"); + let remote = async_proto_params.handle.clone(); + let engine = async_proto_params.engine.clone(); + + let meta_handler = GenericAsyncHandler::setup_signing( + async_proto_params, + threshold, + unsigned_proposals, + signing_set, + async_index, + )?; + + let task = async move { + let misbehaviour_monitor = MisbehaviourMonitor::new(remote, engine, misbehaviour_tx); + + let res = tokio::select! { + res0 = meta_handler => res0, + res1 = misbehaviour_monitor => Err(DKGError::CriticalError { reason: format!("Misbehaviour monitor should not finish before meta handler. Reason for exit: {:?}", res1)}) + }; + + match res { + Ok(_) => { + log::info!(target: "dkg", "The meta handler has executed successfully"); + Ok(async_index) + }, + + Err(err) => { + error!(target: "dkg", "Error executing meta handler {:?}", &err); + let _ = err_handler_tx.send(err.clone()); + Err(err) + }, + } + }; + + Ok(Box::pin(task)) + } + /// Rotates the contents of the DKG local key files from the queued file to the active file. /// /// This is meant to be used when rotating the DKG. During a rotation, we begin generating @@ -226,7 +443,7 @@ where /// /// This should never execute unless we are certain that the rotation will succeed, i.e. /// that the signature of the next DKG public key has been created and stored on-chain. - fn rotate_local_key_files(&mut self) { + fn rotate_local_key_files(&mut self) -> bool { let mut local_key_path: Option = None; let mut queued_local_key_path: Option = None; @@ -234,14 +451,74 @@ where local_key_path = get_key_path(&self.base_path, DKG_LOCAL_KEY_FILE); queued_local_key_path = get_key_path(&self.base_path, QUEUED_DKG_LOCAL_KEY_FILE); } - + debug!(target: "dkg", "Rotating local key files"); + debug!(target: "dkg", "Local key path: {:?}", local_key_path); + debug!(target: "dkg", "Queued local key path: {:?}", queued_local_key_path); if let (Some(path), Some(queued_path)) = (local_key_path, queued_local_key_path) { if let Err(err) = std::fs::copy(queued_path, path) { error!("Error copying queued key {:?}", &err); + return false } else { debug!("Successfully copied queued key to current key"); + return true } } + + false + } + + /// Fetch the local stored keys if they exist. + fn fetch_local_keys(&mut self) -> (Option, Option) { + let mut local_key_path: Option = None; + let mut queued_local_key_path: Option = None; + + if self.base_path.is_some() { + local_key_path = get_key_path(&self.base_path, DKG_LOCAL_KEY_FILE); + queued_local_key_path = get_key_path(&self.base_path, QUEUED_DKG_LOCAL_KEY_FILE); + } + + let sr_pub = self.get_sr25519_public_key(); + match (local_key_path, queued_local_key_path) { + (Some(path), Some(queued_path)) => ( + load_stored_key(path, self.local_keystore.as_ref(), sr_pub).ok(), + load_stored_key(queued_path, self.local_keystore.as_ref(), sr_pub).ok(), + ), + (Some(path), None) => + (load_stored_key(path, self.local_keystore.as_ref(), sr_pub).ok(), None), + (None, Some(queued_path)) => + (None, load_stored_key(queued_path, self.local_keystore.as_ref(), sr_pub).ok()), + (None, None) => (None, None), + } + } + + /// Get the party index of our worker + /// + /// Returns `None` if we are not in the best authority set + pub fn get_party_index(&mut self, header: &B::Header) -> Option { + let public = self.get_authority_public_key(); + let best_authorities = self.get_best_authorities(header); + for elt in best_authorities { + if elt.1 == public { + return Some(elt.0) + } + } + + None + } + + /// Get the next party index of our worker for possible queued keygen + /// + /// Returns `None` if we are not in the next best authority set + pub fn get_next_party_index(&mut self, header: &B::Header) -> Option { + let public = self.get_authority_public_key(); + let next_best_authorities = self.get_next_best_authorities(header); + for elt in next_best_authorities { + if elt.1 == public { + return Some(elt.0) + } + } + + None } /// Get the signature threshold at a specific block @@ -250,24 +527,12 @@ where return self.client.runtime_api().signature_threshold(&at).unwrap_or_default() } - /// Get the keygen threshold at a specific block - pub fn get_keygen_threshold(&self, header: &B::Header) -> u16 { - let at: BlockId = BlockId::hash(header.hash()); - return self.client.runtime_api().keygen_threshold(&at).unwrap_or_default() - } - /// Get the next signature threshold at a specific block pub fn get_next_signature_threshold(&self, header: &B::Header) -> u16 { let at: BlockId = BlockId::hash(header.hash()); return self.client.runtime_api().next_signature_threshold(&at).unwrap_or_default() } - /// Get the next keygen threshold at a specific block - pub fn get_next_keygen_threshold(&self, header: &B::Header) -> u16 { - let at: BlockId = BlockId::hash(header.hash()); - return self.client.runtime_api().next_keygen_threshold(&at).unwrap_or_default() - } - /// Get the active DKG public key pub fn get_dkg_pub_key(&self, header: &B::Header) -> (AuthoritySetId, Vec) { let at: BlockId = BlockId::hash(header.hash()); @@ -292,16 +557,6 @@ where .unwrap_or_default() } - /// Get the jailed signing authorities - pub fn get_signing_jailed(&self, header: &B::Header, set: &[AuthorityId]) -> Vec { - let at: BlockId = BlockId::hash(header.hash()); - return self - .client - .runtime_api() - .get_signing_jailed(&at, set.to_vec()) - .unwrap_or_default() - } - /// Get the best authorities for keygen pub fn get_best_authorities(&self, header: &B::Header) -> Vec<(u16, AuthorityId)> { let at: BlockId = BlockId::hash(header.hash()); @@ -314,59 +569,6 @@ where return self.client.runtime_api().get_next_best_authorities(&at).unwrap_or_default() } - /// Get the party index of our worker - /// - /// Returns `None` if we are not in the best authority set - pub fn get_party_index(&mut self, header: &B::Header) -> Option { - let public = self.get_authority_public_key(); - let best_authorities = self.get_best_authorities(header); - for elt in best_authorities { - if elt.1 == public { - return Some(elt.0) - } - } - - None - } - - /// Get the next party index of our worker for possible queued keygen - /// - /// Returns `None` if we are not in the next best authority set - pub fn get_next_party_index(&mut self, header: &B::Header) -> Option { - let public = self.get_authority_public_key(); - let next_best_authorities = self.get_next_best_authorities(header); - for elt in next_best_authorities { - if elt.1 == public { - return Some(elt.0) - } - } - - None - } - - /// Gets latest block number from latest block header - pub fn get_latest_block_number(&self) -> NumberFor { - if self.latest_header.is_some() { - *self.latest_header.clone().unwrap().number() - } else { - NumberFor::::from(0u32) - } - } - - /// Gets the active DKG authority key - pub fn get_authority_public_key(&mut self) -> Public { - self.key_store - .authority_id(&self.key_store.public_keys().unwrap()) - .unwrap_or_else(|| panic!("Halp")) - } - - /// Gets the active Sr25519 public key - pub fn get_sr25519_public_key(&mut self) -> sp_core::sr25519::Public { - self.key_store - .sr25519_public_key(&self.key_store.sr25519_public_keys().unwrap_or_default()) - .unwrap_or_else(|| panic!("Could not find sr25519 key in keystore")) - } - /// Return the next and queued validator set at header `header`. /// /// Note that the validator set could be `None`. This is the case if we don't find @@ -380,13 +582,20 @@ where pub fn validator_set( &self, header: &B::Header, + ) -> Option<(AuthoritySet, AuthoritySet)> { + Self::validator_set_inner(header, &self.client) + } + + fn validator_set_inner( + header: &B::Header, + client: &Arc, ) -> Option<(AuthoritySet, AuthoritySet)> { let new = if let Some((new, queued)) = find_authorities_change::(header) { Some((new, queued)) } else { let at: BlockId = BlockId::hash(header.hash()); - let current_authority_set = self.client.runtime_api().authority_set(&at).ok(); - let queued_authority_set = self.client.runtime_api().queued_authority_set(&at).ok(); + let current_authority_set = client.runtime_api().authority_set(&at).ok(); + let queued_authority_set = client.runtime_api().queued_authority_set(&at).ok(); match (current_authority_set, queued_authority_set) { (Some(current), Some(queued)) => Some((current, queued)), _ => None, @@ -441,10 +650,15 @@ where return } + let latest_block_num = self.get_latest_block_number(); + // Check if we've already set up the DKG for this authority set - if self.rounds.is_some() && !self.rounds.as_ref().unwrap().has_stalled() { - debug!(target: "dkg", "🕸️ Rounds exists and has not stalled"); - return + // if the active is currently running, and, the keygen has stalled, create one anew + if let Some(rounds) = self.rounds.as_ref() { + if rounds.is_active() && !rounds.keygen_has_stalled(latest_block_num) { + debug!(target: "dkg", "🕸️ Rounds exists and is active"); + return + } } let mut local_key_path: Option = None; @@ -453,8 +667,6 @@ where let _ = cleanup(local_key_path.as_ref().unwrap().clone()); } - let latest_block_num = self.get_latest_block_number(); - // DKG keygen authorities are always taken from the best set of authorities let round_id = genesis_authority_set.id; let maybe_party_index = self.get_party_index(header); @@ -469,31 +681,16 @@ where let best_authorities: Vec = self.get_best_authorities(header).iter().map(|x| x.1.clone()).collect(); - self.rounds = Some( - MultiPartyECDSARounds::builder() - .round_id(round_id) - .party_index(maybe_party_index.unwrap()) - .threshold(self.get_signature_threshold(header)) - .parties(self.get_keygen_threshold(header)) - .local_key_path(local_key_path) - .authorities(best_authorities.clone()) - .jailed_signers(self.get_signing_jailed(header, &best_authorities)) - .build(), + let threshold = self.get_signature_threshold(header); + let authority_public_key = self.get_authority_public_key(); + self.spawn_keygen_protocol( + best_authorities, + authority_public_key, + round_id, + threshold, + local_key_path, + ProtoStageType::Genesis, ); - - self.dkg_state.listening_for_active_pub_key = true; - if let Some(rounds) = self.rounds.as_mut() { - match rounds.start_keygen(latest_block_num) { - Ok(()) => { - info!(target: "dkg", "Keygen started for genesis authority set successfully"); - self.active_keygen_in_progress = true; - }, - Err(err) => { - error!("Error starting keygen {:?}", &err); - self.handle_dkg_error(err); - }, - } - } } fn handle_queued_dkg_setup(&mut self, header: &B::Header, queued: AuthoritySet) { @@ -503,17 +700,23 @@ where } // Check if the next rounds exists and has processed for this next queued round id - if self.next_rounds.is_some() && !self.next_rounds.as_ref().unwrap().has_stalled() { + if self.next_rounds.is_some() && self.next_rounds.as_ref().unwrap().is_active() { + debug!(target: "dkg", "🕸️ Next rounds exists and is active, returning..."); return } + if let Some(rounds) = self.next_rounds.as_ref() { + if rounds.keygen_has_stalled(*header.number()) { + debug!(target: "dkg", "🕸️ Next rounds keygen has stalled, creating new rounds..."); + } + } + let mut queued_local_key_path: Option = None; if self.base_path.is_some() { queued_local_key_path = get_key_path(&self.base_path, QUEUED_DKG_LOCAL_KEY_FILE); let _ = cleanup(queued_local_key_path.as_ref().unwrap().clone()); } - let latest_block_num = self.get_latest_block_number(); // Get the best next authorities using the keygen threshold let round_id = queued.id; @@ -521,7 +724,6 @@ where // Check whether the worker is in the best set or return if maybe_party_index.is_none() { info!(target: "dkg", "🕸️ NOT IN THE SET OF BEST NEXT AUTHORITIES: round {:?}", round_id); - self.next_rounds = None; return } else { info!(target: "dkg", "🕸️ IN THE SET OF BEST NEXT AUTHORITIES: round {:?}", round_id); @@ -529,69 +731,43 @@ where let best_authorities: Vec = self.get_next_best_authorities(header).iter().map(|x| x.1.clone()).collect(); - self.next_rounds = Some( - MultiPartyECDSARounds::builder() - .round_id(round_id) - .party_index(maybe_party_index.unwrap()) - .threshold(self.get_next_signature_threshold(header)) - .parties(self.get_next_keygen_threshold(header)) - .local_key_path(queued_local_key_path) - .authorities(best_authorities.clone()) - .jailed_signers(self.get_signing_jailed(header, &best_authorities)) - .build(), + let threshold = self.get_next_signature_threshold(header); + + let authority_public_key = self.get_authority_public_key(); + self.spawn_keygen_protocol( + best_authorities, + authority_public_key, + round_id, + threshold, + queued_local_key_path, + ProtoStageType::Queued, ); - - self.dkg_state.listening_for_pub_key = true; - if let Some(rounds) = self.next_rounds.as_mut() { - match rounds.start_keygen(latest_block_num) { - Ok(()) => { - info!(target: "dkg", "Keygen started for queued authority set successfully"); - self.queued_keygen_in_progress = true; - }, - Err(err) => { - error!("Error starting keygen {:?}", &err); - self.handle_dkg_error(err); - }, - } - } } // *** Block notifications *** fn process_block_notification(&mut self, header: &B::Header) { - if let Some(latest_header) = &self.latest_header { + debug!(target: "dkg", "🕸️ Processing block notification for block {}", header.number()); + if let Some(latest_header) = self.latest_header.read().clone() { if latest_header.number() >= header.number() { + // We've already seen this block, ignore it. + debug!(target: "dkg", "🕸️ Latest header is greater than or equal to current header, returning..."); return } } - self.latest_header = Some(header.clone()); + *self.latest_header.write() = Some(header.clone()); + debug!(target: "dkg", "🕸️ Latest header is now: {:?}", header.number()); // Clear offchain storage listen_and_clear_offchain_storage(self, header); - // Try to resume DKG when we hear of a new block - try_resume_dkg(self, header); // Attempt to enact new DKG authorities if sessions have changed - if header.number() <= &NumberFor::::from(1u32) { - debug!(target: "dkg", "Starting genesis DKG setup"); - self.enact_genesis_authorities(header); - } else { - self.enact_new_authorities(header); - } - // Send all outgoing messages - send_outgoing_dkg_messages(self); - // Get all unsigned proposals, create offline stages, attempt voting. - // Only do this if the public key is set on-chain. - if !self.get_dkg_pub_key(header).1.is_empty() { - self.create_offline_stages(header); - // Send outgoing messages after offline stage creation - send_outgoing_dkg_messages(self); - // Get all unsigned proposals and check if they are ready to be signed. - self.process_unsigned_proposals(header); - self.untrack_unsigned_proposals(header); + if self.get_dkg_pub_key(header).1.is_empty() { + self.maybe_enact_genesis_authorities(header); } else { - debug!(target: "dkg", "Public key not set on-chain, not creating offline stages {:?}", self.get_dkg_pub_key(header)); + self.maybe_enact_new_authorities(header); + self.submit_unsigned_proposals(header); } } - fn enact_genesis_authorities(&mut self, header: &B::Header) { + fn maybe_enact_genesis_authorities(&mut self, header: &B::Header) { // Get the active and queued validators to check for updates if let Some((active, queued)) = self.validator_set(header) { // If we are in the genesis state, we need to enact the genesis authorities @@ -599,64 +775,98 @@ where debug!(target: "dkg", "🕸️ GENESIS ROUND_ID {:?}", active.id); metric_set!(self, dkg_validator_set_id, active.id); // Setting new validator set id as current - self.current_validator_set = active.clone(); + *self.current_validator_set.write() = active.clone(); self.queued_validator_set = queued.clone(); // verify the new validator set let _ = self.verify_validator_set(header.number(), active.clone()); self.best_dkg_block = Some(*header.number()); + self.best_authorities = self.get_best_authorities(header); + self.best_next_authorities = self.get_next_best_authorities(header); // Setting up the DKG self.handle_genesis_dkg_setup(header, active); // Setting up the queued DKG at genesis self.handle_queued_dkg_setup(header, queued); - // Send outgoing messages after processing the queued DKG setup - send_outgoing_dkg_messages(self); } } } - fn enact_new_authorities(&mut self, header: &B::Header) { + fn maybe_enact_new_authorities(&mut self, header: &B::Header) { + debug!(target: "dkg", "🕸️ maybe_enact_new_authorities"); // Get the active and queued validators to check for updates if let Some((active, queued)) = self.validator_set(header) { - // If the active rounds have stalled, it means we haven't - // successfully generate a genesis key yet. Therefore, we - // continue to re-run keygen. - if let Some(rounds) = self.rounds.as_mut() { - if rounds.has_stalled() { - self.handle_genesis_dkg_setup(header, active.clone()); - } + let next_best = self.get_next_best_authorities(header); + let next_best_has_changed = next_best != self.best_next_authorities; + if next_best_has_changed && self.queued_validator_set.id == queued.id { + debug!(target: "dkg", "🕸️ Best authorities has changed on-chain\nOLD {:?}\nNEW: {:?}", self.best_next_authorities, next_best); + // Update the next best authorities + self.best_next_authorities = next_best; + // Start the queued DKG setup for the new queued authorities + self.handle_queued_dkg_setup(header, queued); + return } // If the next rounds have stalled, we restart similarly to above. - if let Some(rounds) = self.next_rounds.as_mut() { - if rounds.has_stalled() { - self.handle_queued_dkg_setup(header, queued.clone()); + if let Some(rounds) = self.next_rounds.clone() { + debug!(target: "dkg", "🕸️ Status: {:?}, Now: {:?}, Started At: {:?}, Timeout length: {:?}", rounds.status, header.number(), rounds.started_at, KEYGEN_TIMEOUT); + if rounds.keygen_is_not_complete() && + header.number() >= &(rounds.started_at + KEYGEN_TIMEOUT.into()) + { + debug!(target: "dkg", "🕸️ QUEUED DKG STALLED: round {:?}", queued.id); + return self.handle_dkg_error(DKGError::KeygenTimeout { + bad_actors: rounds.current_round_blame().blamed_parties, + }) + } else { + debug!(target: "dkg", "🕸️ QUEUED DKG NOT STALLED: round {:?}", queued.id); } } + + let queued_keygen_in_progress = + self.next_rounds.as_ref().map(|r| !r.is_keygen_finished()).unwrap_or(false); + + debug!(target: "dkg", "🕸️ QUEUED KEYGEN IN PROGRESS: {:?}", queued_keygen_in_progress); + debug!(target: "dkg", "🕸️ QUEUED DKG ID: {:?}", queued.id); + debug!(target: "dkg", "🕸️ QUEUED VALIDATOR SET ID: {:?}", self.queued_validator_set.id); + debug!(target: "dkg", "🕸️ QUEUED DKG STATUS: {:?}", self.next_rounds.as_ref().map(|r| r.status.clone())); // If the session has changed and a keygen is not in progress, we rotate - if self.queued_validator_set.id != queued.id && !self.queued_keygen_in_progress { + if self.queued_validator_set.id != queued.id && !queued_keygen_in_progress { debug!(target: "dkg", "🕸️ ACTIVE ROUND_ID {:?}", active.id); metric_set!(self, dkg_validator_set_id, active.id); - // Rotate the queued key file contents into the local key file if the next - // DKG public key signature has been posted on-chain. - let (set_id, _) = self.get_dkg_pub_key(header); - if set_id == queued.id - 1 { - debug!(target: "dkg", "🕸️ ROTATING LOCAL KEY FILE"); - self.rotate_local_key_files(); - // Rotate the rounds since the authority set has changed - self.rounds = self.next_rounds.take(); - } else { - debug!(target: "dkg", "🕸️ WAITING FOR NEXT DKG PUBLIC KEY SIG"); - } - // verify the new validator set let _ = self.verify_validator_set(header.number(), active.clone()); // Update the validator sets - self.current_validator_set = active; + *self.current_validator_set.write() = active; self.queued_validator_set = queued.clone(); + // Check the local keystore, if a queued key exists with the same + // round ID then we shouldn't rotate since it means we have shut down + // and started up after a previous rotation. + let (_, maybe_queued_key) = self.fetch_local_keys(); + match maybe_queued_key { + Some(queued_key) if queued_key.round_id == queued.id => { + debug!(target: "dkg", "🕸️ QUEUED KEY EXISTS: {:?}", queued_key.round_id); + debug!(target: "dkg", "🕸️ Queued local key exists at same round as queued validator set {:?}", queued.id); + return + }, + Some(k) => { + debug!(target: "dkg", "🕸️ QUEUED KEY EXISTS: {:?}", k.round_id); + debug!(target: "dkg", "🕸️ Queued local key exists at different round than queued validator set {:?}", queued.id); + }, + None => { + debug!(target: "dkg", "🕸️ QUEUED KEY DOES NOT EXIST"); + }, + }; + // If we are starting a new queued DKG, we rotate the next rounds + self.rounds = self.next_rounds.take(); + // We also rotate the best authority caches + self.best_authorities = self.best_next_authorities.clone(); + self.best_next_authorities = self.get_next_best_authorities(header); + // Rotate the key files + let success = self.rotate_local_key_files(); + debug!(target: "dkg", "🕸️ ROTATED LOCAL KEY FILES: {:?}", success); // Start the queued DKG setup for the new queued authorities self.handle_queued_dkg_setup(header, queued); - // Send outgoing messages after processing the queued DKG setup - send_outgoing_dkg_messages(self); } + } else { + // no queued validator set, so we don't do anything + debug!(target: "dkg", "🕸️ NO QUEUED VALIDATOR SET"); } } @@ -675,14 +885,27 @@ where fn verify_signature_against_authorities( &mut self, signed_dkg_msg: SignedDKGMessage, + ) -> Result, DKGError> { + Self::verify_signature_against_authorities_inner( + signed_dkg_msg, + &self.latest_header, + &self.client, + ) + } + + pub fn verify_signature_against_authorities_inner( + signed_dkg_msg: SignedDKGMessage, + latest_header: &Arc>>, + client: &Arc, ) -> Result, DKGError> { let dkg_msg = signed_dkg_msg.msg; let encoded = dkg_msg.encode(); let signature = signed_dkg_msg.signature.unwrap(); // Get authority accounts let mut authorities: Option<(Vec, Vec)> = None; - if let Some(header) = self.latest_header.as_ref() { - authorities = self.validator_set(header).map(|a| (a.0.authorities, a.1.authorities)); + if let Some(header) = latest_header.read().clone() { + authorities = Self::validator_set_inner(&header, client) + .map(|a| (a.0.authorities, a.1.authorities)); } if authorities.is_none() { @@ -711,63 +934,9 @@ where } } - fn process_incoming_dkg_message(&mut self, dkg_msg: DKGMessage) { - if let Some(rounds) = self.rounds.as_mut() { - if dkg_msg.round_id == rounds.get_id() { - let block_number = { - if self.latest_header.is_some() { - Some(*self.latest_header.as_ref().unwrap().number()) - } else { - None - } - }; - match rounds.handle_incoming(dkg_msg.payload.clone(), block_number) { - Ok(()) => (), - Err(err) => - debug!(target: "dkg", "🕸️ Error while handling DKG message {:?}", err), - } - - if rounds.is_keygen_finished() { - trace!(target: "dkg", "🕸️ DKG is ready to sign"); - self.dkg_state.accepted = true; - } - } - } - - if let Some(next_rounds) = self.next_rounds.as_mut() { - if next_rounds.get_id() == dkg_msg.round_id { - let block_number = { - if self.latest_header.is_some() { - Some(*self.latest_header.as_ref().unwrap().number()) - } else { - None - } - }; - - match next_rounds.handle_incoming(dkg_msg.payload.clone(), block_number) { - Ok(()) => {}, - Err(err) => - debug!(target: "dkg", "🕸️ Error while handling DKG message {:?}", err), - } - } - } - - match handle_public_key_broadcast(self, dkg_msg.clone()) { - Ok(()) => (), - Err(err) => error!(target: "dkg", "🕸️ Error while handling DKG message {:?}", err), - }; - - match handle_misbehaviour_report(self, dkg_msg) { - Ok(()) => (), - Err(err) => error!(target: "dkg", "🕸️ Error while handling DKG message {:?}", err), - }; - - send_outgoing_dkg_messages(self); - self.process_finished_rounds(); - } - pub fn handle_dkg_error(&mut self, dkg_error: DKGError) { - let authorities = self.current_validator_set.authorities.clone(); + log::error!(target: "dkg", "Received error: {:?}", dkg_error); + let authorities = self.current_validator_set.read().authorities.clone(); let bad_actors = match dkg_error { DKGError::KeygenMisbehaviour { ref bad_actors } => bad_actors.clone(), @@ -808,6 +977,77 @@ where } } + /// Route messages internally where they need to be routed + fn process_incoming_dkg_message(&mut self, dkg_msg: SignedDKGMessage) { + match &dkg_msg.msg.payload { + DKGMsgPayload::Keygen(..) => { + let msg = Arc::new(dkg_msg); + if let Some(rounds) = self.rounds.as_mut() { + if rounds.round_id == msg.msg.round_id { + if let Err(err) = rounds.deliver_message(msg.clone()) { + self.handle_dkg_error(DKGError::CriticalError { + reason: err.to_string(), + }) + } + } + } + + if let Some(rounds) = self.next_rounds.as_mut() { + if rounds.round_id == msg.msg.round_id { + if let Err(err) = rounds.deliver_message(msg) { + self.handle_dkg_error(DKGError::CriticalError { + reason: err.to_string(), + }) + } + } + } + }, + DKGMsgPayload::Offline(..) | DKGMsgPayload::Vote(..) => { + let msg = Arc::new(dkg_msg); + let async_index = msg.msg.payload.get_async_index(); + if let Some(rounds) = self.signing_rounds[async_index as usize].as_mut() { + if rounds.round_id == msg.msg.round_id { + if let Err(err) = rounds.deliver_message(msg) { + self.handle_dkg_error(DKGError::CriticalError { + reason: err.to_string(), + }) + } + } + } + }, + DKGMsgPayload::PublicKeyBroadcast(_) => { + match self.verify_signature_against_authorities(dkg_msg) { + Ok(dkg_msg) => { + match handle_public_key_broadcast(self, dkg_msg) { + Ok(()) => (), + Err(err) => + error!(target: "dkg", "🕸️ Error while handling DKG message {:?}", err), + }; + }, + + Err(err) => { + log::error!(target: "dkg", "Error while verifying signature against authorities: {:?}", err) + }, + } + }, + DKGMsgPayload::MisbehaviourBroadcast(_) => { + match self.verify_signature_against_authorities(dkg_msg) { + Ok(dkg_msg) => { + match handle_misbehaviour_report(self, dkg_msg) { + Ok(()) => (), + Err(err) => + error!(target: "dkg", "🕸️ Error while handling DKG message {:?}", err), + }; + }, + + Err(err) => { + log::error!(target: "dkg", "Error while verifying signature against authorities: {:?}", err) + }, + } + }, + } + } + fn handle_dkg_report(&mut self, dkg_report: DKGReport) { let (offender, round_id, misbehaviour_type) = match dkg_report { // Keygen misbehaviour possibly leads to keygen failure. This should be slashed @@ -815,7 +1055,7 @@ where DKGReport::KeygenMisbehaviour { offender } => { info!(target: "dkg", "🕸️ DKG Keygen misbehaviour by {}", offender); if let Some(rounds) = self.next_rounds.as_mut() { - (offender, rounds.get_id(), MisbehaviourType::Keygen) + (offender, rounds.round_id, MisbehaviourType::Keygen) } else { (offender, 0, MisbehaviourType::Keygen) } @@ -823,7 +1063,7 @@ where DKGReport::SigningMisbehaviour { offender } => { info!(target: "dkg", "🕸️ DKG Signing misbehaviour by {}", offender); if let Some(rounds) = self.rounds.as_mut() { - (offender, rounds.get_id(), MisbehaviourType::Sign) + (offender, rounds.round_id, MisbehaviourType::Sign) } else { (offender, 0, MisbehaviourType::Sign) } @@ -877,251 +1117,343 @@ where Ok(Public::from(maybe_signer.unwrap())) } - /// Generate a random delay to wait before taking an action. - /// The delay is generated from a random number between 0 and `max_delay`. - pub fn generate_delayed_submit_at( - &self, - start: NumberFor, - max_delay: u32, - ) -> Option<::Number> { - let mut rng = rand::thread_rng(); - let submit_at = start + rng.gen_range(0u32..=max_delay).into(); - Some(submit_at) - } + fn submit_unsigned_proposals(&mut self, header: &B::Header) { + let round_id = + if let Some(rounds) = self.rounds.as_ref() { rounds.round_id } else { return }; - /// Rounds handling + let at: BlockId = BlockId::hash(header.hash()); - fn process_finished_rounds(&mut self) { - if self.rounds.is_none() { + let maybe_party_index = self.get_party_index(header); + // Check whether the worker is in the best set or return + if maybe_party_index.is_none() { + info!(target: "dkg", "🕸️ NOT IN THE SET OF BEST AUTHORITIES: round {:?}", round_id); return + } else { + info!(target: "dkg", "🕸️ IN THE SET OF BEST AUTHORITIES: round {:?}", round_id); } - let mut proposals = Vec::new(); - for finished_round in self.rounds.as_mut().unwrap().get_finished_rounds() { - let proposal = self.handle_finished_round(finished_round); - if let Some(prop) = proposal { - proposals.push(prop) - }; - } - metric_set!( - self, - dkg_round_concluded, - self.rounds.as_mut().unwrap().get_finished_rounds().len() - ); - - save_signed_proposals_in_storage(self, proposals); - } - - fn handle_finished_round(&mut self, finished_round: DKGSignedPayload) -> Option { - trace!(target: "dkg", "Got finished round {:?}", finished_round); - let decoded_key = <(TypedChainId, DKGPayloadKey)>::decode(&mut &finished_round.key[..]); - let payload_key = match decoded_key { - Ok((_chain_id, key)) => key, - Err(_err) => return None, + let unsigned_proposals = match self.client.runtime_api().get_unsigned_proposals(&at) { + Ok(res) => res, + Err(_) => return, }; - get_signed_proposal(self, finished_round, payload_key) - } - - /// Get unsigned proposals and create offline stage using an encoded (ChainIdType, - /// DKGPayloadKey) as the round key - fn create_offline_stages(&mut self, header: &B::Header) { - if self.rounds.is_none() { + if unsigned_proposals.is_empty() { return + } else { + debug!(target: "dkg", "Got unsigned proposals count {}", unsigned_proposals.len()); } - let at: BlockId = BlockId::hash(header.hash()); - let unsigned_proposals = match self.client.runtime_api().get_unsigned_proposals(&at) { - Ok(res) => res, - Err(_) => return, + let best_authorities: Vec = + self.get_best_authorities(header).iter().map(|x| x.1.clone()).collect(); + let threshold = self.get_signature_threshold(header); + let authority_public_key = self.get_authority_public_key(); + + let (active_local_key, _) = self.fetch_local_keys(); + let local_key = if let Some(active_local_key) = active_local_key { + active_local_key.local_key + } else { + return }; - let rounds = self.rounds.as_mut().unwrap(); - let mut errors = Vec::new(); - if rounds.is_keygen_finished() { - // Current signers before resetting jailed signers - let signers_hashset = - rounds.signers.iter().cloned().collect::>(); - // Update jailed signers each time an offline stage is created - // This will trigger a regeneration of signing parties in hopes of - // both randomizing the set of signers as well as removing jailed - // signers after reported signing misbehaviour. - let at: BlockId = BlockId::hash(header.hash()); - let jailed_signers = self - .client - .runtime_api() - .get_signing_jailed(&at, rounds.authorities.clone()) - .unwrap_or_default(); - // Update the jailed signers which may mutate the signers set - rounds.set_jailed_signers(jailed_signers); - let new_signers_hashset = - rounds.signers.iter().cloned().collect::>(); - // Iterate through each unsigned proposal and create offline stages - for unsigned_proposals in &unsigned_proposals { - let key = (unsigned_proposals.typed_chain_id, unsigned_proposals.key); - if self.dkg_state.created_offlinestage_at.contains_key(&key.encode()) { - continue + let mut count = 0; + let mut seed = local_key.public_key().to_bytes(true)[1..].to_vec(); + + // Generate multiple signing sets for signing the same unsigned proposals. + // The goal is to successfully sign proposals immediately in the event that + // some authorities are not present. + // + // For example, if we have authorities: [1,2,3] and we only generate a single + // signing set (1,2), then if either party is absent, we will not be able to sign + // until we handle a misbehaviour. Instead, we brute force sign with multiple sets. + // For `n` authorities, to cover all signing sets of size `t+1`, we need to generate + // (n choose (t+1)) sets. + // + // Sets with the same values are not unique. We only care about all unique, unordered + // permutations of size `t+1`. i.e. (1,2), (2,3), (1,3) === (2,1), (3,2), (3,1) + let factorial = |num: u64| match num { + 0 => 1, + 1.. => (1..num + 1).product(), + }; + // TODO: Modify this to not blow up as n, t grow. + let mut signing_sets = Vec::new(); + let n = factorial(best_authorities.len() as u64); + let k = factorial((threshold + 1) as u64); + let n_minus_k = factorial((best_authorities.len() - threshold as usize - 1) as u64); + let num_combinations = std::cmp::min(n / (k * n_minus_k), MAX_SIGNING_SETS); + debug!(target: "dkg", "Generating {} signing sets", num_combinations); + while signing_sets.len() < num_combinations as usize { + if count > 0 { + seed = sp_core::keccak_256(&seed).to_vec(); + } + let maybe_set = self.generate_signers(&seed, threshold, best_authorities.clone()).ok(); + if let Some(set) = maybe_set { + let set = HashSet::::from_iter(set.iter().cloned()); + if !signing_sets.contains(&set) { + signing_sets.push(set); } + } - // If there are newly jailed signers we need to ensure we restart the offline stage - // process - if signers_hashset.difference(&new_signers_hashset).next().is_some() { - debug!(target: "dkg", "🕸️ FOUND INTERSECTION, REMOVING OLD OFFLINE STAGE\n{:?}\n{:?}", signers_hashset, new_signers_hashset); - rounds.offlines.remove(&key.encode()); - } + count += 1; + } - if let Err(e) = rounds.create_offline_stage(key.encode(), *header.number()) { - error!(target: "dkg", "Failed to create offline stage: {:?}", e); - errors.push(e); - } else { - // We note unsigned proposals for which we have started the offline stage - // to prevent overwriting running offline stages when next this function is - // called this function is called on every block import and the proposal - // might still be in the the unsigned proposals queue. - self.dkg_state.created_offlinestage_at.insert(key.encode(), *header.number()); + let mut futures = Vec::with_capacity(signing_sets.len()); + #[allow(clippy::needless_range_loop)] + for i in 0..signing_sets.len() { + // Filter for only the signing sets that contain our party index. + if signing_sets[i].contains(&maybe_party_index.unwrap()) { + log::info!(target: "dkg", "🕸️ Round Id {:?} | Async index {:?} | {}-out-of-{} signers: ({:?})", round_id, i, threshold, best_authorities.len(), signing_sets[i].clone()); + match self.create_signing_protocol( + best_authorities.clone(), + authority_public_key.clone(), + round_id, + threshold, + None, + ProtoStageType::Signing, + unsigned_proposals.clone(), + signing_sets[i].clone().into_iter().sorted().collect::>(), + i as u8, + ) { + Ok(task) => futures.push(task), + Err(err) => { + log::error!(target: "dkg", "Error creating signing protocol: {:?}", &err); + self.handle_dkg_error(err) + }, } } } - for e in errors { - self.handle_dkg_error(e); - } - } + if futures.is_empty() { + log::error!(target: "dkg", "While creating the signing protocol, 0 were created"); + } else { + // the goal of the meta task is to select the first winner + let meta_signing_protocol = async move { + // select the first future to return Ok(()), ignoring every failure + // (note: the errors are not truly ignored since each individual future + // has logic to handle errors internally, including misbehaviour monitors + let mut results = futures::future::select_ok(futures).await.into_iter(); + if let Some((_success, _losing_futures)) = results.next() { + log::info!(target: "dkg", "*** SUCCESSFULLY EXECUTED meta signing protocol {:?} ***", _success); + } else { + log::warn!(target: "dkg", "*** UNSUCCESSFULLY EXECUTED meta signing protocol"); + } + }; - // *** Proposals handling *** - /// When we create the offline stage we note that round key since the offline stage and voting - /// process could go on for a number of blocks while the proposal is still in the unsigned - /// proposal queue. The untrack interval is the number of blocks after which we expect the a - /// voting round to have reached completion for a proposal After this time elapses for a round - /// key we remove it from [dkg_state.created_offlinestage_at] since we expect that proposal to - /// have been signed and moved to the signed proposals queue already. - fn untrack_unsigned_proposals(&mut self, header: &B::Header) { - let keys = self.dkg_state.created_offlinestage_at.keys().cloned().collect::>(); - let _at: BlockId = BlockId::hash(header.hash()); - let current_block_number = *header.number(); - for key in keys { - let voted_at = self.dkg_state.created_offlinestage_at.get(&key).unwrap(); - let diff = current_block_number - *voted_at; - let untrack_interval = <::Header as Header>::Number::from( - dkg_runtime_primitives::UNTRACK_INTERVAL, - ); - - if diff >= untrack_interval { - self.dkg_state.created_offlinestage_at.remove(&key); - } + // spawn in parallel + let _handle = tokio::task::spawn(meta_signing_protocol); } } - fn process_unsigned_proposals(&mut self, header: &B::Header) { - if self.rounds.is_none() { - return + /// After keygen, this should be called to generate a random set of signers + /// NOTE: since the random set is called using a deterministic seed to and RNG, + /// the resulting set is deterministic + fn generate_signers( + &self, + seed: &[u8], + t: u16, + best_authorities: Vec, + ) -> Result, DKGError> { + let mut final_set = self.get_unjailed_signers(&best_authorities)?; + // Mutate the final set if we don't have enough unjailed signers + if final_set.len() <= t as usize { + let jailed_set = self.get_jailed_signers(&best_authorities)?; + let diff = t as usize + 1 - final_set.len(); + final_set = final_set + .iter() + .chain(jailed_set.iter().take(diff)) + .cloned() + .collect::>(); } - let latest_block_num = self.get_latest_block_number(); - let at: BlockId = BlockId::hash(header.hash()); - let unsigned_proposals = match self.client.runtime_api().get_unsigned_proposals(&at) { - Ok(res) => res, - Err(_) => return, - }; - - debug!(target: "dkg", "Got unsigned proposals count {}", unsigned_proposals.len()); - let rounds = self.rounds.as_mut().unwrap(); - let mut errors = Vec::new(); - for unsigned_proposal in unsigned_proposals { - let key = (unsigned_proposal.typed_chain_id, unsigned_proposal.key); - if !rounds.is_ready_to_vote(key.encode()) { - continue - } + select_random_set(seed, final_set, t + 1).map_err(|err| DKGError::CreateOfflineStage { + reason: format!("generate_signers failed, reason: {}", err), + }) + } - debug!(target: "dkg", "Got unsigned proposal with key = {:?}", &key); - if let Proposal::Unsigned { kind: _, data } = unsigned_proposal.proposal { - if let Err(e) = rounds.vote(key.encode(), data, latest_block_num) { - error!(target: "dkg", "🕸️ error creating new vote: {}", e); - errors.push(e); - } else { - self.votes_sent += 1; - }; - } - } - // Handle all errors - for e in errors { - self.handle_dkg_error(e); - } - // Votes sent to the DKG are unsigned proposals - metric_set!(self, dkg_votes_sent, self.votes_sent); + fn get_jailed_signers_inner( + &self, + best_authorities: &[Public], + ) -> Result, DKGError> { + let now = self.latest_header.read().clone().ok_or_else(|| DKGError::CriticalError { + reason: "latest header does not exist!".to_string(), + })?; + let at: BlockId = BlockId::hash(now.hash()); + Ok(self + .client + .runtime_api() + .get_signing_jailed(&at, best_authorities.to_vec()) + .unwrap_or_default()) + } + fn get_unjailed_signers(&self, best_authorities: &[Public]) -> Result, DKGError> { + let jailed_signers = self.get_jailed_signers_inner(best_authorities)?; + Ok(best_authorities + .iter() + .enumerate() + .filter(|(_, key)| !jailed_signers.contains(key)) + .map(|(i, _)| u16::try_from(i + 1).unwrap_or_default()) + .collect()) + } - // Send messages to all peers - send_outgoing_dkg_messages(self); + /// Get the jailed signers + fn get_jailed_signers(&self, best_authorities: &[Public]) -> Result, DKGError> { + let jailed_signers = self.get_jailed_signers_inner(best_authorities)?; + Ok(best_authorities + .iter() + .enumerate() + .filter(|(_, key)| jailed_signers.contains(key)) + .map(|(i, _)| u16::try_from(i + 1).unwrap_or_default()) + .collect()) } // *** Main run loop *** + /// Wait for initial block import + async fn initialization(&mut self) { + use futures::future; + self.client + .import_notification_stream() + .take_while(|notif| { + if let Some((active, queued)) = self.validator_set(¬if.header) { + // TODO: Consider caching this data and loading it here. + self.best_authorities = self.get_best_authorities(¬if.header); + self.best_next_authorities = self.get_next_best_authorities(¬if.header); + *self.current_validator_set.write() = active; + self.queued_validator_set = queued; + // Route this to the import notification handler + self.handle_import_notification(notif.clone()); + log::debug!(target: "dkg", "Initialization complete"); + future::ready(false) + } else { + future::ready(true) + } + }) + .for_each(|_| future::ready(())) + .await; + // get a new stream that provides _new_ notifications (from here on out) + self.import_notifications = self.client.import_notification_stream(); + } + pub(crate) async fn run(mut self) { - let mut dkg = - Box::pin(self.gossip_engine.lock().messages_for(dkg_topic::()).filter_map( - |notification| async move { - SignedDKGMessage::::decode(&mut ¬ification.message[..]).ok() - }, - )); + let mut dkg = self.gossip_engine.stream(); + let (misbehaviour_tx, mut misbehaviour_rx) = tokio::sync::mpsc::unbounded_channel(); + self.misbehaviour_tx = Some(misbehaviour_tx); - loop { - let engine = self.gossip_engine.clone(); - let gossip_engine = future::poll_fn(|cx| engine.lock().poll_unpin(cx)); + let mut error_handler_rx = self.error_handler_rx.take().unwrap(); - futures::select! { + self.initialization().await; + log::debug!(target: "dkg", "Starting DKG Iteration loop"); + loop { + tokio::select! { notification = self.finality_notifications.next().fuse() => { if let Some(notification) = notification { + log::debug!(target: "dkg", "Going to handle Finality notification"); self.handle_finality_notification(notification); } else { - return; + log::error!("Finality notification stream closed"); + break; } }, notification = self.import_notifications.next().fuse() => { if let Some(notification) = notification { + log::debug!(target: "dkg", "Going to handle Import notification"); self.handle_import_notification(notification); } else { - return; + log::error!("Import notification stream closed"); + break; } }, + + misbehaviour_msg = misbehaviour_rx.recv().fuse() => { + if let Some(msg) = misbehaviour_msg { + log::debug!(target: "dkg", "Going to gossip misbehaviour"); + gossip_misbehaviour_report(&mut self, msg) + } else { + log::error!("Misbehaviour channel closed"); + break; + } + } + + error = error_handler_rx.recv().fuse() => { + if let Some(error) = error { + log::debug!(target: "dkg", "Going to handle dkg error"); + self.handle_dkg_error(error) + } else { + log::error!("DKG Error channel closed"); + break; + } + }, + dkg_msg = dkg.next().fuse() => { if let Some(dkg_msg) = dkg_msg { - if self.current_validator_set.authorities.is_empty() || self.queued_validator_set.authorities.is_empty() { - self.msg_cache.push(dkg_msg); - } else { - let msgs = self.msg_cache.clone(); - for msg in msgs { - match self.verify_signature_against_authorities(msg) { - Ok(raw) => { - trace!(target: "dkg", "🕸️ Got a cached message from gossip engine: ({:?} bytes)", raw.encoded_size()); - self.process_incoming_dkg_message(raw); - }, - Err(e) => { - error!(target: "dkg", "🕸️ Received signature error {:?}", e); - } - } - } - - match self.verify_signature_against_authorities(dkg_msg) { - Ok(raw) => { - trace!(target: "dkg", "🕸️ Got message from gossip engine: ({:?} bytes)", raw.encoded_size()); - self.process_incoming_dkg_message(raw); - }, - Err(e) => { - error!(target: "dkg", "🕸️ Received signature error {:?}", e); - } - } - // Reset the cache - self.msg_cache = Vec::new(); - } + log::debug!(target: "dkg", "Going to handle dkg message"); + self.process_incoming_dkg_message(dkg_msg); } else { - return; + log::error!("DKG stream closed"); + break; } }, - _ = gossip_engine.fuse() => { - error!(target: "dkg", "🕸️ Gossip engine has terminated."); - return; - } } } + + log::info!(target: "dkg", "DKG Iteration loop finished"); + } +} + +/// Extension trait for any type that contains a keystore +#[auto_impl::auto_impl(&mut, &, Arc)] +pub trait KeystoreExt { + fn get_keystore(&self) -> &DKGKeystore; + fn get_authority_public_key(&self) -> Public { + self.get_keystore() + .authority_id(&self.get_keystore().public_keys().unwrap()) + .unwrap_or_else(|| panic!("Could not find authority public key")) + } + + fn get_sr25519_public_key(&self) -> sp_core::sr25519::Public { + self.get_keystore() + .sr25519_public_key(&self.get_keystore().sr25519_public_keys().unwrap_or_default()) + .unwrap_or_else(|| panic!("Could not find sr25519 key in keystore")) + } +} + +impl KeystoreExt for DKGWorker +where + B: Block, + BE: Backend, + GE: GossipEngineIface, + C: Client, +{ + fn get_keystore(&self) -> &DKGKeystore { + &self.key_store + } +} + +impl KeystoreExt for DKGKeystore { + fn get_keystore(&self) -> &DKGKeystore { + self + } +} + +#[auto_impl::auto_impl(&mut, &, Arc)] +pub trait HasLatestHeader { + fn get_latest_header(&self) -> &Arc>>; + /// Gets latest block number from latest block header + fn get_latest_block_number(&self) -> NumberFor { + if let Some(latest_header) = self.get_latest_header().read().clone() { + *latest_header.number() + } else { + NumberFor::::from(0u32) + } + } +} + +impl HasLatestHeader for DKGWorker +where + B: Block, + BE: Backend, + GE: GossipEngineIface, + C: Client, +{ + fn get_latest_header(&self) -> &Arc>> { + &self.latest_header } } diff --git a/dkg-primitives/Cargo.toml b/dkg-primitives/Cargo.toml index d503b2586..f3e4159e3 100644 --- a/dkg-primitives/Cargo.toml +++ b/dkg-primitives/Cargo.toml @@ -15,7 +15,7 @@ sha3 = "0.9" hex = "0.4" serde_json = "1.0" -codec = { version = "2.0.0", package = "parity-scale-codec", features = ["derive"] } +codec = { version = "3", package = "parity-scale-codec", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } rand = "0.8.4" chacha20poly1305 = "0.9.0" @@ -23,16 +23,16 @@ typed-builder = "0.9.1" curv = { package = "curv-kzen", version = "0.9", default-features = false } -round-based = { version = "0.1.4", features = [] } +round-based = { version = "0.1.7", features = [] } multi-party-ecdsa = { git = "https://github.com/webb-tools/multi-party-ecdsa.git" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } dkg-runtime-primitives = { path = "../dkg-runtime-primitives" } -sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } [dev-dependencies] -sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } [features] diff --git a/dkg-primitives/src/lib.rs b/dkg-primitives/src/lib.rs index 4503b53a5..f790fa8f8 100644 --- a/dkg-primitives/src/lib.rs +++ b/dkg-primitives/src/lib.rs @@ -13,7 +13,6 @@ // limitations under the License. // pub mod keys; -pub mod rounds; pub mod types; pub mod utils; diff --git a/dkg-primitives/src/rounds/dkg.rs b/dkg-primitives/src/rounds/dkg.rs deleted file mode 100644 index 6e4df9567..000000000 --- a/dkg-primitives/src/rounds/dkg.rs +++ /dev/null @@ -1,825 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use curv::{arithmetic::Converter, elliptic::curves::Secp256k1, BigInt}; -use log::{debug, error, info, trace, warn}; - -use sp_runtime::traits::AtLeast32BitUnsigned; -use std::{collections::HashMap, path::PathBuf}; - -use super::{keygen::*, offline::*, sign::*}; -use std::mem; -use typed_builder::TypedBuilder; - -use crate::{types::*, utils::select_random_set}; -use dkg_runtime_primitives::{crypto::AuthorityId, keccak_256}; - -pub use gg_2020::{ - party_i::*, - state_machine::{keygen::*, sign::*}, -}; -pub use multi_party_ecdsa::protocols::multi_party_ecdsa::{ - gg_2020, - gg_2020::state_machine::{keygen as gg20_keygen, sign as gg20_sign, traits::RoundBlame}, -}; - -/// DKG State tracker -pub struct DKGState -where - C: AtLeast32BitUnsigned + Copy, -{ - pub accepted: bool, - pub listening_for_pub_key: bool, - pub listening_for_active_pub_key: bool, - pub created_offlinestage_at: HashMap, C>, -} - -/// State machine structure for performing Keygen, Offline stage and Sign rounds -/// HashMap and BtreeMap keys are encoded formats of (ChainIdType, DKGPayloadKey) -/// Using DKGPayloadKey only will cause collisions when proposals with the same nonce but from -/// different chains are submitted -/// -/// Each of KeygenState, OfflineState and SignState is an enum of several sub-states. -/// All of them implement DKGRoundsSM trait for conveniece, but otherwise allow to be -/// pattern-matched to access internal state defined in keygen.rs, offline.rs, sing.rs. -/// -/// They all share similar pattern of enum cases, where: -/// 1. NotStarted - is meant to only collect incoming messages in case some other party -/// has started earlier than us and already sent some messages. -/// 2. Started - sub-state is essentially the wrapper around corresponding -/// multi-party-ecdsa's state machine (Keygen, OfflineStage, SignManual) -/// 3. Finished - final sub-state with either execution result or error. -/// 4. Empty - special case for Keygen is a workaround to avoid using Option for self.keygen. -#[derive(TypedBuilder)] -pub struct MultiPartyECDSARounds -where - Clock: AtLeast32BitUnsigned + Copy, -{ - round_id: RoundId, - party_index: u16, - threshold: u16, - parties: u16, - - // Key generation - #[builder(default=KeygenState::NotStarted(PreKeygenRounds::new()))] - keygen: KeygenState, - #[builder(default = false)] - has_stalled: bool, - - // Signing - #[builder(default)] - pub signers: Vec, - #[builder(default)] - pub offlines: HashMap, OfflineState>, - #[builder(default)] - votes: HashMap, SignState>, - - // File system storage and encryption - #[builder(default)] - local_key_path: Option, - - // Authorities - #[builder(default)] - pub authorities: Vec, - // Jailed signing authorities - #[builder(default)] - jailed_signers: Vec, -} - -impl MultiPartyECDSARounds -where - C: AtLeast32BitUnsigned + Copy, -{ - pub fn get_local_key_path(&self) -> Option { - self.local_key_path.clone() - } - - pub fn set_local_key(&mut self, local_key: LocalKey) { - self.keygen = KeygenState::Finished(Ok(local_key)); - } - - pub fn set_signers(&mut self, signers: Vec) { - self.signers = signers; - } - - pub fn set_jailed_signers(&mut self, jailed_signers: Vec) { - self.jailed_signers = jailed_signers; - - match &self.keygen { - KeygenState::Finished(Ok(local_key)) => { - if let Ok(signer_set) = self.generate_signers(&local_key.clone()) { - self.signers = signer_set; - } - }, - _ => { - error!(target: "dkg", "set_jailed_signers called before local_key is set"); - }, - } - } - - pub fn is_signer(&self) -> bool { - self.signers.contains(&self.party_index) - } - - pub fn dkg_params(&self) -> (u16, u16, u16) { - (self.party_index, self.threshold, self.parties) - } - - pub fn get_public_key(&self) -> Option { - match &self.keygen { - KeygenState::Finished(Ok(local_key)) => Some(local_key.public_key()), - _ => None, - } - } - - pub fn get_id(&self) -> RoundId { - self.round_id - } - - /// A check to know if the protocol has stalled at the keygen stage, - /// We take it that the protocol has stalled if keygen messages are not received from other - /// peers after a certain interval And the keygen stage has not completed. - pub fn has_stalled(&self) -> bool { - self.has_stalled - } - - /// State machine - - /// Tries to proceed and make state transition if necessary for: - /// 1. KeygenState if keygen is still in progress - /// 2. Every OfflineState in self.offlines map - /// 3. Every SignState in self.votes map - /// - /// If the keygen is finished, we extract the `local_key` and set its - /// state to `KeygenState::Finished`. We decide on the signing set - /// when the `local_key` is extracted. - pub fn proceed(&mut self, at: C) -> Vec> { - trace!(target: "dkg", - "🕸️ State before proceed:\n round_id: {:?}\n signers: {:?}", - &self.round_id, &self.signers); - - let mut results = vec![]; - - let keygen_proceed_res = self.keygen.proceed(at); - if keygen_proceed_res.is_err() { - if let Err(DKGError::KeygenTimeout { bad_actors }) = &keygen_proceed_res { - error!(target: "dkg", "🕸️ Keygen timeout: {:?}", bad_actors); - self.has_stalled = true; - } - results.push(keygen_proceed_res.map(|_| DKGResult::Empty)); - } else if self.keygen.is_finished() { - let prev_state = mem::replace(&mut self.keygen, KeygenState::Empty); - self.keygen = match prev_state { - KeygenState::Started(rounds) => { - let finish_result = rounds.try_finish(); - if let Ok(local_key) = &finish_result { - if let Ok(signers_set) = self.generate_signers(local_key) { - self.set_signers(signers_set); - debug!("Party {}, new signers: {:?}", self.party_index, &self.signers); - } - - results.push(Ok(DKGResult::KeygenFinished { - round_id: self.round_id, - local_key: Box::new(local_key.clone()), - })); - } - KeygenState::Finished(finish_result) - }, - _ => prev_state, - }; - } - - let offline_keys = self.offlines.keys().cloned().collect::>(); - for key in offline_keys { - if let Some(mut offline) = self.offlines.remove(&key.clone()) { - let res = offline.proceed(at); - if res.is_err() { - results.push(res.map(|_| DKGResult::Empty)); - } - let next_state = if offline.is_finished() { - match offline { - OfflineState::Started(rounds) => - OfflineState::Finished(rounds.try_finish()), - _ => offline, - } - } else { - offline - }; - self.offlines.insert(key.clone(), next_state); - } - } - - let vote_keys = self.votes.keys().cloned().collect::>(); - for key in vote_keys { - if let Some(mut vote) = self.votes.remove(&key.clone()) { - let res = vote.proceed(at); - if res.is_err() { - results.push(res.map(|_| DKGResult::Empty)); - } - let next_state = if vote.is_finished() { - match vote { - SignState::Started(rounds) => SignState::Finished(rounds.try_finish()), - _ => vote, - } - } else { - vote - }; - self.votes.insert(key.clone(), next_state); - } - } - - results - } - - /// Collects and returns outgoing messages from - /// KeygenState, every OfflineState and every SignState. - pub fn get_outgoing_messages(&mut self) -> Vec { - trace!(target: "dkg", "🕸️ Get outgoing messages"); - - let mut all_messages: Vec = - self.keygen.get_outgoing().into_iter().map(DKGMsgPayload::Keygen).collect(); - - let offline_messages = self - .offlines - .values_mut() - .map(|s| s.get_outgoing()) - .fold(Vec::new(), |mut acc, x| { - acc.extend(x); - acc - }) - .into_iter() - .map(DKGMsgPayload::Offline) - .collect::>(); - - let vote_messages = self - .votes - .values_mut() - .map(|s| s.get_outgoing()) - .fold(Vec::new(), |mut acc, x| { - acc.extend(x); - acc - }) - .into_iter() - .map(DKGMsgPayload::Vote) - .collect::>(); - - all_messages.extend_from_slice(&offline_messages[..]); - all_messages.extend_from_slice(&vote_messages[..]); - - all_messages - } - - /// Depending on the DKGMsgPayload type, dispatches the message to: - /// 1. KeygenState - /// 2. OfflineState with the key corresponding to the one in the payload - /// 3. SignState with the key corresponding to the one in the payload - /// - /// If no OfflineState or SignState with the key in the payload is present in the corresponding - /// map, a new entry with initial state is created (OfflineState::NotStarted or - /// SignState::NotStarted) - pub fn handle_incoming(&mut self, data: DKGMsgPayload, at: Option) -> Result<(), DKGError> { - trace!(target: "dkg", "🕸️ Handle incoming"); - - return match data { - DKGMsgPayload::Keygen(msg) => self.keygen.handle_incoming( - msg, - at.or_else(|| Some(0u32.into())) - .unwrap_or_else(|| panic!("There are no incoming messages for key gen")), - ), - DKGMsgPayload::Offline(msg) => { - let key = msg.key.clone(); - - let offline = self - .offlines - .entry(key.clone()) - .or_insert_with(|| OfflineState::NotStarted(PreOfflineRounds::new())); - - let res = offline.handle_incoming( - msg, - at.or_else(|| Some(0u32.into())) - .unwrap_or_else(|| panic!("There are no incoming messages for offline")), - ); - if let Err(DKGError::CriticalError { reason: _ }) = res { - self.offlines.remove(&key); - } - res - }, - DKGMsgPayload::Vote(msg) => { - let key = msg.round_key.clone(); - // Get the `SignState` or create a new one for this vote (a threshold signature). - let vote = self - .votes - .entry(key.clone()) - .or_insert_with(|| SignState::NotStarted(PreSignRounds::new())); - - let res = vote.handle_incoming( - msg, - at.or_else(|| Some(0u32.into())) - .unwrap_or_else(|| panic!("There are no incoming messages for voting")), - ); - if let Err(DKGError::CriticalError { reason: _ }) = res { - self.votes.remove(&key); - } - res - }, - _ => Ok(()), - } - } - - /// Starts keygen process for the current party. - /// All incoming keygen messages collected so far will be proccessed immediately. - pub fn start_keygen(&mut self, started_at: C) -> Result<(), DKGError> { - info!( - target: "dkg", - "🕸️ Starting new DKG w/ party_index {:?}, threshold {:?}, size {:?}", - self.party_index, - self.threshold, - self.parties, - ); - - let keygen_params = self.keygen_params(); - - self.keygen = match mem::replace(&mut self.keygen, KeygenState::Empty) { - KeygenState::NotStarted(pre_keygen) => { - match Keygen::new(self.party_index, self.threshold, self.parties) { - Ok(new_keygen) => { - let mut keygen = KeygenState::Started(KeygenRounds::new( - keygen_params, - started_at, - new_keygen, - )); - - // Processing pending messages - if let Ok(pending_keygen_msgs) = pre_keygen.try_finish() { - for msg in pending_keygen_msgs.clone() { - if let Err(err) = keygen.handle_incoming(msg, started_at) { - warn!(target: "dkg", "🕸️ Error handling pending keygen msg {:?}", err); - } - keygen.proceed(started_at)?; - } - trace!(target: "dkg", "🕸️ Handled {} pending keygen messages", &pending_keygen_msgs.len()); - } - keygen - }, - Err(err) => return Err(DKGError::StartKeygen { reason: err.to_string() }), - } - }, - _ => return Err(DKGError::StartKeygen { reason: "Already started".to_string() }), - }; - - Ok(()) - } - - /// Starts new offline stage for the provided key. - /// All of the messages collected so far for this key will be processed immediately. - pub fn create_offline_stage(&mut self, key: Vec, started_at: C) -> Result<(), DKGError> { - let sign_params = self.sign_params(); - // Get the offline index in the signer set (different than the party index). - let offline_i = match self.get_offline_stage_index() { - Some(i) => { - debug!(target: "dkg", "🕸️ Creating offline stage for {:?} with signers {:?}", &key, &self.signers); - i - }, - None => { - debug!(target: "dkg", "🕸️ We are not among signers, skipping"); - return Ok(()) - }, - }; - - match &self.keygen { - KeygenState::Finished(Ok(local_key)) => - return match OfflineStage::new(offline_i, self.signers.clone(), local_key.clone()) { - Ok(new_offline_stage) => { - let offline = self - .offlines - .entry(key.clone()) - .or_insert_with(|| OfflineState::NotStarted(PreOfflineRounds::new())); - - match offline { - OfflineState::NotStarted(pre_offline) => { - let mut new_offline = OfflineState::Started(OfflineRounds::new( - sign_params, - started_at, - key.clone(), - new_offline_stage, - )); - - for msg in pre_offline.pending_offline_msgs.clone() { - if let Err(err) = new_offline.handle_incoming(msg, started_at) { - warn!(target: "dkg", "🕸️ Error handling pending offline msg {:?}", err); - } - new_offline.proceed(started_at)?; - } - trace!(target: "dkg", "🕸️ Handled pending offline messages for {:?}", key); - - self.offlines.insert(key, new_offline); - - Ok(()) - }, - _ => Err(DKGError::CreateOfflineStage { - reason: "Already started".to_string(), - }), - } - }, - Err(err) => { - error!("Error creating new offline stage {}", err); - Err(DKGError::CreateOfflineStage { reason: err.to_string() }) - }, - }, - _ => Err(DKGError::CreateOfflineStage { - reason: "Cannot start offline stage, Keygen is not complete".to_string(), - }), - } - } - - /// Starts new signing process for the provided key. - /// All of the messages collected so far for this key will be processed immediately. - pub fn vote( - &mut self, - round_key: Vec, - data: Vec, - started_at: C, - ) -> Result<(), DKGError> { - // Check if we are in the signer set - if self.get_offline_stage_index().is_none() { - trace!(target: "dkg", "🕸️ We are not among signers, skipping"); - return Ok(()) - } - - if let Some(OfflineState::Finished(Ok(completed_offline))) = - self.offlines.remove(&round_key) - { - let hash = BigInt::from_bytes(&keccak_256(&data)); - - let sign_params = self.sign_params(); - - match SignManual::new(hash, completed_offline) { - Ok((sign_manual, sig)) => { - debug!(target: "dkg", "🕸️ Creating vote w/ key {:?}", &round_key); - - let vote = self - .votes - .entry(round_key.clone()) - .or_insert_with(|| SignState::NotStarted(PreSignRounds::new())); - - match vote { - SignState::NotStarted(pre_sign) => { - let mut new_sign = SignState::Started(SignRounds::new( - sign_params, - started_at, - data, - round_key.clone(), - sig, - sign_manual, - )); - - for msg in pre_sign.pending_sign_msgs.clone() { - if let Err(err) = new_sign.handle_incoming(msg, started_at) { - warn!(target: "dkg", "🕸️ Error handling pending vote msg {:?}", err); - } - new_sign.proceed(started_at)?; - } - debug!(target: "dkg", "🕸️ Handled pending vote messages for {:?}", round_key); - - self.votes.insert(round_key.clone(), new_sign); - - Ok(()) - }, - _ => Err(DKGError::Vote { reason: "Already started".to_string() }), - } - }, - Err(err) => Err(DKGError::Vote { reason: err.to_string() }), - } - } else { - Err(DKGError::Vote { reason: "Not ready to vote".to_string() }) - } - } - - pub fn is_keygen_in_progress(&self) -> bool { - !matches!(self.keygen, KeygenState::Finished(_)) - } - - pub fn is_keygen_finished(&self) -> bool { - matches!(self.keygen, KeygenState::Finished(_)) - } - - pub fn is_ready_to_vote(&self, round_key: Vec) -> bool { - matches!(self.offlines.get(&round_key), Some(OfflineState::Finished(Ok(_)))) - } - - pub fn has_vote_in_process(&self, round_key: Vec) -> bool { - self.votes.contains_key(&round_key) - } - - pub fn has_finished_rounds(&self) -> bool { - let finished = self.votes.values().filter(|v| matches!(v, SignState::Finished(_))).count(); - - finished > 0 - } - - pub fn get_finished_rounds(&mut self) -> Vec { - let mut finished: Vec = vec![]; - - let vote_keys = self.votes.keys().cloned().collect::>(); - for key in vote_keys { - if let Some(vote) = self.votes.remove(&key.clone()) { - if vote.is_finished() { - match vote { - SignState::Finished(Ok(signed_payload)) => { - finished.push(signed_payload); - }, - _ => { - self.votes.insert(key.clone(), vote); - }, - } - } else { - self.votes.insert(key.clone(), vote); - }; - } - } - - finished - } - - /// Utils - - /// Returns our party's index in signers vec if any. - /// Indexing starts from 1. - /// OfflineStage must be created using this index if present (not the original keygen index) - fn get_offline_stage_index(&self) -> Option { - for (i, &keygen_i) in (1..).zip(&self.signers) { - if self.party_index == keygen_i { - return Some(i) - } - } - None - } - - /// Get the unjailed signers - pub fn get_unjailed_signers(&self) -> Vec { - self.authorities - .iter() - .enumerate() - .filter(|(_, key)| !self.jailed_signers.contains(key)) - .map(|(i, _)| u16::try_from(i + 1).unwrap_or_default()) - .collect() - } - - /// Get the jailed signers - pub fn get_jailed_signers(&self) -> Vec { - self.authorities - .iter() - .enumerate() - .filter(|(_, key)| self.jailed_signers.contains(key)) - .map(|(i, _)| u16::try_from(i + 1).unwrap_or_default()) - .collect() - } - - /// Generates the signer set by randomly selecting t+1 signers - /// to participate in the signing protocol. We set the signers in the local - /// storage once selected. - pub fn generate_signers( - &self, - local_key: &LocalKey, - ) -> Result, &'static str> { - let (_, threshold, parties) = self.dkg_params(); - // Select the random subset using the local key as a seed - let seed = &local_key.clone().public_key().to_bytes(true)[1..]; - let mut final_set = self.get_unjailed_signers(); - // Mutate the final set if we don't have enough unjailed signers - if final_set.len() <= threshold.into() { - let jailed_set = self.get_jailed_signers(); - let diff = usize::from(threshold) + 1 - final_set.len(); - final_set = final_set - .iter() - .chain(jailed_set.iter().take(diff)) - .cloned() - .collect::>(); - } - - select_random_set(seed, final_set, threshold + 1).map(|set| { - info!(target: "dkg", "🕸️ Round Id {:?} | {}-out-of-{} signers: ({:?})", self.round_id, threshold, parties, set); - set - }) - } - - fn keygen_params(&self) -> KeygenParams { - KeygenParams { - round_id: self.round_id, - party_index: self.party_index, - threshold: self.threshold, - parties: self.parties, - } - } - - fn sign_params(&self) -> SignParams { - // TODO: Currently we use round_id as signer_set_id for consistency, - // but eventually we want to derive this id from both round_id and signers vec - SignParams { - round_id: self.round_id, - party_index: self.party_index, - threshold: self.threshold, - parties: self.parties, - signers: self.signers.clone(), - signer_set_id: self.round_id, - } - } -} - -#[cfg(test)] -mod tests { - use super::{KeygenState, MultiPartyECDSARounds}; - use codec::Encode; - #[allow(clippy::ptr_arg)] - fn check_all_parties_have_public_key(parties: &Vec>) { - for party in parties.iter() { - if party.get_public_key().is_none() { - panic!("No public key for party {}", party.party_index) - } - } - } - - #[allow(clippy::ptr_arg)] - fn check_all_reached_offline_ready(parties: &Vec>) -> bool { - for party in parties.iter() { - match &party.keygen { - KeygenState::Finished(_) => (), - _ => return false, - } - } - true - } - - #[allow(clippy::ptr_arg)] - fn check_all_reached_manual_ready(parties: &Vec>) -> bool { - let round_key = 1u32.encode(); - for party in parties.iter() { - if party.is_signer() && !party.is_ready_to_vote(round_key.clone()) { - return false - } - } - true - } - - #[allow(clippy::ptr_arg)] - fn check_all_signatures_ready(parties: &Vec>) -> bool { - for party in parties.iter() { - if party.is_signer() && !party.has_finished_rounds() { - return false - } - } - true - } - - fn check_all_signatures_correct(parties: &mut Vec>) { - for party in &mut parties.iter_mut() { - if party.is_signer() { - let mut finished_rounds = party.get_finished_rounds(); - - if finished_rounds.len() == 1 { - let finished_round = finished_rounds.remove(0); - - let message = b"Webb".encode(); - - assert!( - dkg_runtime_primitives::utils::validate_ecdsa_signature( - &message, - &finished_round.signature - ), - "Invalid signature for party {}", - party.party_index - ); - - println!("Party {}; sig: {:?}", party.party_index, &finished_round.signature); - } else { - panic!("No signature extracted") - } - } - } - - println!("All signatures are correct"); - } - - fn run_simulation(parties: &mut Vec>, stop_condition: C) - where - C: Fn(&Vec>) -> bool, - { - println!("Simulation starts"); - - let mut msgs_pull = vec![]; - - for party in &mut parties.iter_mut() { - let proceed_res = party.proceed(0); - for res in proceed_res { - if let Err(err) = res { - println!("Error: {:?}", err); - } - } - - msgs_pull.append(&mut party.get_outgoing_messages()); - } - - for _i in 1..100 { - let msgs_pull_frozen = msgs_pull.split_off(0); - - for party in &mut parties.iter_mut() { - for msg_frozen in msgs_pull_frozen.iter() { - match party.handle_incoming(msg_frozen.clone(), None) { - Ok(()) => (), - Err(err) => panic!("{:?}", err), - } - } - msgs_pull.append(&mut party.get_outgoing_messages()); - } - - for party in &mut parties.iter_mut() { - let proceed_res = party.proceed(0); - for res in proceed_res { - if let Err(err) = res { - println!("Error: {:?}", err); - } - } - - msgs_pull.append(&mut party.get_outgoing_messages()); - } - - if stop_condition(parties) { - println!("All parties finished"); - return - } - } - - panic!("Not all parties finished"); - } - - fn simulate_multi_party(t: u16, n: u16) { - let mut parties: Vec> = vec![]; - let round_key = 1u32.encode(); - for i in 1..=n { - let mut party = MultiPartyECDSARounds::builder() - .round_id(0) - .party_index(i) - .threshold(t) - .parties(n) - .build(); - println!("Starting keygen for party {}", party.party_index); - party - .start_keygen(0) - .unwrap_or_else(|_| panic!("Could not start keygen for party")); - parties.push(party); - } - - // Running Keygen stage - println!("Running Keygen"); - run_simulation(&mut parties, check_all_reached_offline_ready); - check_all_parties_have_public_key(&parties); - - // Running Offline stage - println!("Running Offline"); - let parties_refs = &mut parties; - for party in parties_refs.iter_mut() { - println!("Creating offline stage"); - match party.create_offline_stage(round_key.clone(), 0) { - Ok(()) => (), - Err(_err) => (), - } - } - run_simulation(&mut parties, check_all_reached_manual_ready); - - // Running Sign stage - println!("Running Sign"); - let parties_refs = &mut parties; - for party in &mut parties_refs.iter_mut() { - println!("Vote for party {}", party.party_index); - match party.vote(round_key.clone(), "Webb".encode(), 0) { - Ok(()) => (), - Err(_err) => (), - } - } - run_simulation(&mut parties, check_all_signatures_ready); - - // Extract all signatures and check for correctness - check_all_signatures_correct(&mut parties); - } - - #[test] - fn simulate_multi_party_t2_n3() { - simulate_multi_party(2, 3); - } - - #[test] - fn simulate_multi_party_t3_n5() { - simulate_multi_party(3, 5); - } -} diff --git a/dkg-primitives/src/rounds/keygen.rs b/dkg-primitives/src/rounds/keygen.rs deleted file mode 100644 index 0e29ead46..000000000 --- a/dkg-primitives/src/rounds/keygen.rs +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use curv::elliptic::curves::Secp256k1; -use dkg_runtime_primitives::KEYGEN_TIMEOUT; -use log::{debug, error, info, trace, warn}; -use round_based::{IsCritical, Msg, StateMachine}; - -use sp_runtime::traits::AtLeast32BitUnsigned; - -use crate::{types::*, utils::vec_usize_to_u16}; -use std::marker::PhantomData; - -pub use gg_2020::{ - party_i::*, - state_machine::{keygen::*, sign::*}, -}; -pub use multi_party_ecdsa::protocols::multi_party_ecdsa::{ - gg_2020, - gg_2020::state_machine::{keygen as gg20_keygen, sign as gg20_sign, traits::RoundBlame}, -}; - -/// Wrapper state-machine for Keygen rounds -#[allow(clippy::all)] -pub enum KeygenState -where - Clock: AtLeast32BitUnsigned + Copy, -{ - Empty, - NotStarted(PreKeygenRounds), - Started(KeygenRounds), - Finished(Result, DKGError>), -} - -/// Implementation of DKGRoundsSM trait that dispatches calls -/// to the current internal state if applicable. -impl DKGRoundsSM, C> for KeygenState -where - C: AtLeast32BitUnsigned + Copy, -{ - fn proceed(&mut self, at: C) -> Result { - match self { - Self::Started(keygen_rounds) => keygen_rounds.proceed(at), - _ => Ok(true), - } - } - - fn get_outgoing(&mut self) -> Vec { - match self { - Self::Started(keygen_rounds) => keygen_rounds.get_outgoing(), - _ => Vec::new(), - } - } - - fn handle_incoming(&mut self, data: DKGKeygenMessage, at: C) -> Result<(), DKGError> { - match self { - Self::NotStarted(pre_keygen_rounds) => pre_keygen_rounds.handle_incoming(data, at), - Self::Started(keygen_rounds) => keygen_rounds.handle_incoming(data, at), - _ => Ok(()), - } - } - - fn is_finished(&self) -> bool { - match self { - Self::Started(keygen_rounds) => keygen_rounds.is_finished(), - _ => true, - } - } - - fn try_finish(self) -> Result { - match self { - Self::Started(ref keygen_rounds) => - if keygen_rounds.is_finished() { - Ok(self) - } else { - Err(DKGError::SMNotFinished) - }, - _ => Ok(self), - } - } -} - -/// Pre-keygen rounds -/// Used to collect incoming messages from other peers which started earlier -pub struct PreKeygenRounds { - pending_keygen_msgs: Vec, - clock_type: PhantomData, -} - -impl PreKeygenRounds { - pub fn new() -> Self { - Self { pending_keygen_msgs: Vec::default(), clock_type: PhantomData } - } -} - -impl Default for PreKeygenRounds { - fn default() -> Self { - Self::new() - } -} - -impl DKGRoundsSM, C> for PreKeygenRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - fn handle_incoming(&mut self, data: DKGKeygenMessage, _at: C) -> Result<(), DKGError> { - self.pending_keygen_msgs.push(data); - Ok(()) - } - - fn is_finished(&self) -> bool { - true - } - - fn try_finish(self) -> Result, DKGError> { - Ok(self.pending_keygen_msgs) - } -} - -/// Keygen rounds -/// Main state, corresponds to gg20 Keygen state-machine -pub struct KeygenRounds -where - Clock: AtLeast32BitUnsigned + Copy, -{ - params: KeygenParams, - started_at: Clock, - keygen: Keygen, -} - -impl KeygenRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - pub fn new(params: KeygenParams, started_at: C, keygen: Keygen) -> Self { - Self { params, started_at, keygen } - } -} - -impl DKGRoundsSM, C> for KeygenRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - /// Proceed to next step - - fn proceed(&mut self, at: C) -> Result { - trace!(target: "dkg", "🕸️ Keygen party {} enter proceed", self.params.party_index); - - let keygen = &mut self.keygen; - - if keygen.wants_to_proceed() { - debug!(target: "dkg", "🕸️ Keygen party {} wants to proceed", keygen.party_ind()); - trace!(target: "dkg", "🕸️ before: {:?}", keygen); - - match keygen.proceed() { - Ok(_) => { - debug!(target: "dkg", "🕸️ Keygen party {} proceeded", keygen.party_ind()); - trace!(target: "dkg", "🕸️ after: {:?}", keygen); - }, - Err(err) => { - match err { - gg20_keygen::Error::ProceedRound(proceed_err) => match proceed_err { - gg20_keygen::ProceedError::Round2VerifyCommitments(err_type) => - return Err(DKGError::KeygenMisbehaviour { - bad_actors: vec_usize_to_u16(err_type.bad_actors), - }), - gg20_keygen::ProceedError::Round3VerifyVssConstruct(err_type) => - return Err(DKGError::KeygenMisbehaviour { - bad_actors: vec_usize_to_u16(err_type.bad_actors), - }), - gg20_keygen::ProceedError::Round4VerifyDLogProof(err_type) => - return Err(DKGError::KeygenMisbehaviour { - bad_actors: vec_usize_to_u16(err_type.bad_actors), - }), - }, - _ => return Err(DKGError::GenericError { reason: err.to_string() }), - }; - }, - } - } - - let (_, blame_vec) = keygen.round_blame(); - - if keygen.is_finished() { - Ok(true) - } else { - if at - self.started_at > KEYGEN_TIMEOUT.into() { - if !blame_vec.is_empty() { - return Err(DKGError::KeygenTimeout { bad_actors: blame_vec }) - } else { - // Should never happen - warn!(target: "dkg", "🕸️ Keygen timeout reached, but no missing parties found", ); - } - } - Ok(false) - } - } - - /// Get outgoing messages - - fn get_outgoing(&mut self) -> Vec { - trace!(target: "dkg", "🕸️ Getting outgoing keygen messages"); - - let keygen = &mut self.keygen; - - if !keygen.message_queue().is_empty() { - trace!(target: "dkg", "🕸️ Outgoing messages, queue len: {}", keygen.message_queue().len()); - - let round_id = self.params.round_id; - - let enc_messages = keygen - .message_queue() - .iter_mut() - .map(|m| { - trace!(target: "dkg", "🕸️ MPC protocol message {:?}", m); - let serialized = serde_json::to_string(&m).unwrap(); - DKGKeygenMessage { round_id, keygen_msg: serialized.into_bytes() } - }) - .collect::>(); - - keygen.message_queue().clear(); - enc_messages - } else { - Vec::new() - } - } - - /// Handle incoming messages - - fn handle_incoming(&mut self, data: DKGKeygenMessage, _at: C) -> Result<(), DKGError> { - if data.round_id != self.params.round_id { - return Err(DKGError::GenericError { reason: "Round ids do not match".to_string() }) - } - - let keygen = &mut self.keygen; - - trace!(target: "dkg", "🕸️ Handle incoming keygen message"); - if data.keygen_msg.is_empty() { - warn!(target: "dkg", "🕸️ Got empty message"); - return Ok(()) - } - - let msg: Msg = match serde_json::from_slice(&data.keygen_msg) { - Ok(msg) => msg, - Err(err) => { - error!(target: "dkg", "🕸️ Error deserializing msg: {:?}", err); - return Err(DKGError::GenericError { - reason: format!("Error deserializing keygen msg, reason: {}", err), - }) - }, - }; - - if Some(keygen.party_ind()) != msg.receiver && - (msg.receiver.is_some() || msg.sender == keygen.party_ind()) - { - warn!(target: "dkg", "🕸️ Ignore messages sent by self"); - return Ok(()) - } - trace!( - target: "dkg", "🕸️ Party {} got message from={}, broadcast={}: {:?}", - keygen.party_ind(), - msg.sender, - msg.receiver.is_none(), - msg.body, - ); - trace!(target: "dkg", "🕸️ State before incoming message processing: {:?}", keygen); - match keygen.handle_incoming(msg) { - Ok(()) => (), - Err(err) if err.is_critical() => { - error!(target: "dkg", "🕸️ Critical error encountered: {:?}", err); - return Err(DKGError::GenericError { - reason: "Keygen critical error encountered".to_string(), - }) - }, - Err(err) => { - error!(target: "dkg", "🕸️ Non-critical error encountered: {:?}", err); - }, - } - debug!(target: "dkg", "🕸️ State after incoming message processing: {:?}", keygen); - - Ok(()) - } - - /// Try finish - - fn is_finished(&self) -> bool { - self.keygen.is_finished() - } - - fn try_finish(mut self) -> Result, DKGError> { - info!(target: "dkg", "🕸️ Keygen is finished, extracting output, round_id: {:?}", self.params.round_id); - match self.keygen.pick_output() { - Some(Ok(key)) => { - info!(target: "dkg", "🕸️ local share key is extracted"); - Ok(key) - }, - Some(Err(err)) => Err(DKGError::CriticalError { reason: err.to_string() }), - None => Err(DKGError::CriticalError { - reason: "Keygen finished with no result".to_string(), - }), - } - } -} diff --git a/dkg-primitives/src/rounds/offline.rs b/dkg-primitives/src/rounds/offline.rs deleted file mode 100644 index 7c884514e..000000000 --- a/dkg-primitives/src/rounds/offline.rs +++ /dev/null @@ -1,322 +0,0 @@ -use dkg_runtime_primitives::OFFLINE_TIMEOUT; -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use log::{debug, error, info, trace, warn}; -use round_based::{IsCritical, Msg, StateMachine}; - -use sp_runtime::traits::AtLeast32BitUnsigned; - -use crate::{types::*, utils::vec_usize_to_u16}; - -pub use gg_2020::{ - party_i::*, - state_machine::{keygen::*, sign::*}, -}; -pub use multi_party_ecdsa::protocols::multi_party_ecdsa::{ - gg_2020, - gg_2020::state_machine::{keygen as gg20_keygen, sign as gg20_sign, traits::RoundBlame}, -}; - -/// Wrapper state-machine for Offline rounds -#[allow(clippy::large_enum_variant)] -pub enum OfflineState -where - Clock: AtLeast32BitUnsigned + Copy, -{ - NotStarted(PreOfflineRounds), - Started(OfflineRounds), - Finished(Result), -} - -/// Implementation of DKGRoundsSM trait that dispatches calls -/// to the current internal state if applicable. -impl DKGRoundsSM, C> for OfflineState -where - C: AtLeast32BitUnsigned + Copy, -{ - fn proceed(&mut self, at: C) -> Result { - match self { - Self::Started(offline_rounds) => offline_rounds.proceed(at), - _ => Ok(true), - } - } - - fn get_outgoing(&mut self) -> Vec { - match self { - Self::Started(offline_rounds) => offline_rounds.get_outgoing(), - _ => Vec::new(), - } - } - - fn handle_incoming(&mut self, data: DKGOfflineMessage, at: C) -> Result<(), DKGError> { - match self { - Self::NotStarted(pre_offline_rounds) => pre_offline_rounds.handle_incoming(data, at), - Self::Started(offline_rounds) => offline_rounds.handle_incoming(data, at), - _ => Ok(()), - } - } - - fn is_finished(&self) -> bool { - match self { - Self::Started(offline_rounds) => offline_rounds.is_finished(), - _ => true, - } - } - - fn try_finish(self) -> Result { - match self { - Self::Started(ref offline_rounds) => - if offline_rounds.is_finished() { - Ok(self) - } else { - Err(DKGError::SMNotFinished) - }, - _ => Ok(self), - } - } -} - -/// Pre-offline rounds -/// Used to collect incoming messages from other peers which started earlier -pub struct PreOfflineRounds { - pub pending_offline_msgs: Vec, -} - -impl PreOfflineRounds { - pub fn new() -> Self { - Self { pending_offline_msgs: Vec::default() } - } -} - -impl Default for PreOfflineRounds { - fn default() -> Self { - Self::new() - } -} - -impl DKGRoundsSM, C> for PreOfflineRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - fn handle_incoming(&mut self, data: DKGOfflineMessage, _at: C) -> Result<(), DKGError> { - self.pending_offline_msgs.push(data); - Ok(()) - } - - fn is_finished(&self) -> bool { - true - } - - fn try_finish(self) -> Result, DKGError> { - Ok(self.pending_offline_msgs) - } -} - -/// Offline rounds -/// Main state, corresponds to gg20 OfflineStage state-machine -pub struct OfflineRounds -where - Clock: AtLeast32BitUnsigned + Copy, -{ - params: SignParams, - started_at: Clock, - round_key: Vec, - offline_stage: OfflineStage, -} - -impl OfflineRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - pub fn new( - params: SignParams, - started_at: C, - round_key: Vec, - offline_stage: OfflineStage, - ) -> Self { - Self { params, started_at, round_key, offline_stage } - } -} - -impl DKGRoundsSM for OfflineRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - /// Proceed to next step - - fn proceed(&mut self, at: C) -> Result { - trace!(target: "dkg", "🕸️ OfflineStage party {} enter proceed", self.params.party_index); - - let offline_stage = &mut self.offline_stage; - - if offline_stage.wants_to_proceed() { - info!(target: "dkg", "🕸️ OfflineStage party {} wants to proceed", offline_stage.party_ind()); - trace!(target: "dkg", "🕸️ before: {:?}", offline_stage); - // TODO, handle asynchronously - match offline_stage.proceed() { - Ok(_) => { - trace!(target: "dkg", "🕸️ after: {:?}", offline_stage); - }, - Err(err) => { - println!("Error proceeding offline stage {:?}", err); - match err { - gg20_sign::Error::ProceedRound(proceed_err) => match proceed_err { - gg20_sign::rounds::Error::Round1(err_type) | - gg20_sign::rounds::Error::Round2Stage4(err_type) | - gg20_sign::rounds::Error::Round3(err_type) | - gg20_sign::rounds::Error::Round5(err_type) | - gg20_sign::rounds::Error::Round6VerifyProof(err_type) => - return Err(DKGError::OfflineMisbehaviour { - bad_actors: vec_usize_to_u16(err_type.bad_actors), - }), - _ => - return Err(DKGError::GenericError { - reason: proceed_err.to_string(), - }), - }, - _ => return Err(DKGError::GenericError { reason: err.to_string() }), - }; - }, - } - } - - let (_, blame_vec) = offline_stage.round_blame(); - - if offline_stage.is_finished() { - Ok(true) - } else { - if at - self.started_at > OFFLINE_TIMEOUT.into() { - if !blame_vec.is_empty() { - return Err(DKGError::OfflineTimeout { bad_actors: blame_vec }) - } else { - // Should never happen - warn!(target: "dkg", "🕸️ Offline timeout reached, but no missing parties found", ); - } - } - Ok(false) - } - } - - /// Get outgoing messages - - fn get_outgoing(&mut self) -> Vec { - let mut messages = Vec::new(); - trace!(target: "dkg", "🕸️ Getting outgoing offline messages"); - - let offline_stage = &mut self.offline_stage; - - if !offline_stage.message_queue().is_empty() { - trace!(target: "dkg", "🕸️ Outgoing messages, queue len: {}", offline_stage.message_queue().len()); - - let signer_set_id = self.params.signer_set_id; - - for m in offline_stage.message_queue() { - trace!(target: "dkg", "🕸️ MPC protocol message {:?}", *m); - let serialized = serde_json::to_string(&m).unwrap(); - let msg = DKGOfflineMessage { - key: self.round_key.clone(), - signer_set_id, - offline_msg: serialized.into_bytes(), - }; - - messages.push(msg); - } - - offline_stage.message_queue().clear(); - } - - messages - } - - /// Handle incoming messages - - fn handle_incoming(&mut self, data: DKGOfflineMessage, _at: C) -> Result<(), DKGError> { - if data.signer_set_id != self.params.signer_set_id { - return Err(DKGError::GenericError { - reason: format!( - "Incoming Signer set id {} does not match our id {}", - data.signer_set_id, self.params.signer_set_id - ), - }) - } - - let offline_stage = &mut self.offline_stage; - - trace!(target: "dkg", "🕸️ Handle incoming offline message"); - if data.offline_msg.is_empty() { - warn!(target: "dkg", "🕸️ Got empty message"); - return Ok(()) - } - let msg: Msg = match serde_json::from_slice(&data.offline_msg) { - Ok(msg) => msg, - Err(err) => { - error!(target: "dkg", "🕸️ Error deserializing msg: {:?}", err); - return Err(DKGError::GenericError { - reason: "Error deserializing offline msg".to_string(), - }) - }, - }; - - if Some(offline_stage.party_ind()) != msg.receiver && - (msg.receiver.is_some() || msg.sender == offline_stage.party_ind()) - { - warn!(target: "dkg", "🕸️ Ignore messages sent by self"); - return Ok(()) - } - trace!( - target: "dkg", "🕸️ Party {} got message from={}, broadcast={}: {:?}", - offline_stage.party_ind(), - msg.sender, - msg.receiver.is_none(), - msg.body, - ); - debug!(target: "dkg", "🕸️ State before incoming message processing: {:?}", offline_stage); - match offline_stage.handle_incoming(msg) { - Ok(()) => (), - Err(err) if err.is_critical() => { - error!(target: "dkg", "🕸️ Critical error encountered: {:?}", err); - return Err(DKGError::CriticalError { - reason: "Offline critical error encountered".to_string(), - }) - }, - Err(err) => { - error!(target: "dkg", "🕸️ Non-critical error encountered: {:?}", err); - }, - } - trace!(target: "dkg", "🕸️ State after incoming message processing: {:?}", offline_stage); - - Ok(()) - } - - /// Try finish current Stage - - fn is_finished(&self) -> bool { - self.offline_stage.is_finished() - } - - fn try_finish(mut self) -> Result { - info!(target: "dkg", "🕸️ Extracting output for offline stage"); - match self.offline_stage.pick_output() { - Some(Ok(cos)) => { - info!(target: "dkg", "🕸️ CompletedOfflineStage is extracted"); - Ok(cos) - }, - Some(Err(err)) => Err(DKGError::CriticalError { reason: err.to_string() }), - None => Err(DKGError::GenericError { - reason: "OfflineStage finished with no result".to_string(), - }), - } - } -} diff --git a/dkg-primitives/src/rounds/sign.rs b/dkg-primitives/src/rounds/sign.rs deleted file mode 100644 index 107c302b1..000000000 --- a/dkg-primitives/src/rounds/sign.rs +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use codec::Encode; -use curv::arithmetic::Converter; -use dkg_runtime_primitives::SIGN_TIMEOUT; -use log::{debug, error, trace, warn}; -use sp_core::ecdsa::Signature; -use sp_runtime::traits::AtLeast32BitUnsigned; -use std::collections::BTreeMap; - -use crate::{types::*, utils::vec_usize_to_u16}; - -pub use gg_2020::{ - party_i::*, - state_machine::{keygen::*, sign::*}, -}; -pub use multi_party_ecdsa::protocols::multi_party_ecdsa::{ - gg_2020, - gg_2020::state_machine::{keygen as gg20_keygen, sign as gg20_sign, traits::RoundBlame}, -}; - -/// Wrapper state-machine for Sign rounds -pub enum SignState -where - Clock: AtLeast32BitUnsigned + Copy, -{ - NotStarted(PreSignRounds), - Started(SignRounds), - Finished(Result), -} - -/// Implementation of DKGRoundsSM trait that dispatches calls -/// to the current internal state if applicable. -impl DKGRoundsSM, C> for SignState -where - C: AtLeast32BitUnsigned + Copy, -{ - fn proceed(&mut self, at: C) -> Result { - match self { - Self::Started(sign_rounds) => sign_rounds.proceed(at), - _ => Ok(true), - } - } - - fn get_outgoing(&mut self) -> Vec { - match self { - Self::Started(sign_rounds) => sign_rounds.get_outgoing(), - _ => Vec::new(), - } - } - - fn handle_incoming(&mut self, data: DKGVoteMessage, at: C) -> Result<(), DKGError> { - match self { - Self::NotStarted(pre_rounds) => pre_rounds.handle_incoming(data, at), - Self::Started(sign_rounds) => sign_rounds.handle_incoming(data, at), - _ => Ok(()), - } - } - - fn is_finished(&self) -> bool { - match self { - Self::Started(sign_rounds) => sign_rounds.is_finished(), - _ => true, - } - } - - fn try_finish(self) -> Result { - match self { - Self::Started(ref sign_rounds) => - if sign_rounds.is_finished() { - Ok(self) - } else { - Err(DKGError::SMNotFinished) - }, - _ => Ok(self), - } - } -} - -/// Pre-sign rounds -/// Used to collect incoming messages from other peers which started earlier -pub struct PreSignRounds { - pub pending_sign_msgs: Vec, -} - -impl PreSignRounds { - pub fn new() -> Self { - Self { pending_sign_msgs: Vec::default() } - } -} - -impl Default for PreSignRounds { - fn default() -> Self { - Self::new() - } -} - -impl DKGRoundsSM, C> for PreSignRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - fn handle_incoming(&mut self, data: DKGVoteMessage, _at: C) -> Result<(), DKGError> { - self.pending_sign_msgs.push(data); - Ok(()) - } - - fn is_finished(&self) -> bool { - true - } - - fn try_finish(self) -> Result, DKGError> { - Ok(self.pending_sign_msgs) - } -} - -/// Sign rounds -/// Main state, corresponds to gg20 SignManual one round signing object -pub struct SignRounds -where - Clock: AtLeast32BitUnsigned + Copy, -{ - params: SignParams, - round_key: Vec, - sign_tracker: DKGRoundTracker, Clock>, - sign_outgoing_msgs: Vec, -} - -impl SignRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - pub fn new( - params: SignParams, - started_at: C, - payload: Vec, - round_key: Vec, - partial_sig: PartialSignature, - sign_manual: SignManual, - ) -> Self { - let sign_tracker = DKGRoundTracker::, C> { - sign_manual: Some(sign_manual), - payload: Some(payload), - started_at, - ..Default::default() - }; - - let mut sign_outgoing_msgs: Vec = Vec::new(); - let serialized = serde_json::to_string(&partial_sig).unwrap(); - let msg = DKGVoteMessage { - party_ind: params.party_index, - round_key: round_key.clone(), - partial_signature: serialized.into_bytes(), - }; - sign_outgoing_msgs.push(msg); - - Self { params, round_key, sign_tracker, sign_outgoing_msgs } - } -} - -impl DKGRoundsSM for SignRounds -where - C: AtLeast32BitUnsigned + Copy, -{ - /// Proceed to next step - - fn proceed(&mut self, at: C) -> Result { - if self.sign_tracker.is_done(self.params.threshold) { - return Ok(true) - } - // Check if we have signed the message and that the timeout has exhausted - let signed_by_self = self.sign_tracker.is_signed_by(self.params.party_index); - let sign_timeout_exhausted = at - self.sign_tracker.started_at > SIGN_TIMEOUT.into(); - // If so, identify all bad actors and return an error - if signed_by_self && sign_timeout_exhausted { - let signed_by = self.sign_tracker.get_signed_parties(); - let mut not_signed_by: Vec = self - .params - .signers - .iter() - .filter(|v| !signed_by.contains(*v)) - .copied() - .collect(); - - let mut bad_actors: Vec = Vec::new(); - bad_actors.append(&mut not_signed_by); - - Err(DKGError::SignTimeout { bad_actors }) - } else { - Ok(false) - } - } - - /// Get outgoing messages - - fn get_outgoing(&mut self) -> Vec { - trace!(target: "dkg", "🕸️ Getting outgoing vote messages"); - std::mem::take(&mut self.sign_outgoing_msgs) - } - - /// Handle incoming messages - - fn handle_incoming(&mut self, data: DKGVoteMessage, _at: C) -> Result<(), DKGError> { - trace!(target: "dkg", "🕸️ Handle vote message"); - - if data.party_ind == self.params.party_index { - warn!(target: "dkg", "🕸️ Ignore messages sent by self"); - return Ok(()) - } - - let sig: PartialSignature = match serde_json::from_slice(&data.partial_signature) { - Ok(sig) => sig, - Err(err) => { - error!(target: "dkg", "🕸️ Error deserializing msg: {:?}", err); - return Err(DKGError::GenericError { - reason: "Error deserializing vote msg".to_string(), - }) - }, - }; - - self.sign_tracker.add_vote(data.party_ind, sig); - - Ok(()) - } - - /// Try finish - - fn is_finished(&self) -> bool { - self.sign_tracker.is_done(self.params.threshold) - } - - fn try_finish(self) -> Result { - let payload = self.sign_tracker.payload.clone(); - let sig = self.sign_tracker.complete(); - - if let Err(err) = sig { - println!("{:?}", err); - Err(err) - } else if let (Some(payload), Ok(sig)) = (payload, sig) { - match convert_signature(&sig) { - Some(signature) => { - let signed_payload = DKGSignedPayload { - key: self.round_key.clone(), - payload, - signature: signature.encode(), - }; - - debug!(target: "dkg", "🕸️ Finished round w/ key: {:?}", self.round_key); - Ok(signed_payload) - }, - _ => Err(DKGError::GenericError { - reason: "Error serializing signature".to_string(), - }), - } - } else { - Err(DKGError::GenericError { reason: "No payload".to_string() }) - } - } -} - -/// Convenience struct to accumulate partial signatures -/// and later construct the full signature. -struct DKGRoundTracker { - votes: BTreeMap, - sign_manual: Option, - payload: Option, - started_at: Clock, -} - -impl Default for DKGRoundTracker -where - C: AtLeast32BitUnsigned + Copy, -{ - fn default() -> Self { - Self { - votes: Default::default(), - sign_manual: Default::default(), - payload: Default::default(), - started_at: 0u32.into(), - } - } -} - -impl DKGRoundTracker -where - C: AtLeast32BitUnsigned + Copy, -{ - fn add_vote(&mut self, party: u16, vote: PartialSignature) -> bool { - self.votes.insert(party, vote); - true - } - - fn is_signed_by(&self, party: u16) -> bool { - self.votes.contains_key(&party) - } - - fn get_signed_parties(&self) -> Vec { - self.votes.keys().copied().collect() - } - - fn is_done(&self, threshold: u16) -> bool { - self.sign_manual.is_some() && self.votes.len() >= threshold as usize - } - - fn complete(mut self) -> Result { - if let Some(sign_manual) = self.sign_manual.take() { - debug!(target: "dkg", "Trying to complete vote with {} votes", self.votes.len()); - - let votes: Vec = self.votes.into_values().collect(); - - return match sign_manual.complete(&votes) { - Ok(sig) => { - debug!("Obtained complete signature: {}", &sig.recid); - Ok(sig) - }, - Err(err) => { - let sign_err = match err { - SignError::LocalSigning(sign_err) => sign_err, - SignError::CompleteSigning(sign_err) => sign_err, - }; - - match sign_err { - gg20_sign::rounds::Error::Round1(err_type) | - gg20_sign::rounds::Error::Round2Stage4(err_type) | - gg20_sign::rounds::Error::Round3(err_type) | - gg20_sign::rounds::Error::Round5(err_type) | - gg20_sign::rounds::Error::Round6VerifyProof(err_type) => - return Err(DKGError::SignMisbehaviour { - bad_actors: vec_usize_to_u16(err_type.bad_actors), - }), - _ => return Err(DKGError::GenericError { reason: sign_err.to_string() }), - } - }, - } - } - Err(DKGError::GenericError { reason: "No SignManual found".to_string() }) - } -} - -pub fn convert_signature(sig_recid: &SignatureRecid) -> Option { - let r = sig_recid.r.to_bigint().to_bytes(); - let s = sig_recid.s.to_bigint().to_bytes(); - let v = sig_recid.recid + 27u8; - - let mut sig_vec: Vec = Vec::new(); - - for _ in 0..(32 - r.len()) { - sig_vec.extend(&[0]); - } - sig_vec.extend_from_slice(&r); - - for _ in 0..(32 - s.len()) { - sig_vec.extend(&[0]); - } - sig_vec.extend_from_slice(&s); - - sig_vec.extend(&[v]); - - if 65 != sig_vec.len() { - warn!(target: "dkg", "🕸️ Invalid signature len: {}, expected 65", sig_vec.len()); - return None - } - - let mut dkg_sig_arr: [u8; 65] = [0; 65]; - dkg_sig_arr.copy_from_slice(&sig_vec[0..65]); - - Some(Signature(dkg_sig_arr)) -} diff --git a/dkg-primitives/src/types.rs b/dkg-primitives/src/types.rs index a06841ad1..1e159d50f 100644 --- a/dkg-primitives/src/types.rs +++ b/dkg-primitives/src/types.rs @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. // -use crate::rounds::LocalKey; use codec::{Decode, Encode}; use curv::elliptic::curves::{Point, Scalar, Secp256k1}; use dkg_runtime_primitives::{crypto::AuthorityId, MisbehaviourType}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::keygen::LocalKey; +use sp_runtime::traits::{Block, Hash, Header}; use std::fmt; pub type FE = Scalar; @@ -51,6 +52,15 @@ pub struct SignedDKGMessage { pub signature: Option>, } +impl SignedDKGMessage { + pub fn message_hash(&self) -> B::Hash + where + DKGMessage: Encode, + { + <::Hashing as Hash>::hash_of(&self.msg) + } +} + impl fmt::Display for DKGMessage { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let label = match self.payload { @@ -74,11 +84,42 @@ pub enum DKGMsgPayload { MisbehaviourBroadcast(DKGMisbehaviourMessage), } +impl DKGMsgPayload { + /// NOTE: this is hacky + /// TODO: Change enums for keygen, offline, vote + pub fn async_proto_only_get_sender_id(&self) -> Option { + match self { + DKGMsgPayload::Keygen(kg) => Some(kg.sender_id as u16), + DKGMsgPayload::Offline(offline) => Some(offline.signer_set_id as u16), + DKGMsgPayload::Vote(vote) => Some(vote.party_ind), + _ => None, + } + } + + pub fn get_type(&self) -> &'static str { + match self { + DKGMsgPayload::Keygen(_) => "keygen", + DKGMsgPayload::Offline(_) => "offline", + DKGMsgPayload::Vote(_) => "vote", + DKGMsgPayload::PublicKeyBroadcast(_) => "pub_key_broadcast", + DKGMsgPayload::MisbehaviourBroadcast(_) => "misbehaviour", + } + } + + pub fn get_async_index(&self) -> u8 { + match self { + DKGMsgPayload::Offline(m) => m.async_index, + DKGMsgPayload::Vote(m) => m.async_index, + _ => 0, + } + } +} + #[derive(Debug, Clone, Decode, Encode)] #[cfg_attr(feature = "scale-info", derive(scale_info::TypeInfo))] pub struct DKGKeygenMessage { - /// Keygen set epoch id - pub round_id: RoundId, + /// Sender id / party index + pub sender_id: u16, /// Serialized keygen msg pub keygen_msg: Vec, } @@ -92,6 +133,8 @@ pub struct DKGOfflineMessage { pub signer_set_id: SignerSetId, /// Serialized offline stage msg pub offline_msg: Vec, + /// Index in async protocols + pub async_index: u8, } #[derive(Debug, Clone, Decode, Encode)] @@ -103,6 +146,8 @@ pub struct DKGVoteMessage { pub round_key: Vec, /// Serialized partial signature pub partial_signature: Vec, + /// Index in async protocols + pub async_index: u8, } #[derive(Debug, Clone, Decode, Encode)] @@ -191,6 +236,7 @@ pub enum DKGError { SignMisbehaviour { bad_actors: Vec }, SignTimeout { bad_actors: Vec }, StartKeygen { reason: String }, + StartOffline { reason: String }, CreateOfflineStage { reason: String }, Vote { reason: String }, CriticalError { reason: String }, diff --git a/dkg-primitives/src/utils.rs b/dkg-primitives/src/utils.rs index df4c5cdc4..366733a68 100644 --- a/dkg-primitives/src/utils.rs +++ b/dkg-primitives/src/utils.rs @@ -12,13 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. // -use crate::{rounds::LocalKey, types::RoundId}; +use crate::types::RoundId; use chacha20poly1305::{ aead::{Aead, NewAead}, XChaCha20Poly1305, }; use codec::Encode; -use curv::elliptic::curves::Secp256k1; +use curv::{arithmetic::Converter, elliptic::curves::Secp256k1}; +use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::{ + party_i::SignatureRecid, state_machine::keygen::LocalKey, +}; use sc_service::{ChainType, Configuration}; use serde::{Deserialize, Serialize}; use sp_core::{sr25519, Pair, Public}; @@ -27,6 +30,7 @@ use sp_runtime::key_types::ACCOUNT; use std::{fs, path::PathBuf}; use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng}; +use sp_core::ecdsa::Signature; /// Helper function to generate a crypto pair from seed pub fn get_from_seed(seed: &str) -> ::Public { @@ -169,10 +173,10 @@ mod tests { let encrypted_data = encrypt(data.to_vec()); let decrypted_data = decrypt(encrypted_data.clone()); println!("{:?}", encrypted_data); - assert!(encrypted_data != data.to_vec()); + assert_ne!(encrypted_data, data.to_vec()); println!("{:?}, {:?}", data, decrypted_data); - assert!(decrypted_data == data.to_vec()); + assert_eq!(decrypted_data, data.to_vec()); } #[test] @@ -186,9 +190,39 @@ mod tests { for _ in 0..100 { let new_set = select_random_set(&seed, set.clone(), 10).unwrap(); if !random_set.is_empty() { - assert!(random_set == new_set); + assert_eq!(random_set, new_set); } random_set = new_set; } } } + +pub fn convert_signature(sig_recid: &SignatureRecid) -> Option { + let r = sig_recid.r.to_bigint().to_bytes(); + let s = sig_recid.s.to_bigint().to_bytes(); + let v = sig_recid.recid + 27u8; + + let mut sig_vec: Vec = Vec::new(); + + for _ in 0..(32 - r.len()) { + sig_vec.extend(&[0]); + } + sig_vec.extend_from_slice(&r); + + for _ in 0..(32 - s.len()) { + sig_vec.extend(&[0]); + } + sig_vec.extend_from_slice(&s); + + sig_vec.extend(&[v]); + + if 65 != sig_vec.len() { + log::warn!(target: "dkg", "🕸️ Invalid signature len: {}, expected 65", sig_vec.len()); + return None + } + + let mut dkg_sig_arr: [u8; 65] = [0; 65]; + dkg_sig_arr.copy_from_slice(&sig_vec[0..65]); + + Some(Signature(dkg_sig_arr)) +} diff --git a/dkg-runtime-primitives/Cargo.toml b/dkg-runtime-primitives/Cargo.toml index 69a449194..2ba8ff5a9 100644 --- a/dkg-runtime-primitives/Cargo.toml +++ b/dkg-runtime-primitives/Cargo.toml @@ -5,33 +5,30 @@ edition = "2021" [dependencies] impl-trait-for-tuples = { version = "0.2.2", default-features = false } -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ +codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive", ] } -scale-info = { version = "1.0", default-features = false, features = [ +scale-info = { version = "2.1.1", default-features = false, features = [ "derive", ] } tiny-keccak = { version = "2.0.1", default-features = false, features = [ "keccak", ] } -ethereum = { version = "0.9.0", default-features = false, features = [ +ethereum = { version = "0.12.0", default-features = false, features = [ "with-codec", ] } -ethereum-types = { version = "0.12", default-features = false } -webb-proposals = { version = "0.2.5", default-features = false, features = ["scale"] } +ethereum-types = { version = "0.13.1", default-features = false } +webb-proposals = { version = "0.3.2", default-features = false, features = ["scale", "evm", "substrate"] } hex = { version = "0.4", default-features = false } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = 'polkadot-v0.9.17', default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } - -[dev-dependencies] - +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = 'polkadot-v0.9.24', default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } [features] default = ["std"] diff --git a/dkg-runtime-primitives/src/handlers/evm/add_token_to_set.rs b/dkg-runtime-primitives/src/handlers/evm/add_token_to_set.rs index 60cdc7d30..c7b6119cf 100644 --- a/dkg-runtime-primitives/src/handlers/evm/add_token_to_set.rs +++ b/dkg-runtime-primitives/src/handlers/evm/add_token_to_set.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::TokenAddProposal; +use webb_proposals::evm::TokenAddProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/anchor_update.rs b/dkg-runtime-primitives/src/handlers/evm/anchor_update.rs index a036d9ae0..1d9c3e61d 100644 --- a/dkg-runtime-primitives/src/handlers/evm/anchor_update.rs +++ b/dkg-runtime-primitives/src/handlers/evm/anchor_update.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::AnchorUpdateProposal; +use webb_proposals::evm::AnchorUpdateProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/fee_recipient_update.rs b/dkg-runtime-primitives/src/handlers/evm/fee_recipient_update.rs index 402c2be78..c8043948d 100644 --- a/dkg-runtime-primitives/src/handlers/evm/fee_recipient_update.rs +++ b/dkg-runtime-primitives/src/handlers/evm/fee_recipient_update.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::FeeRecipientUpdateProposal; +use webb_proposals::evm::FeeRecipientUpdateProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/fee_update.rs b/dkg-runtime-primitives/src/handlers/evm/fee_update.rs index a13dde1e9..2ed2e8620 100644 --- a/dkg-runtime-primitives/src/handlers/evm/fee_update.rs +++ b/dkg-runtime-primitives/src/handlers/evm/fee_update.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::WrappingFeeUpdateProposal; +use webb_proposals::evm::WrappingFeeUpdateProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/max_deposit_limit_update.rs b/dkg-runtime-primitives/src/handlers/evm/max_deposit_limit_update.rs index 7d9952b6a..755a7d79f 100644 --- a/dkg-runtime-primitives/src/handlers/evm/max_deposit_limit_update.rs +++ b/dkg-runtime-primitives/src/handlers/evm/max_deposit_limit_update.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::MaxDepositLimitProposal; +use webb_proposals::evm::MaxDepositLimitProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/min_withdrawal_limit_update.rs b/dkg-runtime-primitives/src/handlers/evm/min_withdrawal_limit_update.rs index 59455b9cc..ce14fcec6 100644 --- a/dkg-runtime-primitives/src/handlers/evm/min_withdrawal_limit_update.rs +++ b/dkg-runtime-primitives/src/handlers/evm/min_withdrawal_limit_update.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::MinWithdrawalLimitProposal; +use webb_proposals::evm::MinWithdrawalLimitProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/remove_token_from_set.rs b/dkg-runtime-primitives/src/handlers/evm/remove_token_from_set.rs index abb4f1c3d..b72380af5 100644 --- a/dkg-runtime-primitives/src/handlers/evm/remove_token_from_set.rs +++ b/dkg-runtime-primitives/src/handlers/evm/remove_token_from_set.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::TokenRemoveProposal; +use webb_proposals::evm::TokenRemoveProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/rescue_tokens.rs b/dkg-runtime-primitives/src/handlers/evm/rescue_tokens.rs index de5239e19..5d21f93cb 100644 --- a/dkg-runtime-primitives/src/handlers/evm/rescue_tokens.rs +++ b/dkg-runtime-primitives/src/handlers/evm/rescue_tokens.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::RescueTokensProposal; +use webb_proposals::evm::RescueTokensProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/resource_id_update.rs b/dkg-runtime-primitives/src/handlers/evm/resource_id_update.rs index 30e2fdab1..e50b470e3 100644 --- a/dkg-runtime-primitives/src/handlers/evm/resource_id_update.rs +++ b/dkg-runtime-primitives/src/handlers/evm/resource_id_update.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::ResourceIdUpdateProposal; +use webb_proposals::evm::ResourceIdUpdateProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/set_treasury_handler.rs b/dkg-runtime-primitives/src/handlers/evm/set_treasury_handler.rs index 5f3c29b7e..9c4c46018 100644 --- a/dkg-runtime-primitives/src/handlers/evm/set_treasury_handler.rs +++ b/dkg-runtime-primitives/src/handlers/evm/set_treasury_handler.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::SetTreasuryHandlerProposal; +use webb_proposals::evm::SetTreasuryHandlerProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/handlers/evm/set_verifier.rs b/dkg-runtime-primitives/src/handlers/evm/set_verifier.rs index 4b7c774cd..7a3b7c918 100644 --- a/dkg-runtime-primitives/src/handlers/evm/set_verifier.rs +++ b/dkg-runtime-primitives/src/handlers/evm/set_verifier.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use webb_proposals::SetVerifierProposal; +use webb_proposals::evm::SetVerifierProposal; use crate::handlers::validate_proposals::ValidationError; diff --git a/dkg-runtime-primitives/src/lib.rs b/dkg-runtime-primitives/src/lib.rs index 087cdb534..e37528d98 100644 --- a/dkg-runtime-primitives/src/lib.rs +++ b/dkg-runtime-primitives/src/lib.rs @@ -25,7 +25,7 @@ pub mod utils; use crypto::AuthorityId; pub use ethereum::*; pub use ethereum_types::*; -use frame_support::RuntimeDebug; +use frame_support::{log, RuntimeDebug}; pub use proposal::*; pub use crate::proposal::DKGPayloadKey; @@ -58,13 +58,13 @@ pub const GENESIS_AUTHORITY_SET_ID: u64 = 0; pub const GOSSIP_MESSAGE_RESENDING_LIMIT: u8 = 5; /// The keygen timeout limit in blocks before we consider misbehaviours -pub const KEYGEN_TIMEOUT: u32 = 5; +pub const KEYGEN_TIMEOUT: u32 = 2; /// The offline timeout limit in blocks before we consider misbehaviours -pub const OFFLINE_TIMEOUT: u32 = 5; +pub const OFFLINE_TIMEOUT: u32 = 2; /// The sign timeout limit in blocks before we consider misbehaviours -pub const SIGN_TIMEOUT: u32 = 3; +pub const SIGN_TIMEOUT: u32 = 2; // Engine ID for DKG pub const DKG_ENGINE_ID: sp_runtime::ConsensusEngineId = *b"WDKG"; @@ -184,13 +184,32 @@ pub enum ConsensusLog { type AccountId = <::Signer as IdentifyAccount>::AccountId; -#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug)] +#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct UnsignedProposal { pub typed_chain_id: webb_proposals::TypedChainId, pub key: DKGPayloadKey, pub proposal: Proposal, } +impl UnsignedProposal { + pub fn hash(&self) -> Option<[u8; 32]> { + let key = (self.typed_chain_id, self.key); + log::debug!(target: "dkg", "Got unsigned proposal with key = {:?}", &key); + if let Proposal::Unsigned { data, .. } = &self.proposal { + log::debug!(target: "dkg", "Adding unsigned proposal to hash vec"); + Some(keccak_256(data)) + } else { + None + } + } + + pub fn data(&self) -> &Vec { + match &self.proposal { + Proposal::Unsigned { data, .. } | Proposal::Signed { data, .. } => data, + } + } +} + sp_api::decl_runtime_apis! { pub trait DKGApi where diff --git a/dkg-runtime-primitives/src/proposal.rs b/dkg-runtime-primitives/src/proposal.rs index 945c258c9..3c1a2626f 100644 --- a/dkg-runtime-primitives/src/proposal.rs +++ b/dkg-runtime-primitives/src/proposal.rs @@ -240,3 +240,13 @@ pub trait ProposalHandlerTrait { } impl ProposalHandlerTrait for () {} + +/// An unsigned proposal represented in pallet storage +/// We store the creation timestamp to purge expired proposals +#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, scale_info::TypeInfo)] +pub struct StoredUnsignedProposal { + /// Proposal data + pub proposal: Proposal, + /// Creation timestamp + pub timestamp: Timestamp, +} diff --git a/dkg-runtime-primitives/src/utils.rs b/dkg-runtime-primitives/src/utils.rs index 109f934f7..e3b7a4d18 100644 --- a/dkg-runtime-primitives/src/utils.rs +++ b/dkg-runtime-primitives/src/utils.rs @@ -59,7 +59,7 @@ pub fn verify_signer_from_set_ecdsa( if let Ok(data) = recover_ecdsa_pub_key(msg, signature) { let recovered = &data[..32]; if x.0[1..].to_vec() == recovered.to_vec() { - signer = Some(x.clone()); + signer = Some(*x); true } else { false @@ -79,16 +79,21 @@ pub fn verify_signer_from_set( ) -> (Option, bool, Option) { let mut signer = None; let mut inx: Option = None; - let res = maybe_signers.iter().enumerate().any(|(index, x)| { - let decoded_signature = sr25519::Signature::from_slice(signature); - let res = sp_io::crypto::sr25519_verify(&decoded_signature, msg, x); - if res { - inx = Some(index); - signer = Some(*x); - } - - res - }); + let res = + maybe_signers.iter().enumerate().any(|(index, x)| { + match sr25519::Signature::from_slice(signature) { + Some(decoded_signature) => { + let res = sp_io::crypto::sr25519_verify(&decoded_signature, msg, x); + if res { + inx = Some(index); + signer = Some(*x); + } + + res + }, + None => false, + } + }); (signer, res, inx) } @@ -125,6 +130,22 @@ pub enum SignatureError { InvalidECDSASignature(BadOrigin), } +impl SignatureError { + pub fn expected_public_key(&self) -> Option> { + match self { + Self::InvalidRecovery(v) => Some(v.expected.clone()), + _ => None, + } + } + + pub fn actual_public_key(&self) -> Option> { + match self { + Self::InvalidRecovery(v) => Some(v.actual.clone()), + _ => None, + } + } +} + /// This function takes the ecdsa signature and the unhashed data pub fn ensure_signed_by_dkg( signature: &[u8], @@ -140,28 +161,15 @@ pub fn ensure_signed_by_dkg( return Err(SignatureError::InvalidDKGKey(BadOrigin)) } - let current_dkg = &dkg_key[1..]; - - #[cfg(feature = "std")] - frame_support::log::debug!( - target: "dkg", - "Recovered: - ********************************************************** - public key: {} - curr_key: {} - **********************************************************", - hex::encode(recovered_key.clone()), - hex::encode(current_dkg), - ); - + let current_dkg: Vec<_> = dkg_key.iter().skip(1).cloned().collect(); // The stored_key public key is 33 bytes compressed. // The recovered key is 64 bytes uncompressed. The first 32 bytes represent the compressed // portion of the key. let signer = &recovered_key[..32]; // Check if the signer is the current DKG or the previous DKG to buffer for timing issues - let is_not_current_dkg = signer != current_dkg; + let is_current_dkg = signer == current_dkg; - if !is_not_current_dkg { + if is_current_dkg { Ok(()) } else { Err(SignatureError::InvalidRecovery(SignatureResult { diff --git a/dkg-test-suite/.prettierrc.json b/dkg-test-suite/.prettierrc.json index 01002bd2e..b85f36f5b 100644 --- a/dkg-test-suite/.prettierrc.json +++ b/dkg-test-suite/.prettierrc.json @@ -1,6 +1,6 @@ { "singleQuote": true, - "maxLength": 80, + "printWidth": 80, "semi": true, "tabWidth": 2 } diff --git a/dkg-test-suite/package.json b/dkg-test-suite/package.json index b8ebf238f..fdfa24015 100644 --- a/dkg-test-suite/package.json +++ b/dkg-test-suite/package.json @@ -22,7 +22,9 @@ "wrapping-fee-update-proposal-evm": "ts-node ./src/evm/testWrappingFeeUpdateProposal.ts", "wrapping-fee-update-proposal-substrate": "ts-node ./src/substrate/testWrappingFeeUpdateProposal.ts", "script": "ts-node", - "test": "ts-mocha tests/proposals.test.ts" + "format": "prettier --write '**/*.{ts,js,json,yml}'", + "test:e2e": "ts-mocha tests/e2e/**/*.test.ts", + "test:proposals": "ts-mocha tests/proposals.test.ts" }, "author": "", "license": "ISC", diff --git a/dkg-test-suite/src/constants.ts b/dkg-test-suite/src/constants.ts index 0c35625f7..c8720fe25 100644 --- a/dkg-test-suite/src/constants.ts +++ b/dkg-test-suite/src/constants.ts @@ -16,6 +16,8 @@ */ export const SECONDS = 1000; export const MINUTES = 60 * SECONDS; -export const BLOCK_TIME = 3 * SECONDS; -export const ACC1_PK = '0x0000000000000000000000000000000000000000000000000000000000000001'; -export const ACC2_PK = '0x0000000000000000000000000000000000000000000000000000000000000002'; +export const BLOCK_TIME = 6 * SECONDS; +export const ACC1_PK = + '0x0000000000000000000000000000000000000000000000000000000000000001'; +export const ACC2_PK = + '0x0000000000000000000000000000000000000000000000000000000000000002'; diff --git a/dkg-test-suite/src/evm/testAnchorProposal.ts b/dkg-test-suite/src/evm/testAnchorProposal.ts index 8c5cf7ef2..3b265c9c1 100644 --- a/dkg-test-suite/src/evm/testAnchorProposal.ts +++ b/dkg-test-suite/src/evm/testAnchorProposal.ts @@ -43,11 +43,15 @@ async function testAnchorProposal() { Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { Evm: 5002 }); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); const propHash = keccak256(encodeUpdateAnchorProposal(anchorUpdateProposal)); - const proposalType = { anchorupdateproposal: anchorUpdateProposal.header.nonce }; + const proposalType = { + anchorupdateproposal: anchorUpdateProposal.header.nonce, + }; const unsubSignedProps: any = await unsubSignedPropsUtil( api, @@ -76,8 +80,15 @@ async function sendAnchorProposal(api: ApiPromise) { console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { Evm: 5001 }); - const proposalCall = api.tx.dKGProposals.acknowledgeProposal(0, chainIdType, resourceId, prop); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const proposalCall = api.tx.dKGProposals.acknowledgeProposal( + 0, + chainIdType, + resourceId, + prop + ); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/testFeeRecipientUpdateProposal.ts b/dkg-test-suite/src/evm/testFeeRecipientUpdateProposal.ts index 36288db19..de95a262c 100644 --- a/dkg-test-suite/src/evm/testFeeRecipientUpdateProposal.ts +++ b/dkg-test-suite/src/evm/testFeeRecipientUpdateProposal.ts @@ -14,27 +14,24 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { provider, waitNfinalizedBlocks } from '../utils'; import { encodeFeeRecipientUpdateProposal, - registerResourceId, - resourceId, - signAndSendUtil, - unsubSignedPropsUtil + registerResourceId, + resourceId, + signAndSendUtil, + unsubSignedPropsUtil, } from './util/utils'; -import {ethers} from 'ethers'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {feeRecipientUpdateProposal} from "./util/proposals"; +import { ethers } from 'ethers'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { feeRecipientUpdateProposal } from './util/proposals'; async function testFeeRecipientUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendFeeRecipientUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -43,14 +40,26 @@ async function testFeeRecipientUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); - const propHash = keccak256(encodeFeeRecipientUpdateProposal(feeRecipientUpdateProposal)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); + const propHash = keccak256( + encodeFeeRecipientUpdateProposal(feeRecipientUpdateProposal) + ); - const proposalType = {feerecipientupdateproposal: feeRecipientUpdateProposal.header.nonce} + const proposalType = { + feerecipientupdateproposal: feeRecipientUpdateProposal.header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -58,7 +67,7 @@ async function testFeeRecipientUpdateProposal() { } async function sendFeeRecipientUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -66,20 +75,28 @@ async function sendFeeRecipientUpdateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeFeeRecipientUpdateProposal(feeRecipientUpdateProposal)); + const prop = u8aToHex( + encodeFeeRecipientUpdateProposal(feeRecipientUpdateProposal) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'FeeRecipientUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'FeeRecipientUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/testResourceIdUpdateProposal.ts b/dkg-test-suite/src/evm/testResourceIdUpdateProposal.ts index 44d72d256..be8ea426a 100644 --- a/dkg-test-suite/src/evm/testResourceIdUpdateProposal.ts +++ b/dkg-test-suite/src/evm/testResourceIdUpdateProposal.ts @@ -14,26 +14,23 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { provider, waitNfinalizedBlocks } from '../utils'; import { encodeResourceIdUpdateProposal, - registerResourceId, - resourceId, - signAndSendUtil, - unsubSignedPropsUtil + registerResourceId, + resourceId, + signAndSendUtil, + unsubSignedPropsUtil, } from './util/utils'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {resourceIdUpdateProposal} from "./util/proposals"; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { resourceIdUpdateProposal } from './util/proposals'; async function testResourceIdUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendResourceIdUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -42,14 +39,26 @@ async function testResourceIdUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); - const propHash = keccak256(encodeResourceIdUpdateProposal(resourceIdUpdateProposal)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); + const propHash = keccak256( + encodeResourceIdUpdateProposal(resourceIdUpdateProposal) + ); - const proposalType = {resourceidupdateproposal: resourceIdUpdateProposal.header.nonce} + const proposalType = { + resourceidupdateproposal: resourceIdUpdateProposal.header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -57,7 +66,7 @@ async function testResourceIdUpdateProposal() { } async function sendResourceIdUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -65,20 +74,28 @@ async function sendResourceIdUpdateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeResourceIdUpdateProposal(resourceIdUpdateProposal)); + const prop = u8aToHex( + encodeResourceIdUpdateProposal(resourceIdUpdateProposal) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'ResourceIdUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'ResourceIdUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/testSetTreasuryHandlerProposal.ts b/dkg-test-suite/src/evm/testSetTreasuryHandlerProposal.ts index 4959e82bc..b9a34370a 100644 --- a/dkg-test-suite/src/evm/testSetTreasuryHandlerProposal.ts +++ b/dkg-test-suite/src/evm/testSetTreasuryHandlerProposal.ts @@ -14,27 +14,24 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { provider, waitNfinalizedBlocks } from '../utils'; import { encodeSetTreasuryHandlerProposal, - registerResourceId, - resourceId, - signAndSendUtil, - unsubSignedPropsUtil + registerResourceId, + resourceId, + signAndSendUtil, + unsubSignedPropsUtil, } from './util/utils'; -import {ethers} from 'ethers'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {setTreasuryHandlerProposal} from "./util/proposals"; +import { ethers } from 'ethers'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { setTreasuryHandlerProposal } from './util/proposals'; async function testSetTreasuryHandlerProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendSetTreasuryHandlerProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -43,14 +40,26 @@ async function testSetTreasuryHandlerProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); - const propHash = keccak256(encodeSetTreasuryHandlerProposal(setTreasuryHandlerProposal)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); + const propHash = keccak256( + encodeSetTreasuryHandlerProposal(setTreasuryHandlerProposal) + ); - const proposalType = {settreasuryhandlerproposal: setTreasuryHandlerProposal.header.nonce} + const proposalType = { + settreasuryhandlerproposal: setTreasuryHandlerProposal.header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -58,7 +67,7 @@ async function testSetTreasuryHandlerProposal() { } async function sendSetTreasuryHandlerProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -66,20 +75,28 @@ async function sendSetTreasuryHandlerProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeSetTreasuryHandlerProposal(setTreasuryHandlerProposal)); + const prop = u8aToHex( + encodeSetTreasuryHandlerProposal(setTreasuryHandlerProposal) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'SetTreasuryHandler'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'SetTreasuryHandler' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/testSetVerifierProposal.ts b/dkg-test-suite/src/evm/testSetVerifierProposal.ts index 583df9ae8..c4ad09960 100644 --- a/dkg-test-suite/src/evm/testSetVerifierProposal.ts +++ b/dkg-test-suite/src/evm/testSetVerifierProposal.ts @@ -14,27 +14,24 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { provider, waitNfinalizedBlocks } from '../utils'; import { encodeSetVerifierProposal, - registerResourceId, - resourceId, - signAndSendUtil, - unsubSignedPropsUtil + registerResourceId, + resourceId, + signAndSendUtil, + unsubSignedPropsUtil, } from './util/utils'; -import {ethers} from 'ethers'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {setVerifierProposal} from "./util/proposals"; +import { ethers } from 'ethers'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { setVerifierProposal } from './util/proposals'; async function testSetVerifierProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendSetVerifierProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -43,14 +40,24 @@ async function testSetVerifierProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); const propHash = keccak256(encodeSetVerifierProposal(setVerifierProposal)); - const proposalType = {setverifierproposal: setVerifierProposal.header.nonce} + const proposalType = { + setverifierproposal: setVerifierProposal.header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -58,7 +65,7 @@ async function testSetVerifierProposal() { } async function sendSetVerifierProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -71,15 +78,21 @@ async function sendSetVerifierProposal(api: ApiPromise) { console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'SetVerifier'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'SetVerifier' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/testWrappingFeeUpdateProposal.ts b/dkg-test-suite/src/evm/testWrappingFeeUpdateProposal.ts index 01d0d8b70..f2278047a 100644 --- a/dkg-test-suite/src/evm/testWrappingFeeUpdateProposal.ts +++ b/dkg-test-suite/src/evm/testWrappingFeeUpdateProposal.ts @@ -14,26 +14,23 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { provider, waitNfinalizedBlocks } from '../utils'; import { encodeWrappingFeeUpdateProposal, - registerResourceId, - resourceId, - signAndSendUtil, - unsubSignedPropsUtil + registerResourceId, + resourceId, + signAndSendUtil, + unsubSignedPropsUtil, } from './util/utils'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {wrappingFeeUpdateProposal} from "./util/proposals"; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { wrappingFeeUpdateProposal } from './util/proposals'; async function testWrappingFeeUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendWrappingFeeUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -42,14 +39,26 @@ async function testWrappingFeeUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); - const propHash = keccak256(encodeWrappingFeeUpdateProposal(wrappingFeeUpdateProposal)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); + const propHash = keccak256( + encodeWrappingFeeUpdateProposal(wrappingFeeUpdateProposal) + ); - const proposalType = {wrappingfeeupdateproposal: wrappingFeeUpdateProposal.header.nonce} + const proposalType = { + wrappingfeeupdateproposal: wrappingFeeUpdateProposal.header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -57,7 +66,7 @@ async function testWrappingFeeUpdateProposal() { } async function sendWrappingFeeUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -65,20 +74,28 @@ async function sendWrappingFeeUpdateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeWrappingFeeUpdateProposal(wrappingFeeUpdateProposal)); + const prop = u8aToHex( + encodeWrappingFeeUpdateProposal(wrappingFeeUpdateProposal) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'WrappingFeeUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'WrappingFeeUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/token/testTokenAddProposal.ts b/dkg-test-suite/src/evm/token/testTokenAddProposal.ts index 4e7cb3ca7..a017f7321 100644 --- a/dkg-test-suite/src/evm/token/testTokenAddProposal.ts +++ b/dkg-test-suite/src/evm/token/testTokenAddProposal.ts @@ -14,27 +14,24 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; -import { - provider, - waitNfinalizedBlocks, -} from '../../utils'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { provider, waitNfinalizedBlocks } from '../../utils'; import { encodeTokenAddProposal, - registerResourceId, - resourceId, - signAndSendUtil, - unsubSignedPropsUtil + registerResourceId, + resourceId, + signAndSendUtil, + unsubSignedPropsUtil, } from '../util/utils'; -import {ethers} from 'ethers'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {tokenAddProposal} from "../util/proposals"; +import { ethers } from 'ethers'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { tokenAddProposal } from '../util/proposals'; async function testTokenAddProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendTokenAddProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -43,14 +40,22 @@ async function testTokenAddProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); const propHash = keccak256(encodeTokenAddProposal(tokenAddProposal)); - const proposalType = {tokenaddproposal: tokenAddProposal.header.nonce} + const proposalType = { tokenaddproposal: tokenAddProposal.header.nonce }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -58,7 +63,7 @@ async function testTokenAddProposal() { } async function sendTokenAddProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -71,15 +76,21 @@ async function sendTokenAddProposal(api: ApiPromise) { console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'TokenAdd'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'TokenAdd' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/token/testTokenRemoveProposal.ts b/dkg-test-suite/src/evm/token/testTokenRemoveProposal.ts index a5fb3e5a6..417816613 100644 --- a/dkg-test-suite/src/evm/token/testTokenRemoveProposal.ts +++ b/dkg-test-suite/src/evm/token/testTokenRemoveProposal.ts @@ -14,26 +14,23 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; -import { - provider, - waitNfinalizedBlocks, -} from '../../utils'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; +import { provider, waitNfinalizedBlocks } from '../../utils'; import { encodeTokenRemoveProposal, registerResourceId, resourceId, signAndSendUtil, unsubSignedPropsUtil, -} from '../util/utils' -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {tokenRemoveProposal} from "../util/proposals"; +} from '../util/utils'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { tokenRemoveProposal } from '../util/proposals'; async function testTokenRemoveProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendTokenRemoveProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -42,13 +39,23 @@ async function testTokenRemoveProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); - const proposalType = {tokenremoveproposal: tokenRemoveProposal.header.nonce}; + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); + const proposalType = { + tokenremoveproposal: tokenRemoveProposal.header.nonce, + }; const propHash = keccak256(encodeTokenRemoveProposal(tokenRemoveProposal)); - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -56,7 +63,7 @@ async function testTokenRemoveProposal() { } async function sendTokenRemoveProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -69,15 +76,21 @@ async function sendTokenRemoveProposal(api: ApiPromise) { console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'TokenRemove'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'TokenRemove' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/util/proposals.ts b/dkg-test-suite/src/evm/util/proposals.ts index 4534faf26..a2c6277cc 100644 --- a/dkg-test-suite/src/evm/util/proposals.ts +++ b/dkg-test-suite/src/evm/util/proposals.ts @@ -27,7 +27,7 @@ import { SetTreasuryHandlerProposal, SetVerifierProposal, FeeRecipientUpdateProposal, -} from "./utils"; +} from './utils'; let nonce = Math.floor(Math.random() * 100); // Returns a random integer from 0 to 99; @@ -39,7 +39,8 @@ export const anchorUpdateProposal: AnchorUpdateProposal = { }, srcChainId: 5001, lastLeafIndex: 0, - merkleRoot: '0x0000000000000000000000000000000000000000000000000000000000000000', + merkleRoot: + '0x0000000000000000000000000000000000000000000000000000000000000000', }; export const tokenAddProposal: TokenAddProposal = { @@ -69,7 +70,6 @@ export const wrappingFeeUpdateProposal: WrappingFeeUpdateProposal = { newFee: '0xe69a847cd5bc0c9480ada0b339d7f0a8cac2b667', }; - export const minWithdrawalLimitProposal: MinWithdrawalLimitProposal = { header: { resourceId, @@ -125,4 +125,4 @@ export const feeRecipientUpdateProposal: FeeRecipientUpdateProposal = { nonce, }, newFeeRecipient: '0xe69a847cd5bc0c9480ada0b339d7f0a8cac2b667', -}; \ No newline at end of file +}; diff --git a/dkg-test-suite/src/evm/util/utils.ts b/dkg-test-suite/src/evm/util/utils.ts index c5d1257e9..2b2452071 100644 --- a/dkg-test-suite/src/evm/util/utils.ts +++ b/dkg-test-suite/src/evm/util/utils.ts @@ -15,11 +15,11 @@ * */ import { u8aToHex, hexToU8a, assert } from '@polkadot/util'; -import {ApiPromise} from "@polkadot/api"; -import {Bytes, Option} from "@polkadot/types"; -import {KeyringPair} from "@polkadot/keyring/types"; -import {Keyring} from "@polkadot/keyring"; -import {ethers} from "ethers"; +import { ApiPromise } from '@polkadot/api'; +import { Bytes, Option } from '@polkadot/types'; +import { KeyringPair } from '@polkadot/keyring/types'; +import { Keyring } from '@polkadot/keyring'; +import { ethers } from 'ethers'; const LE = true; const BE = false; @@ -122,7 +122,7 @@ function castToChainIdType(v: number): ChainIdType { * - last leaf index (4 bytes). * - merkle root (32 bytes). */ - export interface AnchorUpdateProposal { +export interface AnchorUpdateProposal { /** * The Anchor Proposal Header. * This is the first 40 bytes of the proposal. @@ -151,7 +151,9 @@ function castToChainIdType(v: number): ChainIdType { */ readonly target: string; } -export function encodeUpdateAnchorProposal(proposal: AnchorUpdateProposal): Uint8Array { +export function encodeUpdateAnchorProposal( + proposal: AnchorUpdateProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const updateProposal = new Uint8Array(40 + 42 + 32); updateProposal.set(header, 0); // 0 -> 40 @@ -165,7 +167,9 @@ export function encodeUpdateAnchorProposal(proposal: AnchorUpdateProposal): Uint updateProposal.set(target, 82); // 82 -> 114 return updateProposal; } -export function decodeUpdateAnchorProposal(data: Uint8Array): AnchorUpdateProposal { +export function decodeUpdateAnchorProposal( + data: Uint8Array +): AnchorUpdateProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const chainIdTypeInt = new DataView(data.buffer).getUint16(40, false); // 40 -> 42 const chainIdType = castToChainIdType(chainIdTypeInt); @@ -223,11 +227,13 @@ export function decodeTokenAddProposal(data: Uint8Array): TokenAddProposal { const newTokenAddress = u8aToHex(data.slice(40, 60)); // 40 -> 60 return { header, - newTokenAddress + newTokenAddress, }; } -export function encodeTokenRemoveProposal(proposal: TokenRemoveProposal): Uint8Array { +export function encodeTokenRemoveProposal( + proposal: TokenRemoveProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const tokenRemoveProposal = new Uint8Array(40 + 20); tokenRemoveProposal.set(header, 0); // 0 -> 40 @@ -236,7 +242,9 @@ export function encodeTokenRemoveProposal(proposal: TokenRemoveProposal): Uint8A return tokenRemoveProposal; } -export function decodeTokenRemoveProposal(data: Uint8Array): TokenRemoveProposal { +export function decodeTokenRemoveProposal( + data: Uint8Array +): TokenRemoveProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const removeTokenAddress = u8aToHex(data.slice(40, 60)); // 40 -> 60 return { @@ -271,7 +279,9 @@ export interface WrappingFeeUpdateProposal { readonly newFee: string; } -export function encodeWrappingFeeUpdateProposal(proposal: WrappingFeeUpdateProposal): Uint8Array { +export function encodeWrappingFeeUpdateProposal( + proposal: WrappingFeeUpdateProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const wrappingFeeUpdateProposal = new Uint8Array(40 + 1); wrappingFeeUpdateProposal.set(header, 0); // 0 -> 40 @@ -280,16 +290,17 @@ export function encodeWrappingFeeUpdateProposal(proposal: WrappingFeeUpdatePropo return wrappingFeeUpdateProposal; } -export function decodeWrappingFeeUpdateProposal(data: Uint8Array): WrappingFeeUpdateProposal { +export function decodeWrappingFeeUpdateProposal( + data: Uint8Array +): WrappingFeeUpdateProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const newFee = u8aToHex(data.slice(40, 41)); // 40 -> 41 return { header, - newFee + newFee, }; } - export interface MinWithdrawalLimitProposal { /** * The Wrapping Fee Update Proposal Header. @@ -303,7 +314,9 @@ export interface MinWithdrawalLimitProposal { readonly minWithdrawalLimitBytes: string; } -export function encodeMinWithdrawalLimitProposal(proposal: MinWithdrawalLimitProposal): Uint8Array { +export function encodeMinWithdrawalLimitProposal( + proposal: MinWithdrawalLimitProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const minWithdrawalLimitProposal = new Uint8Array(40 + 32); minWithdrawalLimitProposal.set(header, 0); // 0 -> 40 @@ -312,12 +325,14 @@ export function encodeMinWithdrawalLimitProposal(proposal: MinWithdrawalLimitPro return minWithdrawalLimitProposal; } -export function decodeMinWithDrawalLimitProposal(data: Uint8Array): MinWithdrawalLimitProposal { +export function decodeMinWithDrawalLimitProposal( + data: Uint8Array +): MinWithdrawalLimitProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const minWithdrawalLimitBytes = u8aToHex(data.slice(40, 72)); // 40 -> 72 return { header, - minWithdrawalLimitBytes + minWithdrawalLimitBytes, }; } @@ -334,7 +349,9 @@ export interface MaxDepositLimitProposal { readonly maxDepositLimitBytes: string; } -export function encodeMaxDepositLimitProposal(proposal: MaxDepositLimitProposal): Uint8Array { +export function encodeMaxDepositLimitProposal( + proposal: MaxDepositLimitProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const maxDepositLimitProposal = new Uint8Array(40 + 32); maxDepositLimitProposal.set(header, 0); // 0 -> 40 @@ -343,23 +360,25 @@ export function encodeMaxDepositLimitProposal(proposal: MaxDepositLimitProposal) return maxDepositLimitProposal; } -export function decodeMaxDepositLimitProposal(data: Uint8Array): MaxDepositLimitProposal { +export function decodeMaxDepositLimitProposal( + data: Uint8Array +): MaxDepositLimitProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const maxDepositLimitBytes = u8aToHex(data.slice(40, 72)); // 40 -> 72 return { header, - maxDepositLimitBytes + maxDepositLimitBytes, }; } export interface ResourceIdUpdateProposal { /** * The ResourceIdUpdateProposal Header. - * This is the first 40 bytes of the proposal. - * See `encodeProposalHeader` for more details. - */ + * This is the first 40 bytes of the proposal. + * See `encodeProposalHeader` for more details. + */ readonly header: ProposalHeader; - /** + /** * 32 bytes Hex-encoded string. */ readonly newResourceId: string; @@ -372,7 +391,9 @@ export interface ResourceIdUpdateProposal { */ readonly executionAddress: string; } -export function encodeResourceIdUpdateProposal(proposal: ResourceIdUpdateProposal): Uint8Array { +export function encodeResourceIdUpdateProposal( + proposal: ResourceIdUpdateProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const resourceIdUpdateProposal = new Uint8Array(40 + 32 + 20 + 20); resourceIdUpdateProposal.set(header, 0); // 0 -> 40 @@ -384,7 +405,9 @@ export function encodeResourceIdUpdateProposal(proposal: ResourceIdUpdateProposa resourceIdUpdateProposal.set(executionAddress, 92); // 72 -> 112 return resourceIdUpdateProposal; } -export function decodeResourceIdUpdateProposal(data: Uint8Array): ResourceIdUpdateProposal { +export function decodeResourceIdUpdateProposal( + data: Uint8Array +): ResourceIdUpdateProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const newResourceId = u8aToHex(data.slice(40, 72)); // 40 -> 72 const handlerAddress = u8aToHex(data.slice(72, 92)); // 72 -> 92 @@ -393,7 +416,7 @@ export function decodeResourceIdUpdateProposal(data: Uint8Array): ResourceIdUpda header, newResourceId, handlerAddress, - executionAddress + executionAddress, }; } @@ -410,7 +433,9 @@ export interface SetTreasuryHandlerProposal { readonly newTreasuryHandler: string; } -export function encodeSetTreasuryHandlerProposal(proposal: SetTreasuryHandlerProposal): Uint8Array { +export function encodeSetTreasuryHandlerProposal( + proposal: SetTreasuryHandlerProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const setTreasuryHandlerProposal = new Uint8Array(40 + 20); setTreasuryHandlerProposal.set(header, 0); // 0 -> 40 @@ -419,12 +444,14 @@ export function encodeSetTreasuryHandlerProposal(proposal: SetTreasuryHandlerPro return setTreasuryHandlerProposal; } -export function decodeSetTreasuryHandlerProposal(data: Uint8Array): SetTreasuryHandlerProposal { +export function decodeSetTreasuryHandlerProposal( + data: Uint8Array +): SetTreasuryHandlerProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const newTreasuryHandler = u8aToHex(data.slice(40, 60)); // 40 -> 60 return { header, - newTreasuryHandler + newTreasuryHandler, }; } @@ -441,7 +468,9 @@ export interface SetVerifierProposal { readonly newVerifier: string; } -export function encodeSetVerifierProposal(proposal: SetVerifierProposal): Uint8Array { +export function encodeSetVerifierProposal( + proposal: SetVerifierProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const setVerifierProposal = new Uint8Array(40 + 20); setVerifierProposal.set(header, 0); // 0 -> 40 @@ -450,12 +479,14 @@ export function encodeSetVerifierProposal(proposal: SetVerifierProposal): Uint8A return setVerifierProposal; } -export function decodeSetVerifierProposal(data: Uint8Array): SetVerifierProposal { +export function decodeSetVerifierProposal( + data: Uint8Array +): SetVerifierProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const newVerifier = u8aToHex(data.slice(40, 60)); // 40 -> 60 return { header, - newVerifier + newVerifier, }; } @@ -472,7 +503,9 @@ export interface FeeRecipientUpdateProposal { readonly newFeeRecipient: string; } -export function encodeFeeRecipientUpdateProposal(proposal: FeeRecipientUpdateProposal): Uint8Array { +export function encodeFeeRecipientUpdateProposal( + proposal: FeeRecipientUpdateProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const feeRecipientUpdateProposal = new Uint8Array(40 + 20); feeRecipientUpdateProposal.set(header, 0); // 0 -> 40 @@ -481,22 +514,24 @@ export function encodeFeeRecipientUpdateProposal(proposal: FeeRecipientUpdatePro return feeRecipientUpdateProposal; } -export function decodeFeeRecipientUpdateProposal(data: Uint8Array): FeeRecipientUpdateProposal { +export function decodeFeeRecipientUpdateProposal( + data: Uint8Array +): FeeRecipientUpdateProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const newFeeRecipient = u8aToHex(data.slice(40, 60)); // 40 -> 60 return { header, - newFeeRecipient + newFeeRecipient, }; } export interface RescueTokensProposal { /** * The Rescue Token Proposals Header. - **/ + **/ readonly header: ProposalHeader; - /** + /** * 20 bytes Hex-encoded string. */ readonly tokenAddress: string; @@ -510,7 +545,9 @@ export interface RescueTokensProposal { readonly amount: string; } -export function encodeRescueTokensProposal(proposal: RescueTokensProposal): Uint8Array { +export function encodeRescueTokensProposal( + proposal: RescueTokensProposal +): Uint8Array { const header = encodeProposalHeader(proposal.header); const rescueTokensProposal = new Uint8Array(40 + 20 + 20 + 32); rescueTokensProposal.set(header, 0); // 0 -> 40 @@ -525,7 +562,9 @@ export function encodeRescueTokensProposal(proposal: RescueTokensProposal): Uint return rescueTokensProposal; } -export function decodeRescueTokensProposal(data: Uint8Array): RescueTokensProposal { +export function decodeRescueTokensProposal( + data: Uint8Array +): RescueTokensProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const tokenAddress = u8aToHex(data.slice(40, 60)); // 40 -> 60 const toAddress = u8aToHex(data.slice(60, 80)); // 60 -> 80 @@ -534,8 +573,8 @@ export function decodeRescueTokensProposal(data: Uint8Array): RescueTokensPropos header, tokenAddress, toAddress, - amount - } + amount, + }; } /** @@ -545,7 +584,11 @@ export function decodeRescueTokensProposal(data: Uint8Array): RescueTokensPropos * - 2 bytes of the `chainIdType` encoded as the last 2 bytes just before the `chainId`. * - 4 bytes of the `chainId` which is the last 4 bytes. */ -export function makeResourceId(addr: string, chainIdType: ChainIdType, chainId: number): string { +export function makeResourceId( + addr: string, + chainIdType: ChainIdType, + chainId: number +): string { const rId = new Uint8Array(32); const address = hexToU8a(addr).slice(0, 20); rId.set(address, 6); // 6 -> 26 @@ -569,28 +612,41 @@ function _testEncodeDecode() { }; const srcChainId = 0xbabe; const lastLeafIndex = 0xfeed; - const merkleRoot = '0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'; + const merkleRoot = + '0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'; const updateProposal: AnchorUpdateProposal = { header, chainIdType, srcChainId, lastLeafIndex, merkleRoot, - target: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000', + target: + '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000', }; const headerEncoded = encodeProposalHeader(header); const headerDecoded = decodeProposalHeader(headerEncoded); assert(headerDecoded.resourceId === resourceId, 'resourceId'); - assert(headerDecoded.functionSignature === functionSignature, 'functionSignature'); + assert( + headerDecoded.functionSignature === functionSignature, + 'functionSignature' + ); assert(headerDecoded.nonce === nonce, 'nonce'); const updateProposalEncoded = encodeUpdateAnchorProposal(updateProposal); - const updateProposalDecoded = decodeUpdateAnchorProposal(updateProposalEncoded); + const updateProposalDecoded = decodeUpdateAnchorProposal( + updateProposalEncoded + ); assert(updateProposalDecoded.header.resourceId === resourceId, 'resourceId'); - assert(updateProposalDecoded.header.functionSignature === functionSignature, 'functionSignature'); + assert( + updateProposalDecoded.header.functionSignature === functionSignature, + 'functionSignature' + ); assert(updateProposalDecoded.header.nonce === nonce, 'nonce'); assert(updateProposalDecoded.srcChainId === srcChainId, 'srcChainId'); - assert(updateProposalDecoded.lastLeafIndex === lastLeafIndex, 'lastLeafIndex'); + assert( + updateProposalDecoded.lastLeafIndex === lastLeafIndex, + 'lastLeafIndex' + ); assert(updateProposalDecoded.merkleRoot === merkleRoot, 'merkleRoot'); } @@ -606,36 +662,54 @@ export const newResourceId = makeResourceId( 5002 ); -export async function signAndSendUtil(api: ApiPromise, proposalCall: any, alice: KeyringPair) { - const unsub = await api.tx.sudo.sudo(proposalCall).signAndSend(alice, ({events = [], status}) => { - // console.log(`Current status is: ${status.type}`); +export async function signAndSendUtil( + api: ApiPromise, + proposalCall: any, + alice: KeyringPair +) { + const unsub = await api.tx.sudo + .sudo(proposalCall) + .signAndSend(alice, ({ events = [], status }) => { + // console.log(`Current status is: ${status.type}`); - if (status.isFinalized) { - // console.log(`Transaction included at blockHash ${status.asFinalized}`); + if (status.isFinalized) { + // console.log(`Transaction included at blockHash ${status.asFinalized}`); - events.forEach(({phase, event: {data, method, section}}) => { - // console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); - }); + events.forEach(({ phase, event: { data, method, section } }) => { + // console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); + }); - unsub(); - } - }); + unsub(); + } + }); } -export async function unsubSignedPropsUtil(api: ApiPromise, chainIdType: any, dkgPubKey: any, proposalType: any, propHash: any) { +export async function unsubSignedPropsUtil( + api: ApiPromise, + chainIdType: any, + dkgPubKey: any, + proposalType: any, + propHash: any +) { return await api.query.dKGProposalHandler.signedProposals( chainIdType, proposalType, (res: any) => { if (res) { const parsedResult = JSON.parse(JSON.stringify(res)); - console.log(`Signed ${JSON.stringify(proposalType)} prop: ${JSON.stringify(parsedResult)}`); + console.log( + `Signed ${JSON.stringify(proposalType)} prop: ${JSON.stringify( + parsedResult + )}` + ); if (parsedResult) { const sig = parsedResult.signed.signature; console.log(`Signature: ${sig}`); - const recoveredPubKey = ethers.utils.recoverPublicKey(propHash, sig).substr(2); + const recoveredPubKey = ethers.utils + .recoverPublicKey(propHash, sig) + .substr(2); console.log(`Recovered public key: ${recoveredPubKey}`); console.log(`DKG public key: ${dkgPubKey}`); @@ -661,22 +735,24 @@ export async function registerResourceId(api: ApiPromise) { console.log(`Resource id ${resourceId} is already registered, skipping`); return; } - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const call = api.tx.dKGProposals.setResource(resourceId, '0x00'); console.log('Registering resource id'); - const unsub = await api.tx.sudo.sudo(call).signAndSend(alice, ({events = [], status}) => { - console.log(`Current status is: ${status.type}`); + const unsub = await api.tx.sudo + .sudo(call) + .signAndSend(alice, ({ events = [], status }) => { + console.log(`Current status is: ${status.type}`); - if (status.isFinalized) { - console.log(`Transaction included at blockHash ${status.asFinalized}`); + if (status.isFinalized) { + console.log(`Transaction included at blockHash ${status.asFinalized}`); - events.forEach(({phase, event: {data, method, section}}) => { - console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); - }); + events.forEach(({ phase, event: { data, method, section } }) => { + console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); + }); - unsub(); - } - }); -} \ No newline at end of file + unsub(); + } + }); +} diff --git a/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMaxDepositLimitUpdateProposal.ts b/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMaxDepositLimitUpdateProposal.ts index c9cffa2ad..0edd59640 100644 --- a/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMaxDepositLimitUpdateProposal.ts +++ b/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMaxDepositLimitUpdateProposal.ts @@ -14,26 +14,23 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { encodeMaxDepositLimitProposal, - registerResourceId, + registerResourceId, resourceId, - signAndSendUtil, - unsubSignedPropsUtil + signAndSendUtil, + unsubSignedPropsUtil, } from '../util/utils'; -import { - provider, - waitNfinalizedBlocks -} from '../../utils'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {maxDepositLimitProposal} from "../util/proposals"; +import { provider, waitNfinalizedBlocks } from '../../utils'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { maxDepositLimitProposal } from '../util/proposals'; async function testMaxDepositLimitUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendMaxDepositLimitUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -42,14 +39,26 @@ async function testMaxDepositLimitUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); - const propHash = keccak256(encodeMaxDepositLimitProposal(maxDepositLimitProposal)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); + const propHash = keccak256( + encodeMaxDepositLimitProposal(maxDepositLimitProposal) + ); - const proposalType = {maxdepositlimitupdateproposal: maxDepositLimitProposal.header.nonce} + const proposalType = { + maxdepositlimitupdateproposal: maxDepositLimitProposal.header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -57,7 +66,7 @@ async function testMaxDepositLimitUpdateProposal() { } async function sendMaxDepositLimitUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -70,15 +79,21 @@ async function sendMaxDepositLimitUpdateProposal(api: ApiPromise) { console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'MaxDepositLimitUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'MaxDepositLimitUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMinWithdrawalLimitUpdateProposal.ts b/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMinWithdrawalLimitUpdateProposal.ts index f9ba1b818..80b9bec43 100644 --- a/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMinWithdrawalLimitUpdateProposal.ts +++ b/dkg-test-suite/src/evm/v-anchor-configurable-limit/testMinWithdrawalLimitUpdateProposal.ts @@ -14,26 +14,23 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { encodeMinWithdrawalLimitProposal, - registerResourceId, + registerResourceId, resourceId, - signAndSendUtil, - unsubSignedPropsUtil + signAndSendUtil, + unsubSignedPropsUtil, } from '../util/utils'; -import { - provider, - waitNfinalizedBlocks -} from '../../utils'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {minWithdrawalLimitProposal} from "../util/proposals"; +import { provider, waitNfinalizedBlocks } from '../../utils'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { minWithdrawalLimitProposal } from '../util/proposals'; async function testMinWithdrawalLimitUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendMinWithdrawalLimitUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -42,14 +39,26 @@ async function testMinWithdrawalLimitUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5002}); - const propHash = keccak256(encodeMinWithdrawalLimitProposal(minWithdrawalLimitProposal)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5002, + }); + const propHash = keccak256( + encodeMinWithdrawalLimitProposal(minWithdrawalLimitProposal) + ); - const proposalType = {minwithdrawallimitproposal: minWithdrawalLimitProposal.header.nonce} + const proposalType = { + minwithdrawallimitproposal: minWithdrawalLimitProposal.header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -57,7 +66,7 @@ async function testMinWithdrawalLimitUpdateProposal() { } async function sendMinWithdrawalLimitUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -65,20 +74,28 @@ async function sendMinWithdrawalLimitUpdateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeMinWithdrawalLimitProposal(minWithdrawalLimitProposal)); + const prop = u8aToHex( + encodeMinWithdrawalLimitProposal(minWithdrawalLimitProposal) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${resourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {Evm: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'MinWithdrawalLimitUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + Evm: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'MinWithdrawalLimitUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/keyRefresh.ts b/dkg-test-suite/src/keyRefresh.ts index 502d78abf..cb01d8290 100644 --- a/dkg-test-suite/src/keyRefresh.ts +++ b/dkg-test-suite/src/keyRefresh.ts @@ -39,8 +39,14 @@ async function dkg_refresh() { await waitNfinalizedBlocks(api, 10, 120); const nextKey = await api.query.dkg.nextDKGPublicKey(); const dkgPublicKey = await api.query.dkg.dKGPublicKey(); - assert(JSON.parse(nextKey.toString() as any)[1], 'Next public key should be on chain'); - assert(JSON.parse(dkgPublicKey.toString() as any)[1], 'DKG public key should be on chain'); + assert( + JSON.parse(nextKey.toString() as any)[1], + 'Next public key should be on chain' + ); + assert( + JSON.parse(dkgPublicKey.toString() as any)[1], + 'DKG public key should be on chain' + ); await waitNfinalizedBlocks(api, 37, 37 * 12); const nextPublicKeySignature = await api.query.dkg.nextPublicKeySignature(); assert( @@ -57,17 +63,23 @@ async function dkg_refresh() { // Queued authority should have changed because we chilled Charlie and forced a new era const nextKey1 = await api.query.dkg.nextDKGPublicKey(); assert( - JSON.parse(nextKey.toString() as any)[1] !== JSON.parse(nextKey1.toString() as any)[1], + JSON.parse(nextKey.toString() as any)[1] !== + JSON.parse(nextKey1.toString() as any)[1], 'Next public key should be different' ); await waitNfinalizedBlocks(api, 150, 150 * 5); - // Three Key refreshes should have occured by now and the length of used signatures should be two + // Three Key refreshes should have occurred by now and the length of used signatures should be two let usedSignatures = await api.query.dkg.usedSignatures(); - let parsedSignatures: string[] = (usedSignatures.toHuman() as string[]).slice(1); + let parsedSignatures: string[] = (usedSignatures.toHuman() as string[]).slice( + 1 + ); - assert(parsedSignatures.length == 2, 'There should be two used signatures on chain'); + assert( + parsedSignatures.length == 2, + 'There should be two used signatures on chain' + ); } // Run diff --git a/dkg-test-suite/src/localEvm.ts b/dkg-test-suite/src/localEvm.ts index 883eb4acc..cac4808a7 100644 --- a/dkg-test-suite/src/localEvm.ts +++ b/dkg-test-suite/src/localEvm.ts @@ -19,7 +19,11 @@ import { ethers } from 'ethers'; import { Server } from 'ganache'; import { Bridges, VBridge } from '@webb-tools/protocol-solidity'; import { VBridgeInput } from '@webb-tools/vbridge'; -import { BridgeInput, DeployerConfig, GovernorConfig } from '@webb-tools/interfaces'; +import { + BridgeInput, + DeployerConfig, + GovernorConfig, +} from '@webb-tools/interfaces'; import { MintableToken, GovernedTokenWrapper } from '@webb-tools/tokens'; import { fetchComponentsFromFilePaths } from '@webb-tools/utils'; import path from 'path'; @@ -88,7 +92,10 @@ export class LocalChain { otherWallet: ethers.Signer, initialGovernors: GovernorConfig ): Promise { - const gitRoot = child.execSync('git rev-parse --show-toplevel').toString().trim(); + const gitRoot = child + .execSync('git rev-parse --show-toplevel') + .toString() + .trim(); localWallet.connect(this.provider()); otherWallet.connect(otherChain.provider()); const bridgeInput: BridgeInput = { @@ -139,7 +146,10 @@ export class LocalChain { otherWallet: ethers.Signer, initialGovernors: GovernorConfig ): Promise { - const gitRoot = child.execSync('git rev-parse --show-toplevel').toString().trim(); + const gitRoot = child + .execSync('git rev-parse --show-toplevel') + .toString() + .trim(); localWallet.connect(this.provider()); otherWallet.connect(otherChain.provider()); let webbTokens1 = new Map(); @@ -147,20 +157,20 @@ export class LocalChain { webbTokens1.set(otherChain.chainId, null!); // create the config for the bridge const vBridgeInput = { - vAnchorInputs: { - asset: { - [this.chainId]: [localToken.contract.address], - [otherChain.chainId]: [otherToken.contract.address], - } - }, - chainIDs: [this.chainId, otherChain.chainId], - webbTokens: webbTokens1 - } + vAnchorInputs: { + asset: { + [this.chainId]: [localToken.contract.address], + [otherChain.chainId]: [otherToken.contract.address], + }, + }, + chainIDs: [this.chainId, otherChain.chainId], + webbTokens: webbTokens1, + }; const deployerConfig: DeployerConfig = { [this.chainId]: localWallet, [otherChain.chainId]: otherWallet, - } + }; const smallCircuitZkComponents = await fetchComponentsFromFilePaths( path.resolve( diff --git a/dkg-test-suite/src/substrate/testAnchorCreateProposal.ts b/dkg-test-suite/src/substrate/testAnchorCreateProposal.ts index f97e49fd2..a65b8c110 100644 --- a/dkg-test-suite/src/substrate/testAnchorCreateProposal.ts +++ b/dkg-test-suite/src/substrate/testAnchorCreateProposal.ts @@ -14,29 +14,26 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { ChainIdType, - encodeSubstrateProposal, + encodeSubstrateProposal, makeResourceId, - registerResourceId, - signAndSendUtil, + registerResourceId, + signAndSendUtil, unsubSignedPropsUtil, substratePalletResourceId, } from './util/utils'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; -import {ethers} from 'ethers'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {getAnchorCreateProposal} from "./util/proposals"; +import { provider, waitNfinalizedBlocks } from '../utils'; +import { ethers } from 'ethers'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { getAnchorCreateProposal } from './util/proposals'; async function testAnchorCreateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendAnchorCreateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -45,14 +42,26 @@ async function testAnchorCreateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5002}); - const propHash = keccak256(encodeSubstrateProposal(getAnchorCreateProposal(api), 3000)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5002, + }); + const propHash = keccak256( + encodeSubstrateProposal(getAnchorCreateProposal(api), 3000) + ); - const proposalType = {anchorcreateproposal: getAnchorCreateProposal(api).header.nonce} + const proposalType = { + anchorcreateproposal: getAnchorCreateProposal(api).header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 50000)); @@ -60,7 +69,7 @@ async function testAnchorCreateProposal() { } async function sendAnchorCreateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -68,20 +77,28 @@ async function sendAnchorCreateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeSubstrateProposal(getAnchorCreateProposal(api), 3000)); + const prop = u8aToHex( + encodeSubstrateProposal(getAnchorCreateProposal(api), 3000) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${substratePalletResourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'AnchorCreate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'AnchorCreate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/substrate/testAnchorUpdateProposal.ts b/dkg-test-suite/src/substrate/testAnchorUpdateProposal.ts index d016c78af..38294ca05 100644 --- a/dkg-test-suite/src/substrate/testAnchorUpdateProposal.ts +++ b/dkg-test-suite/src/substrate/testAnchorUpdateProposal.ts @@ -14,29 +14,26 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { ChainIdType, - encodeSubstrateProposal, + encodeSubstrateProposal, makeResourceId, - registerResourceId, - signAndSendUtil, + registerResourceId, + signAndSendUtil, unsubSignedPropsUtil, substratePalletResourceId, } from './util/utils'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; -import {ethers} from 'ethers'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {getAnchorUpdateProposal} from "./util/proposals"; +import { provider, waitNfinalizedBlocks } from '../utils'; +import { ethers } from 'ethers'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { getAnchorUpdateProposal } from './util/proposals'; async function testAnchorUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendAnchorUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -45,14 +42,26 @@ async function testAnchorUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5002}); - const propHash = keccak256(encodeSubstrateProposal(getAnchorUpdateProposal(api), 3000)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5002, + }); + const propHash = keccak256( + encodeSubstrateProposal(getAnchorUpdateProposal(api), 3000) + ); - const proposalType = {anchorupdateproposal: getAnchorUpdateProposal(api).header.nonce} + const proposalType = { + anchorupdateproposal: getAnchorUpdateProposal(api).header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 50000)); @@ -60,7 +69,7 @@ async function testAnchorUpdateProposal() { } async function sendAnchorUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -68,20 +77,28 @@ async function sendAnchorUpdateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeSubstrateProposal(getAnchorUpdateProposal(api), 3000)); + const prop = u8aToHex( + encodeSubstrateProposal(getAnchorUpdateProposal(api), 3000) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${substratePalletResourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'AnchorUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'AnchorUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/substrate/testResourceIdUpdateProposal.ts b/dkg-test-suite/src/substrate/testResourceIdUpdateProposal.ts index dff53e8e1..cf362e762 100644 --- a/dkg-test-suite/src/substrate/testResourceIdUpdateProposal.ts +++ b/dkg-test-suite/src/substrate/testResourceIdUpdateProposal.ts @@ -14,26 +14,23 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { - encodeResourceIdUpdateProposal, - registerResourceId, - signAndSendUtil, + encodeResourceIdUpdateProposal, + registerResourceId, + signAndSendUtil, unsubSignedPropsUtil, substratePalletResourceId, } from './util/utils'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {getResourceIdUpdateProposal} from "./util/proposals"; +import { provider, waitNfinalizedBlocks } from '../utils'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { getResourceIdUpdateProposal } from './util/proposals'; async function testResourceIdUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendResourceIdUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -42,14 +39,26 @@ async function testResourceIdUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5002}); - const propHash = keccak256(encodeResourceIdUpdateProposal(getResourceIdUpdateProposal(api), 3000)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5002, + }); + const propHash = keccak256( + encodeResourceIdUpdateProposal(getResourceIdUpdateProposal(api), 3000) + ); - const proposalType = {resourceidupdateproposal: getResourceIdUpdateProposal(api).header.nonce} + const proposalType = { + resourceidupdateproposal: getResourceIdUpdateProposal(api).header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 50000)); @@ -57,7 +66,7 @@ async function testResourceIdUpdateProposal() { } async function sendResourceIdUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -65,20 +74,28 @@ async function sendResourceIdUpdateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeResourceIdUpdateProposal(getResourceIdUpdateProposal(api), 3000)); + const prop = u8aToHex( + encodeResourceIdUpdateProposal(getResourceIdUpdateProposal(api), 3000) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${substratePalletResourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'ResourceIdUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'ResourceIdUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/substrate/testWrappingFeeUpdateProposal.ts b/dkg-test-suite/src/substrate/testWrappingFeeUpdateProposal.ts index 13067a27f..73c4f19a3 100644 --- a/dkg-test-suite/src/substrate/testWrappingFeeUpdateProposal.ts +++ b/dkg-test-suite/src/substrate/testWrappingFeeUpdateProposal.ts @@ -14,28 +14,25 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { ChainIdType, - encodeSubstrateProposal, + encodeSubstrateProposal, makeResourceId, - registerResourceId, - signAndSendUtil, + registerResourceId, + signAndSendUtil, unsubSignedPropsUtil, substratePalletResourceId, } from './util/utils'; -import { - provider, - waitNfinalizedBlocks, -} from '../utils'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {getWrappingFeeUpdateProposal} from "./util/proposals"; +import { provider, waitNfinalizedBlocks } from '../utils'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { getWrappingFeeUpdateProposal } from './util/proposals'; async function testWrappingFeeUpdateProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendWrappingFeeUpdateProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -44,14 +41,26 @@ async function testWrappingFeeUpdateProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5002}); - const propHash = keccak256(encodeSubstrateProposal(getWrappingFeeUpdateProposal(api), 3000)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5002, + }); + const propHash = keccak256( + encodeSubstrateProposal(getWrappingFeeUpdateProposal(api), 3000) + ); - const proposalType = {wrappingfeeupdateproposal: getWrappingFeeUpdateProposal(api).header.nonce} + const proposalType = { + wrappingfeeupdateproposal: getWrappingFeeUpdateProposal(api).header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 50000)); @@ -59,7 +68,7 @@ async function testWrappingFeeUpdateProposal() { } async function sendWrappingFeeUpdateProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -67,20 +76,28 @@ async function sendWrappingFeeUpdateProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeSubstrateProposal(getWrappingFeeUpdateProposal(api), 3000)); + const prop = u8aToHex( + encodeSubstrateProposal(getWrappingFeeUpdateProposal(api), 3000) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${substratePalletResourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'WrappingFeeUpdate'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'WrappingFeeUpdate' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/substrate/token/testTokenAddProposal.ts b/dkg-test-suite/src/substrate/token/testTokenAddProposal.ts index d76ee2212..e72989401 100644 --- a/dkg-test-suite/src/substrate/token/testTokenAddProposal.ts +++ b/dkg-test-suite/src/substrate/token/testTokenAddProposal.ts @@ -14,29 +14,26 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { ChainIdType, encodeSubstrateProposal, makeResourceId, - registerResourceId, - signAndSendUtil, + registerResourceId, + signAndSendUtil, unsubSignedPropsUtil, substratePalletResourceId, } from '../util/utils'; -import { - provider, - waitNfinalizedBlocks, -} from '../../utils'; -import {ethers} from 'ethers'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {getTokenAddProposal} from "../util/proposals"; +import { provider, waitNfinalizedBlocks } from '../../utils'; +import { ethers } from 'ethers'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { getTokenAddProposal } from '../util/proposals'; async function testTokenAddProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendTokenAddProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -45,14 +42,26 @@ async function testTokenAddProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5002}); - const propHash = keccak256(encodeSubstrateProposal(getTokenAddProposal(api), 3000)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5002, + }); + const propHash = keccak256( + encodeSubstrateProposal(getTokenAddProposal(api), 3000) + ); - const proposalType = {tokenaddproposal: getTokenAddProposal(api).header.nonce} + const proposalType = { + tokenaddproposal: getTokenAddProposal(api).header.nonce, + }; - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 50000)); @@ -60,7 +69,7 @@ async function testTokenAddProposal() { } async function sendTokenAddProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -68,20 +77,28 @@ async function sendTokenAddProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeSubstrateProposal(getTokenAddProposal(api), 3000)); + const prop = u8aToHex( + encodeSubstrateProposal(getTokenAddProposal(api), 3000) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${substratePalletResourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'TokenAdd'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'TokenAdd' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/substrate/token/testTokenRemoveProposal.ts b/dkg-test-suite/src/substrate/token/testTokenRemoveProposal.ts index f4fca6697..57616a804 100644 --- a/dkg-test-suite/src/substrate/token/testTokenRemoveProposal.ts +++ b/dkg-test-suite/src/substrate/token/testTokenRemoveProposal.ts @@ -14,8 +14,8 @@ * limitations under the License. * */ -import {ApiPromise} from '@polkadot/api'; -import {Keyring} from '@polkadot/keyring'; +import { ApiPromise } from '@polkadot/api'; +import { Keyring } from '@polkadot/keyring'; import { ChainIdType, encodeSubstrateProposal, @@ -25,17 +25,14 @@ import { unsubSignedPropsUtil, substratePalletResourceId, } from '../util/utils'; -import { - provider, - waitNfinalizedBlocks, -} from '../../utils'; -import {keccak256} from '@ethersproject/keccak256'; -import {ECPair} from 'ecpair'; -import {assert, u8aToHex} from '@polkadot/util'; -import {getTokenRemoveProposal} from "../util/proposals"; +import { provider, waitNfinalizedBlocks } from '../../utils'; +import { keccak256 } from '@ethersproject/keccak256'; +import { ECPair } from 'ecpair'; +import { assert, u8aToHex } from '@polkadot/util'; +import { getTokenRemoveProposal } from '../util/proposals'; async function testTokenRemoveProposal() { - const api = await ApiPromise.create({provider}); + const api = await ApiPromise.create({ provider }); await registerResourceId(api); await sendTokenRemoveProposal(api); console.log('Waiting for the DKG to Sign the proposal'); @@ -44,13 +41,25 @@ async function testTokenRemoveProposal() { const dkgPubKeyCompressed: any = await api.query.dkg.dKGPublicKey(); const dkgPubKey = ECPair.fromPublicKey( Buffer.from(dkgPubKeyCompressed[1].toHex().substr(2), 'hex'), - {compressed: false} + { compressed: false } ).publicKey.toString('hex'); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5002}); - const proposalType = {tokenremoveproposal: getTokenRemoveProposal(api).header.nonce}; - const propHash = keccak256(encodeSubstrateProposal(getTokenRemoveProposal(api), 3000)); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5002, + }); + const proposalType = { + tokenremoveproposal: getTokenRemoveProposal(api).header.nonce, + }; + const propHash = keccak256( + encodeSubstrateProposal(getTokenRemoveProposal(api), 3000) + ); - const unsubSignedProps: any = await unsubSignedPropsUtil(api, chainIdType, dkgPubKey, proposalType, propHash); + const unsubSignedProps: any = await unsubSignedPropsUtil( + api, + chainIdType, + dkgPubKey, + proposalType, + propHash + ); await new Promise((resolve) => setTimeout(resolve, 50000)); @@ -58,7 +67,7 @@ async function testTokenRemoveProposal() { } async function sendTokenRemoveProposal(api: ApiPromise) { - const keyring = new Keyring({type: 'sr25519'}); + const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const [authoritySetId, dkgPubKey] = await Promise.all([ @@ -66,20 +75,28 @@ async function sendTokenRemoveProposal(api: ApiPromise) { api.query.dkg.dKGPublicKey(), ]); - const prop = u8aToHex(encodeSubstrateProposal(getTokenRemoveProposal(api), 3000)); + const prop = u8aToHex( + encodeSubstrateProposal(getTokenRemoveProposal(api), 3000) + ); console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); console.log(`Resource id is: ${substratePalletResourceId}`); console.log(`Proposal is: ${prop}`); - const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', {SUBSTRATE: 5001}); - const kind = api.createType('DkgRuntimePrimitivesProposalProposalKind', 'TokenRemove'); + const chainIdType = api.createType('WebbProposalsHeaderTypedChainId', { + SUBSTRATE: 5001, + }); + const kind = api.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'TokenRemove' + ); const proposal = api.createType('DkgRuntimePrimitivesProposal', { Unsigned: { kind: kind, - data: prop - } + data: prop, + }, }); - const proposalCall = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); + const proposalCall = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal(proposal); await signAndSendUtil(api, proposalCall, alice); } diff --git a/dkg-test-suite/src/substrate/util/proposals.ts b/dkg-test-suite/src/substrate/util/proposals.ts index 08f8d7bc7..c77594d34 100644 --- a/dkg-test-suite/src/substrate/util/proposals.ts +++ b/dkg-test-suite/src/substrate/util/proposals.ts @@ -18,85 +18,80 @@ import { SubstrateProposal, substratePalletResourceId, ResourceIdUpdateProposal, -} from "./utils"; -import {ApiPromise} from '@polkadot/api'; - +} from './utils'; +import { ApiPromise } from '@polkadot/api'; let nonce = Math.floor(Math.random() * 100); // Returns a random integer from 0 to 99; export const getWrappingFeeUpdateProposal = (api: ApiPromise) => { - const wrappingFeeUpdateProposal: SubstrateProposal = - { + const wrappingFeeUpdateProposal: SubstrateProposal = { header: { resourceId: substratePalletResourceId, functionSignature: '0x00000000', nonce, }, // TODO: this is a dummy call, should replace with actual call - call: api.tx.system.remark("execute wrapping fee update proposal").toString(), - } + call: api.tx.system + .remark('execute wrapping fee update proposal') + .toString(), + }; return wrappingFeeUpdateProposal; -} +}; export const getTokenAddProposal = (api: ApiPromise) => { - const tokenAddProposal: SubstrateProposal = - { + const tokenAddProposal: SubstrateProposal = { header: { resourceId: substratePalletResourceId, functionSignature: '0x00000000', nonce, }, // TODO: this is a dummy call, should replace with actual call - call: api.tx.system.remark("execute token add proposal").toString(), - } + call: api.tx.system.remark('execute token add proposal').toString(), + }; return tokenAddProposal; -} +}; export const getTokenRemoveProposal = (api: ApiPromise) => { - const tokenRemoveProposal: SubstrateProposal = - { + const tokenRemoveProposal: SubstrateProposal = { header: { resourceId: substratePalletResourceId, functionSignature: '0x00000000', nonce, }, // TODO: this is a dummy call, should replace with actual call - call: api.tx.system.remark("execute token remove proposal").toString(), - } + call: api.tx.system.remark('execute token remove proposal').toString(), + }; return tokenRemoveProposal; -} +}; export const getAnchorUpdateProposal = (api: ApiPromise) => { - const anchorUpdateProposal: SubstrateProposal = - { + const anchorUpdateProposal: SubstrateProposal = { header: { resourceId: substratePalletResourceId, functionSignature: '0x00000000', nonce, }, // TODO: this is a dummy call, should replace with actual call - call: api.tx.system.remark("execute anchor update proposal").toString(), - } + call: api.tx.system.remark('execute anchor update proposal').toString(), + }; return anchorUpdateProposal; -} +}; export const getAnchorCreateProposal = (api: ApiPromise) => { - const anchorCreateProposal: SubstrateProposal = - { + const anchorCreateProposal: SubstrateProposal = { header: { resourceId: substratePalletResourceId, functionSignature: '0x00000000', nonce, }, // TODO: this is a dummy call, should replace with actual call - call: api.tx.system.remark("execute anchor update proposal").toString(), - } + call: api.tx.system.remark('execute anchor update proposal').toString(), + }; return anchorCreateProposal; -} +}; export const getResourceIdUpdateProposal = (api: ApiPromise) => { - const resourceIdUpdateProposal: ResourceIdUpdateProposal = - { + const resourceIdUpdateProposal: ResourceIdUpdateProposal = { header: { resourceId: substratePalletResourceId, functionSignature: '0x00000000', @@ -104,7 +99,6 @@ export const getResourceIdUpdateProposal = (api: ApiPromise) => { }, resourceIdToRegister: substratePalletResourceId, methodName: 'execute_wrapping_fee_proposal', - - } + }; return resourceIdUpdateProposal; -} \ No newline at end of file +}; diff --git a/dkg-test-suite/src/substrate/util/utils.ts b/dkg-test-suite/src/substrate/util/utils.ts index 9c4df18e1..2026b26d5 100644 --- a/dkg-test-suite/src/substrate/util/utils.ts +++ b/dkg-test-suite/src/substrate/util/utils.ts @@ -123,7 +123,10 @@ function castToChainIdType(v: number): ChainIdType { * - 2 bytes of the `chainIdType` encoded as the last 2 bytes just before the `chainId`. * - 4 bytes of the `chainId` which is the last 4 bytes. */ -export function makeResourceId(chainIdType: ChainIdType, chainId: number): string { +export function makeResourceId( + chainIdType: ChainIdType, + chainId: number +): string { const rId = new Uint8Array(32); const view = new DataView(rId.buffer); view.setUint16(26, chainIdType, BE); // 26 -> 28 @@ -182,31 +185,40 @@ export interface ResourceIdUpdateProposal { readonly methodName: string; } -export function encodeResourceIdUpdateProposal(proposal: ResourceIdUpdateProposal, lengthOfMethodName: number): Uint8Array { +export function encodeResourceIdUpdateProposal( + proposal: ResourceIdUpdateProposal, + lengthOfMethodName: number +): Uint8Array { const header = encodeProposalHeader(proposal.header); const resourceIdToRegister = hexToU8a(proposal.resourceIdToRegister); - const resourceIdUpdateProposal = new Uint8Array(40 + 32 + lengthOfMethodName); + const resourceIdUpdateProposal = new Uint8Array(40 + 32 + lengthOfMethodName); resourceIdUpdateProposal.set(header, 0); // 0 -> 40 resourceIdUpdateProposal.set(resourceIdToRegister, 40); // 40 -> 72 const hexifiedMethodName = new Buffer(proposal.methodName).toString('hex'); - const methodName = hexToU8a(hexifiedMethodName).slice(0,); + const methodName = hexToU8a(hexifiedMethodName).slice(0); resourceIdUpdateProposal.set(methodName, 72); // 72 -> END return resourceIdUpdateProposal; } -export function decodeResourceIdUpdateProposal(data: Uint8Array): ResourceIdUpdateProposal { +export function decodeResourceIdUpdateProposal( + data: Uint8Array +): ResourceIdUpdateProposal { const header = decodeProposalHeader(data.slice(0, 40)); // 0 -> 40 const resourceIdToRegister = u8aToHex(data.slice(40, 72)); // 40 -> 72 - const hexifiedMethodName = u8aToHex(data.slice(72, )); // 72 -> END - const decodedMethodName = new Buffer(hexifiedMethodName, 'hex').toString(); + const hexifiedMethodName = u8aToHex(data.slice(72)); // 72 -> END + const decodedMethodName = new Buffer(hexifiedMethodName, 'hex').toString(); return { header, resourceIdToRegister, - methodName: decodedMethodName + methodName: decodedMethodName, }; } -export async function signAndSendUtil(api: ApiPromise, proposalCall: any, alice: KeyringPair) { +export async function signAndSendUtil( + api: ApiPromise, + proposalCall: any, + alice: KeyringPair +) { const unsub = await api.tx.sudo .sudo(proposalCall) .signAndSend(alice, ({ events = [], status }) => { @@ -237,13 +249,19 @@ export async function unsubSignedPropsUtil( (res: any) => { if (res) { const parsedResult = JSON.parse(JSON.stringify(res)); - console.log(`Signed ${JSON.stringify(proposalType)} prop: ${JSON.stringify(parsedResult)}`); + console.log( + `Signed ${JSON.stringify(proposalType)} prop: ${JSON.stringify( + parsedResult + )}` + ); if (parsedResult) { const sig = parsedResult.signed.signature; console.log(`Signature: ${sig}`); - const recoveredPubKey = ethers.utils.recoverPublicKey(propHash, sig).substr(2); + const recoveredPubKey = ethers.utils + .recoverPublicKey(propHash, sig) + .substr(2); console.log(`Recovered public key: ${recoveredPubKey}`); console.log(`DKG public key: ${dkgPubKey}`); @@ -260,32 +278,42 @@ export async function unsubSignedPropsUtil( } ); } -export const substratePalletResourceId = makeResourceId(ChainIdType.SUBSTRATE, 5002); +export const substratePalletResourceId = makeResourceId( + ChainIdType.SUBSTRATE, + 5002 +); export async function registerResourceId(api: ApiPromise) { // quick check if the resourceId is already registered const res = await api.query.dKGProposals.resources(substratePalletResourceId); const val = new Option(api.registry, Bytes, res); if (val.isSome) { - console.log(`Resource id ${substratePalletResourceId} is already registered, skipping`); + console.log( + `Resource id ${substratePalletResourceId} is already registered, skipping` + ); return; } const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); - const call = api.tx.dKGProposals.setResource(substratePalletResourceId, '0x00'); + const call = api.tx.dKGProposals.setResource( + substratePalletResourceId, + '0x00' + ); console.log('Registering resource id'); - const unsub = await api.tx.sudo.sudo(call).signAndSend(alice, ({ events = [], status }) => { - console.log(`Current status is: ${status.type}`); + const unsub = await api.tx.sudo + .sudo(call) + .signAndSend(alice, ({ events = [], status }) => { + console.log(`Current status is: ${status.type}`); - if (status.isFinalized) { - console.log(`Transaction included at blockHash ${status.asFinalized}`); + if (status.isFinalized) { + console.log(`Transaction included at blockHash ${status.asFinalized}`); - events.forEach(({ phase, event: { data, method, section } }) => { - console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); - }); + events.forEach(({ phase, event: { data, method, section } }) => { + console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); + }); - unsub(); - } - }); + unsub(); + } + }); } diff --git a/dkg-test-suite/src/testDirectProposal.ts b/dkg-test-suite/src/testDirectProposal.ts index 44ec69503..d1308ca15 100644 --- a/dkg-test-suite/src/testDirectProposal.ts +++ b/dkg-test-suite/src/testDirectProposal.ts @@ -43,35 +43,38 @@ async function testDirectProposal() { { compressed: false } ).publicKey.toString('hex'); - const unsubSignedProps: any = await api.query.dKGProposalHandler.signedProposals( - 1, - { tokenupdateproposal: 1 }, - (res: any) => { - if (res) { - const parsedResult = JSON.parse(JSON.stringify(res)); - console.log(`Signed prop: ${parsedResult}`); - assert(parsedResult, 'Signed proposal should be on chain'); - - if (parsedResult) { - const sig = parsedResult.tokenUpdateSigned.signature; - console.log(`Signature: ${sig}`); - - const propHash = keccak256(tokenUpdateProp); - const recoveredPubKey = ethers.utils.recoverPublicKey(propHash, sig).substr(2); - console.log(`Recovered public key: ${recoveredPubKey}`); - console.log(`DKG public key: ${dkgPubKey}`); - - assert(recoveredPubKey == dkgPubKey, 'Public keys should match'); - if (recoveredPubKey == dkgPubKey) { - console.log(`Public keys match`); - } else { - console.error(`Public keys do not match`); - process.exit(); + const unsubSignedProps: any = + await api.query.dKGProposalHandler.signedProposals( + 1, + { tokenupdateproposal: 1 }, + (res: any) => { + if (res) { + const parsedResult = JSON.parse(JSON.stringify(res)); + console.log(`Signed prop: ${parsedResult}`); + assert(parsedResult, 'Signed proposal should be on chain'); + + if (parsedResult) { + const sig = parsedResult.tokenUpdateSigned.signature; + console.log(`Signature: ${sig}`); + + const propHash = keccak256(tokenUpdateProp); + const recoveredPubKey = ethers.utils + .recoverPublicKey(propHash, sig) + .substr(2); + console.log(`Recovered public key: ${recoveredPubKey}`); + console.log(`DKG public key: ${dkgPubKey}`); + + assert(recoveredPubKey == dkgPubKey, 'Public keys should match'); + if (recoveredPubKey == dkgPubKey) { + console.log(`Public keys match`); + } else { + console.error(`Public keys do not match`); + process.exit(); + } } } } - } - ); + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -97,19 +100,21 @@ async function sendSudoProposal(api: ApiPromise) { data: `0x${raw_data}`, }, }); - const unsub = await api.tx.sudo.sudo(call).signAndSend(alice, ({ events = [], status }) => { - console.log(`Current status is: ${status.type}`); + const unsub = await api.tx.sudo + .sudo(call) + .signAndSend(alice, ({ events = [], status }) => { + console.log(`Current status is: ${status.type}`); - if (status.isFinalized) { - console.log(`Transaction included at blockHash ${status.asFinalized}`); + if (status.isFinalized) { + console.log(`Transaction included at blockHash ${status.asFinalized}`); - events.forEach(({ phase, event: { data, method, section } }) => { - console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); - }); + events.forEach(({ phase, event: { data, method, section } }) => { + console.log(`\t' ${phase}: ${section}.${method}:: ${data}`); + }); - unsub(); - } - }); + unsub(); + } + }); } // Run diff --git a/dkg-test-suite/src/testVAnchorConfigurableLimitsProposal.ts b/dkg-test-suite/src/testVAnchorConfigurableLimitsProposal.ts index 6dff61427..bf948ee7b 100644 --- a/dkg-test-suite/src/testVAnchorConfigurableLimitsProposal.ts +++ b/dkg-test-suite/src/testVAnchorConfigurableLimitsProposal.ts @@ -43,35 +43,38 @@ async function testDirectProposal() { { compressed: false } ).publicKey.toString('hex'); - const unsubSignedProps: any = await api.query.dKGProposalHandler.signedProposals( - 1, - { tokenupdateproposal: 1 }, - (res: any) => { - if (res) { - const parsedResult = JSON.parse(JSON.stringify(res)); - console.log(`Signed prop: ${parsedResult}`); - assert(parsedResult, 'Signed proposal should be on chain'); - - if (parsedResult) { - const sig = parsedResult.tokenUpdateSigned.signature; - console.log(`Signature: ${sig}`); - - const propHash = keccak256(tokenUpdateProp); - const recoveredPubKey = ethers.utils.recoverPublicKey(propHash, sig).substr(2); - console.log(`Recovered public key: ${recoveredPubKey}`); - console.log(`DKG public key: ${dkgPubKey}`); - - assert(recoveredPubKey == dkgPubKey, 'Public keys should match'); - if (recoveredPubKey == dkgPubKey) { - console.log(`Public keys match`); - } else { - console.error(`Public keys do not match`); - process.exit(); + const unsubSignedProps: any = + await api.query.dKGProposalHandler.signedProposals( + 1, + { tokenupdateproposal: 1 }, + (res: any) => { + if (res) { + const parsedResult = JSON.parse(JSON.stringify(res)); + console.log(`Signed prop: ${parsedResult}`); + assert(parsedResult, 'Signed proposal should be on chain'); + + if (parsedResult) { + const sig = parsedResult.tokenUpdateSigned.signature; + console.log(`Signature: ${sig}`); + + const propHash = keccak256(tokenUpdateProp); + const recoveredPubKey = ethers.utils + .recoverPublicKey(propHash, sig) + .substr(2); + console.log(`Recovered public key: ${recoveredPubKey}`); + console.log(`DKG public key: ${dkgPubKey}`); + + assert(recoveredPubKey == dkgPubKey, 'Public keys should match'); + if (recoveredPubKey == dkgPubKey) { + console.log(`Public keys match`); + } else { + console.error(`Public keys do not match`); + process.exit(); + } } } } - } - ); + ); await new Promise((resolve) => setTimeout(resolve, 20000)); @@ -92,11 +95,12 @@ async function sendSudoProposal(api: ApiPromise) { console.log(`DKG authority set id: ${authoritySetId}`); console.log(`DKG pub key: ${dkgPubKey}`); - const callMaxDepositLimit = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal({ - MaxDepositLimitUpdate: { - data: `0x${raw_data}`, - }, - }); + const callMaxDepositLimit = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal({ + MaxDepositLimitUpdate: { + data: `0x${raw_data}`, + }, + }); const unsubMaxDeposit = await api.tx.sudo .sudo(callMaxDepositLimit) .signAndSend(alice, ({ events = [], status }) => { @@ -113,11 +117,12 @@ async function sendSudoProposal(api: ApiPromise) { } }); - const callMinWithdrawalLimit = api.tx.dKGProposalHandler.forceSubmitUnsignedProposal({ - MinWithdrawalLimitUpdate: { - data: `0x${raw_data}`, - }, - }); + const callMinWithdrawalLimit = + api.tx.dKGProposalHandler.forceSubmitUnsignedProposal({ + MinWithdrawalLimitUpdate: { + data: `0x${raw_data}`, + }, + }); const unsubMinWithdrawalLimit = await api.tx.sudo .sudo(callMinWithdrawalLimit) .signAndSend(alice, ({ events = [], status }) => { diff --git a/dkg-test-suite/src/utils.ts b/dkg-test-suite/src/utils.ts index 09a8160eb..bb6a78041 100644 --- a/dkg-test-suite/src/utils.ts +++ b/dkg-test-suite/src/utils.ts @@ -14,7 +14,8 @@ * limitations under the License. * */ -import { ApiPromise, Keyring, WsProvider } from '@polkadot/api'; +import { ApiPromise, Keyring } from '@polkadot/api'; +import { SubmittableExtrinsic } from '@polkadot/api/types'; import { Bytes, Option } from '@polkadot/types'; import { u8aToHex, hexToU8a, assert } from '@polkadot/util'; import child from 'child_process'; @@ -23,7 +24,7 @@ import { ethers } from 'ethers'; export const ALICE = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; -export const provider = new WsProvider('ws://127.0.0.1:9944'); +export const endpoint = 'ws://127.0.0.1:9944'; export async function sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); @@ -43,7 +44,11 @@ export const listenOneBlock = async function (api: ApiPromise) { }); }; -export const waitNfinalizedBlocks = async function (api: ApiPromise, n: number, timeout: number) { +export const waitNfinalizedBlocks = async function ( + api: ApiPromise, + n: number, + timeout: number +) { return new Promise(async (resolve, _reject) => { let count = 0; const unsubscribe = await api.rpc.chain.subscribeNewHeads((header) => { @@ -66,7 +71,9 @@ export const waitNfinalizedBlocks = async function (api: ApiPromise, n: number, export async function fastForward( api: ApiPromise, n: number, - { delayBetweenBlocks }: { delayBetweenBlocks?: number } = { delayBetweenBlocks: 5 } + { delayBetweenBlocks }: { delayBetweenBlocks?: number } = { + delayBetweenBlocks: 5, + } ): Promise { for (let i = 0; i < n; i++) { const createEmpty = true; @@ -80,7 +87,9 @@ export async function fastForward( export async function fastForwardTo( api: ApiPromise, blockNumber: number, - { delayBetweenBlocks }: { delayBetweenBlocks?: number } = { delayBetweenBlocks: 0 } + { delayBetweenBlocks }: { delayBetweenBlocks?: number } = { + delayBetweenBlocks: 0, + } ): Promise { const currentBlockNumber = await api.rpc.chain.getHeader(); const diff = blockNumber - currentBlockNumber.number.toNumber(); @@ -129,12 +138,18 @@ const __NODE_STATE: { }; export function startStandaloneNode( authority: 'alice' | 'bob' | 'charlie', - options: { tmp: boolean; printLogs: boolean } = { tmp: true, printLogs: false } + options: { tmp: boolean; printLogs: boolean } = { + tmp: true, + printLogs: false, + } ): child.ChildProcess { if (__NODE_STATE[authority].isRunning) { return __NODE_STATE[authority].process!; } - const gitRoot = child.execSync('git rev-parse --show-toplevel').toString().trim(); + const gitRoot = child + .execSync('git rev-parse --show-toplevel') + .toString() + .trim(); const nodePath = `${gitRoot}/target/release/dkg-standalone-node`; const ports = { alice: { ws: 9944, http: 9933, p2p: 30333 }, @@ -146,12 +161,15 @@ export function startStandaloneNode( [ `--${authority}`, options.printLogs ? '-linfo' : '-lerror', - options.tmp ? '--tmp' : '', + options.tmp ? `--base-path=./tmp/${authority}` : '', `--ws-port=${ports[authority].ws}`, `--rpc-port=${ports[authority].http}`, `--port=${ports[authority].p2p}`, ...(authority == 'alice' - ? ['--node-key', '0000000000000000000000000000000000000000000000000000000000000001'] + ? [ + '--node-key', + '0000000000000000000000000000000000000000000000000000000000000001', + ] : [ '--bootnodes', `/ip4/127.0.0.1/tcp/${ports['alice'].p2p}/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp`, @@ -200,11 +218,15 @@ export async function waitForTheNextSession(api: ApiPromise): Promise { return waitForEvent(api, 'session', 'NewSession'); } -export async function waitForTheNextDkgPublicKey(api: ApiPromise): Promise { +export async function waitForTheNextDkgPublicKey( + api: ApiPromise +): Promise { return waitForEvent(api, 'dkg', 'NextPublicKeySubmitted'); } -export async function waitForTheNextDkgPublicKeySignature(api: ApiPromise): Promise { +export async function waitForTheNextDkgPublicKeySignature( + api: ApiPromise +): Promise { return waitForEvent(api, 'dkg', 'NextPublicKeySignatureSubmitted'); } @@ -212,7 +234,9 @@ export async function waitForPublicKeyToChange(api: ApiPromise): Promise { return waitForEvent(api, 'dkg', 'PublicKeyChanged'); } -export async function waitForPublicKeySignatureToChange(api: ApiPromise): Promise { +export async function waitForPublicKeySignatureToChange( + api: ApiPromise +): Promise { return waitForEvent(api, 'dkg', 'PublicKeySignatureChanged'); } @@ -237,8 +261,9 @@ export async function waitForEvent( const { event } = record; if (event.section === pallet && event.method === eventVariant) { if (dataQuery) { - const dataKeys = (event.toHuman() as any).data - .map((elt: any) => Object.keys(elt)[0]); + const dataKeys = (event.toHuman() as any).data.map( + (elt: any) => Object.keys(elt)[0] + ); if (dataKeys.includes(dataQuery.key)) { handleUnsub(); } @@ -255,7 +280,9 @@ export async function waitForEvent( * Wait until the DKG Public Key is available and return it uncompressed without the `04` prefix byte. * @param api the current connected api. */ -export async function waitUntilDKGPublicKeyStoredOnChain(api: ApiPromise): Promise<`0x${string}`> { +export async function waitUntilDKGPublicKeyStoredOnChain( + api: ApiPromise +): Promise<`0x${string}`> { return new Promise(async (resolve, _reject) => { const unsubscribe = await api.rpc.chain.subscribeNewHeads(async () => { const dkgKey = await fetchDkgPublicKey(api); @@ -272,7 +299,9 @@ export async function waitUntilDKGPublicKeyStoredOnChain(api: ApiPromise): Promi * returns `null` if the key is not yet available. * @param api the current connected api. */ -export async function fetchDkgPublicKey(api: ApiPromise): Promise<`0x${string}` | null> { +export async function fetchDkgPublicKey( + api: ApiPromise +): Promise<`0x${string}` | null> { const res = await api.query.dkg.dKGPublicKey(); const json = res.toJSON() as [number, string]; if (json && json[1] !== '0x') { @@ -292,7 +321,9 @@ export async function fetchDkgPublicKey(api: ApiPromise): Promise<`0x${string}` * returns `null` if the key is not yet available. * @param api the current connected api. */ -export async function fetchDkgPublicKeySignature(api: ApiPromise): Promise<`0x${string}` | null> { +export async function fetchDkgPublicKeySignature( + api: ApiPromise +): Promise<`0x${string}` | null> { const sig = await api.query.dkg.dKGPublicKeySignature(); if (!sig.isEmpty) { return sig.toHex(); @@ -307,34 +338,55 @@ export async function fetchDkgRefreshNonce(api: ApiPromise): Promise { } export async function triggerDkgManualRefresh(api: ApiPromise): Promise { + const call = api.tx.dkg.manualRefresh(); + return sudoTx(api, call); +} + +export async function sudoTx( + api: ApiPromise, + call: SubmittableExtrinsic<'promise'> +): Promise { const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); - const call = api.tx.dkg.manualRefresh(); - const unsub = await api.tx.sudo.sudo(call).signAndSend(alice, ({ status }) => { - if (status.isFinalized) { - unsub(); - } + return new Promise(async (resolve, _reject) => { + const unsub = await api.tx.sudo + .sudo(call) + .signAndSend(alice, ({ status }) => { + if (status.isFinalized) { + unsub(); + resolve(); + } + }); }); } -export async function triggerDkgManuaIncrementNonce(api: ApiPromise): Promise { +export async function triggerDkgManuaIncrementNonce( + api: ApiPromise +): Promise { const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); const call = api.tx.dkg.manualIncrementNonce(); - const unsub = await api.tx.sudo.sudo(call).signAndSend(alice, ({ status }) => { - if (status.isFinalized) { - unsub(); - } - }); + const unsub = await api.tx.sudo + .sudo(call) + .signAndSend(alice, ({ status }) => { + if (status.isFinalized) { + unsub(); + } + }); } -export function ethAddressFromUncompressedPublicKey(publicKey: `0x${string}`): `0x${string}` { +export function ethAddressFromUncompressedPublicKey( + publicKey: `0x${string}` +): `0x${string}` { const pubKeyHash = ethers.utils.keccak256(publicKey); // we hash it. const address = ethers.utils.getAddress(`0x${pubKeyHash.slice(-40)}`); // take the last 20 bytes and convert it to an address. return address as `0x${string}`; } -export async function registerResourceId(api: ApiPromise, resourceId: string): Promise { +export async function registerResourceId( + api: ApiPromise, + resourceId: string +): Promise { // quick check if the resourceId is already registered const res = await api.query.dKGProposals.resources(resourceId); const val = new Option(api.registry, Bytes, res); @@ -346,24 +398,30 @@ export async function registerResourceId(api: ApiPromise, resourceId: string): P const call = api.tx.dKGProposals.setResource(resourceId, '0x00'); return new Promise(async (resolve, reject) => { - const unsub = await api.tx.sudo.sudo(call).signAndSend(alice, ({ status, events }) => { - if (status.isFinalized) { - unsub(); - const success = events.find(({ event }) => api.events.system.ExtrinsicSuccess.is(event)); - if (success) { - resolve(); - } else { - reject(new Error('Failed to register resourceId')); + const unsub = await api.tx.sudo + .sudo(call) + .signAndSend(alice, ({ status, events }) => { + if (status.isFinalized) { + unsub(); + const success = events.find(({ event }) => + api.events.system.ExtrinsicSuccess.is(event) + ); + if (success) { + resolve(); + } else { + reject(new Error('Failed to register resourceId')); + } } - } - }); + }); }); } /** * Encode function Signature in the Solidity format. */ export function encodeFunctionSignature(func: string): `0x${string}` { - return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(func)).slice(0, 10) as `0x${string}`; + return ethers.utils + .keccak256(ethers.utils.toUtf8Bytes(func)) + .slice(0, 10) as `0x${string}`; } const LE = true; @@ -467,7 +525,11 @@ function castToChainIdType(v: number): ChainIdType { * - 2 bytes of the `chainIdType` encoded as the last 2 bytes just before the `chainId`. * - 4 bytes of the `chainId` which is the last 4 bytes. */ -export function makeResourceId(addr: string, chainIdType: ChainIdType, chainId: number): string { +export function makeResourceId( + addr: string, + chainIdType: ChainIdType, + chainId: number +): string { const rId = new Uint8Array(32); const address = hexToU8a(addr).slice(0, 20); rId.set(address, 6); // 6 -> 26 diff --git a/dkg-test-suite/tests/blueprint.test.ts b/dkg-test-suite/tests/blueprint.test.ts index ce090069b..9eb436264 100644 --- a/dkg-test-suite/tests/blueprint.test.ts +++ b/dkg-test-suite/tests/blueprint.test.ts @@ -16,8 +16,10 @@ */ // just a blueprint test using jest +import { expect } from 'chai'; + describe('Blueprint test', () => { - it('should pass', () => { - expect(true).toBe(true); - }); + it('should pass', () => { + expect(true).to.be.true; + }); }); diff --git a/dkg-test-suite/tests/e2e/keygenChanges.test.ts b/dkg-test-suite/tests/e2e/keygenChanges.test.ts new file mode 100644 index 000000000..53ef69f55 --- /dev/null +++ b/dkg-test-suite/tests/e2e/keygenChanges.test.ts @@ -0,0 +1,246 @@ +/* + * Copyright 2022 Webb Technologies Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// A test suite for testing Keygen changes in the DKG System +// and to observe the behavior of the system. +// +// When we start, we expect the Keygen to equal to 2, then we wait for the first keygen to finish, +// then we update the Keygen to 3, expecting the system to now work with 3 Authorities. +// We then wait for the second keygen to finish, and then we update the Keygen back to 2, +// expecting the system to now work with 2 Authorities. + +import fs from 'fs'; +import { expect } from 'chai'; +import { ChildProcess, execSync } from 'child_process'; +import { + startStandaloneNode, + sudoTx, + waitForTheNextSession, + fetchDkgPublicKey, + sleep, + waitForTheNextDkgPublicKey, + endpoint, +} from '../../src/utils'; +import { ApiPromise, WsProvider } from '@polkadot/api'; +import { Vec } from '@polkadot/types'; +import { BLOCK_TIME } from '../../src/constants'; + +describe('Keygen Changes Flow', function () { + // 8 sessions should be more than enough for the test to complete + this.timeout(80 * BLOCK_TIME); + // 4 session. + this.slow(40 * BLOCK_TIME); + // fail fast, since tests are dependent on each other. + this.bail(true); + + let aliceNode: ChildProcess; + let bobNode: ChildProcess; + let charlieNode: ChildProcess; + let api: ApiPromise; + + before(async () => { + // delete the tmp directory if it exists. + const gitRoot = execSync('git rev-parse --show-toplevel').toString().trim(); + const tmpDir = `${gitRoot}/tmp`; + if (fs.existsSync(tmpDir)) { + fs.rmSync(tmpDir, { recursive: true }); + } + aliceNode = startStandaloneNode('alice', { tmp: true, printLogs: false }); + bobNode = startStandaloneNode('bob', { tmp: true, printLogs: false }); + charlieNode = startStandaloneNode('charlie', { + tmp: true, + printLogs: false, + }); + + api = await ApiPromise.create({ + provider: new WsProvider(endpoint), + }); + }); + + // This test requires at least 3 sessions. + // 3 sessions = 3 * 10 blocks = 30 blocks = 30 * 6 seconds = 180 seconds. + it('should be able to increase the Keygen Threshold', async () => { + // first query the current keygen threshold value. + const currentKeygenThreshold = await api.query.dkg.keygenThreshold(); + expect(currentKeygenThreshold.toHex()).to.equal( + '0x0002', + 'Keygen threshold at the start should be 2' + ); + // then, we shall query the current best authorities. + const currentBestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const currentBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + currentBestAuthoritiesValue.toU8a() + ); + expect(currentBestAuthorities.length).to.equal( + 2, + 'Current best authorities should be 2' + ); + // and we wait for the first keygen to be completed. + await waitForTheNextDkgPublicKey(api); + // next, is to increase the keygen threshold. + const increaseKeygenThreshold = api.tx.dkg.setKeygenThreshold(3); + await sudoTx(api, increaseKeygenThreshold); + // and then, we query for the pending keygen threshold. + // we expect the pending keygen threshold to be 3. + const pendingKeygenThreshold = await api.query.dkg.pendingKeygenThreshold(); + expect(pendingKeygenThreshold.toHex()).to.equal( + '0x0003', + 'Pending keygen threshold should be 3' + ); + // now we wait for the next session, we expect the next keygen threshold to be 3. + // we also expect the next best authorities to be 3. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const nextKeygenThreshold = await api.query.dkg.nextKeygenThreshold(); + expect(nextKeygenThreshold.toHex()).to.equal( + '0x0003', + 'Next keygen threshold should be 3' + ); + const nextBestAuthoritiesValue = await api.query.dkg.nextBestAuthorities(); + const nextBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + nextBestAuthoritiesValue.toU8a() + ); + expect(nextBestAuthorities.length).to.equal( + 3, + 'Next best authorities should be 3' + ); + + // now, wait for the next session, we expect the keygen threshold to be 3. + // and we expect the best authorities to be 3. + // Also, the DKG rotation should still working as expected. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const keygenThreshold = await api.query.dkg.keygenThreshold(); + expect(keygenThreshold.toHex()).to.equal( + '0x0003', + 'Keygen threshold should be now equal to 3' + ); + const bestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const bestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + bestAuthoritiesValue.toU8a() + ); + expect(bestAuthorities.length).to.equal(3, 'Best authorities should be 3'); + // query the current DKG public key. + const currentDkgPublicKey = await fetchDkgPublicKey(api); + // now wait for the next session, we expect the dkg to rotate. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + // query the next DKG public key. + const newDkgPublicKey = await fetchDkgPublicKey(api); + // we expect the new dkg public key to be different from the current dkg public key. + expect(newDkgPublicKey).to.not.equal( + currentDkgPublicKey, + 'DKG public key should be different after a rotation' + ); + }); + + // This test requires at least 3 sessions. + // 3 sessions = 3 * 10 blocks = 30 blocks = 30 * 6 seconds = 180 seconds. + // **NOTE**: this test is also dependent on the previous test. + it('should be able to decrease the Keygen Threshold', async () => { + // first query the current keygen threshold value. + const currentKeygenThreshold = await api.query.dkg.keygenThreshold(); + expect(currentKeygenThreshold.toHex()).to.equal( + '0x0003', + 'Keygen threshold at the start should be 3' + ); + // then, we shall query the current best authorities. + const currentBestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const currentBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + currentBestAuthoritiesValue.toU8a() + ); + expect(currentBestAuthorities.length).to.equal( + 3, + 'Current best authorities should be 3' + ); + // next, is to decrease the keygen threshold. + const decreaseKeygenThreshold = api.tx.dkg.setKeygenThreshold(2); + await sudoTx(api, decreaseKeygenThreshold); + // and then, we query for the pending keygen threshold. + // we expect the pending keygen threshold to be 2. + const pendingKeygenThreshold = await api.query.dkg.pendingKeygenThreshold(); + expect(pendingKeygenThreshold.toHex()).to.equal( + '0x0002', + 'Pending keygen threshold should be 2' + ); + // now we wait for the next session, we expect the next keygen threshold to be 2. + // we also expect the next best authorities to be 2. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const nextKeygenThreshold = await api.query.dkg.nextKeygenThreshold(); + expect(nextKeygenThreshold.toHex()).to.equal( + '0x0002', + 'Next keygen threshold should be 2' + ); + const nextBestAuthoritiesValue = await api.query.dkg.nextBestAuthorities(); + const nextBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + nextBestAuthoritiesValue.toU8a() + ); + expect(nextBestAuthorities.length).to.equal( + 2, + 'Next best authorities should be 2' + ); + + // now, wait for the next session, we expect the keygen threshold to be 2. + // and we expect the best authorities to be 2. + // Also, the DKG rotation should still working as expected. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const keygenThreshold = await api.query.dkg.keygenThreshold(); + expect(keygenThreshold.toHex()).to.equal( + '0x0002', + 'Keygen threshold should be now equal to 2' + ); + const bestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const bestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + bestAuthoritiesValue.toU8a() + ); + expect(bestAuthorities.length).to.equal(2, 'Best authorities should be 2'); + // query the current DKG public key. + const currentDkgPublicKey = await fetchDkgPublicKey(api); + // now wait for the next session, we expect the dkg to rotate. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + // query the next DKG public key. + const newDkgPublicKey = await fetchDkgPublicKey(api); + // we expect the new dkg public key to be different from the current dkg public key. + expect(newDkgPublicKey).to.not.equal( + currentDkgPublicKey, + 'DKG public key should be different after a rotation' + ); + }); + + after(async () => { + await api?.disconnect(); + aliceNode?.kill('SIGINT'); + bobNode?.kill('SIGINT'); + charlieNode?.kill('SIGINT'); + await sleep(BLOCK_TIME * 2); + }); +}); diff --git a/dkg-test-suite/tests/e2e/misbehaviourReporting.test.ts b/dkg-test-suite/tests/e2e/misbehaviourReporting.test.ts new file mode 100644 index 000000000..0e903720c --- /dev/null +++ b/dkg-test-suite/tests/e2e/misbehaviourReporting.test.ts @@ -0,0 +1,281 @@ +/* + * Copyright 2022 Webb Technologies Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// A test suite for testing Misbehaviour in the DKG System +// and to observe the behavior of the system. +// +// When we start, we expect the Keygen to equal to 2, then we wait for the first keygen to finish, +// then we update the Keygen to 3, expecting the system to now work with 3 Authorities. +// Next, we shutdown one of the authorities, we expect the system to report a misbehaviour, +// then, we expect the system to adjust the Keygen to 2, expecting the system to now work with 2 Authorities. +// +// Next, we start the misbehaving authority again, and unjail it, then adjust the Keygen to 3, +// expecting the system to now work with 3 Authorities again. + +import fs from 'fs'; +import { expect } from 'chai'; +import { ChildProcess, execSync } from 'child_process'; +import { + startStandaloneNode, + sudoTx, + waitForTheNextSession, + sleep, + waitForTheNextDkgPublicKey, + waitForEvent, + fetchDkgPublicKey, + endpoint, +} from '../../src/utils'; +import { ApiPromise, Keyring, WsProvider } from '@polkadot/api'; +import { Vec } from '@polkadot/types'; +import { BLOCK_TIME } from '../../src/constants'; + +// Requires total of 8 sessions to complete. +describe('Misbehavior Flow', function () { + // 10 sessions should be more than enough for the test to complete + this.timeout(100 * BLOCK_TIME); + // 5 session. + this.slow(50 * BLOCK_TIME); + // fail fast, since tests are dependent on each other. + this.bail(true); + + let aliceNode: ChildProcess; + let bobNode: ChildProcess; + let charlieNode: ChildProcess; + let api: ApiPromise; + + before(async () => { + // delete the tmp directory if it exists. + const gitRoot = execSync('git rev-parse --show-toplevel').toString().trim(); + const tmpDir = `${gitRoot}/tmp`; + if (fs.existsSync(tmpDir)) { + fs.rmSync(tmpDir, { recursive: true }); + } + aliceNode = startStandaloneNode('alice', { tmp: true, printLogs: false }); + bobNode = startStandaloneNode('bob', { tmp: true, printLogs: false }); + charlieNode = startStandaloneNode('charlie', { + tmp: true, + printLogs: false, + }); + + api = await ApiPromise.create({ + provider: new WsProvider(endpoint), + }); + }); + + // This test requires at least 4 sessions. + // 4 sessions = 4 * 10 blocks = 40 blocks = 40 * 6 seconds = 240 seconds. + it('should report misbehaviour and update the keygen threshold', async () => { + // first query the current keygen threshold value. + const currentKeygenThreshold = await api.query.dkg.keygenThreshold(); + expect(currentKeygenThreshold.toHex()).to.equal( + '0x0002', + 'Keygen threshold at the start should be 2' + ); + // then, we shall query the current best authorities. + const currentBestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const currentBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + currentBestAuthoritiesValue.toU8a() + ); + expect(currentBestAuthorities.length).to.equal( + 2, + 'Current best authorities should be 2' + ); + // and we wait for the first keygen to be completed. + await waitForTheNextDkgPublicKey(api); + // next, is to increase the keygen threshold. + const increaseKeygenThreshold = api.tx.dkg.setKeygenThreshold(3); + await sudoTx(api, increaseKeygenThreshold); + // and then, we query for the pending keygen threshold. + // we expect the pending keygen threshold to be 3. + const pendingKeygenThreshold = await api.query.dkg.pendingKeygenThreshold(); + expect(pendingKeygenThreshold.toHex()).to.equal( + '0x0003', + 'Pending keygen threshold should be 3' + ); + // now we wait for the next session, we expect the next keygen threshold to be 3. + // we also expect the next best authorities to be 3. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const nextKeygenThreshold = await api.query.dkg.nextKeygenThreshold(); + expect(nextKeygenThreshold.toHex()).to.equal( + '0x0003', + 'Next keygen threshold should be 3' + ); + const nextBestAuthoritiesValue = await api.query.dkg.nextBestAuthorities(); + const nextBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + nextBestAuthoritiesValue.toU8a() + ); + expect(nextBestAuthorities.length).to.equal( + 3, + 'Next best authorities should be 3' + ); + + // now, wait for the next session, we expect the keygen threshold to be 3. + // and we expect the best authorities to be 3. + // Also, the DKG rotation should still working as expected. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const keygenThreshold = await api.query.dkg.keygenThreshold(); + expect(keygenThreshold.toHex()).to.equal( + '0x0003', + 'Keygen threshold should be now equal to 3' + ); + const bestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const bestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + bestAuthoritiesValue.toU8a() + ); + expect(bestAuthorities.length).to.equal(3, 'Best authorities should be 3'); + // Now, we shall shutdown one of the authorities. + // + // We will kill charlie's node. + charlieNode.kill('SIGINT'); + // Now, we should expect the system to report misbehaviour. + // and we should expect the keygen threshold to be 2. + // and we should expect the best authorities to be 2. + // Then we also expect a new Keygen to happen. + await waitForEvent(api, 'dkg', 'MisbehaviourReportsSubmitted'); + await sleep(BLOCK_TIME * 1); + // then wait for 2 sessions. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + // now we observe the changes. + const keygenThresholdAfterMisbehaviour = + await api.query.dkg.keygenThreshold(); + expect(keygenThresholdAfterMisbehaviour.toHex()).to.equal( + '0x0002', + 'Keygen threshold after misbehaviour should be now equal to 2' + ); + const bestAuthoritiesValueAfterMisbehaviour = + await api.query.dkg.bestAuthorities(); + const bestAuthoritiesAfterMisbehaviour = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + bestAuthoritiesValueAfterMisbehaviour.toU8a() + ); + expect(bestAuthoritiesAfterMisbehaviour.length).to.equal( + 2, + 'Best authorities after misbehaviour should be now equal to 2' + ); + }); + + // This test requires at least 3 sessions. + // 3 sessions = 3 * 10 blocks = 30 blocks = 30 * 6 seconds = 180 seconds. + it('should include the unjailed authority after keygen threshold change', async () => { + // first query the current keygen threshold value. + const currentKeygenThreshold = await api.query.dkg.keygenThreshold(); + expect(currentKeygenThreshold.toHex()).to.equal( + '0x0002', + 'Keygen threshold at the start should be 2' + ); + // then, we shall query the current best authorities. + const currentBestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const currentBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + currentBestAuthoritiesValue.toU8a() + ); + expect(currentBestAuthorities.length).to.equal( + 2, + 'Current best authorities should be 2' + ); + // then start the killed node, it was charlie. + charlieNode = startStandaloneNode('charlie', { + tmp: true, + printLogs: false, + }); + // then we want to unjail charlie. + const unjailCharlie = api.tx.dkg.unjail(); + const keyring = new Keyring({ type: 'sr25519' }); + const charlie = keyring.addFromUri('//Charlie'); + await unjailCharlie.signAndSend(charlie); + // next, is to increase the keygen threshold. + const increaseKeygenThreshold = api.tx.dkg.setKeygenThreshold(3); + await sudoTx(api, increaseKeygenThreshold); + // and then, we query for the pending keygen threshold. + // we expect the pending keygen threshold to be 3. + const pendingKeygenThreshold = await api.query.dkg.pendingKeygenThreshold(); + expect(pendingKeygenThreshold.toHex()).to.equal( + '0x0003', + 'Pending keygen threshold should be 3' + ); + // now we wait for the next session, we expect the next keygen threshold to be 3. + // we also expect the next best authorities to be 3. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const nextKeygenThreshold = await api.query.dkg.nextKeygenThreshold(); + expect(nextKeygenThreshold.toHex()).to.equal( + '0x0003', + 'Next keygen threshold should be 3' + ); + const nextBestAuthoritiesValue = await api.query.dkg.nextBestAuthorities(); + const nextBestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + nextBestAuthoritiesValue.toU8a() + ); + expect(nextBestAuthorities.length).to.equal( + 3, + 'Next best authorities should be 3' + ); + + // now, wait for the next session, we expect the keygen threshold to be 3. + // and we expect the best authorities to be 3. + // Also, the DKG rotation should still working as expected. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + const keygenThreshold = await api.query.dkg.keygenThreshold(); + expect(keygenThreshold.toHex()).to.equal( + '0x0003', + 'Keygen threshold should be now equal to 3' + ); + const bestAuthoritiesValue = await api.query.dkg.bestAuthorities(); + const bestAuthorities = new Vec( + api.registry, + '(u16,DkgRuntimePrimitivesCryptoPublic)', + bestAuthoritiesValue.toU8a() + ); + expect(bestAuthorities.length).to.equal(3, 'Best authorities should be 3'); + // query the current DKG public key. + const currentDkgPublicKey = await fetchDkgPublicKey(api); + // now wait for the next session, we expect the dkg to rotate. + await waitForTheNextSession(api); + await sleep(BLOCK_TIME * 2); + // query the next DKG public key. + const newDkgPublicKey = await fetchDkgPublicKey(api); + // we expect the new dkg public key to be different from the current dkg public key. + expect(newDkgPublicKey).to.not.equal( + currentDkgPublicKey, + 'DKG public key should be different after a rotation' + ); + }); + + after(async () => { + await api?.disconnect(); + aliceNode?.kill('SIGINT'); + bobNode?.kill('SIGINT'); + charlieNode?.kill('SIGINT'); + await sleep(BLOCK_TIME * 2); + }); +}); diff --git a/dkg-test-suite/tests/maxDepositLimitProposal.test.ts b/dkg-test-suite/tests/maxDepositLimitProposal.test.ts index 15fe3c3a5..06c1603b3 100644 --- a/dkg-test-suite/tests/maxDepositLimitProposal.test.ts +++ b/dkg-test-suite/tests/maxDepositLimitProposal.test.ts @@ -15,91 +15,121 @@ * */ import { - encodeFunctionSignature, - registerResourceId, - waitForEvent, + encodeFunctionSignature, + registerResourceId, + waitForEvent, } from '../src/utils'; import { Keyring } from '@polkadot/api'; -import {hexToNumber, u8aToHex} from '@polkadot/util'; -import {Option} from '@polkadot/types'; -import {HexString} from '@polkadot/util/types'; -import {MaxDepositLimitProposal, signAndSendUtil, ChainIdType, encodeMaxDepositLimitProposal} from '../src/evm/util/utils'; +import { hexToNumber, u8aToHex } from '@polkadot/util'; +import { Option } from '@polkadot/types'; +import { HexString } from '@polkadot/util/types'; +import { + MaxDepositLimitProposal, + signAndSendUtil, + ChainIdType, + encodeMaxDepositLimitProposal, +} from '../src/evm/util/utils'; import { BLOCK_TIME } from '../src/constants'; import { localChain, polkadotApi, signatureVBridge } from './utils/util'; import { expect } from 'chai'; import { ethers } from 'ethers'; it('should be able to update max deposit limit', async () => { - const vAnchor = signatureVBridge.getVAnchor(localChain.chainId)!; - const resourceId = await vAnchor.createResourceId(); - // Create Mintable Token to add to GovernedTokenWrapper - //Create an ERC20 Token - const proposalPayload: MaxDepositLimitProposal = { - header: { - resourceId, - functionSignature: encodeFunctionSignature( - vAnchor.contract.interface.functions['configureMaximumDepositLimit(uint256)'].format() - ), - nonce: Number(await vAnchor.contract.getProposalNonce()) + 1, - chainId: localChain.chainId, - chainIdType: ChainIdType.EVM - }, - maxDepositLimitBytes: "0x50000000", - }; - // register proposal resourceId. - await registerResourceId(polkadotApi, proposalPayload.header.resourceId); - const proposalBytes = encodeMaxDepositLimitProposal(proposalPayload); - // get alice account to send the transaction to the dkg node. - const keyring = new Keyring({type: 'sr25519'}); - const alice = keyring.addFromUri('//Alice'); - const prop = u8aToHex(proposalBytes); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain.chainId, - }); - const kind = polkadotApi.createType('DkgRuntimePrimitivesProposalProposalKind', 'MaxDepositLimitUpdate'); - const maxDepositLimitProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop - } - }); - const proposalCall = polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(maxDepositLimitProposal); + const vAnchor = signatureVBridge.getVAnchor(localChain.chainId)!; + const resourceId = await vAnchor.createResourceId(); + // Create Mintable Token to add to GovernedTokenWrapper + //Create an ERC20 Token + const proposalPayload: MaxDepositLimitProposal = { + header: { + resourceId, + functionSignature: encodeFunctionSignature( + vAnchor.contract.interface.functions[ + 'configureMaximumDepositLimit(uint256)' + ].format() + ), + nonce: Number(await vAnchor.contract.getProposalNonce()) + 1, + chainId: localChain.chainId, + chainIdType: ChainIdType.EVM, + }, + maxDepositLimitBytes: '0x50000000', + }; + // register proposal resourceId. + await registerResourceId(polkadotApi, proposalPayload.header.resourceId); + const proposalBytes = encodeMaxDepositLimitProposal(proposalPayload); + // get alice account to send the transaction to the dkg node. + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const prop = u8aToHex(proposalBytes); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain.chainId, + } + ); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'MaxDepositLimitUpdate' + ); + const maxDepositLimitProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + maxDepositLimitProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'MaxDepositLimitUpdateProposal' }); - // now we need to query the proposal and its signature. - const key = { - MaxDepositLimitUpdateProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'MaxDepositLimitUpdate'; - data: HexString; - signature: HexString; - }; - }; - // perfect! now we need to send it to the signature bridge. - const bridgeSide = await signatureVBridge.getVBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'MaxDepositLimitUpdateProposal', + }); + // now we need to query the proposal and its signature. + const key = { + MaxDepositLimitUpdateProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'MaxDepositLimitUpdate'; + data: HexString; + signature: HexString; + }; + }; + // perfect! now we need to send it to the signature bridge. + const bridgeSide = await signatureVBridge.getVBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; - const governor = await contract.governor(); - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); - // Want to check that fee was updated - const maxDepositLimit = await vAnchor.contract.maximumDepositAmount(); - expect(hexToNumber("0x50000000").toString()).to.eq(maxDepositLimit.toString()); + const governor = await contract.governor(); + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); + // Want to check that fee was updated + const maxDepositLimit = await vAnchor.contract.maximumDepositAmount(); + expect(hexToNumber('0x50000000').toString()).to.eq( + maxDepositLimit.toString() + ); }); diff --git a/dkg-test-suite/tests/minWithdrawalLimit.test.ts b/dkg-test-suite/tests/minWithdrawalLimit.test.ts index b57ad0eb9..a212782e2 100644 --- a/dkg-test-suite/tests/minWithdrawalLimit.test.ts +++ b/dkg-test-suite/tests/minWithdrawalLimit.test.ts @@ -15,116 +15,155 @@ * */ import { - encodeFunctionSignature, - registerResourceId, - waitForEvent, + encodeFunctionSignature, + registerResourceId, + waitForEvent, } from '../src/utils'; -import {Keyring} from '@polkadot/api'; -import {hexToNumber, u8aToHex} from '@polkadot/util'; -import {Option} from '@polkadot/types'; -import {HexString} from '@polkadot/util/types'; -import {MinWithdrawalLimitProposal, signAndSendUtil, ChainIdType, encodeMinWithdrawalLimitProposal} from '../src/evm/util/utils'; +import { Keyring } from '@polkadot/api'; +import { hexToNumber, u8aToHex } from '@polkadot/util'; +import { Option } from '@polkadot/types'; +import { HexString } from '@polkadot/util/types'; +import { + MinWithdrawalLimitProposal, + signAndSendUtil, + ChainIdType, + encodeMinWithdrawalLimitProposal, +} from '../src/evm/util/utils'; import { VBridge } from '@webb-tools/protocol-solidity'; -import { executeAfter, executeBefore, localChain, polkadotApi, signatureVBridge } from './utils/util'; +import { + executeAfter, + executeBefore, + localChain, + polkadotApi, + signatureVBridge, +} from './utils/util'; import { expect } from 'chai'; import { ethers } from 'ethers'; import { hexlify } from 'ethers/lib/utils'; it('should be able to update min withdrawal limit', async () => { - const vAnchor = signatureVBridge.getVAnchor(localChain.chainId)!; - const resourceId = await vAnchor.createResourceId(); - // Create Mintable Token to add to GovernedTokenWrapper - //Create an ERC20 Token - const proposalPayload: MinWithdrawalLimitProposal = { - header: { - resourceId, - functionSignature: encodeFunctionSignature( - vAnchor.contract.interface.functions['configureMinimalWithdrawalLimit(uint256)'].format() - ), - nonce: Number(await vAnchor.contract.getProposalNonce()) + 1, - chainId: localChain.chainId, - chainIdType: ChainIdType.EVM - }, - minWithdrawalLimitBytes: "0x50", - }; - // register proposal resourceId. - await registerResourceId(polkadotApi, proposalPayload.header.resourceId); - const proposalBytes = encodeMinWithdrawalLimitProposal(proposalPayload); - // get alice account to send the transaction to the dkg node. - const keyring = new Keyring({type: 'sr25519'}); - const alice = keyring.addFromUri('//Alice'); - const prop = u8aToHex(proposalBytes); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain.chainId, - }); - const kind = polkadotApi.createType('DkgRuntimePrimitivesProposalProposalKind', 'MinWithdrawalLimitUpdate'); - const minWithdrawalLimitProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop - } - }); - const proposalCall = polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(minWithdrawalLimitProposal); + const vAnchor = signatureVBridge.getVAnchor(localChain.chainId)!; + const resourceId = await vAnchor.createResourceId(); + // Create Mintable Token to add to GovernedTokenWrapper + //Create an ERC20 Token + const proposalPayload: MinWithdrawalLimitProposal = { + header: { + resourceId, + functionSignature: encodeFunctionSignature( + vAnchor.contract.interface.functions[ + 'configureMinimalWithdrawalLimit(uint256)' + ].format() + ), + nonce: Number(await vAnchor.contract.getProposalNonce()) + 1, + chainId: localChain.chainId, + chainIdType: ChainIdType.EVM, + }, + minWithdrawalLimitBytes: '0x50', + }; + // register proposal resourceId. + await registerResourceId(polkadotApi, proposalPayload.header.resourceId); + const proposalBytes = encodeMinWithdrawalLimitProposal(proposalPayload); + // get alice account to send the transaction to the dkg node. + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const prop = u8aToHex(proposalBytes); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain.chainId, + } + ); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'MinWithdrawalLimitUpdate' + ); + const minWithdrawalLimitProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + minWithdrawalLimitProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'MinWithdrawalLimitUpdateProposal' }); - // now we need to query the proposal and its signature. - const key = { - MinWithdrawalLimitUpdateProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'MinWithdrawalLimitUpdate'; - data: HexString; - signature: HexString; - }; - }; + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'MinWithdrawalLimitUpdateProposal', + }); + // now we need to query the proposal and its signature. + const key = { + MinWithdrawalLimitUpdateProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'MinWithdrawalLimitUpdate'; + data: HexString; + signature: HexString; + }; + }; - let signature = dkgProposal.signed.signature.slice(2); - let r = `0x${signature.slice(0, 32)}`; - let s = `0x${signature.slice(32, 64)}`; - let v = parseInt(`0x${signature[64]}`); - let expandedSig = { r, s, v }; - ethers.utils.joinSignature(expandedSig); - // try { - // sig = ethers.utils.joinSignature(expandedSig) - // } catch (e) { - // expandedSig.s = '0x' + (new BN(ec.curve.n).sub(signature.s)).toString('hex'); - // expandedSig.v = (expandedSig.v === 27) ? 28 : 27; - // sig = ethers.utils.joinSignature(expandedSig) - // } + let signature = dkgProposal.signed.signature.slice(2); + let r = `0x${signature.slice(0, 32)}`; + let s = `0x${signature.slice(32, 64)}`; + let v = parseInt(`0x${signature[64]}`); + let expandedSig = { r, s, v }; + ethers.utils.joinSignature(expandedSig); + // try { + // sig = ethers.utils.joinSignature(expandedSig) + // } catch (e) { + // expandedSig.s = '0x' + (new BN(ec.curve.n).sub(signature.s)).toString('hex'); + // expandedSig.v = (expandedSig.v === 27) ? 28 : 27; + // sig = ethers.utils.joinSignature(expandedSig) + // } - // 66 byte string, which represents 32 bytes of data - let messageHash = ethers.utils.solidityKeccak256(["bytes"], [dkgProposal.signed.data]); + // 66 byte string, which represents 32 bytes of data + let messageHash = ethers.utils.solidityKeccak256( + ['bytes'], + [dkgProposal.signed.data] + ); - // 32 bytes of data in Uint8Array - let messageHashBytes = ethers.utils.arrayify(messageHash); - let recovered = ethers.utils.verifyMessage(messageHashBytes, dkgProposal.signed.signature); - console.log(recovered); + // 32 bytes of data in Uint8Array + let messageHashBytes = ethers.utils.arrayify(messageHash); + let recovered = ethers.utils.verifyMessage( + messageHashBytes, + dkgProposal.signed.signature + ); + console.log(recovered); - - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const bridgeSide = await signatureVBridge.getVBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); - // Want to check that fee was updated - const minWithdrawalLimit = await vAnchor.contract.minimalWithdrawalAmount(); - expect(hexToNumber("0x50").toString()).to.eq(minWithdrawalLimit.toString()); -}); \ No newline at end of file + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const bridgeSide = await signatureVBridge.getVBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); + // Want to check that fee was updated + const minWithdrawalLimit = await vAnchor.contract.minimalWithdrawalAmount(); + expect(hexToNumber('0x50').toString()).to.eq(minWithdrawalLimit.toString()); +}); diff --git a/dkg-test-suite/tests/proposals.test.ts b/dkg-test-suite/tests/proposals.test.ts index f8ccf4ee2..3ba6e5e3c 100644 --- a/dkg-test-suite/tests/proposals.test.ts +++ b/dkg-test-suite/tests/proposals.test.ts @@ -16,39 +16,51 @@ */ // just a blueprint test using jest -import { BLOCK_TIME } from "../src/constants"; -import { executeAfter, executeBefore } from "./utils/util"; +import { BLOCK_TIME } from '../src/constants'; +import { executeAfter, executeBefore } from './utils/util'; function importTest(name: string, path: string) { - describe(name, function () { - require(path); - }); + describe(name, function () { + require(path); + }); } describe('E2E Test Runner', function () { - this.timeout(100 * BLOCK_TIME); - before(async () => { - let start = performance.now(); - await executeBefore({ - both: true, - }); - let end = performance.now(); - console.log(`Start - ${start} | End - ${end}`); - }); + this.timeout(100 * BLOCK_TIME); + this.slow(30 * BLOCK_TIME); + before(async () => { + let start = performance.now(); + await executeBefore({ + both: true, + }); + let end = performance.now(); + console.log(`Start - ${start} | End - ${end} | Took - ${end - start} ms`); + }); - importTest('Proposer Set Update Proposal', './proposerSetUpdateProposal.test'); - importTest('Maximum Deposit Limit Update Proposal', './maxDepositLimitProposal.test'); - importTest('Minimum Withdrawal Limit Update Proposal', './minWithdrawalLimit.test'); - importTest('Rescue Tokens Proposal', './rescueTokensProposal.test'); - importTest('Wrapping Fee Update Proposal', './wrappingFeeUpdateProposal.test'); - importTest('Resource ID Update Proposal', './resourceIdUpdateProposal.test'); - importTest('Token Add & Remove Proposal', './tokenUpdateProposal.test'); - importTest('Anchor Update Proposal', './updateAnchorProposal.test'); - importTest('Governor Update / Refresh Proposal', './updateGovernor.test'); - // importTest('Threshold Update (Staking Chill)', './threshold.test'); - - after(async () => { - await executeAfter(); - }); + importTest( + 'Proposer Set Update Proposal', + './proposerSetUpdateProposal.test' + ); + importTest( + 'Maximum Deposit Limit Update Proposal', + './maxDepositLimitProposal.test' + ); + importTest( + 'Minimum Withdrawal Limit Update Proposal', + './minWithdrawalLimit.test' + ); + importTest('Rescue Tokens Proposal', './rescueTokensProposal.test'); + importTest( + 'Wrapping Fee Update Proposal', + './wrappingFeeUpdateProposal.test' + ); + importTest('Resource ID Update Proposal', './resourceIdUpdateProposal.test'); + importTest('Token Add & Remove Proposal', './tokenUpdateProposal.test'); + importTest('Anchor Update Proposal', './updateAnchorProposal.test'); + importTest('Governor Update / Refresh Proposal', './updateGovernor.test'); + // importTest('Threshold Update (Staking Chill)', './threshold.test'); + + after(async () => { + await executeAfter(); + }); }); - \ No newline at end of file diff --git a/dkg-test-suite/tests/proposerSetUpdateProposal.test.ts b/dkg-test-suite/tests/proposerSetUpdateProposal.test.ts index 8d266946e..df57f1ce7 100644 --- a/dkg-test-suite/tests/proposerSetUpdateProposal.test.ts +++ b/dkg-test-suite/tests/proposerSetUpdateProposal.test.ts @@ -1,4 +1,3 @@ - /* * Copyright 2022 Webb Technologies Inc. * @@ -15,121 +14,161 @@ * limitations under the License. */ -import {BLOCK_TIME} from '../src/constants'; +import { BLOCK_TIME } from '../src/constants'; import { - localChain, - polkadotApi, - executeAfter, - signatureBridge, - executeBefore, + localChain, + polkadotApi, + executeAfter, + signatureBridge, + executeBefore, } from './utils/util'; import { Option } from '@polkadot/types'; import { HexString } from '@polkadot/util/types'; import { BigNumber, ethers } from 'ethers'; import { Bridges } from '@webb-tools/protocol-solidity'; import { expect } from 'chai'; -import { ethAddressFromUncompressedPublicKey, fetchDkgPublicKey, fetchDkgPublicKeySignature, fetchDkgRefreshNonce, triggerDkgManuaIncrementNonce, waitForEvent, waitForPublicKeySignatureToChange, waitForPublicKeyToChange } from '../src/utils'; +import { + ethAddressFromUncompressedPublicKey, + fetchDkgPublicKey, + fetchDkgPublicKeySignature, + fetchDkgRefreshNonce, + triggerDkgManuaIncrementNonce, + waitForEvent, + waitForPublicKeySignatureToChange, + waitForPublicKeyToChange, +} from '../src/utils'; it.skip('proposer set update test', async () => { - const provider = localChain.provider(); - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'ProposerSetUpdateProposal' }); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { None: 0 }); - const key = { ProposerSetUpdateProposal: 1 }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'ProposerSetUpdate'; - data: HexString; - signature: HexString; - }; - }; - // now we can transfer ownership. - const bridgeSide = signatureBridge.getBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - - const proposalData = dkgProposal.signed.data.slice(2); - const proposerSetRoot = `0x${proposalData.slice(0, 64)}`; - const averageSessionLength = BigNumber.from(`0x${proposalData.slice(64, 80)}`); - const numOfProposers = BigNumber.from(`0x${proposalData.slice(80, 88)}`); - const proposalNonce = BigNumber.from(`0x${proposalData.slice(88, 96)}`); - - let tx = await contract.updateProposerSetData( - proposerSetRoot, - averageSessionLength, - numOfProposers, - proposalNonce, - dkgProposal.signed.signature - ); - await tx.wait(); - - const contractProposerSetRoot = await bridgeSide.contract.proposerSetRoot(); - expect(proposerSetRoot).to.eq(contractProposerSetRoot); - - const contractAverageSessionLength = await bridgeSide.contract.averageSessionLengthInMillisecs(); - expect(averageSessionLength.toString()).to.eq((BigNumber.from(contractAverageSessionLength)).toString()); - - const contractNumOfProposers = await bridgeSide.contract.numOfProposers(); - expect(numOfProposers.toString()).to.eq((BigNumber.from(contractNumOfProposers)).toString()); - - const contractProposalNonce = await bridgeSide.contract.proposerSetUpdateNonce(); - expect(proposalNonce.toString()).to.eq((BigNumber.from(contractProposalNonce)).toString()); - - // // Now the proposer set root on the contract has been updated - - let proposerAccounts = await polkadotApi.query.dKGProposals.externalProposerAccounts.entries(); - let accounts = new Array(); - for (let i = 0; i { - const anchor = signatureBridge.getAnchor( - localChain.chainId, - ethers.utils.parseEther('1') - )! as Anchors.Anchor; - const governedTokenAddress = anchor.token!; - const governedToken = GovernedTokenWrapper.connect(governedTokenAddress, wallet1); - const mintableTokenAddress = (await governedToken.contract.getTokens())[0]; - const mintableToken = await MintableToken.tokenFromAddress(mintableTokenAddress, wallet1); - const treasuryAddress = await governedToken.getFeeRecipientAddress(); - const treasury = Treasury.connect(treasuryAddress, wallet1); - const keyring = new Keyring({ type: 'sr25519' }); - const alice = keyring.addFromUri('//Alice'); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain.chainId, - }); - // First, we will execute the update wrapping fee proposal to change the fee to be greater than 0 - // This will allow tokens to accumulate to the treasury - { - const governedTokenResourceId = await governedToken.createResourceId(); - // Create Mintable Token to add to GovernedTokenWrapper - //Create an ERC20 Token - const proposalPayload: WrappingFeeUpdateProposal = { - header: { - resourceId: governedTokenResourceId, - functionSignature: encodeFunctionSignature( - governedToken.contract.interface.functions['setFee(uint8,uint256)'].format() - ), - nonce: Number(await governedToken.contract.proposalNonce()) + 1, - chainIdType: ChainIdType.EVM, - chainId: localChain.chainId, - }, - newFee: '0x0A', // wrapping fee of 10 percent - }; + const anchor = signatureBridge.getAnchor( + localChain.chainId, + ethers.utils.parseEther('1') + )! as Anchors.Anchor; + const governedTokenAddress = anchor.token!; + const governedToken = GovernedTokenWrapper.connect( + governedTokenAddress, + wallet1 + ); + const mintableTokenAddress = (await governedToken.contract.getTokens())[0]; + const mintableToken = await MintableToken.tokenFromAddress( + mintableTokenAddress, + wallet1 + ); + const treasuryAddress = await governedToken.getFeeRecipientAddress(); + const treasury = Treasury.connect(treasuryAddress, wallet1); + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain.chainId, + } + ); + // First, we will execute the update wrapping fee proposal to change the fee to be greater than 0 + // This will allow tokens to accumulate to the treasury + { + const governedTokenResourceId = await governedToken.createResourceId(); + // Create Mintable Token to add to GovernedTokenWrapper + //Create an ERC20 Token + const proposalPayload: WrappingFeeUpdateProposal = { + header: { + resourceId: governedTokenResourceId, + functionSignature: encodeFunctionSignature( + governedToken.contract.interface.functions[ + 'setFee(uint8,uint256)' + ].format() + ), + nonce: Number(await governedToken.contract.proposalNonce()) + 1, + chainIdType: ChainIdType.EVM, + chainId: localChain.chainId, + }, + newFee: '0x0A', // wrapping fee of 10 percent + }; - const proposalBytes = encodeWrappingFeeUpdateProposal(proposalPayload); - const prop = u8aToHex(proposalBytes); - const kind = polkadotApi.createType( - 'DkgRuntimePrimitivesProposalProposalKind', - 'WrappingFeeUpdate' - ); - const wrappingFeeUpdateProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop, - }, - }); - const proposalCall = - polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(wrappingFeeUpdateProposal); + const proposalBytes = encodeWrappingFeeUpdateProposal(proposalPayload); + const prop = u8aToHex(proposalBytes); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'WrappingFeeUpdate' + ); + const wrappingFeeUpdateProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + wrappingFeeUpdateProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'WrappingFeeUpdateProposal' }); - // now we need to query the proposal and its signature. - const key = { - WrappingFeeUpdateProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'WrappingFeeUpdate'; - data: HexString; - signature: HexString; - }; - }; - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); - // Want to check that fee was updated - const fee = await governedToken.contract.getFee(); - expect(10).to.eq(fee); - } - await sleep(5 * BLOCK_TIME); // wait for a few blocks - { - // Now we wrap and deposit, the wrapping fee should accumulate to the treasury - const wrappingFee = await governedToken.contract.getFee(); - await governedToken.grantMinterRole(anchor.contract.address); - await mintableToken.approveSpending(anchor.contract.address); - await mintableToken.approveSpending(governedToken.contract.address); - await mintableToken.mintTokens(wallet1.address, '100000000000000000000000'); - await anchor.wrapAndDeposit(mintableToken.contract.address, wrappingFee); + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'WrappingFeeUpdateProposal', + }); + // now we need to query the proposal and its signature. + const key = { + WrappingFeeUpdateProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'WrappingFeeUpdate'; + data: HexString; + signature: HexString; + }; + }; + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); + // Want to check that fee was updated + const fee = await governedToken.contract.getFee(); + expect(10).to.eq(fee); + } + await sleep(5 * BLOCK_TIME); // wait for a few blocks + { + // Now we wrap and deposit, the wrapping fee should accumulate to the treasury + const wrappingFee = await governedToken.contract.getFee(); + await governedToken.grantMinterRole(anchor.contract.address); + await mintableToken.approveSpending(anchor.contract.address); + await mintableToken.approveSpending(governedToken.contract.address); + await mintableToken.mintTokens(wallet1.address, '100000000000000000000000'); + await anchor.wrapAndDeposit(mintableToken.contract.address, wrappingFee); - // Anchor Denomination amount should go to TokenWrapper - expect((await mintableToken.getBalance(governedToken.contract.address)).toString()).to.eq( - anchor.denomination! - ); + // Anchor Denomination amount should go to TokenWrapper + expect( + ( + await mintableToken.getBalance(governedToken.contract.address) + ).toString() + ).to.eq(anchor.denomination!); - // The wrapping fee should be transferred to the treasury - expect((await mintableToken.getBalance(treasury.contract.address)).toString()).to.eq( - BigNumber.from(anchor.denomination!) - .mul(wrappingFee) - .div(100 - wrappingFee) - .toString() - ); + // The wrapping fee should be transferred to the treasury + expect( + (await mintableToken.getBalance(treasury.contract.address)).toString() + ).to.eq( + BigNumber.from(anchor.denomination!) + .mul(wrappingFee) + .div(100 - wrappingFee) + .toString() + ); - expect((await governedToken.contract.balanceOf(anchor.contract.address)).toString()).to.eq( - anchor.denomination! - ); - } + expect( + ( + await governedToken.contract.balanceOf(anchor.contract.address) + ).toString() + ).to.eq(anchor.denomination!); + } - await sleep(5 * BLOCK_TIME); // wait for a few blocks + await sleep(5 * BLOCK_TIME); // wait for a few blocks - // We now execute the rescue tokens proposal - { - const treasuryResourceId = await treasury.createResourceId(); - const to = wallet1.address; - let balTreasuryBeforeRescue = await mintableToken.getBalance(treasury.contract.address); - let balToBeforeRescue = await mintableToken.getBalance(to); - const proposalPayload: RescueTokensProposal = { - header: { - resourceId: treasuryResourceId, - functionSignature: encodeFunctionSignature( - treasury.contract.interface.functions[ - 'rescueTokens(address,address,uint256,uint256)' - ].format() - ), - nonce: Number(await treasury.contract.proposalNonce()) + 1, - chainIdType: ChainIdType.EVM, - chainId: localChain.chainId, - }, - tokenAddress: mintableTokenAddress, - toAddress: to, - amount: '0x01F4', // 500 in hex - }; - const proposalBytes = encodeRescueTokensProposal(proposalPayload); - const prop = u8aToHex(proposalBytes); - const kind = polkadotApi.createType( - 'DkgRuntimePrimitivesProposalProposalKind', - 'RescueTokens' - ); - const rescueTokensProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop, - }, - }); - const proposalCall = - polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(rescueTokensProposal); + // We now execute the rescue tokens proposal + { + const treasuryResourceId = await treasury.createResourceId(); + const to = wallet1.address; + let balTreasuryBeforeRescue = await mintableToken.getBalance( + treasury.contract.address + ); + let balToBeforeRescue = await mintableToken.getBalance(to); + const proposalPayload: RescueTokensProposal = { + header: { + resourceId: treasuryResourceId, + functionSignature: encodeFunctionSignature( + treasury.contract.interface.functions[ + 'rescueTokens(address,address,uint256,uint256)' + ].format() + ), + nonce: Number(await treasury.contract.proposalNonce()) + 1, + chainIdType: ChainIdType.EVM, + chainId: localChain.chainId, + }, + tokenAddress: mintableTokenAddress, + toAddress: to, + amount: '0x01F4', // 500 in hex + }; + const proposalBytes = encodeRescueTokensProposal(proposalPayload); + const prop = u8aToHex(proposalBytes); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'RescueTokens' + ); + const rescueTokensProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + rescueTokensProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'RescueTokensProposal' }); - // now we need to query the proposal and its signature. - const key = { - RescueTokensProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'RescueTokens'; - data: HexString; - signature: HexString; - }; - }; - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - console.log(await contract.governor()); - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'RescueTokensProposal', + }); + // now we need to query the proposal and its signature. + const key = { + RescueTokensProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'RescueTokens'; + data: HexString; + signature: HexString; + }; + }; + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; + console.log(await contract.governor()); + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); - // We check that the address that the tokens were rescued to contain the rescued tokens - let balTreasuryAfterRescue = await mintableToken.getBalance(treasury.contract.address); - let balToAfterRescue = await mintableToken.getBalance(to); + // We check that the address that the tokens were rescued to contain the rescued tokens + let balTreasuryAfterRescue = await mintableToken.getBalance( + treasury.contract.address + ); + let balToAfterRescue = await mintableToken.getBalance(to); - const diffTreasuryBalance = parseInt( - balTreasuryBeforeRescue.sub(balTreasuryAfterRescue).toString() - ); - const diffToBalance = parseInt(balToAfterRescue.sub(balToBeforeRescue).toString()); + const diffTreasuryBalance = parseInt( + balTreasuryBeforeRescue.sub(balTreasuryAfterRescue).toString() + ); + const diffToBalance = parseInt( + balToAfterRescue.sub(balToBeforeRescue).toString() + ); - expect(500 == diffTreasuryBalance).to.eq(true); - expect(500 == diffToBalance).to.eq(true); - } + expect(500 == diffTreasuryBalance).to.eq(true); + expect(500 == diffToBalance).to.eq(true); + } }); diff --git a/dkg-test-suite/tests/resourceIdUpdateProposal.test.ts b/dkg-test-suite/tests/resourceIdUpdateProposal.test.ts index e3ba81741..b5e55b004 100644 --- a/dkg-test-suite/tests/resourceIdUpdateProposal.test.ts +++ b/dkg-test-suite/tests/resourceIdUpdateProposal.test.ts @@ -15,119 +15,152 @@ * */ import { - encodeFunctionSignature, - registerResourceId, - waitForEvent, + encodeFunctionSignature, + registerResourceId, + waitForEvent, } from '../src/utils'; -import {GovernedTokenWrapper} from '@webb-tools/tokens'; -import {Keyring} from '@polkadot/api'; -import {u8aToHex} from '@polkadot/util'; -import {Option} from '@polkadot/types'; -import {HexString} from '@polkadot/util/types'; +import { GovernedTokenWrapper } from '@webb-tools/tokens'; +import { Keyring } from '@polkadot/api'; +import { u8aToHex } from '@polkadot/util'; +import { Option } from '@polkadot/types'; +import { HexString } from '@polkadot/util/types'; import { - signAndSendUtil, - ResourceIdUpdateProposal, - encodeResourceIdUpdateProposal, - ChainIdType, + signAndSendUtil, + ResourceIdUpdateProposal, + encodeResourceIdUpdateProposal, + ChainIdType, } from '../src/evm/util/utils'; import { - localChain, - polkadotApi, - signatureBridge, - wallet1, - executeAfter, - executeBefore + localChain, + polkadotApi, + signatureBridge, + wallet1, + executeAfter, + executeBefore, } from './utils/util'; import { Bridges } from '@webb-tools/protocol-solidity'; import { expect } from 'chai'; it('should be able to sign resource id update proposal', async () => { - const bridgeSide = signatureBridge.getBridgeSide(localChain.chainId); - const resourceId = await bridgeSide.createResourceId(); + const bridgeSide = signatureBridge.getBridgeSide(localChain.chainId); + const resourceId = await bridgeSide.createResourceId(); - // Let's create a new GovernedTokenWrapper and set the resourceId for it via - // the ResourceIdUpdate Proposal - const dummyAddress = '0x1111111111111111111111111111111111111111'; - const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper("token-e2e-test", 'te2e', dummyAddress, dummyAddress, '10000000000000000000000000', false, wallet1); + // Let's create a new GovernedTokenWrapper and set the resourceId for it via + // the ResourceIdUpdate Proposal + const dummyAddress = '0x1111111111111111111111111111111111111111'; + const governedToken = await GovernedTokenWrapper.createGovernedTokenWrapper( + 'token-e2e-test', + 'te2e', + dummyAddress, + dummyAddress, + '10000000000000000000000000', + false, + wallet1 + ); - const newResourceId = await governedToken.createResourceId(); - const handlerAddress = bridgeSide.tokenHandler.contract.address - const executionContextAddress = governedToken.contract.address; + const newResourceId = await governedToken.createResourceId(); + const handlerAddress = bridgeSide.tokenHandler.contract.address; + const executionContextAddress = governedToken.contract.address; - const proposalFunctionSignature = encodeFunctionSignature( - bridgeSide.contract.interface.functions['adminSetResourceWithSignature(bytes32,bytes4,uint32,bytes32,address,address,bytes)'].format() - ) + const proposalFunctionSignature = encodeFunctionSignature( + bridgeSide.contract.interface.functions[ + 'adminSetResourceWithSignature(bytes32,bytes4,uint32,bytes32,address,address,bytes)' + ].format() + ); - const proposalNonce = Number(await bridgeSide.contract.proposalNonce()) + 1; - const proposalPayload: ResourceIdUpdateProposal = { - header: { - resourceId, - functionSignature: proposalFunctionSignature, - nonce: proposalNonce, - chainIdType: ChainIdType.EVM, - chainId: localChain.chainId, - }, - newResourceId: newResourceId, - handlerAddress: handlerAddress, - executionAddress: executionContextAddress, - }; - // register proposal resourceId. - await registerResourceId(polkadotApi, proposalPayload.header.resourceId); - const proposalBytes = encodeResourceIdUpdateProposal(proposalPayload); - // get alice account to send the transaction to the dkg node. - const keyring = new Keyring({type: 'sr25519'}); - const alice = keyring.addFromUri('//Alice'); - const prop = u8aToHex(proposalBytes); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain.chainId, - }); - const kind = polkadotApi.createType('DkgRuntimePrimitivesProposalProposalKind', 'ResourceIdUpdate'); - const resourceIdUpdateProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop - } - }); - const proposalCall = polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(resourceIdUpdateProposal); + const proposalNonce = Number(await bridgeSide.contract.proposalNonce()) + 1; + const proposalPayload: ResourceIdUpdateProposal = { + header: { + resourceId, + functionSignature: proposalFunctionSignature, + nonce: proposalNonce, + chainIdType: ChainIdType.EVM, + chainId: localChain.chainId, + }, + newResourceId: newResourceId, + handlerAddress: handlerAddress, + executionAddress: executionContextAddress, + }; + // register proposal resourceId. + await registerResourceId(polkadotApi, proposalPayload.header.resourceId); + const proposalBytes = encodeResourceIdUpdateProposal(proposalPayload); + // get alice account to send the transaction to the dkg node. + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const prop = u8aToHex(proposalBytes); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain.chainId, + } + ); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'ResourceIdUpdate' + ); + const resourceIdUpdateProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + resourceIdUpdateProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'ResourceIdUpdateProposal' }); - // now we need to query the proposal and its signature. - const key = { - ResourceIdUpdateProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'ResourceIdUpdate'; - data: HexString; - signature: HexString; - }; - }; - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const contract = bridgeSide.contract; - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.adminSetResourceWithSignature( - resourceId, - proposalFunctionSignature, - proposalNonce, - newResourceId, - handlerAddress, - executionContextAddress, - dkgProposal.signed.signature, - ); - await tx2.wait(); + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'ResourceIdUpdateProposal', + }); + // now we need to query the proposal and its signature. + const key = { + ResourceIdUpdateProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'ResourceIdUpdate'; + data: HexString; + signature: HexString; + }; + }; + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const contract = bridgeSide.contract; + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.adminSetResourceWithSignature( + resourceId, + proposalFunctionSignature, + proposalNonce, + newResourceId, + handlerAddress, + executionContextAddress, + dkgProposal.signed.signature + ); + await tx2.wait(); - expect(await bridgeSide.contract._resourceIDToHandlerAddress(newResourceId)).to.eq(handlerAddress); + expect( + await bridgeSide.contract._resourceIDToHandlerAddress(newResourceId) + ).to.eq(handlerAddress); }); diff --git a/dkg-test-suite/tests/threshold.test.ts b/dkg-test-suite/tests/threshold.test.ts index 3596a5d6d..3a07d066b 100644 --- a/dkg-test-suite/tests/threshold.test.ts +++ b/dkg-test-suite/tests/threshold.test.ts @@ -13,54 +13,52 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - waitForEvent, waitForTheNextSession -} from '../src/utils'; +import { waitForEvent, waitForTheNextSession } from '../src/utils'; -import { Keyring } from "@polkadot/api"; +import { Keyring } from '@polkadot/api'; import { expect } from 'chai'; import { polkadotApi } from './utils/util'; it('should be able to remove validator node and update thresholds', async () => { - const keyring = new Keyring({ type: 'sr25519' }); - const charlieStash = keyring.addFromUri('//Charlie//stash'); - const alice = keyring.addFromUri('//Alice'); + const keyring = new Keyring({ type: 'sr25519' }); + const charlieStash = keyring.addFromUri('//Charlie//stash'); + const alice = keyring.addFromUri('//Alice'); - // check and expect threshold count to be 2 - let sigthresholdCount = await polkadotApi.query.dkg.signatureThreshold(); - expect(sigthresholdCount.toString()).to.eq("2"); + // check and expect threshold count to be 2 + let sigthresholdCount = await polkadotApi.query.dkg.signatureThreshold(); + expect(sigthresholdCount.toString()).to.eq('2'); - // check and expect next authorities count to be 3 - let nextAuthorities = await polkadotApi.query.dkg.nextAuthorities(); - // @ts-ignore - expect(nextAuthorities.length.toString()).to.be.eq("3"); + // check and expect next authorities count to be 3 + let nextAuthorities = await polkadotApi.query.dkg.nextAuthorities(); + // @ts-ignore + expect(nextAuthorities.length.toString()).to.be.eq('3'); - // force new era for staking elections - let forceNewEra = polkadotApi.tx.staking.forceNewEraAlways(); - const forceNewEraAlwayCall = polkadotApi.tx.sudo.sudo({ - callIndex: forceNewEra.callIndex, - args: forceNewEra.args, - }); - await forceNewEraAlwayCall.signAndSend(alice); + // force new era for staking elections + let forceNewEra = polkadotApi.tx.staking.forceNewEraAlways(); + const forceNewEraAlwayCall = polkadotApi.tx.sudo.sudo({ + callIndex: forceNewEra.callIndex, + args: forceNewEra.args, + }); + await forceNewEraAlwayCall.signAndSend(alice); - // chill(remove) charlie as validator - let call = polkadotApi.tx.staking.chill(); - await call.signAndSend(charlieStash); - await waitForEvent(polkadotApi, 'staking', 'Chilled'); + // chill(remove) charlie as validator + let call = polkadotApi.tx.staking.chill(); + await call.signAndSend(charlieStash); + await waitForEvent(polkadotApi, 'staking', 'Chilled'); - // wait for the next session - await waitForTheNextSession(polkadotApi); + // wait for the next session + await waitForTheNextSession(polkadotApi); - // check and expect threshold count to be 1 - sigthresholdCount = await polkadotApi.query.dkg.signatureThreshold(); - expect(sigthresholdCount.toString()).to.eq("1"); + // check and expect threshold count to be 1 + sigthresholdCount = await polkadotApi.query.dkg.signatureThreshold(); + expect(sigthresholdCount.toString()).to.eq('1'); - // check and expect threshold count to be 1 - let keygenthresholdCount = await polkadotApi.query.dkg.signatureThreshold(); - expect(keygenthresholdCount.toString()).to.eq("2"); + // check and expect threshold count to be 1 + let keygenthresholdCount = await polkadotApi.query.dkg.signatureThreshold(); + expect(keygenthresholdCount.toString()).to.eq('2'); - // check and expect next authorities count to be 2 - nextAuthorities = await polkadotApi.query.dkg.nextAuthorities(); - // @ts-ignore - expect(nextAuthorities.length.toString()).to.eq("2"); + // check and expect next authorities count to be 2 + nextAuthorities = await polkadotApi.query.dkg.nextAuthorities(); + // @ts-ignore + expect(nextAuthorities.length.toString()).to.eq('2'); }); diff --git a/dkg-test-suite/tests/tokenUpdateProposal.test.ts b/dkg-test-suite/tests/tokenUpdateProposal.test.ts index 7621b5e07..e25ba83b9 100644 --- a/dkg-test-suite/tests/tokenUpdateProposal.test.ts +++ b/dkg-test-suite/tests/tokenUpdateProposal.test.ts @@ -15,181 +15,245 @@ * */ import { - encodeFunctionSignature, - registerResourceId, - sleep, - waitForEvent, + encodeFunctionSignature, + registerResourceId, + sleep, + waitForEvent, } from '../src/utils'; -import {ethers} from 'ethers'; -import {MintableToken, GovernedTokenWrapper} from '@webb-tools/tokens'; -import {Keyring} from '@polkadot/api'; -import {u8aToHex} from '@polkadot/util'; -import {Option} from '@polkadot/types'; -import {HexString} from '@polkadot/util/types'; +import { ethers } from 'ethers'; +import { MintableToken, GovernedTokenWrapper } from '@webb-tools/tokens'; +import { Keyring } from '@polkadot/api'; +import { u8aToHex } from '@polkadot/util'; +import { Option } from '@polkadot/types'; +import { HexString } from '@polkadot/util/types'; import { - signAndSendUtil, - TokenAddProposal, - encodeTokenAddProposal, - ChainIdType, - encodeTokenRemoveProposal, - TokenRemoveProposal, + signAndSendUtil, + TokenAddProposal, + encodeTokenAddProposal, + ChainIdType, + encodeTokenRemoveProposal, + TokenRemoveProposal, } from '../src/evm/util/utils'; import { - localChain, - polkadotApi, - signatureBridge, - wallet1, - executeAfter, - executeBefore + localChain, + polkadotApi, + signatureBridge, + wallet1, + executeAfter, + executeBefore, } from './utils/util'; import { Bridges } from '@webb-tools/protocol-solidity'; import { expect } from 'chai'; import { BLOCK_TIME } from '../src/constants'; it('should be able to sign token add & remove proposal', async () => { - const anchor = signatureBridge.getAnchor(localChain.chainId, ethers.utils.parseEther('1'))!; - const governedTokenAddress = anchor.token!; - let governedToken = GovernedTokenWrapper.connect(governedTokenAddress, wallet1); - const resourceId = await governedToken.createResourceId(); - // Create Mintable Token to add to GovernedTokenWrapper - //Create an ERC20 Token - const tokenToAdd = await MintableToken.createToken('testToken', 'TEST', wallet1); - { - const proposalPayload: TokenAddProposal = { - header: { - resourceId, - functionSignature: encodeFunctionSignature( - governedToken.contract.interface.functions['add(address,uint256)'].format() - ), - nonce: Number(await governedToken.contract.proposalNonce()) + 1, - chainIdType: ChainIdType.EVM, - chainId: localChain.chainId, - }, - newTokenAddress: tokenToAdd.contract.address, - }; - // register proposal resourceId. - await registerResourceId(polkadotApi, proposalPayload.header.resourceId); - const proposalBytes = encodeTokenAddProposal(proposalPayload); - // get alice account to send the transaction to the dkg node. - const keyring = new Keyring({type: 'sr25519'}); - const alice = keyring.addFromUri('//Alice'); - const prop = u8aToHex(proposalBytes); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain.chainId, - }); - const kind = polkadotApi.createType('DkgRuntimePrimitivesProposalProposalKind', 'TokenAdd'); - const tokenAddProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop - } - }); - const proposalCall = polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(tokenAddProposal); + const anchor = signatureBridge.getAnchor( + localChain.chainId, + ethers.utils.parseEther('1') + )!; + const governedTokenAddress = anchor.token!; + let governedToken = GovernedTokenWrapper.connect( + governedTokenAddress, + wallet1 + ); + const resourceId = await governedToken.createResourceId(); + // Create Mintable Token to add to GovernedTokenWrapper + //Create an ERC20 Token + const tokenToAdd = await MintableToken.createToken( + 'testToken', + 'TEST', + wallet1 + ); + { + const proposalPayload: TokenAddProposal = { + header: { + resourceId, + functionSignature: encodeFunctionSignature( + governedToken.contract.interface.functions[ + 'add(address,uint256)' + ].format() + ), + nonce: Number(await governedToken.contract.proposalNonce()) + 1, + chainIdType: ChainIdType.EVM, + chainId: localChain.chainId, + }, + newTokenAddress: tokenToAdd.contract.address, + }; + // register proposal resourceId. + await registerResourceId(polkadotApi, proposalPayload.header.resourceId); + const proposalBytes = encodeTokenAddProposal(proposalPayload); + // get alice account to send the transaction to the dkg node. + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const prop = u8aToHex(proposalBytes); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain.chainId, + } + ); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'TokenAdd' + ); + const tokenAddProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + tokenAddProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'TokenAddProposal' }); - // now we need to query the proposal and its signature. - const key = { - TokenAddProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'TokenAdd'; - data: HexString; - signature: HexString; - }; - }; - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); - // Want to check that token was actually added - expect((await governedToken.contract.getTokens()).includes(tokenToAdd.contract.address)).to.eq(true); - } - await sleep(5 * BLOCK_TIME); - const proposalPayload: TokenRemoveProposal = { - header: { - resourceId, - functionSignature: encodeFunctionSignature( - governedToken.contract.interface.functions['remove(address,uint256)'].format() - ), - nonce: Number(await governedToken.contract.proposalNonce()) + 1, - chainIdType: ChainIdType.EVM, - chainId: localChain.chainId, - }, - removeTokenAddress: tokenToAdd.contract.address, - }; - // register proposal resourceId. - await registerResourceId(polkadotApi, proposalPayload.header.resourceId); - const proposalBytes = encodeTokenRemoveProposal(proposalPayload); - // get alice account to send the transaction to the dkg node. - const keyring = new Keyring({type: 'sr25519'}); - const alice = keyring.addFromUri('//Alice'); - const prop = u8aToHex(proposalBytes); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain.chainId, - }); - const kind = polkadotApi.createType('DkgRuntimePrimitivesProposalProposalKind', 'TokenRemove'); - const tokenRemoveProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop - } - }); - const proposalCall = polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(tokenRemoveProposal); + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'TokenAddProposal', + }); + // now we need to query the proposal and its signature. + const key = { + TokenAddProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'TokenAdd'; + data: HexString; + signature: HexString; + }; + }; + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); + // Want to check that token was actually added + expect( + (await governedToken.contract.getTokens()).includes( + tokenToAdd.contract.address + ) + ).to.eq(true); + } + await sleep(5 * BLOCK_TIME); + const proposalPayload: TokenRemoveProposal = { + header: { + resourceId, + functionSignature: encodeFunctionSignature( + governedToken.contract.interface.functions[ + 'remove(address,uint256)' + ].format() + ), + nonce: Number(await governedToken.contract.proposalNonce()) + 1, + chainIdType: ChainIdType.EVM, + chainId: localChain.chainId, + }, + removeTokenAddress: tokenToAdd.contract.address, + }; + // register proposal resourceId. + await registerResourceId(polkadotApi, proposalPayload.header.resourceId); + const proposalBytes = encodeTokenRemoveProposal(proposalPayload); + // get alice account to send the transaction to the dkg node. + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const prop = u8aToHex(proposalBytes); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain.chainId, + } + ); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'TokenRemove' + ); + const tokenRemoveProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + tokenRemoveProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'TokenRemoveProposal' }); - // now we need to query the proposal and its signature. - const key = { - TokenRemoveProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'TokenRemoveProposal', + }); + // now we need to query the proposal and its signature. + const key = { + TokenRemoveProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'TokenRemove'; - data: HexString; - signature: HexString; - }; - }; - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); - // Want to check that token was actually added - expect((await governedToken.contract.getTokens()).includes(tokenToAdd.contract.address)).to.eq(false); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'TokenRemove'; + data: HexString; + signature: HexString; + }; + }; + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); + // Want to check that token was actually added + expect( + (await governedToken.contract.getTokens()).includes( + tokenToAdd.contract.address + ) + ).to.eq(false); }); diff --git a/dkg-test-suite/tests/updateAnchorProposal.test.ts b/dkg-test-suite/tests/updateAnchorProposal.test.ts index 2a25710d5..fc0d512a2 100644 --- a/dkg-test-suite/tests/updateAnchorProposal.test.ts +++ b/dkg-test-suite/tests/updateAnchorProposal.test.ts @@ -15,150 +15,171 @@ * */ import { - encodeFunctionSignature, - ethAddressFromUncompressedPublicKey, - fetchDkgPublicKey, - registerResourceId, - waitForEvent, + encodeFunctionSignature, + ethAddressFromUncompressedPublicKey, + fetchDkgPublicKey, + registerResourceId, + waitForEvent, } from '../src/utils'; -import {ethers} from 'ethers'; -import {Anchors} from '@webb-tools/protocol-solidity'; -import {Keyring} from '@polkadot/api'; -import {u8aToHex} from '@polkadot/util'; -import {Option} from '@polkadot/types'; -import {HexString} from '@polkadot/util/types'; +import { ethers } from 'ethers'; +import { Anchors } from '@webb-tools/protocol-solidity'; +import { Keyring } from '@polkadot/api'; +import { u8aToHex } from '@polkadot/util'; +import { Option } from '@polkadot/types'; +import { HexString } from '@polkadot/util/types'; import { - AnchorUpdateProposal, - encodeUpdateAnchorProposal, - ChainIdType, + AnchorUpdateProposal, + encodeUpdateAnchorProposal, + ChainIdType, } from '../src/evm/util/utils'; import { - localChain, - polkadotApi, - signatureBridge, - wallet1, - wallet2, - localChain2, executeAfter, executeBefore + localChain, + polkadotApi, + signatureBridge, + wallet1, + wallet2, + localChain2, + executeAfter, + executeBefore, } from './utils/util'; import { Bridges } from '@webb-tools/protocol-solidity'; import { expect } from 'chai'; it('should be able to sign anchor update proposal', async () => { - // get the anhor on localchain1 - const anchor = signatureBridge.getAnchor( - localChain.chainId, - ethers.utils.parseEther('1') - )! as Anchors.Anchor; - await anchor.setSigner(wallet1); - // check the merkle root - const merkleRoot1 = await anchor.contract.getLastRoot(); - // get the anchor on localchain2 - const anchor2 = signatureBridge.getAnchor( - localChain2.chainId, - ethers.utils.parseEther('1') - )! as Anchors.Anchor; - await anchor2.setSigner(wallet2); + // get the anhor on localchain1 + const anchor = signatureBridge.getAnchor( + localChain.chainId, + ethers.utils.parseEther('1') + )! as Anchors.Anchor; + await anchor.setSigner(wallet1); + // check the merkle root + const merkleRoot1 = await anchor.contract.getLastRoot(); + // get the anchor on localchain2 + const anchor2 = signatureBridge.getAnchor( + localChain2.chainId, + ethers.utils.parseEther('1') + )! as Anchors.Anchor; + await anchor2.setSigner(wallet2); - // create a deposit on localchain1 - const deposit = await anchor.deposit(localChain2.chainId); - // now check the new merkel root. - const newMerkleRoot1 = await anchor.contract.getLastRoot(); - expect(newMerkleRoot1).not.to.eq(merkleRoot1); - const lastLeafIndex = deposit.index; - // create anchor update proposal to be sent to the dkg. - const resourceId = await anchor2.createResourceId(); - const proposalPayload: AnchorUpdateProposal = { - header: { - resourceId, - functionSignature: encodeFunctionSignature( - anchor.contract.interface.functions['updateEdge(uint256,bytes32,uint256)'].format() - ), - nonce: 1, - chainId: localChain2.chainId, - chainIdType: ChainIdType.EVM, - }, - chainIdType: ChainIdType.EVM, - srcChainId: localChain.chainId, - merkleRoot: newMerkleRoot1, - lastLeafIndex, - target: anchor.getAddress() - }; - // register proposal resourceId. - await registerResourceId(polkadotApi, proposalPayload.header.resourceId); - const proposalBytes = encodeUpdateAnchorProposal(proposalPayload); - // get alice account to send the transaction to the dkg node. - const keyring = new Keyring({type: 'sr25519'}); - const alice = keyring.addFromUri('//Alice'); - const prop = u8aToHex(proposalBytes); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain2.chainId, - }); - const proposalCall = polkadotApi.tx.dKGProposals.acknowledgeProposal( - proposalPayload.header.nonce, - chainIdType, - resourceId, - prop - ); - const tx = new Promise(async (resolve, reject) => { - const unsub = await proposalCall.signAndSend(alice, ({events, status}) => { - if (status.isFinalized) { - unsub(); - const success = events.find(({event}) => - polkadotApi.events.system.ExtrinsicSuccess.is(event) - ); - if (success) { - resolve(); - } else { - reject(new Error('Proposal failed')); - } - } - }); - }); - await tx; - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { key: 'AnchorUpdateProposal' }); - // now we need to query the proposal and its signature. - const key = { - AnchorUpdateProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'AnchorUpdate'; - data: HexString; - signature: HexString; - }; - }; - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const bridgeSide = signatureBridge.getBridgeSide(localChain2.chainId)!; - // but first, we need to log few things to help us to debug. - let wallet2_ = wallet2.connect(localChain2.provider()); - const contract = bridgeSide.contract.connect(wallet2_); - const currentGovernor = await contract.governor(); - const currentDkgPublicKey = await fetchDkgPublicKey(polkadotApi); - const currentDkgAddress = ethAddressFromUncompressedPublicKey(currentDkgPublicKey!); - expect(currentGovernor).to.eq(currentDkgAddress); - // now we log the proposal data, signature, and if it is signed by the current governor or not. - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const val = await contract._resourceIDToHandlerAddress(resourceId); - const anchorHandlerAddress = await anchor2.getHandler(); - expect(val).to.eq(anchorHandlerAddress); - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); - // now we shall check the new merkle root on the other chain. - const newMerkleRoots = await anchor2.contract.getLatestNeighborRoots(); - // the merkle root should be included now. - expect(newMerkleRoots.includes(newMerkleRoot1)).to.eq(true); + // create a deposit on localchain1 + const deposit = await anchor.deposit(localChain2.chainId); + // now check the new merkel root. + const newMerkleRoot1 = await anchor.contract.getLastRoot(); + expect(newMerkleRoot1).not.to.eq(merkleRoot1); + const lastLeafIndex = deposit.index; + // create anchor update proposal to be sent to the dkg. + const resourceId = await anchor2.createResourceId(); + const proposalPayload: AnchorUpdateProposal = { + header: { + resourceId, + functionSignature: encodeFunctionSignature( + anchor.contract.interface.functions[ + 'updateEdge(uint256,bytes32,uint256)' + ].format() + ), + nonce: 1, + chainId: localChain2.chainId, + chainIdType: ChainIdType.EVM, + }, + chainIdType: ChainIdType.EVM, + srcChainId: localChain.chainId, + merkleRoot: newMerkleRoot1, + lastLeafIndex, + target: anchor.getAddress(), + }; + // register proposal resourceId. + await registerResourceId(polkadotApi, proposalPayload.header.resourceId); + const proposalBytes = encodeUpdateAnchorProposal(proposalPayload); + // get alice account to send the transaction to the dkg node. + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const prop = u8aToHex(proposalBytes); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain2.chainId, + } + ); + const proposalCall = polkadotApi.tx.dKGProposals.acknowledgeProposal( + proposalPayload.header.nonce, + chainIdType, + resourceId, + prop + ); + const tx = new Promise(async (resolve, reject) => { + const unsub = await proposalCall.signAndSend( + alice, + ({ events, status }) => { + if (status.isFinalized) { + unsub(); + const success = events.find(({ event }) => + polkadotApi.events.system.ExtrinsicSuccess.is(event) + ); + if (success) { + resolve(); + } else { + reject(new Error('Proposal failed')); + } + } + } + ); + }); + await tx; + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned', { + key: 'AnchorUpdateProposal', + }); + // now we need to query the proposal and its signature. + const key = { + AnchorUpdateProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'AnchorUpdate'; + data: HexString; + signature: HexString; + }; + }; + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const bridgeSide = signatureBridge.getBridgeSide(localChain2.chainId)!; + // but first, we need to log few things to help us to debug. + let wallet2_ = wallet2.connect(localChain2.provider()); + const contract = bridgeSide.contract.connect(wallet2_); + const currentGovernor = await contract.governor(); + const currentDkgPublicKey = await fetchDkgPublicKey(polkadotApi); + const currentDkgAddress = ethAddressFromUncompressedPublicKey( + currentDkgPublicKey! + ); + expect(currentGovernor).to.eq(currentDkgAddress); + // now we log the proposal data, signature, and if it is signed by the current governor or not. + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const val = await contract._resourceIDToHandlerAddress(resourceId); + const anchorHandlerAddress = await anchor2.getHandler(); + expect(val).to.eq(anchorHandlerAddress); + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); + // now we shall check the new merkle root on the other chain. + const newMerkleRoots = await anchor2.contract.getLatestNeighborRoots(); + // the merkle root should be included now. + expect(newMerkleRoots.includes(newMerkleRoot1)).to.eq(true); }); diff --git a/dkg-test-suite/tests/updateGovernor.test.ts b/dkg-test-suite/tests/updateGovernor.test.ts index 223eb5303..0e3ce0d18 100644 --- a/dkg-test-suite/tests/updateGovernor.test.ts +++ b/dkg-test-suite/tests/updateGovernor.test.ts @@ -16,62 +16,62 @@ */ import { Bridges } from '@webb-tools/protocol-solidity'; import { expect } from 'chai'; -import {BLOCK_TIME} from '../src/constants'; +import { BLOCK_TIME } from '../src/constants'; import { - ethAddressFromUncompressedPublicKey, - fetchDkgPublicKey, - fetchDkgPublicKeySignature, - fetchDkgRefreshNonce, - sleep, - triggerDkgManuaIncrementNonce, - triggerDkgManualRefresh, - waitForPublicKeySignatureToChange, - waitForPublicKeyToChange, + ethAddressFromUncompressedPublicKey, + fetchDkgPublicKey, + fetchDkgPublicKeySignature, + fetchDkgRefreshNonce, + sleep, + triggerDkgManuaIncrementNonce, + triggerDkgManualRefresh, + waitForPublicKeySignatureToChange, + waitForPublicKeyToChange, } from '../src/utils'; import { - localChain, - polkadotApi, - signatureBridge, - executeAfter, - executeBefore + localChain, + polkadotApi, + signatureBridge, + executeAfter, + executeBefore, } from './utils/util'; it.skip('should be able to transfer ownership to new Governor with Signature', async () => { - // we trigger a manual renonce since we already transfered the ownership before. - await triggerDkgManuaIncrementNonce(polkadotApi); - // for some reason, we have to wait for a bit ¯\_(ツ)_/¯. - await sleep(2 * BLOCK_TIME); - // we trigger a manual DKG Refresh. - await triggerDkgManualRefresh(polkadotApi); - // then we wait until the dkg public key and its signature to get changed. - await Promise.all([ - waitForPublicKeyToChange(polkadotApi), - waitForPublicKeySignatureToChange(polkadotApi), - ]); - // then we fetch them. - const dkgPublicKey = await fetchDkgPublicKey(polkadotApi); - const dkgPublicKeySignature = await fetchDkgPublicKeySignature(polkadotApi); - const refreshNonce = await fetchDkgRefreshNonce(polkadotApi); - expect(dkgPublicKey).to.be.length.greaterThan(0); - expect(dkgPublicKeySignature).to.be.length.greaterThan(0); - expect(refreshNonce).to.be.greaterThan(0); - // now we can transfer ownership. - const signatureSide = signatureBridge.getBridgeSide(localChain.chainId); - const contract = signatureSide.contract; - contract.connect(localChain.provider()); - const governor = await contract.governor(); - let nextGovernorAddress = ethAddressFromUncompressedPublicKey(dkgPublicKey!); - // sanity check - expect(nextGovernorAddress).not.to.eq(governor); - const tx = await contract.transferOwnershipWithSignaturePubKey( - dkgPublicKey!, - refreshNonce, - dkgPublicKeySignature!, - ); - await tx.wait(); - // check that the new governor is the same as the one we just set. - const newGovernor = await contract.governor(); - expect(newGovernor).not.to.eq(governor); - expect(newGovernor).to.eq(nextGovernorAddress); -}); \ No newline at end of file + // we trigger a manual renonce since we already transfered the ownership before. + await triggerDkgManuaIncrementNonce(polkadotApi); + // for some reason, we have to wait for a bit ¯\_(ツ)_/¯. + await sleep(2 * BLOCK_TIME); + // we trigger a manual DKG Refresh. + await triggerDkgManualRefresh(polkadotApi); + // then we wait until the dkg public key and its signature to get changed. + await Promise.all([ + waitForPublicKeyToChange(polkadotApi), + waitForPublicKeySignatureToChange(polkadotApi), + ]); + // then we fetch them. + const dkgPublicKey = await fetchDkgPublicKey(polkadotApi); + const dkgPublicKeySignature = await fetchDkgPublicKeySignature(polkadotApi); + const refreshNonce = await fetchDkgRefreshNonce(polkadotApi); + expect(dkgPublicKey).to.be.length.greaterThan(0); + expect(dkgPublicKeySignature).to.be.length.greaterThan(0); + expect(refreshNonce).to.be.greaterThan(0); + // now we can transfer ownership. + const signatureSide = signatureBridge.getBridgeSide(localChain.chainId); + const contract = signatureSide.contract; + contract.connect(localChain.provider()); + const governor = await contract.governor(); + let nextGovernorAddress = ethAddressFromUncompressedPublicKey(dkgPublicKey!); + // sanity check + expect(nextGovernorAddress).not.to.eq(governor); + const tx = await contract.transferOwnershipWithSignaturePubKey( + dkgPublicKey!, + refreshNonce, + dkgPublicKeySignature! + ); + await tx.wait(); + // check that the new governor is the same as the one we just set. + const newGovernor = await contract.governor(); + expect(newGovernor).not.to.eq(governor); + expect(newGovernor).to.eq(nextGovernorAddress); +}); diff --git a/dkg-test-suite/tests/utils/util.ts b/dkg-test-suite/tests/utils/util.ts index e1ab4282e..3a39879c2 100644 --- a/dkg-test-suite/tests/utils/util.ts +++ b/dkg-test-suite/tests/utils/util.ts @@ -14,25 +14,27 @@ * limitations under the License. * */ -import {ACC1_PK, ACC2_PK, BLOCK_TIME, SECONDS} from "../../src/constants"; -import {ApiPromise} from "@polkadot/api"; -import {ChildProcess} from "child_process"; -import {LocalChain} from "../../src/localEvm"; -import {ethers} from "ethers"; -import {Bridges, VBridge} from "@webb-tools/protocol-solidity"; -import {MintableToken} from "@webb-tools/tokens"; +import { ACC1_PK, ACC2_PK, BLOCK_TIME, SECONDS } from '../../src/constants'; +import { ApiPromise, WsProvider } from '@polkadot/api'; +import { ChildProcess, execSync } from 'child_process'; +import fs from 'fs'; +import { LocalChain } from '../../src/localEvm'; +import { ethers } from 'ethers'; +import { Bridges, VBridge } from '@webb-tools/protocol-solidity'; +import { MintableToken } from '@webb-tools/tokens'; import { + endpoint, ethAddressFromUncompressedPublicKey, fetchDkgPublicKey, fetchDkgPublicKeySignature, fetchDkgRefreshNonce, - provider, sleep, + sleep, startStandaloneNode, waitForPublicKeySignatureToChange, waitForPublicKeyToChange, - waitUntilDKGPublicKeyStoredOnChain -} from "../../src/utils"; -import { expect } from "chai"; + waitUntilDKGPublicKeyStoredOnChain, +} from '../../src/utils'; +import { expect } from 'chai'; export let polkadotApi: ApiPromise; export let aliceNode: ChildProcess; @@ -47,13 +49,22 @@ export let wallet2: ethers.Wallet; export let signatureBridge: Bridges.SignatureBridge; export let signatureVBridge: VBridge.VBridge; -export const executeBefore = async ({ isVariable, both }: { +export const executeBefore = async ({ + isVariable, + both, +}: { isVariable?: boolean; both?: boolean; }) => { - aliceNode = startStandaloneNode('alice', {tmp: true, printLogs: false}); - bobNode = startStandaloneNode('bob', {tmp: true, printLogs: false}); - charlieNode = startStandaloneNode('charlie', {tmp: true, printLogs: false}); + // delete the tmp directory if it exists. + const gitRoot = execSync('git rev-parse --show-toplevel').toString().trim(); + const tmpDir = `${gitRoot}/tmp`; + if (fs.existsSync(tmpDir)) { + fs.rmSync(tmpDir, { recursive: true }); + } + aliceNode = startStandaloneNode('alice', { tmp: true, printLogs: false }); + bobNode = startStandaloneNode('bob', { tmp: true, printLogs: false }); + charlieNode = startStandaloneNode('charlie', { tmp: true, printLogs: false }); localChain = new LocalChain('local', 5001, [ { balance: ethers.utils.parseEther('1000').toHexString(), @@ -65,15 +76,18 @@ export const executeBefore = async ({ isVariable, both }: { }, { balance: ethers.utils.parseEther('1000').toHexString(), - secretKey: '0x79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf', + secretKey: + '0x79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf', }, { balance: ethers.utils.parseEther('1000').toHexString(), - secretKey: '0xf8d74108dbe199c4a6e4ef457046db37c325ba3f709b14cabfa1885663e4c589', + secretKey: + '0xf8d74108dbe199c4a6e4ef457046db37c325ba3f709b14cabfa1885663e4c589', }, { balance: ethers.utils.parseEther('1000').toHexString(), - secretKey: '0xcb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854', + secretKey: + '0xcb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854', }, ]); localChain2 = new LocalChain('local2', 5002, [ @@ -89,11 +103,19 @@ export const executeBefore = async ({ isVariable, both }: { wallet1 = new ethers.Wallet(ACC1_PK, localChain.provider()); wallet2 = new ethers.Wallet(ACC2_PK, localChain2.provider()); // Deploy the token. - const localToken = await localChain.deployToken('Webb Token', 'WEBB', wallet1); - const localToken2 = await localChain2.deployToken('Webb Token', 'WEBB', wallet2); + const localToken = await localChain.deployToken( + 'Webb Token', + 'WEBB', + wallet1 + ); + const localToken2 = await localChain2.deployToken( + 'Webb Token', + 'WEBB', + wallet2 + ); polkadotApi = await ApiPromise.create({ - provider, + provider: new WsProvider(endpoint), }); // Update the signature bridge governor. @@ -150,7 +172,7 @@ export const executeBefore = async ({ isVariable, both }: { await handleSetup(!!isVariable, governorAddress); } -} +}; export async function executeAfter() { await polkadotApi.disconnect(); @@ -164,9 +186,12 @@ export async function executeAfter() { export const handleSetup = async (isVariable: boolean, governor: string) => { // get the anchor on localchain1 - const anchor = (isVariable) + const anchor = isVariable ? signatureVBridge.getVAnchor(localChain.chainId)! - : signatureBridge.getAnchor(localChain.chainId, ethers.utils.parseEther('1'))!; + : signatureBridge.getAnchor( + localChain.chainId, + ethers.utils.parseEther('1') + )!; await anchor.setSigner(wallet1); @@ -177,17 +202,22 @@ export const handleSetup = async (isVariable: boolean, governor: string) => { await token.mintTokens(wallet1.address, ethers.utils.parseEther('1000')); // do the same but on localchain2 - const anchor2 = (isVariable) + const anchor2 = isVariable ? signatureVBridge.getVAnchor(localChain2.chainId)! - : signatureBridge.getAnchor(localChain2.chainId, ethers.utils.parseEther('1'))!; + : signatureBridge.getAnchor( + localChain2.chainId, + ethers.utils.parseEther('1') + )!; await anchor2.setSigner(wallet2); - const tokenAddress2 = signatureBridge.getWebbTokenAddress(localChain2.chainId)!; + const tokenAddress2 = signatureBridge.getWebbTokenAddress( + localChain2.chainId + )!; const token2 = await MintableToken.tokenFromAddress(tokenAddress2, wallet2); await token2.approveSpending(anchor2.contract.address); await token2.mintTokens(wallet2.address, ethers.utils.parseEther('1000')); // update the signature bridge governor on both chains. - const sides = (isVariable) + const sides = isVariable ? signatureVBridge.vBridgeSides.values() : signatureBridge.bridgeSides.values(); for (const signatureSide of sides) { @@ -199,38 +229,40 @@ export const handleSetup = async (isVariable: boolean, governor: string) => { const currentGovernor = await contract.governor(); expect(currentGovernor).to.eq(governor); } -} +}; export const waitForAndExecuteNthRotation = async (n: number) => { for (let i = 0; i < n; i++) { - await Promise.all([ - waitForPublicKeyToChange(polkadotApi), - waitForPublicKeySignatureToChange(polkadotApi), - ]); - // then we fetch them. - const dkgPublicKey = await fetchDkgPublicKey(polkadotApi); - const dkgPublicKeySignature = await fetchDkgPublicKeySignature(polkadotApi); - const refreshNonce = await fetchDkgRefreshNonce(polkadotApi); - expect(dkgPublicKey).to.be.length.greaterThan(0); - expect(dkgPublicKeySignature).to.be.length.greaterThan(0); - expect(refreshNonce).to.be.greaterThan(1); - // now we can transfer ownership. - const bridgeSide = signatureBridge.getBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - contract.connect(localChain.provider()); - const governor = await contract.governor(); - let nextGovernorAddress = ethAddressFromUncompressedPublicKey(dkgPublicKey!); - // sanity check - expect(nextGovernorAddress).not.to.eq(governor); - let tx = await contract.transferOwnershipWithSignaturePubKey( - dkgPublicKey!, - refreshNonce, - dkgPublicKeySignature!, - ); - try { - await tx.wait(); - } catch (e) { - console.log(e); - } + await Promise.all([ + waitForPublicKeyToChange(polkadotApi), + waitForPublicKeySignatureToChange(polkadotApi), + ]); + // then we fetch them. + const dkgPublicKey = await fetchDkgPublicKey(polkadotApi); + const dkgPublicKeySignature = await fetchDkgPublicKeySignature(polkadotApi); + const refreshNonce = await fetchDkgRefreshNonce(polkadotApi); + expect(dkgPublicKey).to.be.length.greaterThan(0); + expect(dkgPublicKeySignature).to.be.length.greaterThan(0); + expect(refreshNonce).to.be.greaterThan(1); + // now we can transfer ownership. + const bridgeSide = signatureBridge.getBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; + contract.connect(localChain.provider()); + const governor = await contract.governor(); + let nextGovernorAddress = ethAddressFromUncompressedPublicKey( + dkgPublicKey! + ); + // sanity check + expect(nextGovernorAddress).not.to.eq(governor); + let tx = await contract.transferOwnershipWithSignaturePubKey( + dkgPublicKey!, + refreshNonce, + dkgPublicKeySignature! + ); + try { + await tx.wait(); + } catch (e) { + console.log(e); + } } - } \ No newline at end of file +}; diff --git a/dkg-test-suite/tests/wrappingFeeUpdateProposal.test.ts b/dkg-test-suite/tests/wrappingFeeUpdateProposal.test.ts index fc3ffaa88..997a36c31 100644 --- a/dkg-test-suite/tests/wrappingFeeUpdateProposal.test.ts +++ b/dkg-test-suite/tests/wrappingFeeUpdateProposal.test.ts @@ -15,103 +15,130 @@ * */ import { - encodeFunctionSignature, - registerResourceId, - waitForEvent, + encodeFunctionSignature, + registerResourceId, + waitForEvent, } from '../src/utils'; -import {ethers} from 'ethers'; -import {GovernedTokenWrapper} from '@webb-tools/tokens'; -import {Keyring} from '@polkadot/api'; -import {hexToNumber, u8aToHex} from '@polkadot/util'; -import {Option} from '@polkadot/types'; -import {HexString} from '@polkadot/util/types'; +import { ethers } from 'ethers'; +import { GovernedTokenWrapper } from '@webb-tools/tokens'; +import { Keyring } from '@polkadot/api'; +import { hexToNumber, u8aToHex } from '@polkadot/util'; +import { Option } from '@polkadot/types'; +import { HexString } from '@polkadot/util/types'; import { - signAndSendUtil, - WrappingFeeUpdateProposal, - encodeWrappingFeeUpdateProposal, - ChainIdType, + signAndSendUtil, + WrappingFeeUpdateProposal, + encodeWrappingFeeUpdateProposal, + ChainIdType, } from '../src/evm/util/utils'; import { - localChain, - polkadotApi, - signatureBridge, - wallet1 + localChain, + polkadotApi, + signatureBridge, + wallet1, } from './utils/util'; import { expect } from 'chai'; it('should be able to sign wrapping fee update proposal', async () => { - const anchor = signatureBridge.getAnchor(localChain.chainId, ethers.utils.parseEther('1'))!; - const governedTokenAddress = anchor.token!; - let governedToken = GovernedTokenWrapper.connect(governedTokenAddress, wallet1); - const resourceId = await governedToken.createResourceId(); - // Create Mintable Token to add to GovernedTokenWrapper - //Create an ERC20 Token - const proposalPayload: WrappingFeeUpdateProposal = { - header: { - resourceId, - functionSignature: encodeFunctionSignature( - governedToken.contract.interface.functions['setFee(uint8,uint256)'].format() - ), - nonce: Number(await governedToken.contract.proposalNonce()) + 1, - chainIdType: ChainIdType.EVM, - chainId: localChain.chainId, - }, - newFee: "0x50", - }; - // register proposal resourceId. - await registerResourceId(polkadotApi, proposalPayload.header.resourceId); - const proposalBytes = encodeWrappingFeeUpdateProposal(proposalPayload); - // get alice account to send the transaction to the dkg node. - const keyring = new Keyring({type: 'sr25519'}); - const alice = keyring.addFromUri('//Alice'); - const prop = u8aToHex(proposalBytes); - const chainIdType = polkadotApi.createType('WebbProposalsHeaderTypedChainId', { - Evm: localChain.chainId, - }); - const kind = polkadotApi.createType('DkgRuntimePrimitivesProposalProposalKind', 'WrappingFeeUpdate'); - const wrappingFeeUpdateProposal = polkadotApi.createType('DkgRuntimePrimitivesProposal', { - Unsigned: { - kind: kind, - data: prop - } - }); - const proposalCall = polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal(wrappingFeeUpdateProposal); + const anchor = signatureBridge.getAnchor( + localChain.chainId, + ethers.utils.parseEther('1') + )!; + const governedTokenAddress = anchor.token!; + let governedToken = GovernedTokenWrapper.connect( + governedTokenAddress, + wallet1 + ); + const resourceId = await governedToken.createResourceId(); + // Create Mintable Token to add to GovernedTokenWrapper + //Create an ERC20 Token + const proposalPayload: WrappingFeeUpdateProposal = { + header: { + resourceId, + functionSignature: encodeFunctionSignature( + governedToken.contract.interface.functions[ + 'setFee(uint8,uint256)' + ].format() + ), + nonce: Number(await governedToken.contract.proposalNonce()) + 1, + chainIdType: ChainIdType.EVM, + chainId: localChain.chainId, + }, + newFee: '0x50', + }; + // register proposal resourceId. + await registerResourceId(polkadotApi, proposalPayload.header.resourceId); + const proposalBytes = encodeWrappingFeeUpdateProposal(proposalPayload); + // get alice account to send the transaction to the dkg node. + const keyring = new Keyring({ type: 'sr25519' }); + const alice = keyring.addFromUri('//Alice'); + const prop = u8aToHex(proposalBytes); + const chainIdType = polkadotApi.createType( + 'WebbProposalsHeaderTypedChainId', + { + Evm: localChain.chainId, + } + ); + const kind = polkadotApi.createType( + 'DkgRuntimePrimitivesProposalProposalKind', + 'WrappingFeeUpdate' + ); + const wrappingFeeUpdateProposal = polkadotApi.createType( + 'DkgRuntimePrimitivesProposal', + { + Unsigned: { + kind: kind, + data: prop, + }, + } + ); + const proposalCall = + polkadotApi.tx.dKGProposalHandler.forceSubmitUnsignedProposal( + wrappingFeeUpdateProposal + ); - await signAndSendUtil(polkadotApi, proposalCall, alice); + await signAndSendUtil(polkadotApi, proposalCall, alice); - // now we need to wait until the proposal to be signed on chain. - await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned'); - // now we need to query the proposal and its signature. - const key = { - WrappingFeeUpdateProposal: proposalPayload.header.nonce, - }; - const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals(chainIdType, key); - const value = new Option(polkadotApi.registry, 'DkgRuntimePrimitivesProposal', proposal); - expect(value.isSome).to.eq(true); - const dkgProposal = value.unwrap().toJSON() as { - signed: { - kind: 'WrappingFeeUpdate'; - data: HexString; - signature: HexString; - }; - }; - // sanity check. - expect(dkgProposal.signed.data).to.eq(prop); - // perfect! now we need to send it to the signature bridge. - const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); - const contract = bridgeSide.contract; - const isSignedByGovernor = await contract.isSignatureFromGovernor( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - expect(isSignedByGovernor).to.eq(true); - // check that we have the resouceId mapping. - const tx2 = await contract.executeProposalWithSignature( - dkgProposal.signed.data, - dkgProposal.signed.signature - ); - await tx2.wait(); - // Want to check that fee was updated - const fee = await governedToken.contract.getFee(); - expect(hexToNumber("0x50")).to.eq(fee); + // now we need to wait until the proposal to be signed on chain. + await waitForEvent(polkadotApi, 'dKGProposalHandler', 'ProposalSigned'); + // now we need to query the proposal and its signature. + const key = { + WrappingFeeUpdateProposal: proposalPayload.header.nonce, + }; + const proposal = await polkadotApi.query.dKGProposalHandler.signedProposals( + chainIdType, + key + ); + const value = new Option( + polkadotApi.registry, + 'DkgRuntimePrimitivesProposal', + proposal + ); + expect(value.isSome).to.eq(true); + const dkgProposal = value.unwrap().toJSON() as { + signed: { + kind: 'WrappingFeeUpdate'; + data: HexString; + signature: HexString; + }; + }; + // sanity check. + expect(dkgProposal.signed.data).to.eq(prop); + // perfect! now we need to send it to the signature bridge. + const bridgeSide = await signatureBridge.getBridgeSide(localChain.chainId); + const contract = bridgeSide.contract; + const isSignedByGovernor = await contract.isSignatureFromGovernor( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + expect(isSignedByGovernor).to.eq(true); + // check that we have the resouceId mapping. + const tx2 = await contract.executeProposalWithSignature( + dkgProposal.signed.data, + dkgProposal.signed.signature + ); + await tx2.wait(); + // Want to check that fee was updated + const fee = await governedToken.contract.getFee(); + expect(hexToNumber('0x50')).to.eq(fee); }); diff --git a/e2e_tests.sh b/e2e_tests.sh new file mode 100755 index 000000000..7a1a41ba9 --- /dev/null +++ b/e2e_tests.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cargo build --release --features=integration-tests +cd dkg-test-suite && yarn && yarn test diff --git a/launch/config.yml b/launch/config.yml index 5f646549b..04ec322f8 100644 --- a/launch/config.yml +++ b/launch/config.yml @@ -1,5 +1,5 @@ relaychain: - image: parity/polkadot:v0.9.17 + image: parity/polkadot:v0.9.24 chain: rococo-local runtimeGenesisConfig: configuration: diff --git a/node/Cargo.toml b/node/Cargo.toml deleted file mode 100644 index 622f84527..000000000 --- a/node/Cargo.toml +++ /dev/null @@ -1,106 +0,0 @@ -[package] -name = "dkg-node" -authors = ["Webb tools"] -description = "A new Cumulus FRAME-based Substrate node, ready for hacking." -license = "Unlicense" -version = "3.0.0" -homepage = "https://webb.tools" -repository = "https://github.com/webb-tools/dkg-substrate" -edition = "2018" -build = "build.rs" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[build-dependencies] -substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -[[bin]] -name = "dkg-node" - -[dependencies] -derive_more = "0.99.2" -log = "0.4.14" -codec = { package = "parity-scale-codec", version = "2.0.0" } -clap = { version = "3.1", features = ["derive"] } -serde = { version = "1.0.119", features = ["derive"] } -hex-literal = "0.3.1" - -# RPC related Dependencies -jsonrpc-core = "18.0.0" - -# Local Dependencies -dkg-runtime = { path = "../runtime" } -dkg-runtime-primitives = { path = "../dkg-runtime-primitives" } -dkg-primitives = { path = "../dkg-primitives" } -dkg-gadget = { path = "../dkg-gadget" } - -# Substrate Dependencies -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -## Substrate Client Dependencies -sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", features = ["wasmtime"] } -sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -## Substrate Primitive Dependencies -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -# Cumulus dependencies -cumulus-client-consensus-aura = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-client-consensus-common = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-client-collator = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-client-cli = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-client-network = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-client-service = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-relay-chain-interface = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -cumulus-relay-chain-local = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -pallet-collator-selection = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } - -# Polkadot dependencies -polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.17"} -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.17"} -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.17"} -polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.17"} -polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.17"} - -[features] -default = [] -rococo-native = [ - "polkadot-cli/rococo-native" -] -runtime-benchmarks = [ - "polkadot-service/runtime-benchmarks", - "dkg-runtime/runtime-benchmarks", -] diff --git a/node/build.rs b/node/build.rs deleted file mode 100644 index b4a61897d..000000000 --- a/node/build.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; - -fn main() { - generate_cargo_keys(); - rerun_if_git_head_changed(); -} diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs deleted file mode 100644 index 674f17936..000000000 --- a/node/src/chain_spec.rs +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use cumulus_primitives_core::ParaId; -use dkg_runtime::{AccountId, AuraId, DKGId, Signature, EXISTENTIAL_DEPOSIT, MILLIUNIT}; -use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; -use sc_service::ChainType; -use serde::{Deserialize, Serialize}; -use sp_core::{sr25519, Pair, Public}; -use sp_runtime::traits::{IdentifyAccount, Verify}; - -/// Specialized `ChainSpec` for the normal parachain runtime. -pub type ChainSpec = sc_service::GenericChainSpec; - -/// Helper function to generate a crypto pair from seed -pub fn get_from_seed(seed: &str) -> ::Public { - TPublic::Pair::from_string(&format!("//{}", seed), None) - .expect("static values are valid; qed") - .public() -} - -/// Generate collator keys from seed. -/// -/// This function's return type must always match the session keys of the chain -/// in tuple format. -pub fn get_collator_keys_from_seed(seed: &str) -> AuraId { - get_from_seed::(seed) -} - -/// Generate DKG keys from seed. -/// -/// This function's return type must always match the session keys of the chain -/// in tuple format. -pub fn get_dkg_keys_from_seed(seed: &str) -> DKGId { - get_from_seed::(seed) -} - -/// Generate the session keys from individual elements. -/// -/// The input must be a tuple of individual keys (a single arg for now since we -/// have just one key). -pub fn dkg_session_keys(keys: AuraId, dkg_keys: DKGId) -> dkg_runtime::SessionKeys { - dkg_runtime::SessionKeys { aura: keys, dkg: dkg_keys } -} - -/// The extensions for the [`ChainSpec`]. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] -#[serde(deny_unknown_fields)] -pub struct Extensions { - /// The relay chain of the Parachain. - pub relay_chain: String, - /// The id of the Parachain. - pub para_id: u32, -} - -impl Extensions { - /// Try to get the extension from the given `ChainSpec`. - pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> { - sc_chain_spec::get_extension(chain_spec.extensions()) - } -} - -type AccountPublic = ::Signer; - -/// Helper function to generate an account ID from seed -pub fn get_account_id_from_seed(seed: &str) -> AccountId -where - AccountPublic: From<::Public>, -{ - AccountPublic::from(get_from_seed::(seed)).into_account() -} - -pub fn development_config(id: ParaId) -> ChainSpec { - // Give your base currency a unit name and decimal places - let mut properties = sc_chain_spec::Properties::new(); - properties.insert("tokenSymbol".into(), "tEGG".into()); - properties.insert("tokenDecimals".into(), 12u32.into()); - - ChainSpec::from_genesis( - // Name - "Development", - // ID - "dev", - ChainType::Local, - move || { - testnet_genesis( - get_account_id_from_seed::("Alice"), - vec![ - ( - get_account_id_from_seed::("Alice"), - get_collator_keys_from_seed("Alice"), - get_dkg_keys_from_seed("Alice"), - ), - ( - get_account_id_from_seed::("Bob"), - get_collator_keys_from_seed("Bob"), - get_dkg_keys_from_seed("Bob"), - ), - ( - get_account_id_from_seed::("Charlie"), - get_collator_keys_from_seed("Charlie"), - get_dkg_keys_from_seed("Charlie"), - ), - ], - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - ], - id, - ) - }, - vec![], - None, - None, - None, - None, - Extensions { - relay_chain: "rococo-local".into(), // You MUST set this to the correct network! - para_id: id.into(), - }, - ) -} - -pub fn local_testnet_config(id: ParaId) -> ChainSpec { - // Give your base currency a unit name and decimal places - let mut properties = sc_chain_spec::Properties::new(); - properties.insert("tokenSymbol".into(), "tEGG".into()); - properties.insert("tokenDecimals".into(), 12u32.into()); - - ChainSpec::from_genesis( - // Name - "Local Testnet", - // ID - "local_testnet", - ChainType::Local, - move || { - testnet_genesis( - get_account_id_from_seed::("Alice"), - vec![ - ( - get_account_id_from_seed::("Alice"), - get_collator_keys_from_seed("Alice"), - get_dkg_keys_from_seed("Alice"), - ), - ( - get_account_id_from_seed::("Bob"), - get_collator_keys_from_seed("Bob"), - get_dkg_keys_from_seed("Bob"), - ), - ( - get_account_id_from_seed::("Charlie"), - get_collator_keys_from_seed("Charlie"), - get_dkg_keys_from_seed("Charlie"), - ), - ], - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Charlie"), - get_account_id_from_seed::("Dave"), - get_account_id_from_seed::("Eve"), - get_account_id_from_seed::("Ferdie"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - get_account_id_from_seed::("Charlie//stash"), - get_account_id_from_seed::("Dave//stash"), - get_account_id_from_seed::("Eve//stash"), - get_account_id_from_seed::("Ferdie//stash"), - ], - id, - ) - }, - Vec::new(), - None, - None, - None, - None, - Extensions { - relay_chain: "rococo-local".into(), // You MUST set this to the correct network! - para_id: id.into(), - }, - ) -} - -fn testnet_genesis( - root_key: AccountId, - invulnerables: Vec<(AccountId, AuraId, DKGId)>, - endowed_accounts: Vec, - id: ParaId, -) -> dkg_runtime::GenesisConfig { - dkg_runtime::GenesisConfig { - system: dkg_runtime::SystemConfig { - code: dkg_runtime::WASM_BINARY - .expect("WASM binary was not build, please build it!") - .to_vec(), - }, - sudo: dkg_runtime::SudoConfig { key: Some(root_key) }, - balances: dkg_runtime::BalancesConfig { - balances: endowed_accounts - .iter() - .cloned() - .map(|k| (k, MILLIUNIT * 4_096_000)) - .collect(), - }, - parachain_info: dkg_runtime::ParachainInfoConfig { parachain_id: id }, - collator_selection: dkg_runtime::CollatorSelectionConfig { - invulnerables: invulnerables.iter().cloned().map(|(acc, _, _)| acc).collect(), - candidacy_bond: EXISTENTIAL_DEPOSIT * 16, - ..Default::default() - }, - session: dkg_runtime::SessionConfig { - keys: invulnerables - .iter() - .cloned() - .map(|(acc, aura, dkg)| { - ( - acc.clone(), // account id - acc, // validator id - dkg_session_keys(aura, dkg), // session keys - ) - }) - .collect(), - }, - aura: Default::default(), - aura_ext: Default::default(), - parachain_system: Default::default(), - dkg: dkg_runtime::DKGConfig { - authorities: invulnerables.iter().map(|x| x.2.clone()).collect::<_>(), - threshold: Default::default(), - authority_ids: invulnerables.iter().map(|x| x.0.clone()).collect::<_>(), - }, - dkg_proposals: Default::default(), - } -} diff --git a/node/src/cli.rs b/node/src/cli.rs deleted file mode 100644 index dc614e553..000000000 --- a/node/src/cli.rs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use crate::chain_spec; -use clap::Parser; -use sc_cli::{self, KeySubcommand}; -use std::path::PathBuf; - -/// Sub-commands supported by the collator. -#[derive(Debug, clap::Parser)] -pub enum Subcommand { - /// Export the genesis state of the parachain. - #[clap(name = "export-genesis-state")] - ExportGenesisState(ExportGenesisStateCommand), - - /// Export the genesis wasm of the parachain. - #[clap(name = "export-genesis-wasm")] - ExportGenesisWasm(ExportGenesisWasmCommand), - - /// Key management cli utilities - #[clap(subcommand)] - Key(KeySubcommand), - - /// Build a chain specification. - BuildSpec(sc_cli::BuildSpecCmd), - - /// Validate blocks. - CheckBlock(sc_cli::CheckBlockCmd), - - /// Export blocks. - ExportBlocks(sc_cli::ExportBlocksCmd), - - /// Export the state of a given block into a chain spec. - ExportState(sc_cli::ExportStateCmd), - - /// Import blocks. - ImportBlocks(sc_cli::ImportBlocksCmd), - - /// Remove the whole chain. - PurgeChain(cumulus_client_cli::PurgeChainCmd), - - /// Revert the chain to a previous state. - Revert(sc_cli::RevertCmd), - - /// The custom benchmark subcommmand benchmarking runtime pallets. - #[clap(name = "benchmark", about = "Benchmark runtime pallets.")] - Benchmark(frame_benchmarking_cli::BenchmarkCmd), -} - -/// Command for exporting the genesis state of the parachain -#[derive(Debug, clap::Parser)] -pub struct ExportGenesisStateCommand { - /// Output file name or stdout if unspecified. - #[clap(parse(from_os_str))] - pub output: Option, - - /// Id of the parachain this state is for. - /// - /// Default: 100 - #[clap(long, conflicts_with = "chain")] - pub parachain_id: Option, - - /// Write output in binary. Default is to write in hex. - #[clap(short, long)] - pub raw: bool, - - /// The name of the chain for that the genesis state should be exported. - #[clap(long, conflicts_with = "parachain-id")] - pub chain: Option, -} - -/// Command for exporting the genesis wasm file. -#[derive(Debug, clap::Parser)] -pub struct ExportGenesisWasmCommand { - /// Output file name or stdout if unspecified. - #[clap(parse(from_os_str))] - pub output: Option, - - /// Write output in binary. Default is to write in hex. - #[clap(short, long)] - pub raw: bool, - - /// The name of the chain for that the genesis wasm file should be exported. - #[clap(long)] - pub chain: Option, -} - -#[derive(Debug, clap::Parser)] -#[clap(propagate_version = true)] -#[clap(subcommand_negates_reqs = true)] -#[clap(args_conflicts_with_subcommands = true)] -pub struct Cli { - #[clap(subcommand)] - pub subcommand: Option, - - #[clap(flatten)] - pub run: cumulus_client_cli::RunCmd, - - /// Relay chain arguments - #[clap(raw = true)] - pub relay_chain_args: Vec, -} - -#[derive(Debug)] -pub struct RelayChainCli { - /// The actual relay chain cli object. - pub base: polkadot_cli::RunCmd, - - /// Optional chain id that should be passed to the relay chain. - pub chain_id: Option, - - /// The base path that should be used by the relay chain. - pub base_path: Option, -} - -impl RelayChainCli { - /// Parse the relay chain CLI parameters using the para chain `Configuration`. - pub fn new<'a>( - para_config: &sc_service::Configuration, - relay_chain_args: impl Iterator, - ) -> Self { - let extension = chain_spec::Extensions::try_get(&*para_config.chain_spec); - let chain_id = extension.map(|e| e.relay_chain.clone()); - let base_path = para_config.base_path.as_ref().map(|x| x.path().join("polkadot")); - Self { base_path, chain_id, base: polkadot_cli::RunCmd::parse_from(relay_chain_args) } - } -} diff --git a/node/src/command.rs b/node/src/command.rs deleted file mode 100644 index 66b2a321f..000000000 --- a/node/src/command.rs +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use crate::{ - chain_spec, - cli::{Cli, RelayChainCli, Subcommand}, - service::{new_partial, RuntimeExecutor}, -}; -use codec::Encode; -use cumulus_client_service::genesis::generate_genesis_block; -use cumulus_primitives_core::ParaId; -use dkg_runtime::{Block, RuntimeApi}; -use log::info; -use polkadot_parachain::primitives::AccountIdConversion; -use sc_cli::{ - ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, - NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli, -}; -use sc_service::config::{BasePath, PrometheusConfig}; -use sp_core::hexdisplay::HexDisplay; -use sp_runtime::traits::Block as BlockT; -use std::{io::Write, net::SocketAddr}; - -fn load_spec(id: &str) -> std::result::Result, String> { - Ok(match id { - "dev" => Box::new(chain_spec::development_config(2000.into())), - "template-rococo" => Box::new(chain_spec::local_testnet_config(2000.into())), - "" | "local" => Box::new(chain_spec::local_testnet_config(2000.into())), - path => Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?), - }) -} - -impl SubstrateCli for Cli { - fn impl_name() -> String { - "Parachain Collator Template".into() - } - - fn impl_version() -> String { - env!("SUBSTRATE_CLI_IMPL_VERSION").into() - } - - fn description() -> String { - format!( - "Parachain Collator Template\n\nThe command-line arguments provided first will be \ - passed to the parachain node, while the arguments provided after -- will be passed \ - to the relaychain node.\n\n\ - {} [parachain-args] -- [relaychain-args]", - Self::executable_name() - ) - } - - fn author() -> String { - env!("CARGO_PKG_AUTHORS").into() - } - - fn support_url() -> String { - "https://github.com/substrate-developer-hub/substrate-parachain-template/issues/new".into() - } - - fn copyright_start_year() -> i32 { - 2017 - } - - fn load_spec(&self, id: &str) -> std::result::Result, String> { - load_spec(id) - } - - fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { - &dkg_runtime::VERSION - } -} - -impl SubstrateCli for RelayChainCli { - fn impl_name() -> String { - "Parachain Collator Template".into() - } - - fn impl_version() -> String { - env!("SUBSTRATE_CLI_IMPL_VERSION").into() - } - - fn description() -> String { - "Parachain Collator Template\n\nThe command-line arguments provided first will be \ - passed to the parachain node, while the arguments provided after -- will be passed \ - to the relaychain node.\n\n\ - dkg_node [parachain-args] -- [relaychain-args]" - .into() - } - - fn author() -> String { - env!("CARGO_PKG_AUTHORS").into() - } - - fn support_url() -> String { - "https://github.com/substrate-developer-hub/substrate-parachain-template/issues/new".into() - } - - fn copyright_start_year() -> i32 { - 2017 - } - - fn load_spec(&self, id: &str) -> std::result::Result, String> { - polkadot_cli::Cli::from_iter([RelayChainCli::executable_name()].iter()).load_spec(id) - } - - fn native_runtime_version(chain_spec: &Box) -> &'static RuntimeVersion { - polkadot_cli::Cli::native_runtime_version(chain_spec) - } -} - -#[allow(clippy::borrowed_box)] -fn extract_genesis_wasm(chain_spec: &Box) -> Result> { - let mut storage = chain_spec.build_storage()?; - - storage - .top - .remove(sp_core::storage::well_known_keys::CODE) - .ok_or_else(|| "Could not find wasm file in genesis state!".into()) -} - -macro_rules! construct_async_run { - (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ - let runner = $cli.create_runner($cmd)?; - runner.async_run(|$config| { - let $components = new_partial::< - RuntimeApi, - RuntimeExecutor, - _ - >( - &$config, - crate::service::parachain_build_import_queue, - )?; - let task_manager = $components.task_manager; - { $( $code )* }.map(|v| (v, task_manager)) - }) - }} -} - -/// Parse command line arguments into service configuration. -pub fn run() -> Result<()> { - let cli = Cli::from_args(); - - match &cli.subcommand { - Some(Subcommand::BuildSpec(cmd)) => { - let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) - }, - Some(Subcommand::CheckBlock(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { - Ok(cmd.run(components.client, components.import_queue)) - }) - }, - Some(Subcommand::ExportBlocks(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { - Ok(cmd.run(components.client, config.database)) - }) - }, - Some(Subcommand::ExportState(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { - Ok(cmd.run(components.client, config.chain_spec)) - }) - }, - Some(Subcommand::ImportBlocks(cmd)) => { - construct_async_run!(|components, cli, cmd, config| { - Ok(cmd.run(components.client, components.import_queue)) - }) - }, - Some(Subcommand::PurgeChain(cmd)) => { - let runner = cli.create_runner(cmd)?; - - runner.sync_run(|config| { - let polkadot_cli = RelayChainCli::new( - &config, - [RelayChainCli::executable_name()].iter().chain(cli.relay_chain_args.iter()), - ); - - let polkadot_config = SubstrateCli::create_configuration( - &polkadot_cli, - &polkadot_cli, - config.tokio_handle.clone(), - ) - .map_err(|err| format!("Relay chain argument error: {}", err))?; - - cmd.run(config, polkadot_config) - }) - }, - Some(Subcommand::Revert(cmd)) => construct_async_run!(|components, cli, cmd, config| { - Ok(cmd.run(components.client, components.backend)) - }), - Some(Subcommand::ExportGenesisState(params)) => { - let mut builder = sc_cli::LoggerBuilder::new(""); - builder.with_profiling(sc_tracing::TracingReceiver::Log, ""); - let _ = builder.init(); - - let spec = load_spec(¶ms.chain.clone().unwrap_or_default())?; - let state_version = Cli::native_runtime_version(&spec).state_version(); - let block: Block = generate_genesis_block(&spec, state_version)?; - let raw_header = block.header().encode(); - let output_buf = if params.raw { - raw_header - } else { - format!("0x{:?}", HexDisplay::from(&block.header().encode())).into_bytes() - }; - - if let Some(output) = ¶ms.output { - std::fs::write(output, output_buf)?; - } else { - std::io::stdout().write_all(&output_buf)?; - } - - Ok(()) - }, - Some(Subcommand::ExportGenesisWasm(params)) => { - let mut builder = sc_cli::LoggerBuilder::new(""); - builder.with_profiling(sc_tracing::TracingReceiver::Log, ""); - let _ = builder.init(); - - let raw_wasm_blob = - extract_genesis_wasm(&cli.load_spec(¶ms.chain.clone().unwrap_or_default())?)?; - let output_buf = if params.raw { - raw_wasm_blob - } else { - format!("0x{:?}", HexDisplay::from(&raw_wasm_blob)).into_bytes() - }; - - if let Some(output) = ¶ms.output { - std::fs::write(output, output_buf)?; - } else { - std::io::stdout().write_all(&output_buf)?; - } - - Ok(()) - }, - Some(Subcommand::Benchmark(cmd)) => - if cfg!(feature = "runtime-benchmarks") { - let runner = cli.create_runner(cmd)?; - - runner.sync_run(|config| cmd.run::(config)) - } else { - Err("Benchmarking wasn't enabled when building the node. \ - You can enable it with `--features runtime-benchmarks`." - .into()) - }, - Some(Subcommand::Key(cmd)) => cmd.run(&cli), - None => { - let runner = cli.create_runner(&cli.run.normalize())?; - - runner.run_node_until_exit(|config| async move { - let para_id = chain_spec::Extensions::try_get(&*config.chain_spec) - .map(|e| e.para_id) - .ok_or("Could not find parachain ID in chain-spec.")?; - - let polkadot_cli = RelayChainCli::new( - &config, - [RelayChainCli::executable_name()].iter().chain(cli.relay_chain_args.iter()), - ); - - let id = ParaId::from(para_id); - - let parachain_account = - AccountIdConversion::::into_account(&id); - - let state_version = - RelayChainCli::native_runtime_version(&config.chain_spec).state_version(); - let block: Block = generate_genesis_block(&config.chain_spec, state_version) - .map_err(|e| format!("{:?}", e))?; - let genesis_state = format!("0x{:?}", HexDisplay::from(&block.header().encode())); - - let tokio_handle = config.tokio_handle.clone(); - let polkadot_config = - SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, tokio_handle) - .map_err(|err| format!("Relay chain argument error: {}", err))?; - - info!("Parachain id: {:?}", id); - info!("Parachain Account: {}", parachain_account); - info!("Parachain genesis state: {}", genesis_state); - info!("Is collating: {}", if config.role.is_authority() { "yes" } else { "no" }); - - crate::service::start_parachain_node(config, polkadot_config, id) - .await - .map(|r| r.0) - .map_err(Into::into) - }) - }, - } -} - -impl DefaultConfigurationValues for RelayChainCli { - fn p2p_listen_port() -> u16 { - 30334 - } - - fn rpc_ws_listen_port() -> u16 { - 9945 - } - - fn rpc_http_listen_port() -> u16 { - 9934 - } - - fn prometheus_listen_port() -> u16 { - 9616 - } -} - -impl CliConfiguration for RelayChainCli { - fn shared_params(&self) -> &SharedParams { - self.base.base.shared_params() - } - - fn import_params(&self) -> Option<&ImportParams> { - self.base.base.import_params() - } - - fn network_params(&self) -> Option<&NetworkParams> { - self.base.base.network_params() - } - - fn keystore_params(&self) -> Option<&KeystoreParams> { - self.base.base.keystore_params() - } - - fn base_path(&self) -> Result> { - Ok(self - .shared_params() - .base_path() - .or_else(|| self.base_path.clone().map(Into::into))) - } - - fn rpc_http(&self, default_listen_port: u16) -> Result> { - self.base.base.rpc_http(default_listen_port) - } - - fn rpc_ipc(&self) -> Result> { - self.base.base.rpc_ipc() - } - - fn rpc_ws(&self, default_listen_port: u16) -> Result> { - self.base.base.rpc_ws(default_listen_port) - } - - fn prometheus_config( - &self, - default_listen_port: u16, - chain_spec: &Box, - ) -> Result> { - self.base.base.prometheus_config(default_listen_port, chain_spec) - } - - fn init( - &self, - _support_url: &String, - _impl_version: &String, - _logger_hook: F, - _config: &sc_service::Configuration, - ) -> Result<()> - where - F: FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration), - { - unreachable!("PolkadotCli is never initialized; qed"); - } - - fn chain_id(&self, is_dev: bool) -> Result { - let chain_id = self.base.base.chain_id(is_dev)?; - - Ok(if chain_id.is_empty() { self.chain_id.clone().unwrap_or_default() } else { chain_id }) - } - - fn role(&self, is_dev: bool) -> Result { - self.base.base.role(is_dev) - } - - fn transaction_pool(&self) -> Result { - self.base.base.transaction_pool() - } - - fn state_cache_child_ratio(&self) -> Result> { - self.base.base.state_cache_child_ratio() - } - - fn rpc_methods(&self) -> Result { - self.base.base.rpc_methods() - } - - fn rpc_ws_max_connections(&self) -> Result> { - self.base.base.rpc_ws_max_connections() - } - - fn rpc_cors(&self, is_dev: bool) -> Result>> { - self.base.base.rpc_cors(is_dev) - } - - fn default_heap_pages(&self) -> Result> { - self.base.base.default_heap_pages() - } - - fn force_authoring(&self) -> Result { - self.base.base.force_authoring() - } - - fn disable_grandpa(&self) -> Result { - self.base.base.disable_grandpa() - } - - fn max_runtime_instances(&self) -> Result> { - self.base.base.max_runtime_instances() - } - - fn announce_block(&self) -> Result { - self.base.base.announce_block() - } - - fn telemetry_endpoints( - &self, - chain_spec: &Box, - ) -> Result> { - self.base.base.telemetry_endpoints(chain_spec) - } -} diff --git a/node/src/main.rs b/node/src/main.rs deleted file mode 100644 index 62da3e24f..000000000 --- a/node/src/main.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//! Substrate Parachain Node Template CLI - -#![warn(missing_docs)] - -mod chain_spec; -#[macro_use] -mod service; -mod cli; -mod command; - -fn main() -> sc_cli::Result<()> { - command::run() -} diff --git a/node/src/service.rs b/node/src/service.rs deleted file mode 100644 index c77a4a286..000000000 --- a/node/src/service.rs +++ /dev/null @@ -1,521 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// std -use std::{sync::Arc, time::Duration}; - -// Local Runtime Types -use dkg_runtime::{AccountId, Balance, Index as Nonce, RuntimeApi}; - -// Cumulus Imports -use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion}; -use cumulus_client_consensus_common::ParachainConsensus; -use cumulus_client_network::BlockAnnounceValidator; -use cumulus_client_service::{ - prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams, -}; -use cumulus_primitives_core::ParaId; -use cumulus_relay_chain_interface::RelayChainInterface; -use cumulus_relay_chain_local::build_relay_chain_interface; - -// Substrate Imports -use sc_client_api::ExecutorProvider; -use sc_executor::NativeElseWasmExecutor; -use sc_network::NetworkService; -use sc_service::{ - BasePath, Configuration, PartialComponents, Role, TFullBackend, TFullClient, TaskManager, -}; -use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; -use sp_api::ConstructRuntimeApi; -use sp_consensus::SlotData; -use sp_keystore::SyncCryptoStorePtr; -use sp_runtime::traits::BlakeTwo256; -use substrate_prometheus_endpoint::Registry; - -// Runtime type overrides -type BlockNumber = u32; -type Header = sp_runtime::generic::Header; -pub type Block = sp_runtime::generic::Block; -type Hash = sp_core::H256; - -pub struct RuntimeExecutor; - -impl sc_executor::NativeExecutionDispatch for RuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - - fn dispatch(method: &str, data: &[u8]) -> Option> { - dkg_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - dkg_runtime::native_version() - } -} -pub type DKGRuntimeExecutor = NativeElseWasmExecutor; - -/// Starts a `ServiceBuilder` for a full service. -/// -/// Use this macro if you don't actually need the full service, but just the builder in order to -/// be able to perform chain operations. -#[allow(clippy::type_complexity)] -pub fn new_partial( - config: &Configuration, - build_import_queue: BIQ, -) -> Result< - PartialComponents< - TFullClient>, - TFullBackend, - (), - sc_consensus::DefaultImportQueue< - Block, - TFullClient>, - >, - sc_transaction_pool::FullPool< - Block, - TFullClient>, - >, - (Option, Option), - >, - sc_service::Error, -> -where - RuntimeApi: ConstructRuntimeApi>> - + Send - + Sync - + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt< - Block, - StateBackend = sc_client_api::StateBackendFor, Block>, - > + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder, - sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, - Executor: sc_executor::NativeExecutionDispatch + 'static, - BIQ: FnOnce( - Arc>>, - &Configuration, - Option, - &TaskManager, - ) -> Result< - sc_consensus::DefaultImportQueue< - Block, - TFullClient>, - >, - sc_service::Error, - >, -{ - let telemetry = config - .telemetry_endpoints - .clone() - .filter(|x| !x.is_empty()) - .map(|endpoints| -> Result<_, sc_telemetry::Error> { - let worker = TelemetryWorker::new(16)?; - let telemetry = worker.handle().new_telemetry(endpoints); - Ok((worker, telemetry)) - }) - .transpose()?; - - let executor = sc_executor::NativeElseWasmExecutor::::new( - config.wasm_method, - config.default_heap_pages, - config.max_runtime_instances, - config.runtime_cache_size, - ); - - let (client, backend, keystore_container, task_manager) = - sc_service::new_full_parts::( - config, - telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), - executor, - )?; - let client = Arc::new(client); - - let telemetry_worker_handle = telemetry.as_ref().map(|(worker, _)| worker.handle()); - - let telemetry = telemetry.map(|(worker, telemetry)| { - task_manager.spawn_handle().spawn("telemetry", None, worker.run()); - telemetry - }); - - let transaction_pool = sc_transaction_pool::BasicPool::new_full( - config.transaction_pool.clone(), - config.role.is_authority().into(), - config.prometheus_registry(), - task_manager.spawn_essential_handle(), - client.clone(), - ); - - let import_queue = build_import_queue( - client.clone(), - config, - telemetry.as_ref().map(|telemetry| telemetry.handle()), - &task_manager, - )?; - - let params = PartialComponents { - backend, - client, - import_queue, - keystore_container, - task_manager, - transaction_pool, - select_chain: (), - other: (telemetry, telemetry_worker_handle), - }; - - Ok(params) -} - -/// Start a node with the given parachain `Configuration` and relay chain `Configuration`. -/// -/// This is the actual implementation that is abstract over the executor and the runtime api. -#[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node_impl( - parachain_config: Configuration, - polkadot_config: Configuration, - id: ParaId, - rpc_ext_builder: RB, - build_import_queue: BIQ, - build_consensus: BIC, -) -> sc_service::error::Result<( - TaskManager, - Arc>>, -)> -where - RuntimeApi: ConstructRuntimeApi>> - + Send - + Sync - + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt< - Block, - StateBackend = sc_client_api::StateBackendFor, Block>, - > + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo - + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi - + substrate_frame_rpc_system::AccountNonceApi - + dkg_runtime_primitives::DKGApi< - Block, - dkg_runtime_primitives::crypto::AuthorityId, - dkg_runtime::BlockNumber, - >, - sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, - Executor: sc_executor::NativeExecutionDispatch + 'static, - RB: Fn( - Arc>>, - ) -> Result, sc_service::Error> - + Send - + 'static, - BIQ: FnOnce( - Arc>>, - &Configuration, - Option, - &TaskManager, - ) -> Result< - sc_consensus::DefaultImportQueue< - Block, - TFullClient>, - >, - sc_service::Error, - > + 'static, - BIC: FnOnce( - Arc>>, - Option<&Registry>, - Option, - &TaskManager, - Arc, - Arc< - sc_transaction_pool::FullPool< - Block, - TFullClient>, - >, - >, - Arc>, - SyncCryptoStorePtr, - bool, - ) -> Result>, sc_service::Error>, -{ - if matches!(parachain_config.role, Role::Light) { - return Err("Light client not supported!".into()) - } - - let mut parachain_config = prepare_node_config(parachain_config); - - let params = new_partial::(¶chain_config, build_import_queue)?; - let (mut telemetry, telemetry_worker_handle) = params.other; - - let client = params.client.clone(); - let backend = params.backend.clone(); - let mut task_manager = params.task_manager; - - let (relay_chain_interface, collator_key) = - build_relay_chain_interface(polkadot_config, telemetry_worker_handle, &mut task_manager) - .map_err(|e| match e { - polkadot_service::Error::Sub(x) => x, - s => format!("{}", s).into(), - })?; - - let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id); - - let force_authoring = parachain_config.force_authoring; - let validator = parachain_config.role.is_authority(); - let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let transaction_pool = params.transaction_pool.clone(); - let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue); - - parachain_config.network.extra_sets.push(dkg_gadget::dkg_peers_set_config()); - - let (network, system_rpc_tx, start_network) = - sc_service::build_network(sc_service::BuildNetworkParams { - config: ¶chain_config, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - spawn_handle: task_manager.spawn_handle(), - import_queue: import_queue.clone(), - block_announce_validator_builder: Some(Box::new(|_| { - Box::new(block_announce_validator) - })), - warp_sync: None, - })?; - - let rpc_client = client.clone(); - let rpc_extensions_builder = Box::new(move |_, _| rpc_ext_builder(rpc_client.clone())); - - let base_path = if parachain_config.base_path.is_some() { - match parachain_config.base_path.as_ref() { - Some(BasePath::Permanenent(path_buf)) => Some(path_buf.clone()), - _ => None, - } - } else { - None - }; - - if validator { - dkg_primitives::utils::insert_controller_account_keys_into_keystore( - ¶chain_config, - Some(params.keystore_container.sync_keystore()), - ); - - let dkg_params = dkg_gadget::DKGParams { - client: client.clone(), - backend: backend.clone(), - key_store: Some(params.keystore_container.sync_keystore()), - network: network.clone(), - prometheus_registry: prometheus_registry.clone(), - base_path, - local_keystore: params.keystore_container.local_keystore(), - _block: std::marker::PhantomData::, - }; - - // Start the DKG gadget. - task_manager.spawn_essential_handle().spawn_blocking( - "dkg-gadget", - None, - dkg_gadget::start_dkg_gadget::<_, _, _, _>(dkg_params), - ); - } - - sc_service::spawn_tasks(sc_service::SpawnTasksParams { - rpc_extensions_builder, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - task_manager: &mut task_manager, - config: parachain_config, - keystore: params.keystore_container.sync_keystore(), - backend: backend.clone(), - network: network.clone(), - system_rpc_tx, - telemetry: telemetry.as_mut(), - })?; - - let announce_block = { - let network = network.clone(); - Arc::new(move |hash, data| network.announce_block(hash, data)) - }; - let relay_chain_slot_duration = Duration::from_secs(6); - if validator { - let parachain_consensus = build_consensus( - client.clone(), - prometheus_registry.as_ref(), - telemetry.as_ref().map(|t| t.handle()), - &task_manager, - relay_chain_interface.clone(), - transaction_pool, - network, - params.keystore_container.sync_keystore(), - force_authoring, - )?; - - let spawner = task_manager.spawn_handle(); - - let params = StartCollatorParams { - para_id: id, - block_status: client.clone(), - announce_block, - client: client.clone(), - task_manager: &mut task_manager, - relay_chain_interface, - spawner, - parachain_consensus, - import_queue, - collator_key, - relay_chain_slot_duration, - }; - - start_collator(params).await?; - } else { - let params = StartFullNodeParams { - client: client.clone(), - announce_block, - task_manager: &mut task_manager, - para_id: id, - relay_chain_interface, - relay_chain_slot_duration, - import_queue, - }; - - start_full_node(params)?; - } - - start_network.start_network(); - - Ok((task_manager, client)) -} - -/// Build the import queue for the the parachain runtime. -pub fn parachain_build_import_queue( - client: Arc>, - config: &Configuration, - telemetry: Option, - task_manager: &TaskManager, -) -> Result< - sc_consensus::DefaultImportQueue>, - sc_service::Error, -> { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - cumulus_client_consensus_aura::import_queue::< - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - _, - _, - _, - >(cumulus_client_consensus_aura::ImportQueueParams { - block_import: client.clone(), - client: client.clone(), - create_inherent_data_providers: move |_, _| async move { - let time = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( - *time, - slot_duration.slot_duration(), - ); - - Ok((time, slot)) - }, - registry: config.prometheus_registry(), - can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()), - spawner: &task_manager.spawn_essential_handle(), - telemetry, - }) - .map_err(Into::into) -} - -/// Start a normal parachain node. -pub async fn start_parachain_node( - parachain_config: Configuration, - polkadot_config: Configuration, - id: ParaId, -) -> sc_service::error::Result<(TaskManager, Arc>)> -{ - start_node_impl::( - parachain_config, - polkadot_config, - id, - |_| Ok(Default::default()), - parachain_build_import_queue, - |client, - prometheus_registry, - telemetry, - task_manager, - relay_chain_interface, - transaction_pool, - sync_oracle, - keystore, - force_authoring| { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - - Ok(AuraConsensus::build::( - BuildAuraConsensusParams { - proposer_factory, - create_inherent_data_providers: move |_, (relay_parent, validation_data)| { - let relay_chain_interface = relay_chain_interface.clone(); - async move { - let parachain_inherent = - cumulus_primitives_parachain_inherent::ParachainInherentData::create_at( - relay_parent, - &relay_chain_interface, - &validation_data, - id, - ).await; - let time = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( - *time, - slot_duration.slot_duration(), - ); - - let parachain_inherent = parachain_inherent.ok_or_else(|| { - Box::::from( - "Failed to create parachain inherent", - ) - })?; - Ok((time, slot, parachain_inherent)) - } - }, - block_import: client.clone(), - para_client: client, - backoff_authoring_blocks: Option::<()>::None, - sync_oracle, - keystore, - force_authoring, - slot_duration, - // We got around 500ms for proposing - block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32), - // And a maximum of 750ms if slots are skipped - max_block_proposal_slot_portion: Some(SlotProportion::new(1f32 / 16f32)), - telemetry, - }, - )) - }, - ) - .await -} diff --git a/pallets/dkg-metadata/Cargo.toml b/pallets/dkg-metadata/Cargo.toml index ae83c04f5..dd4766962 100644 --- a/pallets/dkg-metadata/Cargo.toml +++ b/pallets/dkg-metadata/Cargo.toml @@ -6,37 +6,37 @@ version = "0.1.0" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4" -codec = { package = "parity-scale-codec", version = "2.0.0", features = [ +codec = { package = "parity-scale-codec", version = "3", features = [ "derive", ], default-features = false } -scale-info = { version = "1.0", default-features = false, features = [ +scale-info = { version = "2.1.1", default-features = false, features = [ "derive", ] } hex = { version = "0.4", default-features = false } libsecp256k1 = { version = "0.7.0", default-features = false } dkg-runtime-primitives = { path = "../../dkg-runtime-primitives", default-features = false } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false, optional = true } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } [dev-dependencies] serde = { version = "1.0.119" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } [features] default = ["std"] diff --git a/pallets/dkg-metadata/src/benchmarking.rs b/pallets/dkg-metadata/src/benchmarking.rs index 976f7ebb9..78da9f014 100644 --- a/pallets/dkg-metadata/src/benchmarking.rs +++ b/pallets/dkg-metadata/src/benchmarking.rs @@ -27,7 +27,9 @@ use dkg_runtime_primitives::{ use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; use frame_system::RawOrigin; -use sp_io::crypto::{ecdsa_generate, ecdsa_sign_prehashed, sr25519_generate, sr25519_sign}; +use sp_io::crypto::{ + ecdsa_generate, ecdsa_sign, ecdsa_sign_prehashed, sr25519_generate, sr25519_sign, +}; use sp_runtime::{key_types::AURA, traits::TrailingZeroInput, Permill}; const MAX_AUTHORITIES: u32 = 100; @@ -42,18 +44,19 @@ fn assert_has_event(generic_event: ::Event) { frame_system::Pallet::::assert_has_event(generic_event.into()); } -fn mock_signature(pub_key: sr25519::Public, dkg_key: ecdsa::Public) -> (Vec, Vec) { +fn mock_signature(pub_key: ecdsa::Public, dkg_key: ecdsa::Public) -> (Vec, Vec) { let msg = dkg_key.encode(); - let signature: sr25519::Signature = sr25519_sign(AURA, &pub_key, &msg).unwrap(); + let hash = keccak_256(&msg); + let signature: ecdsa::Signature = ecdsa_sign_prehashed(KEY_TYPE, &pub_key, &hash).unwrap(); (msg, signature.encode()) } -fn mock_pub_key() -> sr25519::Public { - sr25519_generate(AURA, None) +fn mock_pub_key() -> ecdsa::Public { + ecdsa_generate(KEY_TYPE, None) } fn mock_misbehaviour_report( - pub_key: sr25519::Public, + pub_key: ecdsa::Public, offender: T::DKGId, misbehaviour_type: MisbehaviourType, ) -> Vec { @@ -65,13 +68,13 @@ fn mock_misbehaviour_report( }); payload.extend_from_slice(round_id.to_be_bytes().as_ref()); payload.extend_from_slice(offender.clone().as_ref()); - - let signature = sr25519_sign(AURA, &pub_key, &payload).unwrap(); + let hash = keccak_256(&payload); + let signature = ecdsa_sign_prehashed(KEY_TYPE, &pub_key, &hash).unwrap(); signature.encode() } -fn mock_account_id(pub_key: sr25519::Public) -> T::AccountId { +fn mock_account_id(pub_key: ecdsa::Public) -> T::AccountId { pub_key.using_encoded(|entropy| { T::AccountId::decode(&mut TrailingZeroInput::new(entropy)) .expect("infinite input; no invalid input; qed") @@ -146,16 +149,17 @@ benchmarks! { let n in 3..MAX_AUTHORITIES; let dkg_key = ecdsa_generate(KEY_TYPE, None); let mut aggregated_public_keys = AggregatedPublicKeys::default(); - let mut current_authorities: Vec = Vec::new(); + let mut current_authorities: Vec = Vec::new(); for id in 1..=n { let authority_id = mock_pub_key(); - aggregated_public_keys.keys_and_signatures.push(mock_signature(authority_id, dkg_key.clone())); - current_authorities.push(mock_account_id::(authority_id)); + aggregated_public_keys.keys_and_signatures.push(mock_signature(authority_id, dkg_key)); + let account_id = T::DKGId::from(authority_id); + current_authorities.push(account_id); } let threshold = u16::try_from(current_authorities.len() / 2).unwrap() + 1; SignatureThreshold::::put(threshold); - CurrentAuthoritiesAccounts::::put(¤t_authorities); - let caller = current_authorities[0].clone(); + Authorities::::put(¤t_authorities); + let caller = T::AccountId::from(sr25519::Public::from_raw([1u8; 32])); }: _(RawOrigin::Signed(caller), aggregated_public_keys) verify { let (id, dkg_key) = Pallet::::dkg_public_key(); @@ -169,16 +173,17 @@ benchmarks! { let n in 3..MAX_AUTHORITIES; let dkg_key = ecdsa_generate(KEY_TYPE, None); let mut aggregated_public_keys = AggregatedPublicKeys::default(); - let mut next_authorities: Vec = Vec::new(); + let mut next_authorities: Vec = Vec::new(); for id in 1..=n { let authority_id = mock_pub_key(); - aggregated_public_keys.keys_and_signatures.push(mock_signature(authority_id, dkg_key.clone())); - next_authorities.push(mock_account_id::(authority_id)); + aggregated_public_keys.keys_and_signatures.push(mock_signature(authority_id, dkg_key)); + let account_id = T::DKGId::from(authority_id); + next_authorities.push(account_id); } let threshold = u16::try_from(next_authorities.len() / 2).unwrap() + 1; NextSignatureThreshold::::put(threshold); - NextAuthoritiesAccounts::::put(&next_authorities); - let caller = next_authorities[0].clone(); + NextAuthorities::::put(&next_authorities); + let caller = T::AccountId::from(sr25519::Public::from_raw([1u8; 32])); }: _(RawOrigin::Signed(caller), aggregated_public_keys) verify { let (_ ,next_dkg_key) = Pallet::::next_dkg_public_key().unwrap(); @@ -219,8 +224,8 @@ benchmarks! { submit_misbehaviour_reports { let n in 3..MAX_AUTHORITIES; let offender: T::DKGId = T::DKGId::from(ecdsa_generate(KEY_TYPE, None)); - let mut next_authorities: Vec = Vec::new(); - let mut reporters: Vec = Vec::new(); + let mut next_authorities: Vec = Vec::new(); + let mut reporters: Vec = Vec::new(); let mut signatures: Vec> = Vec::new(); let round_id = 1; let misbehaviour_type = MisbehaviourType::Keygen; @@ -228,12 +233,13 @@ benchmarks! { let authority_id = mock_pub_key(); let sig = mock_misbehaviour_report::(authority_id, offender.clone(), misbehaviour_type); signatures.push(sig); - reporters.push(authority_id); - next_authorities.push(mock_account_id::(authority_id)); + let dkg_id = T::DKGId::from(authority_id); + reporters.push(dkg_id.clone()); + next_authorities.push(dkg_id); } let threshold = u16::try_from(next_authorities.len() / 2).unwrap() + 1; NextSignatureThreshold::::put(threshold); - NextAuthoritiesAccounts::::put(&next_authorities); + NextAuthorities::::put(&next_authorities); let aggregated_misbehaviour_reports= AggregatedMisbehaviourReports { misbehaviour_type, round_id, @@ -241,7 +247,7 @@ benchmarks! { reporters:reporters.clone(), signatures, }; - let caller = next_authorities[0].clone(); + let caller = T::AccountId::from(sr25519::Public::from_raw([1u8; 32])); }: _(RawOrigin::Signed(caller), aggregated_misbehaviour_reports) verify { assert_last_event::(Event::MisbehaviourReportsSubmitted{ diff --git a/pallets/dkg-metadata/src/lib.rs b/pallets/dkg-metadata/src/lib.rs index 799f81bc9..dff09d73b 100644 --- a/pallets/dkg-metadata/src/lib.rs +++ b/pallets/dkg-metadata/src/lib.rs @@ -101,6 +101,7 @@ use frame_support::{ Parameter, }; use frame_system::offchain::{SendSignedTransaction, Signer}; +use sp_std::convert::{TryFrom, TryInto}; use dkg_runtime_primitives::{ offchain::storage_keys::{ @@ -230,7 +231,9 @@ pub mod pallet { let _res = Self::submit_next_public_key_onchain(block_number); let _res = Self::submit_public_key_signature_onchain(block_number); let _res = Self::submit_misbehaviour_reports_onchain(block_number); + #[cfg(feature = "std")] let (authority_id, pk) = DKGPublicKey::::get(); + #[cfg(feature = "std")] let maybe_next_key = NextDKGPublicKey::::get(); #[cfg(feature = "std")] // required since we use hex and strings frame_support::log::debug!( @@ -472,7 +475,8 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { pub authorities: Vec, - pub threshold: u32, + pub keygen_threshold: u16, + pub signature_threshold: u16, pub authority_ids: Vec, } @@ -536,27 +540,34 @@ pub mod pallet { #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { - Self { authorities: Vec::new(), threshold: 0, authority_ids: Vec::new() } + Self { + authorities: Vec::new(), + signature_threshold: 1, + keygen_threshold: 3, + authority_ids: Vec::new(), + } } } #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - let mut signature_threshold = 1u16; - let keygen_threshold = u16::try_from(self.authorities.len()).unwrap(); - - if keygen_threshold <= signature_threshold { - signature_threshold = keygen_threshold - 1; - } - + assert!( + self.signature_threshold < self.keygen_threshold, + "Signature threshold must be less than keygen threshold" + ); + assert!(self.keygen_threshold > 1, "Keygen threshold must be greater than 1"); + assert!( + self.authority_ids.len() >= self.keygen_threshold as usize, + "Not enough authority ids specified" + ); // Set thresholds to be the same - SignatureThreshold::::put(signature_threshold); - KeygenThreshold::::put(keygen_threshold); - NextSignatureThreshold::::put(signature_threshold); - NextKeygenThreshold::::put(keygen_threshold); - PendingSignatureThreshold::::put(signature_threshold); - PendingKeygenThreshold::::put(keygen_threshold); + SignatureThreshold::::put(self.signature_threshold); + KeygenThreshold::::put(self.keygen_threshold); + NextSignatureThreshold::::put(self.signature_threshold); + NextKeygenThreshold::::put(self.keygen_threshold); + PendingSignatureThreshold::::put(self.signature_threshold); + PendingKeygenThreshold::::put(self.keygen_threshold); // Set refresh parameters RefreshDelay::::put(T::RefreshDelay::get()); RefreshNonce::::put(0); @@ -661,7 +672,9 @@ pub mod pallet { ensure_signed(origin)?; ensure!(!DKGPublicKey::::exists(), Error::::AlreadySubmittedPublicKey); - let authorities = Self::authorities(); + let authorities: Vec = + Self::best_authorities().iter().map(|id| id.1.clone()).collect(); + let dict = Self::process_public_key_submissions(keys_and_signatures, authorities); let threshold = Self::signature_threshold(); @@ -714,7 +727,8 @@ pub mod pallet { ensure_signed(origin)?; ensure!(!NextDKGPublicKey::::exists(), Error::::AlreadySubmittedPublicKey); - let next_authorities = Self::next_authorities(); + let next_authorities: Vec = + Self::next_best_authorities().iter().map(|id| id.1.clone()).collect(); let dict = Self::process_public_key_submissions(keys_and_signatures, next_authorities); let threshold = Self::next_signature_threshold(); @@ -874,24 +888,29 @@ pub mod pallet { // session change let unjailed_authorities = Self::next_best_authorities() .into_iter() - .filter(|(_, id)| { - !JailedKeygenAuthorities::::contains_key(id) || *id != offender - }) + .filter(|(_, id)| !JailedKeygenAuthorities::::contains_key(id)) .map(|(_, id)| id) .collect::>(); - if unjailed_authorities.len() < Self::next_keygen_threshold().into() { - // Handle edge case properly (shouldn't drop below 2 authorities) - if unjailed_authorities.len() > 2 { - JailedKeygenAuthorities::::insert(offender, now); - - let new_val = - u16::try_from(unjailed_authorities.len()).unwrap_or_default(); - NextKeygenThreshold::::put(new_val); - PendingKeygenThreshold::::put(new_val); + if unjailed_authorities.contains(&offender) { + // Jail the offender + JailedKeygenAuthorities::::insert(&offender, now); + if unjailed_authorities.len() <= Self::next_keygen_threshold().into() { + // Handle edge case properly (shouldn't drop below 2 authorities) + if unjailed_authorities.len() > 2 { + let new_val = u16::try_from(unjailed_authorities.len() - 1) + .unwrap_or_default(); + NextKeygenThreshold::::put(new_val); + PendingKeygenThreshold::::put(new_val); + } } - } else { - JailedKeygenAuthorities::::insert(offender, now); } + NextBestAuthorities::::put(Self::get_best_authorities( + Self::next_keygen_threshold() as usize, + &unjailed_authorities + .into_iter() + .filter(|id| *id != offender) + .collect::>(), + )); }, MisbehaviourType::Sign => { // These are the authorities who underwent keygen. @@ -1245,6 +1264,8 @@ impl Pallet { // Set refresh in progress to false RefreshInProgress::::put(false); // Update the next thresholds for the next session + let new_current_signature_threshold = NextSignatureThreshold::::get(); + let new_current_keygen_threshold = NextKeygenThreshold::::get(); NextSignatureThreshold::::put(PendingSignatureThreshold::::get()); NextKeygenThreshold::::put(PendingKeygenThreshold::::get()); // Compute next ID for next authorities @@ -1254,16 +1275,29 @@ impl Pallet { NextAuthorities::::put(&next_authority_ids); NextAuthoritiesAccounts::::put(&next_authorities_accounts); NextAuthoritySetId::::put(next_id.saturating_add(1)); - let next_best_authorities = Self::next_best_authorities(); - NextBestAuthorities::::put(Self::get_best_authorities( - Self::next_keygen_threshold() as usize, - &next_authority_ids, - )); + let new_best_authorities = Self::next_best_authorities(); // Update the keys for the next authorities let next_pub_key = Self::next_dkg_public_key(); let next_pub_key_signature = Self::next_public_key_signature(); let dkg_pub_key = Self::dkg_public_key(); let pub_key_signature = Self::public_key_signature(); + // Ensure next/pending thresholds remain valid across authority set changes that may + // break. We update the pending thresholds because we call `refresh_keys` below, which + // rotates all the thresholds into the current / next sets. Pending becomes the next, + // next becomes the current. + if next_authority_ids.len() < Self::next_keygen_threshold().into() { + NextKeygenThreshold::::put(next_authority_ids.len() as u16); + PendingKeygenThreshold::::put(next_authority_ids.len() as u16); + } + if next_authority_ids.len() <= Self::next_signature_threshold().into() { + NextSignatureThreshold::::put(next_authority_ids.len() as u16 - 1); + PendingSignatureThreshold::::put(next_authority_ids.len() as u16 - 1); + } + // Update the next best authorities after any and all changes to the thresholds. + NextBestAuthorities::::put(Self::get_best_authorities( + Self::next_keygen_threshold() as usize, + &next_authority_ids, + )); // Switch on forced for forceful rotations let v = if forced { // If forced we supply an empty signature @@ -1274,26 +1308,12 @@ impl Pallet { // Rotate the authority set if a next pub key and next signature exist if let Some((next_pub_key, next_pub_key_signature)) = v { // Update the active thresholds for the next session - SignatureThreshold::::put(NextSignatureThreshold::::get()); - KeygenThreshold::::put(NextKeygenThreshold::::get()); - // Ensure next/pending thresholds remain valid across authority set changes that may - // break. We update the pending thresholds because we call `refresh_keys` below, which - // rotates all the thresholds into the current / next sets. Pending becomes the next, - // next becomes the current. - if next_authority_ids.len() < Self::next_keygen_threshold().into() { - NextKeygenThreshold::::put(next_authority_ids.len() as u16); - PendingKeygenThreshold::::put(next_authority_ids.len() as u16); - } - if next_authority_ids.len() <= Self::next_signature_threshold().into() { - NextSignatureThreshold::::put(next_authority_ids.len() as u16 - 1); - PendingSignatureThreshold::::put(next_authority_ids.len() as u16 - 1); - } - + SignatureThreshold::::put(new_current_signature_threshold); + KeygenThreshold::::put(new_current_keygen_threshold); // Update the new and next authorities Authorities::::put(&new_authority_ids); CurrentAuthoritiesAccounts::::put(&new_authorities_accounts); - BestAuthorities::::put(next_best_authorities); - let next_id = Self::authority_set_id().saturating_add(1); + BestAuthorities::::put(new_best_authorities); // Update the set id after changing AuthoritySetId::::put(next_id); // Deposit a consensus log about the authority set change @@ -1318,7 +1338,7 @@ impl Pallet { }); Self::deposit_event(Event::PublicKeySignatureChanged { pub_key_sig: next_pub_key_signature, - }) + }); } } @@ -1337,9 +1357,11 @@ impl Pallet { NextAuthorities::::put(authorities); NextAuthoritySetId::::put(1); NextAuthoritiesAccounts::::put(authority_account_ids); - let best_authorities = Self::get_best_authorities(authorities.len(), authorities); + let best_authorities = + Self::get_best_authorities(Self::keygen_threshold() as usize, authorities); BestAuthorities::::put(best_authorities); - let next_best_authorities = Self::get_best_authorities(authorities.len(), authorities); + let next_best_authorities = + Self::get_best_authorities(Self::keygen_threshold() as usize, authorities); NextBestAuthorities::::put(next_best_authorities); WeightInfo for WebbWeight { // Storage: DKG NextAuthorities (r:1 w:0) // Storage: DKG PendingSignatureThreshold (r:1 w:1) fn set_signature_threshold() -> Weight { - (13_000_000_u64) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (16_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: DKG NextAuthorities (r:1 w:0) // Storage: DKG PendingSignatureThreshold (r:1 w:0) // Storage: DKG PendingKeygenThreshold (r:1 w:1) fn set_keygen_threshold() -> Weight { - (15_000_000_u64) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (27_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: DKG RefreshDelay (r:0 w:1) fn set_refresh_delay(_n: u32, ) -> Weight { - (984_000_u64) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (2_110_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: DKG RefreshInProgress (r:1 w:0) // Storage: DKG RefreshNonce (r:1 w:1) fn manual_increment_nonce() -> Weight { - (5_000_000_u64) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (9_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: DKG RefreshInProgress (r:1 w:1) // Storage: DKG NextDKGPublicKey (r:1 w:0) @@ -98,89 +91,103 @@ impl WeightInfo for WebbWeight { // Storage: DKG ShouldManualRefresh (r:0 w:1) // Storage: DKGProposalHandler UnsignedProposalQueue (r:0 w:1) fn manual_refresh() -> Weight { - (19_000_000_u64) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + (30_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) } // Storage: DKG DKGPublicKey (r:1 w:1) - // Storage: DKG CurrentAuthoritiesAccounts (r:1 w:0) + // Storage: DKG Authorities (r:1 w:0) // Storage: DKG SignatureThreshold (r:1 w:0) // Storage: DKG AuthoritySetId (r:1 w:0) - // Storage: DKG AccountToAuthority (r:3 w:0) + // Storage: DKG AuthorityReputations (r:3 w:3) fn submit_public_key(n: u32, ) -> Weight { - (0_u64) - // Standard Error: 15_510_000 - .saturating_add((2_003_464_000_u64).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n as Weight))) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (0 as Weight) + // Standard Error: 22_593_000 + .saturating_add((2_352_338_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(n as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(n as Weight))) } // Storage: DKG NextDKGPublicKey (r:1 w:1) - // Storage: DKG NextAuthoritiesAccounts (r:1 w:0) + // Storage: DKG NextAuthorities (r:1 w:0) // Storage: DKG NextSignatureThreshold (r:1 w:0) - // Storage: DKG AuthoritySetId (r:1 w:0) + // Storage: DKG NextAuthoritySetId (r:1 w:0) fn submit_next_public_key(n: u32, ) -> Weight { - (0_u64) - // Standard Error: 15_622_000 - .saturating_add((2_004_004_000_u64).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (0 as Weight) + // Standard Error: 22_659_000 + .saturating_add((2_358_378_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: DKG NextDKGPublicKey (r:1 w:1) // Storage: DKG NextPublicKeySignature (r:1 w:1) // Storage: DKG UsedSignatures (r:1 w:1) // Storage: DKG RefreshNonce (r:1 w:0) // Storage: DKG DKGPublicKey (r:1 w:1) + // Storage: DKGProposalHandler UnsignedProposalQueue (r:1 w:0) // Storage: DKG ShouldManualRefresh (r:1 w:1) - // Storage: DKG AuthoritySetId (r:1 w:1) - // Storage: DKG NextSignatureThreshold (r:1 w:1) - // Storage: DKG NextKeygenThreshold (r:1 w:1) + // Storage: DKG NextAuthorities (r:1 w:1) + // Storage: DKG NextAuthoritiesAccounts (r:1 w:1) + // Storage: DKGProposals AuthorityProposers (r:1 w:1) + // Storage: DKGProposals ProposerCount (r:1 w:1) // Storage: DKG PendingSignatureThreshold (r:1 w:0) // Storage: DKG PendingKeygenThreshold (r:1 w:0) + // Storage: DKG NextAuthoritySetId (r:1 w:1) + // Storage: DKG NextBestAuthorities (r:1 w:1) + // Storage: DKG JailedKeygenAuthorities (r:3 w:0) + // Storage: DKG AuthorityReputations (r:3 w:0) // Storage: DKG DKGPublicKeySignature (r:1 w:1) + // Storage: DKG AuthoritySetId (r:1 w:1) // Storage: System Digest (r:1 w:1) + // Storage: DKG NextSignatureThreshold (r:0 w:1) + // Storage: DKG Authorities (r:0 w:1) // Storage: DKG RefreshInProgress (r:0 w:1) // Storage: DKG KeygenThreshold (r:0 w:1) // Storage: DKG HistoricalRounds (r:0 w:1) // Storage: DKG PreviousPublicKey (r:0 w:1) // Storage: DKG SignatureThreshold (r:0 w:1) - // Storage: DKGProposalHandler UnsignedProposalQueue (r:0 w:1) + // Storage: DKG NextKeygenThreshold (r:0 w:1) + // Storage: DKG BestAuthorities (r:0 w:1) + // Storage: DKG CurrentAuthoritiesAccounts (r:0 w:1) + // Storage: DKGProposals ExternalProposerAccounts (r:0 w:3) + // Storage: DKGProposals ExternalAuthorityProposerAccounts (r:0 w:1) + // Storage: DKGProposals Proposers (r:0 w:3) fn submit_public_key_signature() -> Weight { - (221_000_000_u64) - .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(16_u64)) + (383_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(24 as Weight)) + .saturating_add(T::DbWeight::get().writes(31 as Weight)) } - // Storage: DKG NextAuthoritiesAccounts (r:1 w:0) + // Storage: DKG NextAuthorities (r:1 w:0) // Storage: DKG NextSignatureThreshold (r:1 w:0) // Storage: DKG AuthorityReputations (r:1 w:1) - // Storage: DKG NextAuthorities (r:1 w:0) + // Storage: DKG NextBestAuthorities (r:1 w:0) // Storage: DKG JailedKeygenAuthorities (r:3 w:1) - // Storage: DKG PendingKeygenThreshold (r:1 w:1) - // Storage: DKG PendingSignatureThreshold (r:1 w:0) + // Storage: DKG NextKeygenThreshold (r:1 w:0) fn submit_misbehaviour_reports(n: u32, ) -> Weight { - (0_u64) - // Standard Error: 16_027_000 - .saturating_add((2_020_326_000_u64).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(9_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + (0 as Weight) + // Standard Error: 23_711_000 + .saturating_add((2_358_101_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: DKG AccountToAuthority (r:1 w:0) // Storage: DKG JailedKeygenAuthorities (r:1 w:1) // Storage: DKG JailedSigningAuthorities (r:1 w:1) fn unjail() -> Weight { - (16_000_000_u64) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + (22_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: DKG JailedSigningAuthorities (r:0 w:1) fn force_unjail_signing() -> Weight { - (1_000_000_u64) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (2_000_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: DKG JailedKeygenAuthorities (r:0 w:1) fn force_unjail_keygen() -> Weight { - (1_000_000_u64) - .saturating_add(T::DbWeight::get().writes(1_u64)) + (2_000_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } diff --git a/pallets/dkg-proposal-handler/Cargo.toml b/pallets/dkg-proposal-handler/Cargo.toml index e7e5b6753..42b9367b7 100644 --- a/pallets/dkg-proposal-handler/Cargo.toml +++ b/pallets/dkg-proposal-handler/Cargo.toml @@ -6,37 +6,37 @@ version = "0.1.0" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "2.0.0", features = ["derive"], default-features = false } -scale-info = { version = "1.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3", features = ["derive"], default-features = false } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } dkg-runtime-primitives = { path = "../../dkg-runtime-primitives", default-features = false } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false, optional = true } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } pallet-dkg-metadata = { path = "../dkg-metadata", default-features = false } hex-literal = { version = "0.3", optional = true } [dev-dependencies] pallet-dkg-proposals = { path = "../dkg-proposals"} serde = { version = "1.0.119" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } [features] diff --git a/pallets/dkg-proposal-handler/rpc/Cargo.toml b/pallets/dkg-proposal-handler/rpc/Cargo.toml index 49b8bedd8..749a5fd32 100644 --- a/pallets/dkg-proposal-handler/rpc/Cargo.toml +++ b/pallets/dkg-proposal-handler/rpc/Cargo.toml @@ -5,16 +5,14 @@ edition = "2021" authors = ["Webb Tools"] [dependencies] -jsonrpc-core = "18.0.0" -jsonrpc-core-client = "18.0.0" -jsonrpc-derive = "18.0.0" -sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +jsonrpsee = { version = "0.13.0", features = ["server"] } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } pallet-dkg-proposal-handler-runtime-api = { path = "./runtime-api", default-features = false } diff --git a/pallets/dkg-proposal-handler/rpc/runtime-api/Cargo.toml b/pallets/dkg-proposal-handler/rpc/runtime-api/Cargo.toml index 3e07a011e..0a5947eea 100644 --- a/pallets/dkg-proposal-handler/rpc/runtime-api/Cargo.toml +++ b/pallets/dkg-proposal-handler/rpc/runtime-api/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } [features] default = ["std"] diff --git a/pallets/dkg-proposal-handler/rpc/src/error.rs b/pallets/dkg-proposal-handler/rpc/src/error.rs new file mode 100644 index 000000000..4e27499e6 --- /dev/null +++ b/pallets/dkg-proposal-handler/rpc/src/error.rs @@ -0,0 +1,61 @@ +// This file is part of Webb. + +// Copyright (C) 2021 Webb Technologies Inc. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use jsonrpsee::{ + core::Error as JsonRpseeError, + types::error::{CallError, ErrorObject}, +}; + +#[derive(Debug, thiserror::Error)] +/// Top-level error type for the RPC handler +pub enum Error { + /// The DKG Proposals RPC endpoint is not ready. + #[error("DKG Proposals RPC endpoint not ready")] + EndpointNotReady, + /// The unsigned proposals request failed + #[error("Unsigned proposals request failed")] + UnsignedProposalRequestFailed, +} + +/// The error codes returned by jsonrpc. +pub enum ErrorCode { + /// Returned when Linkable Tree RPC endpoint is not ready. + NotReady = 1, + /// Unsigned proposals request failed + UnsignedProposalRequestFailed, +} + +impl From for ErrorCode { + fn from(error: Error) -> Self { + match error { + Error::EndpointNotReady => ErrorCode::NotReady, + Error::UnsignedProposalRequestFailed => ErrorCode::UnsignedProposalRequestFailed, + } + } +} + +impl From for JsonRpseeError { + fn from(error: Error) -> Self { + let message = error.to_string(); + let code = ErrorCode::from(error); + JsonRpseeError::Call(CallError::Custom(ErrorObject::owned( + code as i32, + message, + None::<()>, + ))) + } +} diff --git a/pallets/dkg-proposal-handler/rpc/src/lib.rs b/pallets/dkg-proposal-handler/rpc/src/lib.rs index 95678dc6c..f31c39c80 100644 --- a/pallets/dkg-proposal-handler/rpc/src/lib.rs +++ b/pallets/dkg-proposal-handler/rpc/src/lib.rs @@ -16,14 +16,13 @@ use std::sync::Arc; -use jsonrpc_core::{Error, ErrorCode, Result}; -use jsonrpc_derive::rpc; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; /// Merkle RPC methods. -#[rpc] +#[rpc(client, server)] pub trait DKGProposalHandlerApi { /// Get the passed DKG proposals that have not been signed by the DKG. /// @@ -33,20 +32,21 @@ pub trait DKGProposalHandlerApi { /// specified. /// /// Returns the (full) a Vec of the proposals. - #[rpc(name = "dkg_proposals_getUnsignedProposals")] - fn get_unsigned_proposals(&self, at: Option) -> Result>; + #[method(name = "dkgProposals_getUnsignedProposals")] + fn get_unsigned_proposals(&self, at: Option) -> RpcResult>; } /// A struct that implements the `DKGProposalHandlerApi`. pub struct DKGProposalHandlerClient { client: Arc, + deny_unsafe: DenyUnsafe, _marker: std::marker::PhantomData<(M, P)>, } impl DKGProposalHandlerClient { /// Create new `Merkle` instance with the given reference to the client. - pub fn new(client: Arc) -> Self { - Self { client, _marker: Default::default() } + pub fn new(client: Arc, deny_unsafe: DenyUnsafe) -> Self { + Self { client, deny_unsafe, _marker: Default::default() } } } @@ -58,10 +58,11 @@ where C: HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, C::Api: DKGProposalHandlerApi, { - fn get_unsigned_proposals(&self, at: Option<::Hash>) -> Result> { + fn get_unsigned_proposals(&self, at: Option<::Hash>) -> RpcResult> { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash)); - let proposals = api.get_unsigned_proposals(at)?; - Ok(proposals) + api.get_unsigned_proposals(at) + .map_err(|e| error::Error::UnsignedProposalRequestFailed) + .map_err(Into::into) } } diff --git a/pallets/dkg-proposal-handler/src/lib.rs b/pallets/dkg-proposal-handler/src/lib.rs index 10afecb5f..1e828a802 100644 --- a/pallets/dkg-proposal-handler/src/lib.rs +++ b/pallets/dkg-proposal-handler/src/lib.rs @@ -109,16 +109,18 @@ use dkg_runtime_primitives::{ handlers::decode_proposals::decode_proposal_identifier, ProposalNonce, }; pub use pallet::*; +use sp_std::convert::TryInto; #[cfg(test)] mod mock; #[cfg(test)] mod tests; + use dkg_runtime_primitives::{ offchain::storage_keys::{OFFCHAIN_SIGNED_PROPOSALS, SUBMIT_SIGNED_PROPOSAL_ON_CHAIN_LOCK}, DKGPayloadKey, OffchainSignedProposals, Proposal, ProposalAction, ProposalHandlerTrait, - ProposalKind, TypedChainId, + ProposalKind, StoredUnsignedProposal, TypedChainId, }; use frame_support::pallet_prelude::*; use frame_system::{ @@ -135,7 +137,7 @@ use sp_runtime::{ use sp_std::vec::Vec; pub mod weights; -use weights::WeightInfo; +pub use weights::WeightInfo; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; @@ -148,6 +150,11 @@ pub mod pallet { }; use frame_support::dispatch::DispatchResultWithPostInfo; use frame_system::{offchain::CreateSignedTransaction, pallet_prelude::*}; + use sp_runtime::traits::{CheckedSub, One, Zero}; + + /// Unsigned proposal for this pallet + pub type StoredUnsignedProposalOf = + StoredUnsignedProposal<::BlockNumber>; /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] @@ -161,6 +168,9 @@ pub mod pallet { /// Max number of signed proposal submissions per batch; #[pallet::constant] type MaxSubmissionsPerBatch: Get; + /// Max blocks to store an unsigned proposal + #[pallet::constant] + type UnsignedProposalExpiry: Get; /// Pallet weight information type WeightInfo: WeightInfo; } @@ -179,7 +189,7 @@ pub mod pallet { TypedChainId, Blake2_128Concat, DKGPayloadKey, - Proposal, + StoredUnsignedProposalOf, >; /// All signed proposals. @@ -205,6 +215,10 @@ pub mod pallet { data: Vec, /// The Invalid Signature. invalid_signature: Vec, + /// Expected DKG Public Key (the one currently stored on chain). + expected_public_key: Option>, + /// The actual one we recovered from the data and signature. + actual_public_key: Option>, }, /// Event When a Proposal Gets Signed by DKG. ProposalSigned { @@ -250,6 +264,39 @@ pub mod pallet { res ); } + + /// Hook that execute when there is leftover space in a block + /// This function will look for any unsigned proposals past `UnsignedProposalExpiry` + /// and remove storage. + fn on_idle(now: T::BlockNumber, mut remaining_weight: Weight) -> Weight { + // fetch all unsigned proposals + let unsigned_proposals: Vec<_> = UnsignedProposalQueue::::iter().collect(); + let unsigned_proposals_len = unsigned_proposals.len() as u64; + remaining_weight = + remaining_weight.saturating_sub(T::DbWeight::get().reads(unsigned_proposals_len)); + + // filter out proposals to delete + let unsigned_proposal_past_expiry = unsigned_proposals.into_iter().filter( + |(_, _, StoredUnsignedProposal { timestamp, .. })| { + let time_passed = now.checked_sub(timestamp).unwrap_or_default(); + time_passed > T::UnsignedProposalExpiry::get() + }, + ); + + // remove unsigned proposal until we run out of weight + for expired_proposal in unsigned_proposal_past_expiry { + remaining_weight = + remaining_weight.saturating_sub(T::DbWeight::get().writes(One::one())); + + if remaining_weight.is_zero() { + break + } + + UnsignedProposalQueue::::remove(expired_proposal.0, expired_proposal.1); + } + + remaining_weight + } } #[pallet::call] @@ -280,18 +327,19 @@ pub mod pallet { let result = ensure_signed_by_dkg::>( signature, &data[..], - ) - .map_err(|_| Error::::ProposalSignatureInvalid); + ); match result { Ok(_) => { // Do nothing, it is all good. }, - Err(_e) => { + Err(e) => { // this is a bad signature. // we emit it as an event. Self::deposit_event(Event::InvalidProposalSignature { kind: kind.clone(), data: data.clone(), + expected_public_key: e.expected_public_key(), + actual_public_key: e.actual_public_key(), invalid_signature: signature.clone(), }); frame_support::log::error!( @@ -344,7 +392,11 @@ pub mod pallet { if prop.is_unsigned() { match decode_proposal_identifier(&prop) { Ok(v) => { - UnsignedProposalQueue::::insert(v.typed_chain_id, v.key, prop); + UnsignedProposalQueue::::insert( + v.typed_chain_id, + v.key, + Self::stored_unsigned_proposal_from_unsigned_proposal(prop), + ); Ok(().into()) }, Err(_) => Err(Error::::ProposalFormatInvalid.into()), @@ -360,7 +412,11 @@ impl ProposalHandlerTrait for Pallet { fn handle_unsigned_proposal(proposal: Vec, _action: ProposalAction) -> DispatchResult { let proposal = Proposal::Unsigned { data: proposal, kind: ProposalKind::AnchorUpdate }; if let Ok(v) = decode_proposal_identifier(&proposal) { - UnsignedProposalQueue::::insert(v.typed_chain_id, v.key, proposal); + UnsignedProposalQueue::::insert( + v.typed_chain_id, + v.key, + Self::stored_unsigned_proposal_from_unsigned_proposal(proposal), + ); return Ok(()) } @@ -371,14 +427,14 @@ impl ProposalHandlerTrait for Pallet { proposal: Vec, _action: ProposalAction, ) -> DispatchResult { - #[cfg(feature = "std")] - println!("handle_unsigned_proposer_set_update_proposal"); - #[cfg(feature = "std")] - println!("proposal: {:?}", proposal); let unsigned_proposal = Proposal::Unsigned { data: proposal, kind: ProposalKind::ProposerSetUpdate }; if let Ok(v) = decode_proposal_identifier(&unsigned_proposal) { - UnsignedProposalQueue::::insert(v.typed_chain_id, v.key, unsigned_proposal); + UnsignedProposalQueue::::insert( + v.typed_chain_id, + v.key, + Self::stored_unsigned_proposal_from_unsigned_proposal(unsigned_proposal), + ); return Ok(()) } @@ -396,7 +452,7 @@ impl ProposalHandlerTrait for Pallet { UnsignedProposalQueue::::insert( TypedChainId::None, DKGPayloadKey::RefreshVote(proposal.nonce), - unsigned_proposal, + Self::stored_unsigned_proposal_from_unsigned_proposal(unsigned_proposal), ); Ok(()) @@ -482,16 +538,18 @@ impl Pallet { pub fn get_unsigned_proposals() -> Vec { UnsignedProposalQueue::::iter() - .map(|(typed_chain_id, key, proposal)| dkg_runtime_primitives::UnsignedProposal { - typed_chain_id, - key, - proposal, + .map(|(typed_chain_id, key, stored_unsigned_proposal)| { + dkg_runtime_primitives::UnsignedProposal { + typed_chain_id, + key, + proposal: stored_unsigned_proposal.proposal, + } }) .collect() } /// Checks whether a signed proposal exists in the `SignedProposals` storage - pub fn is_existing_proposal(prop: &Proposal) -> bool { + pub fn is_not_existing_proposal(prop: &Proposal) -> bool { if prop.is_signed() { match decode_proposal_identifier(prop) { Ok(v) => !SignedProposals::::contains_key(v.typed_chain_id, v.key), @@ -502,6 +560,14 @@ impl Pallet { } } + /// Returns `StoredUnsignedProposal` from proposal by inserting current BlockNumber + pub fn stored_unsigned_proposal_from_unsigned_proposal( + proposal: Proposal, + ) -> StoredUnsignedProposalOf { + let timestamp = >::block_number(); + StoredUnsignedProposalOf:: { proposal, timestamp } + } + // *** Offchain worker methods *** /// Offchain worker function that submits signed proposals from the offchain storage on-chain @@ -523,13 +589,22 @@ impl Pallet { } match Self::get_next_offchain_signed_proposal(block_number) { Ok(next_proposals) => { + frame_support::log::debug!( + target: "dkg_proposal_handler", + "submit_signed_proposal_onchain: found {} proposals to submit before filtering\n {:?}", + next_proposals.len(), next_proposals + ); // We filter out all proposals that are already on chain let filtered_proposals = next_proposals .iter() .cloned() - .filter(Self::is_existing_proposal) + .filter(Self::is_not_existing_proposal) .collect::>(); - + frame_support::log::debug!( + target: "dkg_proposal_handler", + "submit_signed_proposal_onchain: found {} proposals to submit after filtering\n {:?}", + filtered_proposals.len(), filtered_proposals + ); // We split the vector into chunks of `T::MaxSubmissionsPerBatch` length and // submit those chunks for chunk in @@ -584,13 +659,13 @@ impl Pallet { match res { Ok(Some(mut prop_wrapper)) => { // log the proposals - frame_support::log::trace!( + frame_support::log::debug!( target: "dkg_proposal_handler", "Offchain signed proposals: {:?}", prop_wrapper.proposals ); // log how many proposal batches are left - frame_support::log::trace!( + frame_support::log::debug!( target: "dkg_proposal_handler", "Offchain signed proposals left: {}", prop_wrapper.proposals.len() @@ -608,8 +683,8 @@ impl Pallet { } }, ) - .cloned() .flatten() + .cloned() .collect::>(); // then we need to keep only the batches that are not yet submitted prop_wrapper.proposals.retain(|(_, submit_at)| *submit_at > block_number); diff --git a/pallets/dkg-proposal-handler/src/mock.rs b/pallets/dkg-proposal-handler/src/mock.rs index eaf0502f6..e26bff3a3 100644 --- a/pallets/dkg-proposal-handler/src/mock.rs +++ b/pallets/dkg-proposal-handler/src/mock.rs @@ -166,6 +166,7 @@ impl pallet_dkg_proposal_handler::Config for Test { type Event = Event; type OffChainAuthId = dkg_runtime_primitives::offchain::crypto::OffchainAuthId; type MaxSubmissionsPerBatch = frame_support::traits::ConstU16<100>; + type UnsignedProposalExpiry = frame_support::traits::ConstU64<10>; type WeightInfo = (); } @@ -330,10 +331,9 @@ pub fn mock_sign_msg( .unwrap(); let pub_key = - SyncCryptoStore::ecdsa_public_keys(&keystore, dkg_runtime_primitives::crypto::Public::ID) + *SyncCryptoStore::ecdsa_public_keys(&keystore, dkg_runtime_primitives::crypto::Public::ID) .get(0) - .unwrap() - .clone(); + .unwrap(); keystore.ecdsa_sign_prehashed(dkg_runtime_primitives::crypto::Public::ID, &pub_key, msg) } diff --git a/pallets/dkg-proposal-handler/src/tests.rs b/pallets/dkg-proposal-handler/src/tests.rs index eaad311f6..dd49c1031 100644 --- a/pallets/dkg-proposal-handler/src/tests.rs +++ b/pallets/dkg-proposal-handler/src/tests.rs @@ -12,9 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. // -use crate::mock::*; +use crate::{mock::*, UnsignedProposalQueue}; use codec::Encode; -use frame_support::{assert_err, assert_ok}; +use frame_support::{ + assert_err, assert_ok, + traits::{Hooks, OnFinalize}, + weights::{constants::RocksDbWeight, DispatchClass}, +}; use sp_runtime::offchain::storage::{StorageRetrievalError, StorageValueRef}; use sp_std::vec::Vec; @@ -59,6 +63,27 @@ fn check_offchain_proposals_num_eq(num: usize) { assert_eq!(stored_props.unwrap().proposals.len(), num); } +// helper function to skip blocks +pub fn run_n_blocks(n: u64) -> u64 { + // lets leave enough weight to read a queue with length one and remove one item + let idle_weight: u64 = RocksDbWeight::get().reads_writes(1, 1); + let start_block = System::block_number(); + + for block_number in start_block..=n { + System::set_block_number(block_number); + + // ensure the on_idle is executed + >::register_extra_weight_unchecked( + DKGProposalHandler::on_idle(block_number, idle_weight), + DispatchClass::Mandatory, + ); + + as OnFinalize>::on_finalize(block_number); + } + + System::block_number() +} + // *** Tests *** #[test] @@ -737,3 +762,39 @@ fn force_submit_should_work_with_valid_proposals() { ); }); } + +#[test] +fn expired_unsigned_proposals_are_removed() { + execute_test_with(|| { + // Submit one unsigned proposal + assert_ok!(DKGProposalHandler::force_submit_unsigned_proposal( + Origin::root(), + make_proposal::<20>( + Proposal::Unsigned { kind: ProposalKind::TokenAdd, data: vec![] }, + TypedChainId::Evm(0) + ) + )); + + // lets time travel to 5 blocks later and submit another proposal + run_n_blocks(5); + assert_ok!(DKGProposalHandler::force_submit_unsigned_proposal( + Origin::root(), + make_proposal::<1>( + Proposal::Unsigned { kind: ProposalKind::WrappingFeeUpdate, data: vec![] }, + TypedChainId::Substrate(0) + ) + )); + + // sanity check + run_n_blocks(10); + assert_eq!(UnsignedProposalQueue::::iter().count(), 2); + + // lets time travel to a block after expiry period of first unsigned + run_n_blocks(11); + assert_eq!(UnsignedProposalQueue::::iter().count(), 1); + + // lets time travel to a block after expiry period of second unsigned + run_n_blocks(16); + assert_eq!(UnsignedProposalQueue::::iter().count(), 0); + }) +} diff --git a/pallets/dkg-proposals/Cargo.toml b/pallets/dkg-proposals/Cargo.toml index 96122b704..44de480e6 100644 --- a/pallets/dkg-proposals/Cargo.toml +++ b/pallets/dkg-proposals/Cargo.toml @@ -13,34 +13,34 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] # primitives -codec = { package = "parity-scale-codec", version = "2.3.0", default-features = false, features = ["derive", "max-encoded-len"] } -scale-info = { version = "1.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } k256 = { version = "0.10.2", default-features = false, features = ["arithmetic", "ecdsa"] } log = { version = "0.4.13", default-features = false } - dkg-runtime-primitives = { path = '../../dkg-runtime-primitives', default-features = false } -sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17" } -sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17" } -sp-io = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17" } -sp-core = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17" } +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } +sp-io = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } +sp-core = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } + # frame dependencies -frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17" } -frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17" } -pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-system-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17", optional = true } -frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.17", optional = true } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } +frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } +pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-system-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24", optional = true } +frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.24", optional = true } [dev-dependencies] pallet-dkg-proposal-handler = { path = "../dkg-proposal-handler" } pallet-dkg-metadata = { path = "../dkg-metadata" } -pallet-collator-selection = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17" } -pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +pallet-collator-selection = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.24" } +pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } hex = { version = "0.4", default-features = false } [features] diff --git a/pallets/dkg-proposals/rpc/Cargo.toml b/pallets/dkg-proposals/rpc/Cargo.toml index 636a55eaa..80d6d7ba1 100644 --- a/pallets/dkg-proposals/rpc/Cargo.toml +++ b/pallets/dkg-proposals/rpc/Cargo.toml @@ -4,16 +4,14 @@ version = "0.1.0" edition = "2021" [dependencies] -jsonrpc-core = "18.0.0" -jsonrpc-core-client = "18.0.0" -jsonrpc-derive = "18.0.0" -sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +jsonrpsee = { version = "0.13.0", features = ["server"] } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } pallet-dkg-proposals-runtime-api = { path = "./runtime-api", default-features = false } diff --git a/pallets/dkg-proposals/rpc/runtime-api/Cargo.toml b/pallets/dkg-proposals/rpc/runtime-api/Cargo.toml index f88684e2e..1a69d24d5 100644 --- a/pallets/dkg-proposals/rpc/runtime-api/Cargo.toml +++ b/pallets/dkg-proposals/rpc/runtime-api/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } [features] default = ["std"] diff --git a/pallets/dkg-proposals/src/lib.rs b/pallets/dkg-proposals/src/lib.rs index ec1554b7a..7b20d268f 100644 --- a/pallets/dkg-proposals/src/lib.rs +++ b/pallets/dkg-proposals/src/lib.rs @@ -314,20 +314,6 @@ pub mod pallet { ProposerCountIsZero, } - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(n: T::BlockNumber) -> Weight { - if n % T::Period::get() == T::BlockNumber::from(0u32) { - // Create the new proposer set merkle tree and update proposal - Self::create_proposer_set_update(); - - return 1 - } - - 0 - } - } - #[pallet::genesis_config] pub struct GenesisConfig { /// Typed ChainId (chain type, chain id) @@ -757,6 +743,7 @@ impl Pallet { /// The signed proposer set update is intended to be used to update the proposer set on /// other blockchains that need a fallback mechanism when the DKG is not available or needs /// to be fixed or changed. + #[allow(dead_code)] fn create_proposer_set_update() { // Merkleize the new proposer set let mut proposer_set_merkle_root = Self::get_proposer_set_tree_root(); @@ -878,7 +865,6 @@ impl .iter() .map(|id| T::DKGAuthorityToMerkleLeaf::convert(id.clone())) .collect::>(); - // TODO: Get difference in list and optimise storage reads/writes // Remove old authorities and their external accounts from the list let old_authority_proposers = Self::authority_proposers(); for old_authority_account in old_authority_proposers { @@ -899,6 +885,8 @@ impl // Update the external accounts of the new authorities ExternalAuthorityProposerAccounts::::put(new_external_accounts); Self::deposit_event(Event::::AuthorityProposersReset { proposers: authorities }); + // Create the new proposer set merkle tree and update proposal + Self::create_proposer_set_update(); } } diff --git a/pallets/dkg-proposals/src/mock.rs b/pallets/dkg-proposals/src/mock.rs index 06d42b389..64f5bad8a 100644 --- a/pallets/dkg-proposals/src/mock.rs +++ b/pallets/dkg-proposals/src/mock.rs @@ -240,6 +240,7 @@ impl pallet_dkg_proposal_handler::Config for Test { type Event = Event; type OffChainAuthId = dkg_runtime_primitives::offchain::crypto::OffchainAuthId; type MaxSubmissionsPerBatch = frame_support::traits::ConstU16<100>; + type UnsignedProposalExpiry = frame_support::traits::ConstU64<10>; type WeightInfo = (); } @@ -318,7 +319,7 @@ pub struct ExtBuilder; impl ExtBuilder { pub fn build() -> sp_io::TestExternalities { - let dkg_id = PalletId(*b"dw/dkgac").into_account(); + let dkg_id = PalletId(*b"dw/dkgac").into_account_truncating(); let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(dkg_id, ENDOWED_BALANCE)] } .assimilate_storage(&mut t) diff --git a/pallets/dkg-proposals/src/tests.rs b/pallets/dkg-proposals/src/tests.rs index 259fda1eb..71e1fbb02 100644 --- a/pallets/dkg-proposals/src/tests.rs +++ b/pallets/dkg-proposals/src/tests.rs @@ -704,7 +704,7 @@ fn session_change_should_create_proposer_set_update_proposal() { assert!( DKGProposalHandler::unsigned_proposals( TypedChainId::None, - DKGPayloadKey::ProposerSetUpdateProposal(4.into()) + DKGPayloadKey::ProposerSetUpdateProposal(5.into()) ) .is_some(), "{}", @@ -716,7 +716,7 @@ fn session_change_should_create_proposer_set_update_proposal() { assert!( DKGProposalHandler::unsigned_proposals( TypedChainId::None, - DKGPayloadKey::ProposerSetUpdateProposal(5.into()) + DKGPayloadKey::ProposerSetUpdateProposal(6.into()) ) .is_none(), "{}", @@ -728,7 +728,7 @@ fn session_change_should_create_proposer_set_update_proposal() { assert!( DKGProposalHandler::unsigned_proposals( TypedChainId::None, - DKGPayloadKey::ProposerSetUpdateProposal(5.into()) + DKGPayloadKey::ProposerSetUpdateProposal(6.into()) ) .is_some(), "{}", @@ -739,7 +739,7 @@ fn session_change_should_create_proposer_set_update_proposal() { assert!( DKGProposalHandler::unsigned_proposals( TypedChainId::None, - DKGPayloadKey::ProposerSetUpdateProposal(8.into()) + DKGPayloadKey::ProposerSetUpdateProposal(9.into()) ) .is_some(), "{}", diff --git a/prometheus.yml b/prometheus.yml new file mode 100644 index 000000000..24c1000c1 --- /dev/null +++ b/prometheus.yml @@ -0,0 +1,18 @@ +# From https://docs.substrate.io/tutorials/v3/node-metrics/#install-prometheus-and-grafana + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'substrate_node' + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + + # Override the global default and scrape targets from this job every 5 seconds. + # ** NOTE: you want to have this *LESS THAN* the block time in order to ensure + # ** that you have a data point for every block! + scrape_interval: 5s + + static_configs: + - targets: ['localhost:9615'] diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml deleted file mode 100644 index 94af71154..000000000 --- a/runtime/Cargo.toml +++ /dev/null @@ -1,150 +0,0 @@ -[package] -name = 'dkg-runtime' -authors = ['Webb tools'] -description = 'A new Cumulus FRAME-based Substrate Runtime, ready for hacking.' -license = 'Unlicense' -version = '3.0.0' -homepage = 'https://webb.tools' -repository = "https://github.com/webb-tools/dkg-substrate" -edition = '2018' -[package.metadata.docs.rs] -targets = ['x86_64-unknown-linux-gnu'] - -[build-dependencies] -substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } - -[dependencies] -codec = { package = 'parity-scale-codec', version = '2.0.0', default-features = false, features = ['derive']} -log = { version = "0.4.14", default-features = false } -serde = { version = '1.0.119', optional = true, features = ['derive'] } -scale-info = { version = "1.0", default-features = false, features = ["derive"] } -hex-literal = { version = "0.3", optional = true } -smallvec = "1.6.1" - -# Local Dependencies -pallet-dkg-metadata = { path = '../pallets/dkg-metadata', default-features = false } -dkg-runtime-primitives = { path = '../dkg-runtime-primitives', default-features = false } -pallet-dkg-proposals = { path = '../pallets/dkg-proposals', default-features = false } -pallet-dkg-proposal-handler = { path = '../pallets/dkg-proposal-handler', default-features = false } - -# Substrate Dependencies -## Substrate Primitive Dependencies -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } - -## Substrate FRAME Dependencies -frame-executive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false, optional = true } -frame-support = { git = 'https://github.com/paritytech/substrate', default-features = false, branch = 'polkadot-v0.9.17' } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false, optional = true } -frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } - -## Substrate Pallet Dependencies -pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } - -# Cumulus Dependencies -cumulus-pallet-aura-ext = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -cumulus-pallet-xcm = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -cumulus-primitives-timestamp = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -cumulus-primitives-utility = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -pallet-collator-selection = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } -parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.17", default-features = false } - -# Polkadot Dependencies -pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "release-v0.9.17" } -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "release-v0.9.17" } -polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.17" } -xcm = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "release-v0.9.17" } -xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "release-v0.9.17" } -xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false , branch = "release-v0.9.17" } - -[features] -default = ['std'] -runtime-benchmarks = [ - 'xcm-builder/runtime-benchmarks', - 'pallet-xcm/runtime-benchmarks', - 'sp-runtime/runtime-benchmarks', - 'frame-benchmarking', - 'frame-support/runtime-benchmarks', - 'frame-system-benchmarking', - 'frame-system/runtime-benchmarks', - 'pallet-balances/runtime-benchmarks', - 'pallet-timestamp/runtime-benchmarks', - 'pallet-dkg-proposal-handler/runtime-benchmarks', - 'hex-literal', - "pallet-dkg-proposals/runtime-benchmarks", - "pallet-dkg-metadata/runtime-benchmarks" -] -std = [ - "codec/std", - "serde", - "scale-info/std", - "log/std", - "sp-api/std", - "sp-std/std", - "sp-io/std", - "sp-core/std", - "sp-runtime/std", - "sp-version/std", - "sp-offchain/std", - "sp-session/std", - "sp-block-builder/std", - "sp-transaction-pool/std", - "sp-inherents/std", - "frame-support/std", - "frame-executive/std", - "frame-system/std", - 'frame-benchmarking/std', - "pallet-balances/std", - "pallet-randomness-collective-flip/std", - "pallet-timestamp/std", - "pallet-sudo/std", - "pallet-transaction-payment/std", - "parachain-info/std", - "cumulus-pallet-aura-ext/std", - "cumulus-pallet-parachain-system/std", - "cumulus-pallet-dmp-queue/std", - "cumulus-pallet-xcmp-queue/std", - "cumulus-pallet-xcm/std", - "cumulus-primitives-core/std", - "cumulus-primitives-timestamp/std", - "cumulus-primitives-utility/std", - "pallet-collator-selection/std", - "xcm/std", - "xcm-builder/std", - "xcm-executor/std", - "pallet-xcm/std", - "polkadot-parachain/std", - "polkadot-runtime-common/std", - "pallet-aura/std", - "sp-consensus-aura/std", - 'pallet-authorship/std', - 'pallet-session/std', - 'pallet-dkg-metadata/std', - 'dkg-runtime-primitives/std', - 'pallet-dkg-proposals/std', - 'pallet-dkg-proposal-handler/std', -] diff --git a/runtime/build.rs b/runtime/build.rs deleted file mode 100644 index 9a68bd348..000000000 --- a/runtime/build.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use substrate_wasm_builder::WasmBuilder; - -fn main() { - WasmBuilder::new() - .with_current_project() - .export_heap_base() - .import_memory() - .build() -} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs deleted file mode 100644 index 20a5eebbc..000000000 --- a/runtime/src/lib.rs +++ /dev/null @@ -1,867 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -#![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] - -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); - -pub mod xcm_config; -use codec::Encode; -use dkg_runtime_primitives::{TypedChainId, UnsignedProposal}; -use pallet_dkg_proposals::DKGEcdsaToEthereum; -use smallvec::smallvec; -use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; -use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{ - self, AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, StaticLookup, Verify, - }, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiSignature, SaturatedConversion, -}; -use xcm_config::{XcmConfig, XcmOriginToTransactDispatchOrigin}; - -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; - -use frame_support::weights::{ - WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, -}; - -// A few exports that help ease life for downstream crates. -pub use dkg_runtime_primitives::crypto::AuthorityId as DKGId; -pub use frame_support::{ - construct_runtime, match_type, parameter_types, - traits::{EnsureOneOf, Everything, IsInVec, Randomness}, - weights::{ - constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, - DispatchClass, IdentityFee, Weight, - }, - PalletId, StorageValue, -}; -use frame_system::{ - limits::{BlockLength, BlockWeights}, - EnsureRoot, -}; -pub use pallet_balances::Call as BalancesCall; -pub use pallet_timestamp::Call as TimestampCall; -pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_runtime::generic::Era; -#[cfg(any(feature = "std", test))] -pub use sp_runtime::BuildStorage; -pub use sp_runtime::{MultiAddress, Perbill, Percent, Permill}; - -// XCM Imports -use xcm::latest::prelude::*; -use xcm_executor::XcmExecutor; - -/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. -pub type Signature = MultiSignature; -/// Some way of identifying an account on the chain. We intentionally make it equivalent -/// to the public key of our transaction signing scheme. -pub type AccountId = <::Signer as IdentifyAccount>::AccountId; -/// Balance of an account. -pub type Balance = u128; -/// Index of a transaction in the chain. -pub type Index = u32; -/// A hash of some data used by the chain. -pub type Hash = sp_core::H256; -/// An index to a block. -pub type BlockNumber = u32; -/// Reputation type -pub type Reputation = u128; -/// The address format for describing accounts. -pub type Address = MultiAddress; -/// Block header type as expected by this runtime. -pub type Header = generic::Header; -/// Block type as expected by this runtime. -pub type Block = generic::Block; -/// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; -/// BlockId type as expected by this runtime. -pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, -); -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -/// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; -pub type SignedPayload = generic::SignedPayload; -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystemReversed, ->; - -/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the -/// node's balance type. -/// -/// This should typically create a mapping between the following ranges: -/// - `[0, MAXIMUM_BLOCK_WEIGHT]` -/// - `[Balance::min, Balance::max]` -/// -/// Yet, it can be used for any other sort of change to weight-fee. Some examples being: -/// - Setting it to `0` will essentially disable the weight fee. -/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. -pub struct WeightToFee; -impl WeightToFeePolynomial for WeightToFee { - type Balance = Balance; - fn polynomial() -> WeightToFeeCoefficients { - // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT: - // in our template, we map to 1/10 of that, or 1/10 MILLIUNIT - let p = MILLIUNIT / 10; - let q = 100 * Balance::from(ExtrinsicBaseWeight::get()); - smallvec![WeightToFeeCoefficient { - degree: 1, - negative: false, - coeff_frac: Perbill::from_rational(p % q, q), - coeff_integer: p / q, - }] - } -} - -/// This runtime version. -#[sp_version::runtime_version] -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("dkg-parachain"), - impl_name: create_runtime_str!("dkg-parachain"), - authoring_version: 1, - spec_version: 1, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 0, -}; - -/// This determines the average expected block time that we are targeting. -/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. -/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked -/// up by `pallet_aura` to implement `fn slot_duration()`. -/// -/// Change this to adjust the block time. -pub const MILLISECS_PER_BLOCK: u64 = 12000; - -pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; - -pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES; - -// Time is measured by number of blocks. -pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); -pub const HOURS: BlockNumber = MINUTES * 60; -pub const DAYS: BlockNumber = HOURS * 24; - -// Unit = the base number of indivisible units for balances -pub const UNIT: Balance = 1_000_000_000_000; -pub const MILLIUNIT: Balance = 1_000_000_000; -pub const MICROUNIT: Balance = 1_000_000; - -/// The version information used to identify this runtime when compiled natively. -#[cfg(feature = "std")] -pub fn native_version() -> NativeVersion { - NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } -} - -/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers. -/// This is used to limit the maximal weight of a single extrinsic. -const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); -/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used -/// by Operational extrinsics. -const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); -/// We allow for 0.5 of a second of compute with a 12 second average block time. -const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2; - -parameter_types! { - pub const BlockHashCount: BlockNumber = 250; - pub const Version: RuntimeVersion = VERSION; - pub RuntimeBlockLength: BlockLength = - BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); - pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() - .base_block(BlockExecutionWeight::get()) - .for_class(DispatchClass::all(), |weights| { - weights.base_extrinsic = ExtrinsicBaseWeight::get(); - }) - .for_class(DispatchClass::Normal, |weights| { - weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); - }) - .for_class(DispatchClass::Operational, |weights| { - weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); - // Operational transactions have some extra reserved space, so that they - // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. - weights.reserved = Some( - MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT - ); - }) - .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) - .build_or_panic(); - pub const SS58Prefix: u8 = 42; -} - -impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - pub dkg: DKG, - } -} - -// Configure FRAME pallets to include in runtime. - -impl frame_system::Config for Runtime { - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = AccountIdLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The header type. - type Header = generic::Header; - /// The ubiquitous event type. - type Event = Event; - /// The ubiquitous origin type. - type Origin = Origin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// Runtime version. - type Version = Version; - /// Converts a module to an index of this module in the runtime. - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// The basic call filter to use in dispatchable. - type BaseCallFilter = Everything; - /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = (); - /// Block & extrinsics weights: base values and limits. - type BlockWeights = RuntimeBlockWeights; - /// The maximum length of a block (in bytes). - type BlockLength = RuntimeBlockLength; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = SS58Prefix; - /// The action to take on a Runtime Upgrade - type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; - type MaxConsumers = frame_support::traits::ConstU32<16>; -} - -parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; -} - -impl pallet_timestamp::Config for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - -pub const EXISTENTIAL_DEPOSIT: u128 = MILLIUNIT; -parameter_types! { - pub const ExistentialDeposit: u128 = EXISTENTIAL_DEPOSIT; - pub const TransferFee: u128 = MILLIUNIT; - pub const CreationFee: u128 = MILLIUNIT; - pub const TransactionByteFee: u128 = MICROUNIT; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; - pub const OperationalFeeMultiplier: u8 = 5; -} - -impl pallet_balances::Config for Runtime { - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; - type MaxLocks = MaxLocks; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; -} - -impl pallet_transaction_payment::Config for Runtime { - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = IdentityFee; - type FeeMultiplierUpdate = (); - type OperationalFeeMultiplier = OperationalFeeMultiplier; -} - -impl pallet_randomness_collective_flip::Config for Runtime {} - -impl pallet_sudo::Config for Runtime { - type Call = Call; - type Event = Event; -} - -parameter_types! { - pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; - pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4; -} - -impl cumulus_pallet_parachain_system::Config for Runtime { - type Event = Event; - type OnSystemEvent = (); - type SelfParaId = parachain_info::Pallet; - type DmpMessageHandler = DmpQueue; - type ReservedDmpWeight = ReservedDmpWeight; - type OutboundXcmpMessageSource = XcmpQueue; - type XcmpMessageHandler = XcmpQueue; - type ReservedXcmpWeight = ReservedXcmpWeight; -} - -impl parachain_info::Config for Runtime {} - -impl cumulus_pallet_aura_ext::Config for Runtime {} - -impl cumulus_pallet_xcmp_queue::Config for Runtime { - type Event = Event; - type XcmExecutor = XcmExecutor; - type ChannelInfo = ParachainSystem; - type VersionWrapper = (); - type ExecuteOverweightOrigin = EnsureRoot; - type ControllerOrigin = EnsureRoot; - type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; -} - -impl cumulus_pallet_dmp_queue::Config for Runtime { - type Event = Event; - type XcmExecutor = XcmExecutor; - type ExecuteOverweightOrigin = frame_system::EnsureRoot; -} - -parameter_types! { - pub const MaxAuthorities: u32 = 1_000; -} - -impl pallet_aura::Config for Runtime { - type AuthorityId = AuraId; - type DisabledValidators = (); - type MaxAuthorities = MaxAuthorities; -} - -parameter_types! { - pub const UncleGenerations: u32 = 0; -} - -impl pallet_authorship::Config for Runtime { - type EventHandler = (CollatorSelection,); - type FilterUncle = (); - type FindAuthor = pallet_session::FindAccountFromAuthorIndex; - type UncleGenerations = UncleGenerations; -} - -parameter_types! { - pub const Period: u32 = 4 * MINUTES; - pub const Offset: u32 = 0; -} - -impl pallet_session::Config for Runtime { - type Event = Event; - type Keys = SessionKeys; - type NextSessionRotation = pallet_session::PeriodicSessions; - // Essentially just Aura, but lets be pedantic. - type SessionHandler = ::KeyTypeIdProviders; - type SessionManager = CollatorSelection; - type ShouldEndSession = pallet_session::PeriodicSessions; - type ValidatorId = ::AccountId; - // we don't have stash and controller, thus we don't need the convert as well. - type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type WeightInfo = pallet_session::weights::SubstrateWeight; -} - -parameter_types! { - pub const DecayPercentage: Percent = Percent::from_percent(50); - pub const PotId: PalletId = PalletId(*b"PotStake"); - pub const MaxCandidates: u32 = 1000; - pub const MinCandidates: u32 = 5; - pub const SessionLength: BlockNumber = 6 * HOURS; - pub const MaxInvulnerables: u32 = 100; - pub const ExecutiveBody: BodyId = BodyId::Executive; -} - -// We allow root only to execute privileged collator selection operations. -pub type CollatorSelectionUpdateOrigin = EnsureRoot; - -impl pallet_collator_selection::Config for Runtime { - type Event = Event; - type Currency = Balances; - type UpdateOrigin = CollatorSelectionUpdateOrigin; - type PotId = PotId; - type MaxCandidates = MaxCandidates; - type MinCandidates = MinCandidates; - type MaxInvulnerables = MaxInvulnerables; - // should be a multiple of session or things will get inconsistent - type KickThreshold = Period; - type ValidatorId = ::AccountId; - type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type ValidatorRegistration = Session; - type WeightInfo = (); -} - -impl pallet_dkg_metadata::Config for Runtime { - type DKGId = DKGId; - type Event = Event; - type OnAuthoritySetChangeHandler = DKGProposals; - type OnDKGPublicKeyChangeHandler = (); - type OffChainAuthId = dkg_runtime_primitives::offchain::crypto::OffchainAuthId; - type NextSessionRotation = pallet_session::PeriodicSessions; - type RefreshDelay = RefreshDelay; - type KeygenJailSentence = Period; - type SigningJailSentence = Period; - type DecayPercentage = DecayPercentage; - type Reputation = Reputation; - type AuthorityIdOf = pallet_dkg_metadata::AuthorityIdOf; - type ProposalHandler = DKGProposalHandler; - type WeightInfo = pallet_dkg_metadata::weights::WebbWeight; -} - -parameter_types! { - pub const ChainIdentifier: TypedChainId = TypedChainId::RococoParachain(5); - pub const ProposalLifetime: BlockNumber = HOURS / 5; - pub const DKGAccountId: PalletId = PalletId(*b"dw/dkgac"); - pub const RefreshDelay: Permill = Permill::from_percent(90); - pub const TimeToRestart: BlockNumber = 3; -} - -impl pallet_dkg_proposal_handler::Config for Runtime { - type Event = Event; - type OffChainAuthId = dkg_runtime_primitives::offchain::crypto::OffchainAuthId; - type MaxSubmissionsPerBatch = frame_support::traits::ConstU16<100>; - type WeightInfo = pallet_dkg_proposal_handler::weights::WebbWeight; -} - -impl pallet_dkg_proposals::Config for Runtime { - type AdminOrigin = frame_system::EnsureRoot; - type DKGAuthorityToMerkleLeaf = DKGEcdsaToEthereum; - type DKGId = DKGId; - type ChainIdentifier = ChainIdentifier; - type Event = Event; - type NextSessionRotation = pallet_session::PeriodicSessions; - type Proposal = Vec; - type ProposalLifetime = ProposalLifetime; - type ProposalHandler = DKGProposalHandler; - type Period = Period; - type WeightInfo = pallet_dkg_proposals::WebbWeight; -} - -impl frame_system::offchain::CreateSignedTransaction for Runtime -where - Call: From, -{ - fn create_transaction>( - call: Call, - public: ::Signer, - account: AccountId, - nonce: Index, - ) -> Option<(Call, ::SignaturePayload)> { - let tip = 0; - // take the biggest period possible. - let period = - BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; - let current_block = System::block_number() - .saturated_into::() - // The `System::block_number` is initialized with `n+1`, - // so the actual block number is `n`. - .saturating_sub(1); - let era = Era::mortal(period, current_block); - let extra = ( - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(era), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ); - let raw_payload = SignedPayload::new(call, extra) - .map_err(|e| { - log::warn!("Unable to create signed payload: {:?}", e); - }) - .ok()?; - let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; - let address = AccountIdLookup::::unlookup(account); - let (call, extra, _) = raw_payload.deconstruct(); - Some((call, (address, signature, extra))) - } -} - -impl frame_system::offchain::SigningTypes for Runtime { - type Public = ::Signer; - type Signature = Signature; -} - -impl frame_system::offchain::SendTransactionTypes for Runtime -where - Call: From, -{ - type OverarchingCall = Call; - type Extrinsic = UncheckedExtrinsic; -} - -// Create the runtime by composing the FRAME pallets that were previously configured. -construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = generic::Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - ParachainInfo: parachain_info::{Pallet, Storage, Config}, - - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage}, - - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage}, - - // Collator support. the order of these 4 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Call, Storage}, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - Aura: pallet_aura::{Pallet, Storage, Config}, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config}, - - // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event}, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, - DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event}, - - // DKG / offchain worker - DKG: pallet_dkg_metadata::{Pallet, Storage, Call, Event, Config}, - DKGProposals: pallet_dkg_proposals, - DKGProposalHandler: pallet_dkg_proposal_handler, - } -); - -impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic( - extrinsic: ::Extrinsic, - ) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl dkg_runtime_primitives::DKGApi for Runtime { - fn authority_set() -> dkg_runtime_primitives::AuthoritySet { - let authorities = DKG::authorities(); - let authority_set_id = DKG::authority_set_id(); - - dkg_runtime_primitives::AuthoritySet { - authorities, - id: authority_set_id - } - } - - fn queued_authority_set() -> dkg_runtime_primitives::AuthoritySet { - let queued_authorities = DKG::next_authorities(); - let queued_authority_set_id = DKG::authority_set_id() + 1u64; - - dkg_runtime_primitives::AuthoritySet { - authorities: queued_authorities, - id: queued_authority_set_id - } - } - - fn signature_threshold() -> u16 { - DKG::signature_threshold() - } - - fn keygen_threshold() -> u16 { - DKG::keygen_threshold() - } - - fn next_signature_threshold() -> u16 { - DKG::next_signature_threshold() - } - - fn next_keygen_threshold() -> u16 { - DKG::next_keygen_threshold() - } - - fn should_refresh(block_number: BlockNumber) -> bool { - DKG::should_refresh(block_number) - } - - fn next_dkg_pub_key() -> Option<(dkg_runtime_primitives::AuthoritySetId, Vec)> { - DKG::next_dkg_public_key() - } - - fn next_pub_key_sig() -> Option> { - DKG::next_public_key_signature() - } - - fn dkg_pub_key() -> (dkg_runtime_primitives::AuthoritySetId, Vec) { - DKG::dkg_public_key() - } - - fn get_best_authorities() -> Vec<(u16, DKGId)> { - DKG::best_authorities() - } - - fn get_next_best_authorities() -> Vec<(u16, DKGId)> { - DKG::next_best_authorities() - } - - fn get_unsigned_proposals() -> Vec { - DKGProposalHandler::get_unsigned_proposals() - } - - fn get_max_extrinsic_delay(block_number: BlockNumber) -> BlockNumber { - DKG::max_extrinsic_delay(block_number) - } - - fn get_authority_accounts() -> (Vec, Vec) { - (DKG::current_authorities_accounts(), DKG::next_authorities_accounts()) - } - - fn get_reputations(authorities: Vec) -> Vec<(DKGId, Reputation)> { - authorities.iter().map(|a| (a.clone(), DKG::authority_reputations(a))).collect() - } - - fn get_keygen_jailed(set: Vec) -> Vec { - set.iter().filter(|a| pallet_dkg_metadata::JailedKeygenAuthorities::::contains_key(a)).cloned().collect() - } - - fn get_signing_jailed(set: Vec) -> Vec { - set.iter().filter(|a| pallet_dkg_metadata::JailedSigningAuthorities::::contains_key(a)).cloned().collect() - } - - fn refresh_nonce() -> u32 { - DKG::refresh_nonce() - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - } - - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> sp_consensus_aura::SlotDuration { - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) - } - - fn authorities() -> Vec { - Aura::authorities().into_inner() - } - } - - impl cumulus_primitives_core::CollectCollationInfo for Runtime { - fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { - ParachainSystem::collect_collation_info(header) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - - use frame_system_benchmarking::Pallet as SystemBench; - - let mut list = Vec::::new(); - - list_benchmark!(list, extra, pallet_balances, Balances); - list_benchmark!(list, extra, frame_system, SystemBench::); - list_benchmark!(list, extra, pallet_timestamp, Timestamp); - list_benchmark!(list, extra, pallet_dkg_proposal_handler, DKGProposalHandler); - - - - let storage_info = AllPalletsWithSystem::storage_info(); - - (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; - - use frame_system_benchmarking::Pallet as SystemBench; - impl frame_system_benchmarking::Config for Runtime {} - - let whitelist: Vec = vec![ - // Block Number - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), - // Total Issuance - hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), - // Execution Phase - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), - // Event Count - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), - // System Events - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), - ]; - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - - add_benchmark!(params, batches, frame_system, SystemBench::); - add_benchmark!(params, batches, pallet_balances, Balances); - add_benchmark!(params, batches, pallet_timestamp, Timestamp); - add_benchmark!(params, batches, pallet_dkg_proposal_handler, DKGProposalHandler); - - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } - Ok(batches) - } - } -} - -struct CheckInherents; - -impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { - fn check_inherents( - block: &Block, - relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof, - ) -> sp_inherents::CheckInherentsResult { - let relay_chain_slot = relay_state_proof - .read_slot() - .expect("Could not read the relay chain slot from the proof"); - - let inherent_data = - cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration( - relay_chain_slot, - sp_std::time::Duration::from_secs(6), - ) - .create_inherent_data() - .expect("Could not create the timestamp inherent data"); - - inherent_data.check_extrinsics(block) - } -} - -cumulus_pallet_parachain_system::register_validate_block! { - Runtime = Runtime, - BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, - CheckInherents = CheckInherents, -} diff --git a/runtime/src/xcm_config.rs b/runtime/src/xcm_config.rs deleted file mode 100644 index 9d9fbb9e3..000000000 --- a/runtime/src/xcm_config.rs +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -use super::{ - AccountId, Balances, Call, Event, Origin, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, - WeightToFee, XcmpQueue, -}; -use frame_support::{ - match_type, parameter_types, - traits::{Everything, Nothing}, - weights::Weight, -}; -use pallet_xcm::XcmPassthrough; -use polkadot_parachain::primitives::Sibling; -use polkadot_runtime_common::impls::ToAuthor; -use xcm::latest::prelude::*; -use xcm_builder::{ - AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, - EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, ParentIsPreset, - RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, - UsingComponents, -}; -use xcm_executor::XcmExecutor; - -parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); - pub const RelayNetwork: NetworkId = NetworkId::Any; - pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); - pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); -} - -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used -/// when determining ownership of accounts for asset transacting and when attempting to use XCM -/// `Transact` in order to determine the dispatch Origin. -pub type LocationToAccountId = ( - // The parent (Relay-chain) origin converts to the parent `AccountId`. - ParentIsPreset, - // Sibling parachain origins convert to AccountId via the `ParaId::into`. - SiblingParachainConvertsVia, - // Straight up local `AccountId32` origins just alias directly to `AccountId`. - AccountId32Aliases, -); - -/// Means for transacting assets on this chain. -pub type LocalAssetTransactor = CurrencyAdapter< - // Use this currency: - Balances, - // Use this currency when it is a fungible asset matching the given location or name: - IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: - LocationToAccountId, - // Our chain's account ID type (we can't get away without mentioning it explicitly): - AccountId, - // We don't track any teleports. - (), ->; - -/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, -/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can -/// biases the kind of local `Origin` it will become. -pub type XcmOriginToTransactDispatchOrigin = ( - // Sovereign account converter; this attempts to derive an `AccountId` from the origin location - // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for - // foreign chains who want to have a local sovereign account on this chain which they control. - SovereignSignedViaLocation, - // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when - // recognized. - RelayChainAsNative, - // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when - // recognized. - SiblingParachainAsNative, - // Native signed account converter; this just converts an `AccountId32` origin into a normal - // `Origin::Signed` origin of the same 32-byte value. - SignedAccountId32AsNative, - // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. - XcmPassthrough, -); - -parameter_types! { - // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate. - pub UnitWeightCost: Weight = 1_000_000_000; - pub const MaxInstructions: u32 = 100; -} - -match_type! { - pub type ParentOrParentsExecutivePlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } - }; -} - -pub type Barrier = ( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom, - AllowUnpaidExecutionFrom, - // ^^^ Parent and its exec plurality get free execution -); - -pub struct XcmConfig; -impl xcm_executor::Config for XcmConfig { - type Call = Call; - type XcmSender = XcmRouter; - // How to withdraw and deposit an asset. - type AssetTransactor = LocalAssetTransactor; - type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = NativeAsset; - type IsTeleporter = (); // Teleporting is disabled. - type LocationInverter = LocationInverter; - type Barrier = Barrier; - type Weigher = FixedWeightBounds; - type Trader = - UsingComponents>; - type ResponseHandler = PolkadotXcm; - type AssetTrap = PolkadotXcm; - type AssetClaims = PolkadotXcm; - type SubscriptionService = PolkadotXcm; -} - -/// No local origins on this chain are allowed to dispatch XCM sends/executions. -pub type LocalOriginToLocation = SignedToAccountId32; - -/// The means for routing XCM messages which are not for local execution into the right message -/// queues. -pub type XcmRouter = ( - // Two routers - use UMP to communicate with the relay chain: - cumulus_primitives_utility::ParentAsUmp, - // ..and XCMP to communicate with the sibling chains. - XcmpQueue, -); - -impl pallet_xcm::Config for Runtime { - type Event = Event; - type SendXcmOrigin = EnsureXcmOrigin; - type XcmRouter = XcmRouter; - type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Nothing; - // ^ Disable dispatchable execute on the XCM pallet. - // Needs to be `Everything` for local testing. - type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Everything; - type XcmReserveTransferFilter = Nothing; - type Weigher = FixedWeightBounds; - type LocationInverter = LocationInverter; - type Origin = Origin; - type Call = Call; - - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - // ^ Override for AdvertisedXcmVersion default - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; -} - -impl cumulus_pallet_xcm::Config for Runtime { - type Event = Event; - type XcmExecutor = XcmExecutor; -} diff --git a/scripts/debugger.mjs b/scripts/debugger.mjs new file mode 100755 index 000000000..bd4c92cc2 --- /dev/null +++ b/scripts/debugger.mjs @@ -0,0 +1,223 @@ +#!/usr/bin/env -S node --experimental-modules +// @ts-check +import { spawn, execSync, ChildProcess } from "node:child_process"; +import * as readline from "node:readline"; +import { stdin as input, stdout as output } from "node:process"; +import { inspect } from "node:util"; + +const authorityMap = { + alice: { + ws: 9944, + http: 9933, + p2p: 30333, + color: "green", + consoleBind: "127.0.0.1:9988", + }, + bob: { + ws: 9945, + http: 9934, + p2p: 30334, + color: "blue", + consoleBind: "127.0.0.1:9989", + }, + charlie: { + ws: 9946, + http: 9935, + p2p: 30335, + color: "yellow", + consoleBind: "127.0.0.1:9990", + }, +}; + +function buildCompletions() { + const completions = ["exit", "quit", "q"]; + for (const authority of Object.keys(authorityMap)) { + completions.push(`start node ${authority}`); + completions.push(`stop node ${authority}`); + } + // another helper for start all nodes + completions.push("start all"); + completions.push("stop all"); + completions.push("compile"); + return completions; +} + +/** + * @param {string} line + */ +function completer(line) { + const completions = buildCompletions(); + const hits = completions.filter((c) => c.startsWith(line)); + // Show all completions if none found + return [hits.length ? hits : completions, line]; +} + +const rl = readline.createInterface({ + input, + output, + completer, + history: buildCompletions(), + historySize: 50, + removeHistoryDuplicates: true, + prompt: "DKG > ", + terminal: true, + tabSize: 4, +}); + +/** + * @param {string | Buffer} msg + */ +function print(msg) { + output.clearLine(0); + output.cursorTo(0); + output.write(msg); + rl.prompt(true); +} + +/** + * @param {string} format + * @param {string} text + * @returns {string} + */ +function colorText(format, text) { + const formatCodes = inspect.colors[format]; + return `\u001b[${formatCodes[0]}m${text}\u001b[${formatCodes[1]}m`; +} + +/** + * @param {'alice' | 'bob' | 'charlie'} authority + * @returns {ChildProcess} + */ +function startNode(authority) { + const opts = authorityMap[authority]; + if (opts === undefined) { + throw new Error(`Unknown authority: ${authority}`); + } + const startArgs = [ + "-ldkg=debug", + "-ldkg_metadata=debug", + "-lruntime::offchain=debug", + "-ldkg_proposal_handler=debug", + `--base-path=./tmp/${authority}`, + "--rpc-cors", + "all", + "--rpc-methods=unsafe", + "--ws-external", + `--ws-port=${opts.ws}`, + `--rpc-port=${opts.http}`, + `--port=${opts.p2p}`, + `--${authority}`, + ]; + + // get git root + const gitRoot = execSync("git rev-parse --show-toplevel").toString().trim(); + const nodePath = `${gitRoot}/target/release/dkg-standalone-node`; + const proc = spawn(nodePath, startArgs, { env: { RUST_LOG_STYLE: "always", TOKIO_CONSOLE_BIND: opts.consoleBind } }); + const printData = function(/** @type {Buffer} */ data) { + for (const line of data.toString().trim().split("\n")) { + // skip empty lines + if (line.length === 0) { + return; + } + const coloredLine = line + .replace("ERROR", colorText("red", "ERROR")) + .replace("WARN", colorText("yellow", "WARN")) + .replace("INFO", colorText("green", "INFO")) + .replace("DEBUG", colorText("blue", "DEBUG")) + .replace("TRACE", colorText("magenta", "TRACE")); + // remove unnecessary prefixes + const finalLine = coloredLine.replace("tokio-runtime-worker", ""); + print(`${colorText(opts.color, authority.toUpperCase())}: ${finalLine}\n`); + } + }; + proc.stdout.on("data", (data) => { + printData(data); + }); + proc.stderr.on("data", (data) => { + printData(data); + }); + + return proc; +} + +const handles = []; +// we need to close all processes when we exit +process.on("exit", () => { + handles.forEach((handle) => { + handle.proc.kill(9); + }); +}); +rl.prompt(true); +rl.on("line", (line) => { + rl.prompt(true); + const cmd = line.trim(); + if (cmd.match(/^q|exit|quit$/i)) { + rl.close(); + process.exit(0); + } + if (cmd.match(/^help$/i)) { + const completions = buildCompletions(); + print(`Available commands: ${completions.join(", ")}\n`); + return; + } + // a regex command to match "start node " and extract the authority + const startNodeRegex = /^start node (alice|bob|charlie)$/i; + if (cmd.match(startNodeRegex)) { + const authority = cmd.match(startNodeRegex)[1].toLowerCase(); + // @ts-ignore + handles.push({ proc: startNode(authority), authority }); + return; + } + // another regex command to match "stop node " and extract the authority + const stopNodeRegex = /^stop node (alice|bob|charlie)$/i; + if (cmd.match(stopNodeRegex)) { + const authority = cmd.match(stopNodeRegex)[1].toLowerCase(); + // @ts-ignore + handles.forEach((handle) => { + if (handle.authority === authority) { + handle.proc.kill(9); + print(`DKG: Stopped ${authority}`); + } + }); + return; + } + // another regex command to match "start all" + const startAllRegex = /^start all$/i; + if (cmd.match(startAllRegex)) { + Object.keys(authorityMap).forEach((authority) => { + // @ts-ignore + handles.push({ proc: startNode(authority), authority }); + }); + return; + } + + const stopAllRegex = /^stop all$/i; + if (cmd.match(stopAllRegex)) { + handles.forEach((handle) => { + handle.proc.kill(9); + }); + return; + } + + const compileRegex = /^compile$/i; + if (cmd.match(compileRegex)) { + // invoke cargo b -q --release + const cargo = spawn("cargo", ["b", "--release"]); + cargo.stdout.on("data", (data) => { + print(data.toString()); + }); + cargo.stderr.on("data", (data) => { + print(data.toString()); + }); + cargo.on("exit", (code) => { + if (code === 0) { + print("DKG: Compiled"); + } else { + print("DKG: Compile failed"); + } + }); + return; + } + print(`DKG: Unknown command: ${cmd}`); + print(`Try "help" for the list of commands.`); +}); diff --git a/scripts/run-standalone.sh b/scripts/run-standalone.sh index 84e3012ad..263878506 100755 --- a/scripts/run-standalone.sh +++ b/scripts/run-standalone.sh @@ -4,15 +4,23 @@ set -e pushd . # The following line ensure we run from the project root -PROJECT_ROOT=`git rev-parse --show-toplevel` -cd $PROJECT_ROOT +PROJECT_ROOT=$(git rev-parse --show-toplevel) +cd "$PROJECT_ROOT" echo "*** Start Webb DKG Node ***" -./target/release/dkg-standalone-node --tmp -lerror --alice --rpc-cors all --ws-external --ws-port 9944 & -./target/release/dkg-standalone-node --tmp -lerror --bob --ws-port 9945 & -./target/release/dkg-standalone-node --tmp \ +./target/release/dkg-standalone-node --base-path=./tmp/alice -lerror --alice \ + --rpc-cors all --ws-external \ + --port 30304 \ + --ws-port 9944 & +./target/release/dkg-standalone-node --base-path=./tmp/bob -lerror --bob \ + --rpc-cors all --ws-external \ + --port 30305 \ + --ws-port 9945 & +./target/release/dkg-standalone-node --base-path=./tmp/charlie -linfo \ --ws-port 9946 \ - -lerror \ + --rpc-cors all \ + --ws-external \ + --port 30306 \ -ldkg=debug \ -ldkg_metadata=debug \ -lruntime::offchain=debug \ diff --git a/standalone/node/Cargo.toml b/standalone/node/Cargo.toml index 00b4f16b3..ab91be2d9 100644 --- a/standalone/node/Cargo.toml +++ b/standalone/node/Cargo.toml @@ -20,51 +20,54 @@ name = "dkg-standalone-node" futures = "0.3.15" clap = { version = "3.0", features = ["derive"] } rand = "0.7.2" -codec = { package = "parity-scale-codec", version = "2.0.0" } +codec = { package = "parity-scale-codec", version = "3" } hex-literal = { package = "hex-literal", version = "0.3.3" } -sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", features = [ +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", features = [ "wasmtime", ] } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", features = [ +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", features = [ "wasmtime", ] } -sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", features = [ +sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", features = [ "wasmtime", ] } -sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-consensus-manual-seal = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-consensus-manual-seal = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } # These dependencies are used for the node template's RPCs -jsonrpc-core = "18.0.0" -sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +jsonrpsee = { version = "0.13.0", features = ["server"] } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } # These dependencies are used for runtime benchmarking -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } # Local dependencies dkg-gadget = { path = "../../dkg-gadget", default-features = false } @@ -72,8 +75,9 @@ dkg-runtime-primitives = { path = "../../dkg-runtime-primitives", default-featur dkg-primitives = { path = "../../dkg-primitives", default-features = false } dkg-standalone-runtime = { version = "3.0.0", path = "../runtime" } + [build-dependencies] -substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } [features] default = [] diff --git a/standalone/node/src/chain_spec.rs b/standalone/node/src/chain_spec.rs index 56d8b83f8..efeb5f6bd 100644 --- a/standalone/node/src/chain_spec.rs +++ b/standalone/node/src/chain_spec.rs @@ -14,9 +14,9 @@ // use dkg_standalone_runtime::{ constants::currency::{Balance, DOLLARS}, - AccountId, BalancesConfig, DKGConfig, DKGId, DKGProposalsConfig, GenesisConfig, Perbill, - ResourceId, SessionConfig, Signature, StakerStatus, StakingConfig, SudoConfig, SystemConfig, - MAX_NOMINATIONS, WASM_BINARY, + AccountId, BalancesConfig, DKGConfig, DKGId, DKGProposalsConfig, GenesisConfig, MaxNominations, + Perbill, ResourceId, SessionConfig, Signature, StakerStatus, StakingConfig, SudoConfig, + SystemConfig, WASM_BINARY, }; use hex_literal::hex; @@ -307,7 +307,7 @@ fn testnet_genesis( .map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)) .chain(initial_nominators.iter().map(|x| { use rand::{seq::SliceRandom, Rng}; - let limit = (MAX_NOMINATIONS as usize).min(initial_authorities.len()); + let limit = (MaxNominations::get() as usize).min(initial_authorities.len()); let count = rng.gen::() % limit; let nominations = initial_authorities .as_slice() @@ -330,6 +330,8 @@ fn testnet_genesis( // Configure endowed accounts with initial balance of 1 << 60. balances: endowed_accounts.iter().cloned().map(|k| (k, ENDOWMENT)).collect(), }, + indices: Default::default(), + nomination_pools: Default::default(), session: SessionConfig { keys: initial_authorities .iter() @@ -354,7 +356,8 @@ fn testnet_genesis( grandpa: Default::default(), dkg: DKGConfig { authorities: initial_authorities.iter().map(|(.., x)| x.clone()).collect::<_>(), - threshold: Default::default(), + keygen_threshold: 2, + signature_threshold: 1, authority_ids: initial_authorities.iter().map(|(x, ..)| x.clone()).collect::<_>(), }, dkg_proposals: DKGProposalsConfig { initial_chain_ids, initial_r_ids, initial_proposers }, diff --git a/standalone/node/src/cli.rs b/standalone/node/src/cli.rs index c29d2d8f5..0ae3b64c1 100644 --- a/standalone/node/src/cli.rs +++ b/standalone/node/src/cli.rs @@ -12,22 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. // + +use sc_cli::RunCmd; + #[derive(Debug, clap::Parser)] pub struct Cli { - /// Possible subcommand with parameters. #[clap(subcommand)] pub subcommand: Option, - #[allow(missing_docs)] #[clap(flatten)] - pub run: sc_cli::RunCmd, + pub run: RunCmd, } -#[derive(Debug, clap::Parser)] +#[derive(Debug, clap::Subcommand)] pub enum Subcommand { /// Key management cli utilities #[clap(subcommand)] Key(sc_cli::KeySubcommand), + /// Build a chain specification. BuildSpec(sc_cli::BuildSpecCmd), @@ -49,7 +51,18 @@ pub enum Subcommand { /// Revert the chain to a previous state. Revert(sc_cli::RevertCmd), - /// The custom benchmark subcommmand benchmarking runtime pallets. - #[clap(name = "benchmark", about = "Benchmark runtime pallets.")] + /// Sub-commands concerned with benchmarking. + #[clap(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), + + /// Try some command against runtime state. + #[cfg(feature = "try-runtime")] + TryRuntime(try_runtime_cli::TryRuntimeCmd), + + /// Try some command against runtime state. Note: `try-runtime` feature must be enabled. + #[cfg(not(feature = "try-runtime"))] + TryRuntime, + + /// Db meta columns information. + ChainInfo(sc_cli::ChainInfoCmd), } diff --git a/standalone/node/src/command.rs b/standalone/node/src/command.rs index 430c962c1..e5972d21c 100644 --- a/standalone/node/src/command.rs +++ b/standalone/node/src/command.rs @@ -1,29 +1,18 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - use crate::{ chain_spec, cli::{Cli, Subcommand}, + command_helper::{inherent_benchmark_data, BenchmarkExtrinsicBuilder}, service, }; use dkg_standalone_runtime::Block; +use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli}; use sc_service::PartialComponents; +use std::sync::Arc; impl SubstrateCli for Cli { fn impl_name() -> String { - "Substrate Node".into() + "DKG Substrate Node".into() } fn impl_version() -> String { @@ -110,19 +99,75 @@ pub fn run() -> sc_cli::Result<()> { runner.async_run(|config| { let PartialComponents { client, task_manager, backend, .. } = service::new_partial(&config)?; - Ok((cmd.run(client, backend), task_manager)) + let aux_revert = Box::new(|client, _, blocks| { + sc_finality_grandpa::revert(client, blocks)?; + Ok(()) + }); + Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) }) }, - Some(Subcommand::Benchmark(cmd)) => - if cfg!(feature = "runtime-benchmarks") { - let runner = cli.create_runner(cmd)?; + Some(Subcommand::Benchmark(cmd)) => { + let runner = cli.create_runner(cmd)?; + + runner.sync_run(|config| { + // This switch needs to be in the client, since the client decides + // which sub-commands it wants to support. + match cmd { + BenchmarkCmd::Pallet(cmd) => { + if !cfg!(feature = "runtime-benchmarks") { + return Err( + "Runtime benchmarking wasn't enabled when building the node. \ + You can enable it with `--features runtime-benchmarks`." + .into(), + ) + } + + cmd.run::(config) + }, + BenchmarkCmd::Block(cmd) => { + let PartialComponents { client, .. } = service::new_partial(&config)?; + cmd.run(client) + }, + BenchmarkCmd::Storage(cmd) => { + let PartialComponents { client, backend, .. } = + service::new_partial(&config)?; + let db = backend.expose_db(); + let storage = backend.expose_storage(); - runner.sync_run(|config| cmd.run::(config)) - } else { - Err("Benchmarking wasn't enabled when building the node. You can enable it with \ - `--features runtime-benchmarks`." - .into()) - }, + cmd.run(config, client, db, storage) + }, + BenchmarkCmd::Overhead(cmd) => { + let PartialComponents { client, .. } = service::new_partial(&config)?; + let ext_builder = BenchmarkExtrinsicBuilder::new(client.clone()); + + cmd.run(config, client, inherent_benchmark_data()?, Arc::new(ext_builder)) + }, + BenchmarkCmd::Machine(cmd) => + cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone()), + } + }) + }, + #[cfg(feature = "try-runtime")] + Some(Subcommand::TryRuntime(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.async_run(|config| { + // we don't need any of the components of new_partial, just a runtime, or a task + // manager to do `async_run`. + let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); + let task_manager = + sc_service::TaskManager::new(config.tokio_handle.clone(), registry) + .map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?; + Ok((cmd.run::(config), task_manager)) + }) + }, + #[cfg(not(feature = "try-runtime"))] + Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ + You can enable it with `--features try-runtime`." + .into()), + Some(Subcommand::ChainInfo(cmd)) => { + let runner = cli.create_runner(cmd)?; + runner.sync_run(|config| cmd.run::(&config)) + }, None => { let runner = cli.create_runner(&cli.run)?; runner.run_node_until_exit(|config| async move { diff --git a/standalone/node/src/command_helper.rs b/standalone/node/src/command_helper.rs new file mode 100644 index 000000000..a82fbf4b4 --- /dev/null +++ b/standalone/node/src/command_helper.rs @@ -0,0 +1,131 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Contains code to setup the command invocations in [`super::command`] which would +//! otherwise bloat that module. + +use crate::service::FullClient; + +use dkg_standalone_runtime as runtime; +use runtime::SystemCall; +use sc_cli::Result; +use sc_client_api::BlockBackend; +use sp_core::{Encode, Pair}; +use sp_inherents::{InherentData, InherentDataProvider}; +use sp_keyring::Sr25519Keyring; +use sp_runtime::{OpaqueExtrinsic, SaturatedConversion}; + +use std::{sync::Arc, time::Duration}; + +/// Generates extrinsics for the `benchmark overhead` command. +/// +/// Note: Should only be used for benchmarking. +pub struct BenchmarkExtrinsicBuilder { + client: Arc, +} + +impl BenchmarkExtrinsicBuilder { + /// Creates a new [`Self`] from the given client. + pub fn new(client: Arc) -> Self { + Self { client } + } +} + +impl frame_benchmarking_cli::ExtrinsicBuilder for BenchmarkExtrinsicBuilder { + fn remark(&self, nonce: u32) -> std::result::Result { + let acc = Sr25519Keyring::Bob.pair(); + let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( + self.client.as_ref(), + acc, + SystemCall::remark { remark: vec![] }.into(), + nonce, + ) + .into(); + + Ok(extrinsic) + } +} + +/// Create a transaction using the given `call`. +/// +/// Note: Should only be used for benchmarking. +pub fn create_benchmark_extrinsic( + client: &FullClient, + sender: sp_core::sr25519::Pair, + call: runtime::Call, + nonce: u32, +) -> runtime::UncheckedExtrinsic { + let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"); + let best_hash = client.chain_info().best_hash; + let best_block = client.chain_info().best_number; + + let period = runtime::BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + let extra: runtime::SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(sp_runtime::generic::Era::mortal( + period, + best_block.saturated_into(), + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ); + + let raw_payload = runtime::SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis_hash, + best_hash, + (), + (), + (), + ), + ); + let signature = raw_payload.using_encoded(|e| sender.sign(e)); + + runtime::UncheckedExtrinsic::new_signed( + call, + sp_runtime::AccountId32::from(sender.public()).into(), + runtime::Signature::Sr25519(signature), + extra, + ) +} + +/// Generates inherent data for the `benchmark overhead` command. +/// +/// Note: Should only be used for benchmarking. +pub fn inherent_benchmark_data() -> Result { + let mut inherent_data = InherentData::new(); + let d = Duration::from_millis(0); + let timestamp = sp_timestamp::InherentDataProvider::new(d.into()); + + timestamp + .provide_inherent_data(&mut inherent_data) + .map_err(|e| format!("creating inherent data: {:?}", e))?; + Ok(inherent_data) +} diff --git a/standalone/node/src/lib.rs b/standalone/node/src/lib.rs index ee0dfc052..283ca493d 100644 --- a/standalone/node/src/lib.rs +++ b/standalone/node/src/lib.rs @@ -13,6 +13,7 @@ // limitations under the License. // pub mod chain_spec; +pub mod command_helper; pub mod rpc; pub mod service; pub mod testnet_fixtures; diff --git a/standalone/node/src/main.rs b/standalone/node/src/main.rs index d421cbac3..69e81189b 100644 --- a/standalone/node/src/main.rs +++ b/standalone/node/src/main.rs @@ -20,6 +20,7 @@ mod chain_spec; mod service; mod cli; mod command; +mod command_helper; mod rpc; mod testnet_fixtures; diff --git a/standalone/node/src/rpc.rs b/standalone/node/src/rpc.rs index 1f51f1da3..da0994dc4 100644 --- a/standalone/node/src/rpc.rs +++ b/standalone/node/src/rpc.rs @@ -1,17 +1,3 @@ -// Copyright 2022 Webb Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// //! A collection of node-specific RPC methods. //! Substrate provides the `sc-rpc` crate, which defines the core RPC layer //! used by Substrate nodes. This file extends those RPC definitions with @@ -19,21 +5,16 @@ #![warn(missing_docs)] -use dkg_standalone_runtime::{opaque::Block, AccountId, Balance, Hash, Index as Nonce}; -use sc_client_api::AuxStore; -use sc_consensus_manual_seal::{ - rpc::{ManualSeal, ManualSealApi}, - EngineCommand, -}; -pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; +use std::sync::Arc; + +use dkg_standalone_runtime::{opaque::Block, AccountId, Balance, Index}; +use jsonrpsee::RpcModule; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; -use std::sync::Arc; -/// A type representing all RPC extensions. -pub type RpcExtension = jsonrpc_core::IoHandler; +pub use sc_rpc_api::DenyUnsafe; /// Full client dependencies. pub struct FullDeps { @@ -43,46 +24,34 @@ pub struct FullDeps { pub pool: Arc

, /// Whether to deny unsafe calls pub deny_unsafe: DenyUnsafe, - /// Manual seal command sink - pub command_sink: Option>>, } /// Instantiate all full RPC extensions. -pub fn create_full(deps: FullDeps) -> RpcExtension +pub fn create_full( + deps: FullDeps, +) -> Result, Box> where - C: ProvideRuntimeApi - + HeaderBackend - + AuxStore - + HeaderMetadata - + Send - + Sync - + 'static, + C: ProvideRuntimeApi, + C: HeaderBackend + HeaderMetadata + 'static, + C: Send + Sync + 'static, + C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: BlockBuilder, - P: TransactionPool + Sync + Send + 'static, + P: TransactionPool + 'static, { - use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; - use substrate_frame_rpc_system::{FullSystem, SystemApi}; - - let mut io = jsonrpc_core::IoHandler::default(); - let FullDeps { client, pool, deny_unsafe, command_sink } = deps; + use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; + use substrate_frame_rpc_system::{System, SystemApiServer}; - io.extend_with(SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe))); + let mut module = RpcModule::new(()); + let FullDeps { client, pool, deny_unsafe } = deps; - io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client))); + module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; + module.merge(TransactionPayment::new(client).into_rpc())?; - if let Some(command_sink) = command_sink { - io.extend_with( - // We provide the rpc handler with the sending end of the channel to allow the rpc - // send EngineCommands to the background block authorship task. - ManualSealApi::to_delegate(ManualSeal::new(command_sink)), - ); - } // Extend this RPC with a custom API by using the following syntax. // `YourRpcStruct` should have a reference to a client, which is needed // to call into the runtime. - // `io.extend_with(YourRpcTrait::to_delegate(YourRpcStruct::new(ReferenceToClient, ...)));` + // `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, ...)))?;` - io + Ok(module) } diff --git a/standalone/node/src/service.rs b/standalone/node/src/service.rs index 7018648e5..bce88bb9d 100644 --- a/standalone/node/src/service.rs +++ b/standalone/node/src/service.rs @@ -12,24 +12,30 @@ // See the License for the specific language governing permissions and // limitations under the License. // + //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. + use dkg_standalone_runtime::{self, opaque::Block, RuntimeApi}; use sc_client_api::{BlockBackend, ExecutorProvider}; use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams}; -use sc_executor::NativeElseWasmExecutor; +pub use sc_executor::NativeElseWasmExecutor; use sc_finality_grandpa::SharedVoterState; use sc_keystore::LocalKeystore; use sc_service::{error::Error as ServiceError, BasePath, Configuration, TaskManager}; use sc_telemetry::{Telemetry, TelemetryWorker}; -use sp_consensus::SlotData; use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; use std::{sync::Arc, time::Duration}; -/// Native executor instance. -pub struct RuntimeExecutor; +// Our native executor instance. +pub struct ExecutorDispatch; -impl sc_executor::NativeExecutionDispatch for RuntimeExecutor { +impl sc_executor::NativeExecutionDispatch for ExecutorDispatch { + /// Only enable the benchmarking host functions when we actually want to benchmark. + #[cfg(feature = "runtime-benchmarks")] type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + /// Otherwise we only use the default Substrate host functions. + #[cfg(not(feature = "runtime-benchmarks"))] + type ExtendHostFunctions = (); fn dispatch(method: &str, data: &[u8]) -> Option> { dkg_standalone_runtime::api::dispatch(method, data) @@ -39,22 +45,12 @@ impl sc_executor::NativeExecutionDispatch for RuntimeExecutor { dkg_standalone_runtime::native_version() } } -pub type Executor = NativeElseWasmExecutor; -type FullClient = sc_service::TFullClient; +pub(crate) type FullClient = + sc_service::TFullClient>; type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; -#[cfg(not(feature = "manual-seal"))] -type Extra = ( - sc_finality_grandpa::GrandpaBlockImport, - sc_finality_grandpa::LinkHalf, - Option, -); - -#[cfg(feature = "manual-seal")] -type Extra = Option; - #[allow(clippy::type_complexity)] pub fn new_partial( config: &Configuration, @@ -65,12 +61,21 @@ pub fn new_partial( FullSelectChain, sc_consensus::DefaultImportQueue, sc_transaction_pool::FullPool, - Extra, + ( + sc_finality_grandpa::GrandpaBlockImport< + FullBackend, + Block, + FullClient, + FullSelectChain, + >, + sc_finality_grandpa::LinkHalf, + Option, + ), >, ServiceError, > { if config.keystore_remote.is_some() { - return Err(ServiceError::Other("Remote Keystores are not supported.".to_string())) + return Err(ServiceError::Other("Remote Keystores are not supported.".into())) } let telemetry = config @@ -84,7 +89,7 @@ pub fn new_partial( }) .transpose()?; - let executor = sc_executor::NativeElseWasmExecutor::::new( + let executor = NativeElseWasmExecutor::::new( config.wasm_method, config.default_heap_pages, config.max_runtime_instances, @@ -92,7 +97,7 @@ pub fn new_partial( ); let (client, backend, keystore_container, task_manager) = - sc_service::new_full_parts::( + sc_service::new_full_parts::( config, telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), executor, @@ -114,7 +119,6 @@ pub fn new_partial( client.clone(), ); - #[cfg(not(feature = "manual-seal"))] let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( client.clone(), &(client.clone() as Arc<_>), @@ -122,17 +126,8 @@ pub fn new_partial( telemetry.as_ref().map(|x| x.handle()), )?; - #[cfg(feature = "manual-seal")] - let import_queue = sc_consensus_manual_seal::import_queue( - Box::new(client.clone()), - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - ); - - #[cfg(not(feature = "manual-seal"))] - let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration(); + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - #[cfg(not(feature = "manual-seal"))] let import_queue = sc_consensus_aura::import_queue::(ImportQueueParams { block_import: grandpa_block_import.clone(), @@ -142,7 +137,7 @@ pub fn new_partial( let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( *timestamp, slot_duration, ); @@ -166,10 +161,7 @@ pub fn new_partial( keystore_container, select_chain, transaction_pool, - #[cfg(not(feature = "manual-seal"))] other: (grandpa_block_import, grandpa_link, telemetry), - #[cfg(feature = "manual-seal")] - other: telemetry, }) } @@ -190,15 +182,9 @@ pub fn new_full(mut config: Configuration) -> Result mut keystore_container, select_chain, transaction_pool, - other, + other: (block_import, grandpa_link, mut telemetry), } = new_partial(&config)?; - #[cfg(not(feature = "manual-seal"))] - let (block_import, grandpa_link, mut telemetry) = other; - - #[cfg(feature = "manual-seal")] - let mut telemetry = other; - if let Some(url) = &config.keystore_remote { match remote_keystore(url) { Ok(k) => keystore_container.set_remote_keystore(k), @@ -209,7 +195,6 @@ pub fn new_full(mut config: Configuration) -> Result ))), }; } - let grandpa_protocol_name = sc_finality_grandpa::protocol_standard_name( &client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"), &config.chain_spec, @@ -220,6 +205,11 @@ pub fn new_full(mut config: Configuration) -> Result .extra_sets .push(sc_finality_grandpa::grandpa_peers_set_config(grandpa_protocol_name.clone())); config.network.extra_sets.push(dkg_gadget::dkg_peers_set_config()); + let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new( + backend.clone(), + grandpa_link.shared_authority_set().clone(), + Vec::default(), + )); let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { @@ -229,7 +219,7 @@ pub fn new_full(mut config: Configuration) -> Result spawn_handle: task_manager.spawn_handle(), import_queue, block_announce_validator_builder: None, - warp_sync: None, + warp_sync: Some(warp_sync), })?; if config.offchain_worker.enabled { @@ -241,13 +231,6 @@ pub fn new_full(mut config: Configuration) -> Result ); } - let role = config.role.clone(); - let force_authoring = config.force_authoring; - let backoff_authoring_blocks: Option<()> = None; - let name = config.network.node_name.clone(); - let enable_grandpa = !config.disable_grandpa; - let prometheus_registry = config.prometheus_registry().cloned(); - let base_path = if config.base_path.is_some() { match config.base_path.as_ref() { Some(BasePath::Permanenent(path_buf)) => Some(path_buf.clone()), @@ -257,6 +240,13 @@ pub fn new_full(mut config: Configuration) -> Result None }; + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let backoff_authoring_blocks: Option<()> = None; + let name = config.network.node_name.clone(); + let enable_grandpa = !config.disable_grandpa; + let prometheus_registry = config.prometheus_registry().cloned(); + if role.is_authority() { dkg_primitives::utils::insert_controller_account_keys_into_keystore( &config, @@ -278,146 +268,90 @@ pub fn new_full(mut config: Configuration) -> Result task_manager.spawn_essential_handle().spawn_blocking( "dkg-gadget", None, - dkg_gadget::start_dkg_gadget::<_, _, _, _>(dkg_params), + dkg_gadget::start_dkg_gadget::<_, _, _>(dkg_params), ); } - // if the node isn't actively participating in consensus then it doesn't - // need a keystore, regardless of which protocol we use below. - let keystore = - if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None }; - - let rpc_client = client.clone(); - let command_sink = if role.is_authority() { - let proposer_factory = sc_basic_authorship::ProposerFactory::new( - task_manager.spawn_handle(), - client.clone(), - transaction_pool.clone(), - prometheus_registry.as_ref(), - telemetry.as_ref().map(|x| x.handle()), - ); - - if cfg!(feature = "manual-seal") { - use futures::prelude::*; - // Channel for the rpc handler to communicate with the authorship task. - let (command_sink, commands_stream) = futures::channel::mpsc::channel(1024); - - let pool = transaction_pool.pool().clone(); - let import_stream = pool.validated_pool().import_notification_stream().map(|_| { - sc_consensus_manual_seal::rpc::EngineCommand::SealNewBlock { - create_empty: true, - finalize: true, - parent_hash: None, - sender: None, - } - }); - let authorship_future = sc_consensus_manual_seal::run_manual_seal( - sc_consensus_manual_seal::ManualSealParams { - block_import: client.clone(), - env: proposer_factory, - client, - pool: transaction_pool.clone(), - commands_stream: futures::stream_select!(commands_stream, import_stream), - select_chain, - consensus_data_provider: None, - create_inherent_data_providers: Box::new(move |_, _| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - Ok(timestamp) - }), - }, - ); - // we spawn the future on a background thread managed by service. - task_manager.spawn_essential_handle().spawn_blocking( - "manual-seal", - Some("block-authoring"), - authorship_future, - ); - Some(command_sink) - } else { - #[cfg(not(feature = "manual-seal"))] - { - let can_author_with = - sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); - - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - let raw_slot_duration = slot_duration.slot_duration(); - - let aura = - sc_consensus_aura::start_aura::( - StartAuraParams { - slot_duration, - client, - select_chain, - block_import, - proposer_factory, - create_inherent_data_providers: move |_, ()| async move { - let timestamp = - sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration( - *timestamp, - raw_slot_duration, - ); - - Ok((timestamp, slot)) - }, - force_authoring, - backoff_authoring_blocks, - keystore: keystore_container.sync_keystore(), - can_author_with, - sync_oracle: network.clone(), - justification_sync_link: network.clone(), - block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32), - max_block_proposal_slot_portion: None, - telemetry: telemetry.as_ref().map(|x| x.handle()), - }, - )?; - - // the AURA authoring task is considered essential, i.e. if it - // fails we take down the service with it. - task_manager.spawn_essential_handle().spawn_blocking( - "aura", - Some("block-authoring"), - aura, - ); - } - None - } - } else { - None - }; - let rpc_extensions_builder = { - let client = rpc_client.clone(); + let client = client.clone(); let pool = transaction_pool.clone(); Box::new(move |deny_unsafe, _| { - let deps = crate::rpc::FullDeps { - client: client.clone(), - pool: pool.clone(), - command_sink: command_sink.clone(), - deny_unsafe, - }; - - Ok(crate::rpc::create_full(deps)) + let deps = + crate::rpc::FullDeps { client: client.clone(), pool: pool.clone(), deny_unsafe }; + crate::rpc::create_full(deps).map_err(Into::into) }) }; let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { network: network.clone(), - client: rpc_client, + client: client.clone(), keystore: keystore_container.sync_keystore(), task_manager: &mut task_manager, - transaction_pool, - rpc_extensions_builder, + transaction_pool: transaction_pool.clone(), + rpc_builder: rpc_extensions_builder, backend, system_rpc_tx, config, telemetry: telemetry.as_mut(), })?; - #[cfg(not(feature = "manual-seal"))] + if role.is_authority() { + let proposer_factory = sc_basic_authorship::ProposerFactory::new( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry.as_ref(), + telemetry.as_ref().map(|x| x.handle()), + ); + + let can_author_with = + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + + let aura = sc_consensus_aura::start_aura::( + StartAuraParams { + slot_duration, + client, + select_chain, + block_import, + proposer_factory, + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + + Ok((timestamp, slot)) + }, + force_authoring, + backoff_authoring_blocks, + keystore: keystore_container.sync_keystore(), + can_author_with, + sync_oracle: network.clone(), + justification_sync_link: network.clone(), + block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32), + max_block_proposal_slot_portion: None, + telemetry: telemetry.as_ref().map(|x| x.handle()), + }, + )?; + + // the AURA authoring task is considered essential, i.e. if it + // fails we take down the service with it. + task_manager + .spawn_essential_handle() + .spawn_blocking("aura", Some("block-authoring"), aura); + } + + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = + if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None }; + let grandpa_config = sc_finality_grandpa::Config { // FIXME #1578 make this available through chainspec gossip_duration: Duration::from_millis(333), @@ -430,7 +364,6 @@ pub fn new_full(mut config: Configuration) -> Result protocol_name: grandpa_protocol_name, }; - #[cfg(not(feature = "manual-seal"))] if enable_grandpa { // start the full GRANDPA voter // NOTE: non-authorities could run the GRANDPA observer protocol, but at diff --git a/standalone/runtime/Cargo.toml b/standalone/runtime/Cargo.toml index 6000436ec..2bcdfd4da 100644 --- a/standalone/runtime/Cargo.toml +++ b/standalone/runtime/Cargo.toml @@ -13,42 +13,45 @@ repository = "https://github.com/webb-tools/dkg-substrate" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ +codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive", ] } -scale-info = { version = "1.0", default-features = false, features = [ +scale-info = { version = "2.1.1", default-features = false, features = [ "derive", ] } -pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-executive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-staking-reward-curve = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -pallet-election-provider-multi-phase = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } -sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } +pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-bags-list = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-nomination-pools = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-staking-reward-curve = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +pallet-election-provider-multi-phase = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } +sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } # Local dependencies dkg-runtime-primitives = { path = "../../dkg-runtime-primitives", default-features = false } @@ -57,16 +60,16 @@ pallet-dkg-proposals = { path = '../../pallets/dkg-proposals', default-features pallet-dkg-proposal-handler = { path = '../../pallets/dkg-proposal-handler', default-features = false } # Used for the node template's RPCs -frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false } # Used for runtime benchmarking -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false, optional = true } -frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17", default-features = false, optional = true } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24", default-features = false, optional = true } hex-literal = { version = "0.3.3", optional = true } [build-dependencies] -substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.17" } +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.24" } [features] default = ["std"] @@ -78,6 +81,7 @@ std = [ "frame-system-rpc-runtime-api/std", "frame-system/std", "pallet-aura/std", + "pallet-indices/std", "pallet-balances/std", "pallet-grandpa/std", "pallet-randomness-collective-flip/std", @@ -85,6 +89,8 @@ std = [ "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", "pallet-transaction-payment/std", + "pallet-nomination-pools/std", + "pallet-bags-list/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", diff --git a/standalone/runtime/src/constants.rs b/standalone/runtime/src/constants.rs index 41a3f7a34..d51a1622a 100644 --- a/standalone/runtime/src/constants.rs +++ b/standalone/runtime/src/constants.rs @@ -36,6 +36,20 @@ pub mod time { pub type BlockNumber = u32; /// Type used for expressing timestamp. pub type Moment = u64; + + use frame_support::weights::{constants::WEIGHT_PER_SECOND, Weight}; + use sp_runtime::Perbill; + /// We assume that ~5% of the block weight is consumed by `on_initialize` + /// handlers. This is used to limit the maximal weight of a single + /// extrinsic. + pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); + /// We allow `Normal` extrinsics to fill up the block up to 75%, the rest + /// can be used by Operational extrinsics. + pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); + + /// We allow for 0.5 seconds of compute with a 6 second average block time. + pub const MAXIMUM_BLOCK_WEIGHT: Weight = WEIGHT_PER_SECOND / 2; + /// Since BABE is probabilistic this is the average expected block time that /// we are targeting. Blocks will be produced at a minimum duration defined /// by `SLOT_DURATION`, but some slots will not be allocated to any diff --git a/standalone/runtime/src/lib.rs b/standalone/runtime/src/lib.rs index cd7267e58..1a841dee8 100644 --- a/standalone/runtime/src/lib.rs +++ b/standalone/runtime/src/lib.rs @@ -22,13 +22,27 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use codec::{Decode, Encode}; use dkg_runtime_primitives::{TypedChainId, UnsignedProposal}; -use frame_support::traits::{ConstU32, Everything, U128CurrencyToVote}; +use frame_election_provider_support::{onchain, ExtendedBalance, SequentialPhragmen, VoteWeight}; +use frame_support::{ + pallet_prelude::Get, + traits::{ConstU16, ConstU32, Everything, U128CurrencyToVote}, + weights::ConstantMultiplier, +}; +#[cfg(any(feature = "std", test))] +pub use frame_system::Call as SystemCall; +use frame_system::{ + limits::{BlockLength, BlockWeights}, + EnsureRoot, +}; use pallet_dkg_proposals::DKGEcdsaToEthereum; +use pallet_election_provider_multi_phase::SolutionAccuracyOf; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; +use pallet_session::historical as pallet_session_historical; #[cfg(any(feature = "std", test))] pub use pallet_staking::StakerStatus; +pub use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment}; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; @@ -41,12 +55,10 @@ use sp_runtime::{ OpaqueKeys, StaticLookup, Verify, }, transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiSignature, Percent, SaturatedConversion, + ApplyExtrinsicResult, FixedPointNumber, MultiSignature, Percent, Perquintill, + SaturatedConversion, }; - -use frame_system::EnsureRoot; -use pallet_session::historical as pallet_session_historical; -use sp_std::prelude::*; +use sp_std::{convert::TryInto, prelude::*}; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; @@ -63,7 +75,6 @@ pub use frame_support::{ }; pub use pallet_balances::Call as BalancesCall; pub use pallet_timestamp::Call as TimestampCall; -use pallet_transaction_payment::CurrencyAdapter; use sp_runtime::generic::Era; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -92,6 +103,8 @@ pub type Index = u32; /// A hash of some data used by the chain. pub type Hash = sp_core::H256; +pub type AccountIndex = u32; + /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades @@ -109,11 +122,11 @@ pub mod opaque { pub type BlockId = generic::BlockId; impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - pub grandpa: Grandpa, - pub dkg: DKG, - } + pub struct SessionKeys { + pub aura: Aura, + pub grandpa: Grandpa, + pub dkg: DKG, + } } } @@ -141,74 +154,74 @@ pub fn native_version() -> NativeVersion { const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); parameter_types! { - pub const Version: RuntimeVersion = VERSION; - pub const BlockHashCount: BlockNumber = 2400; - /// We allow for 2 seconds of compute with a 6 second average block time. - pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights - ::with_sensible_defaults(2 * WEIGHT_PER_SECOND, NORMAL_DISPATCH_RATIO); - pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength - ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); - pub const SS58Prefix: u8 = 42; + pub const BlockHashCount: BlockNumber = 2400; + pub const Version: RuntimeVersion = VERSION; + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); + pub const SS58Prefix: u16 = 42; } -// Configure FRAME pallets to include in runtime. - impl frame_system::Config for Runtime { - /// The basic call filter to use in dispatchable. - type BaseCallFilter = Everything; - /// Block & extrinsics weights: base values and limits. - type BlockWeights = BlockWeights; - /// The maximum length of a block (in bytes). - type BlockLength = BlockLength; - /// The identifier used to distinguish between accounts. + type AccountData = pallet_balances::AccountData; type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = AccountIdLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. + type BaseCallFilter = Everything; + type BlockHashCount = BlockHashCount; + type BlockLength = RuntimeBlockLength; type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. + type BlockWeights = RuntimeBlockWeights; + type Call = Call; + type DbWeight = RocksDbWeight; + type Event = Event; type Hash = Hash; - /// The hashing algorithm used. type Hashing = BlakeTwo256; - /// The header type. type Header = generic::Header; - /// The ubiquitous event type. - type Event = Event; - /// The ubiquitous origin type. + type Index = Index; + type Lookup = Indices; + type MaxConsumers = frame_support::traits::ConstU32<16>; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); type Origin = Origin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// Version of the runtime. - type Version = Version; - /// Converts a module to the index of the module in `construct_runtime!`. - /// - /// This type is being generated by `construct_runtime!`. type PalletInfo = PalletInfo; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = (); - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. type SS58Prefix = SS58Prefix; - /// The set code logic, just the default since we're not a parachain. - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; + type SystemWeightInfo = frame_system::weights::SubstrateWeight; + type Version = Version; +} + +parameter_types! { + pub const IndexDeposit: Balance = DOLLARS; +} + +impl pallet_indices::Config for Runtime { + type AccountIndex = AccountIndex; + type Currency = Balances; + type Deposit = IndexDeposit; + type Event = Event; + type WeightInfo = pallet_indices::weights::SubstrateWeight; } impl pallet_randomness_collective_flip::Config for Runtime {} parameter_types! { - pub const MaxAuthorities: u32 = 1_000; + pub const MaxAuthorities: u32 = 1_000; } impl pallet_aura::Config for Runtime { @@ -238,7 +251,7 @@ impl pallet_grandpa::Config for Runtime { } parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } impl pallet_timestamp::Config for Runtime { @@ -254,17 +267,17 @@ impl pallet_timestamp::Config for Runtime { #[cfg(feature = "integration-tests")] parameter_types! { - // How often we trigger a new session. - // during integration tests, we use manual sessions. - pub const Period: BlockNumber = 6 * HOURS; - pub const Offset: BlockNumber = 0; + // How often we trigger a new session. + // during integration tests, we use manual sessions. + pub const Period: BlockNumber = 6 * HOURS; + pub const Offset: BlockNumber = 0; } #[cfg(not(feature = "integration-tests"))] parameter_types! { - // How often we trigger a new session. - pub const Period: BlockNumber = 1 * MINUTES; - pub const Offset: BlockNumber = 0; + // How often we trigger a new session. + pub const Period: BlockNumber = MINUTES; + pub const Offset: BlockNumber = 0; } impl pallet_session::Config for Runtime { @@ -279,39 +292,30 @@ impl pallet_session::Config for Runtime { type WeightInfo = pallet_session::weights::SubstrateWeight; } -pallet_staking_reward_curve::build! { - const REWARD_CURVE: PiecewiseLinear<'static> = curve!( - min_inflation: 0_040_000, - max_inflation: 0_050_000, - // 60% of total issuance at a yearly inflation rate of 5% - ideal_stake: 0_600_000, - falloff: 0_050_000, - max_piece_count: 40, - test_precision: 0_005_000, - ); -} - impl pallet_session::historical::Config for Runtime { type FullIdentification = pallet_staking::Exposure; type FullIdentificationOf = pallet_staking::ExposureOf; } -use frame_election_provider_support::onchain; -impl onchain::Config for Runtime { - type Accuracy = Perbill; - type DataProvider = Staking; +pallet_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); } parameter_types! { - pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); - pub const SessionsPerEra: sp_staking::SessionIndex = 6; - pub const BondingDuration: u32 = 24 * 28; - pub const SlashDeferDuration: u32 = 24 * 7; // 1/4 the bonding duration. - pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; - pub const MaxNominatorRewardedPerValidator: u32 = 256; - pub const MaxNominations: u32 = MAX_NOMINATIONS; - pub OffchainRepeat: BlockNumber = 5; - pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; + pub const SessionsPerEra: sp_staking::SessionIndex = 6; + pub const BondingDuration: sp_staking::EraIndex = 24 * 28; + pub const SlashDeferDuration: sp_staking::EraIndex = 24 * 7; // 1/4 the bonding duration. + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub const MaxNominatorRewardedPerValidator: u32 = 256; + pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); + pub OffchainRepeat: BlockNumber = 5; } pub struct StakingBenchmarkingConfig; @@ -321,77 +325,73 @@ impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig { } impl pallet_staking::Config for Runtime { - type BondingDuration = BondingDuration; + type MaxNominations = MaxNominations; type Currency = Balances; + type CurrencyBalance = Balance; + type UnixTime = Timestamp; type CurrencyToVote = U128CurrencyToVote; - type ElectionProvider = ElectionProviderMultiPhase; - type EraPayout = pallet_staking::ConvertCurve; + type RewardRemainder = (); type Event = Event; - type GenesisElectionProvider = onchain::OnChainSequentialPhragmen; - type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; - type NextNewSession = Session; - type OffendingValidatorsThreshold = OffendingValidatorsThreshold; - // send the slashed funds to the treasury. + type Slash = (); type Reward = (); - type RewardRemainder = (); - type SessionInterface = Self; - // rewards are minted from the void type SessionsPerEra = SessionsPerEra; - type Slash = (); - /// A super-majority of the council can cancel the slash. - type SlashCancelOrigin = EnsureOneOf, EnsureRoot>; + type BondingDuration = BondingDuration; type SlashDeferDuration = SlashDeferDuration; - // Alternatively, use pallet_staking::UseNominatorsMap to just use the - // nominators map. Note that the aforementioned does not scale to a very large - // number of nominators. - type SortedListProvider = pallet_staking::UseNominatorsMap; - type UnixTime = Timestamp; + /// A super-majority of the council can cancel the slash. + type SlashCancelOrigin = EnsureRoot; + type SessionInterface = Self; + type EraPayout = pallet_staking::ConvertCurve; + type NextNewSession = Session; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type OffendingValidatorsThreshold = OffendingValidatorsThreshold; + type ElectionProvider = ElectionProviderMultiPhase; + type GenesisElectionProvider = onchain::UnboundedExecution; + type VoterList = BagsList; + type MaxUnlockingChunks = ConstU32<32>; + type OnStakerSlash = NominationPools; type WeightInfo = pallet_staking::weights::SubstrateWeight; type BenchmarkingConfig = StakingBenchmarkingConfig; - type MaxNominations = MaxNominations; } parameter_types! { - // phase durations. 1/4 of the last session for each. - pub const SignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4; - pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4; - - // signed config - pub const SignedMaxSubmissions: u32 = 10; - pub const SignedRewardBase: Balance = DOLLARS; - pub const SignedDepositBase: Balance = DOLLARS; - pub const SignedDepositByte: Balance = CENTS; - - pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(1u32, 10_000); - - // miner configs - pub const MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64; - pub MinerMaxWeight: Weight = BlockWeights::get() - .get(DispatchClass::Normal) - .max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed") - .saturating_sub(BlockExecutionWeight::get()); - // Solution can occupy 90% of normal block size - pub MinerMaxLength: u32 = Perbill::from_rational(9u32, 10) * - *BlockLength::get() - .max - .get(DispatchClass::Normal); - - // BagsList allows a practically unbounded count of nominators to participate in NPoS elections. - // To ensure we respect memory limits when using the BagsList this must be set to a number of - // voters we know can fit into a single vec allocation. - pub const VoterSnapshotPerBlock: u32 = 10_000; -} - -sp_npos_elections::generate_solution_type!( - #[compact] - pub struct NposSolution16::< - VoterIndex = u32, - TargetIndex = u16, - Accuracy = sp_runtime::PerU16, - >(16) + // phase durations. 1/4 of the last session for each. + pub const SignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS as u32 / 4; + pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS as u32 / 4; + + // signed config + pub const SignedRewardBase: Balance = DOLLARS; + pub const SignedDepositBase: Balance = DOLLARS; + pub const SignedDepositByte: Balance = CENTS; + pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; + pub BetterUnsignedThreshold: Perbill = Perbill::from_rational(1u32, 10_000); + + // miner configs + pub const MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64; + pub MinerMaxWeight: Weight = RuntimeBlockWeights::get() + .get(DispatchClass::Normal) + .max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed") + .saturating_sub(BlockExecutionWeight::get()); + // Solution can occupy 90% of normal block size + pub MinerMaxLength: u32 = Perbill::from_rational(9u32, 10) * + *RuntimeBlockLength::get() + .max + .get(DispatchClass::Normal); +} + +frame_election_provider_support::generate_solution_type!( + #[compact] + pub struct NposSolution16::< + VoterIndex = u32, + TargetIndex = u16, + Accuracy = sp_runtime::PerU16, + MaxVoters = MaxElectingVoters, + >(16) ); -pub const MAX_NOMINATIONS: u32 = ::LIMIT as u32; +parameter_types! { + pub MaxNominations: u32 = ::LIMIT as u32; + pub MaxElectingVoters: u32 = 10_000; +} /// The numbers configured here could always be more than the the maximum limits of staking pallet /// to ensure election snapshot will not run out of memory. For now, we set them to smaller values @@ -407,17 +407,14 @@ impl pallet_election_provider_multi_phase::BenchmarkingConfig for ElectionProvid const MAXIMUM_TARGETS: u32 = 300; } -/// Maximum number of iterations for balancing that will be executed in the -/// embedded OCW miner of election provider multi phase. +/// Maximum number of iterations for balancing that will be executed in the embedded OCW +/// miner of election provider multi phase. pub const MINER_MAX_ITERATIONS: u32 = 10; -/// A source of random balance for NposSolver, which is meant to be run by the -/// OCW election miner. +/// A source of random balance for NposSolver, which is meant to be run by the OCW election miner. pub struct OffchainRandomBalancing; -impl frame_support::pallet_prelude::Get> - for OffchainRandomBalancing -{ - fn get() -> Option<(usize, sp_npos_elections::ExtendedBalance)> { +impl Get> for OffchainRandomBalancing { + fn get() -> Option<(usize, ExtendedBalance)> { use sp_runtime::traits::TrailingZeroInput; let iters = match MINER_MAX_ITERATIONS { 0 => 0, @@ -434,37 +431,33 @@ impl frame_support::pallet_prelude::Get(sp_std::marker::PhantomData); - -#[cfg(feature = "integration-tests")] -use frame_election_provider_support::ElectionDataProvider; -#[cfg(feature = "integration-tests")] -use sp_npos_elections::Support; - -use frame_election_provider_support::ElectionProvider; -use sp_npos_elections::Supports; +pub struct OnChainSeqPhragmen; +impl onchain::Config for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen< + AccountId, + pallet_election_provider_multi_phase::SolutionAccuracyOf, + >; + type DataProvider = ::DataProvider; + type WeightInfo = frame_election_provider_support::weights::SubstrateWeight; +} -impl ElectionProvider for Fallback { - type AccountId = T::AccountId; - type BlockNumber = T::BlockNumber; - type DataProvider = T::DataProvider; - type Error = &'static str; +impl onchain::BoundedConfig for OnChainSeqPhragmen { + type VotersBound = MaxElectingVoters; + type TargetsBound = ConstU32<2_000>; +} - #[cfg(feature = "integration-tests")] - fn elect() -> Result, Self::Error> { - let targets = ::targets(None); - match targets { - Ok(candidates) => Ok(candidates - .iter() - .map(|x| (x.clone(), Support::::default())) - .collect::>()), - Err(_) => Err("No fallback"), - } - } +pub struct WebbMinerConfig; +impl pallet_election_provider_multi_phase::MinerConfig for WebbMinerConfig { + type AccountId = AccountId; + type MaxLength = MinerMaxLength; + type MaxWeight = MinerMaxWeight; + type MaxVotesPerVoter = MaxNominations; + type Solution = NposSolution16; - #[cfg(not(feature = "integration-tests"))] - fn elect() -> Result, Self::Error> { - Err("No fallback") + #[allow(unused)] + fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight { + 0 } } @@ -474,41 +467,76 @@ impl pallet_election_provider_multi_phase::Config for Runtime { type EstimateCallFee = TransactionPayment; type SignedPhase = SignedPhase; type UnsignedPhase = UnsignedPhase; - type SolutionImprovementThreshold = SolutionImprovementThreshold; + type BetterUnsignedThreshold = BetterUnsignedThreshold; + type BetterSignedThreshold = (); + type MinerConfig = WebbMinerConfig; type OffchainRepeat = OffchainRepeat; - type MinerMaxWeight = MinerMaxWeight; - type MinerMaxLength = MinerMaxLength; type MinerTxPriority = MultiPhaseUnsignedPriority; type SignedMaxSubmissions = ConstU32<10>; type SignedRewardBase = SignedRewardBase; type SignedDepositBase = SignedDepositBase; type SignedDepositByte = SignedDepositByte; + type SignedMaxRefunds = ConstU32<3>; type SignedDepositWeight = (); type SignedMaxWeight = MinerMaxWeight; type SlashHandler = (); // burn slashes type RewardHandler = (); // nothing to do upon rewards type DataProvider = Staking; - type Solution = NposSolution16; - type Fallback = Fallback; - type GovernanceFallback = - frame_election_provider_support::onchain::OnChainSequentialPhragmen; - type Solver = frame_election_provider_support::SequentialPhragmen< - AccountId, - pallet_election_provider_multi_phase::SolutionAccuracyOf, - OffchainRandomBalancing, - >; - type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight; + type Fallback = onchain::BoundedExecution; + type GovernanceFallback = onchain::BoundedExecution; + type Solver = SequentialPhragmen, OffchainRandomBalancing>; type ForceOrigin = EnsureRoot; + type MaxElectableTargets = ConstU16<{ u16::MAX }>; + type MaxElectingVoters = MaxElectingVoters; type BenchmarkingConfig = ElectionProviderBenchmarkConfig; - // BagsList allows a practically unbounded count of nominators to participate in NPoS elections. - // To ensure we respect memory limits when using the BagsList this must be set to a number of - // voters we know can fit into a single vec allocation. - type VoterSnapshotPerBlock = ConstU32<10_000>; + type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight; +} + +impl pallet_bags_list::Config for Runtime { + type Event = Event; + type ScoreProvider = Staking; + type WeightInfo = pallet_bags_list::weights::SubstrateWeight; + type BagThresholds = (); + type Score = VoteWeight; +} + +parameter_types! { + pub const PostUnbondPoolsWindow: u32 = 4; + pub const NominationPoolsPalletId: PalletId = PalletId(*b"py/nopls"); + pub const MinPointsToBalance: u32 = 10; +} + +use sp_runtime::traits::Convert; +pub struct BalanceToU256; +impl Convert for BalanceToU256 { + fn convert(balance: Balance) -> sp_core::U256 { + sp_core::U256::from(balance) + } +} +pub struct U256ToBalance; +impl Convert for U256ToBalance { + fn convert(n: sp_core::U256) -> Balance { + n.try_into().unwrap_or(Balance::max_value()) + } +} + +impl pallet_nomination_pools::Config for Runtime { + type WeightInfo = (); + type Event = Event; + type Currency = Balances; + type BalanceToU256 = BalanceToU256; + type U256ToBalance = U256ToBalance; + type StakingInterface = pallet_staking::Pallet; + type PostUnbondingPoolsWindow = PostUnbondPoolsWindow; + type MaxMetadataLen = ConstU32<256>; + type MaxUnbonding = ConstU32<8>; + type PalletId = NominationPoolsPalletId; + type MinPointsToBalance = MinPointsToBalance; } parameter_types! { - pub const ExistentialDeposit: u128 = EXISTENTIAL_DEPOSIT; - pub const MaxLocks: u32 = 50; + pub const ExistentialDeposit: u128 = EXISTENTIAL_DEPOSIT; + pub const MaxLocks: u32 = 50; } impl pallet_balances::Config for Runtime { @@ -526,17 +554,20 @@ impl pallet_balances::Config for Runtime { } parameter_types! { - pub const DecayPercentage: Percent = Percent::from_percent(50); - pub const TransactionByteFee: Balance = 1; - pub const OperationalFeeMultiplier: u8 = 5; + pub const TransactionByteFee: Balance = 10 * MILLICENTS; + pub const OperationalFeeMultiplier: u8 = 5; + pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); + pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000); + pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128); } impl pallet_transaction_payment::Config for Runtime { type OnChargeTransaction = CurrencyAdapter; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = IdentityFee; - type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = OperationalFeeMultiplier; + type WeightToFee = IdentityFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = + TargetedFeeAdjustment; } impl pallet_sudo::Config for Runtime { @@ -544,6 +575,10 @@ impl pallet_sudo::Config for Runtime { type Call = Call; } +parameter_types! { + pub const DecayPercentage: Percent = Percent::from_percent(50); +} + impl pallet_dkg_metadata::Config for Runtime { type DKGId = DKGId; type Event = Event; @@ -562,17 +597,20 @@ impl pallet_dkg_metadata::Config for Runtime { } parameter_types! { - pub const ChainIdentifier: TypedChainId = TypedChainId::Substrate(5); - pub const ProposalLifetime: BlockNumber = HOURS / 5; - pub const DKGAccountId: PalletId = PalletId(*b"dw/dkgac"); - pub const RefreshDelay: Permill = Permill::from_percent(50); - pub const TimeToRestart: BlockNumber = 3; + pub const ChainIdentifier: TypedChainId = TypedChainId::Substrate(5); + pub const ProposalLifetime: BlockNumber = HOURS / 5; + pub const DKGAccountId: PalletId = PalletId(*b"dw/dkgac"); + pub const RefreshDelay: Permill = Permill::from_percent(50); + pub const TimeToRestart: BlockNumber = 3; + // 1 hr considering block time of 12sec + pub const UnsignedProposalExpiry : BlockNumber = 300; } impl pallet_dkg_proposal_handler::Config for Runtime { type Event = Event; type OffChainAuthId = dkg_runtime_primitives::offchain::crypto::OffchainAuthId; type MaxSubmissionsPerBatch = frame_support::traits::ConstU16<100>; + type UnsignedProposalExpiry = UnsignedProposalExpiry; type WeightInfo = pallet_dkg_proposal_handler::weights::WebbWeight; } @@ -611,6 +649,7 @@ where .saturating_sub(1); let era = Era::mortal(period, current_block); let extra = ( + frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), frame_system::CheckGenesis::::new(), @@ -619,6 +658,7 @@ where frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), ); + let raw_payload = SignedPayload::new(call, extra) .map_err(|e| { frame_support::log::warn!("Unable to create signed payload: {:?}", e); @@ -646,27 +686,30 @@ where // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = opaque::Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: frame_system, - RandomnessCollectiveFlip: pallet_randomness_collective_flip, - Timestamp: pallet_timestamp, - Aura: pallet_aura, - Grandpa: pallet_grandpa, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - Sudo: pallet_sudo, - ElectionProviderMultiPhase: pallet_election_provider_multi_phase, - Staking: pallet_staking, - Session: pallet_session, - Historical: pallet_session_historical, - DKG: pallet_dkg_metadata, - DKGProposals: pallet_dkg_proposals, - DKGProposalHandler: pallet_dkg_proposal_handler - } + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system, + Indices: pallet_indices, + RandomnessCollectiveFlip: pallet_randomness_collective_flip, + Timestamp: pallet_timestamp, + Aura: pallet_aura, + Grandpa: pallet_grandpa, + Balances: pallet_balances, + DKG: pallet_dkg_metadata, + DKGProposals: pallet_dkg_proposals, + DKGProposalHandler: pallet_dkg_proposal_handler, + TransactionPayment: pallet_transaction_payment, + Sudo: pallet_sudo, + ElectionProviderMultiPhase: pallet_election_provider_multi_phase, + BagsList: pallet_bags_list, + NominationPools: pallet_nomination_pools, + Staking: pallet_staking, + Session: pallet_session, + Historical: pallet_session_historical, + } ); /// The address format for describing accounts. @@ -677,6 +720,7 @@ pub type Header = generic::Header; pub type Block = generic::Block; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( + frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, frame_system::CheckGenesis, @@ -697,288 +741,288 @@ pub type Executive = frame_executive::Executive< >; impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block); - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> sp_consensus_aura::SlotDuration { - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) - } - - fn authorities() -> Vec { - Aura::authorities().into_inner() - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - opaque::SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - opaque::SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_authorities() -> GrandpaAuthorityList { - Grandpa::grandpa_authorities() - } - - fn current_set_id() -> fg_primitives::SetId { - Grandpa::current_set_id() - } - - fn submit_report_equivocation_unsigned_extrinsic( - _equivocation_proof: fg_primitives::EquivocationProof< - ::Hash, - NumberFor, - >, - _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, - ) -> Option<()> { - None - } - - fn generate_key_ownership_proof( - _set_id: fg_primitives::SetId, - _authority_id: GrandpaId, - ) -> Option { - // NOTE: this is the only implementation possible since we've - // defined our key owner proof type as a bottom type (i.e. a type - // with no values). - None - } - } - - impl dkg_runtime_primitives::DKGApi for Runtime { - fn authority_set() -> dkg_runtime_primitives::AuthoritySet { - let authorities = DKG::authorities(); - let authority_set_id = DKG::authority_set_id(); - - dkg_runtime_primitives::AuthoritySet { - authorities, - id: authority_set_id - } - } - - fn queued_authority_set() -> dkg_runtime_primitives::AuthoritySet { - let queued_authorities = DKG::next_authorities(); - let queued_authority_set_id = DKG::authority_set_id() + 1u64; - - dkg_runtime_primitives::AuthoritySet { - authorities: queued_authorities, - id: queued_authority_set_id - } - } - - fn signature_threshold() -> u16 { - DKG::signature_threshold() - } - - fn keygen_threshold() -> u16 { - DKG::keygen_threshold() - } - - fn next_signature_threshold() -> u16 { - DKG::next_signature_threshold() - } - - fn next_keygen_threshold() -> u16 { - DKG::next_keygen_threshold() - } - - fn should_refresh(block_number: BlockNumber) -> bool { - DKG::should_refresh(block_number) - } - - fn next_dkg_pub_key() -> Option<(dkg_runtime_primitives::AuthoritySetId, Vec)> { - DKG::next_dkg_public_key() - } - - fn next_pub_key_sig() -> Option> { - DKG::next_public_key_signature() - } - - fn dkg_pub_key() -> (dkg_runtime_primitives::AuthoritySetId, Vec) { - DKG::dkg_public_key() - } - - fn get_best_authorities() -> Vec<(u16, DKGId)> { - DKG::best_authorities() - } - - fn get_next_best_authorities() -> Vec<(u16, DKGId)> { - DKG::next_best_authorities() - } - - fn get_unsigned_proposals() -> Vec { - DKGProposalHandler::get_unsigned_proposals() - } - - fn get_max_extrinsic_delay(block_number: BlockNumber) -> BlockNumber { - DKG::max_extrinsic_delay(block_number) - } - - fn get_authority_accounts() -> (Vec, Vec) { - (DKG::current_authorities_accounts(), DKG::next_authorities_accounts()) - } - - fn get_reputations(authorities: Vec) -> Vec<(DKGId, Reputation)> { - authorities.iter().map(|a| (a.clone(), DKG::authority_reputations(a))).collect() - } - - fn get_keygen_jailed(set: Vec) -> Vec { - set.iter().filter(|a| pallet_dkg_metadata::JailedKeygenAuthorities::::contains_key(a)).cloned().collect() - } - - fn get_signing_jailed(set: Vec) -> Vec { - set.iter().filter(|a| pallet_dkg_metadata::JailedSigningAuthorities::::contains_key(a)).cloned().collect() - } - - fn refresh_nonce() -> u32 { - DKG::refresh_nonce() - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - - use frame_system_benchmarking::Pallet as SystemBench; - - let mut list = Vec::::new(); - - list_benchmark!(list, extra, pallet_balances, Balances); - list_benchmark!(list, extra, frame_system, SystemBench::); - list_benchmark!(list, extra, pallet_timestamp, Timestamp); - list_benchmark!(list, extra, pallet_dkg_proposal_handler, DKGProposalHandler); - list_benchmark!(list, extra, pallet_dkg_proposals, DKGProposals); - list_benchmark!(list, extra, pallet_dkg_metadata, DKG); - - - let storage_info = AllPalletsWithSystem::storage_info(); - - (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; - use frame_support::traits::StorageInfoTrait; - - use frame_system_benchmarking::Pallet as SystemBench; - impl frame_system_benchmarking::Config for Runtime {} - - let whitelist: Vec = vec![ - // Block Number - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), - // Total Issuance - hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), - // Execution Phase - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), - // Event Count - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), - // System Events - hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), - ]; - - let _storage_info = AllPalletsWithSystem::storage_info(); - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - - add_benchmark!(params, batches, frame_system, SystemBench::); - add_benchmark!(params, batches, pallet_balances, Balances); - add_benchmark!(params, batches, pallet_timestamp, Timestamp); - add_benchmark!(params, batches, pallet_dkg_proposal_handler, DKGProposalHandler); - add_benchmark!(params, batches, pallet_dkg_proposals, DKGProposals); - add_benchmark!(params, batches, pallet_dkg_metadata, DKG); - - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } - Ok(batches) - } + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + } + + fn authorities() -> Vec { + Aura::authorities().into_inner() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + opaque::SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + opaque::SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> GrandpaAuthorityList { + Grandpa::grandpa_authorities() + } + + fn current_set_id() -> fg_primitives::SetId { + Grandpa::current_set_id() + } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: fg_primitives::EquivocationProof< + ::Hash, + NumberFor, + >, + _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _set_id: fg_primitives::SetId, + _authority_id: GrandpaId, + ) -> Option { + // NOTE: this is the only implementation possible since we've + // defined our key owner proof type as a bottom type (i.e. a type + // with no values). + None + } + } + + impl dkg_runtime_primitives::DKGApi for Runtime { + fn authority_set() -> dkg_runtime_primitives::AuthoritySet { + let authorities = DKG::authorities(); + let authority_set_id = DKG::authority_set_id(); + + dkg_runtime_primitives::AuthoritySet { + authorities, + id: authority_set_id + } + } + + fn queued_authority_set() -> dkg_runtime_primitives::AuthoritySet { + let queued_authorities = DKG::next_authorities(); + let queued_authority_set_id = DKG::authority_set_id() + 1u64; + + dkg_runtime_primitives::AuthoritySet { + authorities: queued_authorities, + id: queued_authority_set_id + } + } + + fn signature_threshold() -> u16 { + DKG::signature_threshold() + } + + fn keygen_threshold() -> u16 { + DKG::keygen_threshold() + } + + fn next_signature_threshold() -> u16 { + DKG::next_signature_threshold() + } + + fn next_keygen_threshold() -> u16 { + DKG::next_keygen_threshold() + } + + fn should_refresh(block_number: BlockNumber) -> bool { + DKG::should_refresh(block_number) + } + + fn next_dkg_pub_key() -> Option<(dkg_runtime_primitives::AuthoritySetId, Vec)> { + DKG::next_dkg_public_key() + } + + fn next_pub_key_sig() -> Option> { + DKG::next_public_key_signature() + } + + fn dkg_pub_key() -> (dkg_runtime_primitives::AuthoritySetId, Vec) { + DKG::dkg_public_key() + } + + fn get_best_authorities() -> Vec<(u16, DKGId)> { + DKG::best_authorities() + } + + fn get_next_best_authorities() -> Vec<(u16, DKGId)> { + DKG::next_best_authorities() + } + + fn get_unsigned_proposals() -> Vec { + DKGProposalHandler::get_unsigned_proposals() + } + + fn get_max_extrinsic_delay(block_number: BlockNumber) -> BlockNumber { + DKG::max_extrinsic_delay(block_number) + } + + fn get_authority_accounts() -> (Vec, Vec) { + (DKG::current_authorities_accounts(), DKG::next_authorities_accounts()) + } + + fn get_reputations(authorities: Vec) -> Vec<(DKGId, Reputation)> { + authorities.iter().map(|a| (a.clone(), DKG::authority_reputations(a))).collect() + } + + fn get_keygen_jailed(set: Vec) -> Vec { + set.iter().filter(|a| pallet_dkg_metadata::JailedKeygenAuthorities::::contains_key(a)).cloned().collect() + } + + fn get_signing_jailed(set: Vec) -> Vec { + set.iter().filter(|a| pallet_dkg_metadata::JailedSigningAuthorities::::contains_key(a)).cloned().collect() + } + + fn refresh_nonce() -> u32 { + DKG::refresh_nonce() + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + use frame_system_benchmarking::Pallet as SystemBench; + + let mut list = Vec::::new(); + + list_benchmark!(list, extra, pallet_balances, Balances); + list_benchmark!(list, extra, frame_system, SystemBench::); + list_benchmark!(list, extra, pallet_timestamp, Timestamp); + list_benchmark!(list, extra, pallet_dkg_proposal_handler, DKGProposalHandler); + list_benchmark!(list, extra, pallet_dkg_proposals, DKGProposals); + list_benchmark!(list, extra, pallet_dkg_metadata, DKG); + + + let storage_info = AllPalletsWithSystem::storage_info(); + + (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; + use frame_support::traits::StorageInfoTrait; + + use frame_system_benchmarking::Pallet as SystemBench; + impl frame_system_benchmarking::Config for Runtime {} + + let whitelist: Vec = vec![ + // Block Number + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), + // Total Issuance + hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), + // Execution Phase + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), + // Event Count + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), + // System Events + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), + ]; + + let _storage_info = AllPalletsWithSystem::storage_info(); + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmark!(params, batches, frame_system, SystemBench::); + add_benchmark!(params, batches, pallet_balances, Balances); + add_benchmark!(params, batches, pallet_timestamp, Timestamp); + add_benchmark!(params, batches, pallet_dkg_proposal_handler, DKGProposalHandler); + add_benchmark!(params, batches, pallet_dkg_proposals, DKGProposals); + add_benchmark!(params, batches, pallet_dkg_metadata, DKG); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) } + } }