From ff5d56fb76d43d762a3db9365b4dfb40a8a93927 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 2 Aug 2021 12:47:33 +0200 Subject: [PATCH] cargo +nightly fmt (#3540) * cargo +nightly fmt * add cargo-fmt check to ci * update ci * fmt * fmt * skip macro * ignore bridges --- polkadot/.gitlab-ci.yml | 10 +- polkadot/bridges/modules/dispatch/src/lib.rs | 7 +- polkadot/cli/src/browser.rs | 12 +- polkadot/cli/src/cli.rs | 5 +- polkadot/cli/src/command.rs | 138 +- polkadot/cli/src/lib.rs | 4 +- polkadot/core-primitives/src/lib.rs | 10 +- polkadot/erasure-coding/src/lib.rs | 174 +- polkadot/node/client/src/lib.rs | 116 +- polkadot/node/collation-generation/src/lib.rs | 313 ++- .../node/collation-generation/src/tests.rs | 77 +- .../approval-voting/src/approval_checking.rs | 279 +- .../approval-voting/src/approval_db/v1/mod.rs | 87 +- .../src/approval_db/v1/tests.rs | 367 ++- .../node/core/approval-voting/src/backend.rs | 21 +- .../node/core/approval-voting/src/criteria.rs | 240 +- .../node/core/approval-voting/src/import.rs | 352 ++- polkadot/node/core/approval-voting/src/lib.rs | 1016 ++++---- .../core/approval-voting/src/old_tests.rs | 716 +++-- polkadot/node/core/approval-voting/src/ops.rs | 88 +- .../approval-voting/src/persisted_entries.rs | 81 +- .../node/core/approval-voting/src/tests.rs | 462 ++-- .../node/core/approval-voting/src/time.rs | 8 +- polkadot/node/core/av-store/src/lib.rs | 386 ++- polkadot/node/core/av-store/src/tests.rs | 357 +-- polkadot/node/core/backing/src/lib.rs | 495 ++-- polkadot/node/core/backing/src/tests.rs | 664 ++--- .../node/core/bitfield-signing/src/lib.rs | 88 +- .../node/core/bitfield-signing/src/tests.rs | 7 +- .../node/core/candidate-validation/src/lib.rs | 270 +- .../core/candidate-validation/src/tests.rs | 136 +- polkadot/node/core/chain-api/src/lib.rs | 87 +- polkadot/node/core/chain-api/src/tests.rs | 112 +- .../node/core/chain-selection/src/backend.rs | 29 +- .../core/chain-selection/src/db_backend/v1.rs | 290 +- polkadot/node/core/chain-selection/src/lib.rs | 149 +- .../node/core/chain-selection/src/tests.rs | 1048 +++----- .../node/core/chain-selection/src/tree.rs | 142 +- .../core/dispute-coordinator/src/backend.rs | 43 +- .../core/dispute-coordinator/src/db/v1.rs | 207 +- .../node/core/dispute-coordinator/src/lib.rs | 345 +-- .../core/dispute-coordinator/src/tests.rs | 2322 ++++++++--------- .../core/dispute-participation/src/lib.rs | 140 +- .../core/dispute-participation/src/tests.rs | 40 +- .../node/core/parachains-inherent/src/lib.rs | 35 +- polkadot/node/core/provisioner/src/lib.rs | 212 +- polkadot/node/core/provisioner/src/tests.rs | 132 +- polkadot/node/core/pvf/src/artifacts.rs | 36 +- polkadot/node/core/pvf/src/execute/mod.rs | 2 +- polkadot/node/core/pvf/src/execute/queue.rs | 108 +- polkadot/node/core/pvf/src/execute/worker.rs | 119 +- polkadot/node/core/pvf/src/executor_intf.rs | 12 +- polkadot/node/core/pvf/src/host.rs | 222 +- polkadot/node/core/pvf/src/lib.rs | 2 +- polkadot/node/core/pvf/src/prepare/mod.rs | 2 +- polkadot/node/core/pvf/src/prepare/pool.rs | 67 +- polkadot/node/core/pvf/src/prepare/queue.rs | 245 +- polkadot/node/core/pvf/src/prepare/worker.rs | 32 +- polkadot/node/core/pvf/src/testing.rs | 11 +- polkadot/node/core/pvf/src/worker_common.rs | 26 +- polkadot/node/core/pvf/tests/it/adder.rs | 35 +- polkadot/node/core/pvf/tests/it/main.rs | 22 +- .../node/core/pvf/tests/it/worker_common.rs | 10 +- polkadot/node/core/runtime-api/src/cache.rs | 156 +- polkadot/node/core/runtime-api/src/lib.rs | 129 +- polkadot/node/core/runtime-api/src/tests.rs | 274 +- polkadot/node/jaeger/src/lib.rs | 15 +- polkadot/node/jaeger/src/spans.rs | 28 +- polkadot/node/malus/src/lib.rs | 33 +- polkadot/node/malus/src/variant-a.rs | 9 +- polkadot/node/metered-channel/src/bounded.rs | 16 +- polkadot/node/metered-channel/src/lib.rs | 14 +- .../node/metered-channel/src/unbounded.rs | 15 +- polkadot/node/metrics/src/lib.rs | 32 +- .../network/approval-distribution/src/lib.rs | 499 ++-- .../approval-distribution/src/tests.rs | 255 +- .../availability-distribution/src/error.rs | 6 +- .../availability-distribution/src/lib.rs | 70 +- .../availability-distribution/src/metrics.rs | 12 +- .../src/pov_requester/mod.rs | 118 +- .../src/requester/fetch_task/mod.rs | 93 +- .../src/requester/fetch_task/tests.rs | 144 +- .../src/requester/mod.rs | 62 +- .../src/requester/session_cache.rs | 24 +- .../src/responder.rs | 44 +- .../src/tests/mock.rs | 98 +- .../src/tests/mod.rs | 33 +- .../src/tests/state.rs | 228 +- .../network/availability-recovery/src/lib.rs | 284 +- .../availability-recovery/src/tests.rs | 370 +-- .../network/bitfield-distribution/src/lib.rs | 366 ++- .../bitfield-distribution/src/tests.rs | 200 +- polkadot/node/network/bridge/src/lib.rs | 239 +- .../node/network/bridge/src/multiplexer.rs | 71 +- polkadot/node/network/bridge/src/network.rs | 60 +- polkadot/node/network/bridge/src/tests.rs | 826 +++--- .../network/bridge/src/validator_discovery.rs | 149 +- .../src/collator_side/mod.rs | 361 ++- .../src/collator_side/tests.rs | 385 ++- .../network/collator-protocol/src/error.rs | 6 +- .../node/network/collator-protocol/src/lib.rs | 44 +- .../src/validator_side/mod.rs | 458 ++-- .../src/validator_side/tests.rs | 537 ++-- .../network/dispute-distribution/src/error.rs | 10 +- .../network/dispute-distribution/src/lib.rs | 72 +- .../dispute-distribution/src/metrics.rs | 15 +- .../src/receiver/error.rs | 9 +- .../dispute-distribution/src/receiver/mod.rs | 202 +- .../dispute-distribution/src/sender/error.rs | 6 +- .../dispute-distribution/src/sender/mod.rs | 106 +- .../src/sender/send_task.rs | 78 +- .../dispute-distribution/src/tests/mock.rs | 58 +- .../dispute-distribution/src/tests/mod.rs | 870 +++--- .../node/network/gossip-support/src/lib.rs | 99 +- .../node/network/gossip-support/src/tests.rs | 54 +- .../protocol/src/authority_discovery.rs | 20 +- polkadot/node/network/protocol/src/lib.rs | 58 +- .../node/network/protocol/src/peer_set.rs | 7 +- .../node/network/protocol/src/reputation.rs | 5 +- .../protocol/src/request_response/mod.rs | 27 +- .../protocol/src/request_response/request.rs | 79 +- .../protocol/src/request_response/v1.rs | 24 +- .../statement-distribution/src/error.rs | 6 +- .../network/statement-distribution/src/lib.rs | 875 +++---- .../statement-distribution/src/requester.rs | 88 +- .../statement-distribution/src/responder.rs | 70 +- .../statement-distribution/src/tests.rs | 996 ++++--- .../overseer/all-subsystems-gen/src/lib.rs | 118 +- .../node/overseer/examples/minimal-example.rs | 116 +- .../overseer/overseer-gen/examples/dummy.rs | 20 +- .../proc-macro/src/impl_builder.rs | 6 +- .../proc-macro/src/impl_dispatch.rs | 2 +- .../proc-macro/src/impl_message_wrapper.rs | 34 +- .../overseer-gen/proc-macro/src/impl_misc.rs | 6 +- .../proc-macro/src/impl_overseer.rs | 3 +- .../overseer-gen/proc-macro/src/lib.rs | 32 +- .../overseer-gen/proc-macro/src/parse_attr.rs | 142 +- .../proc-macro/src/parse_struct.rs | 140 +- .../node/overseer/overseer-gen/src/lib.rs | 111 +- .../node/overseer/overseer-gen/src/tests.rs | 1 - polkadot/node/overseer/src/lib.rs | 241 +- polkadot/node/overseer/src/metrics.rs | 87 +- polkadot/node/overseer/src/subsystems.rs | 216 +- polkadot/node/overseer/src/tests.rs | 350 ++- polkadot/node/primitives/src/approval.rs | 27 +- .../node/primitives/src/disputes/message.rs | 68 +- polkadot/node/primitives/src/disputes/mod.rs | 43 +- polkadot/node/primitives/src/lib.rs | 27 +- polkadot/node/service/src/chain_spec.rs | 574 ++-- polkadot/node/service/src/grandpa_support.rs | 71 +- polkadot/node/service/src/lib.rs | 394 ++- polkadot/node/service/src/overseer.rs | 167 +- .../node/service/src/parachains_db/mod.rs | 42 +- .../node/service/src/parachains_db/upgrade.rs | 24 +- .../node/service/src/relay_chain_selection.rs | 171 +- polkadot/node/service/src/tests.rs | 143 +- .../node/subsystem-test-helpers/src/lib.rs | 129 +- .../node/subsystem-test-helpers/src/mock.rs | 8 +- polkadot/node/subsystem-types/src/errors.rs | 9 +- polkadot/node/subsystem-types/src/lib.rs | 13 +- polkadot/node/subsystem-types/src/messages.rs | 53 +- .../src/messages/network_bridge_event.rs | 35 +- .../src/determine_new_blocks.rs | 185 +- .../node/subsystem-util/src/error_handling.rs | 25 +- polkadot/node/subsystem-util/src/lib.rs | 221 +- .../src/rolling_session_window.rs | 178 +- .../node/subsystem-util/src/runtime/error.rs | 5 +- .../node/subsystem-util/src/runtime/mod.rs | 96 +- polkadot/node/subsystem-util/src/tests.rs | 96 +- polkadot/node/subsystem/src/lib.rs | 34 +- .../node/test/client/src/block_builder.rs | 71 +- polkadot/node/test/client/src/lib.rs | 23 +- .../test/polkadot-simnet/common/src/lib.rs | 245 +- .../test/polkadot-simnet/test/src/main.rs | 56 +- polkadot/node/test/service/src/chain_spec.rs | 28 +- polkadot/node/test/service/src/lib.rs | 113 +- .../node/test/service/tests/build-blocks.rs | 9 +- .../node/test/service/tests/call-function.rs | 6 +- polkadot/parachain/src/primitives.rs | 57 +- polkadot/parachain/src/wasm_api.rs | 4 +- .../parachain/test-parachains/adder/build.rs | 5 +- .../test-parachains/adder/collator/src/cli.rs | 12 +- .../test-parachains/adder/collator/src/lib.rs | 102 +- .../adder/collator/src/main.rs | 26 +- .../adder/collator/tests/integration.rs | 23 +- .../test-parachains/adder/src/lib.rs | 22 +- .../adder/src/wasm_validation.rs | 32 +- .../parachain/test-parachains/halt/build.rs | 5 +- .../parachain/test-parachains/halt/src/lib.rs | 17 +- polkadot/primitives/src/lib.rs | 1 - polkadot/primitives/src/v0.rs | 82 +- polkadot/primitives/src/v1/mod.rs | 178 +- polkadot/primitives/src/v1/signed.rs | 61 +- polkadot/rpc/src/lib.rs | 144 +- .../common/slot_range_helper/src/lib.rs | 8 +- polkadot/runtime/common/src/auctions.rs | 612 +++-- polkadot/runtime/common/src/claims.rs | 416 ++- polkadot/runtime/common/src/crowdloan.rs | 497 ++-- polkadot/runtime/common/src/elections.rs | 2 +- polkadot/runtime/common/src/impls.rs | 27 +- .../runtime/common/src/integration_tests.rs | 374 +-- polkadot/runtime/common/src/lib.rs | 102 +- polkadot/runtime/common/src/mock.rs | 36 +- .../runtime/common/src/paras_registrar.rs | 345 +-- .../runtime/common/src/paras_sudo_wrapper.rs | 38 +- polkadot/runtime/common/src/purchase.rs | 431 +-- polkadot/runtime/common/src/slot_range.rs | 11 +- polkadot/runtime/common/src/slots.rs | 24 +- polkadot/runtime/common/src/traits.rs | 16 +- polkadot/runtime/common/src/xcm_sender.rs | 12 +- polkadot/runtime/kusama/src/constants.rs | 18 +- polkadot/runtime/kusama/src/tests.rs | 79 +- .../kusama/src/weights/frame_system.rs | 14 +- polkadot/runtime/kusama/src/weights/mod.rs | 2 +- .../kusama/src/weights/pallet_balances.rs | 1 - .../kusama/src/weights/pallet_bounties.rs | 5 +- .../kusama/src/weights/pallet_collective.rs | 21 +- .../kusama/src/weights/pallet_democracy.rs | 49 +- .../pallet_election_provider_multi_phase.rs | 12 +- .../src/weights/pallet_elections_phragmen.rs | 18 +- .../runtime/kusama/src/weights/pallet_gilt.rs | 12 +- .../kusama/src/weights/pallet_identity.rs | 33 +- .../kusama/src/weights/pallet_im_online.rs | 3 +- .../kusama/src/weights/pallet_indices.rs | 1 - .../kusama/src/weights/pallet_membership.rs | 18 +- .../kusama/src/weights/pallet_multisig.rs | 21 +- .../kusama/src/weights/pallet_proxy.rs | 21 +- .../kusama/src/weights/pallet_scheduler.rs | 9 +- .../kusama/src/weights/pallet_session.rs | 1 - .../kusama/src/weights/pallet_staking.rs | 49 +- .../kusama/src/weights/pallet_timestamp.rs | 1 - .../runtime/kusama/src/weights/pallet_tips.rs | 11 +- .../kusama/src/weights/pallet_treasury.rs | 5 +- .../kusama/src/weights/pallet_utility.rs | 5 +- .../kusama/src/weights/pallet_vesting.rs | 13 +- .../src/weights/runtime_common_auctions.rs | 1 - .../src/weights/runtime_common_claims.rs | 1 - .../src/weights/runtime_common_crowdloan.rs | 5 +- .../weights/runtime_common_paras_registrar.rs | 1 - .../src/weights/runtime_common_slots.rs | 3 +- .../runtime/parachains/src/configuration.rs | 324 ++- polkadot/runtime/parachains/src/disputes.rs | 1727 ++++++------ polkadot/runtime/parachains/src/dmp.rs | 54 +- polkadot/runtime/parachains/src/hrmp.rs | 477 +--- polkadot/runtime/parachains/src/inclusion.rs | 1043 ++++---- .../runtime/parachains/src/initializer.rs | 86 +- polkadot/runtime/parachains/src/lib.rs | 14 +- polkadot/runtime/parachains/src/mock.rs | 44 +- polkadot/runtime/parachains/src/origin.rs | 9 +- polkadot/runtime/parachains/src/paras.rs | 434 +-- .../runtime/parachains/src/paras_inherent.rs | 129 +- .../runtime/parachains/src/reward_points.rs | 43 +- .../parachains/src/runtime_api_impl/v1.rs | 116 +- polkadot/runtime/parachains/src/scheduler.rs | 653 ++--- .../runtime/parachains/src/session_info.rs | 69 +- polkadot/runtime/parachains/src/shared.rs | 57 +- polkadot/runtime/parachains/src/ump.rs | 237 +- polkadot/runtime/parachains/src/util.rs | 5 +- polkadot/runtime/polkadot/src/constants.rs | 22 +- .../polkadot/src/weights/frame_system.rs | 14 +- polkadot/runtime/polkadot/src/weights/mod.rs | 6 +- .../polkadot/src/weights/pallet_balances.rs | 1 - .../polkadot/src/weights/pallet_bounties.rs | 5 +- .../polkadot/src/weights/pallet_collective.rs | 21 +- .../polkadot/src/weights/pallet_democracy.rs | 49 +- .../pallet_election_provider_multi_phase.rs | 10 +- .../src/weights/pallet_elections_phragmen.rs | 18 +- .../polkadot/src/weights/pallet_identity.rs | 33 +- .../polkadot/src/weights/pallet_im_online.rs | 3 +- .../polkadot/src/weights/pallet_indices.rs | 1 - .../polkadot/src/weights/pallet_membership.rs | 18 +- .../polkadot/src/weights/pallet_multisig.rs | 21 +- .../polkadot/src/weights/pallet_proxy.rs | 21 +- .../polkadot/src/weights/pallet_scheduler.rs | 9 +- .../polkadot/src/weights/pallet_session.rs | 1 - .../polkadot/src/weights/pallet_staking.rs | 49 +- .../polkadot/src/weights/pallet_timestamp.rs | 1 - .../polkadot/src/weights/pallet_tips.rs | 11 +- .../polkadot/src/weights/pallet_treasury.rs | 5 +- .../polkadot/src/weights/pallet_utility.rs | 5 +- .../polkadot/src/weights/pallet_vesting.rs | 13 +- .../src/weights/runtime_common_claims.rs | 1 - .../runtime/rococo/src/bridge_messages.rs | 115 +- polkadot/runtime/rococo/src/constants.rs | 18 +- polkadot/runtime/rococo/src/lib.rs | 275 +- .../runtime/rococo/src/validator_manager.rs | 11 +- .../runtime/test-runtime/src/constants.rs | 10 +- polkadot/runtime/test-runtime/src/lib.rs | 134 +- polkadot/runtime/westend/src/constants.rs | 18 +- polkadot/runtime/westend/src/tests.rs | 6 +- .../westend/src/weights/frame_system.rs | 14 +- .../westend/src/weights/pallet_balances.rs | 1 - .../pallet_election_provider_multi_phase.rs | 10 +- .../westend/src/weights/pallet_identity.rs | 33 +- .../westend/src/weights/pallet_im_online.rs | 3 +- .../westend/src/weights/pallet_indices.rs | 1 - .../westend/src/weights/pallet_multisig.rs | 21 +- .../westend/src/weights/pallet_proxy.rs | 21 +- .../westend/src/weights/pallet_scheduler.rs | 9 +- .../westend/src/weights/pallet_session.rs | 1 - .../westend/src/weights/pallet_staking.rs | 49 +- .../westend/src/weights/pallet_timestamp.rs | 1 - .../westend/src/weights/pallet_utility.rs | 5 +- .../westend/src/weights/pallet_vesting.rs | 13 +- .../src/weights/runtime_common_auctions.rs | 1 - .../src/weights/runtime_common_crowdloan.rs | 5 +- .../weights/runtime_common_paras_registrar.rs | 1 - .../src/weights/runtime_common_slots.rs | 3 +- polkadot/rustfmt.toml | 3 + polkadot/statement-table/src/generic.rs | 190 +- polkadot/statement-table/src/lib.rs | 6 +- polkadot/tests/common.rs | 6 +- polkadot/tests/purge_chain_works.rs | 6 +- .../tests/running_the_node_and_interrupt.rs | 9 +- polkadot/utils/staking-miner/src/dry_run.rs | 2 +- .../staking-miner/src/emergency_solution.rs | 4 +- polkadot/utils/staking-miner/src/main.rs | 27 +- polkadot/utils/staking-miner/src/monitor.rs | 2 +- polkadot/utils/staking-miner/src/signer.rs | 5 +- polkadot/xcm/pallet-xcm/src/lib.rs | 106 +- polkadot/xcm/src/double_encoded.rs | 41 +- polkadot/xcm/src/lib.rs | 6 +- polkadot/xcm/src/v0/junction.rs | 63 +- polkadot/xcm/src/v0/mod.rs | 111 +- polkadot/xcm/src/v0/multi_asset.rs | 192 +- polkadot/xcm/src/v0/multi_location.rs | 106 +- polkadot/xcm/src/v0/order.rs | 52 +- polkadot/xcm/src/v0/traits.rs | 2 +- polkadot/xcm/xcm-builder/src/barriers.rs | 27 +- .../xcm/xcm-builder/src/currency_adapter.rs | 92 +- .../xcm-builder/src/filter_asset_location.rs | 2 +- .../xcm/xcm-builder/src/fungibles_adapter.rs | 197 +- polkadot/xcm/xcm-builder/src/lib.rs | 19 +- .../xcm-builder/src/location_conversion.rs | 70 +- .../xcm/xcm-builder/src/matches_fungible.rs | 4 +- polkadot/xcm/xcm-builder/src/mock.rs | 120 +- .../xcm/xcm-builder/src/origin_conversion.rs | 159 +- polkadot/xcm/xcm-builder/src/tests.rs | 151 +- polkadot/xcm/xcm-builder/src/weight.rs | 120 +- polkadot/xcm/xcm-executor/src/assets.rs | 242 +- polkadot/xcm/xcm-executor/src/config.rs | 14 +- polkadot/xcm/xcm-executor/src/lib.rs | 115 +- .../xcm/xcm-executor/src/traits/conversion.rs | 32 +- .../src/traits/matches_fungibles.rs | 10 +- polkadot/xcm/xcm-executor/src/traits/mod.rs | 8 +- .../xcm-executor/src/traits/on_response.rs | 10 +- .../xcm-executor/src/traits/should_execute.rs | 4 +- .../xcm-executor/src/traits/transact_asset.rs | 57 +- .../xcm/xcm-executor/src/traits/weight.rs | 14 +- polkadot/xcm/xcm-simulator/src/lib.rs | 1 + 350 files changed, 20716 insertions(+), 21365 deletions(-) diff --git a/polkadot/.gitlab-ci.yml b/polkadot/.gitlab-ci.yml index 3a7d3853299..f3adf63e825 100644 --- a/polkadot/.gitlab-ci.yml +++ b/polkadot/.gitlab-ci.yml @@ -101,6 +101,14 @@ check-line-width: - ./scripts/gitlab/check_line_width.sh allow_failure: true +cargo-fmt: + stage: test + <<: *kubernetes-env + <<: *rules-pr-only + script: + - cargo +nightly fmt --all -- --check + allow_failure: true + test-deterministic-wasm: stage: test <<: *rules-test @@ -172,7 +180,7 @@ spellcheck: - cargo spellcheck --version # compare with the commit parent to the PR, given it's from a default branch - git fetch origin +${CI_DEFAULT_BRANCH}:${CI_DEFAULT_BRANCH} - - time cargo spellcheck check -vvv --cfg=scripts/gitlab/spellcheck.toml --checkers hunspell --code 1 + - time cargo spellcheck check -vvv --cfg=scripts/gitlab/spellcheck.toml --checkers hunspell --code 1 -r $(git diff --name-only ${CI_COMMIT_SHA} $(git merge-base ${CI_COMMIT_SHA} ${CI_DEFAULT_BRANCH})) allow_failure: true diff --git a/polkadot/bridges/modules/dispatch/src/lib.rs b/polkadot/bridges/modules/dispatch/src/lib.rs index 683dffcacf9..a540021f6df 100644 --- a/polkadot/bridges/modules/dispatch/src/lib.rs +++ b/polkadot/bridges/modules/dispatch/src/lib.rs @@ -397,7 +397,7 @@ mod tests { #![allow(clippy::from_over_into)] use super::*; - use frame_support::{parameter_types, weights::Weight, dispatch::GetDispatchInfo}; + use frame_support::{dispatch::GetDispatchInfo, parameter_types, weights::Weight}; use frame_system::{EventRecord, Phase}; use sp_core::H256; use sp_runtime::{ @@ -603,7 +603,10 @@ mod tests { let call_weight = call.get_dispatch_info().weight; let mut message = prepare_root_message(call); message.weight = 7; - assert!(call_weight != 7, "needed for test to actually trigger a weight mismatch"); + assert!( + call_weight != 7, + "needed for test to actually trigger a weight mismatch" + ); System::set_block_number(1); let result = Dispatch::dispatch(SOURCE_CHAIN_ID, TARGET_CHAIN_ID, id, Ok(message), |_, _| unreachable!()); diff --git a/polkadot/cli/src/browser.rs b/polkadot/cli/src/browser.rs index ad9b1bf947e..d85bf4fc310 100644 --- a/polkadot/cli/src/browser.rs +++ b/polkadot/cli/src/browser.rs @@ -24,12 +24,15 @@ pub fn start_client(chain_spec: String, log_level: String) -> Result Result> { +fn start_inner( + chain_spec: String, + log_directives: String, +) -> Result> { set_console_error_panic_hook(); init_logging(&log_directives)?; - let chain_spec = - service::PolkadotChainSpec::from_json_bytes(chain_spec.as_bytes().to_vec()).map_err(|e| format!("{:?}", e))?; + let chain_spec = service::PolkadotChainSpec::from_json_bytes(chain_spec.as_bytes().to_vec()) + .map_err(|e| format!("{:?}", e))?; let config = browser_configuration(chain_spec)?; info!("Polkadot browser node"); @@ -40,7 +43,8 @@ fn start_inner(chain_spec: String, log_directives: String) -> Result. -use log::info; -use service::{IdentifyVariant, self}; -use sc_cli::{SubstrateCli, RuntimeVersion, Role}; use crate::cli::{Cli, Subcommand}; use futures::future::TryFutureExt; +use log::info; +use sc_cli::{Role, RuntimeVersion, SubstrateCli}; +use service::{self, IdentifyVariant}; #[derive(thiserror::Error, Debug)] pub enum Error { @@ -51,28 +51,45 @@ fn get_exec_name() -> Option { } impl SubstrateCli for Cli { - fn impl_name() -> String { "Parity Polkadot".into() } + fn impl_name() -> String { + "Parity Polkadot".into() + } - fn impl_version() -> String { env!("SUBSTRATE_CLI_IMPL_VERSION").into() } + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() + } - fn description() -> String { env!("CARGO_PKG_DESCRIPTION").into() } + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() + } - fn author() -> String { env!("CARGO_PKG_AUTHORS").into() } + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() + } - fn support_url() -> String { "https://github.com/paritytech/polkadot/issues/new".into() } + fn support_url() -> String { + "https://github.com/paritytech/polkadot/issues/new".into() + } - fn copyright_start_year() -> i32 { 2017 } + fn copyright_start_year() -> i32 { + 2017 + } - fn executable_name() -> String { "polkadot".into() } + fn executable_name() -> String { + "polkadot".into() + } fn load_spec(&self, id: &str) -> std::result::Result, String> { let id = if id == "" { let n = get_exec_name().unwrap_or_default(); - ["polkadot", "kusama", "westend", "rococo"].iter() + ["polkadot", "kusama", "westend", "rococo"] + .iter() .cloned() .find(|&chain| n.starts_with(chain)) .unwrap_or("polkadot") - } else { id }; + } else { + id + }; Ok(match id { "kusama" => Box::new(service::chain_spec::kusama_config()?), #[cfg(feature = "kusama-native")] @@ -119,7 +136,8 @@ impl SubstrateCli for Cli { path => { let path = std::path::PathBuf::from(path); - let chain_spec = Box::new(service::PolkadotChainSpec::from_json_file(path.clone())?) as Box; + let chain_spec = Box::new(service::PolkadotChainSpec::from_json_file(path.clone())?) + as Box; // When `force_*` is given or the file name starts with the name of one of the known chains, // we use the chain spec for the specific chain. @@ -152,7 +170,11 @@ impl SubstrateCli for Cli { return &service::rococo_runtime::VERSION } - #[cfg(not(all(feature = "rococo-native", feature = "westend-native", feature = "kusama-native")))] + #[cfg(not(all( + feature = "rococo-native", + feature = "westend-native", + feature = "kusama-native" + )))] let _ = spec; &service::polkadot_runtime::VERSION @@ -193,8 +215,7 @@ pub fn run_node(cli: Cli, overseer_gen: impl service::OverseerGen) -> Result<()> } fn run_node_inner(cli: Cli, overseer_gen: impl service::OverseerGen) -> Result<()> { - let runner = cli.create_runner(&cli.run.base) - .map_err(Error::from)?; + let runner = cli.create_runner(&cli.run.base).map_err(Error::from)?; let chain_spec = &runner.config().chain_spec; set_default_ss58_version(chain_spec); @@ -220,7 +241,9 @@ fn run_node_inner(cli: Cli, overseer_gen: impl service::OverseerGen) -> Result<( match role { #[cfg(feature = "browser")] - Role::Light => service::build_light(config).map(|(task_manager, _)| task_manager).map_err(Into::into), + Role::Light => service::build_light(config) + .map(|(task_manager, _)| task_manager) + .map_err(Into::into), #[cfg(not(feature = "browser"))] Role::Light => Err(Error::Other("Light client not enabled".into())), _ => service::build_full( @@ -231,7 +254,9 @@ fn run_node_inner(cli: Cli, overseer_gen: impl service::OverseerGen) -> Result<( jaeger_agent, None, overseer_gen, - ).map(|full| full.task_manager).map_err(Into::into) + ) + .map(|full| full.task_manager) + .map_err(Into::into), } }) } @@ -244,19 +269,17 @@ pub fn run() -> Result<()> { None => run_node_inner(cli, service::RealOverseerGen), Some(Subcommand::BuildSpec(cmd)) => { let runner = cli.create_runner(cmd)?; - Ok(runner.sync_run(|config| { - cmd.run(config.chain_spec, config.network) - })?) + Ok(runner.sync_run(|config| cmd.run(config.chain_spec, config.network))?) }, Some(Subcommand::CheckBlock(cmd)) => { - let runner = cli.create_runner(cmd) - .map_err(Error::SubstrateCli)?; + let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?; let chain_spec = &runner.config().chain_spec; set_default_ss58_version(chain_spec); runner.async_run(|mut config| { - let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config, None)?; + let (client, _, import_queue, task_manager) = + service::new_chain_ops(&mut config, None)?; Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager)) }) }, @@ -267,8 +290,8 @@ pub fn run() -> Result<()> { set_default_ss58_version(chain_spec); Ok(runner.async_run(|mut config| { - let (client, _, _, task_manager) = service::new_chain_ops(&mut config, None) - .map_err(Error::PolkadotService)?; + let (client, _, _, task_manager) = + service::new_chain_ops(&mut config, None).map_err(Error::PolkadotService)?; Ok((cmd.run(client, config.database).map_err(Error::SubstrateCli), task_manager)) })?) }, @@ -290,7 +313,8 @@ pub fn run() -> Result<()> { set_default_ss58_version(chain_spec); Ok(runner.async_run(|mut config| { - let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config, None)?; + let (client, _, import_queue, task_manager) = + service::new_chain_ops(&mut config, None)?; Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager)) })?) }, @@ -316,9 +340,10 @@ pub fn run() -> Result<()> { #[cfg(any(target_os = "android", feature = "browser"))] { - return Err( - sc_cli::Error::Input("PVF preparation workers are not supported under this platform".into()).into() - ); + return Err(sc_cli::Error::Input( + "PVF preparation workers are not supported under this platform".into(), + ) + .into()) } #[cfg(not(any(target_os = "android", feature = "browser")))] @@ -334,9 +359,10 @@ pub fn run() -> Result<()> { #[cfg(any(target_os = "android", feature = "browser"))] { - return Err( - sc_cli::Error::Input("PVF execution workers are not supported under this platform".into()).into() - ); + return Err(sc_cli::Error::Input( + "PVF execution workers are not supported under this platform".into(), + ) + .into()) } #[cfg(not(any(target_os = "android", feature = "browser")))] @@ -383,45 +409,51 @@ pub fn run() -> Result<()> { use sc_service::TaskManager; let registry = &runner.config().prometheus_config.as_ref().map(|cfg| &cfg.registry); - let task_manager = TaskManager::new( - runner.config().task_executor.clone(), - *registry, - ).map_err(|e| Error::SubstrateService(sc_service::Error::Prometheus(e)))?; + let task_manager = + TaskManager::new(runner.config().task_executor.clone(), *registry) + .map_err(|e| Error::SubstrateService(sc_service::Error::Prometheus(e)))?; ensure_dev(chain_spec).map_err(Error::Other)?; #[cfg(feature = "kusama-native")] if chain_spec.is_kusama() { return runner.async_run(|config| { - Ok((cmd.run::< - service::kusama_runtime::Block, - service::KusamaExecutor, - >(config).map_err(Error::SubstrateCli), task_manager)) + Ok(( + cmd.run::(config) + .map_err(Error::SubstrateCli), + task_manager, + )) }) } #[cfg(feature = "westend-native")] if chain_spec.is_westend() { return runner.async_run(|config| { - Ok((cmd.run::< - service::westend_runtime::Block, - service::WestendExecutor, - >(config).map_err(Error::SubstrateCli), task_manager)) + Ok(( + cmd.run::( + config, + ) + .map_err(Error::SubstrateCli), + task_manager, + )) }) } // else we assume it is polkadot. runner.async_run(|config| { - Ok((cmd.run::< - service::polkadot_runtime::Block, - service::PolkadotExecutor, - >(config).map_err(Error::SubstrateCli), task_manager)) + Ok(( + cmd.run::(config) + .map_err(Error::SubstrateCli), + task_manager, + )) }) }, #[cfg(not(feature = "try-runtime"))] - Some(Subcommand::TryRuntime) => { - Err(Error::Other("TryRuntime wasn't enabled when building the node. \ - You can enable it with `--features try-runtime`.".into()).into()) - }, + Some(Subcommand::TryRuntime) => Err(Error::Other( + "TryRuntime wasn't enabled when building the node. \ + You can enable it with `--features try-runtime`." + .into(), + ) + .into()), }?; Ok(()) } diff --git a/polkadot/cli/src/lib.rs b/polkadot/cli/src/lib.rs index 02120081ee5..cacd9abf992 100644 --- a/polkadot/cli/src/lib.rs +++ b/polkadot/cli/src/lib.rs @@ -26,9 +26,7 @@ mod cli; mod command; pub use service::{ - self, - ProvideRuntimeApi, CoreApi, IdentifyVariant, - Block, RuntimeApiCollection, TFullClient, + self, Block, CoreApi, IdentifyVariant, ProvideRuntimeApi, RuntimeApiCollection, TFullClient, }; #[cfg(feature = "malus")] diff --git a/polkadot/core-primitives/src/lib.rs b/polkadot/core-primitives/src/lib.rs index e4efb825e01..b5b526d7e05 100644 --- a/polkadot/core-primitives/src/lib.rs +++ b/polkadot/core-primitives/src/lib.rs @@ -20,10 +20,14 @@ //! //! These core Polkadot types are used by the relay chain and the Parachains. -use sp_runtime::{generic, MultiSignature, traits::{Verify, IdentifyAccount}}; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; #[cfg(feature = "std")] use parity_util_mem::MallocSizeOf; +use sp_runtime::{ + generic, + traits::{IdentifyAccount, Verify}, + MultiSignature, +}; pub use sp_runtime::traits::{BlakeTwo256, Hash as HashT}; @@ -64,7 +68,7 @@ pub type Hash = sp_core::H256; #[cfg_attr(feature = "std", derive(MallocSizeOf))] pub struct CandidateHash(pub Hash); -#[cfg(feature="std")] +#[cfg(feature = "std")] impl std::fmt::Display for CandidateHash { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) diff --git a/polkadot/erasure-coding/src/lib.rs b/polkadot/erasure-coding/src/lib.rs index 16610ba812d..3c8dd35077b 100644 --- a/polkadot/erasure-coding/src/lib.rs +++ b/polkadot/erasure-coding/src/lib.rs @@ -24,15 +24,17 @@ //! f is the maximum number of faulty validators in the system. //! The data is coded so any f+1 chunks can be used to reconstruct the full data. -use parity_scale_codec::{Encode, Decode}; -use polkadot_primitives::v0::{self, Hash as H256, BlakeTwo256, HashT}; +use parity_scale_codec::{Decode, Encode}; use polkadot_node_primitives::AvailableData; +use polkadot_primitives::v0::{self, BlakeTwo256, Hash as H256, HashT}; use sp_core::Blake2Hasher; -use trie::{EMPTY_PREFIX, MemoryDB, Trie, TrieMut, trie_types::{TrieDBMut, TrieDB}}; use thiserror::Error; +use trie::{ + trie_types::{TrieDB, TrieDBMut}, + MemoryDB, Trie, TrieMut, EMPTY_PREFIX, +}; -use novelpoly::WrappedShard; -use novelpoly::CodeParams; +use novelpoly::{CodeParams, WrappedShard}; // we are limited to the field order of GF(2^16), which is 65536 const MAX_VALIDATORS: usize = novelpoly::f2e16::FIELD_SIZE; @@ -63,7 +65,7 @@ pub enum Error { UnevenLength, /// Chunk index out of bounds. #[error("Chunk is out of bounds: {chunk_index} not included in 0..{n_validators}")] - ChunkIndexOutOfBounds{ chunk_index: usize, n_validators: usize }, + ChunkIndexOutOfBounds { chunk_index: usize, n_validators: usize }, /// Bad payload in reconstructed bytes. #[error("Reconstructed payload invalid")] BadPayload, @@ -83,8 +85,12 @@ pub enum Error { /// Obtain a threshold of chunks that should be enough to recover the data. pub const fn recovery_threshold(n_validators: usize) -> Result { - if n_validators > MAX_VALIDATORS { return Err(Error::TooManyValidators) } - if n_validators <= 1 { return Err(Error::NotEnoughValidators) } + if n_validators > MAX_VALIDATORS { + return Err(Error::TooManyValidators) + } + if n_validators <= 1 { + return Err(Error::NotEnoughValidators) + } let needed = n_validators.saturating_sub(1) / 3; Ok(needed + 1) @@ -97,51 +103,47 @@ fn code_params(n_validators: usize) -> Result { let k_wanted = recovery_threshold(n_wanted)?; if n_wanted > MAX_VALIDATORS as usize { - return Err(Error::TooManyValidators); + return Err(Error::TooManyValidators) } - CodeParams::derive_parameters(n_wanted, k_wanted) - .map_err(|e| { - match e { - novelpoly::Error::WantedShardCountTooHigh(_) => Error::TooManyValidators, - novelpoly::Error::WantedShardCountTooLow(_) => Error::NotEnoughValidators, - _ => Error::UnknownCodeParam, - } - }) + CodeParams::derive_parameters(n_wanted, k_wanted).map_err(|e| match e { + novelpoly::Error::WantedShardCountTooHigh(_) => Error::TooManyValidators, + novelpoly::Error::WantedShardCountTooLow(_) => Error::NotEnoughValidators, + _ => Error::UnknownCodeParam, + }) } /// Obtain erasure-coded chunks for v0 `AvailableData`, one for each validator. /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. -pub fn obtain_chunks_v0(n_validators: usize, data: &v0::AvailableData) - -> Result>, Error> -{ +pub fn obtain_chunks_v0( + n_validators: usize, + data: &v0::AvailableData, +) -> Result>, Error> { obtain_chunks(n_validators, data) } /// Obtain erasure-coded chunks for v1 `AvailableData`, one for each validator. /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. -pub fn obtain_chunks_v1(n_validators: usize, data: &AvailableData) - -> Result>, Error> -{ +pub fn obtain_chunks_v1(n_validators: usize, data: &AvailableData) -> Result>, Error> { obtain_chunks(n_validators, data) } /// Obtain erasure-coded chunks, one for each validator. /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. -fn obtain_chunks(n_validators: usize, data: &T) - -> Result>, Error> -{ +fn obtain_chunks(n_validators: usize, data: &T) -> Result>, Error> { let params = code_params(n_validators)?; let encoded = data.encode(); if encoded.is_empty() { - return Err(Error::BadPayload); + return Err(Error::BadPayload) } - let shards = params.make_encoder().encode::(&encoded[..]) + let shards = params + .make_encoder() + .encode::(&encoded[..]) .expect("Payload non-empty, shard sizes are uniform, and validator numbers checked; qed"); Ok(shards.into_iter().map(|w: WrappedShard| w.into_inner()).collect()) @@ -154,9 +156,9 @@ fn obtain_chunks(n_validators: usize, data: &T) /// are provided, recovery is not possible. /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. -pub fn reconstruct_v0<'a, I: 'a>(n_validators: usize, chunks: I) - -> Result - where I: IntoIterator +pub fn reconstruct_v0<'a, I: 'a>(n_validators: usize, chunks: I) -> Result +where + I: IntoIterator, { reconstruct(n_validators, chunks) } @@ -168,9 +170,9 @@ pub fn reconstruct_v0<'a, I: 'a>(n_validators: usize, chunks: I) /// are provided, recovery is not possible. /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. -pub fn reconstruct_v1<'a, I: 'a>(n_validators: usize, chunks: I) - -> Result - where I: IntoIterator +pub fn reconstruct_v1<'a, I: 'a>(n_validators: usize, chunks: I) -> Result +where + I: IntoIterator, { reconstruct(n_validators, chunks) } @@ -183,42 +185,43 @@ pub fn reconstruct_v1<'a, I: 'a>(n_validators: usize, chunks: I) /// /// Works only up to 65536 validators, and `n_validators` must be non-zero. fn reconstruct<'a, I: 'a, T: Decode>(n_validators: usize, chunks: I) -> Result - where I: IntoIterator +where + I: IntoIterator, { let params = code_params(n_validators)?; let mut received_shards: Vec> = vec![None; n_validators]; let mut shard_len = None; for (chunk_data, chunk_idx) in chunks.into_iter().take(n_validators) { if chunk_idx >= n_validators { - return Err(Error::ChunkIndexOutOfBounds{ chunk_index: chunk_idx, n_validators }); + return Err(Error::ChunkIndexOutOfBounds { chunk_index: chunk_idx, n_validators }) } let shard_len = shard_len.get_or_insert_with(|| chunk_data.len()); if *shard_len % 2 != 0 { - return Err(Error::UnevenLength); + return Err(Error::UnevenLength) } if *shard_len != chunk_data.len() || *shard_len == 0 { - return Err(Error::NonUniformChunks); + return Err(Error::NonUniformChunks) } received_shards[chunk_idx] = Some(WrappedShard::new(chunk_data.to_vec())); } - let res = params.make_encoder().reconstruct(received_shards); - let payload_bytes= match res { + let payload_bytes = match res { Err(e) => match e { novelpoly::Error::NeedMoreShards { .. } => return Err(Error::NotEnoughChunks), novelpoly::Error::ParamterMustBePowerOf2 { .. } => return Err(Error::UnevenLength), novelpoly::Error::WantedShardCountTooHigh(_) => return Err(Error::TooManyValidators), novelpoly::Error::WantedShardCountTooLow(_) => return Err(Error::NotEnoughValidators), novelpoly::Error::PayloadSizeIsZero { .. } => return Err(Error::BadPayload), - novelpoly::Error::InconsistentShardLengths { .. } => return Err(Error::NonUniformChunks), + novelpoly::Error::InconsistentShardLengths { .. } => + return Err(Error::NonUniformChunks), _ => return Err(Error::UnknownReconstruction), - } + }, Ok(payload_bytes) => payload_bytes, }; @@ -236,7 +239,9 @@ pub struct Branches<'a, I> { impl<'a, I: AsRef<[u8]>> Branches<'a, I> { /// Get the trie root. - pub fn root(&self) -> H256 { self.root.clone() } + pub fn root(&self) -> H256 { + self.root.clone() + } } impl<'a, I: AsRef<[u8]>> Iterator for Branches<'a, I> { @@ -249,19 +254,18 @@ impl<'a, I: AsRef<[u8]>> Iterator for Branches<'a, I> { .expect("`Branches` is only created with a valid memorydb that contains all nodes for the trie with given root; qed"); let mut recorder = Recorder::new(); - let res = (self.current_pos as u32).using_encoded(|s| - trie.get_with(s, &mut recorder) - ); + let res = (self.current_pos as u32).using_encoded(|s| trie.get_with(s, &mut recorder)); match res.expect("all nodes in trie present; qed") { Some(_) => { let nodes = recorder.drain().into_iter().map(|r| r.data).collect(); - let chunk = self.chunks.get(self.current_pos) - .expect("there is a one-to-one mapping of chunks to valid merkle branches; qed"); + let chunk = self.chunks.get(self.current_pos).expect( + "there is a one-to-one mapping of chunks to valid merkle branches; qed", + ); self.current_pos += 1; Some((nodes, chunk.as_ref())) - } + }, None => None, } } @@ -270,7 +274,8 @@ impl<'a, I: AsRef<[u8]>> Iterator for Branches<'a, I> { /// Construct a trie from chunks of an erasure-coded value. This returns the root hash and an /// iterator of merkle proofs, one for each validator. pub fn branches<'a, I: 'a>(chunks: &'a [I]) -> Branches<'a, I> - where I: AsRef<[u8]>, +where + I: AsRef<[u8]>, { let mut trie_storage: MemoryDB = MemoryDB::default(); let mut root = H256::default(); @@ -287,12 +292,7 @@ pub fn branches<'a, I: 'a>(chunks: &'a [I]) -> Branches<'a, I> } } - Branches { - trie_storage, - root, - chunks, - current_pos: 0, - } + Branches { trie_storage, root, chunks, current_pos: 0 } } /// Verify a merkle branch, yielding the chunk hash meant to be present at that @@ -304,9 +304,9 @@ pub fn branch_hash(root: &H256, branch_nodes: &[Vec], index: usize) -> Resul } let trie = TrieDB::new(&trie_storage, &root).map_err(|_| Error::InvalidBranchProof)?; - let res = (index as u32).using_encoded(|key| + let res = (index as u32).using_encoded(|key| { trie.get_with(key, |raw_hash: &[u8]| H256::decode(&mut &raw_hash[..])) - ); + }); match res { Ok(Some(Ok(hash))) => Ok(hash), @@ -323,7 +323,7 @@ struct ShardInput<'a, I> { cur_shard: Option<(&'a [u8], usize)>, } -impl<'a, I: Iterator> parity_scale_codec::Input for ShardInput<'a, I> { +impl<'a, I: Iterator> parity_scale_codec::Input for ShardInput<'a, I> { fn remaining_len(&mut self) -> Result, parity_scale_codec::Error> { Ok(Some(self.remaining_len)) } @@ -332,7 +332,9 @@ impl<'a, I: Iterator> parity_scale_codec::Input for ShardInput<'a let mut read_bytes = 0; loop { - if read_bytes == into.len() { break } + if read_bytes == into.len() { + break + } let cur_shard = self.cur_shard.take().or_else(|| self.shards.next().map(|s| (s, 0))); let (active_shard, mut in_shard) = match cur_shard { @@ -341,15 +343,14 @@ impl<'a, I: Iterator> parity_scale_codec::Input for ShardInput<'a }; if in_shard >= active_shard.len() { - continue; + continue } let remaining_len_out = into.len() - read_bytes; let remaining_len_shard = active_shard.len() - in_shard; let write_len = std::cmp::min(remaining_len_out, remaining_len_shard); - into[read_bytes..][..write_len] - .copy_from_slice(&active_shard[in_shard..][..write_len]); + into[read_bytes..][..write_len].copy_from_slice(&active_shard[in_shard..][..write_len]); in_shard += write_len; read_bytes += write_len; @@ -377,59 +378,38 @@ mod tests { #[test] fn round_trip_works() { - let pov_block = PoVBlock { - block_data: BlockData((0..255).collect()), - }; - - let available_data = AvailableData { - pov_block, - omitted_validation: Default::default(), - }; - let chunks = obtain_chunks( - 10, - &available_data, - ).unwrap(); + let pov_block = PoVBlock { block_data: BlockData((0..255).collect()) }; + + let available_data = AvailableData { pov_block, omitted_validation: Default::default() }; + let chunks = obtain_chunks(10, &available_data).unwrap(); assert_eq!(chunks.len(), 10); // any 4 chunks should work. let reconstructed: AvailableData = reconstruct( 10, - [ - (&*chunks[1], 1), - (&*chunks[4], 4), - (&*chunks[6], 6), - (&*chunks[9], 9), - ].iter().cloned(), - ).unwrap(); + [(&*chunks[1], 1), (&*chunks[4], 4), (&*chunks[6], 6), (&*chunks[9], 9)] + .iter() + .cloned(), + ) + .unwrap(); assert_eq!(reconstructed, available_data); } #[test] fn reconstruct_does_not_panic_on_low_validator_count() { - let reconstructed = reconstruct_v1( - 1, - [].iter().cloned(), - ); + let reconstructed = reconstruct_v1(1, [].iter().cloned()); assert_eq!(reconstructed, Err(Error::NotEnoughValidators)); } #[test] fn construct_valid_branches() { - let pov_block = PoVBlock { - block_data: BlockData(vec![2; 256]), - }; + let pov_block = PoVBlock { block_data: BlockData(vec![2; 256]) }; - let available_data = AvailableData { - pov_block, - omitted_validation: Default::default(), - }; + let available_data = AvailableData { pov_block, omitted_validation: Default::default() }; - let chunks = obtain_chunks( - 10, - &available_data, - ).unwrap(); + let chunks = obtain_chunks(10, &available_data).unwrap(); assert_eq!(chunks.len(), 10); diff --git a/polkadot/node/client/src/lib.rs b/polkadot/node/client/src/lib.rs index 9aa522788a9..d71eb950277 100644 --- a/polkadot/node/client/src/lib.rs +++ b/polkadot/node/client/src/lib.rs @@ -19,17 +19,21 @@ //! Provides the [`AbstractClient`] trait that is a super trait that combines all the traits the client implements. //! There is also the [`Client`] enum that combines all the different clients into one common structure. -use std::sync::Arc; -use sp_api::{ProvideRuntimeApi, CallApiAt, NumberFor}; +use polkadot_primitives::v1::{ + AccountId, Balance, Block, BlockNumber, Hash, Header, Nonce, ParachainHost, +}; +use sc_client_api::{AuxStore, Backend as BackendT, BlockchainEvents, KeyIterator, UsageProvider}; +use sc_executor::native_executor_instance; +use sp_api::{CallApiAt, NumberFor, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; +use sp_consensus::BlockStatus; use sp_runtime::{ - Justifications, generic::{BlockId, SignedBlock}, traits::{Block as BlockT, BlakeTwo256}, + generic::{BlockId, SignedBlock}, + traits::{BlakeTwo256, Block as BlockT}, + Justifications, }; -use sc_client_api::{Backend as BackendT, BlockchainEvents, KeyIterator, AuxStore, UsageProvider}; -use sp_storage::{StorageData, StorageKey, ChildInfo, PrefixedStorageKey}; -use polkadot_primitives::v1::{Block, ParachainHost, AccountId, Nonce, Balance, Header, BlockNumber, Hash}; -use sp_consensus::BlockStatus; -use sc_executor::native_executor_instance; +use sp_storage::{ChildInfo, PrefixedStorageKey, StorageData, StorageKey}; +use std::sync::Arc; pub type FullBackend = sc_service::TFullBackend; @@ -84,7 +88,8 @@ pub trait RuntimeApiCollection: + beefy_primitives::BeefyApi where >::StateBackend: sp_api::StateBackend, -{} +{ +} impl RuntimeApiCollection for Api where @@ -103,47 +108,47 @@ where + sp_authority_discovery::AuthorityDiscoveryApi + beefy_primitives::BeefyApi, >::StateBackend: sp_api::StateBackend, -{} +{ +} /// Trait that abstracts over all available client implementations. /// /// For a concrete type there exists [`Client`]. pub trait AbstractClient: - BlockchainEvents + Sized + Send + Sync + BlockchainEvents + + Sized + + Send + + Sync + ProvideRuntimeApi + HeaderBackend - + CallApiAt< - Block, - StateBackend = Backend::State - > + + CallApiAt + AuxStore + UsageProvider - where - Block: BlockT, - Backend: BackendT, - Backend::State: sp_api::StateBackend, - Self::Api: RuntimeApiCollection, -{} +where + Block: BlockT, + Backend: BackendT, + Backend::State: sp_api::StateBackend, + Self::Api: RuntimeApiCollection, +{ +} impl AbstractClient for Client - where - Block: BlockT, - Backend: BackendT, - Backend::State: sp_api::StateBackend, - Client: BlockchainEvents - + ProvideRuntimeApi - + HeaderBackend - + AuxStore - + UsageProvider - + Sized - + Send - + Sync - + CallApiAt< - Block, - StateBackend = Backend::State - >, - Client::Api: RuntimeApiCollection, -{} +where + Block: BlockT, + Backend: BackendT, + Backend::State: sp_api::StateBackend, + Client: BlockchainEvents + + ProvideRuntimeApi + + HeaderBackend + + AuxStore + + UsageProvider + + Sized + + Send + + Sync + + CallApiAt, + Client::Api: RuntimeApiCollection, +{ +} /// Execute something with the client instance. /// @@ -162,12 +167,12 @@ pub trait ExecuteWithClient { /// Execute whatever should be executed with the given client instance. fn execute_with_client(self, client: Arc) -> Self::Output - where - >::StateBackend: sp_api::StateBackend, - Backend: sc_client_api::Backend + 'static, - Backend::State: sp_api::StateBackend, - Api: crate::RuntimeApiCollection, - Client: AbstractClient + 'static; + where + >::StateBackend: sp_api::StateBackend, + Backend: sc_client_api::Backend + 'static, + Backend::State: sp_api::StateBackend, + Api: crate::RuntimeApiCollection, + Client: AbstractClient + 'static; } /// A handle to a Polkadot client instance. @@ -244,7 +249,7 @@ impl UsageProvider for Client { impl sc_client_api::BlockBackend for Client { fn block_body( &self, - id: &BlockId + id: &BlockId, ) -> sp_blockchain::Result::Extrinsic>>> { with_client! { self, @@ -275,10 +280,7 @@ impl sc_client_api::BlockBackend for Client { } } - fn justifications( - &self, - id: &BlockId - ) -> sp_blockchain::Result> { + fn justifications(&self, id: &BlockId) -> sp_blockchain::Result> { with_client! { self, client, @@ -290,7 +292,7 @@ impl sc_client_api::BlockBackend for Client { fn block_hash( &self, - number: NumberFor + number: NumberFor, ) -> sp_blockchain::Result::Hash>> { with_client! { self, @@ -303,7 +305,7 @@ impl sc_client_api::BlockBackend for Client { fn indexed_transaction( &self, - id: &::Hash + id: &::Hash, ) -> sp_blockchain::Result>> { with_client! { self, @@ -316,7 +318,7 @@ impl sc_client_api::BlockBackend for Client { fn block_indexed_body( &self, - id: &BlockId + id: &BlockId, ) -> sp_blockchain::Result>>> { with_client! { self, @@ -390,7 +392,9 @@ impl sc_client_api::StorageProvider for Client { id: &BlockId, prefix: Option<&'a StorageKey>, start_key: Option<&StorageKey>, - ) -> sp_blockchain::Result>::State, Block>> { + ) -> sp_blockchain::Result< + KeyIterator<'a, >::State, Block>, + > { with_client! { self, client, @@ -436,7 +440,9 @@ impl sc_client_api::StorageProvider for Client { child_info: ChildInfo, prefix: Option<&'a StorageKey>, start_key: Option<&StorageKey>, - ) -> sp_blockchain::Result>::State, Block>> { + ) -> sp_blockchain::Result< + KeyIterator<'a, >::State, Block>, + > { with_client! { self, client, diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs index 16f991eb54d..c4b73b8b717 100644 --- a/polkadot/node/collation-generation/src/lib.rs +++ b/polkadot/node/collation-generation/src/lib.rs @@ -18,35 +18,23 @@ #![deny(missing_docs)] -use futures::{ - channel::mpsc, - future::FutureExt, - join, - select, - sink::SinkExt, - stream::StreamExt, -}; -use polkadot_node_primitives::{ - CollationGenerationConfig, AvailableData, PoV, -}; +use futures::{channel::mpsc, future::FutureExt, join, select, sink::SinkExt, stream::StreamExt}; +use parity_scale_codec::Encode; +use polkadot_node_primitives::{AvailableData, CollationGenerationConfig, PoV}; use polkadot_node_subsystem::{ - ActiveLeavesUpdate, messages::{AllMessages, CollationGenerationMessage, CollatorProtocolMessage}, - SpawnedSubsystem, SubsystemContext, SubsystemResult, - SubsystemError, FromOverseer, OverseerSignal, - overseer, + overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, + SubsystemError, SubsystemResult, }; use polkadot_node_subsystem_util::{ - request_availability_cores, request_persisted_validation_data, - request_validators, request_validation_code, metrics::{self, prometheus}, + request_availability_cores, request_persisted_validation_data, request_validation_code, + request_validators, }; use polkadot_primitives::v1::{ - collator_signature_payload, CandidateCommitments, - CandidateDescriptor, CandidateReceipt, CoreState, Hash, OccupiedCoreAssumption, - PersistedValidationData, + collator_signature_payload, CandidateCommitments, CandidateDescriptor, CandidateReceipt, + CoreState, Hash, OccupiedCoreAssumption, PersistedValidationData, }; -use parity_scale_codec::Encode; use sp_core::crypto::Pair; use std::sync::Arc; @@ -66,10 +54,7 @@ pub struct CollationGenerationSubsystem { impl CollationGenerationSubsystem { /// Create a new instance of the `CollationGenerationSubsystem`. pub fn new(metrics: Metrics) -> Self { - Self { - config: None, - metrics, - } + Self { config: None, metrics } } /// Run this subsystem @@ -127,7 +112,10 @@ impl CollationGenerationSubsystem { Context: overseer::SubsystemContext, { match incoming { - Ok(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { activated, .. }))) => { + Ok(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + .. + }))) => { // follow the procedure from the guide if let Some(config) = &self.config { let metrics = self.metrics.clone(); @@ -137,13 +125,15 @@ impl CollationGenerationSubsystem { ctx, metrics, sender, - ).await { + ) + .await + { tracing::warn!(target: LOG_TARGET, err = ?err, "failed to handle new activations"); } } false - } + }, Ok(FromOverseer::Signal(OverseerSignal::Conclude)) => true, Ok(FromOverseer::Communication { msg: CollationGenerationMessage::Initialize(config), @@ -154,7 +144,7 @@ impl CollationGenerationSubsystem { self.config = Some(Arc::new(config)); } false - } + }, Ok(FromOverseer::Signal(OverseerSignal::BlockFinalized(..))) => false, Err(err) => { tracing::error!( @@ -164,7 +154,7 @@ impl CollationGenerationSubsystem { err ); true - } + }, } } } @@ -178,12 +168,10 @@ where let future = async move { self.run(ctx).await; Ok(()) - }.boxed(); - - SpawnedSubsystem { - name: "collation-generation-subsystem", - future, } + .boxed(); + + SpawnedSubsystem { name: "collation-generation-subsystem", future } } } @@ -214,9 +202,8 @@ async fn handle_new_activations( let _availability_core_timer = metrics.time_new_activations_availability_core(); let (scheduled_core, assumption) = match core { - CoreState::Scheduled(scheduled_core) => { - (scheduled_core, OccupiedCoreAssumption::Free) - } + CoreState::Scheduled(scheduled_core) => + (scheduled_core, OccupiedCoreAssumption::Free), CoreState::Occupied(_occupied_core) => { // TODO: https://github.com/paritytech/polkadot/issues/1573 tracing::trace!( @@ -225,8 +212,8 @@ async fn handle_new_activations( relay_parent = ?relay_parent, "core is occupied. Keep going.", ); - continue; - } + continue + }, CoreState::Free => { tracing::trace!( target: LOG_TARGET, @@ -234,7 +221,7 @@ async fn handle_new_activations( "core is free. Keep going.", ); continue - } + }, }; if scheduled_core.para_id != config.para_id { @@ -246,7 +233,7 @@ async fn handle_new_activations( their_para = %scheduled_core.para_id, "core is not assigned to our para. Keep going.", ); - continue; + continue } // we get validation data and validation code synchronously for each core instead of @@ -273,7 +260,7 @@ async fn handle_new_activations( "validation data is not available", ); continue - } + }, }; let validation_code = match request_validation_code( @@ -296,125 +283,131 @@ async fn handle_new_activations( "validation code is not available", ); continue - } + }, }; let validation_code_hash = validation_code.hash(); let task_config = config.clone(); let mut task_sender = sender.clone(); let metrics = metrics.clone(); - ctx.spawn("collation generation collation builder", Box::pin(async move { - let persisted_validation_data_hash = validation_data.hash(); - - let (collation, result_sender) = match (task_config.collator)(relay_parent, &validation_data).await { - Some(collation) => collation.into_inner(), - None => { - tracing::debug!( - target: LOG_TARGET, - para_id = %scheduled_core.para_id, - "collator returned no collation on collate", - ); - return - } - }; - - // Apply compression to the block data. - let pov = { - let pov = polkadot_node_primitives::maybe_compress_pov(collation.proof_of_validity); - let encoded_size = pov.encoded_size(); - - // As long as `POV_BOMB_LIMIT` is at least `max_pov_size`, this ensures - // that honest collators never produce a PoV which is uncompressed. - // - // As such, honest collators never produce an uncompressed PoV which starts with - // a compression magic number, which would lead validators to reject the collation. - if encoded_size > validation_data.max_pov_size as usize { - tracing::debug!( - target: LOG_TARGET, - para_id = %scheduled_core.para_id, - size = encoded_size, - max_size = validation_data.max_pov_size, - "PoV exceeded maximum size" + ctx.spawn( + "collation generation collation builder", + Box::pin(async move { + let persisted_validation_data_hash = validation_data.hash(); + + let (collation, result_sender) = + match (task_config.collator)(relay_parent, &validation_data).await { + Some(collation) => collation.into_inner(), + None => { + tracing::debug!( + target: LOG_TARGET, + para_id = %scheduled_core.para_id, + "collator returned no collation on collate", + ); + return + }, + }; + + // Apply compression to the block data. + let pov = { + let pov = polkadot_node_primitives::maybe_compress_pov( + collation.proof_of_validity, ); + let encoded_size = pov.encoded_size(); + + // As long as `POV_BOMB_LIMIT` is at least `max_pov_size`, this ensures + // that honest collators never produce a PoV which is uncompressed. + // + // As such, honest collators never produce an uncompressed PoV which starts with + // a compression magic number, which would lead validators to reject the collation. + if encoded_size > validation_data.max_pov_size as usize { + tracing::debug!( + target: LOG_TARGET, + para_id = %scheduled_core.para_id, + size = encoded_size, + max_size = validation_data.max_pov_size, + "PoV exceeded maximum size" + ); + + return + } + + pov + }; + + let pov_hash = pov.hash(); + + let signature_payload = collator_signature_payload( + &relay_parent, + &scheduled_core.para_id, + &persisted_validation_data_hash, + &pov_hash, + &validation_code_hash, + ); - return - } - - pov - }; - - let pov_hash = pov.hash(); - - let signature_payload = collator_signature_payload( - &relay_parent, - &scheduled_core.para_id, - &persisted_validation_data_hash, - &pov_hash, - &validation_code_hash, - ); - - let erasure_root = match erasure_root( - n_validators, - validation_data, - pov.clone(), - ) { - Ok(erasure_root) => erasure_root, - Err(err) => { - tracing::error!( + let erasure_root = + match erasure_root(n_validators, validation_data, pov.clone()) { + Ok(erasure_root) => erasure_root, + Err(err) => { + tracing::error!( + target: LOG_TARGET, + para_id = %scheduled_core.para_id, + err = ?err, + "failed to calculate erasure root", + ); + return + }, + }; + + let commitments = CandidateCommitments { + upward_messages: collation.upward_messages, + horizontal_messages: collation.horizontal_messages, + new_validation_code: collation.new_validation_code, + head_data: collation.head_data, + processed_downward_messages: collation.processed_downward_messages, + hrmp_watermark: collation.hrmp_watermark, + }; + + let ccr = CandidateReceipt { + commitments_hash: commitments.hash(), + descriptor: CandidateDescriptor { + signature: task_config.key.sign(&signature_payload), + para_id: scheduled_core.para_id, + relay_parent, + collator: task_config.key.public(), + persisted_validation_data_hash, + pov_hash, + erasure_root, + para_head: commitments.head_data.hash(), + validation_code_hash, + }, + }; + + tracing::debug!( + target: LOG_TARGET, + candidate_hash = ?ccr.hash(), + ?pov_hash, + ?relay_parent, + para_id = %scheduled_core.para_id, + "candidate is generated", + ); + metrics.on_collation_generated(); + + if let Err(err) = task_sender + .send(AllMessages::CollatorProtocol( + CollatorProtocolMessage::DistributeCollation(ccr, pov, result_sender), + )) + .await + { + tracing::warn!( target: LOG_TARGET, para_id = %scheduled_core.para_id, err = ?err, - "failed to calculate erasure root", + "failed to send collation result", ); - return } - }; - - let commitments = CandidateCommitments { - upward_messages: collation.upward_messages, - horizontal_messages: collation.horizontal_messages, - new_validation_code: collation.new_validation_code, - head_data: collation.head_data, - processed_downward_messages: collation.processed_downward_messages, - hrmp_watermark: collation.hrmp_watermark, - }; - - let ccr = CandidateReceipt { - commitments_hash: commitments.hash(), - descriptor: CandidateDescriptor { - signature: task_config.key.sign(&signature_payload), - para_id: scheduled_core.para_id, - relay_parent, - collator: task_config.key.public(), - persisted_validation_data_hash, - pov_hash, - erasure_root, - para_head: commitments.head_data.hash(), - validation_code_hash: validation_code_hash, - }, - }; - - tracing::debug!( - target: LOG_TARGET, - candidate_hash = ?ccr.hash(), - ?pov_hash, - ?relay_parent, - para_id = %scheduled_core.para_id, - "candidate is generated", - ); - metrics.on_collation_generated(); - - if let Err(err) = task_sender.send(AllMessages::CollatorProtocol( - CollatorProtocolMessage::DistributeCollation(ccr, pov, result_sender) - )).await { - tracing::warn!( - target: LOG_TARGET, - para_id = %scheduled_core.para_id, - err = ?err, - "failed to send collation result", - ); - } - }))?; + }), + )?; } } @@ -426,10 +419,8 @@ fn erasure_root( persisted_validation: PersistedValidationData, pov: PoV, ) -> crate::error::Result { - let available_data = AvailableData { - validation_data: persisted_validation, - pov: Arc::new(pov), - }; + let available_data = + AvailableData { validation_data: persisted_validation, pov: Arc::new(pov) }; let chunks = polkadot_erasure_coding::obtain_chunks_v1(n_validators, &available_data)?; Ok(polkadot_erasure_coding::branches(&chunks).root()) @@ -460,13 +451,21 @@ impl Metrics { } /// Provide a timer per relay parents which updates on drop. - fn time_new_activations_relay_parent(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.new_activations_per_relay_parent.start_timer()) + fn time_new_activations_relay_parent( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.new_activations_per_relay_parent.start_timer()) } /// Provide a timer per availability core which updates on drop. - fn time_new_activations_availability_core(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.new_activations_per_availability_core.start_timer()) + fn time_new_activations_availability_core( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.new_activations_per_availability_core.start_timer()) } } diff --git a/polkadot/node/collation-generation/src/tests.rs b/polkadot/node/collation-generation/src/tests.rs index 8c663e7f7be..2e7417a79ec 100644 --- a/polkadot/node/collation-generation/src/tests.rs +++ b/polkadot/node/collation-generation/src/tests.rs @@ -21,10 +21,8 @@ mod handle_new_activations { task::{Context as FuturesContext, Poll}, Future, }; - use polkadot_node_primitives::{Collation, CollationResult, BlockData, PoV, POV_BOMB_LIMIT}; - use polkadot_node_subsystem::messages::{ - AllMessages, RuntimeApiMessage, RuntimeApiRequest, - }; + use polkadot_node_primitives::{BlockData, Collation, CollationResult, PoV, POV_BOMB_LIMIT}; + use polkadot_node_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}; use polkadot_node_subsystem_test_helpers::{ subsystem_test_harness, TestSubsystemContextHandle, }; @@ -39,9 +37,7 @@ mod handle_new_activations { horizontal_messages: Default::default(), new_validation_code: Default::default(), head_data: Default::default(), - proof_of_validity: PoV { - block_data: BlockData(Vec::new()), - }, + proof_of_validity: PoV { block_data: BlockData(Vec::new()) }, processed_downward_messages: Default::default(), hrmp_watermark: Default::default(), } @@ -50,10 +46,13 @@ mod handle_new_activations { fn test_collation_compressed() -> Collation { let mut collation = test_collation(); let compressed = PoV { - block_data: BlockData(sp_maybe_compressed_blob::compress( - &collation.proof_of_validity.block_data.0, - POV_BOMB_LIMIT, - ).unwrap()) + block_data: BlockData( + sp_maybe_compressed_blob::compress( + &collation.proof_of_validity.block_data.0, + POV_BOMB_LIMIT, + ) + .unwrap(), + ), }; collation.proof_of_validity = compressed; collation @@ -81,28 +80,19 @@ mod handle_new_activations { fn test_config>(para_id: Id) -> Arc { Arc::new(CollationGenerationConfig { key: CollatorPair::generate().0, - collator: Box::new(|_: Hash, _vd: &PersistedValidationData| { - TestCollator.boxed() - }), + collator: Box::new(|_: Hash, _vd: &PersistedValidationData| TestCollator.boxed()), para_id: para_id.into(), }) } fn scheduled_core_for>(para_id: Id) -> ScheduledCore { - ScheduledCore { - para_id: para_id.into(), - collator: None, - } + ScheduledCore { para_id: para_id.into(), collator: None } } #[test] fn requests_availability_per_relay_parent() { - let activated_hashes: Vec = vec![ - [1; 32].into(), - [4; 32].into(), - [9; 32].into(), - [16; 32].into(), - ]; + let activated_hashes: Vec = + vec![[1; 32].into(), [4; 32].into(), [9; 32].into(), [16; 32].into()]; let requested_availability_cores = Arc::new(Mutex::new(Vec::new())); @@ -177,7 +167,7 @@ mod handle_new_activations { )), ])) .unwrap(); - } + }, Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( hash, RuntimeApiRequest::PersistedValidationData( @@ -186,21 +176,18 @@ mod handle_new_activations { tx, ), ))) => { - overseer_requested_validation_data - .lock() - .await - .push(hash); + overseer_requested_validation_data.lock().await.push(hash); tx.send(Ok(Default::default())).unwrap(); - } + }, Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( _hash, RuntimeApiRequest::Validators(tx), ))) => { tx.send(Ok(vec![Default::default(); 3])).unwrap(); - } + }, Some(msg) => { panic!("didn't expect any other overseer requests; got {:?}", msg) - } + }, } } }; @@ -252,7 +239,7 @@ mod handle_new_activations { )), ])) .unwrap(); - } + }, Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( _hash, RuntimeApiRequest::PersistedValidationData( @@ -262,13 +249,13 @@ mod handle_new_activations { ), ))) => { tx.send(Ok(Some(test_validation_data()))).unwrap(); - } + }, Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( _hash, RuntimeApiRequest::Validators(tx), ))) => { tx.send(Ok(vec![Default::default(); 3])).unwrap(); - } + }, Some(AllMessages::RuntimeApi(RuntimeApiMessage::Request( _hash, RuntimeApiRequest::ValidationCode( @@ -278,10 +265,10 @@ mod handle_new_activations { ), ))) => { tx.send(Ok(Some(ValidationCode(vec![1, 2, 3])))).unwrap(); - } + }, Some(msg) => { panic!("didn't expect any other overseer requests; got {:?}", msg) - } + }, } } }; @@ -295,9 +282,15 @@ mod handle_new_activations { let sent_messages = Arc::new(Mutex::new(Vec::new())); let subsystem_sent_messages = sent_messages.clone(); subsystem_test_harness(overseer, |mut ctx| async move { - handle_new_activations(subsystem_config, activated_hashes, &mut ctx, Metrics(None), &tx) - .await - .unwrap(); + handle_new_activations( + subsystem_config, + activated_hashes, + &mut ctx, + Metrics(None), + &tx, + ) + .await + .unwrap(); std::mem::drop(tx); @@ -340,7 +333,7 @@ mod handle_new_activations { AllMessages::CollatorProtocol(CollatorProtocolMessage::DistributeCollation( CandidateReceipt { descriptor, .. }, _pov, - .. + .., )) => { // signature generation is non-deterministic, so we can't just assert that the // expected descriptor is correct. What we can do is validate that the produced @@ -365,7 +358,7 @@ mod handle_new_activations { expect_descriptor }; assert_eq!(descriptor, &expect_descriptor); - } + }, _ => panic!("received wrong message type"), } } diff --git a/polkadot/node/core/approval-voting/src/approval_checking.rs b/polkadot/node/core/approval-voting/src/approval_checking.rs index 3f9d2154bf1..17a5cda64c8 100644 --- a/polkadot/node/core/approval-voting/src/approval_checking.rs +++ b/polkadot/node/core/approval-voting/src/approval_checking.rs @@ -16,13 +16,14 @@ //! Utilities for checking whether a candidate has been approved under a given block. +use bitvec::{order::Lsb0 as BitOrderLsb0, slice::BitSlice}; use polkadot_node_primitives::approval::DelayTranche; use polkadot_primitives::v1::ValidatorIndex; -use bitvec::slice::BitSlice; -use bitvec::order::Lsb0 as BitOrderLsb0; -use crate::persisted_entries::{TrancheEntry, ApprovalEntry, CandidateEntry}; -use crate::time::Tick; +use crate::{ + persisted_entries::{ApprovalEntry, CandidateEntry, TrancheEntry}, + time::Tick, +}; /// The required tranches of assignments needed to determine whether a candidate is approved. #[derive(Debug, PartialEq, Clone)] @@ -57,7 +58,7 @@ pub enum RequiredTranches { /// event that there are some assignments that don't have corresponding approval votes. If this /// is `None`, all assignments have approvals. next_no_show: Option, - } + }, } /// The result of a check. @@ -96,12 +97,11 @@ pub fn check_approval( approval: &ApprovalEntry, required: RequiredTranches, ) -> Check { - // any set of size f+1 contains at least one honest node. If at least one // honest node approves, the candidate should be approved. let approvals = candidate.approvals(); if 3 * approvals.count_ones() > approvals.len() { - return Check::ApprovedOneThird; + return Check::ApprovedOneThird } match required { @@ -134,7 +134,7 @@ pub fn check_approval( } else { Check::Unapproved } - } + }, } } @@ -182,7 +182,7 @@ impl State { ) -> RequiredTranches { let covering = if self.depth == 0 { 0 } else { self.covering }; if self.depth != 0 && self.assignments + covering + self.uncovered >= n_validators { - return RequiredTranches::All; + return RequiredTranches::All } // If we have enough assignments and all no-shows are covered, we have reached the number @@ -192,7 +192,7 @@ impl State { needed: tranche, tolerated_missing: self.covered, next_no_show: self.next_no_show, - }; + } } // We're pending more assignments and should look at more tranches. @@ -245,10 +245,7 @@ impl State { self.covered + new_covered }; let uncovered = self.uncovered + new_no_shows; - let next_no_show = super::min_prefer_some( - self.next_no_show, - next_no_show, - ); + let next_no_show = super::min_prefer_some(self.next_no_show, next_no_show); let (depth, covering, uncovered) = if covering == 0 { if uncovered == 0 { @@ -271,27 +268,25 @@ fn filled_tranche_iterator<'a>( ) -> impl Iterator { let mut gap_end = None; - let approval_entries_filled = tranches - .iter() - .flat_map(move |tranche_entry| { - let tranche = tranche_entry.tranche(); - let assignments = tranche_entry.assignments(); + let approval_entries_filled = tranches.iter().flat_map(move |tranche_entry| { + let tranche = tranche_entry.tranche(); + let assignments = tranche_entry.assignments(); - // The new gap_start immediately follows the prior gap_end, if one exists. - // Otherwise, on the first pass, the new gap_start is set to the first - // tranche so that the range below will be empty. - let gap_start = gap_end.map(|end| end + 1).unwrap_or(tranche); - gap_end = Some(tranche); + // The new gap_start immediately follows the prior gap_end, if one exists. + // Otherwise, on the first pass, the new gap_start is set to the first + // tranche so that the range below will be empty. + let gap_start = gap_end.map(|end| end + 1).unwrap_or(tranche); + gap_end = Some(tranche); - (gap_start..tranche).map(|i| (i, &[] as &[_])) - .chain(std::iter::once((tranche, assignments))) - }); + (gap_start..tranche) + .map(|i| (i, &[] as &[_])) + .chain(std::iter::once((tranche, assignments))) + }); let pre_end = tranches.first().map(|t| t.tranche()); let post_start = tranches.last().map_or(0, |t| t.tranche() + 1); - let pre = pre_end.into_iter() - .flat_map(|pre_end| (0..pre_end).map(|i| (i, &[] as &[_]))); + let pre = pre_end.into_iter().flat_map(|pre_end| (0..pre_end).map(|i| (i, &[] as &[_]))); let post = (post_start..).map(|i| (i, &[] as &[_])); pre.chain(approval_entries_filled).chain(post) @@ -313,13 +308,14 @@ fn count_no_shows( drifted_tick_now: Tick, ) -> (usize, Option) { let mut next_no_show = None; - let no_shows = assignments.iter() + let no_shows = assignments + .iter() .map(|(v_index, tick)| (v_index, tick.saturating_sub(clock_drift) + no_show_duration)) .filter(|&(v_index, no_show_at)| { let has_approved = if let Some(approved) = approvals.get(v_index.0 as usize) { *approved } else { - return false; + return false }; let is_no_show = !has_approved && no_show_at <= drifted_tick_now; @@ -331,14 +327,12 @@ fn count_no_shows( // *this node* should observe whether or not the validator is a no show. Recall // that when the when drifted_tick_now is computed during that subsequent wake up, // the clock drift will be removed again to do the comparison above. - next_no_show = super::min_prefer_some( - next_no_show, - Some(no_show_at + clock_drift), - ); + next_no_show = super::min_prefer_some(next_no_show, Some(no_show_at + clock_drift)); } is_no_show - }).count(); + }) + .count(); (no_shows, next_no_show) } @@ -430,9 +424,8 @@ pub fn tranches_to_approve( mod tests { use super::*; + use bitvec::{bitvec, order::Lsb0 as BitOrderLsb0}; use polkadot_primitives::v1::GroupIndex; - use bitvec::bitvec; - use bitvec::order::Lsb0 as BitOrderLsb0; use crate::approval_db; @@ -443,7 +436,8 @@ mod tests { session: 0, block_assignments: Default::default(), approvals: Default::default(), - }.into(); + } + .into(); let approval_entry = approval_db::v1::ApprovalEntry { tranches: Vec::new(), @@ -452,7 +446,8 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); assert!(!check_approval( &candidate, @@ -463,7 +458,8 @@ mod tests { maximum_broadcast: 0, clock_drift: 0, }, - ).is_approved()); + ) + .is_approved()); } #[test] @@ -473,7 +469,8 @@ mod tests { session: 0, block_assignments: Default::default(), approvals: bitvec![BitOrderLsb0, u8; 0; 10], - }.into(); + } + .into(); for i in 0..3 { candidate.mark_approval(ValidatorIndex(i)); @@ -499,35 +496,27 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); assert!(check_approval( &candidate, &approval_entry, - RequiredTranches::Exact { - needed: 0, - tolerated_missing: 0, - next_no_show: None, - }, - ).is_approved()); + RequiredTranches::Exact { needed: 0, tolerated_missing: 0, next_no_show: None }, + ) + .is_approved()); assert!(!check_approval( &candidate, &approval_entry, - RequiredTranches::Exact { - needed: 1, - tolerated_missing: 0, - next_no_show: None, - }, - ).is_approved()); + RequiredTranches::Exact { needed: 1, tolerated_missing: 0, next_no_show: None }, + ) + .is_approved()); assert!(check_approval( &candidate, &approval_entry, - RequiredTranches::Exact { - needed: 1, - tolerated_missing: 2, - next_no_show: None, - }, - ).is_approved()); + RequiredTranches::Exact { needed: 1, tolerated_missing: 2, next_no_show: None }, + ) + .is_approved()); } #[test] @@ -537,7 +526,8 @@ mod tests { session: 0, block_assignments: Default::default(), approvals: bitvec![BitOrderLsb0, u8; 0; 10], - }.into(); + } + .into(); for i in 0..3 { candidate.mark_approval(ValidatorIndex(i)); @@ -563,13 +553,11 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); - let exact_all = RequiredTranches::Exact { - needed: 10, - tolerated_missing: 0, - next_no_show: None, - }; + let exact_all = + RequiredTranches::Exact { needed: 10, tolerated_missing: 0, next_no_show: None }; let pending_all = RequiredTranches::Pending { considered: 5, @@ -578,44 +566,20 @@ mod tests { clock_drift: 12, }; - assert!(!check_approval( - &candidate, - &approval_entry, - RequiredTranches::All, - ).is_approved()); + assert!(!check_approval(&candidate, &approval_entry, RequiredTranches::All,).is_approved()); - assert!(!check_approval( - &candidate, - &approval_entry, - exact_all.clone(), - ).is_approved()); + assert!(!check_approval(&candidate, &approval_entry, exact_all.clone(),).is_approved()); - assert!(!check_approval( - &candidate, - &approval_entry, - pending_all.clone(), - ).is_approved()); + assert!(!check_approval(&candidate, &approval_entry, pending_all.clone(),).is_approved()); // This creates a set of 4/10 approvals, which is always an approval. candidate.mark_approval(ValidatorIndex(3)); - assert!(check_approval( - &candidate, - &approval_entry, - RequiredTranches::All, - ).is_approved()); + assert!(check_approval(&candidate, &approval_entry, RequiredTranches::All,).is_approved()); - assert!(check_approval( - &candidate, - &approval_entry, - exact_all, - ).is_approved()); + assert!(check_approval(&candidate, &approval_entry, exact_all,).is_approved()); - assert!(check_approval( - &candidate, - &approval_entry, - pending_all, - ).is_approved()); + assert!(check_approval(&candidate, &approval_entry, pending_all,).is_approved()); } #[test] @@ -631,15 +595,16 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); - approval_entry.import_assignment(0,ValidatorIndex(0), block_tick); - approval_entry.import_assignment(0,ValidatorIndex(1), block_tick); + approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); + approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); - approval_entry.import_assignment(1,ValidatorIndex(2), block_tick + 1); - approval_entry.import_assignment(1,ValidatorIndex(3), block_tick + 1); + approval_entry.import_assignment(1, ValidatorIndex(2), block_tick + 1); + approval_entry.import_assignment(1, ValidatorIndex(3), block_tick + 1); - approval_entry.import_assignment(2,ValidatorIndex(4), block_tick + 2); + approval_entry.import_assignment(2, ValidatorIndex(4), block_tick + 2); let approvals = bitvec![BitOrderLsb0, u8; 1; 5]; @@ -669,7 +634,8 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); approval_entry.import_assignment(1, ValidatorIndex(2), block_tick); @@ -708,7 +674,8 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); @@ -752,7 +719,8 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); @@ -818,7 +786,8 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); @@ -868,7 +837,7 @@ mod tests { RequiredTranches::Exact { needed: 2, tolerated_missing: 1, - next_no_show: Some(block_tick + 2*no_show_duration + 2), + next_no_show: Some(block_tick + 2 * no_show_duration + 2), }, ); @@ -906,7 +875,8 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); approval_entry.import_assignment(0, ValidatorIndex(0), block_tick); approval_entry.import_assignment(0, ValidatorIndex(1), block_tick); @@ -935,11 +905,7 @@ mod tests { no_show_duration, needed_approvals, ), - RequiredTranches::Exact { - needed: 2, - tolerated_missing: 1, - next_no_show: None, - }, + RequiredTranches::Exact { needed: 2, tolerated_missing: 1, next_no_show: None }, ); // Even though tranche 2 has 2 validators, it only covers 1 no-show. @@ -977,11 +943,7 @@ mod tests { no_show_duration, needed_approvals, ), - RequiredTranches::Exact { - needed: 3, - tolerated_missing: 2, - next_no_show: None, - }, + RequiredTranches::Exact { needed: 3, tolerated_missing: 2, next_no_show: None }, ); } @@ -996,7 +958,8 @@ mod tests { session: 0, block_assignments: Default::default(), approvals: bitvec![BitOrderLsb0, u8; 0; 3], - }.into(); + } + .into(); for i in 0..3 { candidate.mark_approval(ValidatorIndex(i)); @@ -1015,7 +978,8 @@ mod tests { our_approval_sig: None, backing_group: GroupIndex(0), approved: false, - }.into(); + } + .into(); let approvals = bitvec![BitOrderLsb0, u8; 0; 3]; @@ -1043,14 +1007,14 @@ mod tests { const PREFIX: u32 = 10; let test_tranches = vec![ - vec![], // empty set - vec![0], // zero start - vec![0, 3], // zero start with gap - vec![2], // non-zero start - vec![2, 4], // non-zero start with gap - vec![0, 1, 2], // zero start with run and no gap - vec![2, 3, 4, 8], // non-zero start with run and gap - vec![0, 1, 2, 5, 6, 7], // zero start with runs and gap + vec![], // empty set + vec![0], // zero start + vec![0, 3], // zero start with gap + vec![2], // non-zero start + vec![2, 4], // non-zero start with gap + vec![0, 1, 2], // zero start with run and no gap + vec![2, 3, 4, 8], // non-zero start with run and gap + vec![0, 1, 2, 5, 6, 7], // zero start with runs and gap ]; for test_tranche in test_tranches { @@ -1061,7 +1025,8 @@ mod tests { our_approval_sig: None, assignments: bitvec![BitOrderLsb0, u8; 0; 3], approved: false, - }.into(); + } + .into(); // Populate the requested tranches. The assignemnts aren't inspected in // this test. @@ -1072,10 +1037,8 @@ mod tests { let filled_tranches = filled_tranche_iterator(approval_entry.tranches()); // Take the first PREFIX entries and map them to their tranche. - let tranches: Vec = filled_tranches - .take(PREFIX as usize) - .map(|e| e.0) - .collect(); + let tranches: Vec = + filled_tranches.take(PREFIX as usize).map(|e| e.0).collect(); // We expect this sequence to be sequential. let exp_tranches: Vec = (0..PREFIX).collect(); @@ -1194,7 +1157,11 @@ mod tests { #[test] fn count_no_shows_three_validators_one_almost_late_one_no_show_one_approving() { test_count_no_shows(NoShowTest { - assignments: vec![(ValidatorIndex(1), 21), (ValidatorIndex(2), 20), (ValidatorIndex(3), 20)], + assignments: vec![ + (ValidatorIndex(1), 21), + (ValidatorIndex(2), 20), + (ValidatorIndex(3), 20), + ], approvals: vec![3], clock_drift: 10, no_show_duration: 10, @@ -1207,7 +1174,11 @@ mod tests { #[test] fn count_no_shows_three_no_show_validators() { test_count_no_shows(NoShowTest { - assignments: vec![(ValidatorIndex(1), 20), (ValidatorIndex(2), 20), (ValidatorIndex(3), 20)], + assignments: vec![ + (ValidatorIndex(1), 20), + (ValidatorIndex(2), 20), + (ValidatorIndex(3), 20), + ], approvals: vec![], clock_drift: 10, no_show_duration: 10, @@ -1220,7 +1191,11 @@ mod tests { #[test] fn count_no_shows_three_approving_validators() { test_count_no_shows(NoShowTest { - assignments: vec![(ValidatorIndex(1), 20), (ValidatorIndex(2), 20), (ValidatorIndex(3), 20)], + assignments: vec![ + (ValidatorIndex(1), 20), + (ValidatorIndex(2), 20), + (ValidatorIndex(3), 20), + ], approvals: vec![1, 2, 3], clock_drift: 10, no_show_duration: 10, @@ -1270,17 +1245,17 @@ mod tests { } #[test] - fn count_no_shows_validator_index_out_of_approvals_range_is_ignored_as_next_no_show() { - test_count_no_shows(NoShowTest { - assignments: vec![(ValidatorIndex(1000), 21)], - approvals: vec![], - clock_drift: 10, - no_show_duration: 10, - drifted_tick_now: 20, - exp_no_shows: 0, - exp_next_no_show: None, - }) - } + fn count_no_shows_validator_index_out_of_approvals_range_is_ignored_as_next_no_show() { + test_count_no_shows(NoShowTest { + assignments: vec![(ValidatorIndex(1000), 21)], + approvals: vec![], + clock_drift: 10, + no_show_duration: 10, + drifted_tick_now: 20, + exp_no_shows: 0, + exp_next_no_show: None, + }) + } } #[test] @@ -1318,10 +1293,6 @@ fn depth_0_issued_as_exact_even_when_all() { assert_eq!( state.output(0, 10, 10, 20), - RequiredTranches::Exact { - needed: 0, - tolerated_missing: 0, - next_no_show: None, - }, + RequiredTranches::Exact { needed: 0, tolerated_missing: 0, next_no_show: None }, ); } diff --git a/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs b/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs index 7cf0c59ee5a..bcc01717d88 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v1/mod.rs @@ -17,21 +17,22 @@ //! Version 1 of the DB schema. use kvdb::{DBTransaction, KeyValueDB}; -use polkadot_node_subsystem::{SubsystemResult, SubsystemError}; -use polkadot_node_primitives::approval::{DelayTranche, AssignmentCert}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_primitives::approval::{AssignmentCert, DelayTranche}; +use polkadot_node_subsystem::{SubsystemError, SubsystemResult}; use polkadot_primitives::v1::{ - ValidatorIndex, GroupIndex, CandidateReceipt, SessionIndex, CoreIndex, - BlockNumber, Hash, CandidateHash, ValidatorSignature, + BlockNumber, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, Hash, SessionIndex, + ValidatorIndex, ValidatorSignature, }; use sp_consensus_slots::Slot; -use parity_scale_codec::{Encode, Decode}; -use std::collections::BTreeMap; -use std::sync::Arc; -use bitvec::{vec::BitVec, order::Lsb0 as BitOrderLsb0}; +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use std::{collections::BTreeMap, sync::Arc}; -use crate::backend::{Backend, BackendWriteOp}; -use crate::persisted_entries; +use crate::{ + backend::{Backend, BackendWriteOp}, + persisted_entries, +}; const STORED_BLOCKS_KEY: &[u8] = b"Approvals_StoredBlocks"; @@ -48,10 +49,7 @@ impl DbBackend { /// Create a new [`DbBackend`] with the supplied key-value store and /// config. pub fn new(db: Arc, config: Config) -> Self { - DbBackend { - inner: db, - config, - } + DbBackend { inner: db, config } } } @@ -60,22 +58,17 @@ impl Backend for DbBackend { &self, block_hash: &Hash, ) -> SubsystemResult> { - load_block_entry(&*self.inner, &self.config, block_hash) - .map(|e| e.map(Into::into)) + load_block_entry(&*self.inner, &self.config, block_hash).map(|e| e.map(Into::into)) } fn load_candidate_entry( &self, candidate_hash: &CandidateHash, ) -> SubsystemResult> { - load_candidate_entry(&*self.inner, &self.config, candidate_hash) - .map(|e| e.map(Into::into)) + load_candidate_entry(&*self.inner, &self.config, candidate_hash).map(|e| e.map(Into::into)) } - fn load_blocks_at_height( - &self, - block_height: &BlockNumber - ) -> SubsystemResult> { + fn load_blocks_at_height(&self, block_height: &BlockNumber) -> SubsystemResult> { load_blocks_at_height(&*self.inner, &self.config, block_height) } @@ -89,7 +82,8 @@ impl Backend for DbBackend { /// Atomically write the list of operations, with later operations taking precedence over prior. fn write(&mut self, ops: I) -> SubsystemResult<()> - where I: IntoIterator + where + I: IntoIterator, { let mut tx = DBTransaction::new(); for op in ops { @@ -100,20 +94,13 @@ impl Backend for DbBackend { &STORED_BLOCKS_KEY, stored_block_range.encode(), ); - } + }, BackendWriteOp::WriteBlocksAtHeight(h, blocks) => { - tx.put_vec( - self.config.col_data, - &blocks_at_height_key(h), - blocks.encode(), - ); - } + tx.put_vec(self.config.col_data, &blocks_at_height_key(h), blocks.encode()); + }, BackendWriteOp::DeleteBlocksAtHeight(h) => { - tx.delete( - self.config.col_data, - &blocks_at_height_key(h), - ); - } + tx.delete(self.config.col_data, &blocks_at_height_key(h)); + }, BackendWriteOp::WriteBlockEntry(block_entry) => { let block_entry: BlockEntry = block_entry.into(); tx.put_vec( @@ -121,13 +108,10 @@ impl Backend for DbBackend { &block_entry_key(&block_entry.block_hash), block_entry.encode(), ); - } + }, BackendWriteOp::DeleteBlockEntry(hash) => { - tx.delete( - self.config.col_data, - &block_entry_key(&hash), - ); - } + tx.delete(self.config.col_data, &block_entry_key(&hash)); + }, BackendWriteOp::WriteCandidateEntry(candidate_entry) => { let candidate_entry: CandidateEntry = candidate_entry.into(); tx.put_vec( @@ -135,13 +119,10 @@ impl Backend for DbBackend { &candidate_entry_key(&candidate_entry.candidate.hash()), candidate_entry.encode(), ); - } + }, BackendWriteOp::DeleteCandidateEntry(candidate_hash) => { - tx.delete( - self.config.col_data, - &candidate_entry_key(&candidate_hash), - ); - } + tx.delete(self.config.col_data, &candidate_entry_key(&candidate_hash)); + }, } } @@ -257,13 +238,14 @@ impl std::error::Error for Error {} /// Result alias for DB errors. pub type Result = std::result::Result; -pub(crate) fn load_decode(store: &dyn KeyValueDB, col_data: u32, key: &[u8]) -> Result> -{ +pub(crate) fn load_decode( + store: &dyn KeyValueDB, + col_data: u32, + key: &[u8], +) -> Result> { match store.get(col_data, key)? { None => Ok(None), - Some(raw) => D::decode(&mut &raw[..]) - .map(Some) - .map_err(Into::into), + Some(raw) => D::decode(&mut &raw[..]).map(Some).map_err(Into::into), } } @@ -308,7 +290,6 @@ pub fn load_all_blocks(store: &dyn KeyValueDB, config: &Config) -> SubsystemResu let blocks = load_blocks_at_height(store, config, &height)?; hashes.extend(blocks); } - } Ok(hashes) diff --git a/polkadot/node/core/approval-voting/src/approval_db/v1/tests.rs b/polkadot/node/core/approval-voting/src/approval_db/v1/tests.rs index b9b19e3f1c8..21013b1b9bf 100644 --- a/polkadot/node/core/approval-voting/src/approval_db/v1/tests.rs +++ b/polkadot/node/core/approval-voting/src/approval_db/v1/tests.rs @@ -16,21 +16,19 @@ //! Tests for the aux-schema of approval voting. -use super::*; -use std::sync::Arc; -use std::collections::HashMap; -use polkadot_primitives::v1::Id as ParaId; +use super::{DbBackend, StoredBlockRange, *}; +use crate::{ + backend::{Backend, OverlayedBackend}, + ops::{add_block_entry, canonicalize, force_approve, NewCandidateInfo}, +}; use kvdb::KeyValueDB; -use super::{DbBackend, StoredBlockRange}; -use crate::backend::{Backend, OverlayedBackend}; -use crate::ops::{NewCandidateInfo, add_block_entry, force_approve, canonicalize}; +use polkadot_primitives::v1::Id as ParaId; +use std::{collections::HashMap, sync::Arc}; const DATA_COL: u32 = 0; const NUM_COLUMNS: u32 = 1; -const TEST_CONFIG: Config = Config { - col_data: DATA_COL, -}; +const TEST_CONFIG: Config = Config { col_data: DATA_COL }; fn make_db() -> (DbBackend, Arc) { let db_writer: Arc = Arc::new(kvdb_memorydb::create(NUM_COLUMNS)); @@ -80,26 +78,25 @@ fn read_write() { let range = StoredBlockRange(10, 20); let at_height = vec![hash_a, hash_b]; - let block_entry = make_block_entry( - hash_a, - Default::default(), - 1, - vec![(CoreIndex(0), candidate_hash)], - ); + let block_entry = + make_block_entry(hash_a, Default::default(), 1, vec![(CoreIndex(0), candidate_hash)]); let candidate_entry = CandidateEntry { candidate: Default::default(), session: 5, - block_assignments: vec![ - (hash_a, ApprovalEntry { + block_assignments: vec![( + hash_a, + ApprovalEntry { tranches: Vec::new(), backing_group: GroupIndex(1), our_assignment: None, our_approval_sig: None, assignments: Default::default(), approved: false, - }) - ].into_iter().collect(), + }, + )] + .into_iter() + .collect(), approvals: Default::default(), }; @@ -114,7 +111,10 @@ fn read_write() { assert_eq!(load_stored_blocks(store.as_ref(), &TEST_CONFIG).unwrap(), Some(range)); assert_eq!(load_blocks_at_height(store.as_ref(), &TEST_CONFIG, &1).unwrap(), at_height); - assert_eq!(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash_a).unwrap(), Some(block_entry.into())); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &hash_a).unwrap(), + Some(block_entry.into()) + ); assert_eq!( load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash).unwrap(), Some(candidate_entry.into()), @@ -129,7 +129,9 @@ fn read_write() { assert!(load_blocks_at_height(store.as_ref(), &TEST_CONFIG, &1).unwrap().is_empty()); assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash_a).unwrap().is_none()); - assert!(load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash).unwrap().is_none()); + assert!(load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash) + .unwrap() + .is_none()); } #[test] @@ -165,47 +167,48 @@ fn add_block_entry_works() { let n_validators = 10; let mut new_candidate_info = HashMap::new(); - new_candidate_info.insert(candidate_hash_a, NewCandidateInfo::new( - candidate_receipt_a, - GroupIndex(0), - None, - )); + new_candidate_info + .insert(candidate_hash_a, NewCandidateInfo::new(candidate_receipt_a, GroupIndex(0), None)); let mut overlay_db = OverlayedBackend::new(&db); - add_block_entry( - &mut overlay_db, - block_entry_a.clone().into(), - n_validators, - |h| new_candidate_info.get(h).map(|x| x.clone()), - ).unwrap(); + add_block_entry(&mut overlay_db, block_entry_a.clone().into(), n_validators, |h| { + new_candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); - new_candidate_info.insert(candidate_hash_b, NewCandidateInfo::new( - candidate_receipt_b, - GroupIndex(1), - None, - )); + new_candidate_info + .insert(candidate_hash_b, NewCandidateInfo::new(candidate_receipt_b, GroupIndex(1), None)); let mut overlay_db = OverlayedBackend::new(&db); - add_block_entry( - &mut overlay_db, - block_entry_b.clone().into(), - n_validators, - |h| new_candidate_info.get(h).map(|x| x.clone()), - ).unwrap(); + add_block_entry(&mut overlay_db, block_entry_b.clone().into(), n_validators, |h| { + new_candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); - assert_eq!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a).unwrap(), Some(block_entry_a.into())); - assert_eq!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b).unwrap(), Some(block_entry_b.into())); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a).unwrap(), + Some(block_entry_a.into()) + ); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b).unwrap(), + Some(block_entry_b.into()) + ); let candidate_entry_a = load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash_a) - .unwrap().unwrap(); - assert_eq!(candidate_entry_a.block_assignments.keys().collect::>(), vec![&block_hash_a, &block_hash_b]); + .unwrap() + .unwrap(); + assert_eq!( + candidate_entry_a.block_assignments.keys().collect::>(), + vec![&block_hash_a, &block_hash_b] + ); let candidate_entry_b = load_candidate_entry(store.as_ref(), &TEST_CONFIG, &candidate_hash_b) - .unwrap().unwrap(); + .unwrap() + .unwrap(); assert_eq!(candidate_entry_b.block_assignments.keys().collect::>(), vec![&block_hash_b]); } @@ -217,44 +220,30 @@ fn add_block_entry_adds_child() { let block_hash_a = Hash::repeat_byte(2); let block_hash_b = Hash::repeat_byte(69); - let mut block_entry_a = make_block_entry( - block_hash_a, - parent_hash, - 1, - Vec::new(), - ); + let mut block_entry_a = make_block_entry(block_hash_a, parent_hash, 1, Vec::new()); - let block_entry_b = make_block_entry( - block_hash_b, - block_hash_a, - 2, - Vec::new(), - ); + let block_entry_b = make_block_entry(block_hash_b, block_hash_a, 2, Vec::new()); let n_validators = 10; let mut overlay_db = OverlayedBackend::new(&db); - add_block_entry( - &mut overlay_db, - block_entry_a.clone().into(), - n_validators, - |_| None, - ).unwrap(); - - add_block_entry( - &mut overlay_db, - block_entry_b.clone().into(), - n_validators, - |_| None, - ).unwrap(); + add_block_entry(&mut overlay_db, block_entry_a.clone().into(), n_validators, |_| None).unwrap(); + + add_block_entry(&mut overlay_db, block_entry_b.clone().into(), n_validators, |_| None).unwrap(); let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); block_entry_a.children.push(block_hash_b); - assert_eq!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a).unwrap(), Some(block_entry_a.into())); - assert_eq!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b).unwrap(), Some(block_entry_b.into())); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a).unwrap(), + Some(block_entry_a.into()) + ); + assert_eq!( + load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b).unwrap(), + Some(block_entry_b.into()) + ); } #[test] @@ -305,12 +294,8 @@ fn canonicalize_works() { let block_entry_a = make_block_entry(block_hash_a, genesis, 1, Vec::new()); let block_entry_b1 = make_block_entry(block_hash_b1, block_hash_a, 2, Vec::new()); - let block_entry_b2 = make_block_entry( - block_hash_b2, - block_hash_a, - 2, - vec![(CoreIndex(0), cand_hash_1)], - ); + let block_entry_b2 = + make_block_entry(block_hash_b2, block_hash_a, 2, vec![(CoreIndex(0), cand_hash_1)]); let block_entry_c1 = make_block_entry(block_hash_c1, block_hash_b1, 3, Vec::new()); let block_entry_c2 = make_block_entry( block_hash_c2, @@ -324,44 +309,27 @@ fn canonicalize_works() { 4, vec![(CoreIndex(0), cand_hash_3), (CoreIndex(1), cand_hash_4)], ); - let block_entry_d2 = make_block_entry( - block_hash_d2, - block_hash_c2, - 4, - vec![(CoreIndex(0), cand_hash_5)], - ); + let block_entry_d2 = + make_block_entry(block_hash_d2, block_hash_c2, 4, vec![(CoreIndex(0), cand_hash_5)]); let candidate_info = { let mut candidate_info = HashMap::new(); - candidate_info.insert(cand_hash_1, NewCandidateInfo::new( - candidate_receipt_genesis, - GroupIndex(1), - None, - )); - - candidate_info.insert(cand_hash_2, NewCandidateInfo::new( - candidate_receipt_a, - GroupIndex(2), - None, - )); - - candidate_info.insert(cand_hash_3, NewCandidateInfo::new( - candidate_receipt_b, - GroupIndex(3), - None, - )); - - candidate_info.insert(cand_hash_4, NewCandidateInfo::new( - candidate_receipt_b1, - GroupIndex(4), - None, - )); - - candidate_info.insert(cand_hash_5, NewCandidateInfo::new( - candidate_receipt_c1, - GroupIndex(5), - None, - )); + candidate_info.insert( + cand_hash_1, + NewCandidateInfo::new(candidate_receipt_genesis, GroupIndex(1), None), + ); + + candidate_info + .insert(cand_hash_2, NewCandidateInfo::new(candidate_receipt_a, GroupIndex(2), None)); + + candidate_info + .insert(cand_hash_3, NewCandidateInfo::new(candidate_receipt_b, GroupIndex(3), None)); + + candidate_info + .insert(cand_hash_4, NewCandidateInfo::new(candidate_receipt_b1, GroupIndex(4), None)); + + candidate_info + .insert(cand_hash_5, NewCandidateInfo::new(candidate_receipt_c1, GroupIndex(5), None)); candidate_info }; @@ -379,12 +347,10 @@ fn canonicalize_works() { let mut overlay_db = OverlayedBackend::new(&db); for block_entry in blocks { - add_block_entry( - &mut overlay_db, - block_entry.into(), - n_validators, - |h| candidate_info.get(h).map(|x| x.clone()), - ).unwrap(); + add_block_entry(&mut overlay_db, block_entry.into(), n_validators, |h| { + candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); } let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); @@ -393,9 +359,11 @@ fn canonicalize_works() { for (c_hash, in_blocks) in expected { let (entry, in_blocks) = match in_blocks { None => { - assert!(load_candidate_entry(store.as_ref(), &TEST_CONFIG, &c_hash).unwrap().is_none()); + assert!(load_candidate_entry(store.as_ref(), &TEST_CONFIG, &c_hash) + .unwrap() + .is_none()); continue - } + }, Some(i) => ( load_candidate_entry(store.as_ref(), &TEST_CONFIG, &c_hash).unwrap().unwrap(), i, @@ -414,13 +382,13 @@ fn canonicalize_works() { for (hash, with_candidates) in expected { let (entry, with_candidates) = match with_candidates { None => { - assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash).unwrap().is_none()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash) + .unwrap() + .is_none()); continue - } - Some(i) => ( - load_block_entry(store.as_ref(), &TEST_CONFIG, &hash).unwrap().unwrap(), - i, - ), + }, + Some(i) => + (load_block_entry(store.as_ref(), &TEST_CONFIG, &hash).unwrap().unwrap(), i), }; assert_eq!(entry.candidates.len(), with_candidates.len()); @@ -454,7 +422,10 @@ fn canonicalize_works() { let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); - assert_eq!(load_stored_blocks(store.as_ref(), &TEST_CONFIG).unwrap().unwrap(), StoredBlockRange(4, 5)); + assert_eq!( + load_stored_blocks(store.as_ref(), &TEST_CONFIG).unwrap().unwrap(), + StoredBlockRange(4, 5) + ); check_candidates_in_store(vec![ (cand_hash_1, None), @@ -489,25 +460,31 @@ fn force_approve_works() { let single_candidate_vec = vec![(CoreIndex(0), candidate_hash)]; let candidate_info = { let mut candidate_info = HashMap::new(); - candidate_info.insert(candidate_hash, NewCandidateInfo::new( - make_candidate(1.into(), Default::default()), - GroupIndex(1), - None, - )); + candidate_info.insert( + candidate_hash, + NewCandidateInfo::new( + make_candidate(1.into(), Default::default()), + GroupIndex(1), + None, + ), + ); candidate_info }; - let block_hash_a = Hash::repeat_byte(1); // 1 let block_hash_b = Hash::repeat_byte(2); let block_hash_c = Hash::repeat_byte(3); let block_hash_d = Hash::repeat_byte(4); // 4 - let block_entry_a = make_block_entry(block_hash_a, Default::default(), 1, single_candidate_vec.clone()); - let block_entry_b = make_block_entry(block_hash_b, block_hash_a, 2, single_candidate_vec.clone()); - let block_entry_c = make_block_entry(block_hash_c, block_hash_b, 3, single_candidate_vec.clone()); - let block_entry_d = make_block_entry(block_hash_d, block_hash_c, 4, single_candidate_vec.clone()); + let block_entry_a = + make_block_entry(block_hash_a, Default::default(), 1, single_candidate_vec.clone()); + let block_entry_b = + make_block_entry(block_hash_b, block_hash_a, 2, single_candidate_vec.clone()); + let block_entry_c = + make_block_entry(block_hash_c, block_hash_b, 3, single_candidate_vec.clone()); + let block_entry_d = + make_block_entry(block_hash_d, block_hash_c, 4, single_candidate_vec.clone()); let blocks = vec![ block_entry_a.clone(), @@ -518,41 +495,36 @@ fn force_approve_works() { let mut overlay_db = OverlayedBackend::new(&db); for block_entry in blocks { - add_block_entry( - &mut overlay_db, - block_entry.into(), - n_validators, - |h| candidate_info.get(h).map(|x| x.clone()), - ).unwrap(); + add_block_entry(&mut overlay_db, block_entry.into(), n_validators, |h| { + candidate_info.get(h).map(|x| x.clone()) + }) + .unwrap(); } - let approved_hashes = force_approve(&mut overlay_db, block_hash_d, 2).unwrap(); + let approved_hashes = force_approve(&mut overlay_db, block_hash_d, 2).unwrap(); let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); - assert!(load_block_entry( - store.as_ref(), - &TEST_CONFIG, - &block_hash_a, - ).unwrap().unwrap().approved_bitfield.all()); - assert!(load_block_entry( - store.as_ref(), - &TEST_CONFIG, - &block_hash_b, - ).unwrap().unwrap().approved_bitfield.all()); - assert!(load_block_entry( - store.as_ref(), - &TEST_CONFIG, - &block_hash_c, - ).unwrap().unwrap().approved_bitfield.not_any()); - assert!(load_block_entry( - store.as_ref(), - &TEST_CONFIG, - &block_hash_d, - ).unwrap().unwrap().approved_bitfield.not_any()); - assert_eq!( - approved_hashes, - vec![block_hash_b, block_hash_a], - ); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_a,) + .unwrap() + .unwrap() + .approved_bitfield + .all()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_b,) + .unwrap() + .unwrap() + .approved_bitfield + .all()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_c,) + .unwrap() + .unwrap() + .approved_bitfield + .not_any()); + assert!(load_block_entry(store.as_ref(), &TEST_CONFIG, &block_hash_d,) + .unwrap() + .unwrap() + .approved_bitfield + .not_any()); + assert_eq!(approved_hashes, vec![block_hash_b, block_hash_a],); } #[test] @@ -566,60 +538,27 @@ fn load_all_blocks_works() { let block_number = 10; - let block_entry_a = make_block_entry( - block_hash_a, - parent_hash, - block_number, - vec![], - ); + let block_entry_a = make_block_entry(block_hash_a, parent_hash, block_number, vec![]); - let block_entry_b = make_block_entry( - block_hash_b, - parent_hash, - block_number, - vec![], - ); + let block_entry_b = make_block_entry(block_hash_b, parent_hash, block_number, vec![]); - let block_entry_c = make_block_entry( - block_hash_c, - block_hash_a, - block_number + 1, - vec![], - ); + let block_entry_c = make_block_entry(block_hash_c, block_hash_a, block_number + 1, vec![]); let n_validators = 10; let mut overlay_db = OverlayedBackend::new(&db); - add_block_entry( - &mut overlay_db, - block_entry_a.clone().into(), - n_validators, - |_| None - ).unwrap(); + add_block_entry(&mut overlay_db, block_entry_a.clone().into(), n_validators, |_| None).unwrap(); // add C before B to test sorting. - add_block_entry( - &mut overlay_db, - block_entry_c.clone().into(), - n_validators, - |_| None - ).unwrap(); - - add_block_entry( - &mut overlay_db, - block_entry_b.clone().into(), - n_validators, - |_| None - ).unwrap(); + add_block_entry(&mut overlay_db, block_entry_c.clone().into(), n_validators, |_| None).unwrap(); + + add_block_entry(&mut overlay_db, block_entry_b.clone().into(), n_validators, |_| None).unwrap(); let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); assert_eq!( - load_all_blocks( - store.as_ref(), - &TEST_CONFIG - ).unwrap(), + load_all_blocks(store.as_ref(), &TEST_CONFIG).unwrap(), vec![block_hash_a, block_hash_b, block_hash_c], ) } diff --git a/polkadot/node/core/approval-voting/src/backend.rs b/polkadot/node/core/approval-voting/src/backend.rs index 14cd43dba19..e5f57de70d3 100644 --- a/polkadot/node/core/approval-voting/src/backend.rs +++ b/polkadot/node/core/approval-voting/src/backend.rs @@ -21,13 +21,15 @@ //! [`Backend`], maintaining consistency between queries and temporary writes, //! before any commit to the underlying storage is made. -use polkadot_node_subsystem::{SubsystemResult}; +use polkadot_node_subsystem::SubsystemResult; use polkadot_primitives::v1::{BlockNumber, CandidateHash, Hash}; use std::collections::HashMap; -use super::approval_db::v1::StoredBlockRange; -use super::persisted_entries::{BlockEntry, CandidateEntry}; +use super::{ + approval_db::v1::StoredBlockRange, + persisted_entries::{BlockEntry, CandidateEntry}, +}; #[derive(Debug)] pub enum BackendWriteOp { @@ -45,7 +47,10 @@ pub trait Backend { /// Load a block entry from the DB. fn load_block_entry(&self, hash: &Hash) -> SubsystemResult>; /// Load a candidate entry from the DB. - fn load_candidate_entry(&self, candidate_hash: &CandidateHash) -> SubsystemResult>; + fn load_candidate_entry( + &self, + candidate_hash: &CandidateHash, + ) -> SubsystemResult>; /// Load all blocks at a specific height. fn load_blocks_at_height(&self, height: &BlockNumber) -> SubsystemResult>; /// Load all block from the DB. @@ -54,7 +59,8 @@ pub trait Backend { fn load_stored_blocks(&self) -> SubsystemResult>; /// Atomically write the list of operations, with later operations taking precedence over prior. fn write(&mut self, ops: I) -> SubsystemResult<()> - where I: IntoIterator; + where + I: IntoIterator; } /// An in-memory overlay over the backend. @@ -128,7 +134,10 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { self.inner.load_block_entry(hash) } - pub fn load_candidate_entry(&self, candidate_hash: &CandidateHash) -> SubsystemResult> { + pub fn load_candidate_entry( + &self, + candidate_hash: &CandidateHash, + ) -> SubsystemResult> { if let Some(val) = self.candidate_entries.get(&candidate_hash) { return Ok(val.clone()) } diff --git a/polkadot/node/core/approval-voting/src/criteria.rs b/polkadot/node/core/approval-voting/src/criteria.rs index b6f06c0fdb6..ea88c30e3bc 100644 --- a/polkadot/node/core/approval-voting/src/criteria.rs +++ b/polkadot/node/core/approval-voting/src/criteria.rs @@ -16,21 +16,20 @@ //! Assignment criteria VRF generation and checking. +use parity_scale_codec::{Decode, Encode}; use polkadot_node_primitives::approval::{ self as approval_types, AssignmentCert, AssignmentCertKind, DelayTranche, RelayVRFStory, }; use polkadot_primitives::v1::{ - CoreIndex, ValidatorIndex, SessionInfo, AssignmentPair, AssignmentId, GroupIndex, CandidateHash, + AssignmentId, AssignmentPair, CandidateHash, CoreIndex, GroupIndex, SessionInfo, ValidatorIndex, }; use sc_keystore::LocalKeystore; -use parity_scale_codec::{Encode, Decode}; use sp_application_crypto::Public; use merlin::Transcript; use schnorrkel::vrf::VRFInOut; -use std::collections::HashMap; -use std::collections::hash_map::Entry; +use std::collections::{hash_map::Entry, HashMap}; use super::LOG_TARGET; @@ -88,10 +87,7 @@ impl From for crate::approval_db::v1::OurAssignment { } } -fn relay_vrf_modulo_transcript( - relay_vrf_story: RelayVRFStory, - sample: u32, -) -> Transcript { +fn relay_vrf_modulo_transcript(relay_vrf_story: RelayVRFStory, sample: u32) -> Transcript { // combine the relay VRF story with a sample number. let mut t = Transcript::new(approval_types::RELAY_VRF_MODULO_CONTEXT); t.append_message(b"RC-VRF", &relay_vrf_story.0); @@ -100,10 +96,7 @@ fn relay_vrf_modulo_transcript( t } -fn relay_vrf_modulo_core( - vrf_in_out: &VRFInOut, - n_cores: u32, -) -> CoreIndex { +fn relay_vrf_modulo_core(vrf_in_out: &VRFInOut, n_cores: u32) -> CoreIndex { let bytes: [u8; 4] = vrf_in_out.make_bytes(approval_types::CORE_RANDOMNESS_CONTEXT); // interpret as little-endian u32. @@ -111,10 +104,7 @@ fn relay_vrf_modulo_core( CoreIndex(random_core) } -fn relay_vrf_delay_transcript( - relay_vrf_story: RelayVRFStory, - core_index: CoreIndex, -) -> Transcript { +fn relay_vrf_delay_transcript(relay_vrf_story: RelayVRFStory, core_index: CoreIndex) -> Transcript { let mut t = Transcript::new(approval_types::RELAY_VRF_DELAY_CONTEXT); t.append_message(b"RC-VRF", &relay_vrf_story.0); core_index.0.using_encoded(|s| t.append_message(b"core", s)); @@ -129,7 +119,8 @@ fn relay_vrf_delay_tranche( let bytes: [u8; 4] = vrf_in_out.make_bytes(approval_types::TRANCHE_RANDOMNESS_CONTEXT); // interpret as little-endian u32 and reduce by the number of tranches. - let wide_tranche = u32::from_le_bytes(bytes) % (num_delay_tranches + zeroth_delay_tranche_width); + let wide_tranche = + u32::from_le_bytes(bytes) % (num_delay_tranches + zeroth_delay_tranche_width); // Consolidate early results to tranche zero so tranche zero is extra wide. wide_tranche.saturating_sub(zeroth_delay_tranche_width) @@ -202,12 +193,7 @@ impl AssignmentCriteria for RealAssignmentCriteria { config: &Config, leaving_cores: Vec<(CandidateHash, CoreIndex, GroupIndex)>, ) -> HashMap { - compute_assignments( - keystore, - relay_vrf_story, - config, - leaving_cores, - ) + compute_assignments(keystore, relay_vrf_story, config, leaving_cores) } fn check_assignment_cert( @@ -246,13 +232,16 @@ pub(crate) fn compute_assignments( config: &Config, leaving_cores: impl IntoIterator + Clone, ) -> HashMap { - if config.n_cores == 0 || config.assignment_keys.is_empty() || config.validator_groups.is_empty() { + if config.n_cores == 0 || + config.assignment_keys.is_empty() || + config.validator_groups.is_empty() + { return HashMap::new() } let (index, assignments_key): (ValidatorIndex, AssignmentPair) = { - let key = config.assignment_keys.iter().enumerate() - .find_map(|(i, p)| match keystore.key_pair(p) { + let key = config.assignment_keys.iter().enumerate().find_map(|(i, p)| { + match keystore.key_pair(p) { Ok(Some(pair)) => Some((ValidatorIndex(i as _), pair)), Ok(None) => None, Err(sc_keystore::Error::Unavailable) => None, @@ -260,8 +249,9 @@ pub(crate) fn compute_assignments( Err(e) => { tracing::warn!(target: LOG_TARGET, "Encountered keystore error: {:?}", e); None - } - }); + }, + } + }); match key { None => return Default::default(), @@ -270,7 +260,8 @@ pub(crate) fn compute_assignments( }; // Ignore any cores where the assigned group is our own. - let leaving_cores = leaving_cores.into_iter() + let leaving_cores = leaving_cores + .into_iter() .filter(|&(_, _, ref g)| !is_in_backing_group(&config.validator_groups, index, *g)) .map(|(c_hash, core, _)| (c_hash, core)) .collect::>(); @@ -322,8 +313,8 @@ fn compute_relay_vrf_modulo_assignments( relay_vrf_modulo_transcript(relay_vrf_story.clone(), rvm_sample), |vrf_in_out| { *core = relay_vrf_modulo_core(&vrf_in_out, config.n_cores); - if let Some((candidate_hash, _)) - = leaving_cores.clone().into_iter().find(|(_, c)| c == core) + if let Some((candidate_hash, _)) = + leaving_cores.clone().into_iter().find(|(_, c)| c == core) { tracing::trace!( target: LOG_TARGET, @@ -338,7 +329,7 @@ fn compute_relay_vrf_modulo_assignments( } else { None } - } + }, ) }; @@ -347,7 +338,10 @@ fn compute_relay_vrf_modulo_assignments( // has been executed. let cert = AssignmentCert { kind: AssignmentCertKind::RelayVRFModulo { sample: rvm_sample }, - vrf: (approval_types::VRFOutput(vrf_in_out.to_output()), approval_types::VRFProof(vrf_proof)), + vrf: ( + approval_types::VRFOutput(vrf_in_out.to_output()), + approval_types::VRFProof(vrf_proof), + ), }; // All assignments of type RelayVRFModulo have tranche 0. @@ -370,9 +364,8 @@ fn compute_relay_vrf_delay_assignments( assignments: &mut HashMap, ) { for (candidate_hash, core) in leaving_cores { - let (vrf_in_out, vrf_proof, _) = assignments_key.vrf_sign( - relay_vrf_delay_transcript(relay_vrf_story.clone(), core), - ); + let (vrf_in_out, vrf_proof, _) = + assignments_key.vrf_sign(relay_vrf_delay_transcript(relay_vrf_story.clone(), core)); let tranche = relay_vrf_delay_tranche( &vrf_in_out, @@ -382,24 +375,26 @@ fn compute_relay_vrf_delay_assignments( let cert = AssignmentCert { kind: AssignmentCertKind::RelayVRFDelay { core_index: core }, - vrf: (approval_types::VRFOutput(vrf_in_out.to_output()), approval_types::VRFProof(vrf_proof)), + vrf: ( + approval_types::VRFOutput(vrf_in_out.to_output()), + approval_types::VRFProof(vrf_proof), + ), }; - let our_assignment = OurAssignment { - cert, - tranche, - validator_index, - triggered: false, - }; + let our_assignment = OurAssignment { cert, tranche, validator_index, triggered: false }; let used = match assignments.entry(core) { - Entry::Vacant(e) => { let _ = e.insert(our_assignment); true } - Entry::Occupied(mut e) => if e.get().tranche > our_assignment.tranche { - e.insert(our_assignment); + Entry::Vacant(e) => { + let _ = e.insert(our_assignment); true - } else { - false }, + Entry::Occupied(mut e) => + if e.get().tranche > our_assignment.tranche { + e.insert(our_assignment); + true + } else { + false + }, }; if used { @@ -425,7 +420,7 @@ impl std::fmt::Display for InvalidAssignment { } } -impl std::error::Error for InvalidAssignment { } +impl std::error::Error for InvalidAssignment {} /// Checks the crypto of an assignment cert. Failure conditions: /// * Validator index out of bounds @@ -446,7 +441,8 @@ pub(crate) fn check_assignment_cert( assignment: &AssignmentCert, backing_group: GroupIndex, ) -> Result { - let validator_public = config.assignment_keys + let validator_public = config + .assignment_keys .get(validator_index.0 as usize) .ok_or(InvalidAssignment)?; @@ -454,34 +450,33 @@ pub(crate) fn check_assignment_cert( .map_err(|_| InvalidAssignment)?; if claimed_core_index.0 >= config.n_cores { - return Err(InvalidAssignment); + return Err(InvalidAssignment) } // Check that the validator was not part of the backing group // and not already assigned. - let is_in_backing = is_in_backing_group( - &config.validator_groups, - validator_index, - backing_group, - ); + let is_in_backing = + is_in_backing_group(&config.validator_groups, validator_index, backing_group); if is_in_backing { - return Err(InvalidAssignment); + return Err(InvalidAssignment) } let &(ref vrf_output, ref vrf_proof) = &assignment.vrf; match assignment.kind { AssignmentCertKind::RelayVRFModulo { sample } => { if sample >= config.relay_vrf_modulo_samples { - return Err(InvalidAssignment); + return Err(InvalidAssignment) } - let (vrf_in_out, _) = public.vrf_verify_extra( - relay_vrf_modulo_transcript(relay_vrf_story, sample), - &vrf_output.0, - &vrf_proof.0, - assigned_core_transcript(claimed_core_index), - ).map_err(|_| InvalidAssignment)?; + let (vrf_in_out, _) = public + .vrf_verify_extra( + relay_vrf_modulo_transcript(relay_vrf_story, sample), + &vrf_output.0, + &vrf_proof.0, + assigned_core_transcript(claimed_core_index), + ) + .map_err(|_| InvalidAssignment)?; // ensure that the `vrf_in_out` actually gives us the claimed core. if relay_vrf_modulo_core(&vrf_in_out, config.n_cores) == claimed_core_index { @@ -489,24 +484,26 @@ pub(crate) fn check_assignment_cert( } else { Err(InvalidAssignment) } - } + }, AssignmentCertKind::RelayVRFDelay { core_index } => { if core_index != claimed_core_index { - return Err(InvalidAssignment); + return Err(InvalidAssignment) } - let (vrf_in_out, _) = public.vrf_verify( - relay_vrf_delay_transcript(relay_vrf_story, core_index), - &vrf_output.0, - &vrf_proof.0, - ).map_err(|_| InvalidAssignment)?; + let (vrf_in_out, _) = public + .vrf_verify( + relay_vrf_delay_transcript(relay_vrf_story, core_index), + &vrf_output.0, + &vrf_proof.0, + ) + .map_err(|_| InvalidAssignment)?; Ok(relay_vrf_delay_tranche( &vrf_in_out, config.n_delay_tranches, config.zeroth_delay_tranche_width, )) - } + }, } } @@ -521,22 +518,22 @@ fn is_in_backing_group( #[cfg(test)] mod tests { use super::*; - use sp_keystore::CryptoStore; - use sp_keyring::sr25519::Keyring as Sr25519Keyring; + use polkadot_node_primitives::approval::{VRFOutput, VRFProof}; + use polkadot_primitives::v1::{Hash, ASSIGNMENT_KEY_TYPE_ID}; use sp_application_crypto::sr25519; use sp_core::crypto::Pair as PairT; - use polkadot_primitives::v1::{ASSIGNMENT_KEY_TYPE_ID, Hash}; - use polkadot_node_primitives::approval::{VRFOutput, VRFProof}; + use sp_keyring::sr25519::Keyring as Sr25519Keyring; + use sp_keystore::CryptoStore; // sets up a keystore with the given keyring accounts. async fn make_keystore(accounts: &[Sr25519Keyring]) -> LocalKeystore { let store = LocalKeystore::in_memory(); for s in accounts.iter().copied().map(|k| k.to_seed()) { - store.sr25519_generate_new( - ASSIGNMENT_KEY_TYPE_ID, - Some(s.as_str()), - ).await.unwrap(); + store + .sr25519_generate_new(ASSIGNMENT_KEY_TYPE_ID, Some(s.as_str())) + .await + .unwrap(); } store @@ -546,12 +543,15 @@ mod tests { assignment_keys_plus_random(accounts, 0) } - fn assignment_keys_plus_random(accounts: &[Sr25519Keyring], random: usize) -> Vec { - let gen_random = (0..random).map(|_| - AssignmentId::from(sr25519::Pair::generate().0.public()) - ); + fn assignment_keys_plus_random( + accounts: &[Sr25519Keyring], + random: usize, + ) -> Vec { + let gen_random = + (0..random).map(|_| AssignmentId::from(sr25519::Pair::generate().0.public())); - accounts.iter() + accounts + .iter() .map(|k| AssignmentId::from(k.public())) .chain(gen_random) .collect() @@ -562,12 +562,14 @@ mod tests { let big_groups = n_validators % n_groups; let scraps = n_groups * size; - (0..n_groups).map(|i| { - (i * size .. (i + 1) *size) - .chain(if i < big_groups { Some(scraps + i) } else { None }) - .map(|j| ValidatorIndex(j as _)) - .collect::>() - }).collect() + (0..n_groups) + .map(|i| { + (i * size..(i + 1) * size) + .chain(if i < big_groups { Some(scraps + i) } else { None }) + .map(|j| ValidatorIndex(j as _)) + .collect::>() + }) + .collect() } // used for generating assignments where the validity of the VRF doesn't matter. @@ -581,9 +583,7 @@ mod tests { #[test] fn assignments_produced_for_non_backing() { - let keystore = futures::executor::block_on( - make_keystore(&[Sr25519Keyring::Alice]) - ); + let keystore = futures::executor::block_on(make_keystore(&[Sr25519Keyring::Alice])); let c_a = CandidateHash(Hash::repeat_byte(0)); let c_b = CandidateHash(Hash::repeat_byte(1)); @@ -598,7 +598,10 @@ mod tests { Sr25519Keyring::Bob, Sr25519Keyring::Charlie, ]), - validator_groups: vec![vec![ValidatorIndex(0)], vec![ValidatorIndex(1), ValidatorIndex(2)]], + validator_groups: vec![ + vec![ValidatorIndex(0)], + vec![ValidatorIndex(1), ValidatorIndex(2)], + ], n_cores: 2, zeroth_delay_tranche_width: 10, relay_vrf_modulo_samples: 3, @@ -615,9 +618,7 @@ mod tests { #[test] fn assign_to_nonzero_core() { - let keystore = futures::executor::block_on( - make_keystore(&[Sr25519Keyring::Alice]) - ); + let keystore = futures::executor::block_on(make_keystore(&[Sr25519Keyring::Alice])); let c_a = CandidateHash(Hash::repeat_byte(0)); let c_b = CandidateHash(Hash::repeat_byte(1)); @@ -632,7 +633,10 @@ mod tests { Sr25519Keyring::Bob, Sr25519Keyring::Charlie, ]), - validator_groups: vec![vec![ValidatorIndex(0)], vec![ValidatorIndex(1), ValidatorIndex(2)]], + validator_groups: vec![ + vec![ValidatorIndex(0)], + vec![ValidatorIndex(1), ValidatorIndex(2)], + ], n_cores: 2, zeroth_delay_tranche_width: 10, relay_vrf_modulo_samples: 3, @@ -647,9 +651,7 @@ mod tests { #[test] fn succeeds_empty_for_0_cores() { - let keystore = futures::executor::block_on( - make_keystore(&[Sr25519Keyring::Alice]) - ); + let keystore = futures::executor::block_on(make_keystore(&[Sr25519Keyring::Alice])); let relay_vrf_story = RelayVRFStory([42u8; 32]); let assignments = compute_assignments( @@ -689,14 +691,15 @@ mod tests { rotation_offset: usize, f: impl Fn(&mut MutatedAssignment) -> Option, // None = skip ) { - let keystore = futures::executor::block_on( - make_keystore(&[Sr25519Keyring::Alice]) - ); + let keystore = futures::executor::block_on(make_keystore(&[Sr25519Keyring::Alice])); let group_for_core = |i| GroupIndex(((i + rotation_offset) % n_cores) as _); let config = Config { - assignment_keys: assignment_keys_plus_random(&[Sr25519Keyring::Alice], n_validators - 1), + assignment_keys: assignment_keys_plus_random( + &[Sr25519Keyring::Alice], + n_validators - 1, + ), validator_groups: basic_groups(n_validators, n_cores), n_cores: n_cores as u32, zeroth_delay_tranche_width: 10, @@ -710,11 +713,13 @@ mod tests { relay_vrf_story.clone(), &config, (0..n_cores) - .map(|i| ( - CandidateHash(Hash::repeat_byte(i as u8)), - CoreIndex(i as u32), - group_for_core(i), - )) + .map(|i| { + ( + CandidateHash(Hash::repeat_byte(i as u8)), + CoreIndex(i as u32), + group_for_core(i), + ) + }) .collect::>(), ); @@ -743,7 +748,8 @@ mod tests { relay_vrf_story.clone(), &mutated.cert, mutated.group, - ).is_ok(); + ) + .is_ok(); assert_eq!(expected, is_good) } @@ -787,7 +793,7 @@ mod tests { AssignmentCertKind::RelayVRFDelay { .. } => { m.cert.vrf = garbage_vrf(); Some(false) - } + }, _ => None, // skip everything else. } }); @@ -800,7 +806,7 @@ mod tests { AssignmentCertKind::RelayVRFModulo { .. } => { m.cert.vrf = garbage_vrf(); Some(false) - } + }, _ => None, // skip everything else. } }); @@ -813,7 +819,7 @@ mod tests { AssignmentCertKind::RelayVRFModulo { sample } => { m.config.relay_vrf_modulo_samples = sample; Some(false) - } + }, _ => None, // skip everything else. } }); @@ -826,7 +832,7 @@ mod tests { AssignmentCertKind::RelayVRFDelay { .. } => { m.core = CoreIndex((m.core.0 + 1) % 100); Some(false) - } + }, _ => None, // skip everything else. } }); @@ -839,7 +845,7 @@ mod tests { AssignmentCertKind::RelayVRFModulo { .. } => { m.core = CoreIndex((m.core.0 + 1) % 100); Some(false) - } + }, _ => None, // skip everything else. } }); diff --git a/polkadot/node/core/approval-voting/src/import.rs b/polkadot/node/core/approval-voting/src/import.rs index 93bcd69e74a..0aa4d714606 100644 --- a/polkadot/node/core/approval-voting/src/import.rs +++ b/polkadot/node/core/approval-voting/src/import.rs @@ -28,43 +28,42 @@ //! //! We maintain a rolling window of session indices. This starts as empty +use polkadot_node_jaeger as jaeger; +use polkadot_node_primitives::approval::{ + self as approval_types, BlockApprovalMeta, RelayVRFStory, +}; use polkadot_node_subsystem::{ - overseer, messages::{ - RuntimeApiMessage, RuntimeApiRequest, ChainApiMessage, ApprovalDistributionMessage, - ChainSelectionMessage, + ApprovalDistributionMessage, ChainApiMessage, ChainSelectionMessage, RuntimeApiMessage, + RuntimeApiRequest, }, - SubsystemContext, SubsystemError, SubsystemResult, + overseer, SubsystemContext, SubsystemError, SubsystemResult, }; -use polkadot_node_subsystem_util::determine_new_blocks; -use polkadot_node_subsystem_util::rolling_session_window::{ - RollingSessionWindow, SessionWindowUpdate, +use polkadot_node_subsystem_util::{ + determine_new_blocks, + rolling_session_window::{RollingSessionWindow, SessionWindowUpdate}, }; use polkadot_primitives::v1::{ - Hash, SessionIndex, CandidateEvent, Header, CandidateHash, - CandidateReceipt, CoreIndex, GroupIndex, BlockNumber, ConsensusLog, -}; -use polkadot_node_primitives::approval::{ - self as approval_types, BlockApprovalMeta, RelayVRFStory, + BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, ConsensusLog, CoreIndex, + GroupIndex, Hash, Header, SessionIndex, }; -use polkadot_node_jaeger as jaeger; use sc_keystore::LocalKeystore; use sp_consensus_slots::Slot; -use futures::prelude::*; -use futures::channel::oneshot; use bitvec::order::Lsb0 as BitOrderLsb0; +use futures::{channel::oneshot, prelude::*}; -use std::collections::HashMap; -use std::convert::TryFrom; +use std::{collections::HashMap, convert::TryFrom}; use super::approval_db::v1; -use crate::backend::{Backend, OverlayedBackend}; -use crate::persisted_entries::CandidateEntry; -use crate::criteria::{AssignmentCriteria, OurAssignment}; -use crate::time::{slot_number_to_tick, Tick}; +use crate::{ + backend::{Backend, OverlayedBackend}, + criteria::{AssignmentCriteria, OurAssignment}, + persisted_entries::CandidateEntry, + time::{slot_number_to_tick, Tick}, +}; -use super::{LOG_TARGET, State}; +use super::{State, LOG_TARGET}; struct ImportedBlockInfo { included_candidates: Vec<(CandidateHash, CandidateReceipt, CoreIndex, GroupIndex)>, @@ -99,7 +98,8 @@ async fn imported_block_info( ctx.send_message(RuntimeApiMessage::Request( block_hash, RuntimeApiRequest::CandidateEvents(c_tx), - )).await; + )) + .await; let events: Vec = match c_rx.await { Ok(Ok(events)) => events, @@ -107,11 +107,14 @@ async fn imported_block_info( Err(_) => return Ok(None), }; - events.into_iter().filter_map(|e| match e { - CandidateEvent::CandidateIncluded(receipt, _, core, group) - => Some((receipt.hash(), receipt, core, group)), - _ => None, - }).collect() + events + .into_iter() + .filter_map(|e| match e { + CandidateEvent::CandidateIncluded(receipt, _, core, group) => + Some((receipt.hash(), receipt, core, group)), + _ => None, + }) + .collect() }; // fetch session. ignore blocks that are too old, but unless sessions are really @@ -121,7 +124,8 @@ async fn imported_block_info( ctx.send_message(RuntimeApiMessage::Request( block_header.parent_hash, RuntimeApiRequest::SessionIndexForChild(s_tx), - )).await; + )) + .await; let session_index = match s_rx.await { Ok(Ok(s)) => s, @@ -130,10 +134,14 @@ async fn imported_block_info( }; if env.session_window.earliest_session().map_or(true, |e| session_index < e) { - tracing::debug!(target: LOG_TARGET, "Block {} is from ancient session {}. Skipping", - block_hash, session_index); + tracing::debug!( + target: LOG_TARGET, + "Block {} is from ancient session {}. Skipping", + block_hash, + session_index + ); - return Ok(None); + return Ok(None) } session_index @@ -162,7 +170,8 @@ async fn imported_block_info( ctx.send_message(RuntimeApiMessage::Request( block_hash, RuntimeApiRequest::CurrentBabeEpoch(s_tx), - )).await; + )) + .await; match s_rx.await { Ok(Ok(s)) => s, @@ -180,8 +189,8 @@ async fn imported_block_info( block_hash, ); - return Ok(None); - } + return Ok(None) + }, }; let (assignments, slot, relay_vrf_story) = { @@ -201,7 +210,8 @@ async fn imported_block_info( &env.keystore, relay_vrf.clone(), &crate::criteria::Config::from(session_info), - included_candidates.iter() + included_candidates + .iter() .map(|(c_hash, _, core, group)| (*c_hash, *core, *group)) .collect(), ); @@ -210,7 +220,7 @@ async fn imported_block_info( }, Err(_) => return Ok(None), } - } + }, None => { tracing::debug!( target: LOG_TARGET, @@ -218,16 +228,12 @@ async fn imported_block_info( block_hash, ); - return Ok(None); - } + return Ok(None) + }, } }; - tracing::trace!( - target: LOG_TARGET, - n_assignments = assignments.len(), - "Produced assignments" - ); + tracing::trace!(target: LOG_TARGET, n_assignments = assignments.len(), "Produced assignments"); let force_approve = block_header.digest.convert_first(|l| match ConsensusLog::from_digest_item(l) { @@ -241,7 +247,7 @@ async fn imported_block_info( ); Some(num) - } + }, Ok(Some(_)) => None, Ok(None) => None, Err(err) => { @@ -253,7 +259,7 @@ async fn imported_block_info( ); None - } + }, }); Ok(Some(ImportedBlockInfo { @@ -291,8 +297,7 @@ pub(crate) async fn handle_new_head( db: &mut OverlayedBackend<'_, impl Backend>, head: Hash, finalized_number: &Option, -) -> SubsystemResult> -{ +) -> SubsystemResult> { // Update session info based on most recent head. let mut span = jaeger::Span::new(head, "approval-checking-import"); @@ -309,13 +314,13 @@ pub(crate) async fn handle_new_head( e, ); - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, Ok(None) => { tracing::warn!(target: LOG_TARGET, "Missing header for new head {}", head); - return Ok(Vec::new()); - } - Ok(Some(h)) => h + return Ok(Vec::new()) + }, + Ok(Some(h)) => h, } }; @@ -329,15 +334,15 @@ pub(crate) async fn handle_new_head( ); return Ok(Vec::new()) - } + }, Ok(a @ SessionWindowUpdate::Advanced { .. }) => { tracing::info!( target: LOG_TARGET, update = ?a, "Advanced session window for approvals", ); - } - Ok(_) => {} + }, + Ok(_) => {}, } // If we've just started the node and haven't yet received any finality notifications, @@ -351,12 +356,14 @@ pub(crate) async fn handle_new_head( &header, lower_bound_number, ) - .map_err(|e| SubsystemError::with_origin("approval-voting", e)) - .await?; + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) + .await?; span.add_uint_tag("new-blocks", new_blocks.len() as u64); - if new_blocks.is_empty() { return Ok(Vec::new()) } + if new_blocks.is_empty() { + return Ok(Vec::new()) + } let mut approval_meta: Vec = Vec::with_capacity(new_blocks.len()); let mut imported_candidates = Vec::with_capacity(new_blocks.len()); @@ -376,9 +383,11 @@ pub(crate) async fn handle_new_head( None => { // It's possible that we've lost a race with finality. let (tx, rx) = oneshot::channel(); - ctx.send_message( - ChainApiMessage::FinalizedBlockHash(block_header.number.clone(), tx) - ).await; + ctx.send_message(ChainApiMessage::FinalizedBlockHash( + block_header.number.clone(), + tx, + )) + .await; let lost_to_finality = match rx.await { Ok(Ok(Some(h))) if h != block_hash => true, @@ -395,7 +404,7 @@ pub(crate) async fn handle_new_head( ); } - return Ok(Vec::new()); + return Ok(Vec::new()) }, }; } @@ -420,7 +429,9 @@ pub(crate) async fn handle_new_head( force_approve, } = imported_block_info; - let session_info = state.session_window.session_info(session_index) + let session_info = state + .session_window + .session_info(session_index) .expect("imported_block_info requires session to be available; qed"); let (block_tick, no_show_duration) = { @@ -432,7 +443,8 @@ pub(crate) async fn handle_new_head( (block_tick, no_show_duration) }; let needed_approvals = session_info.needed_approvals; - let validator_group_lens: Vec = session_info.validator_groups.iter().map(|v| v.len()).collect(); + let validator_group_lens: Vec = + session_info.validator_groups.iter().map(|v| v.len()).collect(); // insta-approve candidates on low-node testnets: // cf. https://github.com/paritytech/polkadot/issues/2411 let num_candidates = included_candidates.len(); @@ -447,10 +459,10 @@ pub(crate) async fn handle_new_head( } else { let mut result = bitvec::bitvec![BitOrderLsb0, u8; 0; num_candidates]; for (i, &(_, _, _, backing_group)) in included_candidates.iter().enumerate() { - let backing_group_size = validator_group_lens.get(backing_group.0 as usize) - .copied() - .unwrap_or(0); - let needed_approvals = usize::try_from(needed_approvals).expect("usize is at least u32; qed"); + let backing_group_size = + validator_group_lens.get(backing_group.0 as usize).copied().unwrap_or(0); + let needed_approvals = + usize::try_from(needed_approvals).expect("usize is at least u32; qed"); if n_validators.saturating_sub(backing_group_size) < needed_approvals { result.set(i, true); } @@ -481,19 +493,16 @@ pub(crate) async fn handle_new_head( session: session_index, slot, relay_vrf_story: relay_vrf_story.0, - candidates: included_candidates.iter() - .map(|(hash, _, core, _)| (*core, *hash)).collect(), + candidates: included_candidates + .iter() + .map(|(hash, _, core, _)| (*core, *hash)) + .collect(), approved_bitfield, children: Vec::new(), }; if let Some(up_to) = force_approve { - tracing::debug!( - target: LOG_TARGET, - ?block_hash, - up_to, - "Enacting force-approve", - ); + tracing::debug!(target: LOG_TARGET, ?block_hash, up_to, "Enacting force-approve",); let approved_hashes = crate::ops::force_approve(db, block_hash, up_to) .map_err(|e| SubsystemError::with_origin("approval-voting", e))?; @@ -511,19 +520,19 @@ pub(crate) async fn handle_new_head( "Writing BlockEntry", ); - let candidate_entries = crate::ops::add_block_entry( - db, - block_entry.into(), - n_validators, - |candidate_hash| { - included_candidates.iter().find(|(hash, _, _, _)| candidate_hash == hash) - .map(|(_, receipt, core, backing_group)| super::ops::NewCandidateInfo::new( - receipt.clone(), - *backing_group, - assignments.get(core).map(|a| a.clone().into()), - )) - } - ).map_err(|e| SubsystemError::with_origin("approval-voting", e))?; + let candidate_entries = + crate::ops::add_block_entry(db, block_entry.into(), n_validators, |candidate_hash| { + included_candidates.iter().find(|(hash, _, _, _)| candidate_hash == hash).map( + |(_, receipt, core, backing_group)| { + super::ops::NewCandidateInfo::new( + receipt.clone(), + *backing_group, + assignments.get(core).map(|a| a.clone().into()), + ) + }, + ) + }) + .map_err(|e| SubsystemError::with_origin("approval-voting", e))?; approval_meta.push(BlockApprovalMeta { hash: block_hash, number: block_header.number, @@ -532,18 +541,16 @@ pub(crate) async fn handle_new_head( slot, }); - imported_candidates.push( - BlockImportedCandidates { - block_hash, - block_number: block_header.number, - block_tick, - no_show_duration, - imported_candidates: candidate_entries - .into_iter() - .map(|(h, e)| (h, e.into())) - .collect(), - } - ); + imported_candidates.push(BlockImportedCandidates { + block_hash, + block_number: block_header.number, + block_tick, + no_show_duration, + imported_candidates: candidate_entries + .into_iter() + .map(|(h, e)| (h, e.into())) + .collect(), + }); } tracing::trace!( @@ -562,33 +569,30 @@ pub(crate) async fn handle_new_head( pub(crate) mod tests { use super::*; use crate::approval_db::v1::DbBackend; - use polkadot_node_subsystem_test_helpers::make_subsystem_context; + use assert_matches::assert_matches; + use kvdb::KeyValueDB; + use merlin::Transcript; use polkadot_node_primitives::approval::{VRFOutput, VRFProof}; - use polkadot_primitives::v1::{SessionInfo, ValidatorIndex}; use polkadot_node_subsystem::messages::AllMessages; - use sp_core::testing::TaskExecutor; - pub(crate) use sp_runtime::{Digest, DigestItem}; + use polkadot_node_subsystem_test_helpers::make_subsystem_context; + use polkadot_primitives::v1::{SessionInfo, ValidatorIndex}; pub(crate) use sp_consensus_babe::{ - Epoch as BabeEpoch, BabeEpochConfiguration, AllowedSlots, + digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest}, + AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch, }; - pub(crate) use sp_consensus_babe::digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest}; + use sp_core::testing::TaskExecutor; use sp_keyring::sr25519::Keyring as Sr25519Keyring; - use assert_matches::assert_matches; - use merlin::Transcript; + pub(crate) use sp_runtime::{Digest, DigestItem}; use std::{pin::Pin, sync::Arc}; - use kvdb::KeyValueDB; use crate::{ - APPROVAL_SESSIONS, criteria, BlockEntry, - approval_db::v1::Config as DatabaseConfig, + approval_db::v1::Config as DatabaseConfig, criteria, BlockEntry, APPROVAL_SESSIONS, }; const DATA_COL: u32 = 0; const NUM_COLUMNS: u32 = 1; - const TEST_CONFIG: DatabaseConfig = DatabaseConfig { - col_data: DATA_COL, - }; + const TEST_CONFIG: DatabaseConfig = DatabaseConfig { col_data: DATA_COL }; #[derive(Default)] struct MockClock; @@ -598,9 +602,7 @@ pub(crate) mod tests { } fn wait(&self, _tick: Tick) -> Pin + Send + 'static>> { - Box::pin(async move { - () - }) + Box::pin(async move { () }) } } @@ -633,7 +635,11 @@ pub(crate) mod tests { _keystore: &LocalKeystore, _relay_vrf_story: polkadot_node_primitives::approval::RelayVRFStory, _config: &criteria::Config, - _leaving_cores: Vec<(CandidateHash, polkadot_primitives::v1::CoreIndex, polkadot_primitives::v1::GroupIndex)>, + _leaving_cores: Vec<( + CandidateHash, + polkadot_primitives::v1::CoreIndex, + polkadot_primitives::v1::GroupIndex, + )>, ) -> HashMap { HashMap::new() } @@ -675,7 +681,6 @@ pub(crate) mod tests { } } - #[test] fn imported_block_info_is_good() { let pool = TaskExecutor::new(); @@ -691,12 +696,7 @@ pub(crate) mod tests { let mut d = Digest::default(); let (vrf_output, vrf_proof) = garbage_vrf(); d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( - SecondaryVRFPreDigest { - authority_index: 0, - slot, - vrf_output, - vrf_proof, - } + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_output, vrf_proof }, ))); d @@ -719,13 +719,15 @@ pub(crate) mod tests { (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), ]; - - let inclusion_events = candidates.iter().cloned() + let inclusion_events = candidates + .iter() + .cloned() .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) .collect::>(); let test_fut = { - let included_candidates = candidates.iter() + let included_candidates = candidates + .iter() .map(|(r, c, g)| (r.hash(), r.clone(), *c, *g)) .collect::>(); @@ -743,12 +745,8 @@ pub(crate) mod tests { keystore: &LocalKeystore::in_memory(), }; - let info = imported_block_info( - &mut ctx, - env, - hash, - &header, - ).await.unwrap().unwrap(); + let info = + imported_block_info(&mut ctx, env, hash, &header).await.unwrap().unwrap(); assert_eq!(info.included_candidates, included_candidates); assert_eq!(info.session_index, session); @@ -835,7 +833,9 @@ pub(crate) mod tests { (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), ]; - let inclusion_events = candidates.iter().cloned() + let inclusion_events = candidates + .iter() + .cloned() .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) .collect::>(); @@ -854,12 +854,7 @@ pub(crate) mod tests { keystore: &LocalKeystore::in_memory(), }; - let info = imported_block_info( - &mut ctx, - env, - hash, - &header, - ).await.unwrap(); + let info = imported_block_info(&mut ctx, env, hash, &header).await.unwrap(); assert!(info.is_none()); }) @@ -940,7 +935,9 @@ pub(crate) mod tests { (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), ]; - let inclusion_events = candidates.iter().cloned() + let inclusion_events = candidates + .iter() + .cloned() .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) .collect::>(); @@ -955,12 +952,7 @@ pub(crate) mod tests { keystore: &LocalKeystore::in_memory(), }; - let info = imported_block_info( - &mut ctx, - env, - hash, - &header, - ).await.unwrap(); + let info = imported_block_info(&mut ctx, env, hash, &header).await.unwrap(); assert!(info.is_none()); }) @@ -1008,12 +1000,7 @@ pub(crate) mod tests { let mut d = Digest::default(); let (vrf_output, vrf_proof) = garbage_vrf(); d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( - SecondaryVRFPreDigest { - authority_index: 0, - slot, - vrf_output, - vrf_proof, - } + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_output, vrf_proof }, ))); d.push(ConsensusLog::ForceApprove(3).into()); @@ -1038,13 +1025,15 @@ pub(crate) mod tests { (make_candidate(2.into()), CoreIndex(1), GroupIndex(3)), ]; - - let inclusion_events = candidates.iter().cloned() + let inclusion_events = candidates + .iter() + .cloned() .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) .collect::>(); let test_fut = { - let included_candidates = candidates.iter() + let included_candidates = candidates + .iter() .map(|(r, c, g)| (r.hash(), r.clone(), *c, *g)) .collect::>(); @@ -1062,12 +1051,8 @@ pub(crate) mod tests { keystore: &LocalKeystore::in_memory(), }; - let info = imported_block_info( - &mut ctx, - env, - hash, - &header, - ).await.unwrap().unwrap(); + let info = + imported_block_info(&mut ctx, env, hash, &header).await.unwrap().unwrap(); assert_eq!(info.included_candidates, included_candidates); assert_eq!(info.session_index, session); @@ -1159,12 +1144,7 @@ pub(crate) mod tests { let mut d = Digest::default(); let (vrf_output, vrf_proof) = garbage_vrf(); d.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( - SecondaryVRFPreDigest { - authority_index: 0, - slot, - vrf_output, - vrf_proof, - } + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_output, vrf_proof }, ))); d @@ -1186,7 +1166,9 @@ pub(crate) mod tests { (make_candidate(1.into()), CoreIndex(0), GroupIndex(0)), (make_candidate(2.into()), CoreIndex(1), GroupIndex(1)), ]; - let inclusion_events = candidates.iter().cloned() + let inclusion_events = candidates + .iter() + .cloned() .map(|(r, c, g)| CandidateEvent::CandidateIncluded(r, Vec::new().into(), c, g)) .collect::>(); @@ -1202,7 +1184,8 @@ pub(crate) mod tests { candidates: Vec::new(), approved_bitfield: Default::default(), children: Vec::new(), - }.into() + } + .into(), ); let write_ops = overlay_db.into_write_ops(); @@ -1211,13 +1194,9 @@ pub(crate) mod tests { let test_fut = { Box::pin(async move { let mut overlay_db = OverlayedBackend::new(&db); - let result = handle_new_head( - &mut ctx, - &mut state, - &mut overlay_db, - hash, - &Some(1), - ).await.unwrap(); + let result = handle_new_head(&mut ctx, &mut state, &mut overlay_db, hash, &Some(1)) + .await + .unwrap(); let write_ops = overlay_db.into_write_ops(); db.write(write_ops).unwrap(); @@ -1229,14 +1208,11 @@ pub(crate) mod tests { assert_eq!(candidates[1].1.approvals().len(), 6); // the first candidate should be insta-approved // the second should not - let entry: BlockEntry = v1::load_block_entry( - db_writer.as_ref(), - &TEST_CONFIG, - &hash, - ) - .unwrap() - .unwrap() - .into(); + let entry: BlockEntry = + v1::load_block_entry(db_writer.as_ref(), &TEST_CONFIG, &hash) + .unwrap() + .unwrap() + .into(); assert!(entry.is_candidate_approved(&candidates[0].0)); assert!(!entry.is_candidate_approved(&candidates[1].0)); }) diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 75410b5099b..d168f43b5bf 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -21,55 +21,59 @@ //! of others. It uses this information to determine when candidates and blocks have //! been sufficiently approved to finalize. +use kvdb::KeyValueDB; +use polkadot_node_jaeger as jaeger; +use polkadot_node_primitives::{ + approval::{ + BlockApprovalMeta, DelayTranche, IndirectAssignmentCert, IndirectSignedApprovalVote, + }, + SignedDisputeStatement, ValidationResult, +}; use polkadot_node_subsystem::{ + errors::RecoveryError, messages::{ - AssignmentCheckError, AssignmentCheckResult, ApprovalCheckError, ApprovalCheckResult, - ApprovalVotingMessage, RuntimeApiMessage, RuntimeApiRequest, ChainApiMessage, - ApprovalDistributionMessage, CandidateValidationMessage, - AvailabilityRecoveryMessage, ChainSelectionMessage, DisputeCoordinatorMessage, - ImportStatementsResult, HighestApprovedAncestorBlock, BlockDescription, + ApprovalCheckError, ApprovalCheckResult, ApprovalDistributionMessage, + ApprovalVotingMessage, AssignmentCheckError, AssignmentCheckResult, + AvailabilityRecoveryMessage, BlockDescription, CandidateValidationMessage, ChainApiMessage, + ChainSelectionMessage, DisputeCoordinatorMessage, HighestApprovedAncestorBlock, + ImportStatementsResult, RuntimeApiMessage, RuntimeApiRequest, }, - errors::RecoveryError, - overseer::{self, SubsystemSender as _}, SubsystemContext, SubsystemError, SubsystemResult, SpawnedSubsystem, - FromOverseer, OverseerSignal, SubsystemSender, + overseer::{self, SubsystemSender as _}, + FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, + SubsystemResult, SubsystemSender, }; use polkadot_node_subsystem_util::{ - TimeoutExt, metrics::{self, prometheus}, rolling_session_window::RollingSessionWindow, + TimeoutExt, }; use polkadot_primitives::v1::{ - ValidatorIndex, Hash, SessionIndex, SessionInfo, CandidateHash, - CandidateReceipt, BlockNumber, - ValidatorPair, ValidatorSignature, ValidatorId, - CandidateIndex, GroupIndex, ApprovalVote, DisputeStatement, - ValidDisputeStatementKind, + ApprovalVote, BlockNumber, CandidateHash, CandidateIndex, CandidateReceipt, DisputeStatement, + GroupIndex, Hash, SessionIndex, SessionInfo, ValidDisputeStatementKind, ValidatorId, + ValidatorIndex, ValidatorPair, ValidatorSignature, }; -use polkadot_node_primitives::{SignedDisputeStatement, ValidationResult}; -use polkadot_node_primitives::approval::{ - IndirectAssignmentCert, IndirectSignedApprovalVote, DelayTranche, BlockApprovalMeta, -}; -use polkadot_node_jaeger as jaeger; use sc_keystore::LocalKeystore; +use sp_application_crypto::Pair; use sp_consensus::SyncOracle; use sp_consensus_slots::Slot; -use sp_application_crypto::Pair; -use kvdb::KeyValueDB; -use futures::prelude::*; -use futures::future::{BoxFuture, RemoteHandle}; -use futures::channel::oneshot; -use futures::stream::FuturesUnordered; +use futures::{ + channel::oneshot, + future::{BoxFuture, RemoteHandle}, + prelude::*, + stream::FuturesUnordered, +}; -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::collections::btree_map::Entry; -use std::sync::Arc; -use std::time::Duration; +use std::{ + collections::{btree_map::Entry, BTreeMap, HashMap, HashSet}, + sync::Arc, + time::Duration, +}; use approval_checking::RequiredTranches; -use persisted_entries::{ApprovalEntry, CandidateEntry, BlockEntry}; use criteria::{AssignmentCriteria, RealAssignmentCriteria}; -use time::{slot_number_to_tick, Tick, Clock, ClockExt, SystemClock}; +use persisted_entries::{ApprovalEntry, BlockEntry, CandidateEntry}; +use time::{slot_number_to_tick, Clock, ClockExt, SystemClock, Tick}; mod approval_checking; mod approval_db; @@ -77,11 +81,13 @@ mod backend; mod criteria; mod import; mod ops; -mod time; mod persisted_entries; +mod time; -use crate::approval_db::v1::{DbBackend, Config as DatabaseConfig}; -use crate::backend::{Backend, OverlayedBackend}; +use crate::{ + approval_db::v1::{Config as DatabaseConfig, DbBackend}, + backend::{Backend, OverlayedBackend}, +}; #[cfg(test)] mod tests; @@ -325,9 +331,7 @@ impl ApprovalVotingSubsystem { keystore, slot_duration_millis: config.slot_duration_millis, db, - db_config: DatabaseConfig { - col_data: config.col_data, - }, + db_config: DatabaseConfig { col_data: config.col_data }, mode: Mode::Syncing(sync_oracle), metrics, } @@ -339,7 +343,6 @@ where Context: SubsystemContext, Context: overseer::SubsystemContext, { - fn start(self, ctx: Context) -> SpawnedSubsystem { let backend = DbBackend::new(self.db.clone(), self.db_config); let future = run::( @@ -349,13 +352,10 @@ where Box::new(RealAssignmentCriteria), backend, ) - .map_err(|e| SubsystemError::with_origin("approval-voting", e)) - .boxed(); + .map_err(|e| SubsystemError::with_origin("approval-voting", e)) + .boxed(); - SpawnedSubsystem { - name: "approval-voting-subsystem", - future, - } + SpawnedSubsystem { name: "approval-voting-subsystem", future } } } @@ -393,12 +393,14 @@ impl Wakeups { tick: Tick, ) { if let Some(prev) = self.reverse_wakeups.get(&(block_hash, candidate_hash)) { - if prev <= &tick { return } + if prev <= &tick { + return + } // we are replacing previous wakeup with an earlier one. if let Entry::Occupied(mut entry) = self.wakeups.entry(*prev) { - if let Some(pos) = entry.get().iter() - .position(|x| x == &(block_hash, candidate_hash)) + if let Some(pos) = + entry.get().iter().position(|x| x == &(block_hash, candidate_hash)) { entry.get_mut().remove(pos); } @@ -426,9 +428,7 @@ impl Wakeups { self.reverse_wakeups.retain(|&(ref h, ref c_h), tick| { let live = !pruned_blocks.contains(h); if !live { - pruned_wakeups.entry(*tick) - .or_insert_with(HashSet::new) - .insert((*h, *c_h)); + pruned_wakeups.entry(*tick).or_insert_with(HashSet::new).insert((*h, *c_h)); } live }); @@ -455,7 +455,8 @@ impl Wakeups { Some(tick) => { clock.wait(tick).await; match self.wakeups.entry(tick) { - Entry::Vacant(_) => panic!("entry is known to exist since `first` was `Some`; qed"), + Entry::Vacant(_) => + panic!("entry is known to exist since `first` was `Some`; qed"), Entry::Occupied(mut entry) => { let (hash, candidate_hash) = entry.get_mut().pop() .expect("empty entries are removed here and in `schedule`; no other mutation of this map; qed"); @@ -467,9 +468,9 @@ impl Wakeups { self.reverse_wakeups.remove(&(hash, candidate_hash)); (tick, hash, candidate_hash) - } + }, } - } + }, } } } @@ -494,25 +495,11 @@ struct ApprovalState { } impl ApprovalState { - fn approved( - validator_index: ValidatorIndex, - candidate_hash: CandidateHash, - ) -> Self { - Self { - validator_index, - candidate_hash, - approval_outcome: ApprovalOutcome::Approved, - } + fn approved(validator_index: ValidatorIndex, candidate_hash: CandidateHash) -> Self { + Self { validator_index, candidate_hash, approval_outcome: ApprovalOutcome::Approved } } - fn failed( - validator_index: ValidatorIndex, - candidate_hash: CandidateHash, - ) -> Self { - Self { - validator_index, - candidate_hash, - approval_outcome: ApprovalOutcome::Failed, - } + fn failed(validator_index: ValidatorIndex, candidate_hash: CandidateHash) -> Self { + Self { validator_index, candidate_hash, approval_outcome: ApprovalOutcome::Failed } } } @@ -523,10 +510,7 @@ struct CurrentlyCheckingSet { impl Default for CurrentlyCheckingSet { fn default() -> Self { - Self { - candidate_hash_map: HashMap::new(), - currently_checking: FuturesUnordered::new(), - } + Self { candidate_hash_map: HashMap::new(), currently_checking: FuturesUnordered::new() } } } @@ -540,25 +524,21 @@ impl CurrentlyCheckingSet { relay_block: Hash, launch_work: impl Future>>, ) -> SubsystemResult<()> { - let val = self.candidate_hash_map - .entry(candidate_hash) - .or_insert(Default::default()); + let val = self.candidate_hash_map.entry(candidate_hash).or_insert(Default::default()); if let Err(k) = val.binary_search_by_key(&relay_block, |v| *v) { let _ = val.insert(k, relay_block); let work = launch_work.await?; - self.currently_checking.push( - Box::pin(async move { - match work.timeout(APPROVAL_CHECKING_TIMEOUT).await { - None => ApprovalState { - candidate_hash, - validator_index, - approval_outcome: ApprovalOutcome::TimedOut, - }, - Some(approval_state) => approval_state, - } - }) - ); + self.currently_checking.push(Box::pin(async move { + match work.timeout(APPROVAL_CHECKING_TIMEOUT).await { + None => ApprovalState { + candidate_hash, + validator_index, + approval_outcome: ApprovalOutcome::TimedOut, + }, + Some(approval_state) => approval_state, + } + })); } Ok(()) @@ -569,13 +549,16 @@ impl CurrentlyCheckingSet { approvals_cache: &mut lru::LruCache, ) -> (Vec, ApprovalState) { if !self.currently_checking.is_empty() { - if let Some(approval_state) = self.currently_checking - .next() - .await - { - let out = self.candidate_hash_map.remove(&approval_state.candidate_hash).unwrap_or_default(); - approvals_cache.put(approval_state.candidate_hash.clone(), approval_state.approval_outcome.clone()); - return (out, approval_state); + if let Some(approval_state) = self.currently_checking.next().await { + let out = self + .candidate_hash_map + .remove(&approval_state.candidate_hash) + .unwrap_or_default(); + approvals_cache.put( + approval_state.candidate_hash.clone(), + approval_state.approval_outcome.clone(), + ); + return (out, approval_state) } } @@ -607,9 +590,13 @@ impl State { let session_info = match self.session_info(block_entry.session()) { Some(s) => s, None => { - tracing::warn!(target: LOG_TARGET, "Unknown session info for {}", block_entry.session()); - return None; - } + tracing::warn!( + target: LOG_TARGET, + "Unknown session info for {}", + block_entry.session() + ); + return None + }, }; let block_hash = block_entry.block_hash(); @@ -627,14 +614,10 @@ impl State { tranche_now, block_tick, no_show_duration, - session_info.needed_approvals as _ + session_info.needed_approvals as _, ); - let status = ApprovalStatus { - required_tranches, - block_tick, - tranche_now, - }; + let status = ApprovalStatus { required_tranches, block_tick, tranche_now }; Some((approval_entry, status)) } else { @@ -681,10 +664,10 @@ async fn run( assignment_criteria: Box, mut backend: B, ) -> SubsystemResult<()> - where - Context: SubsystemContext, - Context: overseer::SubsystemContext, - B: Backend, +where + Context: SubsystemContext, + Context: overseer::SubsystemContext, + B: Backend, { let mut state = State { session_window: RollingSessionWindow::new(APPROVAL_SESSIONS), @@ -774,8 +757,10 @@ async fn run( &mut approvals_cache, &mut subsystem.mode, actions, - ).await? { - break; + ) + .await? + { + break } if !overlayed_db.is_empty() { @@ -809,7 +794,8 @@ async fn run( // // returns `true` if any of the actions was a `Conclude` command. async fn handle_actions( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), state: &mut State, overlayed_db: &mut OverlayedBackend<'_, impl Backend>, metrics: &Metrics, @@ -824,40 +810,37 @@ async fn handle_actions( let mut actions_iter = actions.into_iter(); while let Some(action) = actions_iter.next() { match action { - Action::ScheduleWakeup { - block_hash, - block_number, - candidate_hash, - tick, - } => wakeups.schedule(block_hash, block_number, candidate_hash, tick), + Action::ScheduleWakeup { block_hash, block_number, candidate_hash, tick } => + wakeups.schedule(block_hash, block_number, candidate_hash, tick), Action::IssueApproval(candidate_hash, approval_request) => { - let mut sender = ctx.sender().clone(); - // Note that the IssueApproval action will create additional - // actions that will need to all be processed before we can - // handle the next action in the set passed to the ambient - // function. - // - // In order to achieve this, we append the existing iterator - // to the end of the iterator made up of these newly generated - // actions. - // - // Note that chaining these iterators is O(n) as we must consume - // the prior iterator. - let next_actions: Vec = issue_approval( - &mut sender, - state, - overlayed_db, - metrics, - candidate_hash, - approval_request, - ).await? - .into_iter() - .map(|v| v.clone()) - .chain(actions_iter) - .collect(); - - actions_iter = next_actions.into_iter(); - } + let mut sender = ctx.sender().clone(); + // Note that the IssueApproval action will create additional + // actions that will need to all be processed before we can + // handle the next action in the set passed to the ambient + // function. + // + // In order to achieve this, we append the existing iterator + // to the end of the iterator made up of these newly generated + // actions. + // + // Note that chaining these iterators is O(n) as we must consume + // the prior iterator. + let next_actions: Vec = issue_approval( + &mut sender, + state, + overlayed_db, + metrics, + candidate_hash, + approval_request, + ) + .await? + .into_iter() + .map(|v| v.clone()) + .chain(actions_iter) + .collect(); + + actions_iter = next_actions.into_iter(); + }, Action::LaunchApproval { candidate_hash, indirect_cert, @@ -869,7 +852,9 @@ async fn handle_actions( backing_group, } => { // Don't launch approval work if the node is syncing. - if let Mode::Syncing(_) = *mode { continue } + if let Mode::Syncing(_) = *mode { + continue + } metrics.on_assignment_produced(assignment_tranche); let block_hash = indirect_cert.block_hash; @@ -882,42 +867,40 @@ async fn handle_actions( match approvals_cache.get(&candidate_hash) { Some(ApprovalOutcome::Approved) => { - let new_actions: Vec = std::iter::once( - Action::IssueApproval( - candidate_hash, - ApprovalVoteRequest { - validator_index, - block_hash, - } - ) - ) - .map(|v| v.clone()) - .chain(actions_iter) - .collect(); + let new_actions: Vec = std::iter::once(Action::IssueApproval( + candidate_hash, + ApprovalVoteRequest { validator_index, block_hash }, + )) + .map(|v| v.clone()) + .chain(actions_iter) + .collect(); actions_iter = new_actions.into_iter(); }, None => { let ctx = &mut *ctx; - currently_checking_set.insert_relay_block_hash( - candidate_hash, - validator_index, - relay_block_hash, - async move { - launch_approval( - ctx, - metrics.clone(), - session, - candidate, - validator_index, - block_hash, - backing_group, - ).await - } - ).await?; - } + currently_checking_set + .insert_relay_block_hash( + candidate_hash, + validator_index, + relay_block_hash, + async move { + launch_approval( + ctx, + metrics.clone(), + session, + candidate, + validator_index, + block_hash, + backing_group, + ) + .await + }, + ) + .await?; + }, Some(_) => {}, } - } + }, Action::InformDisputeCoordinator { candidate_hash, candidate_receipt, @@ -932,31 +915,32 @@ async fn handle_actions( session, statements: vec![(dispute_statement, validator_index)], pending_confirmation, - }).await; + }) + .await; match confirmation_rx.await { - Err(oneshot::Canceled) => tracing::warn!( - target: LOG_TARGET, - "Dispute coordinator confirmation lost", - ), - Ok(ImportStatementsResult::ValidImport) => {} + Err(oneshot::Canceled) => + tracing::warn!(target: LOG_TARGET, "Dispute coordinator confirmation lost",), + Ok(ImportStatementsResult::ValidImport) => {}, Ok(ImportStatementsResult::InvalidImport) => tracing::warn!( target: LOG_TARGET, "Failed to import statements of validity", ), } - } + }, Action::NoteApprovedInChainSelection(block_hash) => { ctx.send_message(ChainSelectionMessage::Approved(block_hash)).await; - } + }, Action::BecomeActive => { *mode = Mode::Active; let messages = distribution_messages_for_activation(overlayed_db)?; ctx.send_messages(messages.into_iter()).await; - } - Action::Conclude => { conclude = true; } + }, + Action::Conclude => { + conclude = true; + }, } } @@ -977,14 +961,10 @@ fn distribution_messages_for_activation( let block_entry = match db.load_block_entry(&block_hash)? { Some(b) => b, None => { - tracing::warn!( - target: LOG_TARGET, - ?block_hash, - "Missing block entry", - ); + tracing::warn!(target: LOG_TARGET, ?block_hash, "Missing block entry",); continue - } + }, }; approval_meta.push(BlockApprovalMeta { hash: block_hash, @@ -1006,7 +986,7 @@ fn distribution_messages_for_activation( ); continue - } + }, }; match candidate_entry.approval_entry(&block_hash) { @@ -1022,7 +1002,7 @@ fn distribution_messages_for_activation( }, i as _, )); - } + }, (Some(assignment), Some(approval_sig)) => { messages.push(ApprovalDistributionMessage::DistributeAssignment( IndirectAssignmentCert { @@ -1039,11 +1019,11 @@ fn distribution_messages_for_activation( candidate_index: i as _, validator: assignment.validator_index(), signature: approval_sig, - } + }, )) - } + }, } - } + }, None => { tracing::warn!( target: LOG_TARGET, @@ -1051,7 +1031,7 @@ fn distribution_messages_for_activation( ?candidate_hash, "Missing approval entry", ); - } + }, } } } @@ -1062,7 +1042,8 @@ fn distribution_messages_for_activation( // Handle an incoming signal from the overseer. Returns true if execution should conclude. async fn handle_from_overseer( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), state: &mut State, db: &mut OverlayedBackend<'_, impl Backend>, metrics: &Metrics, @@ -1070,20 +1051,13 @@ async fn handle_from_overseer( last_finalized_height: &mut Option, wakeups: &mut Wakeups, ) -> SubsystemResult> { - let actions = match x { FromOverseer::Signal(OverseerSignal::ActiveLeaves(update)) => { let mut actions = Vec::new(); for activated in update.activated { let head = activated.hash; - match import::handle_new_head( - ctx, - state, - db, - head, - &*last_finalized_height, - ).await { + match import::handle_new_head(ctx, state, db, head, &*last_finalized_height).await { Err(e) => return Err(SubsystemError::with_origin("db", e)), Ok(block_imported_candidates) => { // Schedule wakeups for all imported candidates. @@ -1125,12 +1099,12 @@ async fn handle_from_overseer( } } } - } + }, } } actions - } + }, FromOverseer::Signal(OverseerSignal::BlockFinalized(block_hash, block_number)) => { *last_finalized_height = Some(block_number); @@ -1140,35 +1114,37 @@ async fn handle_from_overseer( wakeups.prune_finalized_wakeups(block_number); Vec::new() - } + }, FromOverseer::Signal(OverseerSignal::Conclude) => { vec![Action::Conclude] - } + }, FromOverseer::Communication { msg } => match msg { ApprovalVotingMessage::CheckAndImportAssignment(a, claimed_core, res) => { - let (check_outcome, actions) - = check_and_import_assignment(state, db, a, claimed_core)?; + let (check_outcome, actions) = + check_and_import_assignment(state, db, a, claimed_core)?; let _ = res.send(check_outcome); actions - } - ApprovalVotingMessage::CheckAndImportApproval(a, res) => { - check_and_import_approval(state, db, metrics, a, |r| { let _ = res.send(r); })?.0 - } - ApprovalVotingMessage::ApprovedAncestor(target, lower_bound, res ) => { + }, + ApprovalVotingMessage::CheckAndImportApproval(a, res) => + check_and_import_approval(state, db, metrics, a, |r| { + let _ = res.send(r); + })? + .0, + ApprovalVotingMessage::ApprovedAncestor(target, lower_bound, res) => { match handle_approved_ancestor(ctx, db, target, lower_bound, wakeups).await { Ok(v) => { let _ = res.send(v); - } + }, Err(e) => { let _ = res.send(None); - return Err(e); - } + return Err(e) + }, } Vec::new() - } - } + }, + }, }; Ok(actions) @@ -1186,8 +1162,8 @@ async fn handle_approved_ancestor( use bitvec::{order::Lsb0, vec::BitVec}; - let mut span = jaeger::Span::new(&target, "approved-ancestor") - .with_stage(jaeger::Stage::ApprovalChecking); + let mut span = + jaeger::Span::new(&target, "approved-ancestor").with_stage(jaeger::Stage::ApprovalChecking); let mut all_approved_max = None; @@ -1199,11 +1175,13 @@ async fn handle_approved_ancestor( match rx.await { Ok(Ok(Some(n))) => n, Ok(Ok(None)) => return Ok(None), - Ok(Err(_)) | Err(_) => return Ok(None), + Ok(Err(_)) | Err(_) => return Ok(None), } }; - if target_number <= lower_bound { return Ok(None) } + if target_number <= lower_bound { + return Ok(None) + } span.add_string_fmt_debug_tag("target-number", target_number); span.add_string_fmt_debug_tag("target-hash", target); @@ -1218,7 +1196,8 @@ async fn handle_approved_ancestor( hash: target, k: (target_number - (lower_bound + 1)) as usize, response_channel: tx, - }).await; + }) + .await; match rx.await { Ok(Ok(a)) => a, @@ -1237,7 +1216,7 @@ async fn handle_approved_ancestor( // entries we can fail. let entry = match db.load_block_entry(&block_hash)? { None => { - tracing::trace!{ + tracing::trace! { target: LOG_TARGET, "Chain between ({}, {}) and {} not fully known. Forcing vote on {}", target, @@ -1245,8 +1224,8 @@ async fn handle_approved_ancestor( lower_bound, lower_bound, } - return Ok(None); - } + return Ok(None) + }, Some(b) => b, }; @@ -1285,67 +1264,70 @@ async fn handle_approved_ancestor( "Missing expected candidate in DB", ); - continue; - } - Some(c_entry) => { - match c_entry.approval_entry(&block_hash) { - None => { - tracing::warn!( - target: LOG_TARGET, - ?candidate_hash, - ?block_hash, - "Missing expected approval entry under candidate.", - ); - } - Some(a_entry) => { - let n_assignments = a_entry.n_assignments(); - let n_approvals = c_entry.approvals().count_ones(); + continue + }, + Some(c_entry) => match c_entry.approval_entry(&block_hash) { + None => { + tracing::warn!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + "Missing expected approval entry under candidate.", + ); + }, + Some(a_entry) => { + let n_assignments = a_entry.n_assignments(); + let n_approvals = c_entry.approvals().count_ones(); - let status = || format!("{}/{}/{}", + let status = || { + format!( + "{}/{}/{}", n_assignments, n_approvals, a_entry.n_validators(), - ); + ) + }; + + match a_entry.our_assignment() { + None => tracing::debug!( + target: LOG_TARGET, + ?candidate_hash, + ?block_hash, + status = %status(), + "no assignment." + ), + Some(a) => { + let tranche = a.tranche(); + let triggered = a.triggered(); + + let next_wakeup = + wakeups.wakeup_for(block_hash, candidate_hash); - match a_entry.our_assignment() { - None => tracing::debug!( + tracing::debug!( target: LOG_TARGET, ?candidate_hash, ?block_hash, + tranche, + ?next_wakeup, status = %status(), - "no assignment." - ), - Some(a) => { - let tranche = a.tranche(); - let triggered = a.triggered(); - - let next_wakeup = wakeups.wakeup_for( - block_hash, - candidate_hash, - ); - - tracing::debug!( - target: LOG_TARGET, - ?candidate_hash, - ?block_hash, - tranche, - ?next_wakeup, - status = %status(), - triggered, - "assigned." - ); - } - } + triggered, + "assigned." + ); + }, } - } - } + }, + }, } } } block_descriptions.push(BlockDescription { block_hash, session: entry.session(), - candidates: entry.candidates().iter().map(|(_idx, candidate_hash)| *candidate_hash ).collect(), + candidates: entry + .candidates() + .iter() + .map(|(_idx, candidate_hash)| *candidate_hash) + .collect(), }); } @@ -1360,7 +1342,9 @@ async fn handle_approved_ancestor( let mut s = String::with_capacity(bits.len()); for (i, bit) in bits.iter().enumerate().take(MAX_TRACING_WINDOW) { s.push(if *bit { '1' } else { '0' }); - if (target_number - i as u32) % 10 == 0 && i != bits.len() - 1 { s.push(' '); } + if (target_number - i as u32) % 10 == 0 && i != bits.len() - 1 { + s.push(' '); + } } s @@ -1379,31 +1363,27 @@ async fn handle_approved_ancestor( // block within the candidates, which is the expected order block_descriptions.reverse(); - let all_approved_max = all_approved_max.map(|(hash, block_number)| { - HighestApprovedAncestorBlock{ + let all_approved_max = + all_approved_max.map(|(hash, block_number)| HighestApprovedAncestorBlock { hash, number: block_number, descriptions: block_descriptions, - } - }); + }); match all_approved_max { Some(HighestApprovedAncestorBlock { ref hash, ref number, .. }) => { span.add_uint_tag("approved-number", *number as u64); span.add_string_fmt_debug_tag("approved-hash", hash); - } + }, None => { span.add_string_tag("reached-lower-bound", "true"); - } + }, } Ok(all_approved_max) } // `Option::cmp` treats `None` as less than `Some`. -fn min_prefer_some( - a: Option, - b: Option, -) -> Option { +fn min_prefer_some(a: Option, b: Option) -> Option { match (a, b) { (None, None) => None, (None, Some(x)) | (Some(x), None) => Some(x), @@ -1422,43 +1402,37 @@ fn schedule_wakeup_action( let maybe_action = match required_tranches { _ if approval_entry.is_approved() => None, RequiredTranches::All => None, - RequiredTranches::Exact { next_no_show, .. } => next_no_show.map(|tick| Action::ScheduleWakeup { - block_hash, - block_number, - candidate_hash, - tick, - }), + RequiredTranches::Exact { next_no_show, .. } => next_no_show + .map(|tick| Action::ScheduleWakeup { block_hash, block_number, candidate_hash, tick }), RequiredTranches::Pending { considered, next_no_show, clock_drift, .. } => { // select the minimum of `next_no_show`, or the tick of the next non-empty tranche // after `considered`, including any tranche that might contain our own untriggered // assignment. let next_non_empty_tranche = { - let next_announced = approval_entry.tranches().iter() + let next_announced = approval_entry + .tranches() + .iter() .skip_while(|t| t.tranche() <= considered) .map(|t| t.tranche()) .next(); - let our_untriggered = approval_entry - .our_assignment() - .and_then(|t| if !t.triggered() && t.tranche() > considered { + let our_untriggered = approval_entry.our_assignment().and_then(|t| { + if !t.triggered() && t.tranche() > considered { Some(t.tranche()) } else { None - }); + } + }); // Apply the clock drift to these tranches. min_prefer_some(next_announced, our_untriggered) .map(|t| t as Tick + block_tick + clock_drift) }; - min_prefer_some(next_non_empty_tranche, next_no_show) - .map(|tick| Action::ScheduleWakeup { - block_hash, - block_number, - candidate_hash, - tick, - }) - } + min_prefer_some(next_non_empty_tranche, next_no_show).map(|tick| { + Action::ScheduleWakeup { block_hash, block_number, candidate_hash, tick } + }) + }, }; match maybe_action { @@ -1477,7 +1451,7 @@ fn schedule_wakeup_action( block_tick, "No wakeup needed.", ), - Some(_) => {} // unreachable + Some(_) => {}, // unreachable } maybe_action @@ -1493,47 +1467,62 @@ fn check_and_import_assignment( let block_entry = match db.load_block_entry(&assignment.block_hash)? { Some(b) => b, - None => return Ok((AssignmentCheckResult::Bad( - AssignmentCheckError::UnknownBlock(assignment.block_hash), - ), Vec::new())), + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::UnknownBlock( + assignment.block_hash, + )), + Vec::new(), + )), }; let session_info = match state.session_info(block_entry.session()) { Some(s) => s, - None => { - return Ok((AssignmentCheckResult::Bad( - AssignmentCheckError::UnknownSessionIndex(block_entry.session()), - ), Vec::new())); - } + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::UnknownSessionIndex( + block_entry.session(), + )), + Vec::new(), + )), }; - let (claimed_core_index, assigned_candidate_hash) - = match block_entry.candidate(candidate_index as usize) - { - Some((c, h)) => (*c, *h), - None => return Ok((AssignmentCheckResult::Bad( - AssignmentCheckError::InvalidCandidateIndex(candidate_index), - ), Vec::new())), // no candidate at core. - }; + let (claimed_core_index, assigned_candidate_hash) = + match block_entry.candidate(candidate_index as usize) { + Some((c, h)) => (*c, *h), + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex( + candidate_index, + )), + Vec::new(), + )), // no candidate at core. + }; let mut candidate_entry = match db.load_candidate_entry(&assigned_candidate_hash)? { Some(c) => c, - None => { - return Ok((AssignmentCheckResult::Bad( - AssignmentCheckError::InvalidCandidate(candidate_index, assigned_candidate_hash), - ), Vec::new())); - } + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidate( + candidate_index, + assigned_candidate_hash, + )), + Vec::new(), + )), }; let res = { // import the assignment. - let approval_entry = match - candidate_entry.approval_entry_mut(&assignment.block_hash) - { + let approval_entry = match candidate_entry.approval_entry_mut(&assignment.block_hash) { Some(a) => a, - None => return Ok((AssignmentCheckResult::Bad( - AssignmentCheckError::Internal(assignment.block_hash, assigned_candidate_hash), - ), Vec::new())), + None => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::Internal( + assignment.block_hash, + assigned_candidate_hash, + )), + Vec::new(), + )), }; let res = state.assignment_criteria.check_assignment_cert( @@ -1546,26 +1535,28 @@ fn check_and_import_assignment( ); let tranche = match res { - Err(crate::criteria::InvalidAssignment) => return Ok((AssignmentCheckResult::Bad( - AssignmentCheckError::InvalidCert(assignment.validator), - ), Vec::new())), + Err(crate::criteria::InvalidAssignment) => + return Ok(( + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCert( + assignment.validator, + )), + Vec::new(), + )), Ok(tranche) => { - let current_tranche = state.clock.tranche_now( - state.slot_duration_millis, - block_entry.slot(), - ); + let current_tranche = + state.clock.tranche_now(state.slot_duration_millis, block_entry.slot()); let too_far_in_future = current_tranche + TICK_TOO_FAR_IN_FUTURE as DelayTranche; if tranche >= too_far_in_future { - return Ok((AssignmentCheckResult::TooFarInFuture, Vec::new())); + return Ok((AssignmentCheckResult::TooFarInFuture, Vec::new())) } tranche - } + }, }; - let is_duplicate = approval_entry.is_assigned(assignment.validator); + let is_duplicate = approval_entry.is_assigned(assignment.validator); approval_entry.import_assignment(tranche, assignment.validator, tick_now); if is_duplicate { @@ -1611,42 +1602,42 @@ fn check_and_import_approval( with_response: impl FnOnce(ApprovalCheckResult) -> T, ) -> SubsystemResult<(Vec, T)> { macro_rules! respond_early { - ($e: expr) => { { + ($e: expr) => {{ let t = with_response($e); - return Ok((Vec::new(), t)); - } } + return Ok((Vec::new(), t)) + }}; } let block_entry = match db.load_block_entry(&approval.block_hash)? { Some(b) => b, None => { - respond_early!(ApprovalCheckResult::Bad( - ApprovalCheckError::UnknownBlock(approval.block_hash), - )) - } + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::UnknownBlock( + approval.block_hash + ),)) + }, }; let session_info = match state.session_info(block_entry.session()) { Some(s) => s, None => { - respond_early!(ApprovalCheckResult::Bad( - ApprovalCheckError::UnknownSessionIndex(block_entry.session()), - )) - } + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::UnknownSessionIndex( + block_entry.session() + ),)) + }, }; let approved_candidate_hash = match block_entry.candidate(approval.candidate_index as usize) { Some((_, h)) => *h, None => respond_early!(ApprovalCheckResult::Bad( ApprovalCheckError::InvalidCandidateIndex(approval.candidate_index), - )) + )), }; let pubkey = match session_info.validators.get(approval.validator.0 as usize) { Some(k) => k, None => respond_early!(ApprovalCheckResult::Bad( ApprovalCheckError::InvalidValidatorIndex(approval.validator), - )) + )), }; // Transform the approval vote into the wrapper used to import statements into disputes. @@ -1658,33 +1649,35 @@ fn check_and_import_approval( pubkey.clone(), approval.signature.clone(), ) { - Err(_) => respond_early!(ApprovalCheckResult::Bad( - ApprovalCheckError::InvalidSignature(approval.validator), - )), + Err(_) => respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::InvalidSignature( + approval.validator + ),)), Ok(s) => s, }; let candidate_entry = match db.load_candidate_entry(&approved_candidate_hash)? { Some(c) => c, None => { - respond_early!(ApprovalCheckResult::Bad( - ApprovalCheckError::InvalidCandidate(approval.candidate_index, approved_candidate_hash), - )) - } + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::InvalidCandidate( + approval.candidate_index, + approved_candidate_hash + ),)) + }, }; // Don't accept approvals until assignment. match candidate_entry.approval_entry(&approval.block_hash) { None => { - respond_early!(ApprovalCheckResult::Bad( - ApprovalCheckError::Internal(approval.block_hash, approved_candidate_hash), - )) - } + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::Internal( + approval.block_hash, + approved_candidate_hash + ),)) + }, Some(e) if !e.is_assigned(approval.validator) => { - respond_early!(ApprovalCheckResult::Bad( - ApprovalCheckError::NoAssignment(approval.validator), - )) - } + respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::NoAssignment( + approval.validator + ),)) + }, _ => {}, } @@ -1782,20 +1775,20 @@ fn import_checked_approval( // We don't store remote votes, so we can early exit as long at the candidate is // already concluded under the block i.e. we don't need more approvals. if candidate_approved_in_block { - return Vec::new(); + return Vec::new() } - } + }, ApprovalSource::Local(_, _) => { // We never early return on the local validator. - } + }, } let mut actions = Vec::new(); let block_hash = block_entry.block_hash(); let block_number = block_entry.block_number(); - let (is_approved, status) = if let Some((approval_entry, status)) - = state.approval_status(&block_entry, &candidate_entry) + let (is_approved, status) = if let Some((approval_entry, status)) = + state.approval_status(&block_entry, &candidate_entry) { let check = approval_checking::check_approval( &candidate_entry, @@ -1843,11 +1836,12 @@ fn import_checked_approval( "No approval entry for approval under block", ); - return Vec::new(); + return Vec::new() }; { - let approval_entry = candidate_entry.approval_entry_mut(&block_hash) + let approval_entry = candidate_entry + .approval_entry_mut(&block_hash) .expect("Approval entry just fetched; qed"); let was_approved = approval_entry.is_approved(); @@ -1880,7 +1874,6 @@ fn import_checked_approval( // In all other cases, we need to write the candidate entry. db.write_candidate_entry(candidate_entry); } - } actions @@ -1901,23 +1894,20 @@ fn should_trigger_assignment( &candidate_entry, &approval_entry, RequiredTranches::All, - ).is_approved(), - RequiredTranches::Pending { - maximum_broadcast, - clock_drift, - .. - } => { - let drifted_tranche_now - = tranche_now.saturating_sub(clock_drift as DelayTranche); - assignment.tranche() <= maximum_broadcast - && assignment.tranche() <= drifted_tranche_now - } + ) + .is_approved(), + RequiredTranches::Pending { maximum_broadcast, clock_drift, .. } => { + let drifted_tranche_now = + tranche_now.saturating_sub(clock_drift as DelayTranche); + assignment.tranche() <= maximum_broadcast && + assignment.tranche() <= drifted_tranche_now + }, RequiredTranches::Exact { .. } => { // indicates that no new assignments are needed at the moment. false - } + }, } - } + }, } } @@ -1956,7 +1946,7 @@ fn process_wakeup( ); return Ok(Vec::new()) - } + }, }; let block_tick = slot_number_to_tick(state.slot_duration_millis, block_entry.slot()); @@ -2005,7 +1995,8 @@ fn process_wakeup( let maybe_cert = if should_trigger { let maybe_cert = { - let approval_entry = candidate_entry.approval_entry_mut(&relay_block) + let approval_entry = candidate_entry + .approval_entry_mut(&relay_block) .expect("should_trigger only true if this fetched earlier; qed"); approval_entry.trigger_our_assignment(state.clock.tick_now()) @@ -2019,14 +2010,11 @@ fn process_wakeup( }; if let Some((cert, val_index, tranche)) = maybe_cert { - let indirect_cert = IndirectAssignmentCert { - block_hash: relay_block, - validator: val_index, - cert, - }; + let indirect_cert = + IndirectAssignmentCert { block_hash: relay_block, validator: val_index, cert }; - let index_in_candidate = block_entry.candidates().iter() - .position(|(_, h)| &candidate_hash == h); + let index_in_candidate = + block_entry.candidates().iter().position(|(_, h)| &candidate_hash == h); if let Some(i) = index_in_candidate { tracing::trace!( @@ -2051,7 +2039,8 @@ fn process_wakeup( } } - let approval_entry = candidate_entry.approval_entry(&relay_block) + let approval_entry = candidate_entry + .approval_entry(&relay_block) .expect("this function returned earlier if not available; qed"); // Although we ran this earlier in the function, we need to run again because we might have @@ -2081,7 +2070,8 @@ fn process_wakeup( // spawned. When the background work is no longer needed, the `AbortHandle` should be dropped // to cancel the background work and any requests it has spawned. async fn launch_approval( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), metrics: Metrics, session_index: SessionIndex, candidate: CandidateReceipt, @@ -2099,11 +2089,13 @@ async fn launch_approval( impl StaleGuard { fn take(mut self) -> Metrics { - self.0.take().expect(" + self.0.take().expect( + " consumed after take; so this cannot be called twice; \ nothing in this function reaches into the struct to avoid this API; \ qed - ") + ", + ) } } @@ -2130,17 +2122,14 @@ async fn launch_approval( session_index, Some(backing_group), a_tx, - )).await; + )) + .await; - ctx.send_message( - RuntimeApiMessage::Request( - block_hash, - RuntimeApiRequest::ValidationCodeByHash( - candidate.descriptor.validation_code_hash, - code_tx, - ), - ) - ).await; + ctx.send_message(RuntimeApiMessage::Request( + block_hash, + RuntimeApiRequest::ValidationCodeByHash(candidate.descriptor.validation_code_hash, code_tx), + )) + .await; let candidate = candidate.clone(); let metrics_guard = StaleGuard(Some(metrics)); @@ -2154,10 +2143,7 @@ async fn launch_approval( .with_stage(jaeger::Stage::ApprovalChecking); let available_data = match a_rx.await { - Err(_) => return ApprovalState::failed( - validator_index, - candidate_hash, - ), + Err(_) => return ApprovalState::failed(validator_index, candidate_hash), Ok(Ok(a)) => a, Ok(Err(e)) => { match &e { @@ -2169,7 +2155,7 @@ async fn launch_approval( ); // do nothing. we'll just be a no-show and that'll cause others to rise up. metrics_guard.take().on_approval_unavailable(); - } + }, &RecoveryError::Invalid => { tracing::warn!( target: LOG_TARGET, @@ -2177,33 +2163,27 @@ async fn launch_approval( (candidate_hash, candidate.descriptor.para_id), ); - sender.send_message(DisputeCoordinatorMessage::IssueLocalStatement( - session_index, - candidate_hash, - candidate.clone(), - false, - ).into()).await; + sender + .send_message( + DisputeCoordinatorMessage::IssueLocalStatement( + session_index, + candidate_hash, + candidate.clone(), + false, + ) + .into(), + ) + .await; metrics_guard.take().on_approval_invalid(); - } + }, } - return ApprovalState::failed( - validator_index, - candidate_hash, - ); - } + return ApprovalState::failed(validator_index, candidate_hash) + }, }; let validation_code = match code_rx.await { - Err(_) => - return ApprovalState::failed( - validator_index, - candidate_hash, - ), - Ok(Err(_)) => - return ApprovalState::failed( - validator_index, - candidate_hash, - ), + Err(_) => return ApprovalState::failed(validator_index, candidate_hash), + Ok(Err(_)) => return ApprovalState::failed(validator_index, candidate_hash), Ok(Ok(Some(code))) => code, Ok(Ok(None)) => { tracing::warn!( @@ -2216,65 +2196,57 @@ async fn launch_approval( // No dispute necessary, as this indicates that the chain is not behaving // according to expectations. metrics_guard.take().on_approval_unavailable(); - return ApprovalState::failed( - validator_index, - candidate_hash, - ); - } + return ApprovalState::failed(validator_index, candidate_hash) + }, }; let (val_tx, val_rx) = oneshot::channel(); let para_id = candidate.descriptor.para_id; - sender.send_message(CandidateValidationMessage::ValidateFromExhaustive( - available_data.validation_data, - validation_code, - candidate.descriptor.clone(), - available_data.pov, - val_tx, - ).into()).await; + sender + .send_message( + CandidateValidationMessage::ValidateFromExhaustive( + available_data.validation_data, + validation_code, + candidate.descriptor.clone(), + available_data.pov, + val_tx, + ) + .into(), + ) + .await; match val_rx.await { - Err(_) => - return ApprovalState::failed( - validator_index, - candidate_hash, - ), + Err(_) => return ApprovalState::failed(validator_index, candidate_hash), Ok(Ok(ValidationResult::Valid(commitments, _))) => { // Validation checked out. Issue an approval command. If the underlying service is unreachable, // then there isn't anything we can do. - tracing::trace!( - target: LOG_TARGET, - ?candidate_hash, - ?para_id, - "Candidate Valid", - ); + tracing::trace!(target: LOG_TARGET, ?candidate_hash, ?para_id, "Candidate Valid",); let expected_commitments_hash = candidate.commitments_hash; if commitments.hash() == expected_commitments_hash { let _ = metrics_guard.take(); - return ApprovalState::approved( - validator_index, - candidate_hash, - ); + return ApprovalState::approved(validator_index, candidate_hash) } else { // Commitments mismatch - issue a dispute. - sender.send_message(DisputeCoordinatorMessage::IssueLocalStatement( - session_index, - candidate_hash, - candidate.clone(), - false, - ).into()).await; + sender + .send_message( + DisputeCoordinatorMessage::IssueLocalStatement( + session_index, + candidate_hash, + candidate.clone(), + false, + ) + .into(), + ) + .await; metrics_guard.take().on_approval_invalid(); - return ApprovalState::failed( - validator_index, - candidate_hash, - ); + return ApprovalState::failed(validator_index, candidate_hash) } - } + }, Ok(Ok(ValidationResult::Invalid(reason))) => { tracing::warn!( target: LOG_TARGET, @@ -2284,19 +2256,21 @@ async fn launch_approval( "Detected invalid candidate as an approval checker.", ); - sender.send_message(DisputeCoordinatorMessage::IssueLocalStatement( - session_index, - candidate_hash, - candidate.clone(), - false, - ).into()).await; + sender + .send_message( + DisputeCoordinatorMessage::IssueLocalStatement( + session_index, + candidate_hash, + candidate.clone(), + false, + ) + .into(), + ) + .await; metrics_guard.take().on_approval_invalid(); - return ApprovalState::failed( - validator_index, - candidate_hash, - ); - } + return ApprovalState::failed(validator_index, candidate_hash) + }, Ok(Err(e)) => { tracing::error!( target: LOG_TARGET, @@ -2304,17 +2278,13 @@ async fn launch_approval( "Failed to validate candidate due to internal error", ); metrics_guard.take().on_approval_error(); - return ApprovalState::failed( - validator_index, - candidate_hash, - ); - } + return ApprovalState::failed(validator_index, candidate_hash) + }, } }; let (background, remote_handle) = background.remote_handle(); - ctx.spawn("approval-checks", Box::pin(background)) - .map(move |()| remote_handle) + ctx.spawn("approval-checks", Box::pin(background)).map(move |()| remote_handle) } // Issue and import a local approval vote. Should only be invoked after approval checks @@ -2333,13 +2303,10 @@ async fn issue_approval( // not a cause for alarm - just lost a race with pruning, most likely. metrics.on_approval_stale(); return Ok(Vec::new()) - } + }, }; - let candidate_index = match block_entry - .candidates() - .iter() - .position(|e| e.1 == candidate_hash) + let candidate_index = match block_entry.candidates().iter().position(|e| e.1 == candidate_hash) { None => { tracing::warn!( @@ -2350,8 +2317,8 @@ async fn issue_approval( ); metrics.on_approval_error(); - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, Some(idx) => idx, }; @@ -2366,8 +2333,8 @@ async fn issue_approval( ); metrics.on_approval_error(); - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, }; let candidate_hash = match block_entry.candidate(candidate_index as usize) { @@ -2381,8 +2348,8 @@ async fn issue_approval( ); metrics.on_approval_error(); - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, }; let candidate_entry = match db.load_candidate_entry(&candidate_hash)? { @@ -2396,8 +2363,8 @@ async fn issue_approval( ); metrics.on_approval_error(); - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, }; let validator_pubkey = match session_info.validators.get(validator_index.0 as usize) { @@ -2411,17 +2378,12 @@ async fn issue_approval( ); metrics.on_approval_error(); - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, }; let session = block_entry.session(); - let sig = match sign_approval( - &state.keystore, - &validator_pubkey, - candidate_hash, - session, - ) { + let sig = match sign_approval(&state.keystore, &validator_pubkey, candidate_hash, session) { Some(sig) => sig, None => { tracing::warn!( @@ -2432,8 +2394,8 @@ async fn issue_approval( ); metrics.on_approval_error(); - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, }; // Record our statement in the dispute coordinator for later @@ -2444,7 +2406,8 @@ async fn issue_approval( session, validator_pubkey.clone(), sig.clone(), - ).expect("Statement just signed; should pass checks; qed"); + ) + .expect("Statement just signed; should pass checks; qed"); tracing::debug!( target: LOG_TARGET, @@ -2491,8 +2454,9 @@ async fn issue_approval( candidate_index: candidate_index as _, validator: validator_index, signature: sig, - } - ).into()); + }) + .into(), + ); // dispatch to dispute coordinator. actions.extend(inform_disputes_action); diff --git a/polkadot/node/core/approval-voting/src/old_tests.rs b/polkadot/node/core/approval-voting/src/old_tests.rs index 4c6c6a230eb..a122bce7df8 100644 --- a/polkadot/node/core/approval-voting/src/old_tests.rs +++ b/polkadot/node/core/approval-voting/src/old_tests.rs @@ -14,36 +14,34 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use super::*; -use super::approval_db::v1::Config; -use super::backend::{Backend, BackendWriteOp}; -use polkadot_primitives::v1::{ - CandidateDescriptor, CoreIndex, GroupIndex, ValidatorSignature, - DisputeStatement, ValidDisputeStatementKind, +use super::{ + approval_db::v1::Config, + backend::{Backend, BackendWriteOp}, + *, }; use polkadot_node_primitives::approval::{ - AssignmentCert, AssignmentCertKind, VRFOutput, VRFProof, - RELAY_VRF_MODULO_CONTEXT, DelayTranche, + AssignmentCert, AssignmentCertKind, DelayTranche, VRFOutput, VRFProof, RELAY_VRF_MODULO_CONTEXT, }; -use polkadot_node_subsystem_test_helpers::make_subsystem_context; use polkadot_node_subsystem::messages::{AllMessages, HighestApprovedAncestorBlock}; +use polkadot_node_subsystem_test_helpers::make_subsystem_context; +use polkadot_primitives::v1::{ + CandidateDescriptor, CoreIndex, DisputeStatement, GroupIndex, ValidDisputeStatementKind, + ValidatorSignature, +}; use sp_core::testing::TaskExecutor; -use parking_lot::Mutex; +use assert_matches::assert_matches; use bitvec::order::Lsb0 as BitOrderLsb0; -use std::pin::Pin; -use std::sync::Arc; +use parking_lot::Mutex; use sp_keyring::sr25519::Keyring as Sr25519Keyring; -use assert_matches::assert_matches; +use std::{pin::Pin, sync::Arc}; const SLOT_DURATION_MILLIS: u64 = 5000; const DATA_COL: u32 = 0; const NUM_COLUMNS: u32 = 1; -const TEST_CONFIG: Config = Config { - col_data: DATA_COL, -}; +const TEST_CONFIG: Config = Config { col_data: DATA_COL }; fn make_db() -> DbBackend { let db_writer: Arc = Arc::new(kvdb_memorydb::create(NUM_COLUMNS)); @@ -51,9 +49,9 @@ fn make_db() -> DbBackend { } fn overlay_txn(db: &mut T, mut f: F) - where - T: Backend, - F: FnMut(&mut OverlayedBackend<'_, T>) +where + T: Backend, + F: FnMut(&mut OverlayedBackend<'_, T>), { let mut overlay_db = OverlayedBackend::new(db); f(&mut overlay_db); @@ -109,10 +107,8 @@ impl MockClockInner { fn wakeup_all(&mut self, up_to: Tick) { // This finds the position of the first wakeup after // the given tick, or the end of the map. - let drain_up_to = self.wakeups.binary_search_by_key( - &(up_to + 1), - |w| w.0, - ).unwrap_or_else(|i| i); + let drain_up_to = + self.wakeups.binary_search_by_key(&(up_to + 1), |w| w.0).unwrap_or_else(|i| i); for (_, wakeup) in self.wakeups.drain(..drain_up_to) { let _ = wakeup.send(()); @@ -131,10 +127,7 @@ impl MockClockInner { fn register_wakeup(&mut self, tick: Tick, pre_emptive: bool) -> oneshot::Receiver<()> { let (tx, rx) = oneshot::channel(); - let pos = self.wakeups.binary_search_by_key( - &tick, - |w| w.0, - ).unwrap_or_else(|i| i); + let pos = self.wakeups.binary_search_by_key(&tick, |w| w.0).unwrap_or_else(|i| i); self.wakeups.insert(pos, (tick, tx)); @@ -153,14 +146,18 @@ struct MockAssignmentCriteria(Compute, Check); impl AssignmentCriteria for MockAssignmentCriteria where Compute: Fn() -> HashMap, - Check: Fn() -> Result + Check: Fn() -> Result, { fn compute_assignments( &self, _keystore: &LocalKeystore, _relay_vrf_story: polkadot_node_primitives::approval::RelayVRFStory, _config: &criteria::Config, - _leaving_cores: Vec<(CandidateHash, polkadot_primitives::v1::CoreIndex, polkadot_primitives::v1::GroupIndex)>, + _leaving_cores: Vec<( + CandidateHash, + polkadot_primitives::v1::CoreIndex, + polkadot_primitives::v1::GroupIndex, + )>, ) -> HashMap { self.0() } @@ -178,10 +175,12 @@ where } } -impl MockAssignmentCriteria< - fn() -> HashMap, - F, -> { +impl + MockAssignmentCriteria< + fn() -> HashMap, + F, + > +{ fn check_only(f: F) -> Self { MockAssignmentCriteria(Default::default, f) } @@ -193,7 +192,7 @@ fn blank_state() -> State { keystore: Arc::new(LocalKeystore::in_memory()), slot_duration_millis: SLOT_DURATION_MILLIS, clock: Box::new(MockClock::default()), - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { Ok(0) })), + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), } } @@ -216,10 +215,7 @@ fn garbage_assignment_cert(kind: AssignmentCertKind) -> AssignmentCert { let (inout, proof, _) = keypair.vrf_sign(ctx.bytes(msg)); let out = inout.to_output(); - AssignmentCert { - kind, - vrf: (VRFOutput(out), VRFProof(proof)), - } + AssignmentCert { kind, vrf: (VRFOutput(out), VRFProof(proof)) } } fn sign_approval( @@ -274,31 +270,29 @@ fn some_state(config: StateConfig, db: &mut DbBackend) -> State { let state = State { clock: Box::new(MockClock::new(tick)), - ..single_session_state(session_index, SessionInfo { - validators: validators.iter().map(|v| v.public().into()).collect(), - discovery_keys: validators.iter().map(|v| v.public().into()).collect(), - assignment_keys: validators.iter().map(|v| v.public().into()).collect(), - validator_groups: validator_groups.clone(), - n_cores: validator_groups.len() as _, - zeroth_delay_tranche_width: 5, - relay_vrf_modulo_samples: 3, - n_delay_tranches: 50, - no_show_slots, - needed_approvals, - ..Default::default() - }) + ..single_session_state( + session_index, + SessionInfo { + validators: validators.iter().map(|v| v.public().into()).collect(), + discovery_keys: validators.iter().map(|v| v.public().into()).collect(), + assignment_keys: validators.iter().map(|v| v.public().into()).collect(), + validator_groups: validator_groups.clone(), + n_cores: validator_groups.len() as _, + zeroth_delay_tranche_width: 5, + relay_vrf_modulo_samples: 3, + n_delay_tranches: 50, + no_show_slots, + needed_approvals, + ..Default::default() + }, + ) }; let core_index = 0.into(); let block_hash = Hash::repeat_byte(0x01); let candidate_hash = candidate_hash.unwrap_or_else(|| CandidateHash(Hash::repeat_byte(0xCC))); - add_block( - db, - block_hash, - session_index, - slot, - ); + add_block(db, block_hash, session_index, slot); add_candidate_to_block( db, @@ -313,23 +307,23 @@ fn some_state(config: StateConfig, db: &mut DbBackend) -> State { state } -fn add_block( - db: &mut DbBackend, - block_hash: Hash, - session: SessionIndex, - slot: Slot, -) { - overlay_txn(db, |overlay_db| overlay_db.write_block_entry(approval_db::v1::BlockEntry { - block_hash, - parent_hash: Default::default(), - block_number: 0, - session, - slot, - candidates: Vec::new(), - relay_vrf_story: Default::default(), - approved_bitfield: Default::default(), - children: Default::default(), - }.into())); +fn add_block(db: &mut DbBackend, block_hash: Hash, session: SessionIndex, slot: Slot) { + overlay_txn(db, |overlay_db| { + overlay_db.write_block_entry( + approval_db::v1::BlockEntry { + block_hash, + parent_hash: Default::default(), + block_number: 0, + session, + slot, + candidates: Vec::new(), + relay_vrf_story: Default::default(), + approved_bitfield: Default::default(), + children: Default::default(), + } + .into(), + ) + }); } fn add_candidate_to_block( @@ -343,13 +337,16 @@ fn add_candidate_to_block( ) { let mut block_entry = db.load_block_entry(&block_hash).unwrap().unwrap(); - let mut candidate_entry = db.load_candidate_entry(&candidate_hash).unwrap() - .unwrap_or_else(|| approval_db::v1::CandidateEntry { - session: block_entry.session(), - block_assignments: Default::default(), - candidate: candidate_receipt.unwrap_or_default(), - approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], - }.into()); + let mut candidate_entry = + db.load_candidate_entry(&candidate_hash).unwrap().unwrap_or_else(|| { + approval_db::v1::CandidateEntry { + session: block_entry.session(), + block_assignments: Default::default(), + candidate: candidate_receipt.unwrap_or_default(), + approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], + } + .into() + }); block_entry.add_candidate(core, candidate_hash); @@ -362,7 +359,8 @@ fn add_candidate_to_block( our_approval_sig: None, assignments: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], approved: false, - }.into(), + } + .into(), ); overlay_txn(db, |overlay_db| { @@ -377,12 +375,15 @@ fn import_assignment( block_hash: &Hash, validator_index: ValidatorIndex, mut f: F, -) - where F: FnMut(&mut CandidateEntry) +) where + F: FnMut(&mut CandidateEntry), { let mut candidate_entry = db.load_candidate_entry(candidate_hash).unwrap().unwrap(); - candidate_entry.approval_entry_mut(block_hash).unwrap() - .import_assignment(0, validator_index, 0); + candidate_entry.approval_entry_mut(block_hash).unwrap().import_assignment( + 0, + validator_index, + 0, + ); f(&mut candidate_entry); @@ -395,20 +396,21 @@ fn set_our_assignment( block_hash: &Hash, tranche: DelayTranche, mut f: F, -) - where F: FnMut(&mut CandidateEntry) +) where + F: FnMut(&mut CandidateEntry), { let mut candidate_entry = db.load_candidate_entry(&candidate_hash).unwrap().unwrap(); let approval_entry = candidate_entry.approval_entry_mut(&block_hash).unwrap(); - approval_entry.set_our_assignment(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), - tranche, - validator_index: ValidatorIndex(0), - triggered: false, - }.into()); + approval_entry.set_our_assignment( + approval_db::v1::OurAssignment { + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), + tranche, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); f(&mut candidate_entry); @@ -423,16 +425,12 @@ fn rejects_bad_assignment() { let assignment_good = IndirectAssignmentCert { block_hash, validator: ValidatorIndex(0), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { - sample: 0, - }, - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), }; - let mut state = some_state(StateConfig { - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db); + let mut state = some_state( + StateConfig { candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ); let candidate_index = 0; let mut overlay_db = OverlayedBackend::new(&db); @@ -441,7 +439,8 @@ fn rejects_bad_assignment() { &mut overlay_db, assignment_good.clone(), candidate_index, - ).unwrap(); + ) + .unwrap(); assert_eq!(res.0, AssignmentCheckResult::Accepted); // Check that the assignment's been imported. assert_eq!(res.1.len(), 1); @@ -456,20 +455,12 @@ fn rejects_bad_assignment() { let assignment = IndirectAssignmentCert { block_hash: unknown_hash, validator: ValidatorIndex(0), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { - sample: 0, - }, - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), }; let mut overlay_db = OverlayedBackend::new(&db); - let res = check_and_import_assignment( - &mut state, - &mut overlay_db, - assignment, - candidate_index, - ).unwrap(); + let res = check_and_import_assignment(&mut state, &mut overlay_db, assignment, candidate_index) + .unwrap(); assert_eq!(res.0, AssignmentCheckResult::Bad(AssignmentCheckError::UnknownBlock(unknown_hash))); assert_eq!(overlay_db.into_write_ops().count(), 0); @@ -477,21 +468,21 @@ fn rejects_bad_assignment() { assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { Err(criteria::InvalidAssignment) })), - ..some_state(StateConfig { - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + ..some_state( + StateConfig { candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ) }; // same assignment, but this time rejected let mut overlay_db = OverlayedBackend::new(&db); - let res = check_and_import_assignment( - &mut state, - &mut overlay_db, - assignment_good, - candidate_index, - ).unwrap(); - assert_eq!(res.0, AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCert(ValidatorIndex(0)))); + let res = + check_and_import_assignment(&mut state, &mut overlay_db, assignment_good, candidate_index) + .unwrap(); + assert_eq!( + res.0, + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCert(ValidatorIndex(0))) + ); assert_eq!(overlay_db.into_write_ops().count(), 0); } @@ -504,11 +495,7 @@ fn rejects_assignment_in_future() { let assignment = IndirectAssignmentCert { block_hash, validator: ValidatorIndex(0), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { - sample: 0, - }, - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), }; let tick = 9; @@ -516,11 +503,10 @@ fn rejects_assignment_in_future() { assignment_criteria: Box::new(MockAssignmentCriteria::check_only(move || { Ok((tick + 20) as _) })), - ..some_state(StateConfig { - tick, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + ..some_state( + StateConfig { tick, candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ) }; let mut overlay_db = OverlayedBackend::new(&db); @@ -529,7 +515,8 @@ fn rejects_assignment_in_future() { &mut overlay_db, assignment.clone(), candidate_index, - ).unwrap(); + ) + .unwrap(); assert_eq!(res.0, AssignmentCheckResult::TooFarInFuture); let write_ops = overlay_db.into_write_ops().collect::>(); @@ -541,11 +528,10 @@ fn rejects_assignment_in_future() { assignment_criteria: Box::new(MockAssignmentCriteria::check_only(move || { Ok((tick + 20 - 1) as _) })), - ..some_state(StateConfig { - tick, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + ..some_state( + StateConfig { tick, candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ) }; let mut overlay_db = OverlayedBackend::new(&db); @@ -554,16 +540,14 @@ fn rejects_assignment_in_future() { &mut overlay_db, assignment.clone(), candidate_index, - ).unwrap(); + ) + .unwrap(); assert_eq!(res.0, AssignmentCheckResult::Accepted); let write_ops = overlay_db.into_write_ops().collect::>(); assert_eq!(write_ops.len(), 1); - assert_matches!( - write_ops.get(0).unwrap(), - BackendWriteOp::WriteCandidateEntry(..) - ); + assert_matches!(write_ops.get(0).unwrap(), BackendWriteOp::WriteCandidateEntry(..)); } #[test] @@ -574,11 +558,7 @@ fn rejects_assignment_with_unknown_candidate() { let assignment = IndirectAssignmentCert { block_hash, validator: ValidatorIndex(0), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { - sample: 0, - }, - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), }; let mut state = some_state(Default::default(), &mut db); @@ -589,8 +569,12 @@ fn rejects_assignment_with_unknown_candidate() { &mut overlay_db, assignment.clone(), candidate_index, - ).unwrap(); - assert_eq!(res.0, AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex(candidate_index))); + ) + .unwrap(); + assert_eq!( + res.0, + AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex(candidate_index)) + ); assert_eq!(overlay_db.into_write_ops().count(), 0); } @@ -604,21 +588,15 @@ fn assignment_import_updates_candidate_entry_and_schedules_wakeup() { let assignment = IndirectAssignmentCert { block_hash, validator: ValidatorIndex(0), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { - sample: 0, - }, - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), }; let mut state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ) }; let mut overlay_db = OverlayedBackend::new(&db); @@ -627,7 +605,8 @@ fn assignment_import_updates_candidate_entry_and_schedules_wakeup() { &mut overlay_db, assignment.clone(), candidate_index, - ).unwrap(); + ) + .unwrap(); assert_eq!(res, AssignmentCheckResult::Accepted); assert_eq!(actions.len(), 1); @@ -664,13 +643,11 @@ fn rejects_approval_before_assignment() { let candidate_hash = CandidateReceipt::::default().hash(); let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ) }; let vote = IndirectSignedApprovalVote { @@ -681,13 +658,8 @@ fn rejects_approval_before_assignment() { }; let mut overlay_db = OverlayedBackend::new(&db); - let (actions, res) = check_and_import_approval( - &state, - &mut overlay_db, - &Metrics(None), - vote, - |r| r - ).unwrap(); + let (actions, res) = + check_and_import_approval(&state, &mut overlay_db, &Metrics(None), vote, |r| r).unwrap(); assert_eq!(res, ApprovalCheckResult::Bad(ApprovalCheckError::NoAssignment(ValidatorIndex(0)))); assert!(actions.is_empty()); @@ -701,13 +673,11 @@ fn rejects_approval_if_no_candidate_entry() { let candidate_hash = CandidateReceipt::::default().hash(); let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ) }; let vote = IndirectSignedApprovalVote { @@ -717,19 +687,16 @@ fn rejects_approval_if_no_candidate_entry() { signature: sign_approval(Sr25519Keyring::Alice, candidate_hash, 1), }; - overlay_txn(&mut db, |overlay_db| overlay_db.delete_candidate_entry(&candidate_hash)); let mut overlay_db = OverlayedBackend::new(&db); - let (actions, res) = check_and_import_approval( - &state, - &mut overlay_db, - &Metrics(None), - vote, - |r| r - ).unwrap(); + let (actions, res) = + check_and_import_approval(&state, &mut overlay_db, &Metrics(None), vote, |r| r).unwrap(); - assert_eq!(res, ApprovalCheckResult::Bad(ApprovalCheckError::InvalidCandidate(0, candidate_hash))); + assert_eq!( + res, + ApprovalCheckResult::Bad(ApprovalCheckError::InvalidCandidate(0, candidate_hash)) + ); assert!(actions.is_empty()); assert_eq!(overlay_db.into_write_ops().count(), 0); } @@ -742,13 +709,11 @@ fn rejects_approval_if_no_block_entry() { let validator_index = ValidatorIndex(0); let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { candidate_hash: Some(candidate_hash), ..Default::default() }, + &mut db, + ) }; let vote = IndirectSignedApprovalVote { @@ -763,13 +728,8 @@ fn rejects_approval_if_no_block_entry() { overlay_txn(&mut db, |overlay_db| overlay_db.delete_block_entry(&block_hash)); let mut overlay_db = OverlayedBackend::new(&db); - let (actions, res) = check_and_import_approval( - &state, - &mut overlay_db, - &Metrics(None), - vote, - |r| r - ).unwrap(); + let (actions, res) = + check_and_import_approval(&state, &mut overlay_db, &Metrics(None), vote, |r| r).unwrap(); assert_eq!(res, ApprovalCheckResult::Bad(ApprovalCheckError::UnknownBlock(block_hash))); assert!(actions.is_empty()); @@ -785,16 +745,24 @@ fn accepts_and_imports_approval_after_assignment() { let candidate_index = 0; let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie], - validator_groups: vec![vec![ValidatorIndex(0), ValidatorIndex(1)], vec![ValidatorIndex(2)]], - needed_approvals: 2, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { + validators: vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + ], + validator_groups: vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + ], + needed_approvals: 2, + candidate_hash: Some(candidate_hash), + ..Default::default() + }, + &mut db, + ) }; let vote = IndirectSignedApprovalVote { @@ -807,13 +775,8 @@ fn accepts_and_imports_approval_after_assignment() { import_assignment(&mut db, &candidate_hash, &block_hash, validator_index, |_| {}); let mut overlay_db = OverlayedBackend::new(&db); - let (actions, res) = check_and_import_approval( - &state, - &mut overlay_db, - &Metrics(None), - vote, - |r| r - ).unwrap(); + let (actions, res) = + check_and_import_approval(&state, &mut overlay_db, &Metrics(None), vote, |r| r).unwrap(); assert_eq!(res, ApprovalCheckResult::Accepted); @@ -858,16 +821,24 @@ fn second_approval_import_only_schedules_wakeups() { let candidate_index = 0; let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie], - validator_groups: vec![vec![ValidatorIndex(0), ValidatorIndex(1)], vec![ValidatorIndex(2)]], - needed_approvals: 2, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { + validators: vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + ], + validator_groups: vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + ], + needed_approvals: 2, + candidate_hash: Some(candidate_hash), + ..Default::default() + }, + &mut db, + ) }; let vote = IndirectSignedApprovalVote { @@ -884,13 +855,9 @@ fn second_approval_import_only_schedules_wakeups() { // There is only one assignment, so nothing to schedule if we double-import. let mut overlay_db = OverlayedBackend::new(&db); - let (actions, res) = check_and_import_approval( - &state, - &mut overlay_db, - &Metrics(None), - vote.clone(), - |r| r - ).unwrap(); + let (actions, res) = + check_and_import_approval(&state, &mut overlay_db, &Metrics(None), vote.clone(), |r| r) + .unwrap(); assert_eq!(res, ApprovalCheckResult::Accepted); assert!(actions.is_empty()); @@ -901,13 +868,8 @@ fn second_approval_import_only_schedules_wakeups() { import_assignment(&mut db, &candidate_hash, &block_hash, validator_index_b, |_| {}); let mut overlay_db = OverlayedBackend::new(&db); - let (actions, res) = check_and_import_approval( - &state, - &mut overlay_db, - &Metrics(None), - vote, - |r| r - ).unwrap(); + let (actions, res) = + check_and_import_approval(&state, &mut overlay_db, &Metrics(None), vote, |r| r).unwrap(); assert_eq!(res, ApprovalCheckResult::Accepted); assert_eq!(actions.len(), 1); @@ -928,16 +890,24 @@ fn import_checked_approval_updates_entries_and_schedules() { let validator_index_b = ValidatorIndex(1); let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie], - validator_groups: vec![vec![ValidatorIndex(0), ValidatorIndex(1)], vec![ValidatorIndex(2)]], - needed_approvals: 2, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { + validators: vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + ], + validator_groups: vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + ], + needed_approvals: 2, + candidate_hash: Some(candidate_hash), + ..Default::default() + }, + &mut db, + ) }; import_assignment(&mut db, &candidate_hash, &block_hash, validator_index_a, |_| {}); @@ -1026,9 +996,7 @@ fn assignment_triggered_by_all_with_less_than_threshold() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: 1, validator_index: ValidatorIndex(4), triggered: false, @@ -1043,14 +1011,16 @@ fn assignment_triggered_by_all_with_less_than_threshold() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; // 1-of-4 - candidate_entry - .approval_entry_mut(&block_hash) - .unwrap() - .import_assignment(0, ValidatorIndex(0), 0); + candidate_entry.approval_entry_mut(&block_hash).unwrap().import_assignment( + 0, + ValidatorIndex(0), + 0, + ); candidate_entry.mark_approval(ValidatorIndex(0)); @@ -1072,9 +1042,7 @@ fn assignment_not_triggered_by_all_with_threshold() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: 1, validator_index: ValidatorIndex(4), triggered: false, @@ -1089,19 +1057,22 @@ fn assignment_not_triggered_by_all_with_threshold() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; // 2-of-4 - candidate_entry - .approval_entry_mut(&block_hash) - .unwrap() - .import_assignment(0, ValidatorIndex(0), 0); + candidate_entry.approval_entry_mut(&block_hash).unwrap().import_assignment( + 0, + ValidatorIndex(0), + 0, + ); - candidate_entry - .approval_entry_mut(&block_hash) - .unwrap() - .import_assignment(0, ValidatorIndex(1), 0); + candidate_entry.approval_entry_mut(&block_hash).unwrap().import_assignment( + 0, + ValidatorIndex(1), + 0, + ); candidate_entry.mark_approval(ValidatorIndex(0)); candidate_entry.mark_approval(ValidatorIndex(1)); @@ -1124,9 +1095,7 @@ fn assignment_not_triggered_if_already_triggered() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: 1, validator_index: ValidatorIndex(4), triggered: true, @@ -1141,7 +1110,8 @@ fn assignment_not_triggered_if_already_triggered() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; let tranche_now = 1; @@ -1162,9 +1132,7 @@ fn assignment_not_triggered_by_exact() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: 1, validator_index: ValidatorIndex(4), triggered: false, @@ -1179,7 +1147,8 @@ fn assignment_not_triggered_by_exact() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; let tranche_now = 1; @@ -1201,9 +1170,7 @@ fn assignment_not_triggered_more_than_maximum() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: maximum_broadcast + 1, validator_index: ValidatorIndex(4), triggered: false, @@ -1218,7 +1185,8 @@ fn assignment_not_triggered_more_than_maximum() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; let tranche_now = 50; @@ -1245,9 +1213,7 @@ fn assignment_triggered_if_at_maximum() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: maximum_broadcast, validator_index: ValidatorIndex(4), triggered: false, @@ -1262,7 +1228,8 @@ fn assignment_triggered_if_at_maximum() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; let tranche_now = maximum_broadcast; @@ -1289,9 +1256,7 @@ fn assignment_not_triggered_if_at_maximum_but_clock_is_before() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: maximum_broadcast, validator_index: ValidatorIndex(4), triggered: false, @@ -1306,7 +1271,8 @@ fn assignment_not_triggered_if_at_maximum_but_clock_is_before() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; let tranche_now = 9; @@ -1333,9 +1299,7 @@ fn assignment_not_triggered_if_at_maximum_but_clock_is_before_with_drift() { tranches: Vec::new(), backing_group: GroupIndex(0), our_assignment: Some(approval_db::v1::OurAssignment { - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), tranche: maximum_broadcast, validator_index: ValidatorIndex(4), triggered: false, @@ -1350,7 +1314,8 @@ fn assignment_not_triggered_if_at_maximum_but_clock_is_before_with_drift() { session: 1, block_assignments: vec![(block_hash, approval_entry)].into_iter().collect(), approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; 4], - }.into() + } + .into() }; let tranche_now = 10; @@ -1467,16 +1432,24 @@ fn import_checked_approval_sets_one_block_bit_at_a_time() { let validator_index_b = ValidatorIndex(1); let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie], - validator_groups: vec![vec![ValidatorIndex(0), ValidatorIndex(1)], vec![ValidatorIndex(2)]], - needed_approvals: 2, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { + validators: vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + ], + validator_groups: vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + ], + needed_approvals: 2, + candidate_hash: Some(candidate_hash), + ..Default::default() + }, + &mut db, + ) }; add_candidate_to_block( @@ -1586,12 +1559,7 @@ fn approved_ancestor_all_approved() { let session_index = 1; let add_block = |db: &mut DbBackend, block_hash, approved| { - add_block( - db, - block_hash, - session_index, - slot, - ); + add_block(db, block_hash, session_index, slot); let mut block_entry = db.load_block_entry(&block_hash).unwrap().unwrap(); block_entry.add_candidate(CoreIndex(0), candidate_hash); @@ -1662,12 +1630,7 @@ fn approved_ancestor_missing_approval() { let session_index = 1; let add_block = |db: &mut DbBackend, block_hash, approved| { - add_block( - db, - block_hash, - session_index, - slot, - ); + add_block(db, block_hash, session_index, slot); let mut block_entry = db.load_block_entry(&block_hash).unwrap().unwrap(); block_entry.add_candidate(CoreIndex(0), candidate_hash); @@ -1733,28 +1696,23 @@ fn process_wakeup_trigger_assignment_launch_approval() { let session_index = 1; let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), - ..some_state(StateConfig { - validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob], - validator_groups: vec![vec![ValidatorIndex(0)], vec![ValidatorIndex(1)]], - needed_approvals: 2, - session_index, - slot, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), + ..some_state( + StateConfig { + validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob], + validator_groups: vec![vec![ValidatorIndex(0)], vec![ValidatorIndex(1)]], + needed_approvals: 2, + session_index, + slot, + candidate_hash: Some(candidate_hash), + ..Default::default() + }, + &mut db, + ) }; let mut overlay_db = OverlayedBackend::new(&db); - let actions = process_wakeup( - &state, - &mut overlay_db, - block_hash, - candidate_hash, - 1, - ).unwrap(); + let actions = process_wakeup(&state, &mut overlay_db, block_hash, candidate_hash, 1).unwrap(); assert!(actions.is_empty()); assert_eq!(overlay_db.into_write_ops().count(), 0); @@ -1762,13 +1720,7 @@ fn process_wakeup_trigger_assignment_launch_approval() { set_our_assignment(&mut db, &candidate_hash, &block_hash, 0, |_| {}); let mut overlay_db = OverlayedBackend::new(&db); - let actions = process_wakeup( - &state, - &mut overlay_db, - block_hash, - candidate_hash, - 1, - ).unwrap(); + let actions = process_wakeup(&state, &mut overlay_db, block_hash, candidate_hash, 1).unwrap(); assert_eq!(actions.len(), 2); @@ -1820,30 +1772,25 @@ fn process_wakeup_schedules_wakeup() { let session_index = 1; let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(10) - })), - ..some_state(StateConfig { - validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob], - validator_groups: vec![vec![ValidatorIndex(0)], vec![ValidatorIndex(1)]], - needed_approvals: 2, - session_index, - slot, - candidate_hash: Some(candidate_hash), - ..Default::default() - }, &mut db) + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(10))), + ..some_state( + StateConfig { + validators: vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob], + validator_groups: vec![vec![ValidatorIndex(0)], vec![ValidatorIndex(1)]], + needed_approvals: 2, + session_index, + slot, + candidate_hash: Some(candidate_hash), + ..Default::default() + }, + &mut db, + ) }; set_our_assignment(&mut db, &candidate_hash, &block_hash, 10, |_| {}); let mut overlay_db = OverlayedBackend::new(&db); - let actions = process_wakeup( - &state, - &mut overlay_db, - block_hash, - candidate_hash, - 1, - ).unwrap(); + let actions = process_wakeup(&state, &mut overlay_db, block_hash, candidate_hash, 1).unwrap(); assert_eq!(actions.len(), 1); assert_matches!( @@ -1858,14 +1805,10 @@ fn process_wakeup_schedules_wakeup() { } #[test] -fn triggered_assignment_leads_to_recovery_and_validation() { - -} +fn triggered_assignment_leads_to_recovery_and_validation() {} #[test] -fn finalization_event_prunes() { - -} +fn finalization_event_prunes() {} #[test] fn local_approval_import_always_updates_approval_entry() { @@ -1884,18 +1827,11 @@ fn local_approval_import_always_updates_approval_entry() { }; let state = State { - assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| { - Ok(0) - })), + assignment_criteria: Box::new(MockAssignmentCriteria::check_only(|| Ok(0))), ..some_state(state_config.clone(), &mut db) }; - add_block( - &mut db, - block_hash_2, - state_config.session_index, - state_config.slot, - ); + add_block(&mut db, block_hash_2, state_config.session_index, state_config.slot); add_candidate_to_block( &mut db, diff --git a/polkadot/node/core/approval-voting/src/ops.rs b/polkadot/node/core/approval-voting/src/ops.rs index cc02aa811de..f142ac6b49c 100644 --- a/polkadot/node/core/approval-voting/src/ops.rs +++ b/polkadot/node/core/approval-voting/src/ops.rs @@ -19,21 +19,18 @@ use polkadot_node_subsystem::SubsystemResult; -use polkadot_primitives::v1::{ - CandidateHash, CandidateReceipt, BlockNumber, GroupIndex, Hash, +use bitvec::order::Lsb0 as BitOrderLsb0; +use polkadot_primitives::v1::{BlockNumber, CandidateHash, CandidateReceipt, GroupIndex, Hash}; + +use std::{ + collections::{hash_map::Entry, BTreeMap, HashMap}, + convert::Into, }; -use bitvec::{order::Lsb0 as BitOrderLsb0}; - -use std::convert::Into; -use std::collections::{BTreeMap, HashMap}; -use std::collections::hash_map::Entry; - -use super::persisted_entries::{ApprovalEntry, CandidateEntry, BlockEntry}; -use super::backend::{Backend, OverlayedBackend}; -use super::approval_db::{ - v1::{ - OurAssignment, StoredBlockRange, - }, + +use super::{ + approval_db::v1::{OurAssignment, StoredBlockRange}, + backend::{Backend, OverlayedBackend}, + persisted_entries::{ApprovalEntry, BlockEntry, CandidateEntry}, }; /// Information about a new candidate necessary to instantiate the requisite @@ -75,7 +72,7 @@ fn visit_and_remove_block_entry( None => continue, // Should not happen except for corrupt DB Some(c) => c, }) - } + }, }; candidate.block_assignments.remove(&block_hash); @@ -111,11 +108,7 @@ pub fn canonicalize( overlay_db.delete_blocks_at_height(i); for b in at_height { - let _ = visit_and_remove_block_entry( - b, - overlay_db, - &mut visited_candidates, - )?; + let _ = visit_and_remove_block_entry(b, overlay_db, &mut visited_candidates)?; } } @@ -129,11 +122,7 @@ pub fn canonicalize( let mut pruned_branches = Vec::new(); for b in at_height { - let children = visit_and_remove_block_entry( - b, - overlay_db, - &mut visited_candidates, - )?; + let children = visit_and_remove_block_entry(b, overlay_db, &mut visited_candidates)?; if b != canon_hash { pruned_branches.extend(children); @@ -145,13 +134,11 @@ pub fn canonicalize( // Follow all children of non-canonicalized blocks. { - let mut frontier: Vec<(BlockNumber, Hash)> = pruned_branches.into_iter().map(|h| (canon_number + 1, h)).collect(); + let mut frontier: Vec<(BlockNumber, Hash)> = + pruned_branches.into_iter().map(|h| (canon_number + 1, h)).collect(); while let Some((height, next_child)) = frontier.pop() { - let children = visit_and_remove_block_entry( - next_child, - overlay_db, - &mut visited_candidates, - )?; + let children = + visit_and_remove_block_entry(next_child, overlay_db, &mut visited_candidates)?; // extend the frontier of branches to include the given height. frontier.extend(children.into_iter().map(|h| (height + 1, h))); @@ -188,10 +175,7 @@ pub fn canonicalize( // due to the fork pruning, this range actually might go too far above where our actual highest block is, // if a relatively short fork is canonicalized. // TODO https://github.com/paritytech/polkadot/issues/3389 - let new_range = StoredBlockRange( - canon_number + 1, - std::cmp::max(range.1, canon_number + 2), - ); + let new_range = StoredBlockRange(canon_number + 1, std::cmp::max(range.1, canon_number + 2)); overlay_db.write_stored_block_range(new_range); @@ -246,21 +230,20 @@ pub fn add_block_entry( // read and write all updated entries. { for &(_, ref candidate_hash) in entry.candidates() { - let NewCandidateInfo { - candidate, - backing_group, - our_assignment, - } = match candidate_info(candidate_hash) { - None => return Ok(Vec::new()), - Some(info) => info, - }; - - let mut candidate_entry = store.load_candidate_entry(&candidate_hash)? - .unwrap_or_else(move || CandidateEntry { - candidate, - session, - block_assignments: BTreeMap::new(), - approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], + let NewCandidateInfo { candidate, backing_group, our_assignment } = + match candidate_info(candidate_hash) { + None => return Ok(Vec::new()), + Some(info) => info, + }; + + let mut candidate_entry = + store.load_candidate_entry(&candidate_hash)?.unwrap_or_else(move || { + CandidateEntry { + candidate, + session, + block_assignments: BTreeMap::new(), + approvals: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], + } }); candidate_entry.block_assignments.insert( @@ -272,7 +255,7 @@ pub fn add_block_entry( None, bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], false, - ) + ), ); store.write_candidate_entry(candidate_entry.clone()); @@ -313,7 +296,6 @@ pub fn force_approve( // iterate back to the `up_to` block, and then iterate backwards until all blocks // are updated. while let Some(mut entry) = store.load_block_entry(&cur_hash)? { - if entry.block_number() <= up_to { state = State::Approving; } @@ -326,7 +308,7 @@ pub fn force_approve( entry.approved_bitfield.iter_mut().for_each(|mut b| *b = true); approved_hashes.push(entry.block_hash()); store.write_block_entry(entry); - } + }, } } diff --git a/polkadot/node/core/approval-voting/src/persisted_entries.rs b/polkadot/node/core/approval-voting/src/persisted_entries.rs index b2ca8a69107..aaeeda98b86 100644 --- a/polkadot/node/core/approval-voting/src/persisted_entries.rs +++ b/polkadot/node/core/approval-voting/src/persisted_entries.rs @@ -20,18 +20,17 @@ //! Within that context, things are plain-old-data. Within this module, //! data and logic are intertwined. -use polkadot_node_primitives::approval::{DelayTranche, RelayVRFStory, AssignmentCert}; +use polkadot_node_primitives::approval::{AssignmentCert, DelayTranche, RelayVRFStory}; use polkadot_primitives::v1::{ - ValidatorIndex, CandidateReceipt, SessionIndex, GroupIndex, CoreIndex, - Hash, CandidateHash, BlockNumber, ValidatorSignature, + BlockNumber, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, Hash, SessionIndex, + ValidatorIndex, ValidatorSignature, }; use sp_consensus_slots::Slot; +use bitvec::{order::Lsb0 as BitOrderLsb0, slice::BitSlice, vec::BitVec}; use std::collections::BTreeMap; -use bitvec::{slice::BitSlice, vec::BitVec, order::Lsb0 as BitOrderLsb0}; -use super::time::Tick; -use super::criteria::OurAssignment; +use super::{criteria::OurAssignment, time::Tick}; /// Metadata regarding a specific tranche of assignments for a specific candidate. #[derive(Debug, Clone, PartialEq)] @@ -105,11 +104,14 @@ impl ApprovalEntry { } // Note that our assignment is triggered. No-op if already triggered. - pub fn trigger_our_assignment(&mut self, tick_now: Tick) - -> Option<(AssignmentCert, ValidatorIndex, DelayTranche)> - { + pub fn trigger_our_assignment( + &mut self, + tick_now: Tick, + ) -> Option<(AssignmentCert, ValidatorIndex, DelayTranche)> { let our = self.our_assignment.as_mut().and_then(|a| { - if a.triggered() { return None } + if a.triggered() { + return None + } a.mark_triggered(); Some(a.clone()) @@ -143,22 +145,16 @@ impl ApprovalEntry { let idx = match self.tranches.iter().position(|t| t.tranche >= tranche) { Some(pos) => { if self.tranches[pos].tranche > tranche { - self.tranches.insert(pos, TrancheEntry { - tranche: tranche, - assignments: Vec::new(), - }); + self.tranches.insert(pos, TrancheEntry { tranche, assignments: Vec::new() }); } pos - } + }, None => { - self.tranches.push(TrancheEntry { - tranche: tranche, - assignments: Vec::new(), - }); + self.tranches.push(TrancheEntry { tranche, assignments: Vec::new() }); self.tranches.len() - 1 - } + }, }; self.tranches[idx].assignments.push((validator_index, tick_now)); @@ -168,15 +164,16 @@ impl ApprovalEntry { // Produce a bitvec indicating the assignments of all validators up to and // including `tranche`. pub fn assignments_up_to(&self, tranche: DelayTranche) -> BitVec { - self.tranches.iter() - .take_while(|e| e.tranche <= tranche) - .fold(bitvec::bitvec![BitOrderLsb0, u8; 0; self.assignments.len()], |mut a, e| { + self.tranches.iter().take_while(|e| e.tranche <= tranche).fold( + bitvec::bitvec![BitOrderLsb0, u8; 0; self.assignments.len()], + |mut a, e| { for &(v, _) in &e.assignments { a.set(v.0 as _, true); } a - }) + }, + ) } /// Whether the approval entry is approved @@ -299,11 +296,7 @@ impl CandidateEntry { } #[cfg(test)] - pub fn add_approval_entry( - &mut self, - block_hash: Hash, - approval_entry: ApprovalEntry, - ) { + pub fn add_approval_entry(&mut self, block_hash: Hash, approval_entry: ApprovalEntry) { self.block_assignments.insert(block_hash, approval_entry); } } @@ -313,7 +306,11 @@ impl From for CandidateEntry { CandidateEntry { candidate: entry.candidate, session: entry.session, - block_assignments: entry.block_assignments.into_iter().map(|(h, ae)| (h, ae.into())).collect(), + block_assignments: entry + .block_assignments + .into_iter() + .map(|(h, ae)| (h, ae.into())) + .collect(), approvals: entry.approvals, } } @@ -324,7 +321,11 @@ impl From for crate::approval_db::v1::CandidateEntry { Self { candidate: entry.candidate, session: entry.session, - block_assignments: entry.block_assignments.into_iter().map(|(h, ae)| (h, ae.into())).collect(), + block_assignments: entry + .block_assignments + .into_iter() + .map(|(h, ae)| (h, ae.into())) + .collect(), approvals: entry.approvals, } } @@ -360,7 +361,9 @@ impl BlockEntry { /// Whether a candidate is approved in the bitfield. pub fn is_candidate_approved(&self, candidate_hash: &CandidateHash) -> bool { - self.candidates.iter().position(|(_, h)| h == candidate_hash) + self.candidates + .iter() + .position(|(_, h)| h == candidate_hash) .and_then(|p| self.approved_bitfield.get(p).map(|b| *b)) .unwrap_or(false) } @@ -372,10 +375,12 @@ impl BlockEntry { /// Iterate over all unapproved candidates. pub fn unapproved_candidates(&self) -> impl Iterator + '_ { - self.approved_bitfield.iter().enumerate().filter_map(move |(i, a)| if !*a { - Some(self.candidates[i].1) - } else { - None + self.approved_bitfield.iter().enumerate().filter_map(move |(i, a)| { + if !*a { + Some(self.candidates[i].1) + } else { + None + } }) } @@ -385,9 +390,7 @@ impl BlockEntry { /// Panics if the core is already used. #[cfg(test)] pub fn add_candidate(&mut self, core: CoreIndex, candidate_hash: CandidateHash) -> usize { - let pos = self.candidates - .binary_search_by_key(&core, |(c, _)| *c) - .unwrap_err(); + let pos = self.candidates.binary_search_by_key(&core, |(c, _)| *c).unwrap_err(); self.candidates.insert(pos, (core, candidate_hash)); diff --git a/polkadot/node/core/approval-voting/src/tests.rs b/polkadot/node/core/approval-voting/src/tests.rs index c18206ae4d3..fc39815e3e9 100644 --- a/polkadot/node/core/approval-voting/src/tests.rs +++ b/polkadot/node/core/approval-voting/src/tests.rs @@ -16,34 +16,39 @@ // along with Polkadot. If not, see . use super::*; -use std::time::Duration; -use polkadot_overseer::HeadSupportsParachains; -use polkadot_primitives::v1::{ - CoreIndex, GroupIndex, ValidatorSignature, Header, CandidateEvent, -}; -use polkadot_node_subsystem::{ActivatedLeaf, ActiveLeavesUpdate, LeafStatus}; use polkadot_node_primitives::approval::{ - AssignmentCert, AssignmentCertKind, VRFOutput, VRFProof, - RELAY_VRF_MODULO_CONTEXT, DelayTranche, + AssignmentCert, AssignmentCertKind, DelayTranche, VRFOutput, VRFProof, RELAY_VRF_MODULO_CONTEXT, +}; +use polkadot_node_subsystem::{ + messages::{AllMessages, ApprovalVotingMessage, AssignmentCheckResult}, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, }; use polkadot_node_subsystem_test_helpers as test_helpers; -use polkadot_node_subsystem::messages::{AllMessages, ApprovalVotingMessage, AssignmentCheckResult}; use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_overseer::HeadSupportsParachains; +use polkadot_primitives::v1::{CandidateEvent, CoreIndex, GroupIndex, Header, ValidatorSignature}; +use std::time::Duration; +use assert_matches::assert_matches; use parking_lot::Mutex; -use std::pin::Pin; -use std::sync::Arc; -use std::sync::atomic::{AtomicBool, Ordering}; use sp_keyring::sr25519::Keyring as Sr25519Keyring; use sp_keystore::CryptoStore; -use assert_matches::assert_matches; +use std::{ + pin::Pin, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; -use super::import::tests::{ - BabeEpoch, BabeEpochConfiguration, AllowedSlots, Digest, garbage_vrf, DigestItem, PreDigest, - SecondaryVRFPreDigest, CompatibleDigestItem, +use super::{ + approval_db::v1::StoredBlockRange, + backend::BackendWriteOp, + import::tests::{ + garbage_vrf, AllowedSlots, BabeEpoch, BabeEpochConfiguration, CompatibleDigestItem, Digest, + DigestItem, PreDigest, SecondaryVRFPreDigest, + }, }; -use super::approval_db::v1::StoredBlockRange; -use super::backend::BackendWriteOp; const SLOT_DURATION_MILLIS: u64 = 5000; @@ -92,14 +97,8 @@ fn make_sync_oracle(val: bool) -> (TestSyncOracle, TestSyncOracleHandle) { let flag = Arc::new(AtomicBool::new(val)); ( - TestSyncOracle { - flag: flag.clone(), - done_syncing_sender: Arc::new(Mutex::new(Some(tx))), - }, - TestSyncOracleHandle { - flag, - done_syncing_receiver: rx, - } + TestSyncOracle { flag: flag.clone(), done_syncing_sender: Arc::new(Mutex::new(Some(tx))) }, + TestSyncOracleHandle { flag, done_syncing_receiver: rx }, ) } @@ -114,9 +113,7 @@ pub mod test_constants { const DATA_COL: u32 = 0; pub(crate) const NUM_COLUMNS: u32 = 1; - pub(crate) const TEST_CONFIG: DatabaseConfig = DatabaseConfig { - col_data: DATA_COL, - }; + pub(crate) const TEST_CONFIG: DatabaseConfig = DatabaseConfig { col_data: DATA_COL }; } struct MockSupportsParachains; @@ -175,10 +172,8 @@ impl MockClockInner { fn wakeup_all(&mut self, up_to: Tick) { // This finds the position of the first wakeup after // the given tick, or the end of the map. - let drain_up_to = self.wakeups.binary_search_by_key( - &(up_to + 1), - |w| w.0, - ).unwrap_or_else(|i| i); + let drain_up_to = + self.wakeups.binary_search_by_key(&(up_to + 1), |w| w.0).unwrap_or_else(|i| i); for (_, wakeup) in self.wakeups.drain(..drain_up_to) { let _ = wakeup.send(()); @@ -201,10 +196,7 @@ impl MockClockInner { fn register_wakeup(&mut self, tick: Tick, pre_emptive: bool) -> oneshot::Receiver<()> { let (tx, rx) = oneshot::channel(); - let pos = self.wakeups.binary_search_by_key( - &tick, - |w| w.0, - ).unwrap_or_else(|i| i); + let pos = self.wakeups.binary_search_by_key(&tick, |w| w.0).unwrap_or_else(|i| i); self.wakeups.insert(pos, (tick, tx)); @@ -223,14 +215,18 @@ struct MockAssignmentCriteria(Compute, Check); impl AssignmentCriteria for MockAssignmentCriteria where Compute: Fn() -> HashMap, - Check: Fn() -> Result + Check: Fn() -> Result, { fn compute_assignments( &self, _keystore: &LocalKeystore, _relay_vrf_story: polkadot_node_primitives::approval::RelayVRFStory, _config: &criteria::Config, - _leaving_cores: Vec<(CandidateHash, polkadot_primitives::v1::CoreIndex, polkadot_primitives::v1::GroupIndex)>, + _leaving_cores: Vec<( + CandidateHash, + polkadot_primitives::v1::CoreIndex, + polkadot_primitives::v1::GroupIndex, + )>, ) -> HashMap { self.0() } @@ -248,10 +244,12 @@ where } } -impl MockAssignmentCriteria< - fn() -> HashMap, - F, -> { +impl + MockAssignmentCriteria< + fn() -> HashMap, + F, + > +{ fn check_only(f: F) -> Self { MockAssignmentCriteria(Default::default, f) } @@ -266,10 +264,7 @@ struct TestStore { } impl Backend for TestStore { - fn load_block_entry( - &self, - block_hash: &Hash, - ) -> SubsystemResult> { + fn load_block_entry(&self, block_hash: &Hash) -> SubsystemResult> { Ok(self.block_entries.get(block_hash).cloned()) } @@ -280,10 +275,7 @@ impl Backend for TestStore { Ok(self.candidate_entries.get(candidate_hash).cloned()) } - fn load_blocks_at_height( - &self, - height: &BlockNumber, - ) -> SubsystemResult> { + fn load_blocks_at_height(&self, height: &BlockNumber) -> SubsystemResult> { Ok(self.blocks_at_height.get(height).cloned().unwrap_or_default()) } @@ -300,31 +292,33 @@ impl Backend for TestStore { } fn write(&mut self, ops: I) -> SubsystemResult<()> - where I: IntoIterator + where + I: IntoIterator, { for op in ops { match op { BackendWriteOp::WriteStoredBlockRange(stored_block_range) => { self.stored_block_range = Some(stored_block_range); - } + }, BackendWriteOp::WriteBlocksAtHeight(h, blocks) => { self.blocks_at_height.insert(h, blocks); - } + }, BackendWriteOp::DeleteBlocksAtHeight(h) => { let _ = self.blocks_at_height.remove(&h); - } + }, BackendWriteOp::WriteBlockEntry(block_entry) => { self.block_entries.insert(block_entry.block_hash(), block_entry); - } + }, BackendWriteOp::DeleteBlockEntry(hash) => { let _ = self.block_entries.remove(&hash); - } + }, BackendWriteOp::WriteCandidateEntry(candidate_entry) => { - self.candidate_entries.insert(candidate_entry.candidate_receipt().hash(), candidate_entry); - } + self.candidate_entries + .insert(candidate_entry.candidate_receipt().hash(), candidate_entry); + }, BackendWriteOp::DeleteCandidateEntry(candidate_hash) => { let _ = self.candidate_entries.remove(&candidate_hash); - } + }, } } @@ -340,10 +334,7 @@ fn garbage_assignment_cert(kind: AssignmentCertKind) -> AssignmentCert { let (inout, proof, _) = keypair.vrf_sign(ctx.bytes(msg)); let out = inout.to_output(); - AssignmentCert { - kind, - vrf: (VRFOutput(out), VRFProof(proof)), - } + AssignmentCert { kind, vrf: (VRFOutput(out), VRFProof(proof)) } } fn sign_approval( @@ -383,47 +374,40 @@ fn test_harness>( let store = TestStore::default(); - let HarnessConfig { - tick_start, - assigned_tranche, - } = config; + let HarnessConfig { tick_start, assigned_tranche } = config; let clock = Box::new(MockClock::new(tick_start)); let subsystem = run( context, ApprovalVotingSubsystem::with_config( - Config{ - col_data: test_constants::TEST_CONFIG.col_data, - slot_duration_millis: 100u64, - }, + Config { col_data: test_constants::TEST_CONFIG.col_data, slot_duration_millis: 100u64 }, Arc::new(kvdb_memorydb::create(test_constants::NUM_COLUMNS)), Arc::new(keystore), sync_oracle, Metrics::default(), ), clock.clone(), - Box::new(MockAssignmentCriteria::check_only(move || { Ok(assigned_tranche) })), + Box::new(MockAssignmentCriteria::check_only(move || Ok(assigned_tranche))), store, ); - let test_fut = test(TestHarness { - virtual_overseer, - clock, - }); + let test_fut = test(TestHarness { virtual_overseer, clock }); futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - futures::executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer_signal(&mut overseer, OverseerSignal::Conclude).await; - }, subsystem)).1.unwrap(); + futures::executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); } -async fn overseer_send( - overseer: &mut VirtualOverseer, - msg: FromOverseer, -) { +async fn overseer_send(overseer: &mut VirtualOverseer, msg: FromOverseer) { tracing::trace!("Sending message:\n{:?}", &msg); overseer .send(msg) @@ -432,9 +416,7 @@ async fn overseer_send( .expect(&format!("{:?} is enough for sending messages.", TIMEOUT)); } -async fn overseer_recv( - overseer: &mut VirtualOverseer, -) -> AllMessages { +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { let msg = overseer_recv_with_timeout(overseer, TIMEOUT) .await .expect(&format!("{:?} is enough to receive messages.", TIMEOUT)); @@ -449,17 +431,11 @@ async fn overseer_recv_with_timeout( timeout: Duration, ) -> Option { tracing::trace!("Waiting for message..."); - overseer - .recv() - .timeout(timeout) - .await + overseer.recv().timeout(timeout).await } const TIMEOUT: Duration = Duration::from_millis(2000); -async fn overseer_signal( - overseer: &mut VirtualOverseer, - signal: OverseerSignal, -) { +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { overseer .send(FromOverseer::Signal(signal)) .timeout(TIMEOUT) @@ -471,10 +447,7 @@ async fn overseer_signal( fn blank_subsystem_act_on_bad_block() { let (oracle, handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let (tx, rx) = oneshot::channel(); @@ -484,18 +457,19 @@ fn blank_subsystem_act_on_bad_block() { &mut virtual_overseer, FromOverseer::Communication { msg: ApprovalVotingMessage::CheckAndImportAssignment( - IndirectAssignmentCert{ + IndirectAssignmentCert { block_hash: bad_block_hash.clone(), validator: 0u32.into(), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { + sample: 0, + }), }, 0u32, tx, - ) - } - ).await; + ), + }, + ) + .await; handle.await_mode_switch().await; @@ -516,10 +490,7 @@ fn blank_subsystem_act_on_bad_block() { fn ss_rejects_approval_if_no_block_entry() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let block_hash = Hash::repeat_byte(0x01); let candidate_index = 0; @@ -535,7 +506,8 @@ fn ss_rejects_approval_if_no_block_entry() { candidate_hash, session_index, false, - ).await; + ) + .await; assert_matches!( rx.await, @@ -552,10 +524,7 @@ fn ss_rejects_approval_if_no_block_entry() { fn ss_rejects_approval_before_assignment() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let block_hash = Hash::repeat_byte(0x01); @@ -584,7 +553,8 @@ fn ss_rejects_approval_before_assignment() { candidate_hash, session_index, false, - ).await; + ) + .await; assert_matches!( rx.await, @@ -600,59 +570,49 @@ fn ss_rejects_approval_before_assignment() { #[test] fn ss_rejects_assignment_in_future() { let (oracle, _handle) = make_sync_oracle(false); - test_harness(HarnessConfig { - tick_start: 0, - assigned_tranche: TICK_TOO_FAR_IN_FUTURE as _, - ..Default::default() - }, Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - clock, - } = test_harness; + test_harness( + HarnessConfig { + tick_start: 0, + assigned_tranche: TICK_TOO_FAR_IN_FUTURE as _, + ..Default::default() + }, + Box::new(oracle), + |test_harness| async move { + let TestHarness { mut virtual_overseer, clock } = test_harness; - let block_hash = Hash::repeat_byte(0x01); - let candidate_index = 0; - let validator = ValidatorIndex(0); + let block_hash = Hash::repeat_byte(0x01); + let candidate_index = 0; + let validator = ValidatorIndex(0); - // Add block hash 00. - ChainBuilder::new() - .add_block(block_hash, ChainBuilder::GENESIS_HASH, Slot::from(1), 1) - .build(&mut virtual_overseer) - .await; + // Add block hash 00. + ChainBuilder::new() + .add_block(block_hash, ChainBuilder::GENESIS_HASH, Slot::from(1), 1) + .build(&mut virtual_overseer) + .await; - let rx = cai_assignment( - &mut virtual_overseer, - block_hash, - candidate_index, - validator, - ).await; + let rx = + cai_assignment(&mut virtual_overseer, block_hash, candidate_index, validator).await; - assert_eq!(rx.await, Ok(AssignmentCheckResult::TooFarInFuture)); + assert_eq!(rx.await, Ok(AssignmentCheckResult::TooFarInFuture)); - // Advance clock to make assignment reasonably near. - clock.inner.lock().set_tick(1); + // Advance clock to make assignment reasonably near. + clock.inner.lock().set_tick(1); - let rx = cai_assignment( - &mut virtual_overseer, - block_hash, - candidate_index, - validator, - ).await; + let rx = + cai_assignment(&mut virtual_overseer, block_hash, candidate_index, validator).await; - assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); + assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); - virtual_overseer - }); + virtual_overseer + }, + ); } #[test] fn ss_accepts_duplicate_assignment() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let block_hash = Hash::repeat_byte(0x01); let candidate_index = 0; @@ -664,21 +624,13 @@ fn ss_accepts_duplicate_assignment() { .build(&mut virtual_overseer) .await; - let rx = cai_assignment( - &mut virtual_overseer, - block_hash, - candidate_index, - validator, - ).await; + let rx = + cai_assignment(&mut virtual_overseer, block_hash, candidate_index, validator).await; assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); - let rx = cai_assignment( - &mut virtual_overseer, - block_hash, - candidate_index, - validator, - ).await; + let rx = + cai_assignment(&mut virtual_overseer, block_hash, candidate_index, validator).await; assert_eq!(rx.await, Ok(AssignmentCheckResult::AcceptedDuplicate)); @@ -690,10 +642,7 @@ fn ss_accepts_duplicate_assignment() { fn ss_rejects_assignment_with_unknown_candidate() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let block_hash = Hash::repeat_byte(0x01); let candidate_index = 7; @@ -705,16 +654,14 @@ fn ss_rejects_assignment_with_unknown_candidate() { .build(&mut virtual_overseer) .await; - let rx = cai_assignment( - &mut virtual_overseer, - block_hash, - candidate_index, - validator, - ).await; + let rx = + cai_assignment(&mut virtual_overseer, block_hash, candidate_index, validator).await; assert_eq!( rx.await, - Ok(AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex(candidate_index))), + Ok(AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex( + candidate_index + ))), ); virtual_overseer @@ -725,10 +672,7 @@ fn ss_rejects_assignment_with_unknown_candidate() { fn ss_accepts_and_imports_approval_after_assignment() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let block_hash = Hash::repeat_byte(0x01); @@ -749,12 +693,8 @@ fn ss_accepts_and_imports_approval_after_assignment() { .build(&mut virtual_overseer) .await; - let rx = cai_assignment( - &mut virtual_overseer, - block_hash, - candidate_index, - validator, - ).await; + let rx = + cai_assignment(&mut virtual_overseer, block_hash, candidate_index, validator).await; assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); @@ -766,7 +706,8 @@ fn ss_accepts_and_imports_approval_after_assignment() { candidate_hash, session_index, true, - ).await; + ) + .await; assert_eq!(rx.await, Ok(ApprovalCheckResult::Accepted)); @@ -777,10 +718,7 @@ fn ss_accepts_and_imports_approval_after_assignment() { fn ss_assignment_import_updates_candidate_entry_and_schedules_wakeup() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let block_hash = Hash::repeat_byte(0x01); @@ -800,12 +738,8 @@ fn ss_assignment_import_updates_candidate_entry_and_schedules_wakeup() { .build(&mut virtual_overseer) .await; - let rx = cai_assignment( - &mut virtual_overseer, - block_hash, - candidate_index, - validator, - ).await; + let rx = + cai_assignment(&mut virtual_overseer, block_hash, candidate_index, validator).await; assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); @@ -831,16 +765,12 @@ async fn cai_approval( overseer, FromOverseer::Communication { msg: ApprovalVotingMessage::CheckAndImportApproval( - IndirectSignedApprovalVote { - block_hash, - candidate_index, - validator, - signature, - }, + IndirectSignedApprovalVote { block_hash, candidate_index, validator, signature }, tx, ), - } - ).await; + }, + ) + .await; if expect_coordinator { assert_matches!( @@ -870,17 +800,14 @@ async fn cai_assignment( IndirectAssignmentCert { block_hash, validator, - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { - sample: 0, - }, - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }), }, candidate_index, tx, ), - } - ).await; + }, + ) + .await; rx } @@ -889,16 +816,13 @@ struct ChainBuilder { blocks_at_height: BTreeMap>, } - impl ChainBuilder { const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); const GENESIS_PARENT_HASH: Hash = Hash::repeat_byte(0x00); pub fn new() -> Self { - let mut builder = Self { - blocks_by_hash: HashMap::new(), - blocks_at_height: BTreeMap::new(), - }; + let mut builder = + Self { blocks_by_hash: HashMap::new(), blocks_at_height: BTreeMap::new() }; builder.add_block_inner(Self::GENESIS_HASH, Self::GENESIS_PARENT_HASH, Slot::from(0), 0); builder } @@ -912,7 +836,10 @@ impl ChainBuilder { ) -> &'a mut Self { assert!(number != 0, "cannot add duplicate genesis block"); assert!(hash != Self::GENESIS_HASH, "cannot add block with genesis hash"); - assert!(parent_hash != Self::GENESIS_PARENT_HASH, "cannot add block with genesis parent hash"); + assert!( + parent_hash != Self::GENESIS_PARENT_HASH, + "cannot add block with genesis parent hash" + ); assert!(self.blocks_by_hash.len() < u8::MAX.into()); self.add_block_inner(hash, parent_hash, slot, number) } @@ -927,7 +854,8 @@ impl ChainBuilder { let header = ChainBuilder::make_header(parent_hash, slot, number); assert!( self.blocks_by_hash.insert(hash, header).is_none(), - "block with hash {:?} already exists", hash, + "block with hash {:?} already exists", + hash, ); self.blocks_at_height.entry(number).or_insert_with(Vec::new).push(hash); self @@ -939,7 +867,8 @@ impl ChainBuilder { let mut cur_hash = *hash; let mut ancestry = Vec::new(); while cur_hash != Self::GENESIS_PARENT_HASH { - let cur_header = self.blocks_by_hash.get(&cur_hash).expect("chain is not contiguous"); + let cur_header = + self.blocks_by_hash.get(&cur_hash).expect("chain is not contiguous"); ancestry.push((cur_hash, cur_header.clone())); cur_hash = cur_header.parent_hash; } @@ -950,21 +879,12 @@ impl ChainBuilder { } } - fn make_header( - parent_hash: Hash, - slot: Slot, - number: u32, - ) -> Header { + fn make_header(parent_hash: Hash, slot: Slot, number: u32) -> Header { let digest = { let mut digest = Digest::default(); let (vrf_output, vrf_proof) = garbage_vrf(); digest.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( - SecondaryVRFPreDigest { - authority_index: 0, - slot, - vrf_output, - vrf_proof, - } + SecondaryVRFPreDigest { authority_index: 0, slot, vrf_output, vrf_proof }, ))); digest }; @@ -976,8 +896,8 @@ impl ChainBuilder { state_root: Default::default(), parent_hash, } - } - } + } +} async fn import_block( overseer: &mut VirtualOverseer, @@ -1003,13 +923,16 @@ async fn import_block( let (new_head, new_header) = &hashes[hashes.len() - 1]; overseer_send( overseer, - FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash: *new_head, - number: session, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - })), - )).await; + FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + ActivatedLeaf { + hash: *new_head, + number: session, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }, + ))), + ) + .await; assert_matches!( overseer_recv(overseer).await, @@ -1070,22 +993,21 @@ async fn import_block( let (hash, header) = hashes[i as usize].clone(); assert_eq!(hash, *new_head); h_tx.send(Ok(Some(header))).unwrap(); - } + }, AllMessages::ChainApi(ChainApiMessage::Ancestors { hash, k, response_channel, }) => { assert_eq!(hash, *new_head); - assert_eq!(k as u32, session-1); + assert_eq!(k as u32, session - 1); let history: Vec = hashes.iter().map(|v| v.0).take(k).collect(); response_channel.send(Ok(history)).unwrap(); - } - _ => unreachable!{}, + }, + _ => unreachable! {}, } } } - } if session > 0 { @@ -1184,10 +1106,7 @@ fn linear_import_act_on_leaf() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let mut head: Hash = ChainBuilder::GENESIS_HASH; let mut builder = ChainBuilder::new(); @@ -1197,7 +1116,7 @@ fn linear_import_act_on_leaf() { let hash = Hash::repeat_byte(i as u8); builder.add_block(hash, head, slot, i); head = hash; - } + } builder.build(&mut virtual_overseer).await; @@ -1207,18 +1126,19 @@ fn linear_import_act_on_leaf() { &mut virtual_overseer, FromOverseer::Communication { msg: ApprovalVotingMessage::CheckAndImportAssignment( - IndirectAssignmentCert{ + IndirectAssignmentCert { block_hash: head, validator: 0u32.into(), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { + sample: 0, + }), }, 0u32, tx, - ) - } - ).await; + ), + }, + ) + .await; assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); @@ -1232,10 +1152,7 @@ fn forkful_import_at_same_height_act_on_leaf() { let (oracle, _handle) = make_sync_oracle(false); test_harness(Default::default(), Box::new(oracle), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; + let TestHarness { mut virtual_overseer, .. } = test_harness; let mut head: Hash = ChainBuilder::GENESIS_HASH; let mut builder = ChainBuilder::new(); @@ -1252,7 +1169,7 @@ fn forkful_import_at_same_height_act_on_leaf() { let slot = Slot::from(session as u64); let hash = Hash::repeat_byte(session as u8 + i); builder.add_block(hash, head, slot, session); - } + } builder.build(&mut virtual_overseer).await; for head in forks.into_iter() { @@ -1262,18 +1179,19 @@ fn forkful_import_at_same_height_act_on_leaf() { &mut virtual_overseer, FromOverseer::Communication { msg: ApprovalVotingMessage::CheckAndImportAssignment( - IndirectAssignmentCert{ + IndirectAssignmentCert { block_hash: head, validator: 0u32.into(), - cert: garbage_assignment_cert( - AssignmentCertKind::RelayVRFModulo { sample: 0 } - ), + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { + sample: 0, + }), }, 0u32, tx, - ) - } - ).await; + ), + }, + ) + .await; assert_eq!(rx.await, Ok(AssignmentCheckResult::Accepted)); } diff --git a/polkadot/node/core/approval-voting/src/time.rs b/polkadot/node/core/approval-voting/src/time.rs index d12132fab9a..2d1230749a4 100644 --- a/polkadot/node/core/approval-voting/src/time.rs +++ b/polkadot/node/core/approval-voting/src/time.rs @@ -16,11 +16,13 @@ //! Time utilities for approval voting. +use futures::prelude::*; use polkadot_node_primitives::approval::DelayTranche; use sp_consensus_slots::Slot; -use futures::prelude::*; -use std::time::{Duration, SystemTime}; -use std::pin::Pin; +use std::{ + pin::Pin, + time::{Duration, SystemTime}, +}; const TICK_DURATION_MILLIS: u64 = 500; diff --git a/polkadot/node/core/av-store/src/lib.rs b/polkadot/node/core/av-store/src/lib.rs index 09a3a28fed5..1d39961cb3c 100644 --- a/polkadot/node/core/av-store/src/lib.rs +++ b/polkadot/node/core/av-store/src/lib.rs @@ -16,41 +16,36 @@ //! Implements a `AvailabilityStoreSubsystem`. -#![recursion_limit="256"] +#![recursion_limit = "256"] #![warn(missing_docs)] -use std::collections::{HashMap, HashSet, BTreeSet}; -use std::io; -use std::sync::Arc; -use std::time::{Duration, SystemTime, SystemTimeError, UNIX_EPOCH}; +use std::{ + collections::{BTreeSet, HashMap, HashSet}, + io, + sync::Arc, + time::{Duration, SystemTime, SystemTimeError, UNIX_EPOCH}, +}; -use parity_scale_codec::{Encode, Decode, Input, Error as CodecError}; -use futures::{select, channel::oneshot, future, FutureExt}; +use futures::{channel::oneshot, future, select, FutureExt}; use futures_timer::Delay; -use kvdb::{KeyValueDB, DBTransaction}; +use kvdb::{DBTransaction, KeyValueDB}; +use parity_scale_codec::{Decode, Encode, Error as CodecError, Input}; -use polkadot_primitives::v1::{ - Hash, BlockNumber, CandidateEvent, ValidatorIndex, CandidateHash, - CandidateReceipt, Header, -}; -use polkadot_node_primitives::{ - ErasureChunk, AvailableData, -}; -use polkadot_subsystem::{ - FromOverseer, OverseerSignal, SubsystemError, - SubsystemContext, SpawnedSubsystem, - overseer, - ActiveLeavesUpdate, - errors::{ChainApiError, RuntimeApiError}, -}; +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use polkadot_node_primitives::{AvailableData, ErasureChunk}; use polkadot_node_subsystem_util::{ self as util, metrics::{self, prometheus}, }; -use polkadot_subsystem::messages::{ - AvailabilityStoreMessage, ChainApiMessage, +use polkadot_primitives::v1::{ + BlockNumber, CandidateEvent, CandidateHash, CandidateReceipt, Hash, Header, ValidatorIndex, +}; +use polkadot_subsystem::{ + errors::{ChainApiError, RuntimeApiError}, + messages::{AvailabilityStoreMessage, ChainApiMessage}, + overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, + SubsystemError, }; -use bitvec::{vec::BitVec, order::Lsb0 as BitOrderLsb0}; #[cfg(test)] mod tests; @@ -126,7 +121,9 @@ impl Encode for BEBlockNumber { impl Decode for BEBlockNumber { fn decode(value: &mut I) -> Result { - <[u8; std::mem::size_of::()]>::decode(value).map(BlockNumber::from_be_bytes).map(Self) + <[u8; std::mem::size_of::()]>::decode(value) + .map(BlockNumber::from_be_bytes) + .map(Self) } } @@ -143,7 +140,7 @@ enum State { Unfinalized(BETimestamp, Vec<(BEBlockNumber, Hash)>), /// Candidate data has appeared in a finalized block and did so at the given time. #[codec(index = 2)] - Finalized(BETimestamp) + Finalized(BETimestamp), } // Meta information about a candidate. @@ -163,12 +160,12 @@ fn query_inner( Ok(Some(raw)) => { let res = D::decode(&mut &raw[..])?; Ok(Some(res)) - } + }, Ok(None) => Ok(None), Err(e) => { tracing::warn!(target: LOG_TARGET, err = ?e, "Error reading from the availability store"); Err(e.into()) - } + }, } } @@ -193,11 +190,7 @@ fn load_available_data( query_inner(db, config.col_data, &key) } -fn delete_available_data( - tx: &mut DBTransaction, - config: &Config, - hash: &CandidateHash, -) { +fn delete_available_data(tx: &mut DBTransaction, config: &Config, hash: &CandidateHash) { let key = (AVAILABLE_PREFIX, hash).encode(); tx.delete(config.col_data, &key[..]) @@ -247,12 +240,7 @@ fn load_meta( query_inner(db, config.col_meta, &key) } -fn write_meta( - tx: &mut DBTransaction, - config: &Config, - hash: &CandidateHash, - meta: &CandidateMeta, -) { +fn write_meta(tx: &mut DBTransaction, config: &Config, hash: &CandidateHash, meta: &CandidateMeta) { let key = (META_PREFIX, hash).encode(); tx.put_vec(config.col_meta, &key, meta.encode()); @@ -263,11 +251,7 @@ fn delete_meta(tx: &mut DBTransaction, config: &Config, hash: &CandidateHash) { tx.delete(config.col_meta, &key[..]) } -fn delete_unfinalized_height( - tx: &mut DBTransaction, - config: &Config, - block_number: BlockNumber, -) { +fn delete_unfinalized_height(tx: &mut DBTransaction, config: &Config, block_number: BlockNumber) { let prefix = (UNFINALIZED_PREFIX, BEBlockNumber(block_number)).encode(); tx.delete_prefix(config.col_meta, &prefix); } @@ -279,12 +263,8 @@ fn delete_unfinalized_inclusion( block_hash: &Hash, candidate_hash: &CandidateHash, ) { - let key = ( - UNFINALIZED_PREFIX, - BEBlockNumber(block_number), - block_hash, - candidate_hash, - ).encode(); + let key = + (UNFINALIZED_PREFIX, BEBlockNumber(block_number), block_hash, candidate_hash).encode(); tx.delete(config.col_meta, &key[..]); } @@ -338,7 +318,7 @@ fn pruning_range(now: impl Into) -> (Vec, Vec) { fn decode_unfinalized_key(s: &[u8]) -> Result<(BlockNumber, Hash, CandidateHash), CodecError> { if !s.starts_with(UNFINALIZED_PREFIX) { - return Err("missing magic string".into()); + return Err("missing magic string".into()) } <(BEBlockNumber, Hash, CandidateHash)>::decode(&mut &s[UNFINALIZED_PREFIX.len()..]) @@ -347,7 +327,7 @@ fn decode_unfinalized_key(s: &[u8]) -> Result<(BlockNumber, Hash, CandidateHash) fn decode_pruning_key(s: &[u8]) -> Result<(Duration, CandidateHash), CodecError> { if !s.starts_with(PRUNE_BY_TIME_PREFIX) { - return Err("missing magic string".into()); + return Err("missing magic string".into()) } <(BETimestamp, CandidateHash)>::decode(&mut &s[PRUNE_BY_TIME_PREFIX.len()..]) @@ -389,8 +369,8 @@ impl Error { fn trace(&self) { match self { // don't spam the log with spurious errors - Self::RuntimeApi(_) | - Self::Oneshot(_) => tracing::debug!(target: LOG_TARGET, err = ?self), + Self::RuntimeApi(_) | Self::Oneshot(_) => + tracing::debug!(target: LOG_TARGET, err = ?self), // it's worth reporting otherwise _ => tracing::warn!(target: LOG_TARGET, err = ?self), } @@ -457,11 +437,7 @@ pub struct AvailabilityStoreSubsystem { impl AvailabilityStoreSubsystem { /// Create a new `AvailabilityStoreSubsystem` with a given config on disk. - pub fn new( - db: Arc, - config: Config, - metrics: Metrics, - ) -> Self { + pub fn new(db: Arc, config: Config, metrics: Metrics) -> Self { Self::with_pruning_config_and_clock( db, config, @@ -530,14 +506,9 @@ where Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { - let future = run(self, ctx) - .map(|_| Ok(())) - .boxed(); + let future = run(self, ctx).map(|_| Ok(())).boxed(); - SpawnedSubsystem { - name: "availability-store-subsystem", - future, - } + SpawnedSubsystem { name: "availability-store-subsystem", future } } } @@ -555,12 +526,12 @@ where e.trace(); if let Error::Subsystem(SubsystemError::Context(_)) = e { - break; + break } - } + }, Ok(true) => { tracing::info!(target: LOG_TARGET, "received `Conclude` signal, exiting"); - break; + break }, Ok(false) => continue, } @@ -571,8 +542,7 @@ async fn run_iteration( ctx: &mut Context, subsystem: &mut AvailabilityStoreSubsystem, mut next_pruning: &mut future::Fuse, -) - -> Result +) -> Result where Context: SubsystemContext, Context: overseer::SubsystemContext, @@ -634,9 +604,7 @@ where let block_header = { let (tx, rx) = oneshot::channel(); - ctx.send_message( - ChainApiMessage::BlockHeader(activated, tx) - ).await; + ctx.send_message(ChainApiMessage::BlockHeader(activated, tx)).await; match rx.await?? { None => return Ok(()), @@ -647,13 +615,12 @@ where let new_blocks = util::determine_new_blocks( ctx.sender(), - |hash| -> Result { - Ok(subsystem.known_blocks.is_known(hash)) - }, + |hash| -> Result { Ok(subsystem.known_blocks.is_known(hash)) }, activated, &block_header, subsystem.finalized_number.unwrap_or(block_number.saturating_sub(1)), - ).await?; + ) + .await?; // determine_new_blocks is descending in block height for (hash, header) in new_blocks.into_iter().rev() { @@ -669,7 +636,8 @@ where now, hash, header, - ).await?; + ) + .await?; subsystem.known_blocks.insert(hash, block_number); subsystem.db.write(tx)?; } @@ -691,18 +659,12 @@ where Context: SubsystemContext, Context: overseer::SubsystemContext, { - - let candidate_events = util::request_candidate_events( - hash, - ctx.sender(), - ).await.await??; + let candidate_events = util::request_candidate_events(hash, ctx.sender()).await.await??; // We need to request the number of validators based on the parent state, // as that is the number of validators used to create this block. - let n_validators = util::request_validators( - header.parent_hash, - ctx.sender(), - ).await.await??.len(); + let n_validators = + util::request_validators(header.parent_hash, ctx.sender()).await.await??.len(); for event in candidate_events { match event { @@ -716,7 +678,7 @@ where n_validators, receipt, )?; - } + }, CandidateEvent::CandidateIncluded(receipt, _head, _core_index, _group_index) => { note_block_included( db, @@ -726,8 +688,8 @@ where (header.number, hash), receipt, )?; - } - _ => {} + }, + _ => {}, } } @@ -745,11 +707,7 @@ fn note_block_backed( ) -> Result<(), Error> { let candidate_hash = candidate.hash(); - tracing::debug!( - target: LOG_TARGET, - ?candidate_hash, - "Candidate backed", - ); + tracing::debug!(target: LOG_TARGET, ?candidate_hash, "Candidate backed",); if load_meta(db, config, &candidate_hash)?.is_none() { let meta = CandidateMeta { @@ -771,7 +729,7 @@ fn note_block_included( db: &Arc, db_transaction: &mut DBTransaction, config: &Config, - pruning_config:&PruningConfig, + pruning_config: &PruningConfig, block: (BlockNumber, Hash), candidate: CandidateReceipt, ) -> Result<(), Error> { @@ -786,15 +744,11 @@ fn note_block_included( ?candidate_hash, "Candidate included without being backed?", ); - } + }, Some(mut meta) => { let be_block = (BEBlockNumber(block.0), block.1); - tracing::debug!( - target: LOG_TARGET, - ?candidate_hash, - "Candidate included", - ); + tracing::debug!(target: LOG_TARGET, ?candidate_hash, "Candidate included",); meta.state = match meta.state { State::Unavailable(at) => { @@ -803,20 +757,20 @@ fn note_block_included( delete_pruning_key(db_transaction, config, prune_at, &candidate_hash); State::Unfinalized(at, vec![be_block]) - } + }, State::Unfinalized(at, mut within) => { if let Err(i) = within.binary_search(&be_block) { within.insert(i, be_block); State::Unfinalized(at, within) } else { - return Ok(()); + return Ok(()) } - } + }, State::Finalized(_at) => { // This should never happen as a candidate would have to be included after // finality. return Ok(()) - } + }, }; write_unfinalized_block_contains( @@ -827,7 +781,7 @@ fn note_block_included( &candidate_hash, ); write_meta(db_transaction, config, &candidate_hash, &meta); - } + }, } Ok(()) @@ -837,9 +791,9 @@ macro_rules! peek_num { ($iter:ident) => { match $iter.peek() { Some((k, _)) => decode_unfinalized_key(&k[..]).ok().map(|(b, _, _)| b), - None => None + None => None, } - } + }; } async fn process_block_finalized( @@ -863,7 +817,9 @@ where // as it is not `Send`. That is why we create the iterator once within this loop, drop it, // do an asynchronous request, and then instantiate the exact same iterator again. let batch_num = { - let mut iter = subsystem.db.iter_with_prefix(subsystem.config.col_meta, &start_prefix) + let mut iter = subsystem + .db + .iter_with_prefix(subsystem.config.col_meta, &start_prefix) .take_while(|(k, _)| &k[..] < &end_prefix[..]) .peekable(); @@ -873,7 +829,9 @@ where } }; - if batch_num < next_possible_batch { continue } // sanity. + if batch_num < next_possible_batch { + continue + } // sanity. next_possible_batch = batch_num + 1; let batch_finalized_hash = if batch_num == finalized_number { @@ -884,19 +842,22 @@ where match rx.await?? { None => { - tracing::warn!(target: LOG_TARGET, + tracing::warn!( + target: LOG_TARGET, "Availability store was informed that block #{} is finalized, \ but chain API has no finalized hash.", batch_num, ); break - } + }, Some(h) => h, } }; - let iter = subsystem.db.iter_with_prefix(subsystem.config.col_meta, &start_prefix) + let iter = subsystem + .db + .iter_with_prefix(subsystem.config.col_meta, &start_prefix) .take_while(|(k, _)| &k[..] < &end_prefix[..]) .peekable(); @@ -907,13 +868,7 @@ where delete_unfinalized_height(&mut db_transaction, &subsystem.config, batch_num); - update_blocks_at_finalized_height( - &subsystem, - &mut db_transaction, - batch, - batch_num, - now, - )?; + update_blocks_at_finalized_height(&subsystem, &mut db_transaction, batch, batch_num, now)?; // We need to write at the end of the loop so the prefix iterator doesn't pick up the same values again // in the next iteration. Another unfortunate effect of having to re-initialize the iterator. @@ -936,14 +891,14 @@ fn load_all_at_finalized_height( // Load all candidates that were included at this height. loop { match peek_num!(iter) { - None => break, // end of iterator. + None => break, // end of iterator. Some(n) if n != block_number => break, // end of batch. - _ => {} + _ => {}, } let (k, _v) = iter.next().expect("`peek` used to check non-empty; qed"); - let (_, block_hash, candidate_hash) = decode_unfinalized_key(&k[..]) - .expect("`peek_num` checks validity of key; qed"); + let (_, block_hash, candidate_hash) = + decode_unfinalized_key(&k[..]).expect("`peek_num` checks validity of key; qed"); if block_hash == finalized_hash { candidates.insert(candidate_hash, true); @@ -971,8 +926,8 @@ fn update_blocks_at_finalized_height( candidate_hash, ); - continue; - } + continue + }, Some(c) => c, }; @@ -985,7 +940,7 @@ fn update_blocks_at_finalized_height( // iterating over the candidate here indicates that `State` should // be `Unfinalized`. delete_pruning_key(db_transaction, &subsystem.config, at, &candidate_hash); - } + }, State::Unfinalized(_, blocks) => { for (block_num, block_hash) in blocks.iter().cloned() { // this exact height is all getting cleared out anyway. @@ -999,7 +954,7 @@ fn update_blocks_at_finalized_height( ); } } - } + }, } meta.state = State::Finalized(now.into()); @@ -1014,7 +969,7 @@ fn update_blocks_at_finalized_height( ); } else { meta.state = match meta.state { - State::Finalized(_) => continue, // sanity. + State::Finalized(_) => continue, // sanity. State::Unavailable(_) => continue, // sanity. State::Unfinalized(at, mut blocks) => { // Clear out everything at this height. @@ -1035,7 +990,7 @@ fn update_blocks_at_finalized_height( } else { State::Unfinalized(at, blocks) } - } + }, }; // Update the meta entry. @@ -1053,20 +1008,22 @@ fn process_message( match msg { AvailabilityStoreMessage::QueryAvailableData(candidate, tx) => { let _ = tx.send(load_available_data(&subsystem.db, &subsystem.config, &candidate)?); - } + }, AvailabilityStoreMessage::QueryDataAvailability(candidate, tx) => { - let a = load_meta(&subsystem.db, &subsystem.config, &candidate)?.map_or(false, |m| m.data_available); + let a = load_meta(&subsystem.db, &subsystem.config, &candidate)? + .map_or(false, |m| m.data_available); let _ = tx.send(a); - } + }, AvailabilityStoreMessage::QueryChunk(candidate, validator_index, tx) => { let _timer = subsystem.metrics.time_get_chunk(); - let _ = tx.send(load_chunk(&subsystem.db, &subsystem.config, &candidate, validator_index)?); - } + let _ = + tx.send(load_chunk(&subsystem.db, &subsystem.config, &candidate, validator_index)?); + }, AvailabilityStoreMessage::QueryAllChunks(candidate, tx) => { match load_meta(&subsystem.db, &subsystem.config, &candidate)? { None => { let _ = tx.send(Vec::new()); - } + }, Some(meta) => { let mut chunks = Vec::new(); @@ -1086,64 +1043,61 @@ fn process_message( index, "No chunk found for set bit in meta" ); - } + }, } } let _ = tx.send(chunks); - } + }, } - } + }, AvailabilityStoreMessage::QueryChunkAvailability(candidate, validator_index, tx) => { - let a = load_meta(&subsystem.db, &subsystem.config, &candidate)? - .map_or(false, |m| - *m.chunks_stored.get(validator_index.0 as usize).as_deref().unwrap_or(&false) - ); + let a = load_meta(&subsystem.db, &subsystem.config, &candidate)?.map_or(false, |m| { + *m.chunks_stored.get(validator_index.0 as usize).as_deref().unwrap_or(&false) + }); let _ = tx.send(a); - } - AvailabilityStoreMessage::StoreChunk { - candidate_hash, - chunk, - tx, - } => { + }, + AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk, tx } => { subsystem.metrics.on_chunks_received(1); let _timer = subsystem.metrics.time_store_chunk(); match store_chunk(&subsystem.db, &subsystem.config, candidate_hash, chunk) { Ok(true) => { let _ = tx.send(Ok(())); - } + }, Ok(false) => { let _ = tx.send(Err(())); - } + }, Err(e) => { let _ = tx.send(Err(())); return Err(e) - } + }, } - } - AvailabilityStoreMessage::StoreAvailableData(candidate, _our_index, n_validators, available_data, tx) => { + }, + AvailabilityStoreMessage::StoreAvailableData( + candidate, + _our_index, + n_validators, + available_data, + tx, + ) => { subsystem.metrics.on_chunks_received(n_validators as _); let _timer = subsystem.metrics.time_store_available_data(); - let res = store_available_data( - &subsystem, - candidate, - n_validators as _, - available_data, - ); + let res = + store_available_data(&subsystem, candidate, n_validators as _, available_data); match res { Ok(()) => { let _ = tx.send(Ok(())); - } + }, Err(e) => { let _ = tx.send(Err(())); return Err(e) - } + }, } - } + }, } Ok(()) @@ -1170,7 +1124,7 @@ fn store_chunk( write_chunk(&mut tx, config, &candidate_hash, chunk.index, &chunk); write_meta(&mut tx, config, &candidate_hash, &meta); - } + }, None => return Ok(false), // out of bounds. } @@ -1197,7 +1151,7 @@ fn store_available_data( let mut meta = match load_meta(&subsystem.db, &subsystem.config, &candidate_hash)? { Some(m) => { if m.data_available { - return Ok(()); // already stored. + return Ok(()) // already stored. } m @@ -1214,20 +1168,19 @@ fn store_available_data( data_available: false, chunks_stored: BitVec::new(), } - } + }, }; let chunks = erasure::obtain_chunks_v1(n_validators, &available_data)?; let branches = erasure::branches(chunks.as_ref()); - let erasure_chunks = chunks.iter() - .zip(branches.map(|(proof, _)| proof)) - .enumerate() - .map(|(index, (chunk, proof))| ErasureChunk { + let erasure_chunks = chunks.iter().zip(branches.map(|(proof, _)| proof)).enumerate().map( + |(index, (chunk, proof))| ErasureChunk { chunk: chunk.clone(), proof, index: ValidatorIndex(index as u32), - }); + }, + ); for chunk in erasure_chunks { write_chunk(&mut tx, &subsystem.config, &candidate_hash, chunk.index, &chunk); @@ -1236,16 +1189,12 @@ fn store_available_data( meta.data_available = true; meta.chunks_stored = bitvec::bitvec![BitOrderLsb0, u8; 1; n_validators]; - write_meta(&mut tx, &subsystem.config, &candidate_hash, &meta); + write_meta(&mut tx, &subsystem.config, &candidate_hash, &meta); write_available_data(&mut tx, &subsystem.config, &candidate_hash, &available_data); subsystem.db.write(tx)?; - tracing::debug!( - target: LOG_TARGET, - ?candidate_hash, - "Stored data and chunks", - ); + tracing::debug!(target: LOG_TARGET, ?candidate_hash, "Stored data and chunks",); Ok(()) } @@ -1255,7 +1204,8 @@ fn prune_all(db: &Arc, config: &Config, clock: &dyn Clock) -> Re let (range_start, range_end) = pruning_range(now); let mut tx = DBTransaction::new(); - let iter = db.iter_with_prefix(config.col_meta, &range_start[..]) + let iter = db + .iter_with_prefix(config.col_meta, &range_start[..]) .take_while(|(k, _)| &k[..] < &range_end[..]); for (k, _v) in iter { @@ -1334,7 +1284,9 @@ impl Metrics { } /// Provide a timer for `process_block_finalized` which observes on drop. - fn time_process_block_finalized(&self) -> Option { + fn time_process_block_finalized( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.process_block_finalized.start_timer()) } @@ -1375,66 +1327,52 @@ impl metrics::Metrics for Metrics { registry, )?, pruning: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_av_store_pruning", - "Time spent within `av_store::prune_all`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_av_store_pruning", + "Time spent within `av_store::prune_all`", + ))?, registry, )?, process_block_finalized: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_av_store_process_block_finalized", - "Time spent within `av_store::process_block_finalized`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_av_store_process_block_finalized", + "Time spent within `av_store::process_block_finalized`", + ))?, registry, )?, block_activated: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_av_store_block_activated", - "Time spent within `av_store::process_block_activated`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_av_store_block_activated", + "Time spent within `av_store::process_block_activated`", + ))?, registry, )?, process_message: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_av_store_process_message", - "Time spent within `av_store::process_message`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_av_store_process_message", + "Time spent within `av_store::process_message`", + ))?, registry, )?, store_available_data: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_av_store_store_available_data", - "Time spent within `av_store::store_available_data`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_av_store_store_available_data", + "Time spent within `av_store::store_available_data`", + ))?, registry, )?, store_chunk: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_av_store_store_chunk", - "Time spent within `av_store::store_chunk`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_av_store_store_chunk", + "Time spent within `av_store::store_chunk`", + ))?, registry, )?, get_chunk: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_av_store_get_chunk", - "Time spent fetching requested chunks.`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_av_store_get_chunk", + "Time spent fetching requested chunks.`", + ))?, registry, )?, }; diff --git a/polkadot/node/core/av-store/src/tests.rs b/polkadot/node/core/av-store/src/tests.rs index c453b4135d1..54a4d0cb6d8 100644 --- a/polkadot/node/core/av-store/src/tests.rs +++ b/polkadot/node/core/av-store/src/tests.rs @@ -17,27 +17,23 @@ use super::*; use assert_matches::assert_matches; -use futures::{ - future, - channel::oneshot, - executor, - Future, -}; +use futures::{channel::oneshot, executor, future, Future}; -use polkadot_primitives::v1::{ - CandidateDescriptor, CandidateReceipt, HeadData, - PersistedValidationData, Id as ParaId, CandidateHash, Header, ValidatorId, - CoreIndex, GroupIndex, -}; +use parking_lot::Mutex; use polkadot_node_primitives::{AvailableData, BlockData, PoV}; +use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_node_subsystem_util::TimeoutExt; +use polkadot_primitives::v1::{ + CandidateDescriptor, CandidateHash, CandidateReceipt, CoreIndex, GroupIndex, HeadData, Header, + Id as ParaId, PersistedValidationData, ValidatorId, +}; use polkadot_subsystem::{ - ActiveLeavesUpdate, errors::RuntimeApiError, jaeger, ActivatedLeaf, - LeafStatus, messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, + errors::RuntimeApiError, + jaeger, + messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, }; -use polkadot_node_subsystem_test_helpers as test_helpers; use sp_keyring::Sr25519Keyring; -use parking_lot::Mutex; mod columns { pub const DATA: u32 = 0; @@ -45,10 +41,7 @@ mod columns { pub const NUM_COLUMNS: u32 = 2; } -const TEST_CONFIG: Config = Config { - col_data: columns::DATA, - col_meta: columns::META, -}; +const TEST_CONFIG: Config = Config { col_data: columns::DATA, col_meta: columns::META }; type VirtualOverseer = test_helpers::TestSubsystemContextHandle; @@ -95,7 +88,6 @@ impl Clock for TestClock { } } - #[derive(Clone)] struct TestState { persisted_validation_data: PersistedValidationData, @@ -126,34 +118,21 @@ impl Default for TestState { pruning_interval: Duration::from_millis(250), }; - let clock = TestClock { - inner: Arc::new(Mutex::new(Duration::from_secs(0))), - }; + let clock = TestClock { inner: Arc::new(Mutex::new(Duration::from_secs(0))) }; - Self { - persisted_validation_data, - pruning_config, - clock, - } + Self { persisted_validation_data, pruning_config, clock } } } - -fn test_harness>( +fn test_harness>( state: TestState, store: Arc, test: impl FnOnce(VirtualOverseer) -> T, ) { let _ = env_logger::builder() .is_test(true) - .filter( - Some("polkadot_node_core_av_store"), - log::LevelFilter::Trace, - ) - .filter( - Some(LOG_TARGET), - log::LevelFilter::Trace, - ) + .filter(Some("polkadot_node_core_av_store"), log::LevelFilter::Trace) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) .try_init(); let pool = sp_core::testing::TaskExecutor::new(); @@ -174,21 +153,18 @@ fn test_harness>( futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer_signal( - &mut overseer, - OverseerSignal::Conclude, - ).await; - }, subsystem)); + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )); } const TIMEOUT: Duration = Duration::from_millis(100); -async fn overseer_send( - overseer: &mut VirtualOverseer, - msg: AvailabilityStoreMessage, -) { +async fn overseer_send(overseer: &mut VirtualOverseer, msg: AvailabilityStoreMessage) { tracing::trace!(meg = ?msg, "sending message"); overseer .send(FromOverseer::Communication { msg }) @@ -197,9 +173,7 @@ async fn overseer_send( .expect(&format!("{:?} is more than enough for sending messages.", TIMEOUT)); } -async fn overseer_recv( - overseer: &mut VirtualOverseer, -) -> AllMessages { +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { let msg = overseer_recv_with_timeout(overseer, TIMEOUT) .await .expect(&format!("{:?} is more than enough to receive messages", TIMEOUT)); @@ -214,16 +188,10 @@ async fn overseer_recv_with_timeout( timeout: Duration, ) -> Option { tracing::trace!("waiting for message..."); - overseer - .recv() - .timeout(timeout) - .await + overseer.recv().timeout(timeout).await } -async fn overseer_signal( - overseer: &mut VirtualOverseer, - signal: OverseerSignal, -) { +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { overseer .send(FromOverseer::Signal(signal)) .timeout(TIMEOUT) @@ -261,7 +229,8 @@ fn runtime_api_error_does_not_stop_the_subsystem() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let header = Header { parent_hash: Hash::zero(), @@ -298,11 +267,7 @@ fn runtime_api_error_does_not_stop_the_subsystem() { let (tx, rx) = oneshot::channel(); let candidate_hash = CandidateHash(Hash::repeat_byte(33)); let validator_index = ValidatorIndex(5); - let query_chunk = AvailabilityStoreMessage::QueryChunk( - candidate_hash, - validator_index, - tx, - ); + let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx); overseer_send(&mut virtual_overseer, query_chunk.into()).await; @@ -328,30 +293,28 @@ fn store_chunk_works() { // Ensure an entry already exists. In reality this would come from watching // chain events. with_tx(&store, |tx| { - super::write_meta(tx, &TEST_CONFIG, &candidate_hash, &CandidateMeta { - data_available: false, - chunks_stored: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], - state: State::Unavailable(BETimestamp(0)), - }); + super::write_meta( + tx, + &TEST_CONFIG, + &candidate_hash, + &CandidateMeta { + data_available: false, + chunks_stored: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators], + state: State::Unavailable(BETimestamp(0)), + }, + ); }); let (tx, rx) = oneshot::channel(); - let chunk_msg = AvailabilityStoreMessage::StoreChunk { - candidate_hash, - chunk: chunk.clone(), - tx, - }; + let chunk_msg = + AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk: chunk.clone(), tx }; overseer_send(&mut virtual_overseer, chunk_msg.into()).await; assert_eq!(rx.await.unwrap(), Ok(())); let (tx, rx) = oneshot::channel(); - let query_chunk = AvailabilityStoreMessage::QueryChunk( - candidate_hash, - validator_index, - tx, - ); + let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx); overseer_send(&mut virtual_overseer, query_chunk.into()).await; @@ -360,7 +323,6 @@ fn store_chunk_works() { }); } - #[test] fn store_chunk_does_nothing_if_no_entry_already() { let store = Arc::new(kvdb_memorydb::create(columns::NUM_COLUMNS)); @@ -376,21 +338,14 @@ fn store_chunk_does_nothing_if_no_entry_already() { let (tx, rx) = oneshot::channel(); - let chunk_msg = AvailabilityStoreMessage::StoreChunk { - candidate_hash, - chunk: chunk.clone(), - tx, - }; + let chunk_msg = + AvailabilityStoreMessage::StoreChunk { candidate_hash, chunk: chunk.clone(), tx }; overseer_send(&mut virtual_overseer, chunk_msg.into()).await; assert_eq!(rx.await.unwrap(), Err(())); let (tx, rx) = oneshot::channel(); - let query_chunk = AvailabilityStoreMessage::QueryChunk( - candidate_hash, - validator_index, - tx, - ); + let query_chunk = AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx); overseer_send(&mut virtual_overseer, query_chunk.into()).await; @@ -410,23 +365,25 @@ fn query_chunk_checks_meta() { // Ensure an entry already exists. In reality this would come from watching // chain events. with_tx(&store, |tx| { - super::write_meta(tx, &TEST_CONFIG, &candidate_hash, &CandidateMeta { - data_available: false, - chunks_stored: { - let mut v = bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators]; - v.set(validator_index.0 as usize, true); - v + super::write_meta( + tx, + &TEST_CONFIG, + &candidate_hash, + &CandidateMeta { + data_available: false, + chunks_stored: { + let mut v = bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators]; + v.set(validator_index.0 as usize, true); + v + }, + state: State::Unavailable(BETimestamp(0)), }, - state: State::Unavailable(BETimestamp(0)), - }); + ); }); let (tx, rx) = oneshot::channel(); - let query_chunk = AvailabilityStoreMessage::QueryChunkAvailability( - candidate_hash, - validator_index, - tx, - ); + let query_chunk = + AvailabilityStoreMessage::QueryChunkAvailability(candidate_hash, validator_index, tx); overseer_send(&mut virtual_overseer, query_chunk.into()).await; assert!(rx.await.unwrap()); @@ -453,16 +410,13 @@ fn store_block_works() { let validator_index = ValidatorIndex(5); let n_validators = 10; - let pov = PoV { - block_data: BlockData(vec![4, 5, 6]), - }; + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; let available_data = AvailableData { pov: Arc::new(pov), validation_data: test_state.persisted_validation_data.clone(), }; - let (tx, rx) = oneshot::channel(); let block_msg = AvailabilityStoreMessage::StoreAvailableData( candidate_hash, @@ -472,24 +426,23 @@ fn store_block_works() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg: block_msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg: block_msg }).await; assert_eq!(rx.await.unwrap(), Ok(())); let pov = query_available_data(&mut virtual_overseer, candidate_hash).await.unwrap(); assert_eq!(pov, available_data); - let chunk = query_chunk(&mut virtual_overseer, candidate_hash, validator_index).await.unwrap(); + let chunk = query_chunk(&mut virtual_overseer, candidate_hash, validator_index) + .await + .unwrap(); let chunks = erasure::obtain_chunks_v1(10, &available_data).unwrap(); let mut branches = erasure::branches(chunks.as_ref()); let branch = branches.nth(5).unwrap(); - let expected_chunk = ErasureChunk { - chunk: branch.1.to_vec(), - index: ValidatorIndex(5), - proof: branch.0, - }; + let expected_chunk = + ErasureChunk { chunk: branch.1.to_vec(), index: ValidatorIndex(5), proof: branch.0 }; assert_eq!(chunk, expected_chunk); virtual_overseer @@ -505,16 +458,15 @@ fn store_pov_and_query_chunk_works() { let candidate_hash = CandidateHash(Hash::repeat_byte(1)); let n_validators = 10; - let pov = PoV { - block_data: BlockData(vec![4, 5, 6]), - }; + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; let available_data = AvailableData { pov: Arc::new(pov), validation_data: test_state.persisted_validation_data.clone(), }; - let chunks_expected = erasure::obtain_chunks_v1(n_validators as _, &available_data).unwrap(); + let chunks_expected = + erasure::obtain_chunks_v1(n_validators as _, &available_data).unwrap(); let (tx, rx) = oneshot::channel(); let block_msg = AvailabilityStoreMessage::StoreAvailableData( @@ -525,12 +477,14 @@ fn store_pov_and_query_chunk_works() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg: block_msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg: block_msg }).await; assert_eq!(rx.await.unwrap(), Ok(())); for i in 0..n_validators { - let chunk = query_chunk(&mut virtual_overseer, candidate_hash, ValidatorIndex(i as _)).await.unwrap(); + let chunk = query_chunk(&mut virtual_overseer, candidate_hash, ValidatorIndex(i as _)) + .await + .unwrap(); assert_eq!(chunk.chunk, chunks_expected[i as usize]); } @@ -553,9 +507,7 @@ fn query_all_chunks_works() { let n_validators = 10; - let pov = PoV { - block_data: BlockData(vec![4, 5, 6]), - }; + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; let available_data = AvailableData { pov: Arc::new(pov), @@ -578,11 +530,16 @@ fn query_all_chunks_works() { { with_tx(&store, |tx| { - super::write_meta(tx, &TEST_CONFIG, &candidate_hash_2, &CandidateMeta { - data_available: false, - chunks_stored: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators as _], - state: State::Unavailable(BETimestamp(0)), - }); + super::write_meta( + tx, + &TEST_CONFIG, + &candidate_hash_2, + &CandidateMeta { + data_available: false, + chunks_stored: bitvec::bitvec![BitOrderLsb0, u8; 0; n_validators as _], + state: State::Unavailable(BETimestamp(0)), + }, + ); }); let chunk = ErasureChunk { @@ -598,7 +555,9 @@ fn query_all_chunks_works() { tx, }; - virtual_overseer.send(FromOverseer::Communication { msg: store_chunk_msg }).await; + virtual_overseer + .send(FromOverseer::Communication { msg: store_chunk_msg }) + .await; assert_eq!(rx.await.unwrap(), Ok(())); } @@ -638,9 +597,7 @@ fn stored_but_not_included_data_is_pruned() { let candidate_hash = CandidateHash(Hash::repeat_byte(1)); let n_validators = 10; - let pov = PoV { - block_data: BlockData(vec![4, 5, 6]), - }; + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; let available_data = AvailableData { pov: Arc::new(pov), @@ -656,7 +613,7 @@ fn stored_but_not_included_data_is_pruned() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg: block_msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg: block_msg }).await; rx.await.unwrap().unwrap(); @@ -684,16 +641,11 @@ fn stored_data_kept_until_finalized() { test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { let n_validators = 10; - let pov = PoV { - block_data: BlockData(vec![4, 5, 6]), - }; + let pov = PoV { block_data: BlockData(vec![4, 5, 6]) }; let pov_hash = pov.hash(); - let candidate = TestCandidateBuilder { - pov_hash, - ..Default::default() - }.build(); + let candidate = TestCandidateBuilder { pov_hash, ..Default::default() }.build(); let candidate_hash = candidate.hash(); @@ -714,7 +666,7 @@ fn stored_data_kept_until_finalized() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg: block_msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg: block_msg }).await; rx.await.unwrap().unwrap(); @@ -730,7 +682,8 @@ fn stored_data_kept_until_finalized() { block_number, vec![candidate_included(candidate)], (0..n_validators).map(|_| Sr25519Keyring::Alice.public().into()).collect(), - ).await; + ) + .await; // Wait until unavailable data would definitely be pruned. test_state.clock.inc(test_state.pruning_config.keep_unavailable_for * 10); @@ -742,14 +695,13 @@ fn stored_data_kept_until_finalized() { available_data, ); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, true).await - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, true).await); overseer_signal( &mut virtual_overseer, - OverseerSignal::BlockFinalized(new_leaf, block_number) - ).await; + OverseerSignal::BlockFinalized(new_leaf, block_number), + ) + .await; // Wait until unavailable data would definitely be pruned. test_state.clock.inc(test_state.pruning_config.keep_finalized_for / 2); @@ -761,22 +713,16 @@ fn stored_data_kept_until_finalized() { available_data, ); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, true).await - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, true).await); // Wait until it definitely should be gone. test_state.clock.inc(test_state.pruning_config.keep_finalized_for); test_state.wait_for_pruning().await; // At this point data should be gone from the store. - assert!( - query_available_data(&mut virtual_overseer, candidate_hash).await.is_none(), - ); + assert!(query_available_data(&mut virtual_overseer, candidate_hash).await.is_none(),); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, false).await - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_hash, n_validators, false).await); virtual_overseer }); } @@ -787,10 +733,8 @@ fn we_dont_miss_anything_if_import_notifications_are_missed() { let test_state = TestState::default(); test_harness(test_state.clone(), store.clone(), |mut virtual_overseer| async move { - overseer_signal( - &mut virtual_overseer, - OverseerSignal::BlockFinalized(Hash::zero(), 1) - ).await; + overseer_signal(&mut virtual_overseer, OverseerSignal::BlockFinalized(Hash::zero(), 1)) + .await; let header = Header { parent_hash: Hash::repeat_byte(3), @@ -809,7 +753,8 @@ fn we_dont_miss_anything_if_import_notifications_are_missed() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -915,33 +860,26 @@ fn forkfullness_works() { let n_validators = 10; let block_number_1 = 5; let block_number_2 = 5; - let validators: Vec<_> = (0..n_validators).map(|_| Sr25519Keyring::Alice.public().into()).collect(); + let validators: Vec<_> = + (0..n_validators).map(|_| Sr25519Keyring::Alice.public().into()).collect(); let parent_1 = Hash::repeat_byte(3); let parent_2 = Hash::repeat_byte(4); - let pov_1 = PoV { - block_data: BlockData(vec![1, 2, 3]), - }; + let pov_1 = PoV { block_data: BlockData(vec![1, 2, 3]) }; let pov_1_hash = pov_1.hash(); - let pov_2 = PoV { - block_data: BlockData(vec![4, 5, 6]), - }; + let pov_2 = PoV { block_data: BlockData(vec![4, 5, 6]) }; let pov_2_hash = pov_2.hash(); - let candidate_1 = TestCandidateBuilder { - pov_hash: pov_1_hash, - ..Default::default() - }.build(); + let candidate_1 = + TestCandidateBuilder { pov_hash: pov_1_hash, ..Default::default() }.build(); let candidate_1_hash = candidate_1.hash(); - let candidate_2 = TestCandidateBuilder { - pov_hash: pov_2_hash, - ..Default::default() - }.build(); + let candidate_2 = + TestCandidateBuilder { pov_hash: pov_2_hash, ..Default::default() }.build(); let candidate_2_hash = candidate_2.hash(); @@ -964,7 +902,7 @@ fn forkfullness_works() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg }).await; rx.await.unwrap().unwrap(); @@ -977,7 +915,7 @@ fn forkfullness_works() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg }).await; rx.await.unwrap().unwrap(); @@ -997,7 +935,8 @@ fn forkfullness_works() { block_number_1, vec![candidate_included(candidate_1)], validators.clone(), - ).await; + ) + .await; let _new_leaf_2 = import_leaf( &mut virtual_overseer, @@ -1005,12 +944,14 @@ fn forkfullness_works() { block_number_2, vec![candidate_included(candidate_2)], validators.clone(), - ).await; + ) + .await; overseer_signal( &mut virtual_overseer, - OverseerSignal::BlockFinalized(new_leaf_1, block_number_1) - ).await; + OverseerSignal::BlockFinalized(new_leaf_1, block_number_1), + ) + .await; // Data of both candidates should be still present in the DB. assert_eq!( @@ -1023,13 +964,9 @@ fn forkfullness_works() { available_data_2, ); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, true).await, - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, true).await,); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, true).await, - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, true).await,); // Candidate 2 should now be considered unavailable and will be pruned. test_state.clock.inc(test_state.pruning_config.keep_unavailable_for); @@ -1040,38 +977,24 @@ fn forkfullness_works() { available_data_1, ); - assert!( - query_available_data(&mut virtual_overseer, candidate_2_hash).await.is_none(), - ); + assert!(query_available_data(&mut virtual_overseer, candidate_2_hash).await.is_none(),); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, true).await, - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, true).await,); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, false).await, - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, false).await,); // Wait for longer than finalized blocks should be kept for test_state.clock.inc(test_state.pruning_config.keep_finalized_for); test_state.wait_for_pruning().await; // Everything should be pruned now. - assert!( - query_available_data(&mut virtual_overseer, candidate_1_hash).await.is_none(), - ); + assert!(query_available_data(&mut virtual_overseer, candidate_1_hash).await.is_none(),); - assert!( - query_available_data(&mut virtual_overseer, candidate_2_hash).await.is_none(), - ); + assert!(query_available_data(&mut virtual_overseer, candidate_2_hash).await.is_none(),); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, false).await, - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_1_hash, n_validators, false).await,); - assert!( - has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, false).await, - ); + assert!(has_all_chunks(&mut virtual_overseer, candidate_2_hash, n_validators, false).await,); virtual_overseer }); } @@ -1083,7 +1006,7 @@ async fn query_available_data( let (tx, rx) = oneshot::channel(); let query = AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx); - virtual_overseer.send(FromOverseer::Communication{ msg: query }).await; + virtual_overseer.send(FromOverseer::Communication { msg: query }).await; rx.await.unwrap() } @@ -1096,7 +1019,7 @@ async fn query_chunk( let (tx, rx) = oneshot::channel(); let query = AvailabilityStoreMessage::QueryChunk(candidate_hash, index, tx); - virtual_overseer.send(FromOverseer::Communication{ msg: query }).await; + virtual_overseer.send(FromOverseer::Communication { msg: query }).await; rx.await.unwrap() } @@ -1108,7 +1031,9 @@ async fn has_all_chunks( expect_present: bool, ) -> bool { for i in 0..n_validators { - if query_chunk(virtual_overseer, candidate_hash, ValidatorIndex(i)).await.is_some() != expect_present { + if query_chunk(virtual_overseer, candidate_hash, ValidatorIndex(i)).await.is_some() != + expect_present + { return false } } @@ -1139,7 +1064,8 @@ async fn import_leaf( status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; assert_matches!( overseer_recv(virtual_overseer).await, @@ -1163,7 +1089,6 @@ async fn import_leaf( } ); - assert_matches!( overseer_recv(virtual_overseer).await, AllMessages::RuntimeApi(RuntimeApiMessage::Request( diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs index 9ce95459a83..a01fe77b2bf 100644 --- a/polkadot/node/core/backing/src/lib.rs +++ b/polkadot/node/core/backing/src/lib.rs @@ -18,55 +18,50 @@ #![deny(unused_crate_dependencies)] -use std::collections::{HashMap, HashSet}; -use std::pin::Pin; -use std::sync::Arc; +use std::{ + collections::{HashMap, HashSet}, + pin::Pin, + sync::Arc, +}; use bitvec::vec::BitVec; -use futures::{channel::{mpsc, oneshot}, Future, FutureExt, SinkExt, StreamExt}; +use futures::{ + channel::{mpsc, oneshot}, + Future, FutureExt, SinkExt, StreamExt, +}; -use sp_keystore::SyncCryptoStorePtr; +use polkadot_node_primitives::{ + AvailableData, PoV, SignedDisputeStatement, SignedFullStatement, Statement, ValidationResult, +}; +use polkadot_node_subsystem_util::{ + self as util, + metrics::{self, prometheus}, + request_from_runtime, request_session_index_for_child, request_validator_groups, + request_validators, FromJobCommand, JobSender, Validator, +}; use polkadot_primitives::v1::{ - BackedCandidate, CandidateCommitments, CandidateDescriptor, CandidateHash, - CandidateReceipt, CollatorId, CommittedCandidateReceipt, CoreIndex, CoreState, Hash, Id as ParaId, + BackedCandidate, CandidateCommitments, CandidateDescriptor, CandidateHash, CandidateReceipt, + CollatorId, CommittedCandidateReceipt, CoreIndex, CoreState, Hash, Id as ParaId, SessionIndex, SigningContext, ValidatorId, ValidatorIndex, ValidatorSignature, ValidityAttestation, - SessionIndex, -}; -use polkadot_node_primitives::{ - Statement, SignedFullStatement, ValidationResult, PoV, AvailableData, SignedDisputeStatement, }; use polkadot_subsystem::{ - PerLeafSpan, Stage, SubsystemSender, jaeger, - overseer, messages::{ AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage, CandidateBackingMessage, CandidateValidationMessage, CollatorProtocolMessage, - ProvisionableData, ProvisionerMessage, RuntimeApiRequest, - StatementDistributionMessage, ValidationFailed, DisputeCoordinatorMessage, - ImportStatementsResult, - } -}; -use polkadot_node_subsystem_util::{ - self as util, - request_session_index_for_child, - request_validator_groups, - request_validators, - request_from_runtime, - Validator, - FromJobCommand, - JobSender, - metrics::{self, prometheus}, + DisputeCoordinatorMessage, ImportStatementsResult, ProvisionableData, ProvisionerMessage, + RuntimeApiRequest, StatementDistributionMessage, ValidationFailed, + }, + overseer, PerLeafSpan, Stage, SubsystemSender, }; +use sp_keystore::SyncCryptoStorePtr; use statement_table::{ generic::AttestedCandidate as TableAttestedCandidate, - Context as TableContextTrait, - Table, v1::{ - SignedStatement as TableSignedStatement, - Statement as TableStatement, + SignedStatement as TableSignedStatement, Statement as TableStatement, Summary as TableSummary, }, + Context as TableContextTrait, Table, }; use thiserror::Error; @@ -127,12 +122,9 @@ impl std::fmt::Debug for ValidatedCandidateCommand { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let candidate_hash = self.candidate_hash(); match *self { - ValidatedCandidateCommand::Second(_) => - write!(f, "Second({})", candidate_hash), - ValidatedCandidateCommand::Attest(_) => - write!(f, "Attest({})", candidate_hash), - ValidatedCandidateCommand::AttestNoPoV(_) => - write!(f, "Attest({})", candidate_hash), + ValidatedCandidateCommand::Second(_) => write!(f, "Second({})", candidate_hash), + ValidatedCandidateCommand::Attest(_) => write!(f, "Attest({})", candidate_hash), + ValidatedCandidateCommand::AttestNoPoV(_) => write!(f, "Attest({})", candidate_hash), } } } @@ -224,7 +216,9 @@ impl TableContextTrait for TableContext { } fn is_member_of(&self, authority: &ValidatorIndex, group: &ParaId) -> bool { - self.groups.get(group).map_or(false, |g| g.iter().position(|a| a == authority).is_some()) + self.groups + .get(group) + .map_or(false, |g| g.iter().position(|a| a == authority).is_some()) } fn requisite_votes(&self, group: &ParaId) -> usize { @@ -260,10 +254,8 @@ fn table_attested_to_backed( ) -> Option { let TableAttestedCandidate { candidate, validity_votes, group_id: para_id } = attested; - let (ids, validity_votes): (Vec<_>, Vec) = validity_votes - .into_iter() - .map(|(id, vote)| (id, vote.into())) - .unzip(); + let (ids, validity_votes): (Vec<_>, Vec) = + validity_votes.into_iter().map(|(id, vote)| (id, vote.into())).unzip(); let group = table_context.groups.get(¶_id)?; @@ -285,14 +277,15 @@ fn table_attested_to_backed( "Logic error: Validity vote from table does not correspond to group", ); - return None; + return None } } vote_positions.sort_by_key(|(_orig, pos_in_group)| *pos_in_group); Some(BackedCandidate { candidate, - validity_votes: vote_positions.into_iter() + validity_votes: vote_positions + .into_iter() .map(|(pos_in_votes, _pos_in_group)| validity_votes[pos_in_votes].clone()) .collect(), validator_indices, @@ -307,13 +300,15 @@ async fn store_available_data( available_data: AvailableData, ) -> Result<(), Error> { let (tx, rx) = oneshot::channel(); - sender.send_message(AvailabilityStoreMessage::StoreAvailableData( - candidate_hash, - id, - n_validators, - available_data, - tx, - )).await; + sender + .send_message(AvailabilityStoreMessage::StoreAvailableData( + candidate_hash, + id, + n_validators, + available_data, + tx, + )) + .await; let _ = rx.await.map_err(Error::StoreAvailableData)?; @@ -334,33 +329,23 @@ async fn make_pov_available( expected_erasure_root: Hash, span: Option<&jaeger::Span>, ) -> Result, Error> { - let available_data = AvailableData { - pov, - validation_data, - }; + let available_data = AvailableData { pov, validation_data }; { - let _span = span.as_ref().map(|s| { - s.child("erasure-coding").with_candidate(candidate_hash) - }); + let _span = span.as_ref().map(|s| s.child("erasure-coding").with_candidate(candidate_hash)); - let chunks = erasure_coding::obtain_chunks_v1( - n_validators, - &available_data, - )?; + let chunks = erasure_coding::obtain_chunks_v1(n_validators, &available_data)?; let branches = erasure_coding::branches(chunks.as_ref()); let erasure_root = branches.root(); if erasure_root != expected_erasure_root { - return Ok(Err(InvalidErasureRoot)); + return Ok(Err(InvalidErasureRoot)) } } { - let _span = span.as_ref().map(|s| - s.child("store-data").with_candidate(candidate_hash) - ); + let _span = span.as_ref().map(|s| s.child("store-data").with_candidate(candidate_hash)); store_available_data( sender, @@ -368,7 +353,8 @@ async fn make_pov_available( n_validators as u32, candidate_hash, available_data, - ).await?; + ) + .await?; } Ok(Ok(())) @@ -381,15 +367,16 @@ async fn request_pov( candidate_hash: CandidateHash, pov_hash: Hash, ) -> Result, Error> { - let (tx, rx) = oneshot::channel(); - sender.send_message(AvailabilityDistributionMessage::FetchPoV { - relay_parent, - from_validator, - candidate_hash, - pov_hash, - tx, - }).await; + sender + .send_message(AvailabilityDistributionMessage::FetchPoV { + relay_parent, + from_validator, + candidate_hash, + pov_hash, + tx, + }) + .await; let pov = rx.await.map_err(|_| Error::FetchPoV)?; Ok(Arc::new(pov)) @@ -402,13 +389,9 @@ async fn request_candidate_validation( ) -> Result { let (tx, rx) = oneshot::channel(); - sender.send_message( - CandidateValidationMessage::ValidateFromChainState( - candidate, - pov, - tx, - ) - ).await; + sender + .send_message(CandidateValidationMessage::ValidateFromChainState(candidate, pov, tx)) + .await; match rx.await { Ok(Ok(validation_result)) => Ok(validation_result), @@ -417,7 +400,8 @@ async fn request_candidate_validation( } } -type BackgroundValidationResult = Result<(CandidateReceipt, CandidateCommitments, Arc), CandidateReceipt>; +type BackgroundValidationResult = + Result<(CandidateReceipt, CandidateCommitments, Arc), CandidateReceipt>; struct BackgroundValidationParams, F> { sender: JobSender, @@ -435,7 +419,7 @@ async fn validate_and_make_available( params: BackgroundValidationParams< impl SubsystemSender, impl Fn(BackgroundValidationResult) -> ValidatedCandidateCommand + Sync, - > + >, ) -> Result<(), Error> { let BackgroundValidationParams { mut sender, @@ -451,27 +435,22 @@ async fn validate_and_make_available( let pov = match pov { PoVData::Ready(pov) => pov, - PoVData::FetchFromValidator { - from_validator, - candidate_hash, - pov_hash, - } => { + PoVData::FetchFromValidator { from_validator, candidate_hash, pov_hash } => { let _span = span.as_ref().map(|s| s.child("request-pov")); - match request_pov( - &mut sender, - relay_parent, - from_validator, - candidate_hash, - pov_hash, - ).await { + match request_pov(&mut sender, relay_parent, from_validator, candidate_hash, pov_hash) + .await + { Err(Error::FetchPoV) => { - tx_command.send(ValidatedCandidateCommand::AttestNoPoV(candidate.hash())).await.map_err(Error::Mpsc)?; + tx_command + .send(ValidatedCandidateCommand::AttestNoPoV(candidate.hash())) + .await + .map_err(Error::Mpsc)?; return Ok(()) - } + }, Err(err) => return Err(err), Ok(pov) => pov, } - } + }, }; let v = { @@ -512,7 +491,8 @@ async fn validate_and_make_available( validation_data, candidate.descriptor.erasure_root, span.as_ref(), - ).await?; + ) + .await?; match erasure_valid { Ok(()) => Ok((candidate, commitments, pov.clone())), @@ -527,7 +507,7 @@ async fn validate_and_make_available( }, } } - } + }, ValidationResult::Invalid(reason) => { tracing::debug!( target: LOG_TARGET, @@ -536,7 +516,7 @@ async fn validate_and_make_available( "Validation yielded an invalid candidate", ); Err(candidate) - } + }, }; tx_command.send(make_command(res)).await.map_err(Into::into) @@ -591,7 +571,9 @@ impl CandidateBackingJob { match res { Ok((candidate, commitments, _)) => { // sanity check. - if self.seconded.is_none() && !self.issued_statements.contains(&candidate_hash) { + if self.seconded.is_none() && + !self.issued_statements.contains(&candidate_hash) + { self.seconded = Some(candidate_hash); self.issued_statements.insert(candidate_hash); self.metrics.on_candidate_seconded(); @@ -600,24 +582,26 @@ impl CandidateBackingJob { descriptor: candidate.descriptor.clone(), commitments, }); - if let Some(stmt) = self.sign_import_and_distribute_statement( - sender, - statement, - root_span, - ).await? { - sender.send_message( - CollatorProtocolMessage::Seconded(self.parent, stmt) - ).await; + if let Some(stmt) = self + .sign_import_and_distribute_statement(sender, statement, root_span) + .await? + { + sender + .send_message(CollatorProtocolMessage::Seconded( + self.parent, + stmt, + )) + .await; } } - } + }, Err(candidate) => { - sender.send_message( - CollatorProtocolMessage::Invalid(self.parent, candidate) - ).await; - } + sender + .send_message(CollatorProtocolMessage::Invalid(self.parent, candidate)) + .await; + }, } - } + }, ValidatedCandidateCommand::Attest(res) => { // We are done - avoid new validation spawns: self.fallbacks.remove(&candidate_hash); @@ -625,11 +609,12 @@ impl CandidateBackingJob { if !self.issued_statements.contains(&candidate_hash) { if res.is_ok() { let statement = Statement::Valid(candidate_hash); - self.sign_import_and_distribute_statement(sender, statement, &root_span).await?; + self.sign_import_and_distribute_statement(sender, statement, &root_span) + .await?; } self.issued_statements.insert(candidate_hash); } - } + }, ValidatedCandidateCommand::AttestNoPoV(candidate_hash) => { if let Some((attesting, span)) = self.fallbacks.get_mut(&candidate_hash) { if let Some(index) = attesting.backing.pop() { @@ -639,7 +624,6 @@ impl CandidateBackingJob { let attesting = attesting.clone(); self.kick_off_validation_work(sender, attesting, c_span).await? } - } else { tracing::warn!( target: LOG_TARGET, @@ -647,7 +631,7 @@ impl CandidateBackingJob { ); debug_assert!(false); } - } + }, } Ok(()) @@ -658,7 +642,7 @@ impl CandidateBackingJob { sender: &mut JobSender, params: BackgroundValidationParams< impl SubsystemSender, - impl Fn(BackgroundValidationResult) -> ValidatedCandidateCommand + Send + 'static + Sync + impl Fn(BackgroundValidationResult) -> ValidatedCandidateCommand + Send + 'static + Sync, >, ) -> Result<(), Error> { let candidate_hash = params.candidate.hash(); @@ -666,10 +650,16 @@ impl CandidateBackingJob { // spawn background task. let bg = async move { if let Err(e) = validate_and_make_available(params).await { - tracing::error!(target: LOG_TARGET, "Failed to validate and make available: {:?}", e); + tracing::error!( + target: LOG_TARGET, + "Failed to validate and make available: {:?}", + e + ); } }; - sender.send_command(FromJobCommand::Spawn("Backing Validation", bg.boxed())).await?; + sender + .send_command(FromJobCommand::Spawn("Backing Validation", bg.boxed())) + .await?; } Ok(()) @@ -685,13 +675,15 @@ impl CandidateBackingJob { pov: Arc, ) -> Result<(), Error> { // Check that candidate is collated by the right collator. - if self.required_collator.as_ref() + if self + .required_collator + .as_ref() .map_or(false, |c| c != &candidate.descriptor().collator) { - sender.send_message( - CollatorProtocolMessage::Invalid(self.parent, candidate.clone()) - ).await; - return Ok(()); + sender + .send_message(CollatorProtocolMessage::Invalid(self.parent, candidate.clone())) + .await; + return Ok(()) } let candidate_hash = candidate.hash(); @@ -723,8 +715,9 @@ impl CandidateBackingJob { n_validators: self.table_context.validators.len(), span, make_command: ValidatedCandidateCommand::Second, - } - ).await?; + }, + ) + .await?; Ok(()) } @@ -751,12 +744,12 @@ impl CandidateBackingJob { // collect the misbehaviors to avoid double mutable self borrow issues let misbehaviors: Vec<_> = self.table.drain_misbehaviors().collect(); for (validator_id, report) in misbehaviors { - sender.send_message( - ProvisionerMessage::ProvisionableData( + sender + .send_message(ProvisionerMessage::ProvisionableData( self.parent, - ProvisionableData::MisbehaviorReport(self.parent, validator_id, report) - ) - ).await; + ProvisionableData::MisbehaviorReport(self.parent, validator_id, report), + )) + .await; } } @@ -777,14 +770,17 @@ impl CandidateBackingJob { let candidate_hash = statement.payload().candidate_hash(); let import_statement_span = { // create a span only for candidates we're already aware of. - self.get_unbacked_statement_child(root_span, candidate_hash, statement.validator_index()) + self.get_unbacked_statement_child( + root_span, + candidate_hash, + statement.validator_index(), + ) }; - if let Err(ValidatorIndexOutOfBounds) = self.dispatch_new_statement_to_dispute_coordinator( - sender, - candidate_hash, - &statement, - ).await { + if let Err(ValidatorIndexOutOfBounds) = self + .dispatch_new_statement_to_dispute_coordinator(sender, candidate_hash, &statement) + .await + { tracing::warn!( target: LOG_TARGET, session_index = ?self.session_index, @@ -793,14 +789,15 @@ impl CandidateBackingJob { "Supposedly 'Signed' statement has validator index out of bounds." ); - return Ok(None); + return Ok(None) } let stmt = primitive_statement_to_table(statement); let summary = self.table.import_statement(&self.table_context, stmt); - let unbacked_span = if let Some(attested) = summary.as_ref() + let unbacked_span = if let Some(attested) = summary + .as_ref() .and_then(|s| self.table.attested_candidate(&s.candidate, &self.table_context)) { let candidate_hash = attested.candidate.hash(); @@ -808,9 +805,7 @@ impl CandidateBackingJob { if self.backed.insert(candidate_hash) { let span = self.remove_unbacked_span(&candidate_hash); - if let Some(backed) = - table_attested_to_backed(attested, &self.table_context) - { + if let Some(backed) = table_attested_to_backed(attested, &self.table_context) { tracing::debug!( target: LOG_TARGET, candidate_hash = ?candidate_hash, @@ -866,18 +861,11 @@ impl CandidateBackingJob { ) -> Result<(), ValidatorIndexOutOfBounds> { // Dispatch the statement to the dispute coordinator. let validator_index = statement.validator_index(); - let signing_context = SigningContext { - parent_hash: self.parent, - session_index: self.session_index, - }; + let signing_context = + SigningContext { parent_hash: self.parent, session_index: self.session_index }; - let validator_public = match self.table_context - .validators - .get(validator_index.0 as usize) - { - None => { - return Err(ValidatorIndexOutOfBounds); - } + let validator_public = match self.table_context.validators.get(validator_index.0 as usize) { + None => return Err(ValidatorIndexOutOfBounds), Some(v) => v, }; @@ -887,39 +875,36 @@ impl CandidateBackingJob { // Valid statements are only supposed to be imported // once we've seen at least one `Seconded` statement. self.table.get_candidate(&candidate_hash).map(|c| c.to_plain()) - } + }, }; let maybe_signed_dispute_statement = SignedDisputeStatement::from_backing_statement( statement.as_unchecked(), signing_context, validator_public.clone(), - ).ok(); + ) + .ok(); - if let (Some(candidate_receipt), Some(dispute_statement)) - = (maybe_candidate_receipt, maybe_signed_dispute_statement) + if let (Some(candidate_receipt), Some(dispute_statement)) = + (maybe_candidate_receipt, maybe_signed_dispute_statement) { let (pending_confirmation, confirmation_rx) = oneshot::channel(); - sender.send_message( - DisputeCoordinatorMessage::ImportStatements { + sender + .send_message(DisputeCoordinatorMessage::ImportStatements { candidate_hash, candidate_receipt, session: self.session_index, statements: vec![(dispute_statement, validator_index)], pending_confirmation, - } - ).await; + }) + .await; match confirmation_rx.await { - Err(oneshot::Canceled) => tracing::warn!( - target: LOG_TARGET, - "Dispute coordinator confirmation lost", - ), - Ok(ImportStatementsResult::ValidImport) => {} - Ok(ImportStatementsResult::InvalidImport) => tracing::warn!( - target: LOG_TARGET, - "Failed to import statements of validity", - ), + Err(oneshot::Canceled) => + tracing::warn!(target: LOG_TARGET, "Dispute coordinator confirmation lost",), + Ok(ImportStatementsResult::ValidImport) => {}, + Ok(ImportStatementsResult::InvalidImport) => + tracing::warn!(target: LOG_TARGET, "Failed to import statements of validity",), } } @@ -936,7 +921,8 @@ impl CandidateBackingJob { CandidateBackingMessage::Second(relay_parent, candidate, pov) => { let _timer = self.metrics.time_process_second(); - let span = root_span.child("second") + let span = root_span + .child("second") .with_stage(jaeger::Stage::CandidateBacking) .with_pov(&pov) .with_candidate(candidate.hash()) @@ -944,7 +930,7 @@ impl CandidateBackingJob { // Sanity check that candidate is from our assignment. if Some(candidate.descriptor().para_id) != self.assignment { - return Ok(()); + return Ok(()) } // If the message is a `CandidateBackingMessage::Second`, sign and dispatch a @@ -956,13 +942,15 @@ impl CandidateBackingJob { if !self.issued_statements.contains(&candidate_hash) { let pov = Arc::new(pov); - self.validate_and_second(&span, &root_span, sender, &candidate, pov).await?; + self.validate_and_second(&span, &root_span, sender, &candidate, pov) + .await?; } } - } + }, CandidateBackingMessage::Statement(_relay_parent, statement) => { let _timer = self.metrics.time_process_statement(); - let _span = root_span.child("statement") + let _span = root_span + .child("statement") .with_stage(jaeger::Stage::CandidateBacking) .with_candidate(statement.payload().candidate_hash()) .with_relay_parent(_relay_parent); @@ -972,20 +960,21 @@ impl CandidateBackingJob { Err(e) => return Err(e), Ok(()) => (), } - } + }, CandidateBackingMessage::GetBackedCandidates(_, requested_candidates, tx) => { let _timer = self.metrics.time_get_backed_candidates(); let backed = requested_candidates .into_iter() .filter_map(|hash| { - self.table.attested_candidate(&hash, &self.table_context) - .and_then(|attested| table_attested_to_backed(attested, &self.table_context)) + self.table.attested_candidate(&hash, &self.table_context).and_then( + |attested| table_attested_to_backed(attested, &self.table_context), + ) }) .collect(); tx.send(backed).map_err(|data| Error::Send(data))?; - } + }, } Ok(()) @@ -1013,15 +1002,13 @@ impl CandidateBackingJob { ); // Check that candidate is collated by the right collator. - if self.required_collator.as_ref() - .map_or(false, |c| c != &descriptor.collator) - { + if self.required_collator.as_ref().map_or(false, |c| c != &descriptor.collator) { // If not, we've got the statement in the table but we will // not issue validation work for it. // // Act as though we've issued a statement. self.issued_statements.insert(candidate_hash); - return Ok(()); + return Ok(()) } let bg_sender = sender.clone(); @@ -1043,7 +1030,8 @@ impl CandidateBackingJob { span, make_command: ValidatedCandidateCommand::Attest, }, - ).await + ) + .await } /// Import the statement and kick off validation work if it is a part of our assignment. @@ -1068,7 +1056,11 @@ impl CandidateBackingJob { ); let attesting = AttestingData { - candidate: self.table.get_candidate(&candidate_hash).ok_or(Error::CandidateNotFound)?.to_plain(), + candidate: self + .table + .get_candidate(&candidate_hash) + .ok_or(Error::CandidateNotFound)? + .to_plain(), pov_hash: receipt.descriptor.pov_hash, from_validator: statement.validator_index(), backing: Vec::new(), @@ -1076,10 +1068,9 @@ impl CandidateBackingJob { let child = span.as_ref().map(|s| s.child("try")); self.fallbacks.insert(summary.candidate, (attesting.clone(), span)); (attesting, child) - } + }, Statement::Valid(candidate_hash) => { if let Some((attesting, span)) = self.fallbacks.get_mut(candidate_hash) { - let our_index = self.table_context.validator.as_ref().map(|v| v.index()); if our_index == Some(statement.validator_index()) { return Ok(()) @@ -1097,20 +1088,17 @@ impl CandidateBackingJob { } else { return Ok(()) } - } + }, }; - self.kick_off_validation_work( - sender, - attesting, - span, - ).await?; + self.kick_off_validation_work(sender, attesting, span).await?; } Ok(()) } async fn sign_statement(&self, statement: Statement) -> Option { - let signed = self.table_context + let signed = self + .table_context .validator .as_ref()? .sign(self.keystore.clone(), statement) @@ -1126,7 +1114,7 @@ impl CandidateBackingJob { &mut self, parent_span: &jaeger::Span, hash: CandidateHash, - para_id: Option + para_id: Option, ) -> Option<&jaeger::Span> { if !self.backed.contains(&hash) { // only add if we don't consider this backed. @@ -1150,12 +1138,11 @@ impl CandidateBackingJob { hash: CandidateHash, para_id: ParaId, ) -> Option { - self.insert_or_get_unbacked_span(parent_span, hash, Some(para_id)) - .map(|span| { - span.child("validation") - .with_candidate(hash) - .with_stage(Stage::CandidateBacking) - }) + self.insert_or_get_unbacked_span(parent_span, hash, Some(para_id)).map(|span| { + span.child("validation") + .with_candidate(hash) + .with_stage(Stage::CandidateBacking) + }) } fn get_unbacked_statement_child( @@ -1220,12 +1207,12 @@ impl util::JobTrait for CandidateBackingJob { request_validators(parent, &mut sender).await, request_validator_groups(parent, &mut sender).await, request_session_index_for_child(parent, &mut sender).await, - request_from_runtime( - parent, - &mut sender, - |tx| RuntimeApiRequest::AvailabilityCores(tx), - ).await, - ).map_err(Error::JoinMultiple)?; + request_from_runtime(parent, &mut sender, |tx| { + RuntimeApiRequest::AvailabilityCores(tx) + },) + .await, + ) + .map_err(Error::JoinMultiple)?; let validators = try_runtime_api!(validators); let (validator_groups, group_rotation_info) = try_runtime_api!(groups); @@ -1236,23 +1223,22 @@ impl util::JobTrait for CandidateBackingJob { let _span = span.child("validator-construction"); let signing_context = SigningContext { parent_hash: parent, session_index }; - let validator = match Validator::construct( - &validators, - signing_context.clone(), - keystore.clone(), - ).await { - Ok(v) => Some(v), - Err(util::Error::NotAValidator) => None, - Err(e) => { - tracing::warn!( - target: LOG_TARGET, - err = ?e, - "Cannot participate in candidate backing", - ); + let validator = + match Validator::construct(&validators, signing_context.clone(), keystore.clone()) + .await + { + Ok(v) => Some(v), + Err(util::Error::NotAValidator) => None, + Err(e) => { + tracing::warn!( + target: LOG_TARGET, + err = ?e, + "Cannot participate in candidate backing", + ); - return Ok(()) - } - }; + return Ok(()) + }, + }; drop(_span); let mut assignments_span = span.child("compute-assignments"); @@ -1277,22 +1263,18 @@ impl util::JobTrait for CandidateBackingJob { } } - let table_context = TableContext { - groups, - validators, - validator, - }; + let table_context = TableContext { groups, validators, validator }; let (assignment, required_collator) = match assignment { None => { assignments_span.add_string_tag("assigned", "false"); (None, None) - } + }, Some((assignment, required_collator)) => { assignments_span.add_string_tag("assigned", "true"); assignments_span.add_para_id(assignment); (Some(assignment), required_collator) - } + }, }; drop(assignments_span); @@ -1320,7 +1302,8 @@ impl util::JobTrait for CandidateBackingJob { drop(_span); job.run_loop(sender, rx_to, span).await - }.boxed() + } + .boxed() } } @@ -1361,7 +1344,9 @@ impl Metrics { } /// Provide a timer for handling `CandidateBackingMessage::GetBackedCandidates` which observes on drop. - fn time_get_backed_candidates(&self) -> Option { + fn time_get_backed_candidates( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.get_backed_candidates.start_timer()) } } @@ -1384,30 +1369,24 @@ impl metrics::Metrics for Metrics { registry, )?, process_second: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_candidate_backing_process_second", - "Time spent within `candidate_backing::process_second`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_candidate_backing_process_second", + "Time spent within `candidate_backing::process_second`", + ))?, registry, )?, process_statement: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_candidate_backing_process_statement", - "Time spent within `candidate_backing::process_statement`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_candidate_backing_process_statement", + "Time spent within `candidate_backing::process_statement`", + ))?, registry, )?, get_backed_candidates: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_candidate_backing_get_backed_candidates", - "Time spent within `candidate_backing::get_backed_candidates`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_candidate_backing_get_backed_candidates", + "Time spent within `candidate_backing::get_backed_candidates`", + ))?, registry, )?, }; @@ -1416,5 +1395,5 @@ impl metrics::Metrics for Metrics { } /// The candidate backing subsystem. -pub type CandidateBackingSubsystem - = polkadot_node_subsystem_util::JobSubsystem; +pub type CandidateBackingSubsystem = + polkadot_node_subsystem_util::JobSubsystem; diff --git a/polkadot/node/core/backing/src/tests.rs b/polkadot/node/core/backing/src/tests.rs index fc62873218a..86282c38f91 100644 --- a/polkadot/node/core/backing/src/tests.rs +++ b/polkadot/node/core/backing/src/tests.rs @@ -17,29 +17,30 @@ use super::*; use assert_matches::assert_matches; use futures::{future, Future}; -use polkadot_primitives::v1::{GroupRotationInfo, HeadData, PersistedValidationData, ScheduledCore}; +use polkadot_node_primitives::{BlockData, InvalidCandidate}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_primitives::v1::{ + GroupRotationInfo, HeadData, PersistedValidationData, ScheduledCore, +}; use polkadot_subsystem::{ - messages::{RuntimeApiRequest, RuntimeApiMessage, CollatorProtocolMessage}, - ActiveLeavesUpdate, FromOverseer, OverseerSignal, ActivatedLeaf, LeafStatus, + messages::{CollatorProtocolMessage, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, LeafStatus, OverseerSignal, }; -use polkadot_node_primitives::{InvalidCandidate, BlockData}; -use polkadot_node_subsystem_test_helpers as test_helpers; -use sp_keyring::Sr25519Keyring; use sp_application_crypto::AppKey; +use sp_keyring::Sr25519Keyring; use sp_keystore::{CryptoStore, SyncCryptoStore}; +use sp_tracing as _; use statement_table::v1::Misbehavior; use std::collections::HashMap; -use sp_tracing as _; fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { val_ids.iter().map(|v| v.public().into()).collect() } -fn table_statement_to_primitive( - statement: TableStatement, -) -> Statement { +fn table_statement_to_primitive(statement: TableStatement) -> Statement { match statement { - TableStatement::Seconded(committed_candidate_receipt) => Statement::Seconded(committed_candidate_receipt), + TableStatement::Seconded(committed_candidate_receipt) => + Statement::Seconded(committed_candidate_receipt), TableStatement::Valid(candidate_hash) => Statement::Valid(candidate_hash), } } @@ -82,29 +83,26 @@ impl Default for TestState { let keystore = Arc::new(sc_keystore::LocalKeystore::in_memory()); // Make sure `Alice` key is in the keystore, so this mocked node will be a parachain validator. - SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, Some(&validators[0].to_seed())) - .expect("Insert key into keystore"); + SyncCryptoStore::sr25519_generate_new( + &*keystore, + ValidatorId::ID, + Some(&validators[0].to_seed()), + ) + .expect("Insert key into keystore"); let validator_public = validator_pubkeys(&validators); let validator_groups = vec![vec![2, 0, 3, 5], vec![1], vec![4]] - .into_iter().map(|g| g.into_iter().map(ValidatorIndex).collect()).collect(); - let group_rotation_info = GroupRotationInfo { - session_start_block: 0, - group_rotation_frequency: 100, - now: 1, - }; + .into_iter() + .map(|g| g.into_iter().map(ValidatorIndex).collect()) + .collect(); + let group_rotation_info = + GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 100, now: 1 }; let thread_collator: CollatorId = Sr25519Keyring::Two.public().into(); let availability_cores = vec![ - CoreState::Scheduled(ScheduledCore { - para_id: chain_a, - collator: None, - }), - CoreState::Scheduled(ScheduledCore { - para_id: chain_b, - collator: None, - }), + CoreState::Scheduled(ScheduledCore { para_id: chain_a, collator: None }), + CoreState::Scheduled(ScheduledCore { para_id: chain_b, collator: None }), CoreState::Scheduled(ScheduledCore { para_id: thread_a, collator: Some(thread_collator.clone()), @@ -116,10 +114,7 @@ impl Default for TestState { let relay_parent = Hash::repeat_byte(5); - let signing_context = SigningContext { - session_index: 1, - parent_hash: relay_parent, - }; + let signing_context = SigningContext { session_index: 1, parent_hash: relay_parent }; let validation_data = PersistedValidationData { parent_head: HeadData(vec![7, 8, 9]), @@ -145,38 +140,33 @@ impl Default for TestState { type VirtualOverseer = test_helpers::TestSubsystemContextHandle; -fn test_harness>( +fn test_harness>( keystore: SyncCryptoStorePtr, test: impl FnOnce(VirtualOverseer) -> T, ) { let pool = sp_core::testing::TaskExecutor::new(); - let (context, virtual_overseer) = - test_helpers::make_subsystem_context(pool.clone()); + let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); - let subsystem = CandidateBackingSubsystem::new( - pool.clone(), - keystore, - Metrics(None), - ).run(context); + let subsystem = + CandidateBackingSubsystem::new(pool.clone(), keystore, Metrics(None)).run(context); let test_fut = test(virtual_overseer); futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - futures::executor::block_on(future::join(async move { - let mut virtual_overseer = test_fut.await; - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::Conclude, - )).await; - }, subsystem)); + futures::executor::block_on(future::join( + async move { + let mut virtual_overseer = test_fut.await; + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }, + subsystem, + )); } fn make_erasure_root(test: &TestState, pov: PoV) -> Hash { - let available_data = AvailableData { - validation_data: test.validation_data.clone(), - pov: Arc::new(pov), - }; + let available_data = + AvailableData { validation_data: test.validation_data.clone(), pov: Arc::new(pov) }; let chunks = erasure_coding::obtain_chunks_v1(test.validators.len(), &available_data).unwrap(); erasure_coding::branches(&chunks).root() @@ -201,28 +191,24 @@ impl TestCandidateBuilder { erasure_root: self.erasure_root, ..Default::default() }, - commitments: CandidateCommitments { - head_data: self.head_data, - ..Default::default() - }, + commitments: CandidateCommitments { head_data: self.head_data, ..Default::default() }, } } } // Tests that the subsystem performs actions that are requied on startup. -async fn test_startup( - virtual_overseer: &mut VirtualOverseer, - test_state: &TestState, -) { +async fn test_startup(virtual_overseer: &mut VirtualOverseer, test_state: &TestState) { // Start work on some new parent. - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash: test_state.relay_parent, - number: 1, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - }))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + ActivatedLeaf { + hash: test_state.relay_parent, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }, + )))) + .await; // Check that subsystem job issues a request for a validator set. assert_matches!( @@ -302,9 +288,7 @@ fn backing_second_works() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![42, 43, 44]), - }; + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); @@ -316,7 +300,8 @@ fn backing_second_works() { head_data: expected_head_data.clone(), erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let second = CandidateBackingMessage::Second( test_state.relay_parent, @@ -324,7 +309,7 @@ fn backing_second_works() { pov.clone(), ); - virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; + virtual_overseer.send(FromOverseer::Communication { msg: second }).await; assert_matches!( virtual_overseer.recv().await, @@ -362,7 +347,8 @@ fn backing_second_works() { candidate.hash(), test_state.session(), vec![ValidatorIndex(0)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -382,9 +368,11 @@ fn backing_second_works() { } ); - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; virtual_overseer }); } @@ -396,9 +384,7 @@ fn backing_works() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![1, 2, 3]), - }; + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; let pov_hash = pov.hash(); @@ -411,19 +397,24 @@ fn backing_works() { head_data: expected_head_data.clone(), erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let candidate_a_hash = candidate_a.hash(); let public1 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[5].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let public2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[2].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let signed_a = SignedFullStatement::sign( &test_state.keystore, @@ -431,7 +422,11 @@ fn backing_works() { &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let signed_b = SignedFullStatement::sign( &test_state.keystore, @@ -439,18 +434,24 @@ fn backing_works() { &test_state.signing_context, ValidatorIndex(5), &public1.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); - let statement = CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate_a_hash, test_state.session(), vec![ValidatorIndex(2)], - ).await; + ) + .await; // Sending a `Statement::Seconded` for our assignment will start // validation process. The first thing requested is the PoV. @@ -505,7 +506,8 @@ fn backing_works() { candidate_a_hash, test_state.session(), vec![ValidatorIndex(0)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -516,19 +518,18 @@ fn backing_works() { } ); - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_b.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate_a_hash, test_state.session(), vec![ValidatorIndex(5)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -542,9 +543,11 @@ fn backing_works() { } ); - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; virtual_overseer }); } @@ -555,9 +558,7 @@ fn backing_works_while_validation_ongoing() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![1, 2, 3]), - }; + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; let pov_hash = pov.hash(); @@ -570,24 +571,31 @@ fn backing_works_while_validation_ongoing() { head_data: expected_head_data.clone(), erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let candidate_a_hash = candidate_a.hash(); let public1 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[5].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let public2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[2].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let public3 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[3].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let signed_a = SignedFullStatement::sign( &test_state.keystore, @@ -595,7 +603,11 @@ fn backing_works_while_validation_ongoing() { &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let signed_b = SignedFullStatement::sign( &test_state.keystore, @@ -603,7 +615,11 @@ fn backing_works_while_validation_ongoing() { &test_state.signing_context, ValidatorIndex(5), &public1.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let signed_c = SignedFullStatement::sign( &test_state.keystore, @@ -611,17 +627,23 @@ fn backing_works_while_validation_ongoing() { &test_state.signing_context, ValidatorIndex(3), &public3.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); - let statement = CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate_a.hash(), test_state.session(), vec![ValidatorIndex(2)], - ).await; + ) + .await; // Sending a `Statement::Seconded` for our assignment will start // validation process. The first thing requested is PoV from the @@ -656,26 +678,23 @@ fn backing_works_while_validation_ongoing() { } ); - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_b.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_c.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_c.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate_a.hash(), test_state.session(), vec![ValidatorIndex(5), ValidatorIndex(3)], - ).await; + ) + .await; // Candidate gets backed entirely by other votes. assert_matches!( @@ -698,29 +717,31 @@ fn backing_works_while_validation_ongoing() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg }).await; let candidates = rx.await.unwrap(); assert_eq!(1, candidates.len()); assert_eq!(candidates[0].validity_votes.len(), 3); - assert!(candidates[0].validity_votes.contains( - &ValidityAttestation::Implicit(signed_a.signature().clone()) - )); - assert!(candidates[0].validity_votes.contains( - &ValidityAttestation::Explicit(signed_b.signature().clone()) - )); - assert!(candidates[0].validity_votes.contains( - &ValidityAttestation::Explicit(signed_c.signature().clone()) - )); + assert!(candidates[0] + .validity_votes + .contains(&ValidityAttestation::Implicit(signed_a.signature().clone()))); + assert!(candidates[0] + .validity_votes + .contains(&ValidityAttestation::Explicit(signed_b.signature().clone()))); + assert!(candidates[0] + .validity_votes + .contains(&ValidityAttestation::Explicit(signed_c.signature().clone()))); assert_eq!( candidates[0].validator_indices, bitvec::bitvec![bitvec::order::Lsb0, u8; 1, 0, 1, 1], ); - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; virtual_overseer }); } @@ -733,9 +754,7 @@ fn backing_misbehavior_works() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![1, 2, 3]), - }; + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; let pov_hash = pov.hash(); @@ -748,20 +767,28 @@ fn backing_misbehavior_works() { erasure_root: make_erasure_root(&test_state, pov.clone()), head_data: expected_head_data.clone(), ..Default::default() - }.build(); + } + .build(); let candidate_a_hash = candidate_a.hash(); let public2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, - ValidatorId::ID, Some(&test_state.validators[2].to_seed()) - ).await.expect("Insert key into keystore"); + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .await + .expect("Insert key into keystore"); let seconded_2 = SignedFullStatement::sign( &test_state.keystore, Statement::Seconded(candidate_a.clone()), &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let valid_2 = SignedFullStatement::sign( &test_state.keystore, @@ -769,9 +796,14 @@ fn backing_misbehavior_works() { &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); - let statement = CandidateBackingMessage::Statement(test_state.relay_parent, seconded_2.clone()); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, seconded_2.clone()); virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; @@ -780,7 +812,8 @@ fn backing_misbehavior_works() { candidate_a_hash, test_state.session(), vec![ValidatorIndex(2)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -831,7 +864,8 @@ fn backing_misbehavior_works() { candidate_a_hash, test_state.session(), vec![ValidatorIndex(0)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -846,7 +880,8 @@ fn backing_misbehavior_works() { ); // This `Valid` statement is redundant after the `Seconded` statement already sent. - let statement = CandidateBackingMessage::Statement(test_state.relay_parent, valid_2.clone()); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, valid_2.clone()); virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; @@ -855,7 +890,8 @@ fn backing_misbehavior_works() { candidate_a_hash, test_state.session(), vec![ValidatorIndex(2)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -902,13 +938,9 @@ fn backing_dont_second_invalid() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov_block_a = PoV { - block_data: BlockData(vec![42, 43, 44]), - }; + let pov_block_a = PoV { block_data: BlockData(vec![42, 43, 44]) }; - let pov_block_b = PoV { - block_data: BlockData(vec![45, 46, 47]), - }; + let pov_block_b = PoV { block_data: BlockData(vec![45, 46, 47]) }; let pov_hash_a = pov_block_a.hash(); let pov_hash_b = pov_block_b.hash(); @@ -921,7 +953,8 @@ fn backing_dont_second_invalid() { pov_hash: pov_hash_a, erasure_root: make_erasure_root(&test_state, pov_block_a.clone()), ..Default::default() - }.build(); + } + .build(); let candidate_b = TestCandidateBuilder { para_id: test_state.chain_ids[0], @@ -930,7 +963,8 @@ fn backing_dont_second_invalid() { erasure_root: make_erasure_root(&test_state, pov_block_b.clone()), head_data: expected_head_data.clone(), ..Default::default() - }.build(); + } + .build(); let second = CandidateBackingMessage::Second( test_state.relay_parent, @@ -938,8 +972,7 @@ fn backing_dont_second_invalid() { pov_block_a.clone(), ); - virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; - + virtual_overseer.send(FromOverseer::Communication { msg: second }).await; assert_matches!( virtual_overseer.recv().await, @@ -967,7 +1000,7 @@ fn backing_dont_second_invalid() { pov_block_b.clone(), ); - virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; + virtual_overseer.send(FromOverseer::Communication { msg: second }).await; assert_matches!( virtual_overseer.recv().await, @@ -1005,7 +1038,8 @@ fn backing_dont_second_invalid() { candidate_b.hash(), test_state.session(), vec![ValidatorIndex(0)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -1019,9 +1053,11 @@ fn backing_dont_second_invalid() { } ); - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; virtual_overseer }); } @@ -1034,9 +1070,7 @@ fn backing_second_after_first_fails_works() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![42, 43, 44]), - }; + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; let pov_hash = pov.hash(); @@ -1046,12 +1080,16 @@ fn backing_second_after_first_fails_works() { pov_hash, erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let validator2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, - ValidatorId::ID, Some(&test_state.validators[2].to_seed()) - ).await.expect("Insert key into keystore"); + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .await + .expect("Insert key into keystore"); let signed_a = SignedFullStatement::sign( &test_state.keystore, @@ -1059,22 +1097,25 @@ fn backing_second_after_first_fails_works() { &test_state.signing_context, ValidatorIndex(2), &validator2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); // Send in a `Statement` with a candidate. - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_a.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate.hash(), test_state.session(), vec![ValidatorIndex(2)], - ).await; + ) + .await; // Subsystem requests PoV and requests validation. assert_matches!( @@ -1090,7 +1131,6 @@ fn backing_second_after_first_fails_works() { } ); - // Tell subsystem that this candidate is invalid. assert_matches!( virtual_overseer.recv().await, @@ -1113,11 +1153,9 @@ fn backing_second_after_first_fails_works() { pov.clone(), ); - virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; + virtual_overseer.send(FromOverseer::Communication { msg: second }).await; - let pov_to_second = PoV { - block_data: BlockData(vec![3, 2, 1]), - }; + let pov_to_second = PoV { block_data: BlockData(vec![3, 2, 1]) }; let pov_hash = pov_to_second.hash(); @@ -1127,7 +1165,8 @@ fn backing_second_after_first_fails_works() { pov_hash, erasure_root: make_erasure_root(&test_state, pov_to_second.clone()), ..Default::default() - }.build(); + } + .build(); let second = CandidateBackingMessage::Second( test_state.relay_parent, @@ -1138,7 +1177,7 @@ fn backing_second_after_first_fails_works() { // In order to trigger _some_ actions from subsystem ask it to second another // candidate. The only reason to do so is to make sure that no actions were // triggered on the prev step. - virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; + virtual_overseer.send(FromOverseer::Communication { msg: second }).await; assert_matches!( virtual_overseer.recv().await, @@ -1164,9 +1203,7 @@ fn backing_works_after_failed_validation() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![42, 43, 44]), - }; + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; let pov_hash = pov.hash(); @@ -1176,34 +1213,41 @@ fn backing_works_after_failed_validation() { pov_hash, erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let public2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, - ValidatorId::ID, Some(&test_state.validators[2].to_seed()) - ).await.expect("Insert key into keystore"); + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .await + .expect("Insert key into keystore"); let signed_a = SignedFullStatement::sign( &test_state.keystore, Statement::Seconded(candidate.clone()), &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); // Send in a `Statement` with a candidate. - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_a.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate.hash(), test_state.session(), vec![ValidatorIndex(2)], - ).await; + ) + .await; // Subsystem requests PoV and requests validation. assert_matches!( @@ -1242,7 +1286,7 @@ fn backing_works_after_failed_validation() { tx, ); - virtual_overseer.send(FromOverseer::Communication{ msg }).await; + virtual_overseer.send(FromOverseer::Communication { msg }).await; assert_eq!(rx.await.unwrap().len(), 0); virtual_overseer }); @@ -1261,9 +1305,7 @@ fn backing_doesnt_second_wrong_collator() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![42, 43, 44]), - }; + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); @@ -1275,7 +1317,8 @@ fn backing_doesnt_second_wrong_collator() { head_data: expected_head_data.clone(), erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let second = CandidateBackingMessage::Second( test_state.relay_parent, @@ -1283,7 +1326,7 @@ fn backing_doesnt_second_wrong_collator() { pov.clone(), ); - virtual_overseer.send(FromOverseer::Communication{ msg: second }).await; + virtual_overseer.send(FromOverseer::Communication { msg: second }).await; assert_matches!( virtual_overseer.recv().await, @@ -1293,9 +1336,11 @@ fn backing_doesnt_second_wrong_collator() { } ); - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; virtual_overseer }); } @@ -1311,9 +1356,7 @@ fn validation_work_ignores_wrong_collator() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![1, 2, 3]), - }; + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; let pov_hash = pov.hash(); @@ -1326,31 +1369,39 @@ fn validation_work_ignores_wrong_collator() { head_data: expected_head_data.clone(), erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let public2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, - ValidatorId::ID, Some(&test_state.validators[2].to_seed()) - ).await.expect("Insert key into keystore"); + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .await + .expect("Insert key into keystore"); let seconding = SignedFullStatement::sign( &test_state.keystore, Statement::Seconded(candidate_a.clone()), &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - seconding.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, seconding.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; // The statement will be ignored because it has the wrong collator. - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; virtual_overseer }); } @@ -1373,7 +1424,8 @@ fn candidate_backing_reorders_votes() { let validator_public = validator_pubkeys(&validators); let validator_groups = { let mut validator_groups = HashMap::new(); - validator_groups.insert(para_id, vec![0, 1, 2, 3, 4, 5].into_iter().map(ValidatorIndex).collect()); + validator_groups + .insert(para_id, vec![0, 1, 2, 3, 4, 5].into_iter().map(ValidatorIndex).collect()); validator_groups }; @@ -1384,7 +1436,7 @@ fn candidate_backing_reorders_votes() { }; let fake_attestation = |idx: u32| { - let candidate: CommittedCandidateReceipt = Default::default(); + let candidate: CommittedCandidateReceipt = Default::default(); let hash = candidate.hash(); let mut data = vec![0; 64]; data[0..32].copy_from_slice(hash.0.as_bytes()); @@ -1418,11 +1470,8 @@ fn candidate_backing_reorders_votes() { }; // Should be in bitfield order, which is opposite to the order provided to the function. - let expected_attestations = vec![ - fake_attestation(1).into(), - fake_attestation(3).into(), - fake_attestation(5).into(), - ]; + let expected_attestations = + vec![fake_attestation(1).into(), fake_attestation(3).into(), fake_attestation(5).into()]; assert_eq!(backed.validator_indices, expected_bitvec); assert_eq!(backed.validity_votes, expected_attestations); @@ -1436,9 +1485,7 @@ fn retry_works() { test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![42, 43, 44]), - }; + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; let pov_hash = pov.hash(); @@ -1448,57 +1495,76 @@ fn retry_works() { pov_hash, erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let public2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, - ValidatorId::ID, Some(&test_state.validators[2].to_seed()) - ).await.expect("Insert key into keystore"); + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .await + .expect("Insert key into keystore"); let public3 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[3].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let public5 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[5].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let signed_a = SignedFullStatement::sign( &test_state.keystore, Statement::Seconded(candidate.clone()), &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let signed_b = SignedFullStatement::sign( &test_state.keystore, Statement::Valid(candidate.hash()), &test_state.signing_context, ValidatorIndex(3), &public3.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let signed_c = SignedFullStatement::sign( &test_state.keystore, Statement::Valid(candidate.hash()), &test_state.signing_context, ValidatorIndex(5), &public5.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); // Send in a `Statement` with a candidate. - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_a.clone(), - ); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate.hash(), test_state.session(), vec![ValidatorIndex(2)], - ).await; + ) + .await; // Subsystem requests PoV and requests validation. // We cancel - should mean retry on next backing statement. @@ -1515,18 +1581,17 @@ fn retry_works() { } ); - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_b.clone(), - ); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate.hash(), test_state.session(), vec![ValidatorIndex(3)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -1541,47 +1606,37 @@ fn retry_works() { } ); - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_c.clone(), - ); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_c.clone()); + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate.hash(), test_state.session(), vec![ValidatorIndex(5)], - ).await; + ) + .await; // Not deterministic which message comes first: for _ in 0u32..2 { match virtual_overseer.recv().await { - AllMessages::Provisioner( - ProvisionerMessage::ProvisionableData( - _, - ProvisionableData::BackedCandidate(CandidateReceipt { - descriptor, - .. - }) - ) - ) => { + AllMessages::Provisioner(ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::BackedCandidate(CandidateReceipt { descriptor, .. }), + )) => { assert_eq!(descriptor, candidate.descriptor); - } + }, // Subsystem requests PoV and requests validation. // Now we pass. AllMessages::AvailabilityDistribution( - AvailabilityDistributionMessage::FetchPoV { - relay_parent, - tx, - .. - } + AvailabilityDistributionMessage::FetchPoV { relay_parent, tx, .. }, ) if relay_parent == test_state.relay_parent => { tx.send(pov.clone()).unwrap(); - } + }, msg => { assert!(false, "Unexpected message: {:?}", msg); - } + }, } } @@ -1606,9 +1661,7 @@ fn observes_backing_even_if_not_validator() { test_harness(empty_keystore, |mut virtual_overseer| async move { test_startup(&mut virtual_overseer, &test_state).await; - let pov = PoV { - block_data: BlockData(vec![1, 2, 3]), - }; + let pov = PoV { block_data: BlockData(vec![1, 2, 3]) }; let pov_hash = pov.hash(); @@ -1621,24 +1674,31 @@ fn observes_backing_even_if_not_validator() { head_data: expected_head_data.clone(), erasure_root: make_erasure_root(&test_state, pov.clone()), ..Default::default() - }.build(); + } + .build(); let candidate_a_hash = candidate_a.hash(); let public0 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[0].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let public1 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[5].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); let public2 = CryptoStore::sr25519_generate_new( &*test_state.keystore, ValidatorId::ID, Some(&test_state.validators[2].to_seed()), - ).await.expect("Insert key into keystore"); + ) + .await + .expect("Insert key into keystore"); // Produce a 3-of-5 quorum on the candidate. @@ -1648,7 +1708,11 @@ fn observes_backing_even_if_not_validator() { &test_state.signing_context, ValidatorIndex(0), &public0.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let signed_b = SignedFullStatement::sign( &test_state.keystore, @@ -1656,7 +1720,11 @@ fn observes_backing_even_if_not_validator() { &test_state.signing_context, ValidatorIndex(5), &public1.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let signed_c = SignedFullStatement::sign( &test_state.keystore, @@ -1664,32 +1732,34 @@ fn observes_backing_even_if_not_validator() { &test_state.signing_context, ValidatorIndex(2), &public2.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); - let statement = CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_b.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_b.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; - let statement = CandidateBackingMessage::Statement( - test_state.relay_parent, - signed_c.clone(), - ); + let statement = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_c.clone()); - virtual_overseer.send(FromOverseer::Communication{ msg: statement }).await; + virtual_overseer.send(FromOverseer::Communication { msg: statement }).await; test_dispute_coordinator_notifications( &mut virtual_overseer, candidate_a_hash, test_state.session(), vec![ValidatorIndex(0), ValidatorIndex(5), ValidatorIndex(2)], - ).await; + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -1703,9 +1773,11 @@ fn observes_backing_even_if_not_validator() { } ); - virtual_overseer.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent))) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; virtual_overseer }); } diff --git a/polkadot/node/core/bitfield-signing/src/lib.rs b/polkadot/node/core/bitfield-signing/src/lib.rs index 1edc89886a3..4d322fffb7c 100644 --- a/polkadot/node/core/bitfield-signing/src/lib.rs +++ b/polkadot/node/core/bitfield-signing/src/lib.rs @@ -18,24 +18,32 @@ #![deny(unused_crate_dependencies)] #![warn(missing_docs)] -#![recursion_limit="256"] - -use futures::{channel::{mpsc, oneshot}, lock::Mutex, prelude::*, future, Future}; -use sp_keystore::{Error as KeystoreError, SyncCryptoStorePtr}; +#![recursion_limit = "256"] + +use futures::{ + channel::{mpsc, oneshot}, + future, + lock::Mutex, + prelude::*, + Future, +}; use polkadot_node_subsystem::{ - jaeger, PerLeafSpan, SubsystemSender, + errors::RuntimeApiError, + jaeger, messages::{ - AvailabilityStoreMessage, BitfieldDistributionMessage, - BitfieldSigningMessage, RuntimeApiMessage, RuntimeApiRequest, + AvailabilityStoreMessage, BitfieldDistributionMessage, BitfieldSigningMessage, + RuntimeApiMessage, RuntimeApiRequest, }, - errors::RuntimeApiError, + PerLeafSpan, SubsystemSender, }; use polkadot_node_subsystem_util::{ - self as util, JobSubsystem, JobTrait, Validator, metrics::{self, prometheus}, - JobSender, + self as util, + metrics::{self, prometheus}, + JobSender, JobSubsystem, JobTrait, Validator, }; use polkadot_primitives::v1::{AvailabilityBitfield, CoreState, Hash, ValidatorIndex}; -use std::{pin::Pin, time::Duration, iter::FromIterator, sync::Arc}; +use sp_keystore::{Error as KeystoreError, SyncCryptoStorePtr}; +use std::{iter::FromIterator, pin::Pin, sync::Arc, time::Duration}; use wasm_timer::{Delay, Instant}; #[cfg(test)] @@ -45,7 +53,6 @@ mod tests; const JOB_DELAY: Duration = Duration::from_millis(1500); const LOG_TARGET: &str = "parachain::bitfield-signing"; - /// Each `BitfieldSigningJob` prepares a signed bitfield for a single relay parent. pub struct BitfieldSigningJob; @@ -92,7 +99,8 @@ async fn get_core_availability( core.candidate_hash, validator_idx, tx, - ).into(), + ) + .into(), ) .await; @@ -119,15 +127,15 @@ async fn get_availability_cores( ) -> Result, Error> { let (tx, rx) = oneshot::channel(); sender - .send_message(RuntimeApiMessage::Request( - relay_parent, - RuntimeApiRequest::AvailabilityCores(tx), - ).into()) + .send_message( + RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::AvailabilityCores(tx)) + .into(), + ) .await; match rx.await { Ok(Ok(out)) => Ok(out), Ok(Err(runtime_err)) => Err(runtime_err.into()), - Err(err) => Err(err.into()) + Err(err) => Err(err.into()), } } @@ -157,9 +165,11 @@ async fn construct_availability_bitfield( // Handle all cores concurrently // `try_join_all` returns all results in the same order as the input futures. let results = future::try_join_all( - availability_cores.iter() + availability_cores + .iter() .map(|core| get_core_availability(core, validator_idx, &sender, span)), - ).await?; + ) + .await?; tracing::debug!( target: LOG_TARGET, @@ -206,12 +216,10 @@ impl metrics::Metrics for Metrics { registry, )?, run: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_bitfield_signing_run", - "Time spent within `bitfield_signing::run`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_bitfield_signing_run", + "Time spent within `bitfield_signing::run`", + ))?, registry, )?, }; @@ -244,7 +252,8 @@ impl JobTrait for BitfieldSigningJob { // now do all the work we can before we need to wait for the availability store // if we're not a validator, we can just succeed effortlessly - let validator = match Validator::new(relay_parent, keystore.clone(), &mut sender).await { + let validator = match Validator::new(relay_parent, keystore.clone(), &mut sender).await + { Ok(validator) => validator, Err(util::Error::NotAValidator) => return Ok(()), Err(err) => return Err(Error::Util(err)), @@ -260,19 +269,19 @@ impl JobTrait for BitfieldSigningJob { drop(_span); let span_availability = span.child("availability"); - let bitfield = - match construct_availability_bitfield( - relay_parent, - &span_availability, - validator.index(), - sender.subsystem_sender(), - ).await + let bitfield = match construct_availability_bitfield( + relay_parent, + &span_availability, + validator.index(), + sender.subsystem_sender(), + ) + .await { Err(Error::Runtime(runtime_err)) => { // Don't take down the node on runtime API errors. tracing::warn!(target: LOG_TARGET, err = ?runtime_err, "Encountered a runtime API error"); - return Ok(()); - } + return Ok(()) + }, Err(err) => return Err(err), Ok(bitfield) => bitfield, }; @@ -280,7 +289,8 @@ impl JobTrait for BitfieldSigningJob { drop(span_availability); let _span = span.child("signing"); - let signed_bitfield = match validator.sign(keystore.clone(), bitfield) + let signed_bitfield = match validator + .sign(keystore.clone(), bitfield) .await .map_err(|e| Error::Keystore(e))? { @@ -290,8 +300,8 @@ impl JobTrait for BitfieldSigningJob { target: LOG_TARGET, "Key was found at construction, but while signing it could not be found.", ); - return Ok(()); - } + return Ok(()) + }, }; metrics.on_bitfield_signed(); diff --git a/polkadot/node/core/bitfield-signing/src/tests.rs b/polkadot/node/core/bitfield-signing/src/tests.rs index a5f8e564599..194a85051e2 100644 --- a/polkadot/node/core/bitfield-signing/src/tests.rs +++ b/polkadot/node/core/bitfield-signing/src/tests.rs @@ -15,9 +15,9 @@ // along with Polkadot. If not, see . use super::*; -use futures::{pin_mut, executor::block_on}; -use polkadot_primitives::v1::{CandidateHash, OccupiedCore}; +use futures::{executor::block_on, pin_mut}; use polkadot_node_subsystem::messages::AllMessages; +use polkadot_primitives::v1::{CandidateHash, OccupiedCore}; fn occupied_core(para_id: u32, candidate_hash: CandidateHash) -> CoreState { CoreState::Occupied(OccupiedCore { @@ -44,7 +44,8 @@ fn construct_availability_bitfield_works() { &jaeger::Span::Disabled, validator_index, &mut sender, - ).fuse(); + ) + .fuse(); pin_mut!(future); let hash_a = CandidateHash(Hash::repeat_byte(1)); diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index 9b22d82a370..17b625e6767 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -23,34 +23,32 @@ #![deny(unused_crate_dependencies, unused_results)] #![warn(missing_docs)] +use polkadot_node_core_pvf::{ + InvalidCandidate as WasmInvalidCandidate, Pvf, ValidationError, ValidationHost, +}; +use polkadot_node_primitives::{ + BlockData, InvalidCandidate, PoV, ValidationResult, POV_BOMB_LIMIT, VALIDATION_CODE_BOMB_LIMIT, +}; use polkadot_node_subsystem::{ - overseer, - SubsystemContext, SpawnedSubsystem, SubsystemResult, SubsystemError, - FromOverseer, OverseerSignal, + errors::RuntimeApiError, messages::{ - CandidateValidationMessage, RuntimeApiMessage, - ValidationFailed, RuntimeApiRequest, + CandidateValidationMessage, RuntimeApiMessage, RuntimeApiRequest, ValidationFailed, }, - errors::RuntimeApiError, + overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, + SubsystemResult, }; use polkadot_node_subsystem_util::metrics::{self, prometheus}; -use polkadot_node_primitives::{ - VALIDATION_CODE_BOMB_LIMIT, POV_BOMB_LIMIT, ValidationResult, InvalidCandidate, PoV, BlockData, -}; +use polkadot_parachain::primitives::{ValidationParams, ValidationResult as WasmValidationResult}; use polkadot_primitives::v1::{ - ValidationCode, CandidateDescriptor, PersistedValidationData, - OccupiedCoreAssumption, Hash, CandidateCommitments, + CandidateCommitments, CandidateDescriptor, Hash, OccupiedCoreAssumption, + PersistedValidationData, ValidationCode, }; -use polkadot_parachain::primitives::{ValidationParams, ValidationResult as WasmValidationResult}; -use polkadot_node_core_pvf::{Pvf, ValidationHost, ValidationError, InvalidCandidate as WasmInvalidCandidate}; use parity_scale_codec::Encode; -use futures::channel::oneshot; -use futures::prelude::*; +use futures::{channel::oneshot, prelude::*}; -use std::sync::Arc; -use std::path::PathBuf; +use std::{path::PathBuf, sync::Arc}; use async_trait::async_trait; @@ -81,7 +79,7 @@ impl CandidateValidationSubsystem { /// /// Check out [`IsolationStrategy`] to get more details. pub fn with_config(config: Config, metrics: Metrics) -> Self { - CandidateValidationSubsystem { config, metrics, } + CandidateValidationSubsystem { config, metrics } } } @@ -91,13 +89,11 @@ where Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { - let future = run(ctx, self.metrics, self.config.artifacts_cache_path, self.config.program_path) - .map_err(|e| SubsystemError::with_origin("candidate-validation", e)) - .boxed(); - SpawnedSubsystem { - name: "candidate-validation-subsystem", - future, - } + let future = + run(ctx, self.metrics, self.config.artifacts_cache_path, self.config.program_path) + .map_err(|e| SubsystemError::with_origin("candidate-validation", e)) + .boxed(); + SpawnedSubsystem { name: "candidate-validation-subsystem", future } } } @@ -118,8 +114,8 @@ where loop { match ctx.recv().await? { - FromOverseer::Signal(OverseerSignal::ActiveLeaves(_)) => {} - FromOverseer::Signal(OverseerSignal::BlockFinalized(..)) => {} + FromOverseer::Signal(OverseerSignal::ActiveLeaves(_)) => {}, + FromOverseer::Signal(OverseerSignal::BlockFinalized(..)) => {}, FromOverseer::Signal(OverseerSignal::Conclude) => return Ok(()), FromOverseer::Communication { msg } => match msg { CandidateValidationMessage::ValidateFromChainState( @@ -135,16 +131,17 @@ where descriptor, pov, &metrics, - ).await; + ) + .await; match res { Ok(x) => { metrics.on_validation_event(&x); let _ = response_sender.send(x); - } + }, Err(e) => return Err(e), } - } + }, CandidateValidationMessage::ValidateFromExhaustive( persisted_validation_data, validation_code, @@ -161,7 +158,8 @@ where descriptor, pov, &metrics, - ).await; + ) + .await; match res { Ok(x) => { @@ -175,8 +173,8 @@ where }, Err(e) => return Err(e), } - } - } + }, + }, } } } @@ -191,12 +189,7 @@ where Context: SubsystemContext, Context: overseer::SubsystemContext, { - ctx.send_message( - RuntimeApiMessage::Request( - relay_parent, - request, - ) - ).await; + ctx.send_message(RuntimeApiMessage::Request(relay_parent, request)).await; receiver.await.map_err(Into::into) } @@ -222,44 +215,38 @@ where let d = runtime_api_request( ctx, descriptor.relay_parent, - RuntimeApiRequest::PersistedValidationData( - descriptor.para_id, - assumption, - tx, - ), + RuntimeApiRequest::PersistedValidationData(descriptor.para_id, assumption, tx), rx, - ).await?; + ) + .await?; match d { - Ok(None) | Err(_) => { - return Ok(AssumptionCheckOutcome::BadRequest); - } + Ok(None) | Err(_) => return Ok(AssumptionCheckOutcome::BadRequest), Ok(Some(d)) => d, } }; let persisted_validation_data_hash = validation_data.hash(); - SubsystemResult::Ok(if descriptor.persisted_validation_data_hash == persisted_validation_data_hash { - let (code_tx, code_rx) = oneshot::channel(); - let validation_code = runtime_api_request( - ctx, - descriptor.relay_parent, - RuntimeApiRequest::ValidationCode( - descriptor.para_id, - assumption, - code_tx, - ), - code_rx, - ).await?; - - match validation_code { - Ok(None) | Err(_) => AssumptionCheckOutcome::BadRequest, - Ok(Some(v)) => AssumptionCheckOutcome::Matches(validation_data, v), - } - } else { - AssumptionCheckOutcome::DoesNotMatch - }) + SubsystemResult::Ok( + if descriptor.persisted_validation_data_hash == persisted_validation_data_hash { + let (code_tx, code_rx) = oneshot::channel(); + let validation_code = runtime_api_request( + ctx, + descriptor.relay_parent, + RuntimeApiRequest::ValidationCode(descriptor.para_id, assumption, code_tx), + code_rx, + ) + .await?; + + match validation_code { + Ok(None) | Err(_) => AssumptionCheckOutcome::BadRequest, + Ok(Some(v)) => AssumptionCheckOutcome::Matches(validation_data, v), + } + } else { + AssumptionCheckOutcome::DoesNotMatch + }, + ) } async fn find_assumed_validation_data( @@ -310,18 +297,16 @@ where { let (validation_data, validation_code) = match find_assumed_validation_data(ctx, &descriptor).await? { - AssumptionCheckOutcome::Matches(validation_data, validation_code) => { - (validation_data, validation_code) - } + AssumptionCheckOutcome::Matches(validation_data, validation_code) => + (validation_data, validation_code), AssumptionCheckOutcome::DoesNotMatch => { // If neither the assumption of the occupied core having the para included or the assumption // of the occupied core timing out are valid, then the persisted_validation_data_hash in the descriptor // is not based on the relay parent and is thus invalid. - return Ok(Ok(ValidationResult::Invalid(InvalidCandidate::BadParent))); - } - AssumptionCheckOutcome::BadRequest => { - return Ok(Err(ValidationFailed("Assumption Check: Bad request".into()))); - } + return Ok(Ok(ValidationResult::Invalid(InvalidCandidate::BadParent))) + }, + AssumptionCheckOutcome::BadRequest => + return Ok(Err(ValidationFailed("Assumption Check: Bad request".into()))), }; let validation_result = validate_candidate_exhaustive( @@ -344,15 +329,10 @@ where ) .await? { - Ok(true) => {} - Ok(false) => { - return Ok(Ok(ValidationResult::Invalid( - InvalidCandidate::InvalidOutputs, - ))); - } - Err(_) => { - return Ok(Err(ValidationFailed("Check Validation Outputs: Bad request".into()))); - } + Ok(true) => {}, + Ok(false) => return Ok(Ok(ValidationResult::Invalid(InvalidCandidate::InvalidOutputs))), + Err(_) => + return Ok(Err(ValidationFailed("Check Validation Outputs: Bad request".into()))), } } @@ -375,7 +355,7 @@ async fn validate_candidate_exhaustive( &*pov, &validation_code, ) { - return Ok(Ok(ValidationResult::Invalid(e))); + return Ok(Ok(ValidationResult::Invalid(e))) } let raw_validation_code = match sp_maybe_compressed_blob::decompress( @@ -387,22 +367,20 @@ async fn validate_candidate_exhaustive( tracing::debug!(target: LOG_TARGET, err=?e, "Invalid validation code"); // If the validation code is invalid, the candidate certainly is. - return Ok(Ok(ValidationResult::Invalid(InvalidCandidate::CodeDecompressionFailure))); - } + return Ok(Ok(ValidationResult::Invalid(InvalidCandidate::CodeDecompressionFailure))) + }, }; - let raw_block_data = match sp_maybe_compressed_blob::decompress( - &pov.block_data.0, - POV_BOMB_LIMIT, - ) { - Ok(block_data) => BlockData(block_data.to_vec()), - Err(e) => { - tracing::debug!(target: LOG_TARGET, err=?e, "Invalid PoV code"); + let raw_block_data = + match sp_maybe_compressed_blob::decompress(&pov.block_data.0, POV_BOMB_LIMIT) { + Ok(block_data) => BlockData(block_data.to_vec()), + Err(e) => { + tracing::debug!(target: LOG_TARGET, err=?e, "Invalid PoV code"); - // If the PoV is invalid, the candidate certainly is. - return Ok(Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure))); - } - }; + // If the PoV is invalid, the candidate certainly is. + return Ok(Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure))) + }, + }; let params = ValidationParams { parent_head: persisted_validation_data.parent_head.clone(), @@ -411,11 +389,8 @@ async fn validate_candidate_exhaustive( relay_parent_storage_root: persisted_validation_data.relay_parent_storage_root, }; - let result = - validation_backend.validate_candidate( - raw_validation_code.to_vec(), - params - ) + let result = validation_backend + .validate_candidate(raw_validation_code.to_vec(), params) .await; if let Err(ref e) = result { @@ -434,9 +409,11 @@ async fn validate_candidate_exhaustive( Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::WorkerReportedError(e))) => Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(e))), Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbigiousWorkerDeath)) => - Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError("ambigious worker death".to_string()))), + Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError( + "ambigious worker death".to_string(), + ))), - Ok(res) => { + Ok(res) => if res.head_data.hash() != descriptor.para_head { Ok(ValidationResult::Invalid(InvalidCandidate::ParaHeadHashMismatch)) } else { @@ -449,8 +426,7 @@ async fn validate_candidate_exhaustive( hrmp_watermark: res.hrmp_watermark, }; Ok(ValidationResult::Valid(outputs, persisted_validation_data)) - } - } + }, }; Ok(result) @@ -461,7 +437,7 @@ trait ValidationBackend { async fn validate_candidate( &mut self, raw_validation_code: Vec, - params: ValidationParams + params: ValidationParams, ) -> Result; } @@ -470,16 +446,22 @@ impl ValidationBackend for &'_ mut ValidationHost { async fn validate_candidate( &mut self, raw_validation_code: Vec, - params: ValidationParams + params: ValidationParams, ) -> Result { let (tx, rx) = oneshot::channel(); - if let Err(err) = self.execute_pvf( - Pvf::from_code(raw_validation_code), - params.encode(), - polkadot_node_core_pvf::Priority::Normal, - tx, - ).await { - return Err(ValidationError::InternalError(format!("cannot send pvf to the validation host: {:?}", err))); + if let Err(err) = self + .execute_pvf( + Pvf::from_code(raw_validation_code), + params.encode(), + polkadot_node_core_pvf::Priority::Normal, + tx, + ) + .await + { + return Err(ValidationError::InternalError(format!( + "cannot send pvf to the validation host: {:?}", + err + ))) } let validation_result = rx @@ -503,19 +485,19 @@ fn perform_basic_checks( let encoded_pov_size = pov.encoded_size(); if encoded_pov_size > max_pov_size as usize { - return Err(InvalidCandidate::ParamsTooLarge(encoded_pov_size as u64)); + return Err(InvalidCandidate::ParamsTooLarge(encoded_pov_size as u64)) } if pov_hash != candidate.pov_hash { - return Err(InvalidCandidate::PoVHashMismatch); + return Err(InvalidCandidate::PoVHashMismatch) } if validation_code_hash != candidate.validation_code_hash { - return Err(InvalidCandidate::CodeHashMismatch); + return Err(InvalidCandidate::CodeHashMismatch) } if let Err(()) = candidate.check_collator_signature() { - return Err(InvalidCandidate::BadSignature); + return Err(InvalidCandidate::BadSignature) } Ok(()) @@ -551,18 +533,26 @@ impl Metrics { } /// Provide a timer for `validate_from_chain_state` which observes on drop. - fn time_validate_from_chain_state(&self) -> Option { + fn time_validate_from_chain_state( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.validate_from_chain_state.start_timer()) } /// Provide a timer for `validate_from_exhaustive` which observes on drop. - fn time_validate_from_exhaustive(&self) -> Option { + fn time_validate_from_exhaustive( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.validate_from_exhaustive.start_timer()) } /// Provide a timer for `validate_candidate_exhaustive` which observes on drop. - fn time_validate_candidate_exhaustive(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.validate_candidate_exhaustive.start_timer()) + fn time_validate_candidate_exhaustive( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.validate_candidate_exhaustive.start_timer()) } } @@ -580,30 +570,24 @@ impl metrics::Metrics for Metrics { registry, )?, validate_from_chain_state: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_candidate_validation_validate_from_chain_state", - "Time spent within `candidate_validation::validate_from_chain_state`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_candidate_validation_validate_from_chain_state", + "Time spent within `candidate_validation::validate_from_chain_state`", + ))?, registry, )?, validate_from_exhaustive: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_candidate_validation_validate_from_exhaustive", - "Time spent within `candidate_validation::validate_from_exhaustive`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_candidate_validation_validate_from_exhaustive", + "Time spent within `candidate_validation::validate_from_exhaustive`", + ))?, registry, )?, validate_candidate_exhaustive: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_candidate_validation_validate_candidate_exhaustive", - "Time spent within `candidate_validation::validate_candidate_exhaustive`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_candidate_validation_validate_candidate_exhaustive", + "Time spent within `candidate_validation::validate_candidate_exhaustive`", + ))?, registry, )?, }; diff --git a/polkadot/node/core/candidate-validation/src/tests.rs b/polkadot/node/core/candidate-validation/src/tests.rs index c718122a63e..9c5cd34f6b9 100644 --- a/polkadot/node/core/candidate-validation/src/tests.rs +++ b/polkadot/node/core/candidate-validation/src/tests.rs @@ -15,12 +15,12 @@ // along with Polkadot. If not, see . use super::*; +use assert_matches::assert_matches; +use futures::executor; use polkadot_node_subsystem::messages::AllMessages; use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_primitives::v1::{HeadData, UpwardMessage}; use sp_core::testing::TaskExecutor; -use futures::executor; -use assert_matches::assert_matches; use sp_keyring::Sr25519Keyring; fn collator_sign(descriptor: &mut CandidateDescriptor, collator: Sr25519Keyring) { @@ -54,11 +54,9 @@ fn correctly_checks_included_assumption() { let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = test_helpers::make_subsystem_context(pool.clone()); - let (check_fut, check_result) = check_assumption_validation_data( - &mut ctx, - &candidate, - OccupiedCoreAssumption::Included, - ).remote_handle(); + let (check_fut, check_result) = + check_assumption_validation_data(&mut ctx, &candidate, OccupiedCoreAssumption::Included) + .remote_handle(); let test_fut = async move { assert_matches!( @@ -118,11 +116,9 @@ fn correctly_checks_timed_out_assumption() { let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = test_helpers::make_subsystem_context(pool.clone()); - let (check_fut, check_result) = check_assumption_validation_data( - &mut ctx, - &candidate, - OccupiedCoreAssumption::TimedOut, - ).remote_handle(); + let (check_fut, check_result) = + check_assumption_validation_data(&mut ctx, &candidate, OccupiedCoreAssumption::TimedOut) + .remote_handle(); let test_fut = async move { assert_matches!( @@ -180,11 +176,9 @@ fn check_is_bad_request_if_no_validation_data() { let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = test_helpers::make_subsystem_context(pool.clone()); - let (check_fut, check_result) = check_assumption_validation_data( - &mut ctx, - &candidate, - OccupiedCoreAssumption::Included, - ).remote_handle(); + let (check_fut, check_result) = + check_assumption_validation_data(&mut ctx, &candidate, OccupiedCoreAssumption::Included) + .remote_handle(); let test_fut = async move { assert_matches!( @@ -226,11 +220,9 @@ fn check_is_bad_request_if_no_validation_code() { let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = test_helpers::make_subsystem_context(pool.clone()); - let (check_fut, check_result) = check_assumption_validation_data( - &mut ctx, - &candidate, - OccupiedCoreAssumption::TimedOut, - ).remote_handle(); + let (check_fut, check_result) = + check_assumption_validation_data(&mut ctx, &candidate, OccupiedCoreAssumption::TimedOut) + .remote_handle(); let test_fut = async move { assert_matches!( @@ -284,11 +276,9 @@ fn check_does_not_match() { let pool = TaskExecutor::new(); let (mut ctx, mut ctx_handle) = test_helpers::make_subsystem_context(pool.clone()); - let (check_fut, check_result) = check_assumption_validation_data( - &mut ctx, - &candidate, - OccupiedCoreAssumption::Included, - ).remote_handle(); + let (check_fut, check_result) = + check_assumption_validation_data(&mut ctx, &candidate, OccupiedCoreAssumption::Included) + .remote_handle(); let test_fut = async move { assert_matches!( @@ -321,9 +311,7 @@ struct MockValidatorBackend { impl MockValidatorBackend { fn with_hardcoded_result(result: Result) -> Self { - Self { - result, - } + Self { result } } } @@ -332,7 +320,7 @@ impl ValidationBackend for MockValidatorBackend { async fn validate_candidate( &mut self, _raw_validation_code: Vec, - _params: ValidationParams + _params: ValidationParams, ) -> Result { self.result.clone() } @@ -352,12 +340,8 @@ fn candidate_validation_ok_is_ok() { descriptor.validation_code_hash = validation_code.hash(); collator_sign(&mut descriptor, Sr25519Keyring::Alice); - let check = perform_basic_checks( - &descriptor, - validation_data.max_pov_size, - &pov, - &validation_code, - ); + let check = + perform_basic_checks(&descriptor, validation_data.max_pov_size, &pov, &validation_code); assert!(check.is_ok()); let validation_result = WasmValidationResult { @@ -402,18 +386,14 @@ fn candidate_validation_bad_return_is_invalid() { descriptor.validation_code_hash = validation_code.hash(); collator_sign(&mut descriptor, Sr25519Keyring::Alice); - let check = perform_basic_checks( - &descriptor, - validation_data.max_pov_size, - &pov, - &validation_code, - ); + let check = + perform_basic_checks(&descriptor, validation_data.max_pov_size, &pov, &validation_code); assert!(check.is_ok()); let v = executor::block_on(validate_candidate_exhaustive( - MockValidatorBackend::with_hardcoded_result( - Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::AmbigiousWorkerDeath)) - ), + MockValidatorBackend::with_hardcoded_result(Err(ValidationError::InvalidCandidate( + WasmInvalidCandidate::AmbigiousWorkerDeath, + ))), validation_data, validation_code, descriptor, @@ -438,18 +418,14 @@ fn candidate_validation_timeout_is_internal_error() { descriptor.validation_code_hash = validation_code.hash(); collator_sign(&mut descriptor, Sr25519Keyring::Alice); - let check = perform_basic_checks( - &descriptor, - validation_data.max_pov_size, - &pov, - &validation_code, - ); + let check = + perform_basic_checks(&descriptor, validation_data.max_pov_size, &pov, &validation_code); assert!(check.is_ok()); let v = executor::block_on(validate_candidate_exhaustive( - MockValidatorBackend::with_hardcoded_result( - Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout)), - ), + MockValidatorBackend::with_hardcoded_result(Err(ValidationError::InvalidCandidate( + WasmInvalidCandidate::HardTimeout, + ))), validation_data, validation_code, descriptor, @@ -473,18 +449,14 @@ fn candidate_validation_code_mismatch_is_invalid() { descriptor.validation_code_hash = ValidationCode(vec![1; 16]).hash(); collator_sign(&mut descriptor, Sr25519Keyring::Alice); - let check = perform_basic_checks( - &descriptor, - validation_data.max_pov_size, - &pov, - &validation_code, - ); + let check = + perform_basic_checks(&descriptor, validation_data.max_pov_size, &pov, &validation_code); assert_matches!(check, Err(InvalidCandidate::CodeHashMismatch)); let v = executor::block_on(validate_candidate_exhaustive( - MockValidatorBackend::with_hardcoded_result( - Err(ValidationError::InvalidCandidate(WasmInvalidCandidate::HardTimeout)), - ), + MockValidatorBackend::with_hardcoded_result(Err(ValidationError::InvalidCandidate( + WasmInvalidCandidate::HardTimeout, + ))), validation_data, validation_code, descriptor, @@ -504,10 +476,7 @@ fn compressed_code_works() { let head_data = HeadData(vec![1, 1, 1]); let raw_code = vec![2u8; 16]; - let validation_code = sp_maybe_compressed_blob::compress( - &raw_code, - VALIDATION_CODE_BOMB_LIMIT, - ) + let validation_code = sp_maybe_compressed_blob::compress(&raw_code, VALIDATION_CODE_BOMB_LIMIT) .map(ValidationCode) .unwrap(); @@ -546,12 +515,10 @@ fn code_decompression_failure_is_invalid() { let head_data = HeadData(vec![1, 1, 1]); let raw_code = vec![2u8; VALIDATION_CODE_BOMB_LIMIT + 1]; - let validation_code = sp_maybe_compressed_blob::compress( - &raw_code, - VALIDATION_CODE_BOMB_LIMIT + 1, - ) - .map(ValidationCode) - .unwrap(); + let validation_code = + sp_maybe_compressed_blob::compress(&raw_code, VALIDATION_CODE_BOMB_LIMIT + 1) + .map(ValidationCode) + .unwrap(); let mut descriptor = CandidateDescriptor::default(); descriptor.pov_hash = pov.hash(); @@ -578,25 +545,17 @@ fn code_decompression_failure_is_invalid() { )) .unwrap(); - assert_matches!( - v, - Ok(ValidationResult::Invalid(InvalidCandidate::CodeDecompressionFailure)) - ); + assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::CodeDecompressionFailure))); } #[test] fn pov_decompression_failure_is_invalid() { - let validation_data = PersistedValidationData { - max_pov_size: POV_BOMB_LIMIT as u32, - ..Default::default() - }; + let validation_data = + PersistedValidationData { max_pov_size: POV_BOMB_LIMIT as u32, ..Default::default() }; let head_data = HeadData(vec![1, 1, 1]); let raw_block_data = vec![2u8; POV_BOMB_LIMIT + 1]; - let pov = sp_maybe_compressed_blob::compress( - &raw_block_data, - POV_BOMB_LIMIT + 1, - ) + let pov = sp_maybe_compressed_blob::compress(&raw_block_data, POV_BOMB_LIMIT + 1) .map(|raw| PoV { block_data: BlockData(raw) }) .unwrap(); @@ -627,8 +586,5 @@ fn pov_decompression_failure_is_invalid() { )) .unwrap(); - assert_matches!( - v, - Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure)) - ); + assert_matches!(v, Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure))); } diff --git a/polkadot/node/core/chain-api/src/lib.rs b/polkadot/node/core/chain-api/src/lib.rs index 264a27644d1..74ae88e3f45 100644 --- a/polkadot/node/core/chain-api/src/lib.rs +++ b/polkadot/node/core/chain-api/src/lib.rs @@ -40,9 +40,7 @@ use sp_blockchain::HeaderBackend; use polkadot_node_subsystem_util::metrics::{self, prometheus}; use polkadot_primitives::v1::{Block, BlockId}; use polkadot_subsystem::{ - overseer, - messages::ChainApiMessage, - FromOverseer, OverseerSignal, SpawnedSubsystem, + messages::ChainApiMessage, overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, SubsystemResult, }; @@ -60,10 +58,7 @@ pub struct ChainApiSubsystem { impl ChainApiSubsystem { /// Create a new Chain API subsystem with the given client. pub fn new(client: Arc, metrics: Metrics) -> Self { - ChainApiSubsystem { - client, - metrics, - } + ChainApiSubsystem { client, metrics } } } @@ -77,10 +72,7 @@ where let future = run::(ctx, self) .map_err(|e| SubsystemError::with_origin("chain-api", e)) .boxed(); - SpawnedSubsystem { - future, - name: "chain-api-subsystem", - } + SpawnedSubsystem { future, name: "chain-api-subsystem" } } } @@ -107,7 +99,8 @@ where }, ChainApiMessage::BlockHeader(hash, response_channel) => { let _timer = subsystem.metrics.time_block_header(); - let result = subsystem.client + let result = subsystem + .client .header(BlockId::Hash(hash)) .map_err(|e| e.to_string().into()); subsystem.metrics.on_request(result.is_ok()); @@ -119,7 +112,7 @@ where .map_err(|e| e.to_string().into()); subsystem.metrics.on_request(result.is_ok()); let _ = response_channel.send(result); - } + }, ChainApiMessage::FinalizedBlockHash(number, response_channel) => { let _timer = subsystem.metrics.time_finalized_block_hash(); // Note: we don't verify it's finalized @@ -158,7 +151,7 @@ where hash = header.parent_hash; Some(Ok(hash)) } - } + }, } }); @@ -166,7 +159,7 @@ where subsystem.metrics.on_request(result.is_ok()); let _ = response_channel.send(result); }, - } + }, } } } @@ -218,7 +211,9 @@ impl Metrics { } /// Provide a timer for `finalized_block_number` which observes on drop. - fn time_finalized_block_number(&self) -> Option { + fn time_finalized_block_number( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.finalized_block_number.start_timer()) } @@ -242,57 +237,45 @@ impl metrics::Metrics for Metrics { registry, )?, block_number: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_chain_api_block_number", - "Time spent within `chain_api::block_number`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_chain_api_block_number", + "Time spent within `chain_api::block_number`", + ))?, registry, )?, block_header: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_chain_api_block_headers", - "Time spent within `chain_api::block_headers`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_chain_api_block_headers", + "Time spent within `chain_api::block_headers`", + ))?, registry, )?, block_weight: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_chain_api_block_weight", - "Time spent within `chain_api::block_weight`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_chain_api_block_weight", + "Time spent within `chain_api::block_weight`", + ))?, registry, )?, finalized_block_hash: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_chain_api_finalized_block_hash", - "Time spent within `chain_api::finalized_block_hash`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_chain_api_finalized_block_hash", + "Time spent within `chain_api::finalized_block_hash`", + ))?, registry, )?, finalized_block_number: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_chain_api_finalized_block_number", - "Time spent within `chain_api::finalized_block_number`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_chain_api_finalized_block_number", + "Time spent within `chain_api::finalized_block_number`", + ))?, registry, )?, ancestors: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_chain_api_ancestors", - "Time spent within `chain_api::ancestors`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_chain_api_ancestors", + "Time spent within `chain_api::ancestors`", + ))?, registry, )?, }; diff --git a/polkadot/node/core/chain-api/src/tests.rs b/polkadot/node/core/chain-api/src/tests.rs index 730a6a2ae69..22b6dbed546 100644 --- a/polkadot/node/core/chain-api/src/tests.rs +++ b/polkadot/node/core/chain-api/src/tests.rs @@ -1,12 +1,12 @@ use super::*; -use std::collections::BTreeMap; -use futures::{future::BoxFuture, channel::oneshot}; +use futures::{channel::oneshot, future::BoxFuture}; use parity_scale_codec::Encode; +use std::collections::BTreeMap; -use polkadot_primitives::v1::{Hash, BlockNumber, BlockId, Header}; use polkadot_node_primitives::BlockWeight; use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle}; +use polkadot_primitives::v1::{BlockId, BlockNumber, Hash, Header}; use sp_blockchain::Info as BlockInfo; use sp_core::testing::TaskExecutor; @@ -79,10 +79,7 @@ impl Default for TestClient { fn last_key_value(map: &BTreeMap) -> (K, V) { assert!(!map.is_empty()); - map.iter() - .last() - .map(|(k, v)| (k.clone(), v.clone())) - .unwrap() + map.iter().last().map(|(k, v)| (k.clone(), v.clone())).unwrap() } impl HeaderBackend for TestClient { @@ -110,12 +107,9 @@ impl HeaderBackend for TestClient { fn header(&self, id: BlockId) -> sp_blockchain::Result> { match id { // for error path testing - BlockId::Hash(hash) if hash.is_zero() => { - Err(sp_blockchain::Error::Backend("Zero hashes are illegal!".into())) - } - BlockId::Hash(hash) => { - Ok(self.headers.get(&hash).cloned()) - } + BlockId::Hash(hash) if hash.is_zero() => + Err(sp_blockchain::Error::Backend("Zero hashes are illegal!".into())), + BlockId::Hash(hash) => Ok(self.headers.get(&hash).cloned()), _ => unreachable!(), } } @@ -125,8 +119,10 @@ impl HeaderBackend for TestClient { } fn test_harness( - test: impl FnOnce(Arc, TestSubsystemContextHandle) - -> BoxFuture<'static, ()>, + test: impl FnOnce( + Arc, + TestSubsystemContextHandle, + ) -> BoxFuture<'static, ()>, ) { let (ctx, ctx_handle) = make_subsystem_context(TaskExecutor::new()); let client = Arc::new(TestClient::default()); @@ -174,15 +170,18 @@ fn request_block_number() { for (hash, expected) in &test_cases { let (tx, rx) = oneshot::channel(); - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::BlockNumber(*hash, tx), - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::BlockNumber(*hash, tx), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), *expected); } sender.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }.boxed() + } + .boxed() }) } @@ -198,15 +197,18 @@ fn request_block_header() { for (hash, expected) in &test_cases { let (tx, rx) = oneshot::channel(); - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::BlockHeader(*hash, tx), - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::BlockHeader(*hash, tx), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), *expected); } sender.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }.boxed() + } + .boxed() }) } @@ -223,15 +225,18 @@ fn request_block_weight() { for (hash, expected) in &test_cases { let (tx, rx) = oneshot::channel(); - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::BlockWeight(*hash, tx), - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::BlockWeight(*hash, tx), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), *expected); } sender.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }.boxed() + } + .boxed() }) } @@ -246,15 +251,18 @@ fn request_finalized_hash() { for (number, expected) in &test_cases { let (tx, rx) = oneshot::channel(); - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::FinalizedBlockHash(*number, tx), - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::FinalizedBlockHash(*number, tx), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), *expected); } sender.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }.boxed() + } + .boxed() }) } @@ -265,14 +273,17 @@ fn request_last_finalized_number() { let (tx, rx) = oneshot::channel(); let expected = client.info().finalized_number; - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::FinalizedBlockNumber(tx), - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::FinalizedBlockNumber(tx), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), expected); sender.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }.boxed() + } + .boxed() }) } @@ -281,24 +292,35 @@ fn request_ancestors() { test_harness(|_client, mut sender| { async move { let (tx, rx) = oneshot::channel(); - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::Ancestors { hash: THREE, k: 4, response_channel: tx }, - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::Ancestors { hash: THREE, k: 4, response_channel: tx }, + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), vec![TWO, ONE]); let (tx, rx) = oneshot::channel(); - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::Ancestors { hash: TWO, k: 1, response_channel: tx }, - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::Ancestors { hash: TWO, k: 1, response_channel: tx }, + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), vec![ONE]); let (tx, rx) = oneshot::channel(); - sender.send(FromOverseer::Communication { - msg: ChainApiMessage::Ancestors { hash: ERROR_PATH, k: 2, response_channel: tx }, - }).await; + sender + .send(FromOverseer::Communication { + msg: ChainApiMessage::Ancestors { + hash: ERROR_PATH, + k: 2, + response_channel: tx, + }, + }) + .await; assert!(rx.await.unwrap().is_err()); sender.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }.boxed() + } + .boxed() }) } diff --git a/polkadot/node/core/chain-selection/src/backend.rs b/polkadot/node/core/chain-selection/src/backend.rs index 42f2e4794b3..d340e34e18a 100644 --- a/polkadot/node/core/chain-selection/src/backend.rs +++ b/polkadot/node/core/chain-selection/src/backend.rs @@ -25,7 +25,7 @@ use polkadot_primitives::v1::{BlockNumber, Hash}; use std::collections::HashMap; -use crate::{Error, LeafEntrySet, BlockEntry, Timestamp}; +use crate::{BlockEntry, Error, LeafEntrySet, Timestamp}; pub(super) enum BackendWriteOp { WriteBlockEntry(BlockEntry), @@ -47,8 +47,10 @@ pub(super) trait Backend { fn load_stagnant_at(&self, timestamp: Timestamp) -> Result, Error>; /// Load all stagnant lists up to and including the given Unix timestamp /// in ascending order. - fn load_stagnant_at_up_to(&self, up_to: Timestamp) - -> Result)>, Error>; + fn load_stagnant_at_up_to( + &self, + up_to: Timestamp, + ) -> Result)>, Error>; /// Load the earliest kept block number. fn load_first_block_number(&self) -> Result, Error>; /// Load blocks by number. @@ -56,7 +58,8 @@ pub(super) trait Backend { /// Atomically write the list of operations, with later operations taking precedence over prior. fn write(&mut self, ops: I) -> Result<(), Error> - where I: IntoIterator; + where + I: IntoIterator; } /// An in-memory overlay over the backend. @@ -98,7 +101,7 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { pub(super) fn load_blocks_by_number(&self, number: BlockNumber) -> Result, Error> { if let Some(val) = self.blocks_by_number.get(&number) { - return Ok(val.as_ref().map_or(Vec::new(), Clone::clone)); + return Ok(val.as_ref().map_or(Vec::new(), Clone::clone)) } self.inner.load_blocks_by_number(number) @@ -114,7 +117,7 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { pub(super) fn load_stagnant_at(&self, timestamp: Timestamp) -> Result, Error> { if let Some(val) = self.stagnant_at.get(×tamp) { - return Ok(val.as_ref().map_or(Vec::new(), Clone::clone)); + return Ok(val.as_ref().map_or(Vec::new(), Clone::clone)) } self.inner.load_stagnant_at(timestamp) @@ -188,17 +191,15 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { /// return true if `ancestor` is in `head`'s chain. /// /// If the ancestor is an older finalized block, this will return `false`. -fn contains_ancestor( - backend: &impl Backend, - head: Hash, - ancestor: Hash, -) -> Result { +fn contains_ancestor(backend: &impl Backend, head: Hash, ancestor: Hash) -> Result { let mut current_hash = head; loop { - if current_hash == ancestor { return Ok(true) } + if current_hash == ancestor { + return Ok(true) + } match backend.load_block_entry(¤t_hash)? { - Some(e) => { current_hash = e.parent_hash } - None => break + Some(e) => current_hash = e.parent_hash, + None => break, } } diff --git a/polkadot/node/core/chain-selection/src/db_backend/v1.rs b/polkadot/node/core/chain-selection/src/db_backend/v1.rs index 71a4f718f9e..5d7262e2340 100644 --- a/polkadot/node/core/chain-selection/src/db_backend/v1.rs +++ b/polkadot/node/core/chain-selection/src/db_backend/v1.rs @@ -32,14 +32,16 @@ //! The `Vec`s stored are always non-empty. Empty `Vec`s are not stored on disk so there is no //! semantic difference between `None` and an empty `Vec`. -use crate::backend::{Backend, BackendWriteOp}; -use crate::Error; +use crate::{ + backend::{Backend, BackendWriteOp}, + Error, +}; -use polkadot_primitives::v1::{BlockNumber, Hash}; use polkadot_node_primitives::BlockWeight; +use polkadot_primitives::v1::{BlockNumber, Hash}; use kvdb::{DBTransaction, KeyValueDB}; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; use std::sync::Arc; @@ -116,11 +118,7 @@ struct LeafEntry { impl From for LeafEntry { fn from(x: crate::LeafEntry) -> Self { - LeafEntry { - weight: x.weight, - block_number: x.block_number, - block_hash: x.block_hash, - } + LeafEntry { weight: x.weight, block_number: x.block_number, block_hash: x.block_hash } } } @@ -141,17 +139,13 @@ struct LeafEntrySet { impl From for LeafEntrySet { fn from(x: crate::LeafEntrySet) -> Self { - LeafEntrySet { - inner: x.inner.into_iter().map(Into::into).collect(), - } + LeafEntrySet { inner: x.inner.into_iter().map(Into::into).collect() } } } impl From for crate::LeafEntrySet { fn from(x: LeafEntrySet) -> crate::LeafEntrySet { - crate::LeafEntrySet { - inner: x.inner.into_iter().map(Into::into).collect(), - } + crate::LeafEntrySet { inner: x.inner.into_iter().map(Into::into).collect() } } } @@ -208,28 +202,19 @@ impl DbBackend { /// Create a new [`DbBackend`] with the supplied key-value store and /// config. pub fn new(db: Arc, config: Config) -> Self { - DbBackend { - inner: db, - config, - } + DbBackend { inner: db, config } } } impl Backend for DbBackend { fn load_block_entry(&self, hash: &Hash) -> Result, Error> { - load_decode::( - &*self.inner, - self.config.col_data, - &block_entry_key(hash), - ).map(|o| o.map(Into::into)) + load_decode::(&*self.inner, self.config.col_data, &block_entry_key(hash)) + .map(|o| o.map(Into::into)) } fn load_leaves(&self) -> Result { - load_decode::( - &*self.inner, - self.config.col_data, - LEAVES_KEY, - ).map(|o| o.map(Into::into).unwrap_or_default()) + load_decode::(&*self.inner, self.config.col_data, LEAVES_KEY) + .map(|o| o.map(Into::into).unwrap_or_default()) } fn load_stagnant_at(&self, timestamp: crate::Timestamp) -> Result, Error> { @@ -237,16 +222,16 @@ impl Backend for DbBackend { &*self.inner, self.config.col_data, &stagnant_at_key(timestamp.into()), - ).map(|o| o.unwrap_or_default()) + ) + .map(|o| o.unwrap_or_default()) } - fn load_stagnant_at_up_to(&self, up_to: crate::Timestamp) - -> Result)>, Error> - { - let stagnant_at_iter = self.inner.iter_with_prefix( - self.config.col_data, - &STAGNANT_AT_PREFIX[..], - ); + fn load_stagnant_at_up_to( + &self, + up_to: crate::Timestamp, + ) -> Result)>, Error> { + let stagnant_at_iter = + self.inner.iter_with_prefix(self.config.col_data, &STAGNANT_AT_PREFIX[..]); let val = stagnant_at_iter .filter_map(|(k, v)| { @@ -262,10 +247,8 @@ impl Backend for DbBackend { } fn load_first_block_number(&self) -> Result, Error> { - let blocks_at_height_iter = self.inner.iter_with_prefix( - self.config.col_data, - &BLOCK_HEIGHT_PREFIX[..], - ); + let blocks_at_height_iter = + self.inner.iter_with_prefix(self.config.col_data, &BLOCK_HEIGHT_PREFIX[..]); let val = blocks_at_height_iter .filter_map(|(k, _)| decode_block_height_key(&k[..])) @@ -275,16 +258,14 @@ impl Backend for DbBackend { } fn load_blocks_by_number(&self, number: BlockNumber) -> Result, Error> { - load_decode::>( - &*self.inner, - self.config.col_data, - &block_height_key(number), - ).map(|o| o.unwrap_or_default()) + load_decode::>(&*self.inner, self.config.col_data, &block_height_key(number)) + .map(|o| o.unwrap_or_default()) } /// Atomically write the list of operations, with later operations taking precedence over prior. fn write(&mut self, ops: I) -> Result<(), Error> - where I: IntoIterator + where + I: IntoIterator, { let mut tx = DBTransaction::new(); for op in ops { @@ -296,43 +277,29 @@ impl Backend for DbBackend { &block_entry_key(&block_entry.block_hash), block_entry.encode(), ); - } - BackendWriteOp::WriteBlocksByNumber(block_number, v) => { + }, + BackendWriteOp::WriteBlocksByNumber(block_number, v) => if v.is_empty() { - tx.delete( - self.config.col_data, - &block_height_key(block_number), - ); + tx.delete(self.config.col_data, &block_height_key(block_number)); } else { tx.put_vec( self.config.col_data, &block_height_key(block_number), v.encode(), ); - } - } + }, BackendWriteOp::WriteViableLeaves(leaves) => { let leaves: LeafEntrySet = leaves.into(); if leaves.inner.is_empty() { - tx.delete( - self.config.col_data, - &LEAVES_KEY[..], - ); + tx.delete(self.config.col_data, &LEAVES_KEY[..]); } else { - tx.put_vec( - self.config.col_data, - &LEAVES_KEY[..], - leaves.encode(), - ); + tx.put_vec(self.config.col_data, &LEAVES_KEY[..], leaves.encode()); } - } + }, BackendWriteOp::WriteStagnantAt(timestamp, stagnant_at) => { let timestamp: Timestamp = timestamp.into(); if stagnant_at.is_empty() { - tx.delete( - self.config.col_data, - &stagnant_at_key(timestamp), - ); + tx.delete(self.config.col_data, &stagnant_at_key(timestamp)); } else { tx.put_vec( self.config.col_data, @@ -340,26 +307,17 @@ impl Backend for DbBackend { stagnant_at.encode(), ); } - } + }, BackendWriteOp::DeleteBlocksByNumber(block_number) => { - tx.delete( - self.config.col_data, - &block_height_key(block_number), - ); - } + tx.delete(self.config.col_data, &block_height_key(block_number)); + }, BackendWriteOp::DeleteBlockEntry(hash) => { - tx.delete( - self.config.col_data, - &block_entry_key(&hash), - ); - } + tx.delete(self.config.col_data, &block_entry_key(&hash)); + }, BackendWriteOp::DeleteStagnantAt(timestamp) => { let timestamp: Timestamp = timestamp.into(); - tx.delete( - self.config.col_data, - &stagnant_at_key(timestamp), - ); - } + tx.delete(self.config.col_data, &stagnant_at_key(timestamp)); + }, } } @@ -374,9 +332,7 @@ fn load_decode( ) -> Result, Error> { match db.get(col_data, key)? { None => Ok(None), - Some(raw) => D::decode(&mut &raw[..]) - .map(Some) - .map_err(Into::into), + Some(raw) => D::decode(&mut &raw[..]).map(Some).map_err(Into::into), } } @@ -402,8 +358,12 @@ fn stagnant_at_key(timestamp: Timestamp) -> [u8; 14 + 8] { } fn decode_block_height_key(key: &[u8]) -> Option { - if key.len() != 15 + 4 { return None } - if !key.starts_with(BLOCK_HEIGHT_PREFIX) { return None } + if key.len() != 15 + 4 { + return None + } + if !key.starts_with(BLOCK_HEIGHT_PREFIX) { + return None + } let mut bytes = [0; 4]; bytes.copy_from_slice(&key[15..]); @@ -411,8 +371,12 @@ fn decode_block_height_key(key: &[u8]) -> Option { } fn decode_stagnant_at_key(key: &[u8]) -> Option { - if key.len() != 14 + 8 { return None } - if !key.starts_with(STAGNANT_AT_PREFIX) { return None } + if key.len() != 14 + 8 { + return None + } + if !key.starts_with(STAGNANT_AT_PREFIX) { + return None + } let mut bytes = [0; 8]; bytes.copy_from_slice(&key[14..]); @@ -479,9 +443,9 @@ mod tests { weight: 100, }; - backend.write(vec![ - BackendWriteOp::WriteBlockEntry(block_entry.clone().into()) - ]).unwrap(); + backend + .write(vec![BackendWriteOp::WriteBlockEntry(block_entry.clone().into())]) + .unwrap(); assert_eq!( backend.load_block_entry(&block_entry.block_hash).unwrap().map(BlockEntry::from), @@ -509,17 +473,15 @@ mod tests { weight: 100, }; - backend.write(vec![ - BackendWriteOp::WriteBlockEntry(block_entry.clone().into()) - ]).unwrap(); + backend + .write(vec![BackendWriteOp::WriteBlockEntry(block_entry.clone().into())]) + .unwrap(); - backend.write(vec![ - BackendWriteOp::DeleteBlockEntry(block_entry.block_hash), - ]).unwrap(); + backend + .write(vec![BackendWriteOp::DeleteBlockEntry(block_entry.block_hash)]) + .unwrap(); - assert!( - backend.load_block_entry(&block_entry.block_hash).unwrap().is_none(), - ); + assert!(backend.load_block_entry(&block_entry.block_hash).unwrap().is_none(),); } #[test] @@ -529,30 +491,26 @@ mod tests { let mut backend = DbBackend::new(db, config); - assert!( - backend.load_first_block_number().unwrap().is_none(), - ); + assert!(backend.load_first_block_number().unwrap().is_none(),); - backend.write(vec![ - BackendWriteOp::WriteBlocksByNumber(2, vec![Hash::repeat_byte(0)]), - BackendWriteOp::WriteBlocksByNumber(5, vec![Hash::repeat_byte(0)]), - BackendWriteOp::WriteBlocksByNumber(10, vec![Hash::repeat_byte(0)]), - ]).unwrap(); + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![Hash::repeat_byte(0)]), + BackendWriteOp::WriteBlocksByNumber(5, vec![Hash::repeat_byte(0)]), + BackendWriteOp::WriteBlocksByNumber(10, vec![Hash::repeat_byte(0)]), + ]) + .unwrap(); - assert_eq!( - backend.load_first_block_number().unwrap(), - Some(2), - ); + assert_eq!(backend.load_first_block_number().unwrap(), Some(2),); - backend.write(vec![ - BackendWriteOp::WriteBlocksByNumber(2, vec![]), - BackendWriteOp::DeleteBlocksByNumber(5), - ]).unwrap(); + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![]), + BackendWriteOp::DeleteBlocksByNumber(5), + ]) + .unwrap(); - assert_eq!( - backend.load_first_block_number().unwrap(), - Some(10), - ); + assert_eq!(backend.load_first_block_number().unwrap(), Some(10),); } #[test] @@ -563,15 +521,15 @@ mod tests { let mut backend = DbBackend::new(db, config); // Prove that it's cheap - assert!( - backend.load_stagnant_at_up_to(Timestamp::max_value()).unwrap().is_empty(), - ); + assert!(backend.load_stagnant_at_up_to(Timestamp::max_value()).unwrap().is_empty(),); - backend.write(vec![ - BackendWriteOp::WriteStagnantAt(2, vec![Hash::repeat_byte(1)]), - BackendWriteOp::WriteStagnantAt(5, vec![Hash::repeat_byte(2)]), - BackendWriteOp::WriteStagnantAt(10, vec![Hash::repeat_byte(3)]), - ]).unwrap(); + backend + .write(vec![ + BackendWriteOp::WriteStagnantAt(2, vec![Hash::repeat_byte(1)]), + BackendWriteOp::WriteStagnantAt(5, vec![Hash::repeat_byte(2)]), + BackendWriteOp::WriteStagnantAt(10, vec![Hash::repeat_byte(3)]), + ]) + .unwrap(); assert_eq!( backend.load_stagnant_at_up_to(Timestamp::max_value()).unwrap(), @@ -593,32 +551,21 @@ mod tests { assert_eq!( backend.load_stagnant_at_up_to(9).unwrap(), - vec![ - (2, vec![Hash::repeat_byte(1)]), - (5, vec![Hash::repeat_byte(2)]), - ] + vec![(2, vec![Hash::repeat_byte(1)]), (5, vec![Hash::repeat_byte(2)]),] ); - backend.write(vec![ - BackendWriteOp::DeleteStagnantAt(2), - ]).unwrap(); + backend.write(vec![BackendWriteOp::DeleteStagnantAt(2)]).unwrap(); assert_eq!( backend.load_stagnant_at_up_to(5).unwrap(), - vec![ - (5, vec![Hash::repeat_byte(2)]), - ] + vec![(5, vec![Hash::repeat_byte(2)]),] ); - backend.write(vec![ - BackendWriteOp::WriteStagnantAt(5, vec![]), - ]).unwrap(); + backend.write(vec![BackendWriteOp::WriteStagnantAt(5, vec![])]).unwrap(); assert_eq!( backend.load_stagnant_at_up_to(10).unwrap(), - vec![ - (10, vec![Hash::repeat_byte(3)]), - ] + vec![(10, vec![Hash::repeat_byte(3)]),] ); } @@ -629,40 +576,29 @@ mod tests { let mut backend = DbBackend::new(db, config); - backend.write(vec![ - BackendWriteOp::WriteBlocksByNumber(2, vec![Hash::repeat_byte(1)]), - BackendWriteOp::WriteBlocksByNumber(5, vec![Hash::repeat_byte(2)]), - BackendWriteOp::WriteBlocksByNumber(10, vec![Hash::repeat_byte(3)]), - ]).unwrap(); + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![Hash::repeat_byte(1)]), + BackendWriteOp::WriteBlocksByNumber(5, vec![Hash::repeat_byte(2)]), + BackendWriteOp::WriteBlocksByNumber(10, vec![Hash::repeat_byte(3)]), + ]) + .unwrap(); - assert_eq!( - backend.load_blocks_by_number(2).unwrap(), - vec![Hash::repeat_byte(1)], - ); + assert_eq!(backend.load_blocks_by_number(2).unwrap(), vec![Hash::repeat_byte(1)],); - assert_eq!( - backend.load_blocks_by_number(3).unwrap(), - vec![], - ); + assert_eq!(backend.load_blocks_by_number(3).unwrap(), vec![],); - backend.write(vec![ - BackendWriteOp::WriteBlocksByNumber(2, vec![]), - BackendWriteOp::DeleteBlocksByNumber(5), - ]).unwrap(); + backend + .write(vec![ + BackendWriteOp::WriteBlocksByNumber(2, vec![]), + BackendWriteOp::DeleteBlocksByNumber(5), + ]) + .unwrap(); - assert_eq!( - backend.load_blocks_by_number(2).unwrap(), - vec![], - ); + assert_eq!(backend.load_blocks_by_number(2).unwrap(), vec![],); - assert_eq!( - backend.load_blocks_by_number(5).unwrap(), - vec![], - ); + assert_eq!(backend.load_blocks_by_number(5).unwrap(), vec![],); - assert_eq!( - backend.load_blocks_by_number(10).unwrap(), - vec![Hash::repeat_byte(3)], - ); + assert_eq!(backend.load_blocks_by_number(10).unwrap(), vec![Hash::repeat_byte(3)],); } } diff --git a/polkadot/node/core/chain-selection/src/lib.rs b/polkadot/node/core/chain-selection/src/lib.rs index 91e766f53df..eb350e24bd5 100644 --- a/polkadot/node/core/chain-selection/src/lib.rs +++ b/polkadot/node/core/chain-selection/src/lib.rs @@ -16,25 +16,24 @@ //! Implements the Chain Selection Subsystem. -use polkadot_primitives::v1::{BlockNumber, Hash, Header, ConsensusLog}; use polkadot_node_primitives::BlockWeight; use polkadot_node_subsystem::{ - overseer, SubsystemContext, SubsystemError, SpawnedSubsystem, - OverseerSignal, FromOverseer, - messages::{ChainSelectionMessage, ChainApiMessage}, errors::ChainApiError, + messages::{ChainApiMessage, ChainSelectionMessage}, + overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, }; +use polkadot_primitives::v1::{BlockNumber, ConsensusLog, Hash, Header}; +use futures::{channel::oneshot, future::Either, prelude::*}; use kvdb::KeyValueDB; use parity_scale_codec::Error as CodecError; -use futures::channel::oneshot; -use futures::future::Either; -use futures::prelude::*; -use std::time::{UNIX_EPOCH, Duration,SystemTime}; -use std::sync::Arc; +use std::{ + sync::Arc, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; -use crate::backend::{Backend, OverlayedBackend, BackendWriteOp}; +use crate::backend::{Backend, BackendWriteOp, OverlayedBackend}; mod backend; mod db_backend; @@ -108,16 +107,19 @@ struct LeafEntry { impl PartialOrd for LeafEntry { fn partial_cmp(&self, other: &Self) -> Option { - let ord = self.weight.cmp(&other.weight) - .then(self.block_number.cmp(&other.block_number)); + let ord = self.weight.cmp(&other.weight).then(self.block_number.cmp(&other.block_number)); - if !matches!(ord, std::cmp::Ordering::Equal) { Some(ord) } else { None } + if !matches!(ord, std::cmp::Ordering::Equal) { + Some(ord) + } else { + None + } } } #[derive(Debug, Default, Clone)] struct LeafEntrySet { - inner: Vec + inner: Vec, } impl LeafEntrySet { @@ -127,14 +129,16 @@ impl LeafEntrySet { Some(i) => { self.inner.remove(i); true - } + }, } } fn insert(&mut self, new: LeafEntry) { let mut pos = None; for (i, e) in self.inner.iter().enumerate() { - if e == &new { return } + if e == &new { + return + } if e < &new { pos = Some(i); break @@ -238,7 +242,7 @@ impl Clock for SystemClock { ); 0 - } + }, } } } @@ -309,10 +313,7 @@ impl ChainSelectionSubsystem { /// Create a new instance of the subsystem with the given config /// and key-value store. pub fn new(config: Config, db: Arc) -> Self { - ChainSelectionSubsystem { - config, - db, - } + ChainSelectionSubsystem { config, db } } } @@ -328,12 +329,7 @@ where ); SpawnedSubsystem { - future: run( - ctx, - backend, - self.config.stagnant_check_interval, - Box::new(SystemClock), - ) + future: run(ctx, backend, self.config.stagnant_check_interval, Box::new(SystemClock)) .map(Ok) .boxed(), name: "chain-selection-subsystem", @@ -346,31 +342,25 @@ async fn run( mut backend: B, stagnant_check_interval: StagnantCheckInterval, clock: Box, -) - where - Context: SubsystemContext, - Context: overseer::SubsystemContext, - B: Backend, +) where + Context: SubsystemContext, + Context: overseer::SubsystemContext, + B: Backend, { loop { - let res = run_iteration( - &mut ctx, - &mut backend, - &stagnant_check_interval, - &*clock, - ).await; + let res = run_iteration(&mut ctx, &mut backend, &stagnant_check_interval, &*clock).await; match res { Err(e) => { e.trace(); if let Error::Subsystem(SubsystemError::Context(_)) = e { - break; + break } - } + }, Ok(()) => { tracing::info!(target: LOG_TARGET, "received `Conclude` signal, exiting"); - break; - } + break + }, } } } @@ -385,12 +375,11 @@ async fn run_iteration( backend: &mut B, stagnant_check_interval: &StagnantCheckInterval, clock: &(dyn Clock + Sync), -) - -> Result<(), Error> - where - Context: SubsystemContext, - Context: overseer::SubsystemContext, - B: Backend, +) -> Result<(), Error> +where + Context: SubsystemContext, + Context: overseer::SubsystemContext, + B: Backend, { let mut stagnant_check_stream = stagnant_check_interval.timeout_stream(); loop { @@ -461,15 +450,11 @@ async fn fetch_finalized( match hash_rx.await?? { None => { - tracing::warn!( - target: LOG_TARGET, - number, - "Missing hash for finalized block number" - ); + tracing::warn!(target: LOG_TARGET, number, "Missing hash for finalized block number"); return Ok(None) - } - Some(h) => Ok(Some((h, number))) + }, + Some(h) => Ok(Some((h, number))), } } @@ -512,13 +497,9 @@ async fn handle_active_leaf( let header = match fetch_header(ctx, hash).await? { None => { - tracing::warn!( - target: LOG_TARGET, - ?hash, - "Missing header for new head", - ); + tracing::warn!(target: LOG_TARGET, ?hash, "Missing header for new head",); return Ok(Vec::new()) - } + }, Some(h) => h, }; @@ -528,7 +509,8 @@ async fn handle_active_leaf( hash, &header, lower_bound, - ).await?; + ) + .await?; let mut overlay = OverlayedBackend::new(backend); @@ -545,8 +527,8 @@ async fn handle_active_leaf( // If we don't know the weight, we can't import the block. // And none of its descendants either. - break; - } + break + }, Some(w) => w, }; @@ -570,7 +552,9 @@ async fn handle_active_leaf( // Ignores logs with number >= the block header number. fn extract_reversion_logs(header: &Header) -> Vec { let number = header.number; - let mut logs = header.digest.logs() + let mut logs = header + .digest + .logs() .iter() .enumerate() .filter_map(|(i, d)| match ConsensusLog::from_digest_item(d) { @@ -584,7 +568,7 @@ fn extract_reversion_logs(header: &Header) -> Vec { ); None - } + }, Ok(Some(ConsensusLog::Revert(b))) if b < number => Some(b), Ok(Some(ConsensusLog::Revert(b))) => { tracing::warn!( @@ -596,7 +580,7 @@ fn extract_reversion_logs(header: &Header) -> Vec { ); None - } + }, Ok(_) => None, }) .collect::>(); @@ -612,27 +596,18 @@ fn handle_finalized_block( finalized_hash: Hash, finalized_number: BlockNumber, ) -> Result<(), Error> { - let ops = crate::tree::finalize_block( - &*backend, - finalized_hash, - finalized_number, - )?.into_write_ops(); + let ops = + crate::tree::finalize_block(&*backend, finalized_hash, finalized_number)?.into_write_ops(); backend.write(ops) } // Handle an approved block event. -fn handle_approved_block( - backend: &mut impl Backend, - approved_block: Hash, -) -> Result<(), Error> { +fn handle_approved_block(backend: &mut impl Backend, approved_block: Hash) -> Result<(), Error> { let ops = { let mut overlay = OverlayedBackend::new(&*backend); - crate::tree::approve_block( - &mut overlay, - approved_block, - )?; + crate::tree::approve_block(&mut overlay, approved_block)?; overlay.into_write_ops() }; @@ -640,15 +615,9 @@ fn handle_approved_block( backend.write(ops) } -fn detect_stagnant( - backend: &mut impl Backend, - now: Timestamp, -) -> Result<(), Error> { +fn detect_stagnant(backend: &mut impl Backend, now: Timestamp) -> Result<(), Error> { let ops = { - let overlay = crate::tree::detect_stagnant( - &*backend, - now, - )?; + let overlay = crate::tree::detect_stagnant(&*backend, now)?; overlay.into_write_ops() }; @@ -662,9 +631,7 @@ async fn load_leaves( ctx: &mut impl SubsystemContext, backend: &impl Backend, ) -> Result, Error> { - let leaves: Vec<_> = backend.load_leaves()? - .into_hashes_descending() - .collect(); + let leaves: Vec<_> = backend.load_leaves()?.into_hashes_descending().collect(); if leaves.is_empty() { Ok(fetch_finalized(ctx).await?.map_or(Vec::new(), |(h, _)| vec![h])) diff --git a/polkadot/node/core/chain-selection/src/tests.rs b/polkadot/node/core/chain-selection/src/tests.rs index 0256412154f..b9130fd2e61 100644 --- a/polkadot/node/core/chain-selection/src/tests.rs +++ b/polkadot/node/core/chain-selection/src/tests.rs @@ -21,22 +21,25 @@ //! test code the ability to wait for write operations to occur. use super::*; -use std::collections::{HashMap, HashSet, BTreeMap}; -use std::sync::{atomic::{Ordering as AtomicOrdering, AtomicU64}, Arc}; +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + sync::{ + atomic::{AtomicU64, Ordering as AtomicOrdering}, + Arc, + }, +}; +use assert_matches::assert_matches; use futures::channel::oneshot; use parity_scale_codec::Encode; use parking_lot::Mutex; use sp_core::testing::TaskExecutor; -use assert_matches::assert_matches; -use polkadot_primitives::v1::{BlakeTwo256, HashT, ConsensusLog}; use polkadot_node_subsystem::{ - messages::AllMessages, - jaeger, - ActiveLeavesUpdate, ActivatedLeaf, LeafStatus, + jaeger, messages::AllMessages, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, }; use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_primitives::v1::{BlakeTwo256, ConsensusLog, HashT}; #[derive(Default)] struct TestBackendInner { @@ -80,10 +83,7 @@ impl TestBackend { // Assert the backend contains only the given blocks and no others. // This does not check the stagnant_at mapping because that is // pruned lazily by the subsystem as opposed to eagerly. - fn assert_contains_only( - &self, - blocks: Vec<(BlockNumber, Hash)>, - ) { + fn assert_contains_only(&self, blocks: Vec<(BlockNumber, Hash)>) { let hashes: Vec<_> = blocks.iter().map(|(_, h)| *h).collect(); let mut by_number: HashMap<_, HashSet<_>> = HashMap::new(); @@ -107,10 +107,7 @@ impl TestBackend { } } - fn assert_stagnant_at_state( - &self, - stagnant_at: Vec<(Timestamp, Vec)>, - ) { + fn assert_stagnant_at_state(&self, stagnant_at: Vec<(Timestamp, Vec)>) { let inner = self.inner.lock(); assert_eq!(inner.stagnant_at.len(), stagnant_at.len()); for (at, hashes) in stagnant_at { @@ -125,9 +122,7 @@ impl TestBackend { impl Default for TestBackend { fn default() -> Self { - TestBackend { - inner: Default::default(), - } + TestBackend { inner: Default::default() } } } @@ -141,20 +136,33 @@ impl Backend for TestBackend { fn load_stagnant_at(&self, timestamp: Timestamp) -> Result, Error> { Ok(self.inner.lock().stagnant_at.get(×tamp).map_or(Vec::new(), |s| s.clone())) } - fn load_stagnant_at_up_to(&self, up_to: Timestamp) - -> Result)>, Error> - { - Ok(self.inner.lock().stagnant_at.range(..=up_to).map(|(t, v)| (*t, v.clone())).collect()) + fn load_stagnant_at_up_to( + &self, + up_to: Timestamp, + ) -> Result)>, Error> { + Ok(self + .inner + .lock() + .stagnant_at + .range(..=up_to) + .map(|(t, v)| (*t, v.clone())) + .collect()) } fn load_first_block_number(&self) -> Result, Error> { Ok(self.inner.lock().blocks_by_number.range(..).map(|(k, _)| *k).next()) } fn load_blocks_by_number(&self, number: BlockNumber) -> Result, Error> { - Ok(self.inner.lock().blocks_by_number.get(&number).map_or(Vec::new(), |v| v.clone())) + Ok(self + .inner + .lock() + .blocks_by_number + .get(&number) + .map_or(Vec::new(), |v| v.clone())) } fn write(&mut self, ops: I) -> Result<(), Error> - where I: IntoIterator + where + I: IntoIterator, { let mut inner = self.inner.lock(); @@ -162,25 +170,25 @@ impl Backend for TestBackend { match op { BackendWriteOp::WriteBlockEntry(entry) => { inner.block_entries.insert(entry.block_hash, entry); - } + }, BackendWriteOp::WriteBlocksByNumber(number, hashes) => { inner.blocks_by_number.insert(number, hashes); - } + }, BackendWriteOp::WriteViableLeaves(leaves) => { inner.leaves = leaves; - } + }, BackendWriteOp::WriteStagnantAt(time, hashes) => { inner.stagnant_at.insert(time, hashes); - } + }, BackendWriteOp::DeleteBlocksByNumber(number) => { inner.blocks_by_number.remove(&number); - } + }, BackendWriteOp::DeleteBlockEntry(hash) => { inner.block_entries.remove(&hash); - } + }, BackendWriteOp::DeleteStagnantAt(time) => { inner.stagnant_at.remove(&time); - } + }, } } @@ -214,8 +222,8 @@ const TEST_STAGNANT_INTERVAL: Duration = Duration::from_millis(20); type VirtualOverseer = test_helpers::TestSubsystemContextHandle; -fn test_harness>( - test: impl FnOnce(TestBackend, TestClock, VirtualOverseer) -> T +fn test_harness>( + test: impl FnOnce(TestBackend, TestClock, VirtualOverseer) -> T, ) { let pool = TaskExecutor::new(); let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool); @@ -296,7 +304,7 @@ fn child_header(parent_number: BlockNumber, parent_hash: Hash) -> Header { number: parent_number + 1, state_root: Default::default(), extrinsics_root: Default::default(), - digest: Default::default() + digest: Default::default(), } } @@ -304,10 +312,7 @@ fn salt_header(header: &mut Header, salt: impl Encode) { header.state_root = BlakeTwo256::hash_of(&salt) } -fn add_reversions( - header: &mut Header, - reversions: impl IntoIterator, -) { +fn add_reversions(header: &mut Header, reversions: impl IntoIterator) { for log in reversions.into_iter().map(ConsensusLog::Revert) { header.digest.logs.push(log.into()) } @@ -349,14 +354,17 @@ async fn import_blocks_into( let (_, write_rx) = backend.await_next_write(); let hash = header.hash(); - virtual_overseer.send(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( - ActivatedLeaf { - hash, - number: header.number, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - } - )).into()).await; + virtual_overseer + .send( + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash, + number: header.number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })) + .into(), + ) + .await; if let Some((f_n, f_h)) = finalized_base.take() { answer_finalized_block_info(virtual_overseer, f_n, f_h).await; @@ -376,14 +384,9 @@ async fn import_chains_into_empty( finalized_hash: Hash, chains: Vec>, ) { - for (i, chain)in chains.into_iter().enumerate() { + for (i, chain) in chains.into_iter().enumerate() { let finalized_base = Some((finalized_number, finalized_hash)).filter(|_| i == 0); - import_blocks_into( - virtual_overseer, - backend, - finalized_base, - chain, - ).await; + import_blocks_into(virtual_overseer, backend, finalized_base, chain).await; } } @@ -409,14 +412,17 @@ async fn import_all_blocks_into( let head_hash = head.hash(); let (_, write_rx) = backend.await_next_write(); - virtual_overseer.send(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( - ActivatedLeaf { - hash: head_hash, - number: head.number, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - } - )).into()).await; + virtual_overseer + .send( + OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: head_hash, + number: head.number, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + })) + .into(), + ) + .await; if let Some((f_n, f_h)) = finalized_base { answer_finalized_block_info(virtual_overseer, f_n, f_h).await; @@ -429,7 +435,9 @@ async fn import_all_blocks_into( // is imported. { let find_block_header = |expected_hash| { - pre_blocks.iter().cloned() + pre_blocks + .iter() + .cloned() .chain(blocks.iter().map(|(h, _)| h.clone())) .find(|hdr| hdr.hash() == expected_hash) .unwrap() @@ -465,12 +473,11 @@ async fn import_all_blocks_into( let prev_response = nth_ancestor_of_head(behind_head); assert_eq!(h, prev_response.hash()); - let _ = tx.send(Ok( - (0..k as usize).map(|n| n + behind_head + 1) - .map(nth_ancestor_of_head) - .map(|h| h.hash()) - .collect() - )); + let _ = tx.send(Ok((0..k as usize) + .map(|n| n + behind_head + 1) + .map(nth_ancestor_of_head) + .map(|h| h.hash()) + .collect())); for _ in 0..k { assert_matches!( @@ -483,7 +490,7 @@ async fn import_all_blocks_into( } behind_head = behind_head + k as usize; - } + }, AllMessages::ChainApi(ChainApiMessage::BlockHeader(h, tx)) => { let header = find_block_header(h); let _ = tx.send(Ok(Some(header))); @@ -491,14 +498,16 @@ async fn import_all_blocks_into( // Assuming that `determine_new_blocks` uses these // instead of ancestry: 1. behind_head += 1; - } + }, AllMessages::ChainApi(ChainApiMessage::BlockWeight(h, tx)) => { let (_, weight) = blocks.iter().find(|(hdr, _)| hdr.hash() == h).unwrap(); let _ = tx.send(Ok(Some(*weight))); // Last weight has been returned. Time to go. - if h == head_hash { break } - } + if h == head_hash { + break + } + }, _ => panic!("unexpected message"), } } @@ -514,16 +523,17 @@ async fn finalize_block( ) { let (_, write_tx) = backend.await_next_write(); - virtual_overseer.send( - OverseerSignal::BlockFinalized(block_hash, block_number).into() - ).await; + virtual_overseer + .send(OverseerSignal::BlockFinalized(block_hash, block_number).into()) + .await; write_tx.await.unwrap(); } -fn extract_info_from_chain(i: usize, chain: &[(Header, BlockWeight)]) - -> (BlockNumber, Hash, BlockWeight) -{ +fn extract_info_from_chain( + i: usize, + chain: &[(Header, BlockWeight)], +) -> (BlockNumber, Hash, BlockWeight) { let &(ref header, weight) = &chain[i]; (header.number, header.hash(), weight) @@ -541,46 +551,35 @@ fn assert_backend_contains<'a>( header.number, hash, ); - assert!( - backend.load_block_entry(&hash).unwrap().is_some(), - "no entry found for {}", - hash, - ); + assert!(backend.load_block_entry(&hash).unwrap().is_some(), "no entry found for {}", hash,); } } -fn assert_backend_contains_chains( - backend: &TestBackend, - chains: Vec>, -) { +fn assert_backend_contains_chains(backend: &TestBackend, chains: Vec>) { for chain in chains { - assert_backend_contains( - backend, - chain.iter().map(|&(ref hdr, _)| hdr) - ) + assert_backend_contains(backend, chain.iter().map(|&(ref hdr, _)| hdr)) } } -fn assert_leaves( - backend: &TestBackend, - leaves: Vec, -) { +fn assert_leaves(backend: &TestBackend, leaves: Vec) { assert_eq!( - backend.load_leaves().unwrap().into_hashes_descending().into_iter().collect::>(), + backend + .load_leaves() + .unwrap() + .into_hashes_descending() + .into_iter() + .collect::>(), leaves, ); } -async fn assert_leaves_query( - virtual_overseer: &mut VirtualOverseer, - leaves: Vec, -) { +async fn assert_leaves_query(virtual_overseer: &mut VirtualOverseer, leaves: Vec) { assert!(!leaves.is_empty(), "empty leaves impossible. answer finalized query"); let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: ChainSelectionMessage::Leaves(tx) - }).await; + virtual_overseer + .send(FromOverseer::Communication { msg: ChainSelectionMessage::Leaves(tx) }) + .await; assert_eq!(rx.await.unwrap(), leaves); } @@ -591,9 +590,9 @@ async fn assert_finalized_leaves_query( finalized_hash: Hash, ) { let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: ChainSelectionMessage::Leaves(tx) - }).await; + virtual_overseer + .send(FromOverseer::Communication { msg: ChainSelectionMessage::Leaves(tx) }) + .await; answer_finalized_block_info(virtual_overseer, finalized_number, finalized_hash).await; @@ -605,9 +604,11 @@ async fn best_leaf_containing( required: Hash, ) -> Option { let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: ChainSelectionMessage::BestLeafContaining(required, tx) - }).await; + virtual_overseer + .send(FromOverseer::Communication { + msg: ChainSelectionMessage::BestLeafContaining(required, tx), + }) + .await; rx.await.unwrap() } @@ -618,9 +619,9 @@ async fn approve_block( approved: Hash, ) { let (_, write_rx) = backend.await_next_write(); - virtual_overseer.send(FromOverseer::Communication { - msg: ChainSelectionMessage::Approved(approved) - }).await; + virtual_overseer + .send(FromOverseer::Communication { msg: ChainSelectionMessage::Approved(approved) }) + .await; write_rx.await.unwrap() } @@ -646,7 +647,8 @@ fn import_direct_child_of_finalized_on_empty() { &backend, Some((finalized_number, finalized_hash)), vec![(child.clone(), child_weight)], - ).await; + ) + .await; assert_eq!(backend.load_first_block_number().unwrap().unwrap(), child_number); assert_backend_contains(&backend, &[child]); @@ -663,19 +665,16 @@ fn import_chain_on_finalized_incrementally() { let finalized_number = 0; let finalized_hash = Hash::repeat_byte(0); - let (head_hash, chain) = construct_chain_on_base( - vec![1, 2, 3, 4, 5], - finalized_number, - finalized_hash, - |_| {} - ); + let (head_hash, chain) = + construct_chain_on_base(vec![1, 2, 3, 4, 5], finalized_number, finalized_hash, |_| {}); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain.clone(), - ).await; + ) + .await; assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); assert_backend_contains(&backend, chain.iter().map(|&(ref h, _)| h)); @@ -692,33 +691,23 @@ fn import_two_subtrees_on_finalized() { let finalized_number = 0; let finalized_hash = Hash::repeat_byte(0); - let (a_hash, chain_a) = construct_chain_on_base( - vec![1], - finalized_number, - finalized_hash, - |_| {} - ); + let (a_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |_| {}); - let (b_hash, chain_b) = construct_chain_on_base( - vec![2], - finalized_number, - finalized_hash, - |h| salt_header(h, b"b"), - ); + let (b_hash, chain_b) = + construct_chain_on_base(vec![2], finalized_number, finalized_hash, |h| { + salt_header(h, b"b") + }); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_b.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); @@ -736,33 +725,23 @@ fn import_two_subtrees_on_nonzero_finalized() { let finalized_number = 100; let finalized_hash = Hash::repeat_byte(0); - let (a_hash, chain_a) = construct_chain_on_base( - vec![1], - finalized_number, - finalized_hash, - |_| {} - ); + let (a_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |_| {}); - let (b_hash, chain_b) = construct_chain_on_base( - vec![2], - finalized_number, - finalized_hash, - |h| salt_header(h, b"b"), - ); + let (b_hash, chain_b) = + construct_chain_on_base(vec![2], finalized_number, finalized_hash, |h| { + salt_header(h, b"b") + }); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_b.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 101); assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); @@ -786,28 +765,18 @@ fn leaves_ordered_by_weight_and_then_number() { // // expected_leaves: [(C2, 3), (A3, 2), (B2, 2)] - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 1, 2], - finalized_number, - finalized_hash, - |_| {} - ); + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 1, 2], finalized_number, finalized_hash, |_| {}); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); - let (b2_hash, chain_b) = construct_chain_on_base( - vec![2], - 1, - a1_hash, - |h| salt_header(h, b"b"), - ); + let (b2_hash, chain_b) = + construct_chain_on_base(vec![2], 1, a1_hash, |h| salt_header(h, b"b")); - let (c2_hash, chain_c) = construct_chain_on_base( - vec![1, 3], - finalized_number, - finalized_hash, - |h| salt_header(h, b"c"), - ); + let (c2_hash, chain_c) = + construct_chain_on_base(vec![1, 3], finalized_number, finalized_hash, |h| { + salt_header(h, b"c") + }); import_chains_into_empty( &mut virtual_overseer, @@ -815,7 +784,8 @@ fn leaves_ordered_by_weight_and_then_number() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone(), chain_c.clone()], - ).await; + ) + .await; assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); @@ -836,21 +806,13 @@ fn subtrees_imported_even_with_gaps() { // F <- A1 <- A2 <- A3 // A2 <- B3 <- B4 <- B5 - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |_| {} - ); + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |_| {}); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); - let (b5_hash, chain_b) = construct_chain_on_base( - vec![4, 4, 5], - 2, - a2_hash, - |h| salt_header(h, b"b"), - ); + let (b5_hash, chain_b) = + construct_chain_on_base(vec![4, 4, 5], 2, a2_hash, |h| salt_header(h, b"b")); import_all_blocks_into( &mut virtual_overseer, @@ -858,7 +820,8 @@ fn subtrees_imported_even_with_gaps() { Some((finalized_number, finalized_hash)), Vec::new(), chain_a.clone(), - ).await; + ) + .await; import_all_blocks_into( &mut virtual_overseer, @@ -866,7 +829,8 @@ fn subtrees_imported_even_with_gaps() { None, vec![chain_a[0].0.clone(), chain_a[1].0.clone()], chain_b.clone(), - ).await; + ) + .await; assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 1); assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); @@ -888,27 +852,25 @@ fn reversion_removes_viability_of_chain() { // // A3 reverts A1 - let (_a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| if h.number == 3 { add_reversions(h, Some(1)) } - ); + let (_a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 3 { + add_reversions(h, Some(1)) + } + }); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); assert_leaves(&backend, vec![]); - assert_finalized_leaves_query( - &mut virtual_overseer, - finalized_number, - finalized_hash, - ).await; + assert_finalized_leaves_query(&mut virtual_overseer, finalized_number, finalized_hash) + .await; virtual_overseer }); @@ -924,12 +886,12 @@ fn reversion_removes_viability_and_finds_ancestor_as_leaf() { // // A3 reverts A2 - let (_a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| if h.number == 3 { add_reversions(h, Some(2)) } - ); + let (_a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 3 { + add_reversions(h, Some(2)) + } + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); @@ -938,7 +900,8 @@ fn reversion_removes_viability_and_finds_ancestor_as_leaf() { &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); assert_leaves(&backend, vec![a1_hash]); @@ -959,53 +922,32 @@ fn ancestor_of_unviable_is_not_leaf_if_has_children() { // // A3 reverts A2 - let (a2_hash, chain_a) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |_| {} - ); + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |_| {}); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); - let (_a3_hash, chain_a_ext) = construct_chain_on_base( - vec![3], - 2, - a2_hash, - |h| add_reversions(h, Some(2)), - ); + let (_a3_hash, chain_a_ext) = + construct_chain_on_base(vec![3], 2, a2_hash, |h| add_reversions(h, Some(2))); - let (b2_hash, chain_b) = construct_chain_on_base( - vec![1], - 1, - a1_hash, - |h| salt_header(h, b"b") - ); + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1], 1, a1_hash, |h| salt_header(h, b"b")); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_b.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); assert_backend_contains(&backend, chain_b.iter().map(|&(ref h, _)| h)); assert_leaves(&backend, vec![a2_hash, b2_hash]); - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_a_ext.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); assert_backend_contains(&backend, chain_a_ext.iter().map(|&(ref h, _)| h)); @@ -1027,19 +969,20 @@ fn self_and_future_reversions_are_ignored() { // // A3 reverts itself and future blocks. ignored. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| if h.number == 3 { add_reversions(h, vec![3, 4, 100]) } - ); + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 3 { + add_reversions(h, vec![3, 4, 100]) + } + }); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); assert_leaves(&backend, vec![a3_hash]); @@ -1059,19 +1002,20 @@ fn revert_finalized_is_ignored() { // // A3 reverts itself and future blocks. ignored. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| if h.number == 13 { add_reversions(h, vec![10, 9, 8, 0, 1]) } - ); + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { + if h.number == 13 { + add_reversions(h, vec![10, 9, 8, 0, 1]) + } + }); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); assert_leaves(&backend, vec![a3_hash]); @@ -1092,43 +1036,30 @@ fn reversion_affects_viability_of_all_subtrees() { // // B4 reverts A2. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |_| {} - ); + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |_| {}); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); - let (_b4_hash, chain_b) = construct_chain_on_base( - vec![3, 4], - 2, - a2_hash, - |h| { - salt_header(h, b"b"); - if h.number == 4 { - add_reversions(h, Some(2)); - } + let (_b4_hash, chain_b) = construct_chain_on_base(vec![3, 4], 2, a2_hash, |h| { + salt_header(h, b"b"); + if h.number == 4 { + add_reversions(h, Some(2)); } - ); + }); import_blocks_into( &mut virtual_overseer, &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; assert_leaves(&backend, vec![a3_hash]); - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_b.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_b.clone()).await; assert_backend_contains(&backend, chain_a.iter().map(|&(ref h, _)| h)); assert_backend_contains(&backend, chain_b.iter().map(|&(ref h, _)| h)); @@ -1153,44 +1084,28 @@ fn finalize_viable_prunes_subtrees() { // // Finalize A2. Only A2, A3, and X3 should remain. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 10], - finalized_number, - finalized_hash, - |h| salt_header(h, b"a"), - ); + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 10], finalized_number, finalized_hash, |h| { + salt_header(h, b"a") + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); - let (x3_hash, chain_x) = construct_chain_on_base( - vec![3], - 2, - a2_hash, - |h| salt_header(h, b"x"), - ); + let (x3_hash, chain_x) = + construct_chain_on_base(vec![3], 2, a2_hash, |h| salt_header(h, b"x")); - let (b2_hash, chain_b) = construct_chain_on_base( - vec![6], - 1, - a1_hash, - |h| salt_header(h, b"b"), - ); + let (b2_hash, chain_b) = + construct_chain_on_base(vec![6], 1, a1_hash, |h| salt_header(h, b"b")); - let (c3_hash, chain_c) = construct_chain_on_base( - vec![1, 2, 8], - finalized_number, - finalized_hash, - |h| salt_header(h, b"c"), - ); + let (c3_hash, chain_c) = + construct_chain_on_base(vec![1, 2, 8], finalized_number, finalized_hash, |h| { + salt_header(h, b"c") + }); let (_, c2_hash, _) = extract_info_from_chain(1, &chain_c); - let (d3_hash, chain_d) = construct_chain_on_base( - vec![7], - 2, - c2_hash, - |h| salt_header(h, b"d"), - ); + let (d3_hash, chain_d) = + construct_chain_on_base(vec![7], 2, c2_hash, |h| salt_header(h, b"d")); let all_chains = vec![ chain_a.clone(), @@ -1206,42 +1121,26 @@ fn finalize_viable_prunes_subtrees() { finalized_number, finalized_hash, all_chains.clone(), - ).await; + ) + .await; - assert_backend_contains_chains( - &backend, - all_chains.clone(), - ); + assert_backend_contains_chains(&backend, all_chains.clone()); assert_leaves(&backend, vec![a3_hash, c3_hash, d3_hash, b2_hash, x3_hash]); // Finalize block A2. Now lots of blocks should go missing. - finalize_block( - &mut virtual_overseer, - &backend, - 2, - a2_hash, - ).await; + finalize_block(&mut virtual_overseer, &backend, 2, a2_hash).await; // A2 <- A3 // A2 <- X3 - backend.assert_contains_only(vec![ - (3, a3_hash), - (3, x3_hash), - ]); + backend.assert_contains_only(vec![(3, a3_hash), (3, x3_hash)]); assert_leaves(&backend, vec![a3_hash, x3_hash]); assert_leaves_query(&mut virtual_overseer, vec![a3_hash, x3_hash]).await; - assert_eq!( - backend.load_first_block_number().unwrap().unwrap(), - 3, - ); + assert_eq!(backend.load_first_block_number().unwrap().unwrap(), 3,); - assert_eq!( - backend.load_blocks_by_number(3).unwrap(), - vec![a3_hash, x3_hash], - ); + assert_eq!(backend.load_blocks_by_number(3).unwrap(), vec![a3_hash, x3_hash],); virtual_overseer }); @@ -1257,17 +1156,13 @@ fn finalization_does_not_clobber_unviability() { // A3 reverts A2. // Finalize A1. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 10], - finalized_number, - finalized_hash, - |h| { + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 10], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); if h.number == 3 { add_reversions(h, Some(2)); } - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); @@ -1277,25 +1172,14 @@ fn finalization_does_not_clobber_unviability() { &backend, Some((finalized_number, finalized_hash)), chain_a.clone(), - ).await; + ) + .await; - finalize_block( - &mut virtual_overseer, - &backend, - 1, - a1_hash, - ).await; + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; assert_leaves(&backend, vec![]); - assert_finalized_leaves_query( - &mut virtual_overseer, - 1, - a1_hash, - ).await; - backend.assert_contains_only(vec![ - (3, a3_hash), - (2, a2_hash), - ]); + assert_finalized_leaves_query(&mut virtual_overseer, 1, a1_hash).await; + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash)]); virtual_overseer }); @@ -1313,27 +1197,19 @@ fn finalization_erases_unviable() { // A2 reverts A1. // Finalize A1. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| { + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); if h.number == 2 { add_reversions(h, Some(1)); } - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); - let (b2_hash, chain_b) = construct_chain_on_base( - vec![1], - 1, - a1_hash, - |h| salt_header(h, b"b"), - ); + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1], 1, a1_hash, |h| salt_header(h, b"b")); import_chains_into_empty( &mut virtual_overseer, @@ -1341,25 +1217,17 @@ fn finalization_erases_unviable() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone()], - ).await; + ) + .await; assert_leaves(&backend, vec![]); - finalize_block( - &mut virtual_overseer, - &backend, - 1, - a1_hash, - ).await; + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; assert_leaves(&backend, vec![a3_hash, b2_hash]); assert_leaves_query(&mut virtual_overseer, vec![a3_hash, b2_hash]).await; - backend.assert_contains_only(vec![ - (3, a3_hash), - (2, a2_hash), - (2, b2_hash), - ]); + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash), (2, b2_hash)]); virtual_overseer }); @@ -1378,11 +1246,8 @@ fn finalize_erases_unviable_but_keeps_later_unviability() { // A3 reverts A2. // Finalize A1. A2 is stil unviable, but B2 is viable. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| { + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); if h.number == 2 { add_reversions(h, Some(1)); @@ -1390,18 +1255,13 @@ fn finalize_erases_unviable_but_keeps_later_unviability() { if h.number == 3 { add_reversions(h, Some(2)); } - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); - let (b2_hash, chain_b) = construct_chain_on_base( - vec![1], - 1, - a1_hash, - |h| salt_header(h, b"b"), - ); + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1], 1, a1_hash, |h| salt_header(h, b"b")); import_chains_into_empty( &mut virtual_overseer, @@ -1409,25 +1269,17 @@ fn finalize_erases_unviable_but_keeps_later_unviability() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone()], - ).await; + ) + .await; assert_leaves(&backend, vec![]); - finalize_block( - &mut virtual_overseer, - &backend, - 1, - a1_hash, - ).await; + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; assert_leaves(&backend, vec![b2_hash]); assert_leaves_query(&mut virtual_overseer, vec![b2_hash]).await; - backend.assert_contains_only(vec![ - (3, a3_hash), - (2, a2_hash), - (2, b2_hash), - ]); + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash), (2, b2_hash)]); virtual_overseer }); @@ -1444,18 +1296,14 @@ fn finalize_erases_unviable_from_one_but_not_all_reverts() { // A3 reverts A2 and A1. // Finalize A1. A2 is stil unviable. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| { + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); if h.number == 3 { add_reversions(h, Some(1)); add_reversions(h, Some(2)); } - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); @@ -1466,28 +1314,17 @@ fn finalize_erases_unviable_from_one_but_not_all_reverts() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; assert_leaves(&backend, vec![]); - finalize_block( - &mut virtual_overseer, - &backend, - 1, - a1_hash, - ).await; + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; assert_leaves(&backend, vec![]); - assert_finalized_leaves_query( - &mut virtual_overseer, - 1, - a1_hash, - ).await; + assert_finalized_leaves_query(&mut virtual_overseer, 1, a1_hash).await; - backend.assert_contains_only(vec![ - (3, a3_hash), - (2, a2_hash), - ]); + backend.assert_contains_only(vec![(3, a3_hash), (2, a2_hash)]); virtual_overseer }); @@ -1505,34 +1342,22 @@ fn finalize_triggers_viability_search() { // A3 reverts A1. // Finalize A1. A3, B3, and C3 are all viable now. - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| { + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); if h.number == 3 { add_reversions(h, Some(1)); } - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); - let (b3_hash, chain_b) = construct_chain_on_base( - vec![4], - 2, - a2_hash, - |h| salt_header(h, b"b"), - ); + let (b3_hash, chain_b) = + construct_chain_on_base(vec![4], 2, a2_hash, |h| salt_header(h, b"b")); - let (c3_hash, chain_c) = construct_chain_on_base( - vec![5], - 2, - a2_hash, - |h| salt_header(h, b"c"), - ); + let (c3_hash, chain_c) = + construct_chain_on_base(vec![5], 2, a2_hash, |h| salt_header(h, b"c")); import_chains_into_empty( &mut virtual_overseer, @@ -1540,26 +1365,17 @@ fn finalize_triggers_viability_search() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone(), chain_c.clone()], - ).await; + ) + .await; assert_leaves(&backend, vec![]); - finalize_block( - &mut virtual_overseer, - &backend, - 1, - a1_hash, - ).await; + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; assert_leaves(&backend, vec![c3_hash, b3_hash, a3_hash]); assert_leaves_query(&mut virtual_overseer, vec![c3_hash, b3_hash, a3_hash]).await; - backend.assert_contains_only(vec![ - (3, a3_hash), - (3, b3_hash), - (3, c3_hash), - (2, a2_hash), - ]); + backend.assert_contains_only(vec![(3, a3_hash), (3, b3_hash), (3, c3_hash), (2, a2_hash)]); virtual_overseer }); @@ -1567,7 +1383,7 @@ fn finalize_triggers_viability_search() { #[test] fn best_leaf_none_with_empty_db() { - test_harness(|_backend, _, mut virtual_overseer| async move { + test_harness(|_backend, _, mut virtual_overseer| async move { let required = Hash::repeat_byte(1); let best_leaf = best_leaf_containing(&mut virtual_overseer, required).await; assert!(best_leaf.is_none()); @@ -1586,17 +1402,13 @@ fn best_leaf_none_with_no_viable_leaves() { // // A2 reverts A1. - let (a2_hash, chain_a) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); if h.number == 2 { add_reversions(h, Some(1)); } - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); @@ -1606,7 +1418,8 @@ fn best_leaf_none_with_no_viable_leaves() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; let best_leaf = best_leaf_containing(&mut virtual_overseer, a2_hash).await; assert!(best_leaf.is_none()); @@ -1626,14 +1439,10 @@ fn best_leaf_none_with_unknown_required() { // F <- A1 <- A2 - let (_a2_hash, chain_a) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (_a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); let unknown_hash = Hash::repeat_byte(0x69); @@ -1643,7 +1452,8 @@ fn best_leaf_none_with_unknown_required() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; let best_leaf = best_leaf_containing(&mut virtual_overseer, unknown_hash).await; assert!(best_leaf.is_none()); @@ -1663,28 +1473,20 @@ fn best_leaf_none_with_unviable_required() { // // A2 reverts A1. - let (a2_hash, chain_a) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); if h.number == 2 { add_reversions(h, Some(1)); } - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); - let (_b2_hash, chain_b) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (_b2_hash, chain_b) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"b"); - } - ); + }); import_chains_into_empty( &mut virtual_overseer, @@ -1692,7 +1494,8 @@ fn best_leaf_none_with_unviable_required() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone()], - ).await; + ) + .await; let best_leaf = best_leaf_containing(&mut virtual_overseer, a2_hash).await; assert!(best_leaf.is_none()); @@ -1715,23 +1518,15 @@ fn best_leaf_with_finalized_required() { // // B2 > A2 - let (_a2_hash, chain_a) = construct_chain_on_base( - vec![1, 1], - finalized_number, - finalized_hash, - |h| { + let (_a2_hash, chain_a) = + construct_chain_on_base(vec![1, 1], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); - let (b2_hash, chain_b) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (b2_hash, chain_b) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"b"); - } - ); + }); import_chains_into_empty( &mut virtual_overseer, @@ -1739,7 +1534,8 @@ fn best_leaf_with_finalized_required() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone()], - ).await; + ) + .await; let best_leaf = best_leaf_containing(&mut virtual_overseer, finalized_hash).await; assert_eq!(best_leaf, Some(b2_hash)); @@ -1759,25 +1555,17 @@ fn best_leaf_with_unfinalized_required() { // // B2 > A2 - let (a2_hash, chain_a) = construct_chain_on_base( - vec![1, 1], - finalized_number, - finalized_hash, - |h| { + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 1], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); - let (_b2_hash, chain_b) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (_b2_hash, chain_b) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"b"); - } - ); + }); import_chains_into_empty( &mut virtual_overseer, @@ -1785,7 +1573,8 @@ fn best_leaf_with_unfinalized_required() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone()], - ).await; + ) + .await; let best_leaf = best_leaf_containing(&mut virtual_overseer, a1_hash).await; assert_eq!(best_leaf, Some(a2_hash)); @@ -1806,36 +1595,22 @@ fn best_leaf_ancestor_of_all_leaves() { // // C3 > B3 > A3 - let (_a3_hash, chain_a) = construct_chain_on_base( - vec![1, 1, 2], - finalized_number, - finalized_hash, - |h| { + let (_a3_hash, chain_a) = + construct_chain_on_base(vec![1, 1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); - let (_b3_hash, chain_b) = construct_chain_on_base( - vec![2, 3], - 1, - a1_hash, - |h| { - salt_header(h, b"b"); - } - ); + let (_b3_hash, chain_b) = construct_chain_on_base(vec![2, 3], 1, a1_hash, |h| { + salt_header(h, b"b"); + }); let (_, b2_hash, _) = extract_info_from_chain(0, &chain_b); - let (c3_hash, chain_c) = construct_chain_on_base( - vec![4], - 2, - b2_hash, - |h| { - salt_header(h, b"c"); - } - ); + let (c3_hash, chain_c) = construct_chain_on_base(vec![4], 2, b2_hash, |h| { + salt_header(h, b"c"); + }); import_chains_into_empty( &mut virtual_overseer, @@ -1843,7 +1618,8 @@ fn best_leaf_ancestor_of_all_leaves() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone(), chain_c.clone()], - ).await; + ) + .await; let best_leaf = best_leaf_containing(&mut virtual_overseer, a1_hash).await; assert_eq!(best_leaf, Some(c3_hash)); @@ -1860,14 +1636,10 @@ fn approve_message_approves_block_entry() { // F <- A1 <- A2 <- A3 - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| { + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); @@ -1878,7 +1650,8 @@ fn approve_message_approves_block_entry() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; approve_block(&mut virtual_overseer, &backend, a3_hash).await; @@ -1910,14 +1683,10 @@ fn approve_nonexistent_has_no_effect() { // F <- A1 <- A2 <- A3 - let (a3_hash, chain_a) = construct_chain_on_base( - vec![1, 2, 3], - finalized_number, - finalized_hash, - |h| { + let (a3_hash, chain_a) = + construct_chain_on_base(vec![1, 2, 3], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); let (_, a2_hash, _) = extract_info_from_chain(1, &chain_a); @@ -1928,7 +1697,8 @@ fn approve_nonexistent_has_no_effect() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; let nonexistent = Hash::repeat_byte(1); approve_block(&mut virtual_overseer, &backend, nonexistent).await; @@ -1961,23 +1731,14 @@ fn block_has_correct_stagnant_at() { // F <- A1 <- A2 - let (a1_hash, chain_a) = construct_chain_on_base( - vec![1], - finalized_number, - finalized_hash, - |h| { + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); - let (a2_hash, chain_a_ext) = construct_chain_on_base( - vec![1], - 1, - a1_hash, - |h| { - salt_header(h, b"a"); - } - ); + let (a2_hash, chain_a_ext) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"a"); + }); import_chains_into_empty( &mut virtual_overseer, @@ -1985,16 +1746,12 @@ fn block_has_correct_stagnant_at() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; clock.inc_by(1); - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_a_ext.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; backend.assert_stagnant_at_state(vec![ (STAGNANT_TIMEOUT, vec![a1_hash]), @@ -2013,14 +1770,10 @@ fn detects_stagnant() { // F <- A1 - let (a1_hash, chain_a) = construct_chain_on_base( - vec![1], - finalized_number, - finalized_hash, - |h| { + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); import_chains_into_empty( &mut virtual_overseer, @@ -2028,7 +1781,8 @@ fn detects_stagnant() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; { let (_, write_rx) = backend.await_next_write(); @@ -2058,23 +1812,14 @@ fn finalize_stagnant_unlocks_subtree() { // F <- A1 <- A2 - let (a1_hash, chain_a) = construct_chain_on_base( - vec![1], - finalized_number, - finalized_hash, - |h| { + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); - let (a2_hash, chain_a_ext) = construct_chain_on_base( - vec![1], - 1, - a1_hash, - |h| { - salt_header(h, b"a"); - } - ); + let (a2_hash, chain_a_ext) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"a"); + }); import_chains_into_empty( &mut virtual_overseer, @@ -2082,16 +1827,12 @@ fn finalize_stagnant_unlocks_subtree() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; clock.inc_by(1); - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_a_ext.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; { let (_, write_rx) = backend.await_next_write(); @@ -2109,12 +1850,7 @@ fn finalize_stagnant_unlocks_subtree() { assert_leaves(&backend, vec![]); - finalize_block( - &mut virtual_overseer, - &backend, - 1, - a1_hash, - ).await; + finalize_block(&mut virtual_overseer, &backend, 1, a1_hash).await; assert_leaves(&backend, vec![a2_hash]); @@ -2130,23 +1866,14 @@ fn approval_undoes_stagnant_unlocking_subtree() { // F <- A1 <- A2 - let (a1_hash, chain_a) = construct_chain_on_base( - vec![1], - finalized_number, - finalized_hash, - |h| { + let (a1_hash, chain_a) = + construct_chain_on_base(vec![1], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); - let (a2_hash, chain_a_ext) = construct_chain_on_base( - vec![1], - 1, - a1_hash, - |h| { - salt_header(h, b"a"); - } - ); + let (a2_hash, chain_a_ext) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"a"); + }); import_chains_into_empty( &mut virtual_overseer, @@ -2154,16 +1881,12 @@ fn approval_undoes_stagnant_unlocking_subtree() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; clock.inc_by(1); - import_blocks_into( - &mut virtual_overseer, - &backend, - None, - chain_a_ext.clone(), - ).await; + import_blocks_into(&mut virtual_overseer, &backend, None, chain_a_ext.clone()).await; { let (_, write_rx) = backend.await_next_write(); @@ -2174,11 +1897,7 @@ fn approval_undoes_stagnant_unlocking_subtree() { backend.assert_stagnant_at_state(vec![(STAGNANT_TIMEOUT + 1, vec![a2_hash])]); - approve_block( - &mut virtual_overseer, - &backend, - a1_hash, - ).await; + approve_block(&mut virtual_overseer, &backend, a1_hash).await; assert_matches!( backend.load_block_entry(&a1_hash).unwrap().unwrap().viability.approval, @@ -2200,25 +1919,16 @@ fn stagnant_preserves_parents_children() { // F <- A1 <- A2 // A1 <- B2 - let (a2_hash, chain_a) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); - let (b2_hash, chain_b) = construct_chain_on_base( - vec![1], - 1, - a1_hash, - |h| { - salt_header(h, b"b"); - } - ); + let (b2_hash, chain_b) = construct_chain_on_base(vec![1], 1, a1_hash, |h| { + salt_header(h, b"b"); + }); import_chains_into_empty( &mut virtual_overseer, @@ -2226,7 +1936,8 @@ fn stagnant_preserves_parents_children() { finalized_number, finalized_hash, vec![chain_a.clone(), chain_b.clone()], - ).await; + ) + .await; approve_block(&mut virtual_overseer, &backend, a1_hash).await; approve_block(&mut virtual_overseer, &backend, b2_hash).await; @@ -2255,14 +1966,10 @@ fn stagnant_makes_childless_parent_leaf() { // F <- A1 <- A2 - let (a2_hash, chain_a) = construct_chain_on_base( - vec![1, 2], - finalized_number, - finalized_hash, - |h| { + let (a2_hash, chain_a) = + construct_chain_on_base(vec![1, 2], finalized_number, finalized_hash, |h| { salt_header(h, b"a"); - } - ); + }); let (_, a1_hash, _) = extract_info_from_chain(0, &chain_a); @@ -2272,7 +1979,8 @@ fn stagnant_makes_childless_parent_leaf() { finalized_number, finalized_hash, vec![chain_a.clone()], - ).await; + ) + .await; approve_block(&mut virtual_overseer, &backend, a1_hash).await; diff --git a/polkadot/node/core/chain-selection/src/tree.rs b/polkadot/node/core/chain-selection/src/tree.rs index ff3db9e9e4a..e797ef992ca 100644 --- a/polkadot/node/core/chain-selection/src/tree.rs +++ b/polkadot/node/core/chain-selection/src/tree.rs @@ -23,17 +23,12 @@ //! Each direct descendant of the finalized block acts as its own sub-tree, //! and as the finalized block advances, orphaned sub-trees are entirely pruned. -use polkadot_primitives::v1::{BlockNumber, Hash}; use polkadot_node_primitives::BlockWeight; - +use polkadot_primitives::v1::{BlockNumber, Hash}; use std::collections::HashMap; -use super::{ - LOG_TARGET, - Approval, BlockEntry, Error, LeafEntry, ViabilityCriteria, - Timestamp, -}; +use super::{Approval, BlockEntry, Error, LeafEntry, Timestamp, ViabilityCriteria, LOG_TARGET}; use crate::backend::{Backend, OverlayedBackend}; // A viability update to be applied to a block. @@ -43,10 +38,7 @@ impl ViabilityUpdate { // Apply the viability update to a single block, yielding the updated // block entry along with a vector of children and the updates to apply // to them. - fn apply(self, mut entry: BlockEntry) -> ( - BlockEntry, - Vec<(Hash, ViabilityUpdate)> - ) { + fn apply(self, mut entry: BlockEntry) -> (BlockEntry, Vec<(Hash, ViabilityUpdate)>) { // 1. When an ancestor has changed from unviable to viable, // we erase the `earliest_unviable_ancestor` of all descendants // until encountering a explicitly unviable descendant D. @@ -81,7 +73,9 @@ impl ViabilityUpdate { }; entry.viability.earliest_unviable_ancestor = maybe_earliest_unviable; - let recurse = entry.children.iter() + let recurse = entry + .children + .iter() .cloned() .map(move |c| (c, ViabilityUpdate(next_earliest_unviable))) .collect(); @@ -152,10 +146,10 @@ fn propagate_viability_update( "Missing expected block entry" ); - continue; - } + continue + }, Some(entry) => entry, - } + }, }; let (new_entry, children) = update.apply(entry); @@ -184,9 +178,8 @@ fn propagate_viability_update( backend.write_block_entry(new_entry); - tree_frontier.extend( - children.into_iter().map(|(h, update)| (BlockEntryRef::Hash(h), update)) - ); + tree_frontier + .extend(children.into_iter().map(|(h, update)| (BlockEntryRef::Hash(h), update))); } // Revisit the viability pivots now that we've traversed the entire subtree. @@ -229,12 +222,11 @@ fn propagate_viability_update( // Furthermore, if the set of viable leaves is empty, the // finalized block is implicitly the viable leaf. continue - } - Some(entry) => { + }, + Some(entry) => if entry.children.len() == pivot_count { viable_leaves.insert(entry.leaf_entry()); - } - } + }, } } @@ -254,12 +246,7 @@ pub(crate) fn import_block( stagnant_at: Timestamp, ) -> Result<(), Error> { add_block(backend, block_hash, block_number, parent_hash, weight, stagnant_at)?; - apply_reversions( - backend, - block_hash, - block_number, - reversion_logs, - )?; + apply_reversions(backend, block_hash, block_number, reversion_logs)?; Ok(()) } @@ -276,7 +263,9 @@ fn load_ancestor( block_number: BlockNumber, ancestor_number: BlockNumber, ) -> Result, Error> { - if block_number <= ancestor_number { return Ok(None) } + if block_number <= ancestor_number { + return Ok(None) + } let mut current_hash = block_hash; let mut current_entry = None; @@ -289,7 +278,7 @@ fn load_ancestor( let parent_hash = entry.parent_hash; current_entry = Some(entry); current_hash = parent_hash; - } + }, } } @@ -314,24 +303,22 @@ fn add_block( let mut leaves = backend.load_leaves()?; let parent_entry = backend.load_block_entry(&parent_hash)?; - let inherited_viability = parent_entry.as_ref() - .and_then(|parent| parent.non_viable_ancestor_for_child()); + let inherited_viability = + parent_entry.as_ref().and_then(|parent| parent.non_viable_ancestor_for_child()); // 1. Add the block to the DB assuming it's not reverted. - backend.write_block_entry( - BlockEntry { - block_hash, - block_number, - parent_hash, - children: Vec::new(), - viability: ViabilityCriteria { - earliest_unviable_ancestor: inherited_viability, - explicitly_reverted: false, - approval: Approval::Unapproved, - }, - weight, - } - ); + backend.write_block_entry(BlockEntry { + block_hash, + block_number, + parent_hash, + children: Vec::new(), + viability: ViabilityCriteria { + earliest_unviable_ancestor: inherited_viability, + explicitly_reverted: false, + approval: Approval::Unapproved, + }, + weight, + }); // 2. Update leaves if inherited viability is fine. if inherited_viability.is_none() { @@ -370,38 +357,34 @@ fn apply_reversions( // Note: since revert numbers are in ascending order, the expensive propagation // of unviability is only heavy on the first log. for revert_number in reversions { - let mut ancestor_entry = match load_ancestor( - backend, - block_hash, - block_number, - revert_number, - )? { - None => { - tracing::warn!( - target: LOG_TARGET, - ?block_hash, - block_number, - revert_target = revert_number, - "The hammer has dropped. \ + let mut ancestor_entry = + match load_ancestor(backend, block_hash, block_number, revert_number)? { + None => { + tracing::warn!( + target: LOG_TARGET, + ?block_hash, + block_number, + revert_target = revert_number, + "The hammer has dropped. \ A block has indicated that its finalized ancestor be reverted. \ Please inform an adult.", - ); + ); - continue - } - Some(ancestor_entry) => { - tracing::info!( - target: LOG_TARGET, - ?block_hash, - block_number, - revert_target = revert_number, - revert_hash = ?ancestor_entry.block_hash, - "A block has signaled that its ancestor be reverted due to a bad parachain block.", - ); - - ancestor_entry - } - }; + continue + }, + Some(ancestor_entry) => { + tracing::info!( + target: LOG_TARGET, + ?block_hash, + block_number, + revert_target = revert_number, + revert_hash = ?ancestor_entry.block_hash, + "A block has signaled that its ancestor be reverted due to a bad parachain block.", + ); + + ancestor_entry + }, + }; ancestor_entry.viability.explicitly_reverted = true; propagate_viability_update(backend, ancestor_entry)?; @@ -431,8 +414,8 @@ pub(super) fn finalize_block<'a, B: Backend + 'a>( None => { // This implies that there are no unfinalized blocks and hence nothing // to update. - return Ok(backend); - } + return Ok(backend) + }, Some(e) => e, }; @@ -474,9 +457,7 @@ pub(super) fn finalize_block<'a, B: Backend + 'a>( // Add all children to the frontier. let next_height = dead_number + 1; - frontier.extend( - entry.into_iter().flat_map(|e| e.children).map(|h| (h, next_height)) - ); + frontier.extend(entry.into_iter().flat_map(|e| e.children).map(|h| (h, next_height))); } } @@ -533,7 +514,6 @@ pub(super) fn approve_block( } else { backend.write_block_entry(entry); } - } else { tracing::debug!( target: LOG_TARGET, diff --git a/polkadot/node/core/dispute-coordinator/src/backend.rs b/polkadot/node/core/dispute-coordinator/src/backend.rs index dfd53213f70..75a9caa7599 100644 --- a/polkadot/node/core/dispute-coordinator/src/backend.rs +++ b/polkadot/node/core/dispute-coordinator/src/backend.rs @@ -21,12 +21,12 @@ //! [`Backend`], maintaining consistency between queries and temporary writes, //! before any commit to the underlying storage is made. -use polkadot_primitives::v1::{CandidateHash, SessionIndex}; use polkadot_node_subsystem::SubsystemResult; +use polkadot_primitives::v1::{CandidateHash, SessionIndex}; use std::collections::HashMap; -use super::db::v1::{RecentDisputes, CandidateVotes}; +use super::db::v1::{CandidateVotes, RecentDisputes}; #[derive(Debug)] pub enum BackendWriteOp { @@ -54,7 +54,8 @@ pub trait Backend { /// Atomically writes the list of operations, with later operations taking precedence over /// prior. fn write(&mut self, ops: I) -> SubsystemResult<()> - where I: IntoIterator; + where + I: IntoIterator; } /// An in-memory overlay for the backend. @@ -112,7 +113,7 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { pub fn load_candidate_votes( &self, session: SessionIndex, - candidate_hash: &CandidateHash + candidate_hash: &CandidateHash, ) -> SubsystemResult> { if let Some(val) = self.candidate_votes.get(&(session, *candidate_hash)) { return Ok(val.clone()) @@ -142,7 +143,7 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { &mut self, session: SessionIndex, candidate_hash: CandidateHash, - votes: CandidateVotes + votes: CandidateVotes, ) { self.candidate_votes.insert((session, candidate_hash), Some(votes)); } @@ -150,34 +151,28 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> { /// Prepare a deletion of the candidate votes under the indicated candidate. /// /// Later calls to this function for the same candidate will override earlier ones. - pub fn delete_candidate_votes( - &mut self, - session: SessionIndex, - candidate_hash: CandidateHash, - ) { + pub fn delete_candidate_votes(&mut self, session: SessionIndex, candidate_hash: CandidateHash) { self.candidate_votes.insert((session, candidate_hash), None); } /// Transform this backend into a set of write-ops to be written to the inner backend. pub fn into_write_ops(self) -> impl Iterator { - let earliest_session_ops = self.earliest_session + let earliest_session_ops = self + .earliest_session .map(|s| BackendWriteOp::WriteEarliestSession(s)) .into_iter(); - let recent_dispute_ops = self.recent_disputes - .map(|d| BackendWriteOp::WriteRecentDisputes(d)) - .into_iter(); - - let candidate_vote_ops = self.candidate_votes - .into_iter() - .map(|((session, candidate), votes)| match votes { - Some(votes) => BackendWriteOp::WriteCandidateVotes(session, candidate, votes), - None => BackendWriteOp::DeleteCandidateVotes(session, candidate), - }); + let recent_dispute_ops = + self.recent_disputes.map(|d| BackendWriteOp::WriteRecentDisputes(d)).into_iter(); - earliest_session_ops - .chain(recent_dispute_ops) - .chain(candidate_vote_ops) + let candidate_vote_ops = + self.candidate_votes + .into_iter() + .map(|((session, candidate), votes)| match votes { + Some(votes) => BackendWriteOp::WriteCandidateVotes(session, candidate, votes), + None => BackendWriteOp::DeleteCandidateVotes(session, candidate), + }); + earliest_session_ops.chain(recent_dispute_ops).chain(candidate_vote_ops) } } diff --git a/polkadot/node/core/dispute-coordinator/src/db/v1.rs b/polkadot/node/core/dispute-coordinator/src/db/v1.rs index 2d8b488fed6..1de5c2e3ba5 100644 --- a/polkadot/node/core/dispute-coordinator/src/db/v1.rs +++ b/polkadot/node/core/dispute-coordinator/src/db/v1.rs @@ -16,19 +16,21 @@ //! `V1` database for the dispute coordinator. +use polkadot_node_subsystem::{SubsystemError, SubsystemResult}; use polkadot_primitives::v1::{ - CandidateReceipt, ValidDisputeStatementKind, InvalidDisputeStatementKind, ValidatorIndex, - ValidatorSignature, SessionIndex, CandidateHash, Hash, + CandidateHash, CandidateReceipt, Hash, InvalidDisputeStatementKind, SessionIndex, + ValidDisputeStatementKind, ValidatorIndex, ValidatorSignature, }; -use polkadot_node_subsystem::{SubsystemResult, SubsystemError}; use std::sync::Arc; -use kvdb::{KeyValueDB, DBTransaction}; -use parity_scale_codec::{Encode, Decode}; +use kvdb::{DBTransaction, KeyValueDB}; +use parity_scale_codec::{Decode, Encode}; -use crate::{DISPUTE_WINDOW, DisputeStatus}; -use crate::backend::{Backend, BackendWriteOp, OverlayedBackend}; +use crate::{ + backend::{Backend, BackendWriteOp, OverlayedBackend}, + DisputeStatus, DISPUTE_WINDOW, +}; const RECENT_DISPUTES_KEY: &[u8; 15] = b"recent-disputes"; const EARLIEST_SESSION_KEY: &[u8; 16] = b"earliest-session"; @@ -41,10 +43,7 @@ pub struct DbBackend { impl DbBackend { pub fn new(db: Arc, config: ColumnConfiguration) -> Self { - Self { - inner: db, - config, - } + Self { inner: db, config } } } @@ -71,38 +70,28 @@ impl Backend for DbBackend { /// Atomically writes the list of operations, with later operations taking precedence over /// prior. fn write(&mut self, ops: I) -> SubsystemResult<()> - where I: IntoIterator + where + I: IntoIterator, { let mut tx = DBTransaction::new(); for op in ops { match op { BackendWriteOp::WriteEarliestSession(session) => { - tx.put_vec( - self.config.col_data, - EARLIEST_SESSION_KEY, - session.encode(), - ); - } + tx.put_vec(self.config.col_data, EARLIEST_SESSION_KEY, session.encode()); + }, BackendWriteOp::WriteRecentDisputes(recent_disputes) => { - tx.put_vec( - self.config.col_data, - RECENT_DISPUTES_KEY, - recent_disputes.encode(), - ); - } + tx.put_vec(self.config.col_data, RECENT_DISPUTES_KEY, recent_disputes.encode()); + }, BackendWriteOp::WriteCandidateVotes(session, candidate_hash, votes) => { tx.put_vec( self.config.col_data, &candidate_votes_key(session, &candidate_hash), votes.encode(), ); - } + }, BackendWriteOp::DeleteCandidateVotes(session, candidate_hash) => { - tx.delete( - self.config.col_data, - &candidate_votes_key(session, &candidate_hash), - ); - } + tx.delete(self.config.col_data, &candidate_votes_key(session, &candidate_hash)); + }, } } @@ -174,14 +163,10 @@ pub enum Error { /// Result alias for DB errors. pub type Result = std::result::Result; -fn load_decode(db: &dyn KeyValueDB, col_data: u32, key: &[u8]) - -> Result> -{ +fn load_decode(db: &dyn KeyValueDB, col_data: u32, key: &[u8]) -> Result> { match db.get(col_data, key)? { None => Ok(None), - Some(raw) => D::decode(&mut &raw[..]) - .map(Some) - .map_err(Into::into), + Some(raw) => D::decode(&mut &raw[..]).map(Some).map_err(Into::into), } } @@ -231,7 +216,7 @@ pub(crate) fn note_current_session( None => { // First launch - write new-earliest. overlay_db.write_earliest_session(new_earliest); - } + }, Some(prev_earliest) if new_earliest > prev_earliest => { // Prune all data in the outdated sessions. overlay_db.write_earliest_session(new_earliest); @@ -240,10 +225,7 @@ pub(crate) fn note_current_session( { let mut recent_disputes = overlay_db.load_recent_disputes()?.unwrap_or_default(); - let lower_bound = ( - new_earliest, - CandidateHash(Hash::repeat_byte(0x00)), - ); + let lower_bound = (new_earliest, CandidateHash(Hash::repeat_byte(0x00))); let new_recent_disputes = recent_disputes.split_off(&lower_bound); // Any remanining disputes are considered ancient and must be pruned. @@ -256,10 +238,10 @@ pub(crate) fn note_current_session( } } } - } + }, Some(_) => { // nothing to do. - } + }, } Ok(()) @@ -285,13 +267,17 @@ mod tests { overlay_db.write_earliest_session(0); overlay_db.write_earliest_session(1); - overlay_db.write_recent_disputes(vec![ - ((0, CandidateHash(Hash::repeat_byte(0))), DisputeStatus::Active), - ].into_iter().collect()); + overlay_db.write_recent_disputes( + vec![((0, CandidateHash(Hash::repeat_byte(0))), DisputeStatus::Active)] + .into_iter() + .collect(), + ); - overlay_db.write_recent_disputes(vec![ - ((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active), - ].into_iter().collect()); + overlay_db.write_recent_disputes( + vec![((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active)] + .into_iter() + .collect(), + ); overlay_db.write_candidate_votes( 1, @@ -318,23 +304,23 @@ mod tests { ); // Test that overlay returns the correct values before committing. - assert_eq!( - overlay_db.load_earliest_session().unwrap().unwrap(), - 1, - ); + assert_eq!(overlay_db.load_earliest_session().unwrap().unwrap(), 1,); assert_eq!( overlay_db.load_recent_disputes().unwrap().unwrap(), - vec![ - ((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active), - ].into_iter().collect() + vec![((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active),] + .into_iter() + .collect() ); assert_eq!( - overlay_db.load_candidate_votes( - 1, - &CandidateHash(Hash::repeat_byte(1)) - ).unwrap().unwrap().candidate_receipt.descriptor.para_id, + overlay_db + .load_candidate_votes(1, &CandidateHash(Hash::repeat_byte(1))) + .unwrap() + .unwrap() + .candidate_receipt + .descriptor + .para_id, ParaId::from(5), ); @@ -342,23 +328,23 @@ mod tests { backend.write(write_ops).unwrap(); // Test that subsequent writes were written. - assert_eq!( - backend.load_earliest_session().unwrap().unwrap(), - 1, - ); + assert_eq!(backend.load_earliest_session().unwrap().unwrap(), 1,); assert_eq!( backend.load_recent_disputes().unwrap().unwrap(), - vec![ - ((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active), - ].into_iter().collect() + vec![((1, CandidateHash(Hash::repeat_byte(1))), DisputeStatus::Active),] + .into_iter() + .collect() ); assert_eq!( - backend.load_candidate_votes( - 1, - &CandidateHash(Hash::repeat_byte(1)) - ).unwrap().unwrap().candidate_receipt.descriptor.para_id, + backend + .load_candidate_votes(1, &CandidateHash(Hash::repeat_byte(1))) + .unwrap() + .unwrap() + .candidate_receipt + .descriptor + .para_id, ParaId::from(5), ); } @@ -377,17 +363,20 @@ mod tests { candidate_receipt: Default::default(), valid: Vec::new(), invalid: Vec::new(), - } + }, ); let write_ops = overlay_db.into_write_ops(); backend.write(write_ops).unwrap(); assert_eq!( - backend.load_candidate_votes( - 1, - &CandidateHash(Hash::repeat_byte(1)) - ).unwrap().unwrap().candidate_receipt.descriptor.para_id, + backend + .load_candidate_votes(1, &CandidateHash(Hash::repeat_byte(1))) + .unwrap() + .unwrap() + .candidate_receipt + .descriptor + .para_id, ParaId::from(0), ); @@ -404,7 +393,7 @@ mod tests { }, valid: Vec::new(), invalid: Vec::new(), - } + }, ); overlay_db.delete_candidate_votes(1, CandidateHash(Hash::repeat_byte(1))); @@ -412,12 +401,10 @@ mod tests { let write_ops = overlay_db.into_write_ops(); backend.write(write_ops).unwrap(); - assert!( - backend.load_candidate_votes( - 1, - &CandidateHash(Hash::repeat_byte(1)) - ).unwrap().is_none() - ); + assert!(backend + .load_candidate_votes(1, &CandidateHash(Hash::repeat_byte(1))) + .unwrap() + .is_none()); } #[test] @@ -445,36 +432,24 @@ mod tests { let mut overlay_db = OverlayedBackend::new(&backend); overlay_db.write_earliest_session(prev_earliest_session); - overlay_db.write_recent_disputes(vec![ - ((very_old, hash_a), DisputeStatus::Active), - ((slightly_old, hash_b), DisputeStatus::Active), - ((new_earliest_session, hash_c), DisputeStatus::Active), - ((very_recent, hash_d), DisputeStatus::Active), - ].into_iter().collect()); - - overlay_db.write_candidate_votes( - very_old, - hash_a, - blank_candidate_votes(), + overlay_db.write_recent_disputes( + vec![ + ((very_old, hash_a), DisputeStatus::Active), + ((slightly_old, hash_b), DisputeStatus::Active), + ((new_earliest_session, hash_c), DisputeStatus::Active), + ((very_recent, hash_d), DisputeStatus::Active), + ] + .into_iter() + .collect(), ); - overlay_db.write_candidate_votes( - slightly_old, - hash_b, - blank_candidate_votes(), - ); + overlay_db.write_candidate_votes(very_old, hash_a, blank_candidate_votes()); - overlay_db.write_candidate_votes( - new_earliest_session, - hash_c, - blank_candidate_votes(), - ); + overlay_db.write_candidate_votes(slightly_old, hash_b, blank_candidate_votes()); - overlay_db.write_candidate_votes( - very_recent, - hash_d, - blank_candidate_votes(), - ); + overlay_db.write_candidate_votes(new_earliest_session, hash_c, blank_candidate_votes()); + + overlay_db.write_candidate_votes(very_recent, hash_d, blank_candidate_votes()); let write_ops = overlay_db.into_write_ops(); backend.write(write_ops).unwrap(); @@ -482,22 +457,24 @@ mod tests { let mut overlay_db = OverlayedBackend::new(&backend); note_current_session(&mut overlay_db, current_session).unwrap(); - assert_eq!( - overlay_db.load_earliest_session().unwrap(), - Some(new_earliest_session), - ); + assert_eq!(overlay_db.load_earliest_session().unwrap(), Some(new_earliest_session),); assert_eq!( overlay_db.load_recent_disputes().unwrap().unwrap(), vec![ ((new_earliest_session, hash_c), DisputeStatus::Active), ((very_recent, hash_d), DisputeStatus::Active), - ].into_iter().collect(), + ] + .into_iter() + .collect(), ); assert!(overlay_db.load_candidate_votes(very_old, &hash_a).unwrap().is_none()); assert!(overlay_db.load_candidate_votes(slightly_old, &hash_b).unwrap().is_none()); - assert!(overlay_db.load_candidate_votes(new_earliest_session, &hash_c).unwrap().is_some()); + assert!(overlay_db + .load_candidate_votes(new_earliest_session, &hash_c) + .unwrap() + .is_some()); assert!(overlay_db.load_candidate_votes(very_recent, &hash_d).unwrap().is_some()); } } diff --git a/polkadot/node/core/dispute-coordinator/src/lib.rs b/polkadot/node/core/dispute-coordinator/src/lib.rs index db35c49803f..2322ce01148 100644 --- a/polkadot/node/core/dispute-coordinator/src/lib.rs +++ b/polkadot/node/core/dispute-coordinator/src/lib.rs @@ -25,38 +25,42 @@ //! another node, this will trigger the dispute participation subsystem to recover and validate the block and call //! back to this subsystem. -use std::collections::HashSet; -use std::sync::Arc; -use std::time::{SystemTime, UNIX_EPOCH}; +use std::{ + collections::HashSet, + sync::Arc, + time::{SystemTime, UNIX_EPOCH}, +}; -use polkadot_node_primitives::{CandidateVotes, DISPUTE_WINDOW, DisputeMessage, SignedDisputeStatement, DisputeMessageCheckError}; +use polkadot_node_primitives::{ + CandidateVotes, DisputeMessage, DisputeMessageCheckError, SignedDisputeStatement, + DISPUTE_WINDOW, +}; use polkadot_node_subsystem::{ - overseer, SubsystemContext, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemError, errors::{ChainApiError, RuntimeApiError}, messages::{ - ChainApiMessage, DisputeCoordinatorMessage, DisputeDistributionMessage, - DisputeParticipationMessage, ImportStatementsResult, BlockDescription, - } + BlockDescription, ChainApiMessage, DisputeCoordinatorMessage, DisputeDistributionMessage, + DisputeParticipationMessage, ImportStatementsResult, + }, + overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, }; use polkadot_node_subsystem_util::rolling_session_window::{ RollingSessionWindow, SessionWindowUpdate, }; use polkadot_primitives::v1::{ - BlockNumber, CandidateHash, CandidateReceipt, DisputeStatement, Hash, - SessionIndex, SessionInfo, ValidatorIndex, ValidatorPair, ValidatorSignature + BlockNumber, CandidateHash, CandidateReceipt, DisputeStatement, Hash, SessionIndex, + SessionInfo, ValidatorIndex, ValidatorPair, ValidatorSignature, }; -use futures::prelude::*; -use futures::channel::oneshot; +use futures::{channel::oneshot, prelude::*}; use kvdb::KeyValueDB; -use parity_scale_codec::{Encode, Decode, Error as CodecError}; +use parity_scale_codec::{Decode, Encode, Error as CodecError}; use sc_keystore::LocalKeystore; -use db::v1::{RecentDisputes, DbBackend}; use backend::{Backend, OverlayedBackend}; +use db::v1::{DbBackend, RecentDisputes}; -mod db; mod backend; +mod db; #[cfg(test)] mod tests; @@ -116,11 +120,7 @@ pub struct DisputeCoordinatorSubsystem { impl DisputeCoordinatorSubsystem { /// Create a new instance of the subsystem. - pub fn new( - store: Arc, - config: Config, - keystore: Arc, - ) -> Self { + pub fn new(store: Arc, config: Config, keystore: Arc) -> Self { DisputeCoordinatorSubsystem { store, config, keystore } } } @@ -132,14 +132,9 @@ where { fn start(self, ctx: Context) -> SpawnedSubsystem { let backend = DbBackend::new(self.store.clone(), self.config.column_config()); - let future = run(self, ctx, backend, Box::new(SystemClock)) - .map(|_| Ok(())) - .boxed(); + let future = run(self, ctx, backend, Box::new(SystemClock)).map(|_| Ok(())).boxed(); - SpawnedSubsystem { - name: "dispute-coordinator-subsystem", - future, - } + SpawnedSubsystem { name: "dispute-coordinator-subsystem", future } } } @@ -167,7 +162,7 @@ impl Clock for SystemClock { ); 0 - } + }, } } } @@ -210,8 +205,8 @@ impl Error { fn trace(&self) { match self { // don't spam the log with spurious errors - Self::RuntimeApi(_) | - Self::Oneshot(_) => tracing::debug!(target: LOG_TARGET, err = ?self), + Self::RuntimeApi(_) | Self::Oneshot(_) => + tracing::debug!(target: LOG_TARGET, err = ?self), // it's worth reporting otherwise _ => tracing::warn!(target: LOG_TARGET, err = ?self), } @@ -260,8 +255,10 @@ impl DisputeStatus { pub fn concluded_against(self, now: Timestamp) -> DisputeStatus { match self { DisputeStatus::Active => DisputeStatus::ConcludedAgainst(now), - DisputeStatus::ConcludedFor(at) => DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)), - DisputeStatus::ConcludedAgainst(at) => DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)), + DisputeStatus::ConcludedFor(at) => + DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)), + DisputeStatus::ConcludedAgainst(at) => + DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)), } } @@ -287,8 +284,7 @@ async fn run( mut ctx: Context, mut backend: B, clock: Box, -) -where +) where Context: overseer::SubsystemContext, Context: SubsystemContext, B: Backend, @@ -300,13 +296,13 @@ where e.trace(); if let Error::Subsystem(SubsystemError::Context(_)) = e { - break; + break } - } + }, Ok(()) => { tracing::info!(target: LOG_TARGET, "received `Conclude` signal, exiting"); - break; - } + break + }, } } } @@ -337,34 +333,22 @@ where loop { let mut overlay_db = OverlayedBackend::new(backend); match ctx.recv().await? { - FromOverseer::Signal(OverseerSignal::Conclude) => { - return Ok(()) - } + FromOverseer::Signal(OverseerSignal::Conclude) => return Ok(()), FromOverseer::Signal(OverseerSignal::ActiveLeaves(update)) => { handle_new_activations( ctx, &mut overlay_db, &mut state, update.activated.into_iter().map(|a| a.hash), - ).await?; + ) + .await?; if !state.recovery_state.complete() { - handle_startup( - ctx, - &mut overlay_db, - &mut state, - ).await?; + handle_startup(ctx, &mut overlay_db, &mut state).await?; } - } + }, FromOverseer::Signal(OverseerSignal::BlockFinalized(_, _)) => {}, - FromOverseer::Communication { msg } => { - handle_incoming( - ctx, - &mut overlay_db, - &mut state, - msg, - clock.now(), - ).await? - } + FromOverseer::Communication { msg } => + handle_incoming(ctx, &mut overlay_db, &mut state, msg, clock.now()).await?, } if !overlay_db.is_empty() { @@ -395,12 +379,13 @@ where Ok(None) => return Ok(()), Err(e) => { tracing::error!(target: LOG_TARGET, "Failed initial load of recent disputes: {:?}", e); - return Err(e.into()); + return Err(e.into()) }, }; // Filter out disputes that have already concluded. - let active_disputes = recent_disputes.into_iter() + let active_disputes = recent_disputes + .into_iter() .filter(|(_, status)| *status == DisputeStatus::Active) .collect::(); @@ -409,7 +394,11 @@ where Ok(Some(votes)) => votes.into(), Ok(None) => continue, Err(e) => { - tracing::error!(target: LOG_TARGET, "Failed initial load of candidate votes: {:?}", e); + tracing::error!( + target: LOG_TARGET, + "Failed initial load of candidate votes: {:?}", + e + ); continue }, }; @@ -422,7 +411,7 @@ where "Missing info for session which has an active dispute", ); continue - } + }, Some(info) => info.validators.clone(), }; @@ -434,16 +423,18 @@ where // 1) their statement already exists, or // 2) the validator key is not in the local keystore (i.e. the validator is remote). // The remaining set only contains local validators that are also missing statements. - let missing_local_statement = validators.iter() + let missing_local_statement = validators + .iter() .enumerate() .map(|(index, validator)| (ValidatorIndex(index as _), validator)) - .any(|(index, validator)| + .any(|(index, validator)| { !voted_indices.contains(&index) && - state.keystore - .key_pair::(validator) - .ok() - .map_or(false, |v| v.is_some()) - ); + state + .keystore + .key_pair::(validator) + .ok() + .map_or(false, |v| v.is_some()) + }); // Send a `DisputeParticipationMessage` for all non-concluded disputes which do not have a // recorded local statement. @@ -455,10 +446,14 @@ where session, n_validators: n_validators as u32, report_availability, - }).await; + }) + .await; if !receive_availability.await? { - tracing::debug!(target: LOG_TARGET, "Participation failed. Candidate not available"); + tracing::debug!( + target: LOG_TARGET, + "Participation failed. Candidate not available" + ); } } } @@ -467,7 +462,8 @@ where } async fn handle_new_activations( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), overlay_db: &mut OverlayedBackend<'_, impl Backend>, state: &mut State, new_activations: impl IntoIterator, @@ -476,9 +472,7 @@ async fn handle_new_activations( let block_header = { let (tx, rx) = oneshot::channel(); - ctx.send_message( - ChainApiMessage::BlockHeader(new_leaf, tx) - ).await; + ctx.send_message(ChainApiMessage::BlockHeader(new_leaf, tx)).await; match rx.await?? { None => continue, @@ -486,11 +480,11 @@ async fn handle_new_activations( } }; - match state.rolling_session_window.cache_session_info_for_head( - ctx, - new_leaf, - &block_header, - ).await { + match state + .rolling_session_window + .cache_session_info_for_head(ctx, new_leaf, &block_header) + .await + { Err(e) => { tracing::warn!( target: LOG_TARGET, @@ -499,24 +493,19 @@ async fn handle_new_activations( ); continue - } - Ok(SessionWindowUpdate::Initialized { window_end, .. }) - | Ok(SessionWindowUpdate::Advanced { new_window_end: window_end, .. }) - => { + }, + Ok(SessionWindowUpdate::Initialized { window_end, .. }) | + Ok(SessionWindowUpdate::Advanced { new_window_end: window_end, .. }) => { let session = window_end; if state.highest_session.map_or(true, |s| s < session) { - tracing::trace!( - target: LOG_TARGET, - session, - "Observed new session. Pruning", - ); + tracing::trace!(target: LOG_TARGET, session, "Observed new session. Pruning",); state.highest_session = Some(session); db::v1::note_current_session(overlay_db, session)?; } - } - _ => {} + }, + _ => {}, } } @@ -548,26 +537,21 @@ async fn handle_incoming( statements, now, pending_confirmation, - ).await?; - } + ) + .await?; + }, DisputeCoordinatorMessage::RecentDisputes(rx) => { let recent_disputes = overlay_db.load_recent_disputes()?.unwrap_or_default(); let _ = rx.send(recent_disputes.keys().cloned().collect()); - } + }, DisputeCoordinatorMessage::ActiveDisputes(rx) => { let recent_disputes = overlay_db.load_recent_disputes()?.unwrap_or_default(); let _ = rx.send(collect_active(recent_disputes, now)); - } - DisputeCoordinatorMessage::QueryCandidateVotes( - query, - rx - ) => { + }, + DisputeCoordinatorMessage::QueryCandidateVotes(query, rx) => { let mut query_output = Vec::new(); for (session_index, candidate_hash) in query.into_iter() { - if let Some(v) = overlay_db.load_candidate_votes( - session_index, - &candidate_hash, - )? { + if let Some(v) = overlay_db.load_candidate_votes(session_index, &candidate_hash)? { query_output.push((session_index, candidate_hash, v.into())); } else { tracing::debug!( @@ -578,7 +562,7 @@ async fn handle_incoming( } } let _ = rx.send(query_output); - } + }, DisputeCoordinatorMessage::IssueLocalStatement( session, candidate_hash, @@ -594,33 +578,37 @@ async fn handle_incoming( session, valid, now, - ).await?; - } + ) + .await?; + }, DisputeCoordinatorMessage::DetermineUndisputedChain { base_number, block_descriptions, tx, } => { - let undisputed_chain = determine_undisputed_chain( - overlay_db, - base_number, - block_descriptions - )?; + let undisputed_chain = + determine_undisputed_chain(overlay_db, base_number, block_descriptions)?; let _ = tx.send(undisputed_chain); - } + }, } Ok(()) } -fn collect_active(recent_disputes: RecentDisputes, now: Timestamp) -> Vec<(SessionIndex, CandidateHash)> { - recent_disputes.iter().filter_map(|(disputed, status)| - status.concluded_at().filter(|at| at + ACTIVE_DURATION_SECS < now).map_or( - Some(*disputed), - |_| None, - ) - ).collect() +fn collect_active( + recent_disputes: RecentDisputes, + now: Timestamp, +) -> Vec<(SessionIndex, CandidateHash)> { + recent_disputes + .iter() + .filter_map(|(disputed, status)| { + status + .concluded_at() + .filter(|at| at + ACTIVE_DURATION_SECS < now) + .map_or(Some(*disputed), |_| None) + }) + .collect() } fn insert_into_statement_vec( @@ -649,11 +637,12 @@ async fn handle_import_statements( pending_confirmation: oneshot::Sender, ) -> Result<(), Error> { if state.highest_session.map_or(true, |h| session + DISPUTE_WINDOW < h) { - // It is not valid to participate in an ancient dispute (spam?). - pending_confirmation.send(ImportStatementsResult::InvalidImport).map_err(|_| Error::OneshotSend)?; + pending_confirmation + .send(ImportStatementsResult::InvalidImport) + .map_err(|_| Error::OneshotSend)?; - return Ok(()); + return Ok(()) } let validators = match state.rolling_session_window.session_info(session) { @@ -669,7 +658,7 @@ async fn handle_import_statements( .map_err(|_| Error::OneshotSend)?; return Ok(()) - } + }, Some(info) => info.validators.clone(), }; @@ -677,7 +666,8 @@ async fn handle_import_statements( let supermajority_threshold = polkadot_primitives::v1::supermajority_threshold(n_validators); - let mut votes = overlay_db.load_candidate_votes(session, &candidate_hash)? + let mut votes = overlay_db + .load_candidate_votes(session, &candidate_hash)? .map(CandidateVotes::from) .unwrap_or_else(|| CandidateVotes { candidate_receipt: candidate_receipt.clone(), @@ -687,7 +677,8 @@ async fn handle_import_statements( // Update candidate votes. for (statement, val_index) in statements { - if validators.get(val_index.0 as usize) + if validators + .get(val_index.0 as usize) .map_or(true, |v| v != statement.validator_public()) { tracing::debug!( @@ -709,7 +700,7 @@ async fn handle_import_statements( val_index, statement.validator_signature().clone(), ); - } + }, DisputeStatement::Invalid(invalid_kind) => { insert_into_statement_vec( &mut votes.invalid, @@ -717,7 +708,7 @@ async fn handle_import_statements( val_index, statement.validator_signature().clone(), ); - } + }, } } @@ -766,7 +757,8 @@ async fn handle_import_statements( session, n_validators: n_validators as u32, report_availability, - }).await; + }) + .await; if !receive_availability.await.map_err(Error::Oneshot)? { // If the data is not available, we disregard the dispute votes. @@ -775,7 +767,8 @@ async fn handle_import_statements( // // We expect that if the candidate is truly disputed that the higher-level network // code will retry. - pending_confirmation.send(ImportStatementsResult::InvalidImport) + pending_confirmation + .send(ImportStatementsResult::InvalidImport) .map_err(|_| Error::OneshotSend)?; tracing::debug!( @@ -819,13 +812,14 @@ async fn issue_local_statement( ); return Ok(()) - } + }, Some(info) => info, }; let validators = info.validators.clone(); - let votes = overlay_db.load_candidate_votes(session, &candidate_hash)? + let votes = overlay_db + .load_candidate_votes(session, &candidate_hash)? .map(CandidateVotes::from) .unwrap_or_else(|| CandidateVotes { candidate_receipt: candidate_receipt.clone(), @@ -841,7 +835,9 @@ async fn issue_local_statement( let voted_indices: HashSet<_> = voted_indices.into_iter().collect(); for (index, validator) in validators.iter().enumerate() { let index = ValidatorIndex(index as _); - if voted_indices.contains(&index) { continue } + if voted_indices.contains(&index) { + continue + } if state.keystore.key_pair::(validator).ok().flatten().is_none() { continue } @@ -853,20 +849,21 @@ async fn issue_local_statement( candidate_hash, session, validator.clone(), - ).await; + ) + .await; match res { Ok(Some(signed_dispute_statement)) => { statements.push((signed_dispute_statement, index)); - } - Ok(None) => {} + }, + Ok(None) => {}, Err(e) => { tracing::error!( target: LOG_TARGET, err = ?e, "Encountered keystore error while signing dispute statement", ); - } + }, } } @@ -874,20 +871,15 @@ async fn issue_local_statement( for (statement, index) in &statements { let dispute_message = match make_dispute_message(info, &votes, statement.clone(), *index) { Err(err) => { - tracing::debug!( - target: LOG_TARGET, - ?err, - "Creating dispute message failed." - ); + tracing::debug!(target: LOG_TARGET, ?err, "Creating dispute message failed."); continue - } + }, Ok(dispute_message) => dispute_message, }; ctx.send_message(DisputeDistributionMessage::SendDispute(dispute_message)).await; } - // Do import if !statements.is_empty() { let (pending_confirmation, _rx) = oneshot::channel(); @@ -901,7 +893,8 @@ async fn issue_local_statement( statements, now, pending_confirmation, - ).await?; + ) + .await?; } Ok(()) @@ -923,42 +916,52 @@ fn make_dispute_message( info: &SessionInfo, votes: &CandidateVotes, our_vote: SignedDisputeStatement, - our_index: ValidatorIndex + our_index: ValidatorIndex, ) -> Result { - let validators = &info.validators; let (valid_statement, valid_index, invalid_statement, invalid_index) = if let DisputeStatement::Valid(_) = our_vote.statement() { - let (statement_kind, validator_index, validator_signature) - = votes.invalid.get(0).ok_or(MakeDisputeMessageError::NoOppositeVote)?.clone(); + let (statement_kind, validator_index, validator_signature) = + votes.invalid.get(0).ok_or(MakeDisputeMessageError::NoOppositeVote)?.clone(); let other_vote = SignedDisputeStatement::new_checked( DisputeStatement::Invalid(statement_kind), our_vote.candidate_hash().clone(), our_vote.session_index(), - validators.get(validator_index.0 as usize).ok_or(MakeDisputeMessageError::InvalidValidatorIndex)?.clone(), + validators + .get(validator_index.0 as usize) + .ok_or(MakeDisputeMessageError::InvalidValidatorIndex)? + .clone(), validator_signature, - ).map_err(|()| MakeDisputeMessageError::InvalidStoredStatement)?; + ) + .map_err(|()| MakeDisputeMessageError::InvalidStoredStatement)?; (our_vote, our_index, other_vote, validator_index) - } else { - let (statement_kind, validator_index, validator_signature) - = votes.valid.get(0).ok_or(MakeDisputeMessageError::NoOppositeVote)?.clone(); - let other_vote = SignedDisputeStatement::new_checked( - DisputeStatement::Valid(statement_kind), - our_vote.candidate_hash().clone(), - our_vote.session_index(), - validators.get(validator_index.0 as usize).ok_or(MakeDisputeMessageError::InvalidValidatorIndex)?.clone(), - validator_signature, - ).map_err(|()| MakeDisputeMessageError::InvalidStoredStatement)?; - (other_vote, validator_index, our_vote, our_index) - }; + } else { + let (statement_kind, validator_index, validator_signature) = + votes.valid.get(0).ok_or(MakeDisputeMessageError::NoOppositeVote)?.clone(); + let other_vote = SignedDisputeStatement::new_checked( + DisputeStatement::Valid(statement_kind), + our_vote.candidate_hash().clone(), + our_vote.session_index(), + validators + .get(validator_index.0 as usize) + .ok_or(MakeDisputeMessageError::InvalidValidatorIndex)? + .clone(), + validator_signature, + ) + .map_err(|()| MakeDisputeMessageError::InvalidStoredStatement)?; + (other_vote, validator_index, our_vote, our_index) + }; DisputeMessage::from_signed_statements( - valid_statement, valid_index, - invalid_statement, invalid_index, + valid_statement, + valid_index, + invalid_statement, + invalid_index, votes.candidate_receipt.clone(), info, - ).map_err(MakeDisputeMessageError::InvalidStatementCombination) + ) + .map_err(MakeDisputeMessageError::InvalidStatementCombination) } /// Determine the the best block and its block number. @@ -969,7 +972,8 @@ fn determine_undisputed_chain( base_number: BlockNumber, block_descriptions: Vec, ) -> Result, Error> { - let last = block_descriptions.last() + let last = block_descriptions + .last() .map(|e| (base_number + block_descriptions.len() as BlockNumber, e.block_hash)); // Fast path for no disputes. @@ -980,21 +984,20 @@ fn determine_undisputed_chain( }; let is_possibly_invalid = |session, candidate_hash| { - recent_disputes.get(&(session, candidate_hash)).map_or( - false, - |status| status.is_possibly_invalid(), - ) + recent_disputes + .get(&(session, candidate_hash)) + .map_or(false, |status| status.is_possibly_invalid()) }; for (i, BlockDescription { session, candidates, .. }) in block_descriptions.iter().enumerate() { if candidates.iter().any(|c| is_possibly_invalid(*session, *c)) { if i == 0 { - return Ok(None); + return Ok(None) } else { return Ok(Some(( base_number + i as BlockNumber, block_descriptions[i - 1].block_hash, - ))); + ))) } } } diff --git a/polkadot/node/core/dispute-coordinator/src/tests.rs b/polkadot/node/core/dispute-coordinator/src/tests.rs index a3b8c669eae..08f4a8c7e47 100644 --- a/polkadot/node/core/dispute-coordinator/src/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/tests.rs @@ -17,26 +17,30 @@ use std::collections::HashMap; use super::*; +use assert_matches::assert_matches; +use futures::{ + channel::oneshot, + future::{self, BoxFuture}, +}; use overseer::TimeoutExt; -use polkadot_primitives::v1::{BlakeTwo256, HashT, ValidatorId, Header, SessionInfo}; -use polkadot_node_subsystem::{jaeger, ActiveLeavesUpdate, ActivatedLeaf, LeafStatus}; -use polkadot_node_subsystem::messages::{ - AllMessages, ChainApiMessage, RuntimeApiMessage, RuntimeApiRequest, - BlockDescription, +use parity_scale_codec::Encode; +use polkadot_node_subsystem::{ + jaeger, + messages::{ + AllMessages, BlockDescription, ChainApiMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, }; use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle}; +use polkadot_primitives::v1::{BlakeTwo256, HashT, Header, SessionInfo, ValidatorId}; use sp_core::testing::TaskExecutor; use sp_keyring::Sr25519Keyring; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; -use futures::{ - channel::oneshot, - future::{self, BoxFuture}, -}; -use parity_scale_codec::Encode; -use assert_matches::assert_matches; -use std::sync::atomic::{AtomicU64, Ordering as AtomicOrdering}; -use std::time::Duration; +use std::{ + sync::atomic::{AtomicU64, Ordering as AtomicOrdering}, + time::Duration, +}; const TEST_TIMEOUT: Duration = Duration::from_secs(2); @@ -45,10 +49,9 @@ fn make_keystore(accounts: &[Sr25519Keyring]) -> LocalKeystore { let store = LocalKeystore::in_memory(); for s in accounts.iter().copied().map(|k| k.to_seed()) { - store.sr25519_generate_new( - polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID, - Some(s.as_str()), - ).unwrap(); + store + .sr25519_generate_new(polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID, Some(s.as_str())) + .unwrap(); } store @@ -106,9 +109,7 @@ impl Default for TestState { Sr25519Keyring::One, ]; - let validator_public = validators.iter() - .map(|k| ValidatorId::from(k.public())) - .collect(); + let validator_public = validators.iter().map(|k| ValidatorId::from(k.public())).collect(); let validator_groups = vec![ vec![ValidatorIndex(0), ValidatorIndex(1)], @@ -120,9 +121,7 @@ impl Default for TestState { let subsystem_keystore = make_keystore(&[Sr25519Keyring::Alice]).into(); let db = Arc::new(kvdb_memorydb::create(1)); - let config = Config { - col_data: 0, - }; + let config = Config { col_data: 0 }; TestState { validators, @@ -159,16 +158,19 @@ impl TestState { let _ = self.headers.insert(block_hash, block_header.clone()); - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( - ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash: block_hash, - span: Arc::new(jaeger::Span::Disabled), - number: block_number, - status: LeafStatus::Fresh, - }) - ))).await; - - self.handle_sync_queries(virtual_overseer, block_hash, block_header, session).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: block_hash, + span: Arc::new(jaeger::Span::Disabled), + number: block_number, + status: LeafStatus::Fresh, + }), + ))) + .await; + + self.handle_sync_queries(virtual_overseer, block_hash, block_header, session) + .await; } async fn handle_sync_queries( @@ -215,23 +217,23 @@ impl TestState { } } - async fn handle_resume_sync(&self, virtual_overseer: &mut VirtualOverseer, session: SessionIndex) { + async fn handle_resume_sync( + &self, + virtual_overseer: &mut VirtualOverseer, + session: SessionIndex, + ) { let leaves: Vec = self.headers.keys().cloned().collect(); for leaf in leaves.iter() { - virtual_overseer.send( - FromOverseer::Signal( - OverseerSignal::ActiveLeaves( - ActiveLeavesUpdate::start_work( - ActivatedLeaf { - hash: *leaf, - number: 1, - span: Arc::new(jaeger::Span::Disabled), - status: LeafStatus::Fresh, - } - ) - ) - ) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: *leaf, + number: 1, + span: Arc::new(jaeger::Span::Disabled), + status: LeafStatus::Fresh, + }), + ))) + .await; let header = self.headers.get(leaf).unwrap().clone(); self.handle_sync_queries(virtual_overseer, *leaf, header, session).await; @@ -239,13 +241,9 @@ impl TestState { } fn session_info(&self) -> SessionInfo { - let discovery_keys = self.validators.iter() - .map(|k| <_>::from(k.public())) - .collect(); + let discovery_keys = self.validators.iter().map(|k| <_>::from(k.public())).collect(); - let assignment_keys = self.validators.iter() - .map(|k| <_>::from(k.public())) - .collect(); + let assignment_keys = self.validators.iter().map(|k| <_>::from(k.public())).collect(); SessionInfo { validators: self.validator_public.clone(), @@ -272,17 +270,15 @@ impl TestState { let keystore = self.master_keystore.clone() as SyncCryptoStorePtr; - SignedDisputeStatement::sign_explicit( - &keystore, - valid, - candidate_hash, - session, - public, - ).await.unwrap().unwrap() + SignedDisputeStatement::sign_explicit(&keystore, valid, candidate_hash, session, public) + .await + .unwrap() + .unwrap() } fn resume(self, test: F) -> Self - where F: FnOnce(TestState, VirtualOverseer) -> BoxFuture<'static, TestState> + where + F: FnOnce(TestState, VirtualOverseer) -> BoxFuture<'static, TestState>, { let (ctx, ctx_handle) = make_subsystem_context(TaskExecutor::new()); let subsystem = DisputeCoordinatorSubsystem::new( @@ -300,1097 +296,1053 @@ impl TestState { } fn test_harness(test: F) -> TestState - where F: FnOnce(TestState, VirtualOverseer) -> BoxFuture<'static, TestState> +where + F: FnOnce(TestState, VirtualOverseer) -> BoxFuture<'static, TestState>, { TestState::default().resume(test) } #[test] fn conflicting_votes_lead_to_dispute_participation() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - false, - ).await; - - let invalid_vote_2 = test_state.issue_statement_with_index( - 2, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(0)), - (invalid_vote, ValidatorIndex(1)), - ], - pending_confirmation, - }, - }).await; - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation(DisputeParticipationMessage::Participate { - candidate_hash: c_hash, - candidate_receipt: c_receipt, - session: s, - n_validators, - report_availability, - }) => { - assert_eq!(c_hash, candidate_hash); - assert_eq!(c_receipt, candidate_receipt); - assert_eq!(s, session); - assert_eq!(n_validators, test_state.validators.len() as u32); - report_availability.send(true).unwrap(); + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, false).await; + + let invalid_vote_2 = + test_state.issue_statement_with_index(2, candidate_hash, session, false).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(0)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation, + }, + }) + .await; + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation(DisputeParticipationMessage::Participate { + candidate_hash: c_hash, + candidate_receipt: c_receipt, + session: s, + n_validators, + report_availability, + }) => { + assert_eq!(c_hash, candidate_hash); + assert_eq!(c_receipt, candidate_receipt); + assert_eq!(s, session); + assert_eq!(n_validators, test_state.validators.len() as u32); + report_availability.send(true).unwrap(); + } + ); + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap(), vec![(session, candidate_hash)]); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.len(), 1); + assert_eq!(votes.invalid.len(), 1); } - ); - - { - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert_eq!(rx.await.unwrap(), vec![(session, candidate_hash)]); - - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::QueryCandidateVotes( - vec![(session, candidate_hash)], - tx, - ), - }).await; - - let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); - assert_eq!(votes.valid.len(), 1); - assert_eq!(votes.invalid.len(), 1); - } - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (invalid_vote_2, ValidatorIndex(2)), - ], - pending_confirmation, - }, - }).await; - - { - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::QueryCandidateVotes( - vec![(session, candidate_hash)], - tx, - ), - }).await; - - let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); - assert_eq!(votes.valid.len(), 1); - assert_eq!(votes.invalid.len(), 2); - } + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(invalid_vote_2, ValidatorIndex(2))], + pending_confirmation, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.len(), 1); + assert_eq!(votes.invalid.len(), 2); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - // This confirms that the second vote doesn't lead to participation again. - assert!(virtual_overseer.try_recv().await.is_none()); + // This confirms that the second vote doesn't lead to participation again. + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn positive_votes_dont_trigger_participation() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let valid_vote_2 = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - true, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(0)), - ], - pending_confirmation, - }, - }).await; - - { - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert!(rx.await.unwrap().is_empty()); - - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::QueryCandidateVotes( - vec![(session, candidate_hash)], - tx, - ), - }).await; - - let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); - assert_eq!(votes.valid.len(), 1); - assert!(votes.invalid.is_empty()); - } + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let valid_vote_2 = + test_state.issue_statement_with_index(1, candidate_hash, session, true).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote, ValidatorIndex(0))], + pending_confirmation, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.len(), 1); + assert!(votes.invalid.is_empty()); + } - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote_2, ValidatorIndex(1)), - ], - pending_confirmation, - }, - }).await; - - { - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert!(rx.await.unwrap().is_empty()); - - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::QueryCandidateVotes( - vec![(session, candidate_hash)], - tx, - ), - }).await; - - let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); - assert_eq!(votes.valid.len(), 2); - assert!(votes.invalid.is_empty()); - } + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote_2, ValidatorIndex(1))], + pending_confirmation, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.len(), 2); + assert!(votes.invalid.is_empty()); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - // This confirms that no participation request is made. - assert!(virtual_overseer.try_recv().await.is_none()); + // This confirms that no participation request is made. + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn wrong_validator_index_is_ignored() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(1)), - (invalid_vote, ValidatorIndex(0)), - ], - pending_confirmation, - }, - }).await; - - { - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert!(rx.await.unwrap().is_empty()); - - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::QueryCandidateVotes( - vec![(session, candidate_hash)], - tx, - ), - }).await; - - let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); - assert!(votes.valid.is_empty()); - assert!(votes.invalid.is_empty()); - } + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, false).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(0)), + ], + pending_confirmation, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert!(votes.valid.is_empty()); + assert!(votes.invalid.is_empty()); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - // This confirms that no participation request is made. - assert!(virtual_overseer.try_recv().await.is_none()); + // This confirms that no participation request is made. + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn finality_votes_ignore_disputed_candidates() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(0)), - (invalid_vote, ValidatorIndex(1)), - ], - pending_confirmation, - }, - }).await; + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, false).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(0)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation, + }, + }) + .await; - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(true).unwrap(); } - ) => { - report_availability.send(true).unwrap(); + ); + + { + let (tx, rx) = oneshot::channel(); + + let block_hash_a = Hash::repeat_byte(0x0a); + let block_hash_b = Hash::repeat_byte(0x0b); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base_number: 10, + block_descriptions: vec![BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![candidate_hash], + }], + tx, + }, + }) + .await; + + assert!(rx.await.unwrap().is_none()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base_number: 10, + block_descriptions: vec![ + BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![], + }, + BlockDescription { + block_hash: block_hash_b, + session, + candidates: vec![candidate_hash], + }, + ], + tx, + }, + }) + .await; + + assert_eq!(rx.await.unwrap(), Some((11, block_hash_a))); } - ); - { - let (tx, rx) = oneshot::channel(); - - let block_hash_a = Hash::repeat_byte(0x0a); - let block_hash_b = Hash::repeat_byte(0x0b); - - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::DetermineUndisputedChain{ - base_number: 10, - block_descriptions: vec![ - BlockDescription { block_hash: block_hash_a, session, candidates: vec![candidate_hash] }, - ], - tx, - }, - }).await; - - assert!(rx.await.unwrap().is_none()); - - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::DetermineUndisputedChain { - base_number: 10, - block_descriptions: vec![ - BlockDescription { block_hash: block_hash_a, session, candidates: vec![] }, - BlockDescription { block_hash: block_hash_b, session, candidates: vec![candidate_hash] }, - ], - tx, - }, - }).await; - - assert_eq!(rx.await.unwrap(), Some((11, block_hash_a))); - } - - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn supermajority_valid_dispute_may_be_finalized() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let supermajority_threshold = polkadot_primitives::v1::supermajority_threshold( - test_state.validators.len() - ); - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(0)), - (invalid_vote, ValidatorIndex(1)), - ], - pending_confirmation, - }, - }).await; + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let supermajority_threshold = + polkadot_primitives::v1::supermajority_threshold(test_state.validators.len()); + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, false).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(0)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation, + }, + }) + .await; - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - candidate_hash: c_hash, - candidate_receipt: c_receipt, - session: s, - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + candidate_hash: c_hash, + candidate_receipt: c_receipt, + session: s, + report_availability, + .. + } + ) => { + assert_eq!(candidate_hash, c_hash); + assert_eq!(candidate_receipt, c_receipt); + assert_eq!(session, s); + report_availability.send(true).unwrap(); } - ) => { - assert_eq!(candidate_hash, c_hash); - assert_eq!(candidate_receipt, c_receipt); - assert_eq!(session, s); - report_availability.send(true).unwrap(); - } - ); + ); - let mut statements = Vec::new(); - for i in (0..supermajority_threshold - 1).map(|i| i + 2) { - let vote = test_state.issue_statement_with_index( - i, - candidate_hash, - session, - true, - ).await; + let mut statements = Vec::new(); + for i in (0..supermajority_threshold - 1).map(|i| i + 2) { + let vote = + test_state.issue_statement_with_index(i, candidate_hash, session, true).await; - statements.push((vote, ValidatorIndex(i as _))); - }; + statements.push((vote, ValidatorIndex(i as _))); + } - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements, - pending_confirmation, - }, - }).await; - - { - let (tx, rx) = oneshot::channel(); - - let block_hash_a = Hash::repeat_byte(0x0a); - let block_hash_b = Hash::repeat_byte(0x0b); - - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::DetermineUndisputedChain { - base_number: 10, - block_descriptions: vec![ - BlockDescription { block_hash: block_hash_a, session, candidates: vec![candidate_hash] }, - ], - tx, - }, - }).await; - - assert_eq!(rx.await.unwrap(), Some((11, block_hash_a))); - - let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::DetermineUndisputedChain { - base_number: 10, - block_descriptions: vec![ - BlockDescription { block_hash: block_hash_a, session, candidates: vec![] }, - BlockDescription { block_hash: block_hash_b, session, candidates: vec![candidate_hash] }, - ], - tx, - }, - }).await; - - assert_eq!(rx.await.unwrap(), Some((12, block_hash_b))); - } + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + { + let (tx, rx) = oneshot::channel(); + + let block_hash_a = Hash::repeat_byte(0x0a); + let block_hash_b = Hash::repeat_byte(0x0b); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base_number: 10, + block_descriptions: vec![BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![candidate_hash], + }], + tx, + }, + }) + .await; + + assert_eq!(rx.await.unwrap(), Some((11, block_hash_a))); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::DetermineUndisputedChain { + base_number: 10, + block_descriptions: vec![ + BlockDescription { + block_hash: block_hash_a, + session, + candidates: vec![], + }, + BlockDescription { + block_hash: block_hash_b, + session, + candidates: vec![candidate_hash], + }, + ], + tx, + }, + }) + .await; + + assert_eq!(rx.await.unwrap(), Some((12, block_hash_b))); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn concluded_supermajority_for_non_active_after_time() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let supermajority_threshold = + polkadot_primitives::v1::supermajority_threshold(test_state.validators.len()); + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, false).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(0)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation, + }, + }) + .await; - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let supermajority_threshold = polkadot_primitives::v1::supermajority_threshold( - test_state.validators.len() - ); - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(0)), - (invalid_vote, ValidatorIndex(1)), - ], - pending_confirmation, - }, - }).await; - - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(true).unwrap(); } - ) => { - report_availability.send(true).unwrap(); - } - ); + ); - let mut statements = Vec::new(); - for i in (0..supermajority_threshold - 1).map(|i| i + 2) { - let vote = test_state.issue_statement_with_index( - i, - candidate_hash, - session, - true, - ).await; + let mut statements = Vec::new(); + for i in (0..supermajority_threshold - 1).map(|i| i + 2) { + let vote = + test_state.issue_statement_with_index(i, candidate_hash, session, true).await; - statements.push((vote, ValidatorIndex(i as _))); - }; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements, - pending_confirmation, - }, - }).await; - - test_state.clock.set(ACTIVE_DURATION_SECS + 1); - - { - let (tx, rx) = oneshot::channel(); - - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert!(rx.await.unwrap().is_empty()); - - let (tx, rx) = oneshot::channel(); - - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::RecentDisputes(tx), - }).await; + statements.push((vote, ValidatorIndex(i as _))); + } - assert_eq!(rx.await.unwrap().len(), 1); - } + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + test_state.clock.set(ACTIVE_DURATION_SECS + 1); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::RecentDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn concluded_supermajority_against_non_active_after_time() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let supermajority_threshold = + polkadot_primitives::v1::supermajority_threshold(test_state.validators.len()); + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, false).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(0)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation, + }, + }) + .await; - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let supermajority_threshold = polkadot_primitives::v1::supermajority_threshold( - test_state.validators.len() - ); - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(0)), - (invalid_vote, ValidatorIndex(1)), - ], - pending_confirmation, - }, - }).await; - - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(true).unwrap(); } - ) => { - report_availability.send(true).unwrap(); - } - ); - - let mut statements = Vec::new(); - for i in (0..supermajority_threshold - 1).map(|i| i + 2) { - let vote = test_state.issue_statement_with_index( - i, - candidate_hash, - session, - false, - ).await; - - statements.push((vote, ValidatorIndex(i as _))); - }; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements, - pending_confirmation, - }, - }).await; - - test_state.clock.set(ACTIVE_DURATION_SECS + 1); + ); - { - let (tx, rx) = oneshot::channel(); + let mut statements = Vec::new(); + for i in (0..supermajority_threshold - 1).map(|i| i + 2) { + let vote = + test_state.issue_statement_with_index(i, candidate_hash, session, false).await; - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert!(rx.await.unwrap().is_empty()); - - let (tx, rx) = oneshot::channel(); - - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::RecentDisputes(tx), - }).await; + statements.push((vote, ValidatorIndex(i as _))); + } - assert_eq!(rx.await.unwrap().len(), 1); - } + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + test_state.clock.set(ACTIVE_DURATION_SECS + 1); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); + + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::RecentDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn fresh_dispute_ignored_if_unavailable() { - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(0)), - (invalid_vote, ValidatorIndex(1)), - ], - pending_confirmation, - }, - }).await; + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, false).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(0)), + (invalid_vote, ValidatorIndex(1)), + ], + pending_confirmation, + }, + }) + .await; - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(false).unwrap(); } - ) => { - report_availability.send(false).unwrap(); - } - ); + ); - { - let (tx, rx) = oneshot::channel(); + { + let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; - assert!(rx.await.unwrap().is_empty()); + assert!(rx.await.unwrap().is_empty()); - let (tx, rx) = oneshot::channel(); + let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::RecentDisputes(tx), - }).await; + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::RecentDisputes(tx), + }) + .await; - assert!(rx.await.unwrap().is_empty()); - } + assert!(rx.await.unwrap().is_empty()); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn resume_dispute_without_local_statement() { let session = 1; - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 2, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(1)), - (invalid_vote, ValidatorIndex(2)), - ], - pending_confirmation, - }, - }).await; + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let valid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(2, candidate_hash, session, false).await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation, + }, + }) + .await; - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(true).unwrap(); } - ) => { - report_availability.send(true).unwrap(); - } - ); + ); - assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); - { - let (tx, rx) = oneshot::channel(); + { + let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; - assert_eq!(rx.await.unwrap().len(), 1); - } + assert_eq!(rx.await.unwrap().len(), 1); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })) + test_state + }) + }) // Alice should send a DisputeParticiationMessage::Participate on restart since she has no // local statement for the active dispute. - .resume(|test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; + .resume(|test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - candidate_hash: c_hash, - candidate_receipt: c_receipt, - session: s, - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + candidate_hash: c_hash, + candidate_receipt: c_receipt, + session: s, + report_availability, + .. + } + ) => { + assert_eq!(candidate_hash, c_hash); + assert_eq!(candidate_receipt, c_receipt); + assert_eq!(session, s); + report_availability.send(true).unwrap(); } - ) => { - assert_eq!(candidate_hash, c_hash); - assert_eq!(candidate_receipt, c_receipt); - assert_eq!(session, s); - report_availability.send(true).unwrap(); + ); + + let valid_vote0 = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + let valid_vote3 = + test_state.issue_statement_with_index(3, candidate_hash, session, true).await; + let valid_vote4 = + test_state.issue_statement_with_index(4, candidate_hash, session, true).await; + let valid_vote5 = + test_state.issue_statement_with_index(5, candidate_hash, session, true).await; + + let (pending_confirmation, _confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote0, ValidatorIndex(0)), + (valid_vote3, ValidatorIndex(3)), + (valid_vote4, ValidatorIndex(4)), + (valid_vote5, ValidatorIndex(5)), + ], + pending_confirmation, + }, + }) + .await; + + // Advance the clock far enough so that the concluded dispute will be omitted from an + // ActiveDisputes query. + test_state.clock.set(test_state.clock.now() + ACTIVE_DURATION_SECS + 1); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert!(rx.await.unwrap().is_empty()); } - ); - - let valid_vote0 = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - let valid_vote3 = test_state.issue_statement_with_index( - 3, - candidate_hash, - session, - true, - ).await; - let valid_vote4 = test_state.issue_statement_with_index( - 4, - candidate_hash, - session, - true, - ).await; - let valid_vote5 = test_state.issue_statement_with_index( - 5, - candidate_hash, - session, - true, - ).await; - - let (pending_confirmation, _confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote0, ValidatorIndex(0)), - (valid_vote3, ValidatorIndex(3)), - (valid_vote4, ValidatorIndex(4)), - (valid_vote5, ValidatorIndex(5)), - ], - pending_confirmation, - }, - }).await; - - // Advance the clock far enough so that the concluded dispute will be omitted from an - // ActiveDisputes query. - test_state.clock.set(test_state.clock.now() + ACTIVE_DURATION_SECS + 1 ); - - { - let (tx, rx) = oneshot::channel(); - - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert!(rx.await.unwrap().is_empty()); - } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] fn resume_dispute_with_local_statement() { let session = 1; - test_harness(|mut test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let local_valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 2, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (local_valid_vote, ValidatorIndex(0)), - (valid_vote, ValidatorIndex(1)), - (invalid_vote, ValidatorIndex(2)), - ], - pending_confirmation, - }, - }).await; + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let local_valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let valid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(2, candidate_hash, session, false).await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (local_valid_vote, ValidatorIndex(0)), + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation, + }, + }) + .await; - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(true).unwrap(); } - ) => { - report_availability.send(true).unwrap(); - } - ); + ); - assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); - { - let (tx, rx) = oneshot::channel(); + { + let (tx, rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; - assert_eq!(rx.await.unwrap().len(), 1); - } + assert_eq!(rx.await.unwrap().len(), 1); + } - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })) + test_state + }) + }) // Alice should send a DisputeParticiationMessage::Participate on restart since she has no // local statement for the active dispute. - .resume(|test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; + .resume(|test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; - // Assert that subsystem is not sending Participation messages because we issued a local statement - assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + // Assert that subsystem is not sending Participation messages because we issued a local statement + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] @@ -1398,88 +1350,85 @@ fn resume_dispute_without_local_statement_or_local_key() { let session = 1; let mut test_state = TestState::default(); test_state.subsystem_keystore = make_keystore(&[Sr25519Keyring::Two]).into(); - test_state.resume(|mut test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 2, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (valid_vote, ValidatorIndex(1)), - (invalid_vote, ValidatorIndex(2)), - ], - pending_confirmation, - }, - }).await; - - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + test_state + .resume(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let valid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(2, candidate_hash, session, false).await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation, + }, + }) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(true).unwrap(); + } + ); + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); } - ) => { - report_availability.send(true).unwrap(); - } - ); - - assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); - { - let (tx, rx) = oneshot::channel(); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert_eq!(rx.await.unwrap().len(), 1); - } - - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); - - test_state - })) - // Alice should send a DisputeParticiationMessage::Participate on restart since she has no - // local statement for the active dispute. - .resume(|test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; + test_state + }) + }) + // Alice should send a DisputeParticiationMessage::Participate on restart since she has no + // local statement for the active dispute. + .resume(|test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; - // Assert that subsystem is not sending Participation messages because we issued a local statement - assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + // Assert that subsystem is not sending Participation messages because we issued a local statement + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } #[test] @@ -1488,94 +1437,87 @@ fn resume_dispute_with_local_statement_without_local_key() { let mut test_state = TestState::default(); test_state.subsystem_keystore = make_keystore(&[Sr25519Keyring::Two]).into(); - test_state.resume(|mut test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; - - let candidate_receipt = CandidateReceipt::default(); - let candidate_hash = candidate_receipt.hash(); - - test_state.activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - ).await; - - let local_valid_vote = test_state.issue_statement_with_index( - 0, - candidate_hash, - session, - true, - ).await; - - let valid_vote = test_state.issue_statement_with_index( - 1, - candidate_hash, - session, - true, - ).await; - - let invalid_vote = test_state.issue_statement_with_index( - 2, - candidate_hash, - session, - false, - ).await; - - let (pending_confirmation, confirmation_rx) = oneshot::channel(); - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_hash, - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![ - (local_valid_vote, ValidatorIndex(0)), - (valid_vote, ValidatorIndex(1)), - (invalid_vote, ValidatorIndex(2)), - ], - pending_confirmation, - }, - }).await; - - assert_matches!( - virtual_overseer.recv().await, - AllMessages::DisputeParticipation( - DisputeParticipationMessage::Participate { - report_availability, - .. + test_state + .resume(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = CandidateReceipt::default(); + let candidate_hash = candidate_receipt.hash(); + + test_state.activate_leaf_at_session(&mut virtual_overseer, session, 1).await; + + let local_valid_vote = + test_state.issue_statement_with_index(0, candidate_hash, session, true).await; + + let valid_vote = + test_state.issue_statement_with_index(1, candidate_hash, session, true).await; + + let invalid_vote = + test_state.issue_statement_with_index(2, candidate_hash, session, false).await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_hash, + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (local_valid_vote, ValidatorIndex(0)), + (valid_vote, ValidatorIndex(1)), + (invalid_vote, ValidatorIndex(2)), + ], + pending_confirmation, + }, + }) + .await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeParticipation( + DisputeParticipationMessage::Participate { + report_availability, + .. + } + ) => { + report_availability.send(true).unwrap(); + } + ); + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + { + let (tx, rx) = oneshot::channel(); + + virtual_overseer + .send(FromOverseer::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); } - ) => { - report_availability.send(true).unwrap(); - } - ); - - assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); - { - let (tx, rx) = oneshot::channel(); - - virtual_overseer.send(FromOverseer::Communication { - msg: DisputeCoordinatorMessage::ActiveDisputes(tx), - }).await; - - assert_eq!(rx.await.unwrap().len(), 1); - } + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); - - test_state - })) - // Alice should send a DisputeParticiationMessage::Participate on restart since she has no - // local statement for the active dispute. - .resume(|test_state, mut virtual_overseer| Box::pin(async move { - test_state.handle_resume_sync(&mut virtual_overseer, session).await; + test_state + }) + }) + // Alice should send a DisputeParticiationMessage::Participate on restart since she has no + // local statement for the active dispute. + .resume(|test_state, mut virtual_overseer| { + Box::pin(async move { + test_state.handle_resume_sync(&mut virtual_overseer, session).await; - // Assert that subsystem is not sending Participation messages because we issued a local statement - assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + // Assert that subsystem is not sending Participation messages because we issued a local statement + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); - test_state - })); + test_state + }) + }); } diff --git a/polkadot/node/core/dispute-participation/src/lib.rs b/polkadot/node/core/dispute-participation/src/lib.rs index 619da697857..c79d10462e0 100644 --- a/polkadot/node/core/dispute-participation/src/lib.rs +++ b/polkadot/node/core/dispute-participation/src/lib.rs @@ -20,20 +20,18 @@ //! notified of a dispute, we recover the candidate data, validate the //! candidate, and cast our vote in the dispute. -use futures::channel::oneshot; -use futures::prelude::*; +use futures::{channel::oneshot, prelude::*}; use polkadot_node_primitives::ValidationResult; use polkadot_node_subsystem::{ errors::{RecoveryError, RuntimeApiError}, - overseer, messages::{ - AvailabilityRecoveryMessage, AvailabilityStoreMessage, - CandidateValidationMessage, DisputeCoordinatorMessage, DisputeParticipationMessage, - RuntimeApiMessage, RuntimeApiRequest, + AvailabilityRecoveryMessage, AvailabilityStoreMessage, CandidateValidationMessage, + DisputeCoordinatorMessage, DisputeParticipationMessage, RuntimeApiMessage, + RuntimeApiRequest, }, - ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, - SubsystemContext, SubsystemError, + overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, + SubsystemError, }; use polkadot_primitives::v1::{BlockNumber, CandidateHash, CandidateReceipt, Hash, SessionIndex}; @@ -64,10 +62,7 @@ where fn start(self, ctx: Context) -> SpawnedSubsystem { let future = run(ctx).map(|_| Ok(())).boxed(); - SpawnedSubsystem { - name: "dispute-participation-subsystem", - future, - } + SpawnedSubsystem { name: "dispute-participation-subsystem", future } } } @@ -106,7 +101,7 @@ impl Error { // don't spam the log with spurious errors Self::RuntimeApi(_) | Self::Oneshot(_) => { tracing::debug!(target: LOG_TARGET, err = ?self) - } + }, // it's worth reporting otherwise _ => tracing::warn!(target: LOG_TARGET, err = ?self), } @@ -125,20 +120,20 @@ where Err(_) => return, Ok(FromOverseer::Signal(OverseerSignal::Conclude)) => { tracing::info!(target: LOG_TARGET, "Received `Conclude` signal, exiting"); - return; - } - Ok(FromOverseer::Signal(OverseerSignal::BlockFinalized(_, _))) => {} + return + }, + Ok(FromOverseer::Signal(OverseerSignal::BlockFinalized(_, _))) => {}, Ok(FromOverseer::Signal(OverseerSignal::ActiveLeaves(update))) => { update_state(&mut state, update); - } + }, Ok(FromOverseer::Communication { msg }) => { if let Err(err) = handle_incoming(&mut ctx, &mut state, msg).await { err.trace(); if let Error::Subsystem(SubsystemError::Context(_)) = err { - return; + return } } - } + }, } } } @@ -163,7 +158,7 @@ async fn handle_incoming( session, n_validators, report_availability, - } => { + } => if let Some((_, block_hash)) = state.recent_block { participate( ctx, @@ -176,9 +171,8 @@ async fn handle_incoming( ) .await } else { - return Err(ParticipationError::MissingRecentBlockState.into()); - } - } + return Err(ParticipationError::MissingRecentBlockState.into()) + }, } } @@ -198,47 +192,43 @@ async fn participate( // in order to validate a candidate we need to start by recovering the // available data - ctx.send_message( - AvailabilityRecoveryMessage::RecoverAvailableData( - candidate_receipt.clone(), - session, - None, - recover_available_data_tx, - ) - ) + ctx.send_message(AvailabilityRecoveryMessage::RecoverAvailableData( + candidate_receipt.clone(), + session, + None, + recover_available_data_tx, + )) .await; let available_data = match recover_available_data_rx.await? { Ok(data) => { report_availability.send(true).map_err(|_| Error::OneshotSendFailed)?; data - } + }, Err(RecoveryError::Invalid) => { report_availability.send(true).map_err(|_| Error::OneshotSendFailed)?; // the available data was recovered but it is invalid, therefore we'll // vote negatively for the candidate dispute cast_invalid_vote(ctx, candidate_hash, candidate_receipt, session).await; - return Ok(()); - } + return Ok(()) + }, Err(RecoveryError::Unavailable) => { report_availability.send(false).map_err(|_| Error::OneshotSendFailed)?; - return Err(ParticipationError::MissingAvailableData(candidate_hash).into()); - } + return Err(ParticipationError::MissingAvailableData(candidate_hash).into()) + }, }; // we also need to fetch the validation code which we can reference by its // hash as taken from the candidate descriptor - ctx.send_message( - RuntimeApiMessage::Request( - block_hash, - RuntimeApiRequest::ValidationCodeByHash( - candidate_receipt.descriptor.validation_code_hash, - code_tx, - ), - ) - ) + ctx.send_message(RuntimeApiMessage::Request( + block_hash, + RuntimeApiRequest::ValidationCodeByHash( + candidate_receipt.descriptor.validation_code_hash, + code_tx, + ), + )) .await; let validation_code = match code_rx.await?? { @@ -251,22 +241,20 @@ async fn participate( block_hash, ); - return Err(ParticipationError::MissingValidationCode(candidate_hash).into()); - } + return Err(ParticipationError::MissingValidationCode(candidate_hash).into()) + }, }; // we dispatch a request to store the available data for the candidate. we // want to maximize data availability for other potential checkers involved // in the dispute - ctx.send_message( - AvailabilityStoreMessage::StoreAvailableData( - candidate_hash, - None, - n_validators, - available_data.clone(), - store_available_data_tx, - ) - ) + ctx.send_message(AvailabilityStoreMessage::StoreAvailableData( + candidate_hash, + None, + n_validators, + available_data.clone(), + store_available_data_tx, + )) .await; match store_available_data_rx.await? { @@ -276,21 +264,19 @@ async fn participate( "Failed to store available data for candidate {:?}", candidate_hash, ); - } - Ok(()) => {} + }, + Ok(()) => {}, } // we issue a request to validate the candidate with the provided exhaustive // parameters - ctx.send_message( - CandidateValidationMessage::ValidateFromExhaustive( - available_data.validation_data, - validation_code, - candidate_receipt.descriptor.clone(), - available_data.pov, - validation_tx, - ) - ) + ctx.send_message(CandidateValidationMessage::ValidateFromExhaustive( + available_data.validation_data, + validation_code, + candidate_receipt.descriptor.clone(), + available_data.pov, + validation_tx, + )) .await; // we cast votes (either positive or negative) depending on the outcome of @@ -305,7 +291,7 @@ async fn participate( ); cast_invalid_vote(ctx, candidate_hash, candidate_receipt, session).await; - } + }, Ok(ValidationResult::Invalid(invalid)) => { tracing::warn!( target: LOG_TARGET, @@ -315,7 +301,7 @@ async fn participate( ); cast_invalid_vote(ctx, candidate_hash, candidate_receipt, session).await; - } + }, Ok(ValidationResult::Valid(commitments, _)) => { if commitments.hash() != candidate_receipt.commitments_hash { tracing::warn!( @@ -329,7 +315,7 @@ async fn participate( } else { cast_valid_vote(ctx, candidate_hash, candidate_receipt, session).await; } - } + }, } Ok(()) @@ -372,13 +358,11 @@ async fn issue_local_statement( session: SessionIndex, valid: bool, ) { - ctx.send_message( - DisputeCoordinatorMessage::IssueLocalStatement( - session, - candidate_hash, - candidate_receipt, - valid, - ), - ) + ctx.send_message(DisputeCoordinatorMessage::IssueLocalStatement( + session, + candidate_hash, + candidate_receipt, + valid, + )) .await } diff --git a/polkadot/node/core/dispute-participation/src/tests.rs b/polkadot/node/core/dispute-participation/src/tests.rs index 43aecd3f784..40bfdd3f7b6 100644 --- a/polkadot/node/core/dispute-participation/src/tests.rs +++ b/polkadot/node/core/dispute-participation/src/tests.rs @@ -24,8 +24,10 @@ use super::*; use parity_scale_codec::Encode; use polkadot_node_primitives::{AvailableData, BlockData, InvalidCandidate, PoV}; use polkadot_node_subsystem::{ + jaeger, + messages::{AllMessages, ValidationFailed}, overseer::Subsystem, - jaeger, messages::{AllMessages, ValidationFailed}, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, }; use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle}; use polkadot_primitives::v1::{BlakeTwo256, CandidateCommitments, HashT, Header, ValidationCode}; @@ -45,9 +47,7 @@ where let (subsystem_result, _) = futures::executor::block_on(future::join(spawned_subsystem.future, async move { let mut ctx_handle = test_future.await; - ctx_handle - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .await; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; // no further request is received by the overseer which means that // no further attempt to participate was made @@ -69,14 +69,14 @@ async fn activate_leaf(virtual_overseer: &mut VirtualOverseer, block_number: Blo let block_hash = block_header.hash(); virtual_overseer - .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( - ActiveLeavesUpdate::start_work(ActivatedLeaf { + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + ActivatedLeaf { hash: block_hash, span: Arc::new(jaeger::Span::Disabled), number: block_number, status: LeafStatus::Fresh, - }), - ))) + }, + )))) .await; } @@ -102,20 +102,19 @@ async fn participate(virtual_overseer: &mut VirtualOverseer) -> oneshot::Receive n_validators, report_availability, }, - }) - .await; + }) + .await; receive_availability } -async fn recover_available_data(virtual_overseer: &mut VirtualOverseer, receive_availability: oneshot::Receiver) { - let pov_block = PoV { - block_data: BlockData(Vec::new()), - }; +async fn recover_available_data( + virtual_overseer: &mut VirtualOverseer, + receive_availability: oneshot::Receiver, +) { + let pov_block = PoV { block_data: BlockData(Vec::new()) }; - let available_data = AvailableData { - pov: Arc::new(pov_block), - validation_data: Default::default(), - }; + let available_data = + AvailableData { pov: Arc::new(pov_block), validation_data: Default::default() }; assert_matches!( virtual_overseer.recv().await, @@ -217,7 +216,10 @@ fn cannot_participate_if_cannot_recover_available_data() { "overseer did not receive recover available data message", ); - assert_eq!(receive_availability.await.expect("Availability should get reported"), false); + assert_eq!( + receive_availability.await.expect("Availability should get reported"), + false + ); virtual_overseer }) diff --git a/polkadot/node/core/parachains-inherent/src/lib.rs b/polkadot/node/core/parachains-inherent/src/lib.rs index 0ba09a86ace..87b4f6f247f 100644 --- a/polkadot/node/core/parachains-inherent/src/lib.rs +++ b/polkadot/node/core/parachains-inherent/src/lib.rs @@ -26,12 +26,9 @@ use futures::{select, FutureExt}; use polkadot_node_subsystem::{ - overseer::Handle, - messages::ProvisionerMessage, errors::SubsystemError, -}; -use polkadot_primitives::v1::{ - Block, Hash, InherentData as ParachainsInherentData, + errors::SubsystemError, messages::ProvisionerMessage, overseer::Handle, }; +use polkadot_primitives::v1::{Block, Hash, InherentData as ParachainsInherentData}; use sp_blockchain::HeaderBackend; use sp_runtime::generic::BlockId; use std::time; @@ -54,13 +51,18 @@ impl ParachainsInherentDataProvider { let pid = async { let (sender, receiver) = futures::channel::oneshot::channel(); overseer.wait_for_activation(parent, sender).await; - receiver.await.map_err(|_| Error::ClosedChannelAwaitingActivation)?.map_err(|e| Error::Subsystem(e))?; + receiver + .await + .map_err(|_| Error::ClosedChannelAwaitingActivation)? + .map_err(|e| Error::Subsystem(e))?; let (sender, receiver) = futures::channel::oneshot::channel(); - overseer.send_msg( - ProvisionerMessage::RequestInherentData(parent, sender), - std::any::type_name::(), - ).await; + overseer + .send_msg( + ProvisionerMessage::RequestInherentData(parent, sender), + std::any::type_name::(), + ) + .await; receiver.await.map_err(|_| Error::ClosedChannelAwaitingInherentData) }; @@ -96,7 +98,7 @@ impl ParachainsInherentDataProvider { disputes: Vec::new(), parent_header, } - } + }, }; Ok(Self { inherent_data }) @@ -105,11 +107,12 @@ impl ParachainsInherentDataProvider { #[async_trait::async_trait] impl sp_inherents::InherentDataProvider for ParachainsInherentDataProvider { - fn provide_inherent_data(&self, inherent_data: &mut sp_inherents::InherentData) -> Result<(), sp_inherents::Error> { - inherent_data.put_data( - polkadot_primitives::v1::PARACHAINS_INHERENT_IDENTIFIER, - &self.inherent_data, - ) + fn provide_inherent_data( + &self, + inherent_data: &mut sp_inherents::InherentData, + ) -> Result<(), sp_inherents::Error> { + inherent_data + .put_data(polkadot_primitives::v1::PARACHAINS_INHERENT_IDENTIFIER, &self.inherent_data) } async fn try_handle_error( diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs index f9c87468f03..21a2fb5fba2 100644 --- a/polkadot/node/core/provisioner/src/lib.rs +++ b/polkadot/node/core/provisioner/src/lib.rs @@ -24,25 +24,29 @@ use futures::{ channel::{mpsc, oneshot}, prelude::*, }; +use futures_timer::Delay; use polkadot_node_subsystem::{ - errors::{ChainApiError, RuntimeApiError}, PerLeafSpan, SubsystemSender, jaeger, + errors::{ChainApiError, RuntimeApiError}, + jaeger, messages::{ - CandidateBackingMessage, ChainApiMessage, ProvisionableData, ProvisionerInherentData, - ProvisionerMessage, DisputeCoordinatorMessage, + CandidateBackingMessage, ChainApiMessage, DisputeCoordinatorMessage, ProvisionableData, + ProvisionerInherentData, ProvisionerMessage, }, + PerLeafSpan, SubsystemSender, }; use polkadot_node_subsystem_util::{ - self as util, JobSubsystem, JobSender, - request_availability_cores, request_persisted_validation_data, JobTrait, metrics::{self, prometheus}, + self as util, + metrics::{self, prometheus}, + request_availability_cores, request_persisted_validation_data, JobSender, JobSubsystem, + JobTrait, }; use polkadot_primitives::v1::{ - BackedCandidate, BlockNumber, CandidateReceipt, CoreState, Hash, OccupiedCoreAssumption, - SignedAvailabilityBitfield, ValidatorIndex, MultiDisputeStatementSet, DisputeStatementSet, - DisputeStatement, + BackedCandidate, BlockNumber, CandidateReceipt, CoreState, DisputeStatement, + DisputeStatementSet, Hash, MultiDisputeStatementSet, OccupiedCoreAssumption, + SignedAvailabilityBitfield, ValidatorIndex, }; -use std::{pin::Pin, collections::BTreeMap, sync::Arc}; +use std::{collections::BTreeMap, pin::Pin, sync::Arc}; use thiserror::Error; -use futures_timer::Delay; #[cfg(test)] mod tests; @@ -92,7 +96,7 @@ pub struct ProvisioningJob { signed_bitfields: Vec, metrics: Metrics, inherent_after: InherentAfter, - awaiting_inherent: Vec> + awaiting_inherent: Vec>, } /// Errors in the provisioner. @@ -132,7 +136,9 @@ pub enum Error { #[error("failed to send return message with Inherents")] InherentDataReturnChannel, - #[error("backed candidate does not correspond to selected candidate; check logic in provisioner")] + #[error( + "backed candidate does not correspond to selected candidate; check logic in provisioner" + )] BackedCandidateOrderingProblem, } @@ -156,13 +162,10 @@ impl JobTrait for ProvisioningJob { mut sender: JobSender, ) -> Pin> + Send>> { async move { - let job = ProvisioningJob::new( - relay_parent, - metrics, - receiver, - ); + let job = ProvisioningJob::new(relay_parent, metrics, receiver); - job.run_loop(sender.subsystem_sender(), PerLeafSpan::new(span, "provisioner")).await + job.run_loop(sender.subsystem_sender(), PerLeafSpan::new(span, "provisioner")) + .await } .boxed() } @@ -190,9 +193,7 @@ impl ProvisioningJob { sender: &mut impl SubsystemSender, span: PerLeafSpan, ) -> Result<(), Error> { - use ProvisionerMessage::{ - ProvisionableData, RequestInherentData, - }; + use ProvisionerMessage::{ProvisionableData, RequestInherentData}; loop { futures::select! { msg = self.receiver.next() => match msg { @@ -248,17 +249,21 @@ impl ProvisioningJob { } } - fn note_provisionable_data(&mut self, span: &jaeger::Span, provisionable_data: ProvisionableData) { + fn note_provisionable_data( + &mut self, + span: &jaeger::Span, + provisionable_data: ProvisionableData, + ) { match provisionable_data { - ProvisionableData::Bitfield(_, signed_bitfield) => { - self.signed_bitfields.push(signed_bitfield) - } + ProvisionableData::Bitfield(_, signed_bitfield) => + self.signed_bitfields.push(signed_bitfield), ProvisionableData::BackedCandidate(backed_candidate) => { - let _span = span.child("provisionable-backed") + let _span = span + .child("provisionable-backed") .with_para_id(backed_candidate.descriptor().para_id); self.backed_candidates.push(backed_candidate) - } - _ => {} + }, + _ => {}, } } } @@ -291,27 +296,23 @@ async fn send_inherent_data( ) -> Result<(), Error> { let availability_cores = request_availability_cores(relay_parent, from_job) .await - .await.map_err(|err| Error::CanceledAvailabilityCores(err))??; + .await + .map_err(|err| Error::CanceledAvailabilityCores(err))??; let bitfields = select_availability_bitfields(&availability_cores, bitfields); - let candidates = select_candidates( - &availability_cores, - &bitfields, - candidates, - relay_parent, - from_job, - ).await?; + let candidates = + select_candidates(&availability_cores, &bitfields, candidates, relay_parent, from_job) + .await?; let disputes = select_disputes(from_job).await?; - let inherent_data = ProvisionerInherentData { - bitfields, - backed_candidates: candidates, - disputes, - }; + let inherent_data = + ProvisionerInherentData { bitfields, backed_candidates: candidates, disputes }; for return_sender in return_senders { - return_sender.send(inherent_data.clone()).map_err(|_data| Error::InherentDataReturnChannel)?; + return_sender + .send(inherent_data.clone()) + .map_err(|_data| Error::InherentDataReturnChannel)?; } Ok(()) @@ -333,16 +334,18 @@ fn select_availability_bitfields( ) -> Vec { let mut selected: BTreeMap = BTreeMap::new(); - 'a: - for bitfield in bitfields.iter().cloned() { + 'a: for bitfield in bitfields.iter().cloned() { if bitfield.payload().0.len() != cores.len() { continue } - let is_better = selected.get(&bitfield.validator_index()) + let is_better = selected + .get(&bitfield.validator_index()) .map_or(true, |b| b.payload().0.count_ones() < bitfield.payload().0.count_ones()); - if !is_better { continue } + if !is_better { + continue + } for (idx, _) in cores.iter().enumerate().filter(|v| !v.1.is_occupied()) { // Bit is set for an unoccupied core - invalid @@ -374,23 +377,24 @@ async fn select_candidates( let (scheduled_core, assumption) = match core { CoreState::Scheduled(scheduled_core) => (scheduled_core, OccupiedCoreAssumption::Free), CoreState::Occupied(occupied_core) => { - if bitfields_indicate_availability(core_idx, bitfields, &occupied_core.availability) { + if bitfields_indicate_availability(core_idx, bitfields, &occupied_core.availability) + { if let Some(ref scheduled_core) = occupied_core.next_up_on_available { (scheduled_core, OccupiedCoreAssumption::Included) } else { - continue; + continue } } else { if occupied_core.time_out_at != block_number { - continue; + continue } if let Some(ref scheduled_core) = occupied_core.next_up_on_time_out { (scheduled_core, OccupiedCoreAssumption::TimedOut) } else { - continue; + continue } } - } + }, CoreState::Free => continue, }; @@ -401,7 +405,8 @@ async fn select_candidates( sender, ) .await - .await.map_err(|err| Error::CanceledPersistedValidationData(err))?? + .await + .map_err(|err| Error::CanceledPersistedValidationData(err))?? { Some(v) => v, None => continue, @@ -412,8 +417,8 @@ async fn select_candidates( // we arbitrarily pick the first of the backed candidates which match the appropriate selection criteria if let Some(candidate) = candidates.iter().find(|backed_candidate| { let descriptor = &backed_candidate.descriptor; - descriptor.para_id == scheduled_core.para_id - && descriptor.persisted_validation_data_hash == computed_validation_data_hash + descriptor.para_id == scheduled_core.para_id && + descriptor.persisted_validation_data_hash == computed_validation_data_hash }) { let candidate_hash = candidate.hash(); tracing::trace!( @@ -430,11 +435,16 @@ async fn select_candidates( // now get the backed candidates corresponding to these candidate receipts let (tx, rx) = oneshot::channel(); - sender.send_message(CandidateBackingMessage::GetBackedCandidates( - relay_parent, - selected_candidates.clone(), - tx, - ).into()).await; + sender + .send_message( + CandidateBackingMessage::GetBackedCandidates( + relay_parent, + selected_candidates.clone(), + tx, + ) + .into(), + ) + .await; let mut candidates = rx.await.map_err(|err| Error::CanceledBackedCandidates(err))?; // `selected_candidates` is generated in ascending order by core index, and `GetBackedCandidates` @@ -445,7 +455,9 @@ async fn select_candidates( // in order, we can ensure that the backed candidates are also in order. let mut backed_idx = 0; for selected in selected_candidates { - if selected == candidates.get(backed_idx).ok_or(Error::BackedCandidateOrderingProblem)?.hash() { + if selected == + candidates.get(backed_idx).ok_or(Error::BackedCandidateOrderingProblem)?.hash() + { backed_idx += 1; } } @@ -484,12 +496,7 @@ async fn get_block_number_under_construction( sender: &mut impl SubsystemSender, ) -> Result { let (tx, rx) = oneshot::channel(); - sender - .send_message(ChainApiMessage::BlockNumber( - relay_parent, - tx, - ).into()) - .await; + sender.send_message(ChainApiMessage::BlockNumber(relay_parent, tx).into()).await; match rx.await.map_err(|err| Error::CanceledBlockNumber(err))? { Ok(Some(n)) => Ok(n + 1), @@ -528,8 +535,8 @@ fn bitfields_indicate_availability( availability_len, ); - return false; - } + return false + }, Some(mut bit_mut) => *bit_mut |= bitfield.payload().0[core_idx], } } @@ -562,16 +569,17 @@ async fn select_disputes( ); Vec::new() - } + }, }; // Load all votes for all disputes from the coordinator. let dispute_candidate_votes = { let (tx, rx) = oneshot::channel(); - sender.send_message(DisputeCoordinatorMessage::QueryCandidateVotes( - recent_disputes, - tx, - ).into()).await; + sender + .send_message( + DisputeCoordinatorMessage::QueryCandidateVotes(recent_disputes, tx).into(), + ) + .await; match rx.await { Ok(v) => v, @@ -581,24 +589,29 @@ async fn select_disputes( "Unable to query candidate votes - subsystem disconnected?", ); Vec::new() - } + }, } }; // Transform all `CandidateVotes` into `MultiDisputeStatementSet`. - Ok(dispute_candidate_votes.into_iter().map(|(session_index, candidate_hash, votes)| { - let valid_statements = votes.valid.into_iter() - .map(|(s, i, sig)| (DisputeStatement::Valid(s), i, sig)); - - let invalid_statements = votes.invalid.into_iter() - .map(|(s, i, sig)| (DisputeStatement::Invalid(s), i, sig)); - - DisputeStatementSet { - candidate_hash, - session: session_index, - statements: valid_statements.chain(invalid_statements).collect(), - } - }).collect()) + Ok(dispute_candidate_votes + .into_iter() + .map(|(session_index, candidate_hash, votes)| { + let valid_statements = + votes.valid.into_iter().map(|(s, i, sig)| (DisputeStatement::Valid(s), i, sig)); + + let invalid_statements = votes + .invalid + .into_iter() + .map(|(s, i, sig)| (DisputeStatement::Invalid(s), i, sig)); + + DisputeStatementSet { + candidate_hash, + session: session_index, + statements: valid_statements.chain(invalid_statements).collect(), + } + }) + .collect()) } #[derive(Clone)] @@ -623,7 +636,9 @@ impl Metrics { } /// Provide a timer for `request_inherent_data` which observes on drop. - fn time_request_inherent_data(&self) -> Option { + fn time_request_inherent_data( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.request_inherent_data.start_timer()) } @@ -647,21 +662,17 @@ impl metrics::Metrics for Metrics { registry, )?, request_inherent_data: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_provisioner_request_inherent_data", - "Time spent within `provisioner::request_inherent_data`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_provisioner_request_inherent_data", + "Time spent within `provisioner::request_inherent_data`", + ))?, registry, )?, provisionable_data: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_provisioner_provisionable_data", - "Time spent within `provisioner::provisionable_data`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_provisioner_provisionable_data", + "Time spent within `provisioner::provisionable_data`", + ))?, registry, )?, }; @@ -669,6 +680,5 @@ impl metrics::Metrics for Metrics { } } - /// The provisioning subsystem. pub type ProvisioningSubsystem = JobSubsystem; diff --git a/polkadot/node/core/provisioner/src/tests.rs b/polkadot/node/core/provisioner/src/tests.rs index 8c5587ab147..104a04569f3 100644 --- a/polkadot/node/core/provisioner/src/tests.rs +++ b/polkadot/node/core/provisioner/src/tests.rs @@ -34,20 +34,16 @@ pub fn default_bitvec(n_cores: usize) -> CoreAvailability { } pub fn scheduled_core(id: u32) -> ScheduledCore { - ScheduledCore { - para_id: id.into(), - ..Default::default() - } + ScheduledCore { para_id: id.into(), ..Default::default() } } mod select_availability_bitfields { - use super::super::*; - use super::{default_bitvec, occupied_core}; + use super::{super::*, default_bitvec, occupied_core}; use futures::executor::block_on; - use std::sync::Arc; - use polkadot_primitives::v1::{SigningContext, ValidatorIndex, ValidatorId}; + use polkadot_primitives::v1::{SigningContext, ValidatorId, ValidatorIndex}; use sp_application_crypto::AppKey; - use sp_keystore::{CryptoStore, SyncCryptoStorePtr, testing::KeyStore}; + use sp_keystore::{testing::KeyStore, CryptoStore, SyncCryptoStorePtr}; + use std::sync::Arc; async fn signed_bitfield( keystore: &SyncCryptoStorePtr, @@ -63,7 +59,11 @@ mod select_availability_bitfields { &>::default(), validator_idx, &public.into(), - ).await.ok().flatten().expect("Should be signed") + ) + .await + .ok() + .flatten() + .expect("Should be signed") } #[test] @@ -109,11 +109,8 @@ mod select_availability_bitfields { let mut bitvec2 = bitvec.clone(); bitvec2.set(2, true); - let cores = vec![ - CoreState::Free, - CoreState::Scheduled(Default::default()), - occupied_core(2), - ]; + let cores = + vec![CoreState::Free, CoreState::Scheduled(Default::default()), occupied_core(2)]; let bitfields = vec![ block_on(signed_bitfield(&keystore, bitvec0, ValidatorIndex(0))), @@ -191,16 +188,18 @@ mod select_availability_bitfields { } mod select_candidates { - use super::super::*; - use super::{build_occupied_core, occupied_core, scheduled_core, default_bitvec}; + use super::{super::*, build_occupied_core, default_bitvec, occupied_core, scheduled_core}; use polkadot_node_subsystem::messages::{ AllMessages, RuntimeApiMessage, - RuntimeApiRequest::{AvailabilityCores, PersistedValidationData as PersistedValidationDataReq}, + RuntimeApiRequest::{ + AvailabilityCores, PersistedValidationData as PersistedValidationDataReq, + }, }; + use polkadot_node_subsystem_test_helpers::TestSubsystemSender; use polkadot_primitives::v1::{ - BlockNumber, CandidateDescriptor, PersistedValidationData, CommittedCandidateReceipt, CandidateCommitments, + BlockNumber, CandidateCommitments, CandidateDescriptor, CommittedCandidateReceipt, + PersistedValidationData, }; - use polkadot_node_subsystem_test_helpers::TestSubsystemSender; const BLOCK_UNDER_PRODUCTION: BlockNumber = 128; @@ -307,21 +306,21 @@ mod select_candidates { while let Some(from_job) = receiver.next().await { match from_job { - AllMessages::ChainApi(BlockNumber(_relay_parent, tx)) => { - tx.send(Ok(Some(BLOCK_UNDER_PRODUCTION - 1))).unwrap() - } + AllMessages::ChainApi(BlockNumber(_relay_parent, tx)) => + tx.send(Ok(Some(BLOCK_UNDER_PRODUCTION - 1))).unwrap(), AllMessages::RuntimeApi(Request( _parent_hash, PersistedValidationDataReq(_para_id, _assumption, tx), )) => tx.send(Ok(Some(Default::default()))).unwrap(), - AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx))) => { - tx.send(Ok(mock_availability_cores())).unwrap() - } - AllMessages::CandidateBacking( - CandidateBackingMessage::GetBackedCandidates(_, _, sender) - ) => { + AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx))) => + tx.send(Ok(mock_availability_cores())).unwrap(), + AllMessages::CandidateBacking(CandidateBackingMessage::GetBackedCandidates( + _, + _, + sender, + )) => { let _ = sender.send(expected.clone()); - } + }, _ => panic!("Unexpected message: {:?}", from_job), } } @@ -329,9 +328,12 @@ mod select_candidates { #[test] fn can_succeed() { - test_harness(|r| mock_overseer(r, Vec::new()), |mut tx: TestSubsystemSender| async move { - select_candidates(&[], &[], &[], Default::default(), &mut tx).await.unwrap(); - }) + test_harness( + |r| mock_overseer(r, Vec::new()), + |mut tx: TestSubsystemSender| async move { + select_candidates(&[], &[], &[], Default::default(), &mut tx).await.unwrap(); + }, + ) } // this tests that only the appropriate candidates get selected. @@ -368,8 +370,7 @@ mod select_candidates { candidate } else if idx < mock_cores.len() * 2 { // for the second repetition of the candidates, give them the wrong hash - candidate.descriptor.persisted_validation_data_hash - = Default::default(); + candidate.descriptor.persisted_validation_data_hash = Default::default(); candidate } else { // third go-around: right hash, wrong para_id @@ -380,34 +381,38 @@ mod select_candidates { .collect(); // why those particular indices? see the comments on mock_availability_cores() - let expected_candidates: Vec<_> = [1, 4, 7, 8, 10] - .iter() - .map(|&idx| candidates[idx].clone()) - .collect(); + let expected_candidates: Vec<_> = + [1, 4, 7, 8, 10].iter().map(|&idx| candidates[idx].clone()).collect(); let expected_backed = expected_candidates .iter() .map(|c| BackedCandidate { - candidate: CommittedCandidateReceipt { descriptor: c.descriptor.clone(), ..Default::default() }, + candidate: CommittedCandidateReceipt { + descriptor: c.descriptor.clone(), + ..Default::default() + }, validity_votes: Vec::new(), validator_indices: default_bitvec(n_cores), }) .collect(); - test_harness(|r| mock_overseer(r, expected_backed), |mut tx: TestSubsystemSender| async move { - let result = - select_candidates(&mock_cores, &[], &candidates, Default::default(), &mut tx) - .await.unwrap(); + test_harness( + |r| mock_overseer(r, expected_backed), + |mut tx: TestSubsystemSender| async move { + let result = + select_candidates(&mock_cores, &[], &candidates, Default::default(), &mut tx) + .await + .unwrap(); - result.into_iter() - .for_each(|c| + result.into_iter().for_each(|c| { assert!( expected_candidates.iter().any(|c2| c.candidate.corresponds_to(c2)), "Failed to find candidate: {:?}", c, ) - ); - }) + }); + }, + ) } #[test] @@ -430,7 +435,11 @@ mod select_candidates { ..Default::default() }, commitments: CandidateCommitments { - new_validation_code: if cores_with_code.contains(&i) { Some(vec![].into()) } else { None }, + new_validation_code: if cores_with_code.contains(&i) { + Some(vec![].into()) + } else { + None + }, ..Default::default() }, ..Default::default() @@ -439,10 +448,8 @@ mod select_candidates { let candidates: Vec<_> = committed_receipts.iter().map(|r| r.to_plain()).collect(); - let expected_candidates: Vec<_> = cores - .iter() - .map(|&idx| candidates[idx].clone()) - .collect(); + let expected_candidates: Vec<_> = + cores.iter().map(|&idx| candidates[idx].clone()).collect(); let expected_backed: Vec<_> = cores .iter() @@ -453,19 +460,22 @@ mod select_candidates { }) .collect(); - test_harness(|r| mock_overseer(r, expected_backed), |mut tx: TestSubsystemSender| async move { - let result = - select_candidates(&mock_cores, &[], &candidates, Default::default(), &mut tx) - .await.unwrap(); + test_harness( + |r| mock_overseer(r, expected_backed), + |mut tx: TestSubsystemSender| async move { + let result = + select_candidates(&mock_cores, &[], &candidates, Default::default(), &mut tx) + .await + .unwrap(); - result.into_iter() - .for_each(|c| + result.into_iter().for_each(|c| { assert!( expected_candidates.iter().any(|c2| c.candidate.corresponds_to(c2)), "Failed to find candidate: {:?}", c, ) - ); - }) + }); + }, + ) } } diff --git a/polkadot/node/core/pvf/src/artifacts.rs b/polkadot/node/core/pvf/src/artifacts.rs index 2b739fe1230..4f872c07960 100644 --- a/polkadot/node/core/pvf/src/artifacts.rs +++ b/polkadot/node/core/pvf/src/artifacts.rs @@ -15,15 +15,13 @@ // along with Polkadot. If not, see . use always_assert::always; -use async_std::{ - path::{Path, PathBuf}, -}; +use async_std::path::{Path, PathBuf}; +use parity_scale_codec::{Decode, Encode}; use polkadot_parachain::primitives::ValidationCodeHash; use std::{ collections::HashMap, time::{Duration, SystemTime}, }; -use parity_scale_codec::{Encode, Decode}; /// A final product of preparation process. Contains either a ready to run compiled artifact or /// a description what went wrong. @@ -70,8 +68,8 @@ impl ArtifactId { /// Tries to recover the artifact id from the given file name. #[cfg(test)] pub fn from_file_name(file_name: &str) -> Option { - use std::str::FromStr as _; use polkadot_core_primitives::Hash; + use std::str::FromStr as _; let file_name = file_name.strip_prefix(Self::PREFIX)?; let code_hash = Hash::from_str(file_name).ok()?.into(); @@ -123,9 +121,7 @@ impl Artifacts { #[cfg(test)] pub(crate) fn empty() -> Self { - Self { - artifacts: HashMap::new(), - } + Self { artifacts: HashMap::new() } } /// Returns the state of the given artifact by its ID. @@ -139,10 +135,7 @@ impl Artifacts { /// replacing existing ones. pub fn insert_preparing(&mut self, artifact_id: ArtifactId) { // See the precondition. - always!(self - .artifacts - .insert(artifact_id, ArtifactState::Preparing) - .is_none()); + always!(self.artifacts.insert(artifact_id, ArtifactState::Preparing).is_none()); } /// Insert an artifact with the given ID as "prepared". @@ -164,9 +157,7 @@ impl Artifacts { let mut to_remove = vec![]; for (k, v) in self.artifacts.iter() { - if let ArtifactState::Prepared { - last_time_needed, .. - } = *v { + if let ArtifactState::Prepared { last_time_needed, .. } = *v { if now .duration_since(last_time_needed) .map(|age| age > artifact_ttl) @@ -187,8 +178,8 @@ impl Artifacts { #[cfg(test)] mod tests { + use super::{ArtifactId, Artifacts}; use async_std::path::Path; - use super::{Artifacts, ArtifactId}; use sp_core::H256; use std::str::FromStr; @@ -213,17 +204,24 @@ mod tests { #[test] fn path() { let path = Path::new("/test"); - let hash = H256::from_str("1234567890123456789012345678901234567890123456789012345678901234").unwrap().into(); + let hash = + H256::from_str("1234567890123456789012345678901234567890123456789012345678901234") + .unwrap() + .into(); assert_eq!( ArtifactId::new(hash).path(path).to_str(), - Some("/test/wasmtime_0x1234567890123456789012345678901234567890123456789012345678901234"), + Some( + "/test/wasmtime_0x1234567890123456789012345678901234567890123456789012345678901234" + ), ); } #[test] fn artifacts_removes_cache_on_startup() { - let fake_cache_path = async_std::task::block_on(async move { crate::worker_common::tmpfile("test-cache").await.unwrap() }); + let fake_cache_path = async_std::task::block_on(async move { + crate::worker_common::tmpfile("test-cache").await.unwrap() + }); let fake_artifact_path = { let mut p = fake_cache_path.clone(); p.push("wasmtime_0x1234567890123456789012345678901234567890123456789012345678901234"); diff --git a/polkadot/node/core/pvf/src/execute/mod.rs b/polkadot/node/core/pvf/src/execute/mod.rs index f1580f9d668..86e1d79fc95 100644 --- a/polkadot/node/core/pvf/src/execute/mod.rs +++ b/polkadot/node/core/pvf/src/execute/mod.rs @@ -23,5 +23,5 @@ mod queue; mod worker; -pub use queue::{ToQueue, start}; +pub use queue::{start, ToQueue}; pub use worker::worker_entrypoint; diff --git a/polkadot/node/core/pvf/src/execute/queue.rs b/polkadot/node/core/pvf/src/execute/queue.rs index 98aab605aff..4b940e82db8 100644 --- a/polkadot/node/core/pvf/src/execute/queue.rs +++ b/polkadot/node/core/pvf/src/execute/queue.rs @@ -16,31 +16,27 @@ //! A queue that handles requests for PVF execution. +use super::worker::Outcome; use crate::{ - worker_common::{IdleWorker, WorkerHandle}, host::ResultSender, - LOG_TARGET, InvalidCandidate, ValidationError, + worker_common::{IdleWorker, WorkerHandle}, + InvalidCandidate, ValidationError, LOG_TARGET, }; -use super::worker::Outcome; -use std::{collections::VecDeque, fmt, time::Duration}; +use async_std::path::PathBuf; use futures::{ - Future, FutureExt, channel::mpsc, future::BoxFuture, stream::{FuturesUnordered, StreamExt as _}, + Future, FutureExt, }; -use async_std::path::PathBuf; use slotmap::HopSlotMap; +use std::{collections::VecDeque, fmt, time::Duration}; slotmap::new_key_type! { struct Worker; } #[derive(Debug)] pub enum ToQueue { - Enqueue { - artifact_path: PathBuf, - params: Vec, - result_tx: ResultSender, - }, + Enqueue { artifact_path: PathBuf, params: Vec, result_tx: ResultSender }, } struct ExecuteJob { @@ -86,11 +82,7 @@ impl Workers { /// /// Returns `None` if either worker is not recognized or idle token is absent. fn claim_idle(&mut self, worker: Worker) -> Option { - self - .running - .get_mut(worker)? - .idle - .take() + self.running.get_mut(worker)?.idle.take() } } @@ -167,17 +159,9 @@ async fn purge_dead(workers: &mut Workers) { } fn handle_to_queue(queue: &mut Queue, to_queue: ToQueue) { - let ToQueue::Enqueue { - artifact_path, - params, - result_tx, - } = to_queue; - - let job = ExecuteJob { - artifact_path, - params, - result_tx, - }; + let ToQueue::Enqueue { artifact_path, params, result_tx } = to_queue; + + let job = ExecuteJob { artifact_path, params, result_tx }; if let Some(available) = queue.workers.find_available() { assign(queue, available, job); @@ -194,18 +178,15 @@ async fn handle_mux(queue: &mut Queue, event: QueueEvent) { QueueEvent::Spawn((idle, handle)) => { queue.workers.spawn_inflight -= 1; - let worker = queue.workers.running.insert(WorkerData { - idle: Some(idle), - handle, - }); + let worker = queue.workers.running.insert(WorkerData { idle: Some(idle), handle }); if let Some(job) = queue.queue.pop_front() { assign(queue, worker, job); } - } + }, QueueEvent::StartWork(worker, outcome, result_tx) => { handle_job_finish(queue, worker, outcome, result_tx); - } + }, } } @@ -213,38 +194,22 @@ async fn handle_mux(queue: &mut Queue, event: QueueEvent) { /// worker. Otherwise, puts back into the available workers list. fn handle_job_finish(queue: &mut Queue, worker: Worker, outcome: Outcome, result_tx: ResultSender) { let (idle_worker, result) = match outcome { - Outcome::Ok { - result_descriptor, - duration_ms, - idle_worker, - } => { + Outcome::Ok { result_descriptor, duration_ms, idle_worker } => { // TODO: propagate the soft timeout drop(duration_ms); (Some(idle_worker), Ok(result_descriptor)) - } + }, Outcome::InvalidCandidate { err, idle_worker } => ( Some(idle_worker), - Err(ValidationError::InvalidCandidate( - InvalidCandidate::WorkerReportedError(err), - )), - ), - Outcome::InternalError { err, idle_worker } => ( - Some(idle_worker), - Err(ValidationError::InternalError(err)), - ), - Outcome::HardTimeout => ( - None, - Err(ValidationError::InvalidCandidate( - InvalidCandidate::HardTimeout, - )), - ), - Outcome::IoErr => ( - None, - Err(ValidationError::InvalidCandidate( - InvalidCandidate::AmbigiousWorkerDeath, - )), + Err(ValidationError::InvalidCandidate(InvalidCandidate::WorkerReportedError(err))), ), + Outcome::InternalError { err, idle_worker } => + (Some(idle_worker), Err(ValidationError::InternalError(err))), + Outcome::HardTimeout => + (None, Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout))), + Outcome::IoErr => + (None, Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbigiousWorkerDeath))), }; // First we send the result. It may fail due the other end of the channel being dropped, that's @@ -293,15 +258,11 @@ async fn spawn_worker_task(program_path: PathBuf, spawn_timeout: Duration) -> Qu match super::worker::spawn(&program_path, spawn_timeout).await { Ok((idle, handle)) => break QueueEvent::Spawn((idle, handle)), Err(err) => { - tracing::warn!( - target: LOG_TARGET, - "failed to spawn an execute worker: {:?}", - err, - ); + tracing::warn!(target: LOG_TARGET, "failed to spawn an execute worker: {:?}", err,); // Assume that the failure intermittent and retry after a delay. Delay::new(Duration::from_secs(3)).await; - } + }, } } } @@ -310,14 +271,11 @@ async fn spawn_worker_task(program_path: PathBuf, spawn_timeout: Duration) -> Qu /// /// The worker must be running and idle. fn assign(queue: &mut Queue, worker: Worker, job: ExecuteJob) { - let idle = queue - .workers - .claim_idle(worker) - .expect( - "this caller must supply a worker which is idle and running; + let idle = queue.workers.claim_idle(worker).expect( + "this caller must supply a worker which is idle and running; thus claim_idle cannot return None; - qed." - ); + qed.", + ); queue.mux.push( async move { let outcome = super::worker::start_work(idle, job.artifact_path, job.params).await; @@ -333,12 +291,6 @@ pub fn start( spawn_timeout: Duration, ) -> (mpsc::Sender, impl Future) { let (to_queue_tx, to_queue_rx) = mpsc::channel(20); - let run = Queue::new( - program_path, - worker_capacity, - spawn_timeout, - to_queue_rx, - ) - .run(); + let run = Queue::new(program_path, worker_capacity, spawn_timeout, to_queue_rx).run(); (to_queue_tx, run) } diff --git a/polkadot/node/core/pvf/src/execute/worker.rs b/polkadot/node/core/pvf/src/execute/worker.rs index 12d073c08cf..55d63de9260 100644 --- a/polkadot/node/core/pvf/src/execute/worker.rs +++ b/polkadot/node/core/pvf/src/execute/worker.rs @@ -16,14 +16,13 @@ use crate::{ artifacts::Artifact, - LOG_TARGET, executor_intf::TaskExecutor, worker_common::{ - IdleWorker, SpawnErr, WorkerHandle, bytes_to_path, framed_recv, framed_send, path_to_bytes, - spawn_with_program_path, worker_event_loop, + bytes_to_path, framed_recv, framed_send, path_to_bytes, spawn_with_program_path, + worker_event_loop, IdleWorker, SpawnErr, WorkerHandle, }, + LOG_TARGET, }; -use std::time::{Duration, Instant}; use async_std::{ io, os::unix::net::UnixStream, @@ -31,8 +30,9 @@ use async_std::{ }; use futures::FutureExt; use futures_timer::Delay; +use parity_scale_codec::{Decode, Encode}; use polkadot_parachain::primitives::ValidationResult; -use parity_scale_codec::{Encode, Decode}; +use std::time::{Duration, Instant}; const EXECUTION_TIMEOUT: Duration = Duration::from_secs(3); @@ -43,36 +43,20 @@ pub async fn spawn( program_path: &Path, spawn_timeout: Duration, ) -> Result<(IdleWorker, WorkerHandle), SpawnErr> { - spawn_with_program_path( - "execute", - program_path, - &["execute-worker"], - spawn_timeout, - ) - .await + spawn_with_program_path("execute", program_path, &["execute-worker"], spawn_timeout).await } /// Outcome of PVF execution. pub enum Outcome { /// PVF execution completed successfully and the result is returned. The worker is ready for /// another job. - Ok { - result_descriptor: ValidationResult, - duration_ms: u64, - idle_worker: IdleWorker, - }, + Ok { result_descriptor: ValidationResult, duration_ms: u64, idle_worker: IdleWorker }, /// The candidate validation failed. It may be for example because the preparation process /// produced an error or the wasm execution triggered a trap. - InvalidCandidate { - err: String, - idle_worker: IdleWorker, - }, + InvalidCandidate { err: String, idle_worker: IdleWorker }, /// An internal error happened during the validation. Such an error is most likely related to /// some transient glitch. - InternalError { - err: String, - idle_worker: IdleWorker, - }, + InternalError { err: String, idle_worker: IdleWorker }, /// The execution time exceeded the hard limit. The worker is terminated. HardTimeout, /// An I/O error happened during communication with the worker. This may mean that the worker @@ -97,7 +81,7 @@ pub async fn start_work( ); if send_request(&mut stream, &artifact_path, &validation_params).await.is_err() { - return Outcome::IoErr; + return Outcome::IoErr } let response = futures::select! { @@ -111,22 +95,12 @@ pub async fn start_work( }; match response { - Response::Ok { - result_descriptor, - duration_ms, - } => Outcome::Ok { - result_descriptor, - duration_ms, - idle_worker: IdleWorker { stream, pid }, - }, - Response::InvalidCandidate(err) => Outcome::InvalidCandidate { - err, - idle_worker: IdleWorker { stream, pid }, - }, - Response::InternalError(err) => Outcome::InternalError { - err, - idle_worker: IdleWorker { stream, pid }, - }, + Response::Ok { result_descriptor, duration_ms } => + Outcome::Ok { result_descriptor, duration_ms, idle_worker: IdleWorker { stream, pid } }, + Response::InvalidCandidate(err) => + Outcome::InvalidCandidate { err, idle_worker: IdleWorker { stream, pid } }, + Response::InternalError(err) => + Outcome::InternalError { err, idle_worker: IdleWorker { stream, pid } }, } } @@ -167,10 +141,7 @@ async fn recv_response(stream: &mut UnixStream) -> io::Result { #[derive(Encode, Decode)] enum Response { - Ok { - result_descriptor: ValidationResult, - duration_ms: u64, - }, + Ok { result_descriptor: ValidationResult, duration_ms: u64 }, InvalidCandidate(String), InternalError(String), } @@ -190,10 +161,7 @@ impl Response { pub fn worker_entrypoint(socket_path: &str) { worker_event_loop("execute", socket_path, |mut stream| async move { let executor = TaskExecutor::new().map_err(|e| { - io::Error::new( - io::ErrorKind::Other, - format!("cannot create task executor: {}", e), - ) + io::Error::new(io::ErrorKind::Other, format!("cannot create task executor: {}", e)) })?; loop { let (artifact_path, params) = recv_request(&mut stream).await?; @@ -215,13 +183,12 @@ async fn validate_using_artifact( spawner: &TaskExecutor, ) -> Response { let artifact_bytes = match async_std::fs::read(artifact_path).await { - Err(e) => { + Err(e) => return Response::InternalError(format!( "failed to read the artifact at {}: {:?}", artifact_path.display(), e, - )) - } + )), Ok(b) => b, }; @@ -231,47 +198,31 @@ async fn validate_using_artifact( }; let compiled_artifact = match &artifact { - Artifact::PrevalidationErr(msg) => { - return Response::format_invalid("prevalidation", msg); - } - Artifact::PreparationErr(msg) => { - return Response::format_invalid("preparation", msg); - } - Artifact::DidntMakeIt => { - return Response::format_invalid("preparation timeout", ""); - } + Artifact::PrevalidationErr(msg) => return Response::format_invalid("prevalidation", msg), + Artifact::PreparationErr(msg) => return Response::format_invalid("preparation", msg), + Artifact::DidntMakeIt => return Response::format_invalid("preparation timeout", ""), Artifact::Compiled { compiled_artifact } => compiled_artifact, }; let validation_started_at = Instant::now(); - let descriptor_bytes = - match unsafe { - // SAFETY: this should be safe since the compiled artifact passed here comes from the - // file created by the prepare workers. These files are obtained by calling - // [`executor_intf::prepare`]. - crate::executor_intf::execute(compiled_artifact, params, spawner.clone()) - } { - Err(err) => { - return Response::format_invalid("execute", &err.to_string()); - } - Ok(d) => d, - }; + let descriptor_bytes = match unsafe { + // SAFETY: this should be safe since the compiled artifact passed here comes from the + // file created by the prepare workers. These files are obtained by calling + // [`executor_intf::prepare`]. + crate::executor_intf::execute(compiled_artifact, params, spawner.clone()) + } { + Err(err) => return Response::format_invalid("execute", &err.to_string()), + Ok(d) => d, + }; let duration_ms = validation_started_at.elapsed().as_millis() as u64; let result_descriptor = match ValidationResult::decode(&mut &descriptor_bytes[..]) { - Err(err) => { - return Response::InvalidCandidate(format!( - "validation result decoding failed: {}", - err - )) - } + Err(err) => + return Response::InvalidCandidate(format!("validation result decoding failed: {}", err)), Ok(r) => r, }; - Response::Ok { - result_descriptor, - duration_ms, - } + Response::Ok { result_descriptor, duration_ms } } diff --git a/polkadot/node/core/pvf/src/executor_intf.rs b/polkadot/node/core/pvf/src/executor_intf.rs index 0e19b3d59b7..a1ccbbf897e 100644 --- a/polkadot/node/core/pvf/src/executor_intf.rs +++ b/polkadot/node/core/pvf/src/executor_intf.rs @@ -16,16 +16,14 @@ //! Interface to the Substrate Executor -use std::any::{TypeId, Any}; use sc_executor_common::{ runtime_blob::RuntimeBlob, wasm_runtime::{InvokeMethod, WasmModule as _}, }; -use sc_executor_wasmtime::{Config, Semantics, DeterministicStackLimit}; -use sp_core::{ - storage::{ChildInfo, TrackedStorageKey}, -}; +use sc_executor_wasmtime::{Config, DeterministicStackLimit, Semantics}; +use sp_core::storage::{ChildInfo, TrackedStorageKey}; use sp_wasm_interface::HostFunctions as _; +use std::any::{Any, TypeId}; const CONFIG: Config = Config { // TODO: Make sure we don't use more than 1GB: https://github.com/paritytech/polkadot/issues/699 @@ -95,9 +93,7 @@ pub unsafe fn execute( CONFIG, HostFunctions::host_functions(), )?; - runtime - .new_instance()? - .call(InvokeMethod::Export("validate_block"), params) + runtime.new_instance()?.call(InvokeMethod::Export("validate_block"), params) })? } diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index ca571a49daa..720a8a52172 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -21,22 +21,19 @@ //! [`ValidationHost`], that allows communication with that event-loop. use crate::{ - Priority, Pvf, ValidationError, - artifacts::{Artifacts, ArtifactState, ArtifactId}, - execute, prepare, -}; -use std::{ - collections::HashMap, - time::{Duration, SystemTime}, + artifacts::{ArtifactId, ArtifactState, Artifacts}, + execute, prepare, Priority, Pvf, ValidationError, }; use always_assert::never; -use async_std::{ - path::{Path, PathBuf}, -}; -use polkadot_parachain::primitives::ValidationResult; +use async_std::path::{Path, PathBuf}; use futures::{ - Future, FutureExt, SinkExt, StreamExt, channel::{mpsc, oneshot}, + Future, FutureExt, SinkExt, StreamExt, +}; +use polkadot_parachain::primitives::ValidationResult; +use std::{ + collections::HashMap, + time::{Duration, SystemTime}, }; /// An alias to not spell the type for the oneshot sender for the PVF execution result. @@ -64,12 +61,7 @@ impl ValidationHost { result_tx: ResultSender, ) -> Result<(), String> { self.to_host_tx - .send(ToHost::ExecutePvf { - pvf, - params, - priority, - result_tx, - }) + .send(ToHost::ExecutePvf { pvf, params, priority, result_tx }) .await .map_err(|_| "the inner loop hung up".to_string()) } @@ -89,15 +81,8 @@ impl ValidationHost { } enum ToHost { - ExecutePvf { - pvf: Pvf, - params: Vec, - priority: Priority, - result_tx: ResultSender, - }, - HeadsUp { - active_pvfs: Vec, - }, + ExecutePvf { pvf: Pvf, params: Vec, priority: Priority, result_tx: ResultSender }, + HeadsUp { active_pvfs: Vec }, } /// Configuration for the validation host. @@ -180,12 +165,7 @@ pub fn start(config: Config) -> (ValidationHost, impl Future) { let run = async move { let artifacts = Artifacts::new(&config.cache_path).await; - futures::pin_mut!( - run_prepare_queue, - run_prepare_pool, - run_execute_queue, - run_sweeper - ); + futures::pin_mut!(run_prepare_queue, run_prepare_pool, run_execute_queue, run_sweeper); run( Inner { @@ -375,12 +355,7 @@ async fn handle_to_host( to_host: ToHost, ) -> Result<(), Fatal> { match to_host { - ToHost::ExecutePvf { - pvf, - params, - priority, - result_tx, - } => { + ToHost::ExecutePvf { pvf, params, priority, result_tx } => { handle_execute_pvf( cache_path, artifacts, @@ -393,10 +368,10 @@ async fn handle_to_host( result_tx, ) .await?; - } + }, ToHost::HeadsUp { active_pvfs } => { handle_heads_up(artifacts, prepare_queue, active_pvfs).await?; - } + }, } Ok(()) @@ -417,9 +392,7 @@ async fn handle_execute_pvf( if let Some(state) = artifacts.artifact_state_mut(&artifact_id) { match state { - ArtifactState::Prepared { - ref mut last_time_needed, - } => { + ArtifactState::Prepared { ref mut last_time_needed } => { *last_time_needed = SystemTime::now(); send_execute( @@ -431,19 +404,16 @@ async fn handle_execute_pvf( }, ) .await?; - } + }, ArtifactState::Preparing => { send_prepare( prepare_queue, - prepare::ToQueue::Amend { - priority, - artifact_id: artifact_id.clone(), - }, + prepare::ToQueue::Amend { priority, artifact_id: artifact_id.clone() }, ) .await?; awaiting_prepare.add(artifact_id, params, result_tx); - } + }, } } else { // Artifact is unknown: register it and enqueue a job with the corresponding priority and @@ -454,7 +424,7 @@ async fn handle_execute_pvf( awaiting_prepare.add(artifact_id, params, result_tx); } - return Ok(()); + return Ok(()) } async fn handle_heads_up( @@ -468,15 +438,13 @@ async fn handle_heads_up( let artifact_id = active_pvf.as_artifact_id(); if let Some(state) = artifacts.artifact_state_mut(&artifact_id) { match state { - ArtifactState::Prepared { - last_time_needed, .. - } => { + ArtifactState::Prepared { last_time_needed, .. } => { *last_time_needed = now; - } + }, ArtifactState::Preparing => { // Already preparing. We don't need to send a priority amend either because // it can't get any lower than the background. - } + }, } } else { // The artifact is unknown: register it and put a background job into the prepare queue. @@ -484,10 +452,7 @@ async fn handle_heads_up( send_prepare( prepare_queue, - prepare::ToQueue::Enqueue { - priority: Priority::Background, - pvf: active_pvf, - }, + prepare::ToQueue::Enqueue { priority: Priority::Background, pvf: active_pvf }, ) .await?; } @@ -512,8 +477,8 @@ async fn handle_prepare_done( // thus the artifact cannot be unknown, only preparing; // qed. never!("an unknown artifact was prepared: {:?}", artifact_id); - return Ok(()); - } + return Ok(()) + }, Some(ArtifactState::Prepared { .. }) => { // before sending request to prepare, the artifact is inserted with `preparing` state; // the requests are deduplicated for the same artifact id; @@ -521,8 +486,8 @@ async fn handle_prepare_done( // thus the artifact cannot be prepared, only preparing; // qed. never!("the artifact is already prepared: {:?}", artifact_id); - return Ok(()); - } + return Ok(()) + }, Some(state @ ArtifactState::Preparing) => state, }; @@ -534,24 +499,18 @@ async fn handle_prepare_done( if result_tx.is_canceled() { // Preparation could've taken quite a bit of time and the requester may be not interested // in execution anymore, in which case we just skip the request. - continue; + continue } send_execute( execute_queue, - execute::ToQueue::Enqueue { - artifact_path: artifact_path.clone(), - params, - result_tx, - }, + execute::ToQueue::Enqueue { artifact_path: artifact_path.clone(), params, result_tx }, ) .await?; } // Now consider the artifact prepared. - *state = ArtifactState::Prepared { - last_time_needed: SystemTime::now(), - }; + *state = ArtifactState::Prepared { last_time_needed: SystemTime::now() }; Ok(()) } @@ -592,7 +551,7 @@ async fn sweeper_task(mut sweeper_rx: mpsc::Receiver) { None => break, Some(condemned) => { let _ = async_std::fs::remove_file(condemned).await; - } + }, } } } @@ -611,8 +570,8 @@ fn pulse_every(interval: std::time::Duration) -> impl futures::Stream #[cfg(test)] mod tests { use super::*; - use futures::future::BoxFuture; use assert_matches::assert_matches; + use futures::future::BoxFuture; #[async_std::test] async fn pulse_test() { @@ -634,9 +593,7 @@ mod tests { } fn artifact_path(descriminator: u32) -> PathBuf { - artifact_id(descriminator) - .path(&PathBuf::from(std::env::temp_dir())) - .to_owned() + artifact_id(descriminator).path(&PathBuf::from(std::env::temp_dir())).to_owned() } struct Builder { @@ -673,13 +630,7 @@ mod tests { } impl Test { - fn new( - Builder { - cleanup_pulse_interval, - artifact_ttl, - artifacts, - }: Builder, - ) -> Self { + fn new(Builder { cleanup_pulse_interval, artifact_ttl, artifacts }: Builder) -> Self { let cache_path = PathBuf::from(std::env::temp_dir()); let (to_host_tx, to_host_rx) = mpsc::channel(10); @@ -727,20 +678,14 @@ mod tests { async fn poll_and_recv_to_prepare_queue(&mut self) -> prepare::ToQueue { let to_prepare_queue_rx = &mut self.to_prepare_queue_rx; - run_until( - &mut self.run, - async { to_prepare_queue_rx.next().await.unwrap() }.boxed(), - ) - .await + run_until(&mut self.run, async { to_prepare_queue_rx.next().await.unwrap() }.boxed()) + .await } async fn poll_and_recv_to_execute_queue(&mut self) -> execute::ToQueue { let to_execute_queue_rx = &mut self.to_execute_queue_rx; - run_until( - &mut self.run, - async { to_execute_queue_rx.next().await.unwrap() }.boxed(), - ) - .await + run_until(&mut self.run, async { to_execute_queue_rx.next().await.unwrap() }.boxed()) + .await } async fn poll_ensure_to_execute_queue_is_empty(&mut self) { @@ -798,7 +743,7 @@ mod tests { } if let Poll::Ready(r) = futures::poll!(&mut *fut) { - break r; + break r } if futures::poll!(&mut *task).is_ready() { @@ -831,9 +776,7 @@ mod tests { let mut test = builder.build(); let mut host = test.host_handle(); - host.heads_up(vec![Pvf::from_discriminator(1)]) - .await - .unwrap(); + host.heads_up(vec![Pvf::from_discriminator(1)]).await.unwrap(); let to_sweeper_rx = &mut test.to_sweeper_rx; run_until( @@ -847,9 +790,7 @@ mod tests { // Extend TTL for the first artifact and make sure we don't receive another file removal // request. - host.heads_up(vec![Pvf::from_discriminator(1)]) - .await - .unwrap(); + host.heads_up(vec![Pvf::from_discriminator(1)]).await.unwrap(); test.poll_ensure_to_sweeper_is_empty().await; } @@ -858,9 +799,7 @@ mod tests { let mut test = Builder::default().build(); let mut host = test.host_handle(); - host.heads_up(vec![Pvf::from_discriminator(1)]) - .await - .unwrap(); + host.heads_up(vec![Pvf::from_discriminator(1)]).await.unwrap(); // Run until we receive a prepare request. let prepare_q_rx = &mut test.to_prepare_queue_rx; @@ -877,22 +816,14 @@ mod tests { .await; let (result_tx, _result_rx) = oneshot::channel(); - host.execute_pvf( - Pvf::from_discriminator(1), - vec![], - Priority::Critical, - result_tx, - ) - .await - .unwrap(); + host.execute_pvf(Pvf::from_discriminator(1), vec![], Priority::Critical, result_tx) + .await + .unwrap(); run_until( &mut test.run, async { - assert_matches!( - prepare_q_rx.next().await.unwrap(), - prepare::ToQueue::Amend { .. } - ); + assert_matches!(prepare_q_rx.next().await.unwrap(), prepare::ToQueue::Amend { .. }); } .boxed(), ) @@ -907,14 +838,9 @@ mod tests { let mut host = test.host_handle(); let (result_tx, result_rx_pvf_1_1) = oneshot::channel(); - host.execute_pvf( - Pvf::from_discriminator(1), - b"pvf1".to_vec(), - Priority::Normal, - result_tx, - ) - .await - .unwrap(); + host.execute_pvf(Pvf::from_discriminator(1), b"pvf1".to_vec(), Priority::Normal, result_tx) + .await + .unwrap(); let (result_tx, result_rx_pvf_1_2) = oneshot::channel(); host.execute_pvf( @@ -927,14 +853,9 @@ mod tests { .unwrap(); let (result_tx, result_rx_pvf_2) = oneshot::channel(); - host.execute_pvf( - Pvf::from_discriminator(2), - b"pvf2".to_vec(), - Priority::Normal, - result_tx, - ) - .await - .unwrap(); + host.execute_pvf(Pvf::from_discriminator(2), b"pvf2".to_vec(), Priority::Normal, result_tx) + .await + .unwrap(); assert_matches!( test.poll_and_recv_to_prepare_queue().await, @@ -972,39 +893,27 @@ mod tests { ); result_tx_pvf_1_1 - .send(Err(ValidationError::InvalidCandidate( - InvalidCandidate::AmbigiousWorkerDeath, - ))) + .send(Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbigiousWorkerDeath))) .unwrap(); assert_matches!( result_rx_pvf_1_1.now_or_never().unwrap().unwrap(), - Err(ValidationError::InvalidCandidate( - InvalidCandidate::AmbigiousWorkerDeath, - )) + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbigiousWorkerDeath,)) ); result_tx_pvf_1_2 - .send(Err(ValidationError::InvalidCandidate( - InvalidCandidate::AmbigiousWorkerDeath, - ))) + .send(Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbigiousWorkerDeath))) .unwrap(); assert_matches!( result_rx_pvf_1_2.now_or_never().unwrap().unwrap(), - Err(ValidationError::InvalidCandidate( - InvalidCandidate::AmbigiousWorkerDeath, - )) + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbigiousWorkerDeath,)) ); result_tx_pvf_2 - .send(Err(ValidationError::InvalidCandidate( - InvalidCandidate::AmbigiousWorkerDeath, - ))) + .send(Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbigiousWorkerDeath))) .unwrap(); assert_matches!( result_rx_pvf_2.now_or_never().unwrap().unwrap(), - Err(ValidationError::InvalidCandidate( - InvalidCandidate::AmbigiousWorkerDeath, - )) + Err(ValidationError::InvalidCandidate(InvalidCandidate::AmbigiousWorkerDeath,)) ); } @@ -1014,14 +923,9 @@ mod tests { let mut host = test.host_handle(); let (result_tx, result_rx) = oneshot::channel(); - host.execute_pvf( - Pvf::from_discriminator(1), - b"pvf1".to_vec(), - Priority::Normal, - result_tx, - ) - .await - .unwrap(); + host.execute_pvf(Pvf::from_discriminator(1), b"pvf1".to_vec(), Priority::Normal, result_tx) + .await + .unwrap(); assert_matches!( test.poll_and_recv_to_prepare_queue().await, diff --git a/polkadot/node/core/pvf/src/lib.rs b/polkadot/node/core/pvf/src/lib.rs index 04719944cbc..bd72a5e1ed0 100644 --- a/polkadot/node/core/pvf/src/lib.rs +++ b/polkadot/node/core/pvf/src/lib.rs @@ -91,7 +91,7 @@ pub mod testing; #[doc(hidden)] pub use sp_tracing; -pub use error::{ValidationError, InvalidCandidate}; +pub use error::{InvalidCandidate, ValidationError}; pub use priority::Priority; pub use pvf::Pvf; diff --git a/polkadot/node/core/pvf/src/prepare/mod.rs b/polkadot/node/core/pvf/src/prepare/mod.rs index 080dd069e29..ac03cefc6fd 100644 --- a/polkadot/node/core/pvf/src/prepare/mod.rs +++ b/polkadot/node/core/pvf/src/prepare/mod.rs @@ -26,6 +26,6 @@ mod pool; mod queue; mod worker; -pub use queue::{ToQueue, FromQueue, start as start_queue}; pub use pool::start as start_pool; +pub use queue::{start as start_queue, FromQueue, ToQueue}; pub use worker::worker_entrypoint; diff --git a/polkadot/node/core/pvf/src/prepare/pool.rs b/polkadot/node/core/pvf/src/prepare/pool.rs index 2c92e023f7a..a42cb7a12b7 100644 --- a/polkadot/node/core/pvf/src/prepare/pool.rs +++ b/polkadot/node/core/pvf/src/prepare/pool.rs @@ -14,21 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use super::worker::{self, Outcome}; use crate::{ worker_common::{IdleWorker, WorkerHandle}, LOG_TARGET, }; -use super::{ - worker::{self, Outcome}, -}; -use std::{fmt, sync::Arc, task::Poll, time::Duration}; +use always_assert::never; +use assert_matches::assert_matches; use async_std::path::{Path, PathBuf}; use futures::{ - Future, FutureExt, StreamExt, channel::mpsc, future::BoxFuture, stream::FuturesUnordered, + channel::mpsc, future::BoxFuture, stream::FuturesUnordered, Future, FutureExt, StreamExt, }; use slotmap::HopSlotMap; -use assert_matches::assert_matches; -use always_assert::never; +use std::{fmt, sync::Arc, task::Poll, time::Duration}; slotmap::new_key_type! { pub struct Worker; } @@ -170,7 +168,7 @@ async fn purge_dead( // The idle token is missing, meaning this worker is now occupied: skip it. This is // because the worker process is observed by the work task and should it reach the // deadline or be terminated it will be handled by the corresponding mux event. - continue; + continue } if let Poll::Ready(()) = futures::poll!(&mut data.handle) { @@ -197,13 +195,8 @@ fn handle_to_pool( match to_pool { ToPool::Spawn => { mux.push(spawn_worker_task(program_path.to_owned(), spawn_timeout).boxed()); - } - ToPool::StartWork { - worker, - code, - artifact_path, - background_priority, - } => { + }, + ToPool::StartWork { worker, code, artifact_path, background_priority } => { if let Some(data) = spawned.get_mut(worker) { if let Some(idle) = data.idle.take() { mux.push( @@ -213,7 +206,7 @@ fn handle_to_pool( code, cache_path.to_owned(), artifact_path, - background_priority + background_priority, ) .boxed(), ); @@ -229,16 +222,15 @@ fn handle_to_pool( // That's a relatively normal situation since the queue may send `start_work` and // before receiving it the pool would report that the worker died. } - } + }, ToPool::Kill(worker) => { // It may be absent if it were previously already removed by `purge_dead`. let _ = spawned.remove(worker); - } - ToPool::BumpPriority(worker) => { + }, + ToPool::BumpPriority(worker) => if let Some(data) = spawned.get(worker) { worker::bump_priority(&data.handle); - } - } + }, } } @@ -249,15 +241,11 @@ async fn spawn_worker_task(program_path: PathBuf, spawn_timeout: Duration) -> Po match worker::spawn(&program_path, spawn_timeout).await { Ok((idle, handle)) => break PoolEvent::Spawn(idle, handle), Err(err) => { - tracing::warn!( - target: LOG_TARGET, - "failed to spawn a prepare worker: {:?}", - err, - ); + tracing::warn!(target: LOG_TARGET, "failed to spawn a prepare worker: {:?}", err,); // Assume that the failure intermittent and retry after a delay. Delay::new(Duration::from_secs(3)).await; - } + }, } } } @@ -282,15 +270,12 @@ fn handle_mux( ) -> Result<(), Fatal> { match event { PoolEvent::Spawn(idle, handle) => { - let worker = spawned.insert(WorkerData { - idle: Some(idle), - handle, - }); + let worker = spawned.insert(WorkerData { idle: Some(idle), handle }); reply(from_pool, FromPool::Spawned(worker))?; Ok(()) - } + }, PoolEvent::StartWork(worker, outcome) => { match outcome { Outcome::Concluded(idle) => { @@ -298,8 +283,8 @@ fn handle_mux( None => { // Perhaps the worker was killed meanwhile and the result is no longer // relevant. - return Ok(()); - } + return Ok(()) + }, Some(data) => data, }; @@ -311,23 +296,23 @@ fn handle_mux( reply(from_pool, FromPool::Concluded(worker, false))?; Ok(()) - } + }, Outcome::Unreachable => { if spawned.remove(worker).is_some() { reply(from_pool, FromPool::Rip(worker))?; } Ok(()) - } + }, Outcome::DidntMakeIt => { if spawned.remove(worker).is_some() { reply(from_pool, FromPool::Concluded(worker, true))?; } Ok(()) - } + }, } - } + }, } } @@ -340,11 +325,7 @@ pub fn start( program_path: PathBuf, cache_path: PathBuf, spawn_timeout: Duration, -) -> ( - mpsc::Sender, - mpsc::UnboundedReceiver, - impl Future, -) { +) -> (mpsc::Sender, mpsc::UnboundedReceiver, impl Future) { let (to_pool_tx, to_pool_rx) = mpsc::channel(10); let (from_pool_tx, from_pool_rx) = mpsc::unbounded(); diff --git a/polkadot/node/core/pvf/src/prepare/queue.rs b/polkadot/node/core/pvf/src/prepare/queue.rs index 53ccc0d6cb4..6e68bdae4e1 100644 --- a/polkadot/node/core/pvf/src/prepare/queue.rs +++ b/polkadot/node/core/pvf/src/prepare/queue.rs @@ -16,14 +16,12 @@ //! A queue that handles requests for PVF preparation. -use super::{ - pool::{self, Worker}, -}; -use crate::{LOG_TARGET, Priority, Pvf, artifacts::ArtifactId}; -use futures::{Future, SinkExt, channel::mpsc, stream::StreamExt as _}; -use std::collections::{HashMap, VecDeque}; -use async_std::path::PathBuf; +use super::pool::{self, Worker}; +use crate::{artifacts::ArtifactId, Priority, Pvf, LOG_TARGET}; use always_assert::{always, never}; +use async_std::path::PathBuf; +use futures::{channel::mpsc, stream::StreamExt as _, Future, SinkExt}; +use std::collections::{HashMap, VecDeque}; /// A request to pool. #[derive(Debug)] @@ -35,10 +33,7 @@ pub enum ToQueue { /// [`ToQueue::Amend`]. Enqueue { priority: Priority, pvf: Pvf }, /// Amends the priority for the given [`ArtifactId`] if it is running. If it's not, then it's noop. - Amend { - priority: Priority, - artifact_id: ArtifactId, - }, + Amend { priority: Priority, artifact_id: ArtifactId }, } /// A response from queue. @@ -62,11 +57,7 @@ struct Limits { impl Limits { /// Returns `true` if the queue is allowed to request one more worker. fn can_afford_one_more(&self, spawned_num: usize, critical: bool) -> bool { - let cap = if critical { - self.hard_capacity - } else { - self.soft_capacity - }; + let cap = if critical { self.hard_capacity } else { self.soft_capacity }; spawned_num < cap } @@ -179,10 +170,7 @@ impl Queue { from_pool_rx, cache_path, spawn_inflight: 0, - limits: Limits { - hard_capacity, - soft_capacity, - }, + limits: Limits { hard_capacity, soft_capacity }, jobs: slotmap::SlotMap::with_key(), unscheduled: Unscheduled::default(), artifact_id_to_job: HashMap::new(), @@ -194,7 +182,7 @@ impl Queue { macro_rules! break_if_fatal { ($expr:expr) => { if let Err(Fatal) = $expr { - break; + break } }; } @@ -215,13 +203,10 @@ async fn handle_to_queue(queue: &mut Queue, to_queue: ToQueue) -> Result<(), Fat match to_queue { ToQueue::Enqueue { priority, pvf } => { handle_enqueue(queue, priority, pvf).await?; - } - ToQueue::Amend { - priority, - artifact_id, - } => { + }, + ToQueue::Amend { priority, artifact_id } => { handle_amend(queue, priority, artifact_id).await?; - } + }, } Ok(()) } @@ -241,14 +226,10 @@ async fn handle_enqueue(queue: &mut Queue, priority: Priority, pvf: Pvf) -> Resu "duplicate `enqueue` command received for {:?}", artifact_id, ); - return Ok(()); + return Ok(()) } - let job = queue.jobs.insert(JobData { - priority, - pvf, - worker: None, - }); + let job = queue.jobs.insert(JobData { priority, pvf, worker: None }); queue.artifact_id_to_job.insert(artifact_id, job); if let Some(available) = find_idle_worker(queue) { @@ -264,12 +245,7 @@ async fn handle_enqueue(queue: &mut Queue, priority: Priority, pvf: Pvf) -> Resu } fn find_idle_worker(queue: &mut Queue) -> Option { - queue - .workers - .iter() - .filter(|(_, data)| data.is_idle()) - .map(|(k, _)| k) - .next() + queue.workers.iter().filter(|(_, data)| data.is_idle()).map(|(k, _)| k).next() } async fn handle_amend( @@ -336,8 +312,8 @@ async fn handle_worker_concluded( // Assume the conditions holds, then this never is not hit; // qed. never!("never_none, {}", stringify!($expr)); - return Ok(()); - } + return Ok(()) + }, } }; } @@ -388,10 +364,7 @@ async fn handle_worker_concluded( spawn_extra_worker(queue, false).await?; } } else { - if queue - .limits - .should_cull(queue.workers.len() + queue.spawn_inflight) - { + if queue.limits.should_cull(queue.workers.len() + queue.spawn_inflight) { // We no longer need services of this worker. Kill it. queue.workers.remove(worker); send_pool(&mut queue.to_pool_tx, pool::ToPool::Kill(worker)).await?; @@ -412,20 +385,16 @@ async fn handle_worker_rip(queue: &mut Queue, worker: Worker) -> Result<(), Fata if let Some(WorkerData { job: Some(job), .. }) = worker_data { // This is an edge case where the worker ripped after we sent assignment but before it // was received by the pool. - let priority = queue - .jobs - .get(job) - .map(|data| data.priority) - .unwrap_or_else(|| { - // job is inserted upon enqueue and removed on concluded signal; - // this is enclosed in the if statement that narrows the situation to before - // conclusion; - // that means that the job still exists and is known; - // this path cannot be hit; - // qed. - never!("the job of the ripped worker must be known but it is not"); - Priority::Normal - }); + let priority = queue.jobs.get(job).map(|data| data.priority).unwrap_or_else(|| { + // job is inserted upon enqueue and removed on concluded signal; + // this is enclosed in the if statement that narrows the situation to before + // conclusion; + // that means that the job still exists and is known; + // this path cannot be hit; + // qed. + never!("the job of the ripped worker must be known but it is not"); + Priority::Normal + }); queue.unscheduled.readd(priority, job); } @@ -500,11 +469,7 @@ pub fn start( cache_path: PathBuf, to_pool_tx: mpsc::Sender, from_pool_rx: mpsc::UnboundedReceiver, -) -> ( - mpsc::Sender, - mpsc::UnboundedReceiver, - impl Future, -) { +) -> (mpsc::Sender, mpsc::UnboundedReceiver, impl Future) { let (to_queue_tx, to_queue_rx) = mpsc::channel(150); let (from_queue_tx, from_queue_rx) = mpsc::unbounded(); @@ -524,11 +489,11 @@ pub fn start( #[cfg(test)] mod tests { - use slotmap::SlotMap; + use super::*; use assert_matches::assert_matches; - use futures::{FutureExt, future::BoxFuture}; + use futures::{future::BoxFuture, FutureExt}; + use slotmap::SlotMap; use std::task::Poll; - use super::*; /// Creates a new PVF which artifact id can be uniquely identified by the given number. fn pvf(descriminator: u32) -> Pvf { @@ -549,7 +514,7 @@ mod tests { } if let Poll::Ready(r) = futures::poll!(&mut *fut) { - break r; + break r } if futures::poll!(&mut *task).is_ready() { @@ -597,37 +562,21 @@ mod tests { } fn send_queue(&mut self, to_queue: ToQueue) { - self.to_queue_tx - .send(to_queue) - .now_or_never() - .unwrap() - .unwrap(); + self.to_queue_tx.send(to_queue).now_or_never().unwrap().unwrap(); } async fn poll_and_recv_from_queue(&mut self) -> FromQueue { let from_queue_rx = &mut self.from_queue_rx; - run_until( - &mut self.run, - async { from_queue_rx.next().await.unwrap() }.boxed(), - ) - .await + run_until(&mut self.run, async { from_queue_rx.next().await.unwrap() }.boxed()).await } fn send_from_pool(&mut self, from_pool: pool::FromPool) { - self.from_pool_tx - .send(from_pool) - .now_or_never() - .unwrap() - .unwrap(); + self.from_pool_tx.send(from_pool).now_or_never().unwrap().unwrap(); } async fn poll_and_recv_to_pool(&mut self) -> pool::ToPool { let to_pool_rx = &mut self.to_pool_rx; - run_until( - &mut self.run, - async { to_pool_rx.next().await.unwrap() }.boxed(), - ) - .await + run_until(&mut self.run, async { to_pool_rx.next().await.unwrap() }.boxed()).await } async fn poll_ensure_to_pool_is_empty(&mut self) { @@ -655,10 +604,7 @@ mod tests { async fn properly_concludes() { let mut test = Test::new(2, 2); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Background, - pvf: pvf(1), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Background, pvf: pvf(1) }); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); let w = test.workers.insert(()); @@ -675,18 +621,9 @@ mod tests { async fn dont_spawn_over_soft_limit_unless_critical() { let mut test = Test::new(2, 3); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(1), - }); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(2), - }); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(3), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(1) }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(2) }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(3) }); // Receive only two spawns. assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); @@ -699,27 +636,15 @@ mod tests { test.send_from_pool(pool::FromPool::Spawned(w2)); // Get two start works. - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); test.send_from_pool(pool::FromPool::Concluded(w1, false)); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); // Enqueue a critical job. - test.send_queue(ToQueue::Enqueue { - priority: Priority::Critical, - pvf: pvf(4), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Critical, pvf: pvf(4) }); // 2 out of 2 are working, but there is a critical job incoming. That means that spawning // another worker is warranted. @@ -730,23 +655,14 @@ mod tests { async fn cull_unwanted() { let mut test = Test::new(1, 2); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(1), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(1) }); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); let w1 = test.workers.insert(()); test.send_from_pool(pool::FromPool::Spawned(w1)); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); // Enqueue a critical job, which warrants spawning over the soft limit. - test.send_queue(ToQueue::Enqueue { - priority: Priority::Critical, - pvf: pvf(2), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Critical, pvf: pvf(2) }); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); // However, before the new worker had a chance to spawn, the first worker finishes with its @@ -764,47 +680,29 @@ mod tests { async fn bump_prio_on_urgency_change() { let mut test = Test::new(2, 2); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Background, - pvf: pvf(1), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Background, pvf: pvf(1) }); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); let w = test.workers.insert(()); test.send_from_pool(pool::FromPool::Spawned(w)); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); test.send_queue(ToQueue::Amend { priority: Priority::Normal, artifact_id: pvf(1).as_artifact_id(), }); - assert_eq!( - test.poll_and_recv_to_pool().await, - pool::ToPool::BumpPriority(w) - ); + assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::BumpPriority(w)); } #[async_std::test] async fn worker_mass_die_out_doesnt_stall_queue() { let mut test = Test::new(2, 2); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(1), - }); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(2), - }); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(3), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(1) }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(2) }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(3) }); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); @@ -815,14 +713,8 @@ mod tests { test.send_from_pool(pool::FromPool::Spawned(w1)); test.send_from_pool(pool::FromPool::Spawned(w2)); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); // Conclude worker 1 and rip it. test.send_from_pool(pool::FromPool::Concluded(w1, true)); @@ -840,20 +732,14 @@ mod tests { async fn doesnt_resurrect_ripped_worker_if_no_work() { let mut test = Test::new(2, 2); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(1), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(1) }); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); let w1 = test.workers.insert(()); test.send_from_pool(pool::FromPool::Spawned(w1)); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); test.send_from_pool(pool::FromPool::Concluded(w1, true)); test.poll_ensure_to_pool_is_empty().await; @@ -863,10 +749,7 @@ mod tests { async fn rip_for_start_work() { let mut test = Test::new(2, 2); - test.send_queue(ToQueue::Enqueue { - priority: Priority::Normal, - pvf: pvf(1), - }); + test.send_queue(ToQueue::Enqueue { priority: Priority::Normal, pvf: pvf(1) }); assert_eq!(test.poll_and_recv_to_pool().await, pool::ToPool::Spawn); @@ -875,10 +758,7 @@ mod tests { // Now, to the interesting part. After the queue normally issues the start_work command to // the pool, before receiving the command the queue may report that the worker ripped. - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); test.send_from_pool(pool::FromPool::Rip(w1)); // In this case, the pool should spawn a new worker and request it to work on the item. @@ -886,9 +766,6 @@ mod tests { let w2 = test.workers.insert(()); test.send_from_pool(pool::FromPool::Spawned(w2)); - assert_matches!( - test.poll_and_recv_to_pool().await, - pool::ToPool::StartWork { .. } - ); + assert_matches!(test.poll_and_recv_to_pool().await, pool::ToPool::StartWork { .. }); } } diff --git a/polkadot/node/core/pvf/src/prepare/worker.rs b/polkadot/node/core/pvf/src/prepare/worker.rs index 2de955eb5a7..fc5c9ce350b 100644 --- a/polkadot/node/core/pvf/src/prepare/worker.rs +++ b/polkadot/node/core/pvf/src/prepare/worker.rs @@ -15,17 +15,17 @@ // along with Polkadot. If not, see . use crate::{ - LOG_TARGET, artifacts::Artifact, worker_common::{ - IdleWorker, SpawnErr, WorkerHandle, bytes_to_path, framed_recv, framed_send, path_to_bytes, - spawn_with_program_path, tmpfile_in, worker_event_loop, + bytes_to_path, framed_recv, framed_send, path_to_bytes, spawn_with_program_path, + tmpfile_in, worker_event_loop, IdleWorker, SpawnErr, WorkerHandle, }, + LOG_TARGET, }; use async_std::{ io, os::unix::net::UnixStream, - path::{PathBuf, Path}, + path::{Path, PathBuf}, }; use futures::FutureExt as _; use futures_timer::Delay; @@ -43,13 +43,7 @@ pub async fn spawn( program_path: &Path, spawn_timeout: Duration, ) -> Result<(IdleWorker, WorkerHandle), SpawnErr> { - spawn_with_program_path( - "prepare", - program_path, - &["prepare-worker"], - spawn_timeout, - ) - .await + spawn_with_program_path("prepare", program_path, &["prepare-worker"], spawn_timeout).await } pub enum Outcome { @@ -99,7 +93,7 @@ pub async fn start_work( "failed to send a prepare request: {:?}", err, ); - return Outcome::Unreachable; + return Outcome::Unreachable } // Wait for the result from the worker, keeping in mind that there may be a timeout, the @@ -172,13 +166,13 @@ pub async fn start_work( Selected::Done => { renice(pid, NICENESS_FOREGROUND); Outcome::Concluded(IdleWorker { stream, pid }) - } + }, Selected::IoErr | Selected::Deadline => { let bytes = Artifact::DidntMakeIt.serialize(); // best effort: there is nothing we can do here if the write fails. let _ = async_std::fs::write(&artifact_path, &bytes).await; Outcome::DidntMakeIt - } + }, } }) .await @@ -202,8 +196,8 @@ where "failed to create a temp file for the artifact: {:?}", err, ); - return Outcome::DidntMakeIt; - } + return Outcome::DidntMakeIt + }, }; let outcome = f(tmp_file.clone()).await; @@ -223,7 +217,7 @@ where "failed to remove the tmp file: {:?}", err, ); - } + }, } outcome @@ -304,9 +298,7 @@ pub fn worker_entrypoint(socket_path: &str) { fn prepare_artifact(code: &[u8]) -> Artifact { let blob = match crate::executor_intf::prevalidate(code) { - Err(err) => { - return Artifact::PrevalidationErr(format!("{:?}", err)); - } + Err(err) => return Artifact::PrevalidationErr(format!("{:?}", err)), Ok(b) => b, }; diff --git a/polkadot/node/core/pvf/src/testing.rs b/polkadot/node/core/pvf/src/testing.rs index 35ba80c1bdc..20cf85151f8 100644 --- a/polkadot/node/core/pvf/src/testing.rs +++ b/polkadot/node/core/pvf/src/testing.rs @@ -29,9 +29,10 @@ pub fn validate_candidate( code: &[u8], params: &[u8], ) -> Result, Box> { - use crate::executor_intf::{prevalidate, prepare, execute, TaskExecutor}; + use crate::executor_intf::{execute, prepare, prevalidate, TaskExecutor}; - let code = sp_maybe_compressed_blob::decompress(code, 10 * 1024 * 1024).expect("Decompressing code failed"); + let code = sp_maybe_compressed_blob::decompress(code, 10 * 1024 * 1024) + .expect("Decompressing code failed"); let blob = prevalidate(&*code)?; let artifact = prepare(blob)?; @@ -61,15 +62,15 @@ macro_rules! decl_puppet_worker_main { match subcommand.as_ref() { "sleep" => { std::thread::sleep(std::time::Duration::from_secs(5)); - } + }, "prepare-worker" => { let socket_path = &args[2]; $crate::prepare_worker_entrypoint(socket_path); - } + }, "execute-worker" => { let socket_path = &args[2]; $crate::execute_worker_entrypoint(socket_path); - } + }, other => panic!("unknown subcommand: {}", other), } } diff --git a/polkadot/node/core/pvf/src/worker_common.rs b/polkadot/node/core/pvf/src/worker_common.rs index 02f7bce4ea6..0c142776764 100644 --- a/polkadot/node/core/pvf/src/worker_common.rs +++ b/polkadot/node/core/pvf/src/worker_common.rs @@ -20,12 +20,13 @@ use crate::LOG_TARGET; use async_std::{ io, os::unix::net::{UnixListener, UnixStream}, - path::{PathBuf, Path}, + path::{Path, PathBuf}, }; use futures::{ - AsyncRead, AsyncWrite, AsyncReadExt as _, AsyncWriteExt as _, FutureExt as _, never::Never, + never::Never, AsyncRead, AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _, FutureExt as _, }; use futures_timer::Delay; +use pin_project::pin_project; use rand::Rng; use std::{ fmt, mem, @@ -33,7 +34,6 @@ use std::{ task::{Context, Poll}, time::Duration, }; -use pin_project::pin_project; /// This is publicly exposed only for integration tests. #[doc(hidden)] @@ -47,9 +47,7 @@ pub async fn spawn_with_program_path( with_transient_socket_path(debug_id, |socket_path| { let socket_path = socket_path.to_owned(); async move { - let listener = UnixListener::bind(&socket_path) - .await - .map_err(|_| SpawnErr::Bind)?; + let listener = UnixListener::bind(&socket_path).await.map_err(|_| SpawnErr::Bind)?; let handle = WorkerHandle::spawn(program_path, extra_args, socket_path) .map_err(|_| SpawnErr::ProcessSpawn)?; @@ -97,11 +95,7 @@ pub async fn tmpfile_in(prefix: &str, dir: &Path) -> io::Result { let mut buf = Vec::with_capacity(prefix.len() + DESCRIMINATOR_LEN); buf.extend(prefix.as_bytes()); - buf.extend( - rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(DESCRIMINATOR_LEN), - ); + buf.extend(rand::thread_rng().sample_iter(&Alphanumeric).take(DESCRIMINATOR_LEN)); let s = std::str::from_utf8(&buf) .expect("the string is collected from a valid utf-8 sequence; qed"); @@ -120,9 +114,7 @@ pub async fn tmpfile_in(prefix: &str, dir: &Path) -> io::Result { } } - Err( - io::Error::new(io::ErrorKind::Other, "failed to create a temporary file") - ) + Err(io::Error::new(io::ErrorKind::Other, "failed to create a temporary file")) } /// The same as [`tmpfile_in`], but uses [`std::env::temp_dir`] as the directory. @@ -245,17 +237,17 @@ impl futures::Future for WorkerHandle { Ok(0) => { // 0 means EOF means the child was terminated. Resolve. Poll::Ready(()) - } + }, Ok(_bytes_read) => { // weird, we've read something. Pretend that never happened and reschedule ourselves. cx.waker().wake_by_ref(); Poll::Pending - } + }, Err(_) => { // The implementation is guaranteed to not to return WouldBlock and Interrupted. This // leaves us with a legit errors which we suppose were due to termination. Poll::Ready(()) - } + }, } } } diff --git a/polkadot/node/core/pvf/tests/it/adder.rs b/polkadot/node/core/pvf/tests/it/adder.rs index 97af2ef4efc..147af508cc4 100644 --- a/polkadot/node/core/pvf/tests/it/adder.rs +++ b/polkadot/node/core/pvf/tests/it/adder.rs @@ -15,22 +15,16 @@ // along with Polkadot. If not, see . use super::TestHost; -use polkadot_parachain::{ - primitives::{ - RelayChainBlockNumber, BlockData as GenericBlockData, HeadData as GenericHeadData, - ValidationParams, - }, -}; +use adder::{hash_state, BlockData, HeadData}; use parity_scale_codec::{Decode, Encode}; -use adder::{HeadData, BlockData, hash_state}; +use polkadot_parachain::primitives::{ + BlockData as GenericBlockData, HeadData as GenericHeadData, RelayChainBlockNumber, + ValidationParams, +}; #[async_std::test] async fn execute_good_on_parent() { - let parent_head = HeadData { - number: 0, - parent_hash: [0; 32], - post_state: hash_state(0), - }; + let parent_head = HeadData { number: 0, parent_hash: [0; 32], post_state: hash_state(0) }; let block_data = BlockData { state: 0, add: 512 }; @@ -65,16 +59,9 @@ async fn execute_good_chain_on_parent() { let host = TestHost::new(); for add in 0..10 { - let parent_head = HeadData { - number, - parent_hash, - post_state: hash_state(last_state), - }; + let parent_head = HeadData { number, parent_hash, post_state: hash_state(last_state) }; - let block_data = BlockData { - state: last_state, - add, - }; + let block_data = BlockData { state: last_state, add }; let ret = host .validate_candidate( @@ -103,11 +90,7 @@ async fn execute_good_chain_on_parent() { #[async_std::test] async fn execute_bad_on_parent() { - let parent_head = HeadData { - number: 0, - parent_hash: [0; 32], - post_state: hash_state(0), - }; + let parent_head = HeadData { number: 0, parent_hash: [0; 32], post_state: hash_state(0) }; let block_data = BlockData { state: 256, // start state is wrong. diff --git a/polkadot/node/core/pvf/tests/it/main.rs b/polkadot/node/core/pvf/tests/it/main.rs index c559675bbcd..57fea2e2ca3 100644 --- a/polkadot/node/core/pvf/tests/it/main.rs +++ b/polkadot/node/core/pvf/tests/it/main.rs @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use polkadot_node_core_pvf::{Pvf, ValidationHost, start, Config, InvalidCandidate, ValidationError}; -use polkadot_parachain::primitives::{BlockData, ValidationParams, ValidationResult}; -use parity_scale_codec::Encode as _; use async_std::sync::Mutex; +use parity_scale_codec::Encode as _; +use polkadot_node_core_pvf::{ + start, Config, InvalidCandidate, Pvf, ValidationError, ValidationHost, +}; +use polkadot_parachain::primitives::{BlockData, ValidationParams, ValidationResult}; mod adder; mod worker_common; @@ -44,10 +46,7 @@ impl TestHost { f(&mut config); let (host, task) = start(config); let _ = async_std::task::spawn(task); - Self { - _cache_dir: cache_dir, - host: Mutex::new(host), - } + Self { _cache_dir: cache_dir, host: Mutex::new(host) } } async fn validate_candidate( @@ -57,7 +56,8 @@ impl TestHost { ) -> Result { let (result_tx, result_rx) = futures::channel::oneshot::channel(); - let code = sp_maybe_compressed_blob::decompress(code, 16 * 1024 * 1024).expect("Compression works"); + let code = sp_maybe_compressed_blob::decompress(code, 16 * 1024 * 1024) + .expect("Compression works"); self.host .lock() @@ -91,7 +91,7 @@ async fn terminates_on_timeout() { .await; match result { - Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)) => {} + Err(ValidationError::InvalidCandidate(InvalidCandidate::HardTimeout)) => {}, r => panic!("{:?}", r), } } @@ -124,8 +124,8 @@ async fn parallel_execution() { // total time should be < 2 x EXECUTION_TIMEOUT_SEC const EXECUTION_TIMEOUT_SEC: u64 = 3; assert!( - std::time::Instant::now().duration_since(start) - < std::time::Duration::from_secs(EXECUTION_TIMEOUT_SEC * 2) + std::time::Instant::now().duration_since(start) < + std::time::Duration::from_secs(EXECUTION_TIMEOUT_SEC * 2) ); } diff --git a/polkadot/node/core/pvf/tests/it/worker_common.rs b/polkadot/node/core/pvf/tests/it/worker_common.rs index ec77bd71044..464b80a9fe5 100644 --- a/polkadot/node/core/pvf/tests/it/worker_common.rs +++ b/polkadot/node/core/pvf/tests/it/worker_common.rs @@ -20,13 +20,9 @@ use std::time::Duration; #[async_std::test] async fn spawn_timeout() { - let result = spawn_with_program_path( - "integration-test", - PUPPET_EXE, - &["sleep"], - Duration::from_secs(2), - ) - .await; + let result = + spawn_with_program_path("integration-test", PUPPET_EXE, &["sleep"], Duration::from_secs(2)) + .await; assert!(matches!(result, Err(SpawnErr::AcceptTimeout))); } diff --git a/polkadot/node/core/runtime-api/src/cache.rs b/polkadot/node/core/runtime-api/src/cache.rs index 0077ac07635..962959a2384 100644 --- a/polkadot/node/core/runtime-api/src/cache.rs +++ b/polkadot/node/core/runtime-api/src/cache.rs @@ -71,18 +71,32 @@ impl ResidentSize for VecOfDoesNotAllocate { pub(crate) struct RequestResultCache { authorities: MemoryLruCache>, validators: MemoryLruCache>>, - validator_groups: MemoryLruCache>, GroupRotationInfo)>>, + validator_groups: + MemoryLruCache>, GroupRotationInfo)>>, availability_cores: MemoryLruCache>>, - persisted_validation_data: MemoryLruCache<(Hash, ParaId, OccupiedCoreAssumption), ResidentSizeOf>>, - check_validation_outputs: MemoryLruCache<(Hash, ParaId, CandidateCommitments), ResidentSizeOf>, + persisted_validation_data: MemoryLruCache< + (Hash, ParaId, OccupiedCoreAssumption), + ResidentSizeOf>, + >, + check_validation_outputs: + MemoryLruCache<(Hash, ParaId, CandidateCommitments), ResidentSizeOf>, session_index_for_child: MemoryLruCache>, - validation_code: MemoryLruCache<(Hash, ParaId, OccupiedCoreAssumption), ResidentSizeOf>>, - validation_code_by_hash: MemoryLruCache>>, - candidate_pending_availability: MemoryLruCache<(Hash, ParaId), ResidentSizeOf>>, + validation_code: MemoryLruCache< + (Hash, ParaId, OccupiedCoreAssumption), + ResidentSizeOf>, + >, + validation_code_by_hash: + MemoryLruCache>>, + candidate_pending_availability: + MemoryLruCache<(Hash, ParaId), ResidentSizeOf>>, candidate_events: MemoryLruCache>>, session_info: MemoryLruCache>>, - dmq_contents: MemoryLruCache<(Hash, ParaId), ResidentSizeOf>>>, - inbound_hrmp_channels_contents: MemoryLruCache<(Hash, ParaId), ResidentSizeOf>>>>, + dmq_contents: + MemoryLruCache<(Hash, ParaId), ResidentSizeOf>>>, + inbound_hrmp_channels_contents: MemoryLruCache< + (Hash, ParaId), + ResidentSizeOf>>>, + >, current_babe_epoch: MemoryLruCache>, } @@ -98,7 +112,9 @@ impl Default for RequestResultCache { session_index_for_child: MemoryLruCache::new(SESSION_INDEX_FOR_CHILD_CACHE_SIZE), validation_code: MemoryLruCache::new(VALIDATION_CODE_CACHE_SIZE), validation_code_by_hash: MemoryLruCache::new(VALIDATION_CODE_CACHE_SIZE), - candidate_pending_availability: MemoryLruCache::new(CANDIDATE_PENDING_AVAILABILITY_CACHE_SIZE), + candidate_pending_availability: MemoryLruCache::new( + CANDIDATE_PENDING_AVAILABILITY_CACHE_SIZE, + ), candidate_events: MemoryLruCache::new(CANDIDATE_EVENTS_CACHE_SIZE), session_info: MemoryLruCache::new(SESSION_INFO_CACHE_SIZE), dmq_contents: MemoryLruCache::new(DMQ_CONTENTS_CACHE_SIZE), @@ -109,11 +125,18 @@ impl Default for RequestResultCache { } impl RequestResultCache { - pub(crate) fn authorities(&mut self, relay_parent: &Hash) -> Option<&Vec> { + pub(crate) fn authorities( + &mut self, + relay_parent: &Hash, + ) -> Option<&Vec> { self.authorities.get(relay_parent).map(|v| &v.0) } - pub(crate) fn cache_authorities(&mut self, relay_parent: Hash, authorities: Vec) { + pub(crate) fn cache_authorities( + &mut self, + relay_parent: Hash, + authorities: Vec, + ) { self.authorities.insert(relay_parent, VecOfDoesNotAllocate(authorities)); } @@ -125,11 +148,18 @@ impl RequestResultCache { self.validators.insert(relay_parent, ResidentSizeOf(validators)); } - pub(crate) fn validator_groups(&mut self, relay_parent: &Hash) -> Option<&(Vec>, GroupRotationInfo)> { + pub(crate) fn validator_groups( + &mut self, + relay_parent: &Hash, + ) -> Option<&(Vec>, GroupRotationInfo)> { self.validator_groups.get(relay_parent).map(|v| &v.0) } - pub(crate) fn cache_validator_groups(&mut self, relay_parent: Hash, groups: (Vec>, GroupRotationInfo)) { + pub(crate) fn cache_validator_groups( + &mut self, + relay_parent: Hash, + groups: (Vec>, GroupRotationInfo), + ) { self.validator_groups.insert(relay_parent, ResidentSizeOf(groups)); } @@ -141,19 +171,33 @@ impl RequestResultCache { self.availability_cores.insert(relay_parent, ResidentSizeOf(cores)); } - pub(crate) fn persisted_validation_data(&mut self, key: (Hash, ParaId, OccupiedCoreAssumption)) -> Option<&Option> { + pub(crate) fn persisted_validation_data( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + ) -> Option<&Option> { self.persisted_validation_data.get(&key).map(|v| &v.0) } - pub(crate) fn cache_persisted_validation_data(&mut self, key: (Hash, ParaId, OccupiedCoreAssumption), data: Option) { + pub(crate) fn cache_persisted_validation_data( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + data: Option, + ) { self.persisted_validation_data.insert(key, ResidentSizeOf(data)); } - pub(crate) fn check_validation_outputs(&mut self, key: (Hash, ParaId, CandidateCommitments)) -> Option<&bool> { + pub(crate) fn check_validation_outputs( + &mut self, + key: (Hash, ParaId, CandidateCommitments), + ) -> Option<&bool> { self.check_validation_outputs.get(&key).map(|v| &v.0) } - pub(crate) fn cache_check_validation_outputs(&mut self, key: (Hash, ParaId, CandidateCommitments), value: bool) { + pub(crate) fn cache_check_validation_outputs( + &mut self, + key: (Hash, ParaId, CandidateCommitments), + value: bool, + ) { self.check_validation_outputs.insert(key, ResidentSizeOf(value)); } @@ -161,33 +205,58 @@ impl RequestResultCache { self.session_index_for_child.get(relay_parent).map(|v| &v.0) } - pub(crate) fn cache_session_index_for_child(&mut self, relay_parent: Hash, index: SessionIndex) { + pub(crate) fn cache_session_index_for_child( + &mut self, + relay_parent: Hash, + index: SessionIndex, + ) { self.session_index_for_child.insert(relay_parent, ResidentSizeOf(index)); } - pub(crate) fn validation_code(&mut self, key: (Hash, ParaId, OccupiedCoreAssumption)) -> Option<&Option> { + pub(crate) fn validation_code( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + ) -> Option<&Option> { self.validation_code.get(&key).map(|v| &v.0) } - pub(crate) fn cache_validation_code(&mut self, key: (Hash, ParaId, OccupiedCoreAssumption), value: Option) { + pub(crate) fn cache_validation_code( + &mut self, + key: (Hash, ParaId, OccupiedCoreAssumption), + value: Option, + ) { self.validation_code.insert(key, ResidentSizeOf(value)); } // the actual key is `ValidationCodeHash` (`Hash` is ignored), // but we keep the interface that way to keep the macro simple - pub(crate) fn validation_code_by_hash(&mut self, key: (Hash, ValidationCodeHash)) -> Option<&Option> { + pub(crate) fn validation_code_by_hash( + &mut self, + key: (Hash, ValidationCodeHash), + ) -> Option<&Option> { self.validation_code_by_hash.get(&key.1).map(|v| &v.0) } - pub(crate) fn cache_validation_code_by_hash(&mut self, key: ValidationCodeHash, value: Option) { + pub(crate) fn cache_validation_code_by_hash( + &mut self, + key: ValidationCodeHash, + value: Option, + ) { self.validation_code_by_hash.insert(key, ResidentSizeOf(value)); } - pub(crate) fn candidate_pending_availability(&mut self, key: (Hash, ParaId)) -> Option<&Option> { + pub(crate) fn candidate_pending_availability( + &mut self, + key: (Hash, ParaId), + ) -> Option<&Option> { self.candidate_pending_availability.get(&key).map(|v| &v.0) } - pub(crate) fn cache_candidate_pending_availability(&mut self, key: (Hash, ParaId), value: Option) { + pub(crate) fn cache_candidate_pending_availability( + &mut self, + key: (Hash, ParaId), + value: Option, + ) { self.candidate_pending_availability.insert(key, ResidentSizeOf(value)); } @@ -195,11 +264,18 @@ impl RequestResultCache { self.candidate_events.get(relay_parent).map(|v| &v.0) } - pub(crate) fn cache_candidate_events(&mut self, relay_parent: Hash, events: Vec) { + pub(crate) fn cache_candidate_events( + &mut self, + relay_parent: Hash, + events: Vec, + ) { self.candidate_events.insert(relay_parent, ResidentSizeOf(events)); } - pub(crate) fn session_info(&mut self, key: (Hash, SessionIndex)) -> Option<&Option> { + pub(crate) fn session_info( + &mut self, + key: (Hash, SessionIndex), + ) -> Option<&Option> { self.session_info.get(&key.1).map(|v| &v.0) } @@ -207,19 +283,33 @@ impl RequestResultCache { self.session_info.insert(key, ResidentSizeOf(value)); } - pub(crate) fn dmq_contents(&mut self, key: (Hash, ParaId)) -> Option<&Vec>> { + pub(crate) fn dmq_contents( + &mut self, + key: (Hash, ParaId), + ) -> Option<&Vec>> { self.dmq_contents.get(&key).map(|v| &v.0) } - pub(crate) fn cache_dmq_contents(&mut self, key: (Hash, ParaId), value: Vec>) { + pub(crate) fn cache_dmq_contents( + &mut self, + key: (Hash, ParaId), + value: Vec>, + ) { self.dmq_contents.insert(key, ResidentSizeOf(value)); } - pub(crate) fn inbound_hrmp_channels_contents(&mut self, key: (Hash, ParaId)) -> Option<&BTreeMap>>> { + pub(crate) fn inbound_hrmp_channels_contents( + &mut self, + key: (Hash, ParaId), + ) -> Option<&BTreeMap>>> { self.inbound_hrmp_channels_contents.get(&key).map(|v| &v.0) } - pub(crate) fn cache_inbound_hrmp_channel_contents(&mut self, key: (Hash, ParaId), value: BTreeMap>>) { + pub(crate) fn cache_inbound_hrmp_channel_contents( + &mut self, + key: (Hash, ParaId), + value: BTreeMap>>, + ) { self.inbound_hrmp_channels_contents.insert(key, ResidentSizeOf(value)); } @@ -246,6 +336,10 @@ pub(crate) enum RequestResult { CandidateEvents(Hash, Vec), SessionInfo(Hash, SessionIndex, Option), DmqContents(Hash, ParaId, Vec>), - InboundHrmpChannelsContents(Hash, ParaId, BTreeMap>>), + InboundHrmpChannelsContents( + Hash, + ParaId, + BTreeMap>>, + ), CurrentBabeEpoch(Hash, Epoch), } diff --git a/polkadot/node/core/runtime-api/src/lib.rs b/polkadot/node/core/runtime-api/src/lib.rs index 54eb95b4cdb..cf2ec719c8e 100644 --- a/polkadot/node/core/runtime-api/src/lib.rs +++ b/polkadot/node/core/runtime-api/src/lib.rs @@ -22,27 +22,23 @@ #![deny(unused_crate_dependencies)] #![warn(missing_docs)] +use polkadot_node_subsystem_util::metrics::{self, prometheus}; +use polkadot_primitives::v1::{Block, BlockId, Hash, ParachainHost}; use polkadot_subsystem::{ - SubsystemError, SubsystemResult, - FromOverseer, OverseerSignal, SpawnedSubsystem, - SubsystemContext, errors::RuntimeApiError, - messages::{ - RuntimeApiMessage, RuntimeApiRequest as Request, - }, - overseer, + messages::{RuntimeApiMessage, RuntimeApiRequest as Request}, + overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, + SubsystemResult, }; -use polkadot_node_subsystem_util::metrics::{self, prometheus}; -use polkadot_primitives::v1::{Block, BlockId, Hash, ParachainHost}; use sp_api::ProvideRuntimeApi; use sp_authority_discovery::AuthorityDiscoveryApi; -use sp_core::traits::SpawnNamed; use sp_consensus_babe::BabeApi; +use sp_core::traits::SpawnNamed; -use futures::{prelude::*, stream::FuturesUnordered, channel::oneshot, select}; -use std::{sync::Arc, collections::VecDeque, pin::Pin}; use cache::{RequestResult, RequestResultCache}; +use futures::{channel::oneshot, prelude::*, select, stream::FuturesUnordered}; +use std::{collections::VecDeque, pin::Pin, sync::Arc}; mod cache; @@ -75,7 +71,11 @@ pub struct RuntimeApiSubsystem { impl RuntimeApiSubsystem { /// Create a new Runtime API subsystem wrapping the given client and metrics. - pub fn new(client: Arc, metrics: Metrics, spawn_handle: impl SpawnNamed + 'static) -> Self { + pub fn new( + client: Arc, + metrics: Metrics, + spawn_handle: impl SpawnNamed + 'static, + ) -> Self { RuntimeApiSubsystem { client, metrics, @@ -87,21 +87,20 @@ impl RuntimeApiSubsystem { } } -impl overseer::Subsystem for RuntimeApiSubsystem where +impl overseer::Subsystem for RuntimeApiSubsystem +where Client: ProvideRuntimeApi + Send + 'static + Sync, Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Context: SubsystemContext, Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { - SpawnedSubsystem { - future: run(ctx, self).boxed(), - name: "runtime-api-subsystem", - } + SpawnedSubsystem { future: run(ctx, self).boxed(), name: "runtime-api-subsystem" } } } -impl RuntimeApiSubsystem where +impl RuntimeApiSubsystem +where Client: ProvideRuntimeApi + Send + 'static + Sync, Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, { @@ -117,26 +116,31 @@ impl RuntimeApiSubsystem where self.requests_cache.cache_validator_groups(relay_parent, groups), AvailabilityCores(relay_parent, cores) => self.requests_cache.cache_availability_cores(relay_parent, cores), - PersistedValidationData(relay_parent, para_id, assumption, data) => - self.requests_cache.cache_persisted_validation_data((relay_parent, para_id, assumption), data), - CheckValidationOutputs(relay_parent, para_id, commitments, b) => - self.requests_cache.cache_check_validation_outputs((relay_parent, para_id, commitments), b), + PersistedValidationData(relay_parent, para_id, assumption, data) => self + .requests_cache + .cache_persisted_validation_data((relay_parent, para_id, assumption), data), + CheckValidationOutputs(relay_parent, para_id, commitments, b) => self + .requests_cache + .cache_check_validation_outputs((relay_parent, para_id, commitments), b), SessionIndexForChild(relay_parent, session_index) => self.requests_cache.cache_session_index_for_child(relay_parent, session_index), - ValidationCode(relay_parent, para_id, assumption, code) => - self.requests_cache.cache_validation_code((relay_parent, para_id, assumption), code), + ValidationCode(relay_parent, para_id, assumption, code) => self + .requests_cache + .cache_validation_code((relay_parent, para_id, assumption), code), ValidationCodeByHash(_relay_parent, validation_code_hash, code) => self.requests_cache.cache_validation_code_by_hash(validation_code_hash, code), - CandidatePendingAvailability(relay_parent, para_id, candidate) => - self.requests_cache.cache_candidate_pending_availability((relay_parent, para_id), candidate), + CandidatePendingAvailability(relay_parent, para_id, candidate) => self + .requests_cache + .cache_candidate_pending_availability((relay_parent, para_id), candidate), CandidateEvents(relay_parent, events) => self.requests_cache.cache_candidate_events(relay_parent, events), SessionInfo(_relay_parent, session_index, info) => self.requests_cache.cache_session_info(session_index, info), DmqContents(relay_parent, para_id, messages) => self.requests_cache.cache_dmq_contents((relay_parent, para_id), messages), - InboundHrmpChannelsContents(relay_parent, para_id, contents) => - self.requests_cache.cache_inbound_hrmp_channel_contents((relay_parent, para_id), contents), + InboundHrmpChannelsContents(relay_parent, para_id, contents) => self + .requests_cache + .cache_inbound_hrmp_channel_contents((relay_parent, para_id), contents), CurrentBabeEpoch(relay_parent, epoch) => self.requests_cache.cache_current_babe_epoch(relay_parent, epoch), } @@ -169,12 +173,12 @@ impl RuntimeApiSubsystem where } match request { - Request::Authorities(sender) => query!(authorities(), sender) - .map(|sender| Request::Authorities(sender)), - Request::Validators(sender) => query!(validators(), sender) - .map(|sender| Request::Validators(sender)), - Request::ValidatorGroups(sender) => query!(validator_groups(), sender) - .map(|sender| Request::ValidatorGroups(sender)), + Request::Authorities(sender) => + query!(authorities(), sender).map(|sender| Request::Authorities(sender)), + Request::Validators(sender) => + query!(validators(), sender).map(|sender| Request::Validators(sender)), + Request::ValidatorGroups(sender) => + query!(validator_groups(), sender).map(|sender| Request::ValidatorGroups(sender)), Request::AvailabilityCores(sender) => query!(availability_cores(), sender) .map(|sender| Request::AvailabilityCores(sender)), Request::PersistedValidationData(para, assumption, sender) => @@ -183,9 +187,8 @@ impl RuntimeApiSubsystem where Request::CheckValidationOutputs(para, commitments, sender) => query!(check_validation_outputs(para, commitments), sender) .map(|sender| Request::CheckValidationOutputs(para, commitments, sender)), - Request::SessionIndexForChild(sender) => - query!(session_index_for_child(), sender) - .map(|sender| Request::SessionIndexForChild(sender)), + Request::SessionIndexForChild(sender) => query!(session_index_for_child(), sender) + .map(|sender| Request::SessionIndexForChild(sender)), Request::ValidationCode(para, assumption, sender) => query!(validation_code(para, assumption), sender) .map(|sender| Request::ValidationCode(para, assumption, sender)), @@ -195,18 +198,17 @@ impl RuntimeApiSubsystem where Request::CandidatePendingAvailability(para, sender) => query!(candidate_pending_availability(para), sender) .map(|sender| Request::CandidatePendingAvailability(para, sender)), - Request::CandidateEvents(sender) => query!(candidate_events(), sender) - .map(|sender| Request::CandidateEvents(sender)), + Request::CandidateEvents(sender) => + query!(candidate_events(), sender).map(|sender| Request::CandidateEvents(sender)), Request::SessionInfo(index, sender) => query!(session_info(index), sender) .map(|sender| Request::SessionInfo(index, sender)), - Request::DmqContents(id, sender) => query!(dmq_contents(id), sender) - .map(|sender| Request::DmqContents(id, sender)), + Request::DmqContents(id, sender) => + query!(dmq_contents(id), sender).map(|sender| Request::DmqContents(id, sender)), Request::InboundHrmpChannelsContents(id, sender) => query!(inbound_hrmp_channels_contents(id), sender) .map(|sender| Request::InboundHrmpChannelsContents(id, sender)), Request::CurrentBabeEpoch(sender) => - query!(current_babe_epoch(), sender) - .map(|sender| Request::CurrentBabeEpoch(sender)), + query!(current_babe_epoch(), sender).map(|sender| Request::CurrentBabeEpoch(sender)), } } @@ -224,14 +226,10 @@ impl RuntimeApiSubsystem where }; let request = async move { - let result = make_runtime_api_request( - client, - metrics, - relay_parent, - request, - ); + let result = make_runtime_api_request(client, metrics, relay_parent, request); let _ = sender.send(result); - }.boxed(); + } + .boxed(); if self.active_requests.len() >= MAX_PARALLEL_REQUESTS { self.waiting_requests.push_back((request, receiver)); @@ -271,7 +269,8 @@ impl RuntimeApiSubsystem where async fn run( mut ctx: Context, mut subsystem: RuntimeApiSubsystem, -) -> SubsystemResult<()> where +) -> SubsystemResult<()> +where Client: ProvideRuntimeApi + Send + Sync + 'static, Client::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Context: SubsystemContext, @@ -323,12 +322,14 @@ where Request::Authorities(sender) => query!(Authorities, authorities(), sender), Request::Validators(sender) => query!(Validators, validators(), sender), Request::ValidatorGroups(sender) => query!(ValidatorGroups, validator_groups(), sender), - Request::AvailabilityCores(sender) => query!(AvailabilityCores, availability_cores(), sender), + Request::AvailabilityCores(sender) => + query!(AvailabilityCores, availability_cores(), sender), Request::PersistedValidationData(para, assumption, sender) => query!(PersistedValidationData, persisted_validation_data(para, assumption), sender), Request::CheckValidationOutputs(para, commitments, sender) => query!(CheckValidationOutputs, check_validation_outputs(para, commitments), sender), - Request::SessionIndexForChild(sender) => query!(SessionIndexForChild, session_index_for_child(), sender), + Request::SessionIndexForChild(sender) => + query!(SessionIndexForChild, session_index_for_child(), sender), Request::ValidationCode(para, assumption, sender) => query!(ValidationCode, validation_code(para, assumption), sender), Request::ValidationCodeByHash(validation_code_hash, sender) => @@ -338,7 +339,8 @@ where Request::CandidateEvents(sender) => query!(CandidateEvents, candidate_events(), sender), Request::SessionInfo(index, sender) => query!(SessionInfo, session_info(index), sender), Request::DmqContents(id, sender) => query!(DmqContents, dmq_contents(id), sender), - Request::InboundHrmpChannelsContents(id, sender) => query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), sender), + Request::InboundHrmpChannelsContents(id, sender) => + query!(InboundHrmpChannelsContents, inbound_hrmp_channels_contents(id), sender), Request::CurrentBabeEpoch(sender) => query!(CurrentBabeEpoch, current_epoch(), sender), } } @@ -365,12 +367,15 @@ impl Metrics { } fn on_cached_request(&self) { - self.0.as_ref() + self.0 + .as_ref() .map(|metrics| metrics.chain_api_requests.with_label_values(&["cached"]).inc()); } /// Provide a timer for `make_runtime_api_request` which observes on drop. - fn time_make_runtime_api_request(&self) -> Option { + fn time_make_runtime_api_request( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.make_runtime_api_request.start_timer()) } } @@ -389,12 +394,10 @@ impl metrics::Metrics for Metrics { registry, )?, make_runtime_api_request: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_runtime_api_make_runtime_api_request", - "Time spent within `runtime_api::make_runtime_api_request`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_runtime_api_make_runtime_api_request", + "Time spent within `runtime_api::make_runtime_api_request`", + ))?, registry, )?, }; diff --git a/polkadot/node/core/runtime-api/src/tests.rs b/polkadot/node/core/runtime-api/src/tests.rs index 787dc8884b0..e96bd56fea4 100644 --- a/polkadot/node/core/runtime-api/src/tests.rs +++ b/polkadot/node/core/runtime-api/src/tests.rs @@ -16,18 +16,19 @@ use super::*; +use futures::channel::oneshot; +use polkadot_node_primitives::{BabeAllowedSlots, BabeEpoch, BabeEpochConfiguration}; +use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_primitives::v1::{ - ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, PersistedValidationData, - Id as ParaId, OccupiedCoreAssumption, SessionIndex, ValidationCode, - CommittedCandidateReceipt, CandidateEvent, InboundDownwardMessage, - InboundHrmpMessage, SessionInfo, AuthorityDiscoveryId, ValidationCodeHash, + AuthorityDiscoveryId, CandidateEvent, CommittedCandidateReceipt, CoreState, GroupRotationInfo, + Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, + PersistedValidationData, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, + ValidatorId, ValidatorIndex, }; -use polkadot_node_subsystem_test_helpers as test_helpers; use sp_core::testing::TaskExecutor; -use std::{collections::{HashMap, BTreeMap}, sync::{Arc, Mutex}}; -use futures::channel::oneshot; -use polkadot_node_primitives::{ - BabeEpoch, BabeEpochConfiguration, BabeAllowedSlots, +use std::{ + collections::{BTreeMap, HashMap}, + sync::{Arc, Mutex}, }; #[derive(Default, Clone)] @@ -201,9 +202,11 @@ fn requests_authorities() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::Authorities(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::Authorities(tx)), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), runtime_api.authorities); @@ -225,9 +228,11 @@ fn requests_validators() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::Validators(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::Validators(tx)), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), runtime_api.validators); @@ -249,9 +254,11 @@ fn requests_validator_groups() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::ValidatorGroups(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::ValidatorGroups(tx)), + }) + .await; assert_eq!(rx.await.unwrap().unwrap().0, runtime_api.validator_groups); @@ -273,9 +280,11 @@ fn requests_availability_cores() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), runtime_api.availability_cores); @@ -302,22 +311,26 @@ fn requests_persisted_validation_data() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::PersistedValidationData(para_a, OccupiedCoreAssumption::Included, tx) - ), - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::PersistedValidationData(para_a, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::PersistedValidationData(para_b, OccupiedCoreAssumption::Included, tx) - ), - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::PersistedValidationData(para_b, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), None); @@ -347,36 +360,26 @@ fn requests_check_validation_outputs() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::CheckValidationOutputs( - para_a, - commitments.clone(), - tx, + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CheckValidationOutputs(para_a, commitments.clone(), tx), ), - ) - }).await; - assert_eq!( - rx.await.unwrap().unwrap(), - runtime_api.validation_outputs_results[¶_a], - ); + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), runtime_api.validation_outputs_results[¶_a],); let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::CheckValidationOutputs( - para_b, - commitments, - tx, + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CheckValidationOutputs(para_b, commitments, tx), ), - ) - }).await; - assert_eq!( - rx.await.unwrap().unwrap(), - runtime_api.validation_outputs_results[¶_b], - ); + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), runtime_api.validation_outputs_results[¶_b],); ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; }; @@ -396,9 +399,11 @@ fn requests_session_index_for_child() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::SessionIndexForChild(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::SessionIndexForChild(tx)), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), runtime_api.session_index_for_child); @@ -424,9 +429,14 @@ fn requests_session_info() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::SessionInfo(session_index, tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::SessionInfo(session_index, tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); @@ -454,22 +464,26 @@ fn requests_validation_code() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::ValidationCode(para_a, OccupiedCoreAssumption::Included, tx) - ), - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCode(para_a, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::ValidationCode(para_b, OccupiedCoreAssumption::Included, tx) - ), - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCode(para_b, OccupiedCoreAssumption::Included, tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), None); @@ -496,23 +510,27 @@ fn requests_candidate_pending_availability() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::CandidatePendingAvailability(para_a, tx), - ) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CandidatePendingAvailability(para_a, tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::CandidatePendingAvailability(para_b, tx), - ) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CandidatePendingAvailability(para_b, tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), None); @@ -534,9 +552,11 @@ fn requests_candidate_events() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::CandidateEvents(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::CandidateEvents(tx)), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), runtime_api.candidate_events); @@ -561,10 +581,7 @@ fn requests_dmq_contents() { runtime_api.dmq_contents.insert(para_a, vec![]); runtime_api.dmq_contents.insert( para_b, - vec![InboundDownwardMessage { - sent_at: 228, - msg: b"Novus Ordo Seclorum".to_vec(), - }], + vec![InboundDownwardMessage { sent_at: 228, msg: b"Novus Ordo Seclorum".to_vec() }], ); runtime_api @@ -589,15 +606,10 @@ fn requests_dmq_contents() { .await; assert_eq!( rx.await.unwrap().unwrap(), - vec![InboundDownwardMessage { - sent_at: 228, - msg: b"Novus Ordo Seclorum".to_vec(), - }] + vec![InboundDownwardMessage { sent_at: 228, msg: b"Novus Ordo Seclorum".to_vec() }] ); - ctx_handle - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .await; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; }; futures::executor::block_on(future::join(subsystem_task, test_task)); } @@ -614,13 +626,7 @@ fn requests_inbound_hrmp_channels_contents() { let para_b_inbound_channels = [ (para_a, vec![]), - ( - para_c, - vec![InboundHrmpMessage { - sent_at: 1, - data: "𝙀=𝙈𝘾²".as_bytes().to_owned(), - }], - ), + (para_c, vec![InboundHrmpMessage { sent_at: 1, data: "𝙀=𝙈𝘾²".as_bytes().to_owned() }]), ] .iter() .cloned() @@ -630,9 +636,7 @@ fn requests_inbound_hrmp_channels_contents() { let mut runtime_api = MockRuntimeApi::default(); runtime_api.hrmp_channels.insert(para_a, BTreeMap::new()); - runtime_api - .hrmp_channels - .insert(para_b, para_b_inbound_channels.clone()); + runtime_api.hrmp_channels.insert(para_b, para_b_inbound_channels.clone()); runtime_api }); @@ -662,9 +666,7 @@ fn requests_inbound_hrmp_channels_contents() { .await; assert_eq!(rx.await.unwrap().unwrap(), para_b_inbound_channels,); - ctx_handle - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .await; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; }; futures::executor::block_on(future::join(subsystem_task, test_task)); } @@ -680,10 +682,7 @@ fn requests_validation_code_by_hash() { for n in 0..5 { let code = ValidationCode::from(vec![n; 32]); - runtime_api.validation_code_by_hash.insert( - code.hash(), - code.clone(), - ); + runtime_api.validation_code_by_hash.insert(code.hash(), code.clone()); validation_code.push(code); } @@ -697,12 +696,14 @@ fn requests_validation_code_by_hash() { let test_task = async move { for code in validation_code { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::ValidationCodeByHash(code.hash(), tx), - ) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCodeByHash(code.hash(), tx), + ), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), Some(code)); } @@ -732,9 +733,11 @@ fn multiple_requests_in_parallel_are_working() { for _ in 0..MAX_PARALLEL_REQUESTS * 10 { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)), + }) + .await; receivers.push(rx); } @@ -763,10 +766,7 @@ fn request_babe_epoch() { duration: 10, authorities: Vec::new(), randomness: [1u8; 32], - config: BabeEpochConfiguration { - c: (1, 4), - allowed_slots: BabeAllowedSlots::PrimarySlots, - }, + config: BabeEpochConfiguration { c: (1, 4), allowed_slots: BabeAllowedSlots::PrimarySlots }, }; runtime_api.babe_epoch = Some(epoch.clone()); let runtime_api = Arc::new(runtime_api); @@ -778,9 +778,11 @@ fn request_babe_epoch() { let test_task = async move { let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::CurrentBabeEpoch(tx)) - }).await; + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::CurrentBabeEpoch(tx)), + }) + .await; assert_eq!(rx.await.unwrap().unwrap(), epoch); ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; diff --git a/polkadot/node/jaeger/src/lib.rs b/polkadot/node/jaeger/src/lib.rs index dc8c329316e..eef8f17d53c 100644 --- a/polkadot/node/jaeger/src/lib.rs +++ b/polkadot/node/jaeger/src/lib.rs @@ -50,9 +50,11 @@ mod config; mod errors; mod spans; -pub use self::config::{JaegerConfig, JaegerConfigBuilder}; -pub use self::errors::JaegerError; -pub use self::spans::{PerLeafSpan, Span, Stage}; +pub use self::{ + config::{JaegerConfig, JaegerConfigBuilder}, + errors::JaegerError, + spans::{PerLeafSpan, Span, Stage}, +}; use self::spans::TraceIdentifier; @@ -103,8 +105,9 @@ impl Jaeger { log::info!("🐹 Collecting jaeger spans for {:?}", &jaeger_agent); - let (traces_in, mut traces_out) = - mick_jaeger::init(mick_jaeger::Config { service_name: format!("polkadot-{}", cfg.node_name) }); + let (traces_in, mut traces_out) = mick_jaeger::init(mick_jaeger::Config { + service_name: format!("polkadot-{}", cfg.node_name), + }); // Spawn a background task that pulls span information and sends them on the network. spawner.spawn( @@ -120,7 +123,7 @@ impl Jaeger { }, Err(e) => { log::warn!(target: "jaeger", "UDP socket open error: {}", e); - } + }, } }), ); diff --git a/polkadot/node/jaeger/src/spans.rs b/polkadot/node/jaeger/src/spans.rs index 36e63cadcc7..596d9fca782 100644 --- a/polkadot/node/jaeger/src/spans.rs +++ b/polkadot/node/jaeger/src/spans.rs @@ -84,12 +84,13 @@ //! ``` use parity_scale_codec::Encode; -use polkadot_primitives::v1::{BlakeTwo256, CandidateHash, Hash, HashT, Id as ParaId, ValidatorIndex}; use polkadot_node_primitives::PoV; +use polkadot_primitives::v1::{ + BlakeTwo256, CandidateHash, Hash, HashT, Id as ParaId, ValidatorIndex, +}; use sc_network::PeerId; -use std::fmt; -use std::sync::Arc; +use std::{fmt, sync::Arc}; use super::INSTANCE; @@ -240,7 +241,10 @@ impl Span { /// Creates a new span builder based on anything that can be lazily evaluated /// to and identifier. pub fn new(identifier: I, span_name: &'static str) -> Span { - let mut span = INSTANCE.read_recursive().span(|| ::eval(&identifier), span_name).into(); + let mut span = INSTANCE + .read_recursive() + .span(|| ::eval(&identifier), span_name) + .into(); ::extra_tags(&identifier, &mut span); span } @@ -349,8 +353,9 @@ impl Span { #[inline(always)] pub fn add_follows_from(&mut self, other: &Self) { match (self, other) { - (Self::Enabled(ref mut inner), Self::Enabled(ref other_inner)) => inner.add_follows_from(&other_inner), - _ => {} + (Self::Enabled(ref mut inner), Self::Enabled(ref other_inner)) => + inner.add_follows_from(&other_inner), + _ => {}, } } @@ -372,29 +377,30 @@ impl Span { pub fn add_string_tag(&mut self, tag: &'static str, val: V) { match self { Self::Enabled(ref mut inner) => inner.add_string_tag(tag, val.to_string().as_str()), - Self::Disabled => {} + Self::Disabled => {}, } } /// Add a string tag, without consuming the span. pub fn add_string_fmt_debug_tag(&mut self, tag: &'static str, val: V) { match self { - Self::Enabled(ref mut inner) => inner.add_string_tag(tag, format!("{:?}", val).as_str()), - Self::Disabled => {} + Self::Enabled(ref mut inner) => + inner.add_string_tag(tag, format!("{:?}", val).as_str()), + Self::Disabled => {}, } } pub fn add_int_tag(&mut self, tag: &'static str, value: i64) { match self { Self::Enabled(ref mut inner) => inner.add_int_tag(tag, value), - Self::Disabled => {} + Self::Disabled => {}, } } pub fn add_uint_tag(&mut self, tag: &'static str, value: u64) { match self { Self::Enabled(ref mut inner) => inner.add_int_tag(tag, value as i64), - Self::Disabled => {} + Self::Disabled => {}, } } diff --git a/polkadot/node/malus/src/lib.rs b/polkadot/node/malus/src/lib.rs index 8939f917d0f..87c853e0038 100644 --- a/polkadot/node/malus/src/lib.rs +++ b/polkadot/node/malus/src/lib.rs @@ -21,9 +21,8 @@ //! messages on the overseer level. use polkadot_node_subsystem::*; -pub use polkadot_node_subsystem::{overseer, messages::AllMessages, FromOverseer}; -use std::future::Future; -use std::pin::Pin; +pub use polkadot_node_subsystem::{messages::AllMessages, overseer, FromOverseer}; +use std::{future::Future, pin::Pin}; /// Filter incoming and outgoing messages. pub trait MsgFilter: Send + Sync + Clone + 'static { @@ -95,11 +94,7 @@ where inner: inner.sender().clone(), message_filter: message_filter.clone(), }; - Self { - inner, - message_filter, - sender, - } + Self { inner, message_filter, sender } } } @@ -108,7 +103,8 @@ impl overseer::SubsystemContext for FilteredContext where Context: overseer::SubsystemContext + SubsystemContext, Fil: MsgFilter::Message>, - ::AllMessages: From<::Message>, + ::AllMessages: + From<::Message>, { type Message = ::Message; type Sender = FilteredSender<::Sender, Fil>; @@ -120,11 +116,10 @@ where loop { match self.inner.try_recv().await? { None => return Ok(None), - Some(msg) => { + Some(msg) => if let Some(msg) = self.message_filter.filter_in(msg) { - return Ok(Some(msg)); - } - } + return Ok(Some(msg)) + }, } } } @@ -133,7 +128,7 @@ where loop { let msg = self.inner.recv().await?; if let Some(msg) = self.message_filter.filter_in(msg) { - return Ok(msg); + return Ok(msg) } } } @@ -167,10 +162,7 @@ pub struct FilteredSubsystem { impl FilteredSubsystem { pub fn new(subsystem: Sub, message_filter: Fil) -> Self { - Self { - subsystem, - message_filter, - } + Self { subsystem, message_filter } } } @@ -183,6 +175,9 @@ where { fn start(self, ctx: Context) -> SpawnedSubsystem { let ctx = FilteredContext::new(ctx, self.message_filter); - overseer::Subsystem::, SubsystemError>::start(self.subsystem, ctx) + overseer::Subsystem::, SubsystemError>::start( + self.subsystem, + ctx, + ) } } diff --git a/polkadot/node/malus/src/variant-a.rs b/polkadot/node/malus/src/variant-a.rs index fa2e1423d14..014e2b59857 100644 --- a/polkadot/node/malus/src/variant-a.rs +++ b/polkadot/node/malus/src/variant-a.rs @@ -27,8 +27,7 @@ use polkadot_cli::{ create_default_subsystems, service::{ AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, HeaderBackend, Overseer, - OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, ProvideRuntimeApi, - SpawnNamed, + OverseerGen, OverseerGenArgs, OverseerHandle, ParachainHost, ProvideRuntimeApi, SpawnNamed, }, Cli, }; @@ -42,8 +41,10 @@ use polkadot_node_subsystem_util::metrics::Metrics as _; // Filter wrapping related types. use malus::*; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; use structopt::StructOpt; diff --git a/polkadot/node/metered-channel/src/bounded.rs b/polkadot/node/metered-channel/src/bounded.rs index 43a77f707fc..ecfc0d60b45 100644 --- a/polkadot/node/metered-channel/src/bounded.rs +++ b/polkadot/node/metered-channel/src/bounded.rs @@ -16,14 +16,17 @@ //! Metered variant of bounded mpsc channels to be able to extract metrics. -use futures::{channel::mpsc, task::Poll, task::Context, sink::SinkExt, stream::Stream}; +use futures::{ + channel::mpsc, + sink::SinkExt, + stream::Stream, + task::{Context, Poll}, +}; -use std::result; -use std::pin::Pin; +use std::{pin::Pin, result}; use super::Meter; - /// Create a wrapped `mpsc::channel` pair of `MeteredSender` and `MeteredReceiver`. pub fn channel(capacity: usize) -> (MeteredSender, MeteredReceiver) { let (tx, rx) = mpsc::channel(capacity); @@ -61,7 +64,7 @@ impl Stream for MeteredReceiver { Poll::Ready(x) => { self.meter.note_received(); Poll::Ready(x) - } + }, other => other, } } @@ -84,7 +87,7 @@ impl MeteredReceiver { Some(x) => { self.meter.note_received(); Ok(Some(x)) - } + }, None => Ok(None), } } @@ -96,7 +99,6 @@ impl futures::stream::FusedStream for MeteredReceiver { } } - /// The sender component, tracking the number of items /// sent across it. #[derive(Debug)] diff --git a/polkadot/node/metered-channel/src/lib.rs b/polkadot/node/metered-channel/src/lib.rs index 917c04264df..4fe1bcd2252 100644 --- a/polkadot/node/metered-channel/src/lib.rs +++ b/polkadot/node/metered-channel/src/lib.rs @@ -16,16 +16,17 @@ //! Metered variant of mpsc channels to be able to extract metrics. -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; use derive_more::{Add, Display}; mod bounded; mod unbounded; -pub use self::bounded::*; -pub use self::unbounded::*; +pub use self::{bounded::*, unbounded::*}; /// A peek into the inner state of a meter. #[derive(Debug, Clone, Default)] @@ -74,8 +75,7 @@ impl Meter { #[cfg(test)] mod tests { use super::*; - use futures::executor::block_on; - use futures::StreamExt; + use futures::{executor::block_on, StreamExt}; #[derive(Clone, Copy, Debug, Default)] struct Msg { @@ -137,8 +137,8 @@ mod tests { }); } - use std::time::Duration; use futures_timer::Delay; + use std::time::Duration; #[test] fn stream_and_sink() { diff --git a/polkadot/node/metered-channel/src/unbounded.rs b/polkadot/node/metered-channel/src/unbounded.rs index bf1400681a6..3b846611fb3 100644 --- a/polkadot/node/metered-channel/src/unbounded.rs +++ b/polkadot/node/metered-channel/src/unbounded.rs @@ -16,14 +16,16 @@ //! Metered variant of unbounded mpsc channels to be able to extract metrics. -use futures::{channel::mpsc, task::Poll, task::Context, stream::Stream}; +use futures::{ + channel::mpsc, + stream::Stream, + task::{Context, Poll}, +}; -use std::result; -use std::pin::Pin; +use std::{pin::Pin, result}; use super::Meter; - /// Create a wrapped `mpsc::channel` pair of `MeteredSender` and `MeteredReceiver`. pub fn unbounded() -> (UnboundedMeteredSender, UnboundedMeteredReceiver) { let (tx, rx) = mpsc::unbounded(); @@ -61,7 +63,7 @@ impl Stream for UnboundedMeteredReceiver { Poll::Ready(x) => { self.meter.note_received(); Poll::Ready(x) - } + }, other => other, } } @@ -84,7 +86,7 @@ impl UnboundedMeteredReceiver { Some(x) => { self.meter.note_received(); Ok(Some(x)) - } + }, None => Ok(None), } } @@ -96,7 +98,6 @@ impl futures::stream::FusedStream for UnboundedMeteredReceiver { } } - /// The sender component, tracking the number of items /// sent across it. #[derive(Debug)] diff --git a/polkadot/node/metrics/src/lib.rs b/polkadot/node/metrics/src/lib.rs index 6ee20777925..4fa852508b5 100644 --- a/polkadot/node/metrics/src/lib.rs +++ b/polkadot/node/metrics/src/lib.rs @@ -28,7 +28,7 @@ use futures::prelude::*; use futures_timer::Delay; use std::{ pin::Pin, - task::{Poll, Context}, + task::{Context, Poll}, time::Duration, }; @@ -39,7 +39,6 @@ pub mod metrics { /// Reexport Substrate Prometheus types. pub use substrate_prometheus_endpoint as prometheus; - /// Subsystem- or job-specific Prometheus metrics. /// /// Usually implemented as a wrapper for `Option` @@ -47,13 +46,17 @@ pub mod metrics { /// Prometheus metrics internally hold an `Arc` reference, so cloning them is fine. pub trait Metrics: Default + Clone { /// Try to register metrics in the Prometheus registry. - fn try_register(registry: &prometheus::Registry) -> Result; + fn try_register( + registry: &prometheus::Registry, + ) -> Result; /// Convenience method to register metrics in the optional Prometheus registry. /// /// If no registry is provided, returns `Default::default()`. Otherwise, returns the same /// thing that `try_register` does. - fn register(registry: Option<&prometheus::Registry>) -> Result { + fn register( + registry: Option<&prometheus::Registry>, + ) -> Result { match registry { None => Ok(Self::default()), Some(registry) => Self::try_register(registry), @@ -63,7 +66,9 @@ pub mod metrics { // dummy impl impl Metrics for () { - fn try_register(_registry: &prometheus::Registry) -> Result<(), prometheus::PrometheusError> { + fn try_register( + _registry: &prometheus::Registry, + ) -> Result<(), prometheus::PrometheusError> { Ok(()) } } @@ -86,34 +91,27 @@ impl Metronome { /// Create a new metronome source with a defined cycle duration. pub fn new(cycle: Duration) -> Self { let period = cycle.into(); - Self { - period, - delay: Delay::new(period), - state: MetronomeState::Snooze, - } + Self { period, delay: Delay::new(period), state: MetronomeState::Snooze } } } impl futures::Stream for Metronome { type Item = (); - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_> - ) -> Poll> { + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { loop { match self.state { MetronomeState::SetAlarm => { let val = self.period.clone(); self.delay.reset(val); self.state = MetronomeState::Snooze; - } + }, MetronomeState::Snooze => { if !Pin::new(&mut self.delay).poll(cx).is_ready() { break } self.state = MetronomeState::SetAlarm; - return Poll::Ready(Some(())); - } + return Poll::Ready(Some(())) + }, } } Poll::Pending diff --git a/polkadot/node/network/approval-distribution/src/lib.rs b/polkadot/node/network/approval-distribution/src/lib.rs index c0848a32817..0e6167eb47d 100644 --- a/polkadot/node/network/approval-distribution/src/lib.rs +++ b/polkadot/node/network/approval-distribution/src/lib.rs @@ -20,43 +20,46 @@ #![warn(missing_docs)] -use std::collections::{BTreeMap, HashMap, HashSet, hash_map}; use futures::{channel::oneshot, FutureExt as _}; -use polkadot_primitives::v1::{ - Hash, BlockNumber, ValidatorIndex, ValidatorSignature, CandidateIndex, +use polkadot_node_network_protocol::{ + v1 as protocol_v1, PeerId, UnifiedReputationChange as Rep, View, }; -use polkadot_node_primitives::{ - approval::{AssignmentCert, BlockApprovalMeta, IndirectSignedApprovalVote, IndirectAssignmentCert}, +use polkadot_node_primitives::approval::{ + AssignmentCert, BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote, }; use polkadot_node_subsystem::{ - overseer, messages::{ - ApprovalDistributionMessage, ApprovalVotingMessage, NetworkBridgeMessage, - AssignmentCheckResult, ApprovalCheckResult, NetworkBridgeEvent, + ApprovalCheckResult, ApprovalDistributionMessage, ApprovalVotingMessage, + AssignmentCheckResult, NetworkBridgeEvent, NetworkBridgeMessage, }, + overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, - ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, }; use polkadot_node_subsystem_util::{ + self as util, metrics::{self, prometheus}, - self as util, MIN_GOSSIP_PEERS, + MIN_GOSSIP_PEERS, }; -use polkadot_node_network_protocol::{ - PeerId, View, v1 as protocol_v1, UnifiedReputationChange as Rep, +use polkadot_primitives::v1::{ + BlockNumber, CandidateIndex, Hash, ValidatorIndex, ValidatorSignature, }; +use std::collections::{hash_map, BTreeMap, HashMap, HashSet}; #[cfg(test)] mod tests; const LOG_TARGET: &str = "parachain::approval-distribution"; -const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("Peer sent an out-of-view assignment or approval"); +const COST_UNEXPECTED_MESSAGE: Rep = + Rep::CostMinor("Peer sent an out-of-view assignment or approval"); const COST_DUPLICATE_MESSAGE: Rep = Rep::CostMinorRepeated("Peer sent identical messages"); -const COST_ASSIGNMENT_TOO_FAR_IN_THE_FUTURE: Rep = Rep::CostMinor("The vote was valid but too far in the future"); +const COST_ASSIGNMENT_TOO_FAR_IN_THE_FUTURE: Rep = + Rep::CostMinor("The vote was valid but too far in the future"); const COST_INVALID_MESSAGE: Rep = Rep::CostMajor("The vote was bad"); const BENEFIT_VALID_MESSAGE: Rep = Rep::BenefitMinor("Peer sent a valid message"); -const BENEFIT_VALID_MESSAGE_FIRST: Rep = Rep::BenefitMinorFirst("Valid message with new information"); +const BENEFIT_VALID_MESSAGE_FIRST: Rep = + Rep::BenefitMinorFirst("Valid message with new information"); /// The Approval Distribution subsystem. pub struct ApprovalDistribution { @@ -189,50 +192,39 @@ enum PendingMessage { impl State { async fn handle_network_msg( &mut self, - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), metrics: &Metrics, event: NetworkBridgeEvent, ) { match event { NetworkBridgeEvent::PeerConnected(peer_id, role, _) => { // insert a blank view if none already present - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - ?role, - "Peer connected", - ); + tracing::trace!(target: LOG_TARGET, ?peer_id, ?role, "Peer connected",); self.peer_views.entry(peer_id).or_default(); - } + }, NetworkBridgeEvent::PeerDisconnected(peer_id) => { - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - "Peer disconnected", - ); + tracing::trace!(target: LOG_TARGET, ?peer_id, "Peer disconnected",); self.peer_views.remove(&peer_id); self.blocks.iter_mut().for_each(|(_hash, entry)| { entry.known_by.remove(&peer_id); }) - } + }, NetworkBridgeEvent::NewGossipTopology(peers) => { - let newly_added: Vec = peers.difference(&self.gossip_peers).cloned().collect(); + let newly_added: Vec = + peers.difference(&self.gossip_peers).cloned().collect(); self.gossip_peers = peers; for peer_id in newly_added { if let Some(view) = self.peer_views.remove(&peer_id) { self.handle_peer_view_change(ctx, metrics, peer_id, view).await; } } - } + }, NetworkBridgeEvent::PeerViewChange(peer_id, view) => { self.handle_peer_view_change(ctx, metrics, peer_id, view).await; - } + }, NetworkBridgeEvent::OurViewChange(view) => { - tracing::trace!( - target: LOG_TARGET, - ?view, - "Own view change", - ); + tracing::trace!(target: LOG_TARGET, ?view, "Own view change",); for head in view.iter() { if !self.blocks.contains_key(head) { self.pending_known.entry(*head).or_default(); @@ -250,16 +242,18 @@ impl State { } live }); - } + }, NetworkBridgeEvent::PeerMessage(peer_id, msg) => { self.process_incoming_peer_message(ctx, metrics, peer_id, msg).await; - } + }, } } async fn handle_new_blocks( &mut self, - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), metrics: &Metrics, + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), + metrics: &Metrics, metas: Vec, ) { let mut new_hashes = HashSet::new(); @@ -282,7 +276,7 @@ impl State { // In case there are duplicates, we should only set this if the entry // was vacant. self.blocks_by_number.entry(meta.number).or_default().push(meta.hash); - } + }, _ => continue, } } @@ -294,17 +288,22 @@ impl State { ); { - let pending_now_known = self.pending_known.keys() + let pending_now_known = self + .pending_known + .keys() .filter(|k| self.blocks.contains_key(k)) .copied() .collect::>(); - let to_import = pending_now_known.into_iter() - .inspect(|h| tracing::trace!( - target: LOG_TARGET, - block_hash = ?h, - "Extracting pending messages for new block" - )) + let to_import = pending_now_known + .into_iter() + .inspect(|h| { + tracing::trace!( + target: LOG_TARGET, + block_hash = ?h, + "Extracting pending messages for new block" + ) + }) .filter_map(|k| self.pending_known.remove(&k)) .flatten() .collect::>(); @@ -327,16 +326,18 @@ impl State { MessageSource::Peer(peer_id), assignment, claimed_index, - ).await; - } + ) + .await; + }, PendingMessage::Approval(approval_vote) => { self.import_and_circulate_approval( ctx, metrics, MessageSource::Peer(peer_id), approval_vote, - ).await; - } + ) + .await; + }, } } } @@ -344,10 +345,7 @@ impl State { for (peer_id, view) in self.peer_views.iter() { let intersection = view.iter().filter(|h| new_hashes.contains(h)); - let view_intersection = View::new( - intersection.cloned(), - view.finalized_number, - ); + let view_intersection = View::new(intersection.cloned(), view.finalized_number); Self::unify_with_peer( ctx, &self.gossip_peers, @@ -355,13 +353,16 @@ impl State { &mut self.blocks, peer_id.clone(), view_intersection, - ).await; + ) + .await; } } async fn process_incoming_peer_message( &mut self, - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), metrics: &Metrics, + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), + metrics: &Metrics, peer_id: PeerId, msg: protocol_v1::ApprovalDistributionMessage, ) { @@ -393,7 +394,7 @@ impl State { PendingMessage::Assignment(assignment, claimed_index), )); - continue; + continue } self.import_and_circulate_assignment( @@ -402,9 +403,10 @@ impl State { MessageSource::Peer(peer_id.clone()), assignment, claimed_index, - ).await; + ) + .await; } - } + }, protocol_v1::ApprovalDistributionMessage::Approvals(approvals) => { tracing::trace!( target: LOG_TARGET, @@ -427,12 +429,9 @@ impl State { "Pending approval", ); - pending.push(( - peer_id.clone(), - PendingMessage::Approval(approval_vote), - )); + pending.push((peer_id.clone(), PendingMessage::Approval(approval_vote))); - continue; + continue } self.import_and_circulate_approval( @@ -440,23 +439,22 @@ impl State { metrics, MessageSource::Peer(peer_id.clone()), approval_vote, - ).await; + ) + .await; } - } + }, } } async fn handle_peer_view_change( &mut self, - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), metrics: &Metrics, + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), + metrics: &Metrics, peer_id: PeerId, view: View, ) { - tracing::trace!( - target: LOG_TARGET, - ?view, - "Peer view change", - ); + tracing::trace!(target: LOG_TARGET, ?view, "Peer view change",); let finalized_number = view.finalized_number; let old_view = self.peer_views.insert(peer_id.clone(), view.clone()); let old_finalized_number = old_view.map(|v| v.finalized_number).unwrap_or(0); @@ -470,13 +468,13 @@ impl State { let range = old_finalized_number..=finalized_number; if !range.is_empty() && !blocks.is_empty() { self.blocks_by_number - .range(range) - .flat_map(|(_number, hashes)| hashes) - .for_each(|hash| { - if let Some(entry) = blocks.get_mut(hash) { - entry.known_by.remove(&peer_id); - } - }); + .range(range) + .flat_map(|(_number, hashes)| hashes) + .for_each(|hash| { + if let Some(entry) = blocks.get_mut(hash) { + entry.known_by.remove(&peer_id); + } + }); } Self::unify_with_peer( @@ -486,13 +484,11 @@ impl State { &mut self.blocks, peer_id.clone(), view, - ).await; + ) + .await; } - fn handle_block_finalized( - &mut self, - finalized_number: BlockNumber, - ) { + fn handle_block_finalized(&mut self, finalized_number: BlockNumber) { // we want to prune every block up to (including) finalized_number // why +1 here? // split_off returns everything after the given key, including the key @@ -502,16 +498,16 @@ impl State { std::mem::swap(&mut self.blocks_by_number, &mut old_blocks); // now that we pruned `self.blocks_by_number`, let's clean up `self.blocks` too - old_blocks.values() - .flatten() - .for_each(|h| { - self.blocks.remove(h); - }); + old_blocks.values().flatten().for_each(|h| { + self.blocks.remove(h); + }); } async fn import_and_circulate_assignment( &mut self, - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), metrics: &Metrics, + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), + metrics: &Metrics, source: MessageSource, assignment: IndirectAssignmentCert, claimed_candidate_index: CandidateIndex, @@ -532,16 +528,13 @@ impl State { ); modify_reputation(ctx, peer_id, COST_UNEXPECTED_MESSAGE).await; } - return; - } + return + }, }; // compute a fingerprint of the assignment - let fingerprint = MessageFingerprint::Assignment( - block_hash, - claimed_candidate_index, - validator_index, - ); + let fingerprint = + MessageFingerprint::Assignment(block_hash, claimed_candidate_index, validator_index); if let Some(peer_id) = source.peer_id() { // check if our knowledge of the peer already contains this assignment @@ -559,9 +552,9 @@ impl State { modify_reputation(ctx, peer_id, COST_DUPLICATE_MESSAGE).await; } peer_knowledge.received.insert(fingerprint); - return; + return } - } + }, hash_map::Entry::Vacant(_) => { tracing::debug!( target: LOG_TARGET, @@ -570,22 +563,17 @@ impl State { "Assignment from a peer is out of view", ); modify_reputation(ctx, peer_id.clone(), COST_UNEXPECTED_MESSAGE).await; - } + }, } // if the assignment is known to be valid, reward the peer if entry.knowledge.known_messages.contains(&fingerprint) { modify_reputation(ctx, peer_id.clone(), BENEFIT_VALID_MESSAGE).await; if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - ?fingerprint, - "Known assignment", - ); + tracing::trace!(target: LOG_TARGET, ?peer_id, ?fingerprint, "Known assignment",); peer_knowledge.received.insert(fingerprint.clone()); } - return; + return } let (tx, rx) = oneshot::channel(); @@ -594,18 +582,16 @@ impl State { assignment.clone(), claimed_candidate_index, tx, - )).await; + )) + .await; let timer = metrics.time_awaiting_approval_voting(); let result = match rx.await { Ok(result) => result, Err(_) => { - tracing::debug!( - target: LOG_TARGET, - "The approval voting subsystem is down", - ); - return; - } + tracing::debug!(target: LOG_TARGET, "The approval voting subsystem is down",); + return + }, }; drop(timer); @@ -623,7 +609,7 @@ impl State { if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { peer_knowledge.received.insert(fingerprint.clone()); } - } + }, AssignmentCheckResult::AcceptedDuplicate => { // "duplicate" assignments aren't necessarily equal. // There is more than one way each validator can be assigned to each core. @@ -636,8 +622,8 @@ impl State { ?peer_id, "Got an `AcceptedDuplicate` assignment", ); - return; - } + return + }, AssignmentCheckResult::TooFarInFuture => { tracing::debug!( target: LOG_TARGET, @@ -645,8 +631,8 @@ impl State { "Got an assignment too far in the future", ); modify_reputation(ctx, peer_id, COST_ASSIGNMENT_TOO_FAR_IN_THE_FUTURE).await; - return; - } + return + }, AssignmentCheckResult::Bad(error) => { tracing::info!( target: LOG_TARGET, @@ -655,8 +641,8 @@ impl State { "Got a bad assignment from peer", ); modify_reputation(ctx, peer_id, COST_INVALID_MESSAGE).await; - return; - } + return + }, } } else { if !entry.knowledge.known_messages.insert(fingerprint.clone()) { @@ -666,7 +652,7 @@ impl State { ?fingerprint, "Importing locally an already known assignment", ); - return; + return } else { tracing::debug!( target: LOG_TARGET, @@ -685,10 +671,10 @@ impl State { Some(candidate_entry) => { // set the approval state for validator_index to Assigned // unless the approval state is set already - candidate_entry.approvals - .entry(validator_index) - .or_insert_with(|| (ApprovalState::Assigned(assignment.cert.clone()), local_source)); - } + candidate_entry.approvals.entry(validator_index).or_insert_with(|| { + (ApprovalState::Assigned(assignment.cert.clone()), local_source) + }); + }, None => { tracing::warn!( target: LOG_TARGET, @@ -696,7 +682,7 @@ impl State { ?claimed_candidate_index, "Expected a candidate entry on import_and_circulate_assignment", ); - } + }, } // Dispatch a ApprovalDistributionV1Message::Assignment(assignment, candidate_index) @@ -712,11 +698,8 @@ impl State { let assignments = vec![(assignment, claimed_candidate_index)]; let gossip_peers = &self.gossip_peers; - let peers = util::choose_random_subset( - |e| gossip_peers.contains(e), - peers, - MIN_GOSSIP_PEERS, - ); + let peers = + util::choose_random_subset(|e| gossip_peers.contains(e), peers, MIN_GOSSIP_PEERS); // Add the fingerprint of the assignment to the knowledge of each peer. for peer in peers.iter() { @@ -739,15 +722,18 @@ impl State { ctx.send_message(NetworkBridgeMessage::SendValidationMessage( peers, protocol_v1::ValidationProtocol::ApprovalDistribution( - protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + protocol_v1::ApprovalDistributionMessage::Assignments(assignments), ), - )).await; + )) + .await; } } async fn import_and_circulate_approval( &mut self, - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), metrics: &Metrics, + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), + metrics: &Metrics, source: MessageSource, vote: IndirectSignedApprovalVote, ) { @@ -761,16 +747,13 @@ impl State { if let Some(peer_id) = source.peer_id() { modify_reputation(ctx, peer_id, COST_UNEXPECTED_MESSAGE).await; } - return; - } + return + }, }; // compute a fingerprint of the approval - let fingerprint = MessageFingerprint::Approval( - block_hash.clone(), - candidate_index, - validator_index, - ); + let fingerprint = + MessageFingerprint::Approval(block_hash.clone(), candidate_index, validator_index); if let Some(peer_id) = source.peer_id() { let assignment_fingerprint = MessageFingerprint::Assignment( @@ -787,7 +770,7 @@ impl State { "Unknown approval assignment", ); modify_reputation(ctx, peer_id, COST_UNEXPECTED_MESSAGE).await; - return; + return } // check if our knowledge of the peer already contains this approval @@ -806,9 +789,9 @@ impl State { modify_reputation(ctx, peer_id, COST_DUPLICATE_MESSAGE).await; } peer_knowledge.received.insert(fingerprint); - return; + return } - } + }, hash_map::Entry::Vacant(_) => { tracing::debug!( target: LOG_TARGET, @@ -817,41 +800,31 @@ impl State { "Approval from a peer is out of view", ); modify_reputation(ctx, peer_id.clone(), COST_UNEXPECTED_MESSAGE).await; - } + }, } // if the approval is known to be valid, reward the peer if entry.knowledge.contains(&fingerprint) { - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - ?fingerprint, - "Known approval", - ); + tracing::trace!(target: LOG_TARGET, ?peer_id, ?fingerprint, "Known approval",); modify_reputation(ctx, peer_id.clone(), BENEFIT_VALID_MESSAGE).await; if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { peer_knowledge.received.insert(fingerprint.clone()); } - return; + return } let (tx, rx) = oneshot::channel(); - ctx.send_message(ApprovalVotingMessage::CheckAndImportApproval( - vote.clone(), - tx, - )).await; + ctx.send_message(ApprovalVotingMessage::CheckAndImportApproval(vote.clone(), tx)) + .await; let timer = metrics.time_awaiting_approval_voting(); let result = match rx.await { Ok(result) => result, Err(_) => { - tracing::debug!( - target: LOG_TARGET, - "The approval voting subsystem is down", - ); - return; - } + tracing::debug!(target: LOG_TARGET, "The approval voting subsystem is down",); + return + }, }; drop(timer); @@ -870,7 +843,7 @@ impl State { if let Some(peer_knowledge) = entry.known_by.get_mut(&peer_id) { peer_knowledge.received.insert(fingerprint.clone()); } - } + }, ApprovalCheckResult::Bad(error) => { modify_reputation(ctx, peer_id, COST_INVALID_MESSAGE).await; tracing::info!( @@ -879,8 +852,8 @@ impl State { %error, "Got a bad approval from peer", ); - return; - } + return + }, } } else { if !entry.knowledge.insert(fingerprint.clone()) { @@ -890,7 +863,7 @@ impl State { ?fingerprint, "Importing locally an already known approval", ); - return; + return } else { tracing::debug!( target: LOG_TARGET, @@ -915,12 +888,12 @@ impl State { validator_index, (ApprovalState::Approved(cert, vote.signature.clone()), local_source), ); - } + }, Some((ApprovalState::Approved(..), _)) => { unreachable!( "we only insert it after the fingerprint, checked the fingerprint above; qed" ); - } + }, None => { // this would indicate a bug in approval-voting tracing::warn!( @@ -930,9 +903,9 @@ impl State { ?validator_index, "Importing an approval we don't have an assignment for", ); - } + }, } - } + }, None => { tracing::warn!( target: LOG_TARGET, @@ -941,7 +914,7 @@ impl State { ?validator_index, "Expected a candidate entry on import_and_circulate_approval", ); - } + }, } // Dispatch a ApprovalDistributionV1Message::Approval(vote) @@ -956,11 +929,8 @@ impl State { .collect::>(); let gossip_peers = &self.gossip_peers; - let peers = util::choose_random_subset( - |e| gossip_peers.contains(e), - peers, - MIN_GOSSIP_PEERS, - ); + let peers = + util::choose_random_subset(|e| gossip_peers.contains(e), peers, MIN_GOSSIP_PEERS); // Add the fingerprint of the assignment to the knowledge of each peer. for peer in peers.iter() { @@ -984,32 +954,32 @@ impl State { ctx.send_message(NetworkBridgeMessage::SendValidationMessage( peers, protocol_v1::ValidationProtocol::ApprovalDistribution( - protocol_v1::ApprovalDistributionMessage::Approvals(approvals) + protocol_v1::ApprovalDistributionMessage::Approvals(approvals), ), - )).await; + )) + .await; } } async fn unify_with_peer( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), gossip_peers: &HashSet, + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), + gossip_peers: &HashSet, metrics: &Metrics, entries: &mut HashMap, peer_id: PeerId, view: View, ) { let is_gossip_peer = gossip_peers.contains(&peer_id); - let lucky = is_gossip_peer || util::gen_ratio( - util::MIN_GOSSIP_PEERS.saturating_sub(gossip_peers.len()), - util::MIN_GOSSIP_PEERS, - ); + let lucky = is_gossip_peer || + util::gen_ratio( + util::MIN_GOSSIP_PEERS.saturating_sub(gossip_peers.len()), + util::MIN_GOSSIP_PEERS, + ); if !lucky { - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - "Unlucky peer", - ); - return; + tracing::trace!(target: LOG_TARGET, ?peer_id, "Unlucky peer",); + return } metrics.on_unify_with_peer(); @@ -1036,7 +1006,7 @@ impl State { }; vacant.insert(knowledge); block - } + }, }; // step 5. block = entry.parent_hash.clone(); @@ -1046,17 +1016,14 @@ impl State { } // step 6. // send all assignments and approvals for all candidates in those blocks to the peer - Self::send_gossip_messages_to_peer( - entries, - ctx, - peer_id, - to_send - ).await; + Self::send_gossip_messages_to_peer(entries, ctx, peer_id, to_send).await; } async fn send_gossip_messages_to_peer( entries: &HashMap, - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), peer_id: PeerId, + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), + peer_id: PeerId, blocks: Vec, ) { let mut assignments = Vec::new(); @@ -1078,7 +1045,9 @@ impl State { for (candidate_index, candidate_entry) in entry.candidates.iter().enumerate() { let candidate_index = candidate_index as u32; - for (validator_index, (approval_state, _is_local)) in candidate_entry.approvals.iter() { + for (validator_index, (approval_state, _is_local)) in + candidate_entry.approvals.iter() + { match approval_state { ApprovalState::Assigned(cert) => { assignments.push(( @@ -1089,7 +1058,7 @@ impl State { }, candidate_index.clone(), )); - } + }, ApprovalState::Approved(assignment_cert, signature) => { assignments.push(( IndirectAssignmentCert { @@ -1105,7 +1074,7 @@ impl State { candidate_index: candidate_index.clone(), signature: signature.clone(), }); - } + }, } } } @@ -1123,9 +1092,10 @@ impl State { ctx.send_message(NetworkBridgeMessage::SendValidationMessage( vec![peer_id.clone()], protocol_v1::ValidationProtocol::ApprovalDistribution( - protocol_v1::ApprovalDistributionMessage::Assignments(assignments) + protocol_v1::ApprovalDistributionMessage::Assignments(assignments), ), - )).await; + )) + .await; } if !approvals.is_empty() { @@ -1140,17 +1110,18 @@ impl State { ctx.send_message(NetworkBridgeMessage::SendValidationMessage( vec![peer_id], protocol_v1::ValidationProtocol::ApprovalDistribution( - protocol_v1::ApprovalDistributionMessage::Approvals(approvals) + protocol_v1::ApprovalDistributionMessage::Approvals(approvals), ), - )).await; + )) + .await; } } } - /// Modify the reputation of a peer based on its behavior. async fn modify_reputation( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), peer_id: PeerId, rep: Rep, ) { @@ -1161,9 +1132,7 @@ async fn modify_reputation( "Reputation change for peer", ); - ctx.send_message( - NetworkBridgeMessage::ReportPeer(peer_id, rep), - ).await; + ctx.send_message(NetworkBridgeMessage::ReportPeer(peer_id, rep)).await; } impl ApprovalDistribution { @@ -1192,7 +1161,7 @@ impl ApprovalDistribution { Ok(message) => message, Err(e) => { tracing::debug!(target: LOG_TARGET, err = ?e, "Failed to receive a message from Overseer, exiting"); - return; + return }, }; match message { @@ -1200,13 +1169,13 @@ impl ApprovalDistribution { msg: ApprovalDistributionMessage::NetworkBridgeUpdateV1(event), } => { state.handle_network_msg(&mut ctx, &self.metrics, event).await; - } + }, FromOverseer::Communication { msg: ApprovalDistributionMessage::NewBlocks(metas), } => { tracing::debug!(target: LOG_TARGET, "Processing NewBlocks"); state.handle_new_blocks(&mut ctx, &self.metrics, metas).await; - } + }, FromOverseer::Communication { msg: ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index), } => { @@ -1217,14 +1186,16 @@ impl ApprovalDistribution { candidate_index, ); - state.import_and_circulate_assignment( - &mut ctx, - &self.metrics, - MessageSource::Local, - cert, - candidate_index, - ).await; - } + state + .import_and_circulate_assignment( + &mut ctx, + &self.metrics, + MessageSource::Local, + cert, + candidate_index, + ) + .await; + }, FromOverseer::Communication { msg: ApprovalDistributionMessage::DistributeApproval(vote), } => { @@ -1235,24 +1206,26 @@ impl ApprovalDistribution { vote.candidate_index, ); - state.import_and_circulate_approval( - &mut ctx, - &self.metrics, - MessageSource::Local, - vote, - ).await; - } - FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { .. })) => { + state + .import_and_circulate_approval( + &mut ctx, + &self.metrics, + MessageSource::Local, + vote, + ) + .await; + }, + FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + .. + })) => { tracing::trace!(target: LOG_TARGET, "active leaves signal (ignored)"); // handled by NewBlocks - } + }, FromOverseer::Signal(OverseerSignal::BlockFinalized(_hash, number)) => { tracing::trace!(target: LOG_TARGET, number = %number, "finalized signal"); state.handle_block_finalized(number); }, - FromOverseer::Signal(OverseerSignal::Conclude) => { - return; - } + FromOverseer::Signal(OverseerSignal::Conclude) => return, } } } @@ -1264,18 +1237,12 @@ where Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { - let future = self.run(ctx) - .map(|_| Ok(())) - .boxed(); + let future = self.run(ctx).map(|_| Ok(())).boxed(); - SpawnedSubsystem { - name: "approval-distribution-subsystem", - future, - } + SpawnedSubsystem { name: "approval-distribution-subsystem", future } } } - /// Approval Distribution metrics. #[derive(Default, Clone)] pub struct Metrics(Option); @@ -1314,12 +1281,20 @@ impl Metrics { self.0.as_ref().map(|metrics| metrics.time_unify_with_peer.start_timer()) } - fn time_import_pending_now_known(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.time_import_pending_now_known.start_timer()) + fn time_import_pending_now_known( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.time_import_pending_now_known.start_timer()) } - fn time_awaiting_approval_voting(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.time_awaiting_approval_voting.start_timer()) + fn time_awaiting_approval_voting( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.time_awaiting_approval_voting.start_timer()) } } @@ -1348,30 +1323,24 @@ impl metrics::Metrics for Metrics { registry, )?, time_unify_with_peer: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_time_unify_with_peer", - "Time spent within fn `unify_with_peer`.", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_time_unify_with_peer", + "Time spent within fn `unify_with_peer`.", + ))?, registry, )?, time_import_pending_now_known: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_time_import_pending_now_known", - "Time spent on importing pending assignments and approvals.", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_time_import_pending_now_known", + "Time spent on importing pending assignments and approvals.", + ))?, registry, )?, time_awaiting_approval_voting: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_time_awaiting_approval_voting", - "Time spent awaiting a reply from the Approval Voting Subsystem.", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_time_awaiting_approval_voting", + "Time spent awaiting a reply from the Approval Voting Subsystem.", + ))?, registry, )?, }; diff --git a/polkadot/node/network/approval-distribution/src/tests.rs b/polkadot/node/network/approval-distribution/src/tests.rs index 00f862e35fc..0bca13b80ac 100644 --- a/polkadot/node/network/approval-distribution/src/tests.rs +++ b/polkadot/node/network/approval-distribution/src/tests.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::time::Duration; -use futures::{future, Future, executor}; +use super::*; use assert_matches::assert_matches; -use polkadot_node_subsystem::messages::{AllMessages, ApprovalCheckError}; -use polkadot_node_subsystem_test_helpers as test_helpers; -use polkadot_node_subsystem_util::TimeoutExt as _; +use futures::{executor, future, Future}; use polkadot_node_network_protocol::{view, ObservedRole}; use polkadot_node_primitives::approval::{ - AssignmentCertKind, RELAY_VRF_MODULO_CONTEXT, VRFOutput, VRFProof, + AssignmentCertKind, VRFOutput, VRFProof, RELAY_VRF_MODULO_CONTEXT, }; -use super::*; +use polkadot_node_subsystem::messages::{AllMessages, ApprovalCheckError}; +use polkadot_node_subsystem_test_helpers as test_helpers; +use polkadot_node_subsystem_util::TimeoutExt as _; +use std::time::Duration; type VirtualOverseer = test_helpers::TestSubsystemContextHandle; @@ -34,10 +34,7 @@ fn test_harness>( ) -> State { let _ = env_logger::builder() .is_test(true) - .filter( - Some(LOG_TARGET), - log::LevelFilter::Trace, - ) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) .try_init(); let pool = sp_core::testing::TaskExecutor::new(); @@ -52,14 +49,17 @@ fn test_harness>( futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .timeout(TIMEOUT) - .await - .expect("Conclude send timeout"); - }, subsystem)); + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer + .send(FromOverseer::Signal(OverseerSignal::Conclude)) + .timeout(TIMEOUT) + .await + .expect("Conclude send timeout"); + }, + subsystem, + )); } state @@ -67,10 +67,7 @@ fn test_harness>( const TIMEOUT: Duration = Duration::from_millis(100); -async fn overseer_send( - overseer: &mut VirtualOverseer, - msg: ApprovalDistributionMessage, -) { +async fn overseer_send(overseer: &mut VirtualOverseer, msg: ApprovalDistributionMessage) { tracing::trace!(msg = ?msg, "Sending message"); overseer .send(FromOverseer::Communication { msg }) @@ -79,14 +76,8 @@ async fn overseer_send( .expect("msg send timeout"); } -async fn overseer_signal_block_finalized( - overseer: &mut VirtualOverseer, - number: BlockNumber, -) { - tracing::trace!( - ?number, - "Sending a finalized signal", - ); +async fn overseer_signal_block_finalized(overseer: &mut VirtualOverseer, number: BlockNumber) { + tracing::trace!(?number, "Sending a finalized signal",); // we don't care about the block hash overseer .send(FromOverseer::Signal(OverseerSignal::BlockFinalized(Hash::zero(), number))) @@ -95,15 +86,9 @@ async fn overseer_signal_block_finalized( .expect("signal send timeout"); } -async fn overseer_recv( - overseer: &mut VirtualOverseer, -) -> AllMessages { +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { tracing::trace!("Waiting for a message"); - let msg = overseer - .recv() - .timeout(TIMEOUT) - .await - .expect("msg recv timeout"); + let msg = overseer.recv().timeout(TIMEOUT).await.expect("msg recv timeout"); tracing::trace!(msg = ?msg, "Received message"); @@ -117,16 +102,21 @@ async fn setup_peer_with_view( ) { overseer_send( virtual_overseer, - ApprovalDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected(peer_id.clone(), ObservedRole::Full, None) - ) - ).await; + ApprovalDistributionMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected( + peer_id.clone(), + ObservedRole::Full, + None, + )), + ) + .await; overseer_send( virtual_overseer, - ApprovalDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_id.clone(), view) - ) - ).await; + ApprovalDistributionMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer_id.clone(), + view, + )), + ) + .await; } async fn send_message_from_peer( @@ -136,16 +126,15 @@ async fn send_message_from_peer( ) { overseer_send( virtual_overseer, - ApprovalDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage(peer_id.clone(), msg) - ) - ).await; + ApprovalDistributionMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage( + peer_id.clone(), + msg, + )), + ) + .await; } -fn fake_assignment_cert( - block_hash: Hash, - validator: ValidatorIndex, -) -> IndirectAssignmentCert { +fn fake_assignment_cert(block_hash: Hash, validator: ValidatorIndex) -> IndirectAssignmentCert { let ctx = schnorrkel::signing_context(RELAY_VRF_MODULO_CONTEXT); let msg = b"WhenParachains?"; let mut prng = rand_core::OsRng; @@ -157,11 +146,9 @@ fn fake_assignment_cert( block_hash, validator, cert: AssignmentCert { - kind: AssignmentCertKind::RelayVRFModulo { - sample: 1, - }, + kind: AssignmentCertKind::RelayVRFModulo { sample: 1 }, vrf: (VRFOutput(out), VRFProof(proof)), - } + }, } } @@ -184,7 +171,6 @@ async fn expect_reputation_change( ); } - /// import an assignment /// connect a new peer /// the new peer sends us the same assignment @@ -263,13 +249,7 @@ fn try_import_the_same_assignment() { expect_reputation_change(overseer, &peer_d, COST_UNEXPECTED_MESSAGE).await; expect_reputation_change(overseer, &peer_d, BENEFIT_VALID_MESSAGE).await; - assert!(overseer - .recv() - .timeout(TIMEOUT) - .await - .is_none(), - "no message should be sent", - ); + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent",); virtual_overseer }); } @@ -311,7 +291,8 @@ fn spam_attack_results_in_negative_reputation_change() { let validator_index = ValidatorIndex(candidate_index as u32); let cert = fake_assignment_cert(hash_b, validator_index); (cert, candidate_index as u32) - }).collect(); + }) + .collect(); let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments.clone()); send_message_from_peer(overseer, peer, msg.clone()).await; @@ -338,10 +319,12 @@ fn spam_attack_results_in_negative_reputation_change() { // send a view update that removes block B from peer's view by bumping the finalized_number overseer_send( overseer, - ApprovalDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer.clone(), View::with_finalized(2)) - ) - ).await; + ApprovalDistributionMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer.clone(), + View::with_finalized(2), + )), + ) + .await; // send the assignments again send_message_from_peer(overseer, peer, msg.clone()).await; @@ -355,7 +338,6 @@ fn spam_attack_results_in_negative_reputation_change() { }); } - /// Imagine we send a message to peer A and peer B. /// Upon receiving them, they both will try to send the message each other. /// This test makes sure they will not punish each other for such duplicate messages. @@ -389,16 +371,19 @@ fn peer_sending_us_the_same_we_just_sent_them_is_ok() { let cert = fake_assignment_cert(hash, validator_index); overseer_send( overseer, - ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index) - ).await; + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; // update peer view to include the hash overseer_send( overseer, - ApprovalDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer.clone(), view![hash]) - ) - ).await; + ApprovalDistributionMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer.clone(), + view![hash], + )), + ) + .await; // we should send them the assignment assert_matches!( @@ -420,13 +405,7 @@ fn peer_sending_us_the_same_we_just_sent_them_is_ok() { let msg = protocol_v1::ApprovalDistributionMessage::Assignments(assignments); send_message_from_peer(overseer, peer, msg.clone()).await; - assert!(overseer - .recv() - .timeout(TIMEOUT) - .await - .is_none(), - "we should not punish the peer", - ); + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "we should not punish the peer",); // send the assignments again send_message_from_peer(overseer, peer, msg).await; @@ -469,8 +448,9 @@ fn import_approval_happy_path() { let cert = fake_assignment_cert(hash, validator_index); overseer_send( overseer, - ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index) - ).await; + ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index), + ) + .await; assert_matches!( overseer_recv(overseer).await, @@ -716,15 +696,9 @@ fn update_peer_view() { let cert_a = fake_assignment_cert(hash_a, ValidatorIndex(0)); let cert_b = fake_assignment_cert(hash_b, ValidatorIndex(0)); - overseer_send( - overseer, - ApprovalDistributionMessage::DistributeAssignment(cert_a, 0) - ).await; + overseer_send(overseer, ApprovalDistributionMessage::DistributeAssignment(cert_a, 0)).await; - overseer_send( - overseer, - ApprovalDistributionMessage::DistributeAssignment(cert_b, 0) - ).await; + overseer_send(overseer, ApprovalDistributionMessage::DistributeAssignment(cert_b, 0)).await; // connect a peer setup_peer_with_view(overseer, peer, view![hash_a]).await; @@ -747,7 +721,8 @@ fn update_peer_view() { assert_eq!(state.peer_views.get(peer).map(|v| v.finalized_number), Some(0)); assert_eq!( - state.blocks + state + .blocks .get(&hash_a) .unwrap() .known_by @@ -764,17 +739,20 @@ fn update_peer_view() { // update peer's view overseer_send( overseer, - ApprovalDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer.clone(), View::new(vec![hash_b, hash_c, hash_d], 2)) - ) - ).await; + ApprovalDistributionMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer.clone(), + View::new(vec![hash_b, hash_c, hash_d], 2), + )), + ) + .await; let cert_c = fake_assignment_cert(hash_c, ValidatorIndex(0)); overseer_send( overseer, - ApprovalDistributionMessage::DistributeAssignment(cert_c.clone(), 0) - ).await; + ApprovalDistributionMessage::DistributeAssignment(cert_c.clone(), 0), + ) + .await; // we should send relevant assignments to the peer assert_matches!( @@ -795,7 +773,8 @@ fn update_peer_view() { assert_eq!(state.peer_views.get(peer).map(|v| v.finalized_number), Some(2)); assert_eq!( - state.blocks + state + .blocks .get(&hash_c) .unwrap() .known_by @@ -813,22 +792,17 @@ fn update_peer_view() { // update peer's view overseer_send( overseer, - ApprovalDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer.clone(), View::with_finalized(finalized_number)) - ) - ).await; + ApprovalDistributionMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer.clone(), + View::with_finalized(finalized_number), + )), + ) + .await; virtual_overseer }); assert_eq!(state.peer_views.get(peer).map(|v| v.finalized_number), Some(finalized_number)); - assert!( - state.blocks - .get(&hash_c) - .unwrap() - .known_by - .get(peer) - .is_none() - ); + assert!(state.blocks.get(&hash_c).unwrap().known_by.get(peer).is_none()); } /// E.g. if someone copies the keys... @@ -882,16 +856,11 @@ fn import_remotely_then_locally() { // import the same assignment locally overseer_send( overseer, - ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index) - ).await; - - assert!(overseer - .recv() - .timeout(TIMEOUT) - .await - .is_none(), - "no message should be sent", - ); + ApprovalDistributionMessage::DistributeAssignment(cert, candidate_index), + ) + .await; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent",); // send the approval remotely let approval = IndirectSignedApprovalVote { @@ -916,18 +885,9 @@ fn import_remotely_then_locally() { expect_reputation_change(overseer, peer, BENEFIT_VALID_MESSAGE_FIRST).await; // import the same approval locally - overseer_send( - overseer, - ApprovalDistributionMessage::DistributeApproval(approval) - ).await; - - assert!(overseer - .recv() - .timeout(TIMEOUT) - .await - .is_none(), - "no message should be sent", - ); + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval)).await; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent",); virtual_overseer }); } @@ -967,13 +927,12 @@ fn sends_assignments_even_when_state_is_approved() { overseer_send( overseer, - ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index) - ).await; + ApprovalDistributionMessage::DistributeAssignment(cert.clone(), candidate_index), + ) + .await; - overseer_send( - overseer, - ApprovalDistributionMessage::DistributeApproval(approval.clone()), - ).await; + overseer_send(overseer, ApprovalDistributionMessage::DistributeApproval(approval.clone())) + .await; // connect the peer. setup_peer_with_view(overseer, peer, view![hash]).await; @@ -1007,13 +966,7 @@ fn sends_assignments_even_when_state_is_approved() { } ); - assert!(overseer - .recv() - .timeout(TIMEOUT) - .await - .is_none(), - "no message should be sent", - ); + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent",); virtual_overseer }); } diff --git a/polkadot/node/network/availability-distribution/src/error.rs b/polkadot/node/network/availability-distribution/src/error.rs index 7494ce06352..12a3ec60ce8 100644 --- a/polkadot/node/network/availability-distribution/src/error.rs +++ b/polkadot/node/network/availability-distribution/src/error.rs @@ -22,7 +22,7 @@ use thiserror::Error; use futures::channel::oneshot; -use polkadot_node_subsystem_util::{Fault, runtime, unwrap_non_fatal}; +use polkadot_node_subsystem_util::{runtime, unwrap_non_fatal, Fault}; use polkadot_subsystem::SubsystemError; use crate::LOG_TARGET; @@ -113,9 +113,7 @@ pub type Result = std::result::Result; /// /// We basically always want to try and continue on error. This utility function is meant to /// consume top-level errors by simply logging them -pub fn log_error(result: Result<()>, ctx: &'static str) - -> std::result::Result<(), Fatal> -{ +pub fn log_error(result: Result<()>, ctx: &'static str) -> std::result::Result<(), Fatal> { if let Some(error) = unwrap_non_fatal(result.map_err(|e| e.0))? { tracing::warn!(target: LOG_TARGET, error = ?error, ctx); } diff --git a/polkadot/node/network/availability-distribution/src/lib.rs b/polkadot/node/network/availability-distribution/src/lib.rs index 67de44ccdcb..98396a4b332 100644 --- a/polkadot/node/network/availability-distribution/src/lib.rs +++ b/polkadot/node/network/availability-distribution/src/lib.rs @@ -19,15 +19,13 @@ use futures::{future::Either, FutureExt, StreamExt, TryFutureExt}; use sp_keystore::SyncCryptoStorePtr; use polkadot_subsystem::{ - messages::AvailabilityDistributionMessage, FromOverseer, OverseerSignal, SpawnedSubsystem, - SubsystemContext, SubsystemError, - overseer, + messages::AvailabilityDistributionMessage, overseer, FromOverseer, OverseerSignal, + SpawnedSubsystem, SubsystemContext, SubsystemError, }; /// Error and [`Result`] type for this subsystem. mod error; -use error::Fatal; -use error::{Result, log_error}; +use error::{log_error, Fatal, Result}; use polkadot_node_subsystem_util::runtime::RuntimeInfo; @@ -70,19 +68,15 @@ where .map_err(|e| SubsystemError::with_origin("availability-distribution", e)) .boxed(); - SpawnedSubsystem { - name: "availability-distribution-subsystem", - future, - } + SpawnedSubsystem { name: "availability-distribution-subsystem", future } } } impl AvailabilityDistributionSubsystem { - /// Create a new instance of the availability distribution. pub fn new(keystore: SyncCryptoStorePtr, metrics: Metrics) -> Self { let runtime = RuntimeInfo::new(Some(keystore)); - Self { runtime, metrics } + Self { runtime, metrics } } /// Start processing work as passed on from the Overseer. @@ -103,44 +97,41 @@ impl AvailabilityDistributionSubsystem { // Handle task messages sending: let message = match action { - Either::Left(subsystem_msg) => { - subsystem_msg.map_err(|e| Fatal::IncomingMessageChannel(e))? - } + Either::Left(subsystem_msg) => + subsystem_msg.map_err(|e| Fatal::IncomingMessageChannel(e))?, Either::Right(from_task) => { let from_task = from_task.ok_or(Fatal::RequesterExhausted)?; ctx.send_message(from_task).await; - continue; - } + continue + }, }; match message { FromOverseer::Signal(OverseerSignal::ActiveLeaves(update)) => { log_error( - requester.get_mut().update_fetching_heads(&mut ctx, &mut self.runtime, update).await, - "Error in Requester::update_fetching_heads" + requester + .get_mut() + .update_fetching_heads(&mut ctx, &mut self.runtime, update) + .await, + "Error in Requester::update_fetching_heads", )?; - } - FromOverseer::Signal(OverseerSignal::BlockFinalized(..)) => {} - FromOverseer::Signal(OverseerSignal::Conclude) => { - return Ok(()); - } + }, + FromOverseer::Signal(OverseerSignal::BlockFinalized(..)) => {}, + FromOverseer::Signal(OverseerSignal::Conclude) => return Ok(()), FromOverseer::Communication { msg: AvailabilityDistributionMessage::ChunkFetchingRequest(req), - } => { - answer_chunk_request_log(&mut ctx, req, &self.metrics).await - } + } => answer_chunk_request_log(&mut ctx, req, &self.metrics).await, FromOverseer::Communication { msg: AvailabilityDistributionMessage::PoVFetchingRequest(req), - } => { - answer_pov_request_log(&mut ctx, req, &self.metrics).await - } + } => answer_pov_request_log(&mut ctx, req, &self.metrics).await, FromOverseer::Communication { - msg: AvailabilityDistributionMessage::FetchPoV { - relay_parent, - from_validator, - candidate_hash, - pov_hash, - tx, - }, + msg: + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + from_validator, + candidate_hash, + pov_hash, + tx, + }, } => { log_error( pov_requester::fetch_pov( @@ -151,10 +142,11 @@ impl AvailabilityDistributionSubsystem { candidate_hash, pov_hash, tx, - ).await, - "pov_requester::fetch_pov" + ) + .await, + "pov_requester::fetch_pov", )?; - } + }, } } } diff --git a/polkadot/node/network/availability-distribution/src/metrics.rs b/polkadot/node/network/availability-distribution/src/metrics.rs index 925bbc8fe43..d92ba8a5d42 100644 --- a/polkadot/node/network/availability-distribution/src/metrics.rs +++ b/polkadot/node/network/availability-distribution/src/metrics.rs @@ -14,9 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use polkadot_node_subsystem_util::metrics::prometheus::{Counter, U64, Registry, PrometheusError, CounterVec, Opts}; -use polkadot_node_subsystem_util::metrics::prometheus; -use polkadot_node_subsystem_util::metrics; +use polkadot_node_subsystem_util::{ + metrics, + metrics::{ + prometheus, + prometheus::{Counter, CounterVec, Opts, PrometheusError, Registry, U64}, + }, +}; /// Label for success counters. pub const SUCCEEDED: &'static str = "succeeded"; @@ -31,7 +35,6 @@ pub const NOT_FOUND: &'static str = "not-found"; #[derive(Clone, Default)] pub struct Metrics(Option); - #[derive(Clone)] struct MetricsInner { /// Number of chunks fetched. @@ -137,4 +140,3 @@ impl metrics::Metrics for Metrics { Ok(Metrics(Some(metrics))) } } - diff --git a/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs b/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs index b091db144df..216ced7d1ed 100644 --- a/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs +++ b/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs @@ -16,23 +16,26 @@ //! PoV requester takes care of requesting PoVs from validators of a backing group. -use futures::{FutureExt, channel::oneshot, future::BoxFuture}; +use futures::{channel::oneshot, future::BoxFuture, FutureExt}; -use polkadot_subsystem::jaeger; -use polkadot_node_network_protocol::request_response::{OutgoingRequest, Recipient, request::{RequestError, Requests}, - v1::{PoVFetchingRequest, PoVFetchingResponse}}; -use polkadot_primitives::v1::{ - CandidateHash, Hash, ValidatorIndex, +use polkadot_node_network_protocol::request_response::{ + request::{RequestError, Requests}, + v1::{PoVFetchingRequest, PoVFetchingResponse}, + OutgoingRequest, Recipient, }; use polkadot_node_primitives::PoV; +use polkadot_node_subsystem_util::runtime::RuntimeInfo; +use polkadot_primitives::v1::{CandidateHash, Hash, ValidatorIndex}; use polkadot_subsystem::{ + jaeger, + messages::{IfDisconnected, NetworkBridgeMessage}, SubsystemContext, - messages::{NetworkBridgeMessage, IfDisconnected} }; -use polkadot_node_subsystem_util::runtime::RuntimeInfo; -use crate::error::{Fatal, NonFatal}; -use crate::LOG_TARGET; +use crate::{ + error::{Fatal, NonFatal}, + LOG_TARGET, +}; /// Start background worker for taking care of fetching the requested `PoV` from the network. pub async fn fetch_pov( @@ -42,32 +45,31 @@ pub async fn fetch_pov( from_validator: ValidatorIndex, candidate_hash: CandidateHash, pov_hash: Hash, - tx: oneshot::Sender + tx: oneshot::Sender, ) -> super::Result<()> where Context: SubsystemContext, { let info = &runtime.get_session_info(ctx.sender(), parent).await?.session_info; - let authority_id = info.discovery_keys.get(from_validator.0 as usize) + let authority_id = info + .discovery_keys + .get(from_validator.0 as usize) .ok_or(NonFatal::InvalidValidatorIndex)? .clone(); let (req, pending_response) = OutgoingRequest::new( Recipient::Authority(authority_id), - PoVFetchingRequest { - candidate_hash, - }, + PoVFetchingRequest { candidate_hash }, ); let full_req = Requests::PoVFetching(req); - ctx.send_message( - NetworkBridgeMessage::SendRequests( - vec![full_req], - // We are supposed to be connected to validators of our group via `PeerSet`, - // but at session boundaries that is kind of racy, in case a connection takes - // longer to get established, so we try to connect in any case. - IfDisconnected::TryConnect - ) - ).await; + ctx.send_message(NetworkBridgeMessage::SendRequests( + vec![full_req], + // We are supposed to be connected to validators of our group via `PeerSet`, + // but at session boundaries that is kind of racy, in case a connection takes + // longer to get established, so we try to connect in any case. + IfDisconnected::TryConnect, + )) + .await; let span = jaeger::Span::new(candidate_hash, "fetch-pov") .with_validator_index(from_validator) @@ -85,11 +87,7 @@ async fn fetch_pov_job( tx: oneshot::Sender, ) { if let Err(err) = do_fetch_pov(pov_hash, pending_response, span, tx).await { - tracing::warn!( - target: LOG_TARGET, - ?err, - "fetch_pov_job" - ); + tracing::warn!(target: LOG_TARGET, ?err, "fetch_pov_job"); } } @@ -99,15 +97,11 @@ async fn do_fetch_pov( pending_response: BoxFuture<'static, Result>, _span: jaeger::Span, tx: oneshot::Sender, -) - -> std::result::Result<(), NonFatal> -{ +) -> std::result::Result<(), NonFatal> { let response = pending_response.await.map_err(NonFatal::FetchPoV)?; let pov = match response { PoVFetchingResponse::PoV(pov) => pov, - PoVFetchingResponse::NoSuchPoV => { - return Err(NonFatal::NoSuchPoV) - } + PoVFetchingResponse::NoSuchPoV => return Err(NonFatal::NoSuchPoV), }; if pov.hash() == pov_hash { tx.send(pov).map_err(|_| NonFatal::SendResponse) @@ -124,38 +118,37 @@ mod tests { use parity_scale_codec::Encode; use sp_core::testing::TaskExecutor; - use polkadot_primitives::v1::{CandidateHash, Hash, ValidatorIndex}; use polkadot_node_primitives::BlockData; + use polkadot_primitives::v1::{CandidateHash, Hash, ValidatorIndex}; + use polkadot_subsystem::messages::{ + AllMessages, AvailabilityDistributionMessage, RuntimeApiMessage, RuntimeApiRequest, + }; use polkadot_subsystem_testhelpers as test_helpers; - use polkadot_subsystem::messages::{AvailabilityDistributionMessage, RuntimeApiMessage, RuntimeApiRequest, AllMessages}; use test_helpers::mock::make_ferdie_keystore; use super::*; - use crate::LOG_TARGET; - use crate::tests::mock::{make_session_info}; + use crate::{tests::mock::make_session_info, LOG_TARGET}; #[test] fn rejects_invalid_pov() { sp_tracing::try_init_simple(); - let pov = PoV { - block_data: BlockData(vec![1,2,3,4,5,6]), - }; + let pov = PoV { block_data: BlockData(vec![1, 2, 3, 4, 5, 6]) }; test_run(Hash::default(), pov); } #[test] fn accepts_valid_pov() { sp_tracing::try_init_simple(); - let pov = PoV { - block_data: BlockData(vec![1,2,3,4,5,6]), - }; + let pov = PoV { block_data: BlockData(vec![1, 2, 3, 4, 5, 6]) }; test_run(pov.hash(), pov); } fn test_run(pov_hash: Hash, pov: PoV) { let pool = TaskExecutor::new(); - let (mut context, mut virtual_overseer) = - test_helpers::make_subsystem_context::(pool.clone()); + let (mut context, mut virtual_overseer) = test_helpers::make_subsystem_context::< + AvailabilityDistributionMessage, + TaskExecutor, + >(pool.clone()); let keystore = make_ferdie_keystore(); let mut runtime = polkadot_node_subsystem_util::runtime::RuntimeInfo::new(Some(keystore)); @@ -169,34 +162,33 @@ mod tests { CandidateHash::default(), pov_hash, tx, - ).await.expect("Should succeed"); + ) + .await + .expect("Should succeed"); }; let tester = async move { loop { match virtual_overseer.recv().await { - AllMessages::RuntimeApi( - RuntimeApiMessage::Request( - _, - RuntimeApiRequest::SessionIndexForChild(tx) - ) - ) => { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { tx.send(Ok(0)).unwrap(); - } - AllMessages::RuntimeApi( - RuntimeApiMessage::Request( - _, - RuntimeApiRequest::SessionInfo(_, tx) - ) - ) => { + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(_, tx), + )) => { tx.send(Ok(Some(make_session_info()))).unwrap(); - } + }, AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(mut reqs, _)) => { let req = assert_matches!( reqs.pop(), Some(Requests::PoVFetching(outgoing)) => {outgoing} ); - req.pending_response.send(Ok(PoVFetchingResponse::PoV(pov.clone()).encode())) + req.pending_response + .send(Ok(PoVFetchingResponse::PoV(pov.clone()).encode())) .unwrap(); break }, diff --git a/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs b/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs index 0b2aeb6d41f..a088b52b884 100644 --- a/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs +++ b/polkadot/node/network/availability-distribution/src/requester/fetch_task/mod.rs @@ -16,28 +16,33 @@ use std::collections::HashSet; -use futures::channel::mpsc; -use futures::channel::oneshot; -use futures::future::select; -use futures::{FutureExt, SinkExt}; +use futures::{ + channel::{mpsc, oneshot}, + future::select, + FutureExt, SinkExt, +}; use polkadot_erasure_coding::branch_hash; use polkadot_node_network_protocol::request_response::{ - request::{OutgoingRequest, RequestError, Requests, Recipient}, + request::{OutgoingRequest, Recipient, RequestError, Requests}, v1::{ChunkFetchingRequest, ChunkFetchingResponse}, }; -use polkadot_primitives::v1::{AuthorityDiscoveryId, BlakeTwo256, CandidateHash, GroupIndex, Hash, HashT, OccupiedCore, SessionIndex}; use polkadot_node_primitives::ErasureChunk; -use polkadot_subsystem::messages::{ - AllMessages, AvailabilityStoreMessage, NetworkBridgeMessage, IfDisconnected, +use polkadot_primitives::v1::{ + AuthorityDiscoveryId, BlakeTwo256, CandidateHash, GroupIndex, Hash, HashT, OccupiedCore, + SessionIndex, +}; +use polkadot_subsystem::{ + jaeger, + messages::{AllMessages, AvailabilityStoreMessage, IfDisconnected, NetworkBridgeMessage}, + SubsystemContext, }; -use polkadot_subsystem::{SubsystemContext, jaeger}; use crate::{ error::{Fatal, Result}, + metrics::{Metrics, FAILED, SUCCEEDED}, requester::session_cache::{BadValidators, SessionInfo}, LOG_TARGET, - metrics::{Metrics, SUCCEEDED, FAILED}, }; #[cfg(test)] @@ -140,10 +145,7 @@ impl FetchTaskConfig { // Don't run tasks for our backing group: if session_info.our_group == Some(core.group_responsible) { - return FetchTaskConfig { - live_in, - prepared_running: None, - }; + return FetchTaskConfig { live_in, prepared_running: None } } let span = jaeger::Span::new(core.candidate_hash, "availability-distribution") @@ -165,10 +167,7 @@ impl FetchTaskConfig { sender, span, }; - FetchTaskConfig { - live_in, - prepared_running: Some(prepared_running), - } + FetchTaskConfig { live_in, prepared_running: Some(prepared_running) } } } @@ -180,10 +179,7 @@ impl FetchTask { where Context: SubsystemContext, { - let FetchTaskConfig { - prepared_running, - live_in, - } = config; + let FetchTaskConfig { prepared_running, live_in } = config; if let Some(running) = prepared_running { let (handle, kill) = oneshot::channel(); @@ -191,15 +187,9 @@ impl FetchTask { ctx.spawn("chunk-fetcher", running.run(kill).boxed()) .map_err(|e| Fatal::SpawnTask(e))?; - Ok(FetchTask { - live_in, - state: FetchedState::Started(handle), - }) + Ok(FetchTask { live_in, state: FetchedState::Started(handle) }) } else { - Ok(FetchTask { - live_in, - state: FetchedState::Canceled, - }) + Ok(FetchTask { live_in, state: FetchedState::Canceled }) } } @@ -261,7 +251,9 @@ impl RunningTask { let mut bad_validators = Vec::new(); let mut succeeded = false; let mut count: u32 = 0; - let mut _span = self.span.child("fetch-task") + let mut _span = self + .span + .child("fetch-task") .with_chunk_index(self.request.index.0) .with_relay_parent(self.relay_parent); // Try validators in reverse order: @@ -271,7 +263,7 @@ impl RunningTask { if count > 0 { self.metrics.on_retry(); } - count +=1; + count += 1; // Send request: let resp = match self.do_request(&validator).await { @@ -283,16 +275,14 @@ impl RunningTask { ); self.metrics.on_fetch(FAILED); return - } + }, Err(TaskError::PeerError) => { bad_validators.push(validator); continue - } + }, }; let chunk = match resp { - ChunkFetchingResponse::Chunk(resp) => { - resp.recombine_into_chunk(&self.request) - } + ChunkFetchingResponse::Chunk(resp) => resp.recombine_into_chunk(&self.request), ChunkFetchingResponse::NoSuchChunk => { tracing::debug!( target: LOG_TARGET, @@ -301,20 +291,20 @@ impl RunningTask { ); bad_validators.push(validator); continue - } + }, }; // Data genuine? if !self.validate_chunk(&validator, &chunk) { bad_validators.push(validator); - continue; + continue } // Ok, let's store it and be happy: self.store_chunk(chunk).await; succeeded = true; _span.add_string_tag("success", "true"); - break; + break } _span.add_int_tag("tries", count as _); if succeeded { @@ -337,7 +327,7 @@ impl RunningTask { self.sender .send(FromFetchTask::Message(AllMessages::NetworkBridge( - NetworkBridgeMessage::SendRequests(vec![requests], IfDisconnected::TryConnect) + NetworkBridgeMessage::SendRequests(vec![requests], IfDisconnected::TryConnect), ))) .await .map_err(|_| TaskError::ShuttingDown)?; @@ -352,7 +342,7 @@ impl RunningTask { "Peer sent us invalid erasure chunk data" ); Err(TaskError::PeerError) - } + }, Err(RequestError::NetworkError(err)) => { tracing::warn!( target: LOG_TARGET, @@ -361,13 +351,13 @@ impl RunningTask { "Some network error occurred when fetching erasure chunk" ); Err(TaskError::PeerError) - } + }, Err(RequestError::Canceled(oneshot::Canceled)) => { tracing::warn!(target: LOG_TARGET, origin= ?validator, "Erasure chunk request got canceled"); Err(TaskError::PeerError) - } + }, } } @@ -383,13 +373,13 @@ impl RunningTask { error = ?e, "Failed to calculate chunk merkle proof", ); - return false; - } + return false + }, }; let erasure_chunk_hash = BlakeTwo256::hash(&chunk.chunk); if anticipated_hash != erasure_chunk_hash { tracing::warn!(target: LOG_TARGET, origin = ?validator, "Received chunk does not match merkle tree"); - return false; + return false } true } @@ -437,12 +427,9 @@ impl RunningTask { } async fn conclude_fail(&mut self) { - if let Err(err) = self.sender.send(FromFetchTask::Failed(self.request.candidate_hash)).await { - tracing::warn!( - target: LOG_TARGET, - ?err, - "Sending `Failed` message for task failed" - ); + if let Err(err) = self.sender.send(FromFetchTask::Failed(self.request.candidate_hash)).await + { + tracing::warn!(target: LOG_TARGET, ?err, "Sending `Failed` message for task failed"); } } } diff --git a/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs b/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs index 1a770fb641c..48616e336ae 100644 --- a/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs +++ b/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs @@ -16,24 +16,24 @@ use std::collections::HashMap; - use parity_scale_codec::Encode; -use futures::channel::{mpsc, oneshot}; -use futures::{executor, Future, FutureExt, StreamExt, select}; -use futures::task::{Poll, Context, noop_waker}; +use futures::{ + channel::{mpsc, oneshot}, + executor, select, + task::{noop_waker, Context, Poll}, + Future, FutureExt, StreamExt, +}; use sc_network as network; use sp_keyring::Sr25519Keyring; -use polkadot_primitives::v1::{CandidateHash, ValidatorIndex}; +use polkadot_node_network_protocol::request_response::{v1, Recipient}; use polkadot_node_primitives::{BlockData, PoV}; -use polkadot_node_network_protocol::request_response::v1; -use polkadot_node_network_protocol::request_response::Recipient; +use polkadot_primitives::v1::{CandidateHash, ValidatorIndex}; -use crate::metrics::Metrics; -use crate::tests::mock::get_valid_chunk_data; use super::*; +use crate::{metrics::Metrics, tests::mock::get_valid_chunk_data}; #[test] fn task_can_be_canceled() { @@ -54,16 +54,14 @@ fn task_does_not_accept_invalid_chunk() { let validators = vec![Sr25519Keyring::Alice.public().into()]; task.group = validators; let test = TestRun { - chunk_responses: { + chunk_responses: { let mut m = HashMap::new(); m.insert( Recipient::Authority(Sr25519Keyring::Alice.public().into()), - ChunkFetchingResponse::Chunk( - v1::ChunkResponse { - chunk: vec![1,2,3], - proof: vec![vec![9,8,2], vec![2,3,4]], - } - ) + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: vec![1, 2, 3], + proof: vec![vec![9, 8, 2], vec![2, 3, 4]], + }), ); m }, @@ -75,9 +73,7 @@ fn task_does_not_accept_invalid_chunk() { #[test] fn task_stores_valid_chunk() { let (mut task, rx) = get_test_running_task(); - let pov = PoV { - block_data: BlockData(vec![45, 46, 47]), - }; + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; let (root_hash, chunk) = get_valid_chunk_data(pov); task.erasure_root = root_hash; task.request.index = chunk.index; @@ -86,16 +82,14 @@ fn task_stores_valid_chunk() { task.group = validators; let test = TestRun { - chunk_responses: { + chunk_responses: { let mut m = HashMap::new(); m.insert( Recipient::Authority(Sr25519Keyring::Alice.public().into()), - ChunkFetchingResponse::Chunk( - v1::ChunkResponse { - chunk: chunk.chunk.clone(), - proof: chunk.proof, - } - ) + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: chunk.chunk.clone(), + proof: chunk.proof, + }), ); m }, @@ -111,27 +105,23 @@ fn task_stores_valid_chunk() { #[test] fn task_does_not_accept_wrongly_indexed_chunk() { let (mut task, rx) = get_test_running_task(); - let pov = PoV { - block_data: BlockData(vec![45, 46, 47]), - }; + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; let (root_hash, chunk) = get_valid_chunk_data(pov); task.erasure_root = root_hash; - task.request.index = ValidatorIndex(chunk.index.0+1); + task.request.index = ValidatorIndex(chunk.index.0 + 1); let validators = vec![Sr25519Keyring::Alice.public().into()]; task.group = validators; let test = TestRun { - chunk_responses: { + chunk_responses: { let mut m = HashMap::new(); m.insert( Recipient::Authority(Sr25519Keyring::Alice.public().into()), - ChunkFetchingResponse::Chunk( - v1::ChunkResponse { - chunk: chunk.chunk.clone(), - proof: chunk.proof, - } - ) + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: chunk.chunk.clone(), + proof: chunk.proof, + }), ); m }, @@ -144,46 +134,44 @@ fn task_does_not_accept_wrongly_indexed_chunk() { #[test] fn task_stores_valid_chunk_if_there_is_one() { let (mut task, rx) = get_test_running_task(); - let pov = PoV { - block_data: BlockData(vec![45, 46, 47]), - }; + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; let (root_hash, chunk) = get_valid_chunk_data(pov); task.erasure_root = root_hash; task.request.index = chunk.index; let validators = [ - // Only Alice has valid chunk - should succeed, even though she is tried last. - Sr25519Keyring::Alice, - Sr25519Keyring::Bob, Sr25519Keyring::Charlie, - Sr25519Keyring::Dave, Sr25519Keyring::Eve, - ] - .iter().map(|v| v.public().into()).collect::>(); + // Only Alice has valid chunk - should succeed, even though she is tried last. + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ] + .iter() + .map(|v| v.public().into()) + .collect::>(); task.group = validators; let test = TestRun { - chunk_responses: { + chunk_responses: { let mut m = HashMap::new(); m.insert( Recipient::Authority(Sr25519Keyring::Alice.public().into()), - ChunkFetchingResponse::Chunk( - v1::ChunkResponse { - chunk: chunk.chunk.clone(), - proof: chunk.proof, - } - ) + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: chunk.chunk.clone(), + proof: chunk.proof, + }), ); m.insert( Recipient::Authority(Sr25519Keyring::Bob.public().into()), - ChunkFetchingResponse::NoSuchChunk + ChunkFetchingResponse::NoSuchChunk, ); m.insert( Recipient::Authority(Sr25519Keyring::Charlie.public().into()), - ChunkFetchingResponse::Chunk( - v1::ChunkResponse { - chunk: vec![1,2,3], - proof: vec![vec![9,8,2], vec![2,3,4]], - } - ) + ChunkFetchingResponse::Chunk(v1::ChunkResponse { + chunk: vec![1, 2, 3], + proof: vec![vec![9, 8, 2], vec![2, 3, 4]], + }), ); m @@ -205,7 +193,6 @@ struct TestRun { valid_chunks: HashSet>, } - impl TestRun { fn run(self, task: RunningTask, rx: mpsc::Receiver) { sp_tracing::try_init_simple(); @@ -228,8 +215,7 @@ impl TestRun { match msg { FromFetchTask::Concluded(_) => break, FromFetchTask::Failed(_) => break, - FromFetchTask::Message(msg) => - end_ok = self.handle_message(msg).await, + FromFetchTask::Message(msg) => end_ok = self.handle_message(msg).await, } } if !end_ok { @@ -242,44 +228,50 @@ impl TestRun { /// end. async fn handle_message(&self, msg: AllMessages) -> bool { match msg { - AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::TryConnect)) => { + AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests( + reqs, + IfDisconnected::TryConnect, + )) => { let mut valid_responses = 0; for req in reqs { let req = match req { Requests::ChunkFetching(req) => req, _ => panic!("Unexpected request"), }; - let response = self.chunk_responses.get(&req.peer) - .ok_or(network::RequestFailure::Refused); + let response = + self.chunk_responses.get(&req.peer).ok_or(network::RequestFailure::Refused); if let Ok(ChunkFetchingResponse::Chunk(resp)) = &response { if self.valid_chunks.contains(&resp.chunk) { valid_responses += 1; } } - req.pending_response.send(response.map(Encode::encode)) + req.pending_response + .send(response.map(Encode::encode)) .expect("Sending response should succeed"); } return (valid_responses == 0) && self.valid_chunks.is_empty() - } - AllMessages::AvailabilityStore( - AvailabilityStoreMessage::StoreChunk { chunk, tx, .. } - ) => { + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreChunk { + chunk, + tx, + .. + }) => { assert!(self.valid_chunks.contains(&chunk.chunk)); tx.send(Ok(())).expect("Answering fetching task should work"); return true - } + }, _ => { tracing::debug!(target: LOG_TARGET, "Unexpected message"); return false - } + }, } } } /// Get a `RunningTask` filled with dummy values. fn get_test_running_task() -> (RunningTask, mpsc::Receiver) { - let (tx,rx) = mpsc::channel(0); + let (tx, rx) = mpsc::channel(0); ( RunningTask { @@ -287,7 +279,7 @@ fn get_test_running_task() -> (RunningTask, mpsc::Receiver) { group_index: GroupIndex(0), group: Vec::new(), request: ChunkFetchingRequest { - candidate_hash: CandidateHash([43u8;32].into()), + candidate_hash: CandidateHash([43u8; 32].into()), index: ValidatorIndex(0), }, erasure_root: Hash::repeat_byte(99), @@ -296,6 +288,6 @@ fn get_test_running_task() -> (RunningTask, mpsc::Receiver) { metrics: Metrics::new_dummy(), span: jaeger::Span::Disabled, }, - rx + rx, ) } diff --git a/polkadot/node/network/availability-distribution/src/requester/mod.rs b/polkadot/node/network/availability-distribution/src/requester/mod.rs index 57bc9468642..f678a768d61 100644 --- a/polkadot/node/network/availability-distribution/src/requester/mod.rs +++ b/polkadot/node/network/availability-distribution/src/requester/mod.rs @@ -17,12 +17,14 @@ //! Requester takes care of requesting erasure chunks for candidates that are pending //! availability. -use std::collections::{ - hash_map::{Entry, HashMap}, - hash_set::HashSet, +use std::{ + collections::{ + hash_map::{Entry, HashMap}, + hash_set::HashSet, + }, + iter::IntoIterator, + pin::Pin, }; -use std::iter::IntoIterator; -use std::pin::Pin; use futures::{ channel::mpsc, @@ -30,20 +32,18 @@ use futures::{ Stream, }; -use polkadot_node_subsystem_util::runtime::{RuntimeInfo, get_occupied_cores}; +use polkadot_node_subsystem_util::runtime::{get_occupied_cores, RuntimeInfo}; use polkadot_primitives::v1::{CandidateHash, Hash, OccupiedCore}; use polkadot_subsystem::{ - messages::AllMessages, - ActiveLeavesUpdate, SubsystemContext, ActivatedLeaf, + messages::AllMessages, ActivatedLeaf, ActiveLeavesUpdate, SubsystemContext, }; -use super::{LOG_TARGET, Metrics}; +use super::{Metrics, LOG_TARGET}; /// Cache for session information. mod session_cache; use session_cache::SessionCache; - /// A task fetching a particular chunk. mod fetch_task; use fetch_task::{FetchTask, FetchTaskConfig, FromFetchTask}; @@ -81,13 +81,7 @@ impl Requester { /// by advancing the stream. pub fn new(metrics: Metrics) -> Self { let (tx, rx) = mpsc::channel(1); - Requester { - fetches: HashMap::new(), - session_cache: SessionCache::new(), - tx, - rx, - metrics, - } + Requester { fetches: HashMap::new(), session_cache: SessionCache::new(), tx, rx, metrics } } /// Update heads that need availability distribution. /// @@ -101,15 +95,8 @@ impl Requester { where Context: SubsystemContext, { - tracing::trace!( - target: LOG_TARGET, - ?update, - "Update fetching heads" - ); - let ActiveLeavesUpdate { - activated, - deactivated, - } = update; + tracing::trace!(target: LOG_TARGET, ?update, "Update fetching heads"); + let ActiveLeavesUpdate { activated, deactivated } = update; // Order important! We need to handle activated, prior to deactivated, otherwise we might // cancel still needed jobs. self.start_requesting_chunks(ctx, runtime, activated.into_iter()).await?; @@ -194,7 +181,7 @@ impl Requester { e.insert(FetchTask::start(task_cfg, ctx).await?); } // Not a validator, nothing to do. - } + }, } } Ok(()) @@ -204,28 +191,21 @@ impl Requester { impl Stream for Requester { type Item = AllMessages; - fn poll_next( - mut self: Pin<&mut Self>, - ctx: &mut Context, - ) -> Poll> { + fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { loop { match Pin::new(&mut self.rx).poll_next(ctx) { - Poll::Ready(Some(FromFetchTask::Message(m))) => - return Poll::Ready(Some(m)), + Poll::Ready(Some(FromFetchTask::Message(m))) => return Poll::Ready(Some(m)), Poll::Ready(Some(FromFetchTask::Concluded(Some(bad_boys)))) => { self.session_cache.report_bad_log(bad_boys); continue - } - Poll::Ready(Some(FromFetchTask::Concluded(None))) => - continue, + }, + Poll::Ready(Some(FromFetchTask::Concluded(None))) => continue, Poll::Ready(Some(FromFetchTask::Failed(candidate_hash))) => { // Make sure we retry on next block still pending availability. self.fetches.remove(&candidate_hash); - } - Poll::Ready(None) => - return Poll::Ready(None), - Poll::Pending => - return Poll::Pending, + }, + Poll::Ready(None) => return Poll::Ready(None), + Poll::Pending => return Poll::Pending, } } } diff --git a/polkadot/node/network/availability-distribution/src/requester/session_cache.rs b/polkadot/node/network/availability-distribution/src/requester/session_cache.rs index 8c62c0cd325..25b53d25aaa 100644 --- a/polkadot/node/network/availability-distribution/src/requester/session_cache.rs +++ b/polkadot/node/network/availability-distribution/src/requester/session_cache.rs @@ -34,7 +34,6 @@ use crate::{ /// /// It should be ensured that a cached session stays live in the cache as long as we might need it. pub struct SessionCache { - /// Look up cached sessions by `SessionIndex`. /// /// Note: Performance of fetching is really secondary here, but we need to ensure we are going @@ -110,12 +109,11 @@ impl SessionCache { if let Some(o_info) = self.session_info_cache.get(&session_index) { tracing::trace!(target: LOG_TARGET, session_index, "Got session from lru"); - return Ok(Some(with_info(o_info))); + return Ok(Some(with_info(o_info))) } - if let Some(info) = self - .query_info_from_runtime(ctx, runtime, parent, session_index) - .await? + if let Some(info) = + self.query_info_from_runtime(ctx, runtime, parent, session_index).await? { tracing::trace!(target: LOG_TARGET, session_index, "Calling `with_info`"); let r = with_info(&info); @@ -132,7 +130,7 @@ impl SessionCache { /// Not being able to report bad validators is not fatal, so we should not shutdown the /// subsystem on this. pub fn report_bad_log(&mut self, report: BadValidators) { - if let Err(err) = self.report_bad(report) { + if let Err(err) = self.report_bad(report) { tracing::warn!( target: LOG_TARGET, err = ?err, @@ -150,10 +148,9 @@ impl SessionCache { .session_info_cache .get_mut(&report.session_index) .ok_or(NonFatal::NoSuchCachedSession)?; - let group = session - .validator_groups - .get_mut(report.group_index.0 as usize) - .expect("A bad validator report must contain a valid group for the reported session. qed."); + let group = session.validator_groups.get_mut(report.group_index.0 as usize).expect( + "A bad validator report must contain a valid group for the reported session. qed.", + ); let bad_set = report.bad_validators.iter().collect::>(); // Get rid of bad boys: @@ -212,12 +209,7 @@ impl SessionCache { }) .collect(); - let info = SessionInfo { - validator_groups, - our_index, - session_index, - our_group, - }; + let info = SessionInfo { validator_groups, our_index, session_index, our_group }; return Ok(Some(info)) } return Ok(None) diff --git a/polkadot/node/network/availability-distribution/src/responder.rs b/polkadot/node/network/availability-distribution/src/responder.rs index 0805b9d332d..e9b779c2ba7 100644 --- a/polkadot/node/network/availability-distribution/src/responder.rs +++ b/polkadot/node/network/availability-distribution/src/responder.rs @@ -21,15 +21,15 @@ use std::sync::Arc; use futures::channel::oneshot; use polkadot_node_network_protocol::request_response::{request::IncomingRequest, v1}; -use polkadot_primitives::v1::{CandidateHash, ValidatorIndex}; use polkadot_node_primitives::{AvailableData, ErasureChunk}; -use polkadot_subsystem::{ - messages::AvailabilityStoreMessage, - SubsystemContext, jaeger, -}; +use polkadot_primitives::v1::{CandidateHash, ValidatorIndex}; +use polkadot_subsystem::{jaeger, messages::AvailabilityStoreMessage, SubsystemContext}; -use crate::error::{NonFatal, Result}; -use crate::{LOG_TARGET, metrics::{Metrics, SUCCEEDED, FAILED, NOT_FOUND}}; +use crate::{ + error::{NonFatal, Result}, + metrics::{Metrics, FAILED, NOT_FOUND, SUCCEEDED}, + LOG_TARGET, +}; /// Variant of `answer_pov_request` that does Prometheus metric and logging on errors. /// @@ -38,14 +38,12 @@ pub async fn answer_pov_request_log( ctx: &mut Context, req: IncomingRequest, metrics: &Metrics, -) -where +) where Context: SubsystemContext, { let res = answer_pov_request(ctx, req).await; match res { - Ok(result) => - metrics.on_served_pov(if result {SUCCEEDED} else {NOT_FOUND}), + Ok(result) => metrics.on_served_pov(if result { SUCCEEDED } else { NOT_FOUND }), Err(err) => { tracing::warn!( target: LOG_TARGET, @@ -53,7 +51,7 @@ where "Serving PoV failed with error" ); metrics.on_served_pov(FAILED); - } + }, } } @@ -70,8 +68,7 @@ where { let res = answer_chunk_request(ctx, req).await; match res { - Ok(result) => - metrics.on_served_chunk(if result {SUCCEEDED} else {NOT_FOUND}), + Ok(result) => metrics.on_served_chunk(if result { SUCCEEDED } else { NOT_FOUND }), Err(err) => { tracing::warn!( target: LOG_TARGET, @@ -79,7 +76,7 @@ where "Serving chunk failed with error" ); metrics.on_served_chunk(FAILED); - } + }, } } @@ -104,7 +101,7 @@ where Some(av_data) => { let pov = Arc::try_unwrap(av_data.pov).unwrap_or_else(|a| (&*a).clone()); v1::PoVFetchingResponse::PoV(pov) - } + }, }; req.send_response(response).map_err(|_| NonFatal::SendResponse)?; @@ -123,8 +120,7 @@ where { let span = jaeger::Span::new(req.payload.candidate_hash, "answer-chunk-request"); - let _child_span = span.child("answer-chunk-request") - .with_chunk_index(req.payload.index.0); + let _child_span = span.child("answer-chunk-request").with_chunk_index(req.payload.index.0); let chunk = query_chunk(ctx, req.payload.candidate_hash, req.payload.index).await?; @@ -158,10 +154,8 @@ where Context: SubsystemContext, { let (tx, rx) = oneshot::channel(); - ctx.send_message( - AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx), - ) - .await; + ctx.send_message(AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx)) + .await; let result = rx.await.map_err(|e| { tracing::trace!( @@ -185,10 +179,8 @@ where Context: SubsystemContext, { let (tx, rx) = oneshot::channel(); - ctx.send_message( - AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx), - ) - .await; + ctx.send_message(AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx)) + .await; let result = rx.await.map_err(|e| NonFatal::QueryAvailableDataResponseChannel(e))?; Ok(result) diff --git a/polkadot/node/network/availability-distribution/src/tests/mock.rs b/polkadot/node/network/availability-distribution/src/tests/mock.rs index ae17e2be1ff..0b11b22bf3b 100644 --- a/polkadot/node/network/availability-distribution/src/tests/mock.rs +++ b/polkadot/node/network/availability-distribution/src/tests/mock.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . - //! Helper functions and tools to generate mock data useful for testing this subsystem. use std::sync::Arc; @@ -22,43 +21,44 @@ use std::sync::Arc; use sp_keyring::Sr25519Keyring; use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks}; +use polkadot_node_primitives::{AvailableData, BlockData, ErasureChunk, PoV}; use polkadot_primitives::v1::{ - CandidateCommitments, CandidateDescriptor, CandidateHash, - CommittedCandidateReceipt, GroupIndex, Hash, HeadData, Id as ParaId, - OccupiedCore, PersistedValidationData, SessionInfo, ValidatorIndex + CandidateCommitments, CandidateDescriptor, CandidateHash, CommittedCandidateReceipt, + GroupIndex, Hash, HeadData, Id as ParaId, OccupiedCore, PersistedValidationData, SessionInfo, + ValidatorIndex, }; -use polkadot_node_primitives::{PoV, ErasureChunk, AvailableData, BlockData}; - /// Create dummy session info with two validator groups. pub fn make_session_info() -> SessionInfo { - let validators = vec![ - Sr25519Keyring::Ferdie, // <- this node, role: validator - Sr25519Keyring::Alice, - Sr25519Keyring::Bob, - Sr25519Keyring::Charlie, - Sr25519Keyring::Dave, - Sr25519Keyring::Eve, - Sr25519Keyring::One, - ]; - - let validator_groups: Vec> = [vec![5, 0, 3], vec![1, 6, 2, 4]] - .iter().map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()).collect(); - - SessionInfo { - discovery_keys: validators.iter().map(|k| k.public().into()).collect(), - // Not used: - n_cores: validator_groups.len() as u32, - validator_groups, - // Not used values: - validators: validators.iter().map(|k| k.public().into()).collect(), - assignment_keys: Vec::new(), - zeroth_delay_tranche_width: 0, - relay_vrf_modulo_samples: 0, - n_delay_tranches: 0, - no_show_slots: 0, - needed_approvals: 0, - } + let validators = vec![ + Sr25519Keyring::Ferdie, // <- this node, role: validator + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + Sr25519Keyring::One, + ]; + + let validator_groups: Vec> = [vec![5, 0, 3], vec![1, 6, 2, 4]] + .iter() + .map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()) + .collect(); + + SessionInfo { + discovery_keys: validators.iter().map(|k| k.public().into()).collect(), + // Not used: + n_cores: validator_groups.len() as u32, + validator_groups, + // Not used values: + validators: validators.iter().map(|k| k.public().into()).collect(), + assignment_keys: Vec::new(), + zeroth_delay_tranche_width: 0, + relay_vrf_modulo_samples: 0, + n_delay_tranches: 0, + no_show_slots: 0, + needed_approvals: 0, + } } /// Builder for constructing occupied cores. @@ -72,9 +72,7 @@ pub struct OccupiedCoreBuilder { impl OccupiedCoreBuilder { pub fn build(self) -> (OccupiedCore, (CandidateHash, ErasureChunk)) { - let pov = PoV { - block_data: BlockData(vec![45, 46, 47]), - }; + let pov = PoV { block_data: BlockData(vec![45, 46, 47]) }; let pov_hash = pov.hash(); let (erasure_root, chunk) = get_valid_chunk_data(pov.clone()); let candidate_receipt = TestCandidateBuilder { @@ -83,7 +81,8 @@ impl OccupiedCoreBuilder { relay_parent: self.relay_parent, erasure_root, ..Default::default() - }.build(); + } + .build(); let core = OccupiedCore { next_up_on_available: None, occupied_since: 0, @@ -117,10 +116,7 @@ impl TestCandidateBuilder { erasure_root: self.erasure_root, ..Default::default() }, - commitments: CandidateCommitments { - head_data: self.head_data, - ..Default::default() - }, + commitments: CandidateCommitments { head_data: self.head_data, ..Default::default() }, } } } @@ -134,18 +130,18 @@ pub fn get_valid_chunk_data(pov: PoV) -> (Hash, ErasureChunk) { max_pov_size: 1024, relay_parent_storage_root: Default::default(), }; - let available_data = AvailableData { - validation_data: persisted, pov: Arc::new(pov), - }; + let available_data = AvailableData { validation_data: persisted, pov: Arc::new(pov) }; let chunks = obtain_chunks(fake_validator_count, &available_data).unwrap(); let branches = branches(chunks.as_ref()); let root = branches.root(); - let chunk = branches.enumerate() - .map(|(index, (proof, chunk))| ErasureChunk { - chunk: chunk.to_vec(), - index: ValidatorIndex(index as _), - proof, - }) - .next().expect("There really should be 10 chunks."); + let chunk = branches + .enumerate() + .map(|(index, (proof, chunk))| ErasureChunk { + chunk: chunk.to_vec(), + index: ValidatorIndex(index as _), + proof, + }) + .next() + .expect("There really should be 10 chunks."); (root, chunk) } diff --git a/polkadot/node/network/availability-distribution/src/tests/mod.rs b/polkadot/node/network/availability-distribution/src/tests/mod.rs index b914a0cc0ba..068b35ce9dc 100644 --- a/polkadot/node/network/availability-distribution/src/tests/mod.rs +++ b/polkadot/node/network/availability-distribution/src/tests/mod.rs @@ -27,7 +27,7 @@ use super::*; mod state; /// State for test harnesses. -use state::{TestState, TestHarness}; +use state::{TestHarness, TestState}; /// Mock data useful for testing. pub(crate) mod mock; @@ -60,9 +60,7 @@ fn test_harness>( #[test] fn check_basic() { let state = TestState::default(); - test_harness(state.keystore.clone(), move |harness| { - state.run(harness) - }); + test_harness(state.keystore.clone(), move |harness| state.run(harness)); } /// Check whether requester tries all validators in group. @@ -75,9 +73,7 @@ fn check_fetch_tries_all() { v.push(None); v.push(None); } - test_harness(state.keystore.clone(), move |harness| { - state.run(harness) - }); + test_harness(state.keystore.clone(), move |harness| state.run(harness)); } /// Check whether requester tries all validators in group @@ -87,10 +83,9 @@ fn check_fetch_tries_all() { #[test] fn check_fetch_retry() { let mut state = TestState::default(); - state.cores.insert( - state.relay_chain[2], - state.cores.get(&state.relay_chain[1]).unwrap().clone(), - ); + state + .cores + .insert(state.relay_chain[2], state.cores.get(&state.relay_chain[1]).unwrap().clone()); // We only care about the first three blocks. // 1. scheduled // 2. occupied @@ -98,20 +93,18 @@ fn check_fetch_retry() { state.relay_chain.truncate(3); // Get rid of unused valid chunks: - let valid_candidate_hashes: HashSet<_> = state.cores + let valid_candidate_hashes: HashSet<_> = state + .cores .get(&state.relay_chain[1]) .iter() .flat_map(|v| v.iter()) - .filter_map(|c| { - match c { - CoreState::Occupied(core) => Some(core.candidate_hash), - _ => None, - } + .filter_map(|c| match c { + CoreState::Occupied(core) => Some(core.candidate_hash), + _ => None, }) .collect(); state.valid_chunks.retain(|(ch, _)| valid_candidate_hashes.contains(ch)); - for (_, v) in state.chunks.iter_mut() { // This should still succeed as cores are still pending availability on next block. v.push(None); @@ -120,7 +113,5 @@ fn check_fetch_retry() { v.push(None); v.push(None); } - test_harness(state.keystore.clone(), move |harness| { - state.run(harness) - }); + test_harness(state.keystore.clone(), move |harness| state.run(harness)); } diff --git a/polkadot/node/network/availability-distribution/src/tests/state.rs b/polkadot/node/network/availability-distribution/src/tests/state.rs index f07000d21cd..1a402e9a040 100644 --- a/polkadot/node/network/availability-distribution/src/tests/state.rs +++ b/polkadot/node/network/availability-distribution/src/tests/state.rs @@ -14,38 +14,44 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::{collections::{HashMap, HashSet}, sync::Arc, time::Duration}; +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, + time::Duration, +}; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_subsystem_testhelpers::TestSubsystemContextHandle; -use futures::{FutureExt, channel::oneshot, SinkExt, channel::mpsc, StreamExt}; +use futures::{ + channel::{mpsc, oneshot}, + FutureExt, SinkExt, StreamExt, +}; use futures_timer::Delay; -use sp_keystore::SyncCryptoStorePtr; -use sp_core::{traits::SpawnNamed, testing::TaskExecutor}; use sc_network as network; -use sc_network::IfDisconnected; -use sc_network::config as netconfig; +use sc_network::{config as netconfig, IfDisconnected}; +use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; +use sp_keystore::SyncCryptoStorePtr; -use polkadot_subsystem::{ - ActiveLeavesUpdate, FromOverseer, OverseerSignal, ActivatedLeaf, LeafStatus, - messages::{ - AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage, NetworkBridgeMessage, - RuntimeApiMessage, RuntimeApiRequest, - } -}; -use polkadot_primitives::v1::{CandidateHash, CoreState, GroupIndex, Hash, Id - as ParaId, ScheduledCore, SessionInfo, - ValidatorIndex -}; -use polkadot_node_primitives::ErasureChunk; use polkadot_node_network_protocol::{ jaeger, - request_response::{IncomingRequest, OutgoingRequest, Requests, v1} + request_response::{v1, IncomingRequest, OutgoingRequest, Requests}, +}; +use polkadot_node_primitives::ErasureChunk; +use polkadot_primitives::v1::{ + CandidateHash, CoreState, GroupIndex, Hash, Id as ParaId, ScheduledCore, SessionInfo, + ValidatorIndex, +}; +use polkadot_subsystem::{ + messages::{ + AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage, + NetworkBridgeMessage, RuntimeApiMessage, RuntimeApiRequest, + }, + ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, LeafStatus, OverseerSignal, }; use polkadot_subsystem_testhelpers as test_helpers; -use test_helpers::{SingleItemSink, mock::make_ferdie_keystore}; +use test_helpers::{mock::make_ferdie_keystore, SingleItemSink}; use super::mock::{make_session_info, OccupiedCoreBuilder}; use crate::LOG_TARGET; @@ -94,35 +100,32 @@ impl Default for TestState { let mut cores = HashMap::new(); let mut chunks = HashMap::new(); - cores.insert(relay_chain[0], + cores.insert( + relay_chain[0], vec![ - CoreState::Scheduled(ScheduledCore { - para_id: chain_ids[0], - collator: None, - }), - CoreState::Scheduled(ScheduledCore { - para_id: chain_ids[1], - collator: None, - }), - ] + CoreState::Scheduled(ScheduledCore { para_id: chain_ids[0], collator: None }), + CoreState::Scheduled(ScheduledCore { para_id: chain_ids[1], collator: None }), + ], ); - let heads = { + let heads = { let mut advanced = relay_chain.iter(); advanced.next(); relay_chain.iter().zip(advanced) }; for (relay_parent, relay_child) in heads { - let (p_cores, p_chunks): (Vec<_>, Vec<_>) = chain_ids.iter().enumerate() + let (p_cores, p_chunks): (Vec<_>, Vec<_>) = chain_ids + .iter() + .enumerate() .map(|(i, para_id)| { let (core, chunk) = OccupiedCoreBuilder { group_responsible: GroupIndex(i as _), para_id: *para_id, relay_parent: relay_parent.clone(), - }.build(); + } + .build(); (CoreState::Occupied(core), chunk) - } - ) + }) .unzip(); cores.insert(relay_child.clone(), p_cores); // Skip chunks for our own group (won't get fetched): @@ -146,11 +149,12 @@ impl Default for TestState { } impl TestState { - /// Run, but fail after some timeout. pub async fn run(self, harness: TestHarness) { // Make sure test won't run forever. - let f = self.run_inner(harness.pool, harness.virtual_overseer).timeout(Duration::from_secs(10)); + let f = self + .run_inner(harness.pool, harness.virtual_overseer) + .timeout(Duration::from_secs(10)); assert!(f.await.is_some(), "Test ran into timeout"); } @@ -167,17 +171,19 @@ impl TestState { let updates = { let mut advanced = self.relay_chain.iter(); advanced.next(); - self - .relay_chain.iter().zip(advanced) - .map(|(old, new)| ActiveLeavesUpdate { - activated: Some(ActivatedLeaf { - hash: new.clone(), - number: 1, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - }), - deactivated: vec![old.clone()].into(), - }).collect::>() + self.relay_chain + .iter() + .zip(advanced) + .map(|(old, new)| ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: new.clone(), + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + deactivated: vec![old.clone()].into(), + }) + .collect::>() }; // We should be storing all valid chunks during execution: @@ -190,24 +196,27 @@ impl TestState { // Spawning necessary as incoming queue can only hold a single item, we don't want to dead // lock ;-) let update_tx = tx.clone(); - executor.spawn("Sending active leaves updates", async move { - for update in updates { - overseer_signal( - update_tx.clone(), - OverseerSignal::ActiveLeaves(update) - ).await; - // We need to give the subsystem a little time to do its job, otherwise it will - // cancel jobs as obsolete: - Delay::new(Duration::from_millis(20)).await; + executor.spawn( + "Sending active leaves updates", + async move { + for update in updates { + overseer_signal(update_tx.clone(), OverseerSignal::ActiveLeaves(update)).await; + // We need to give the subsystem a little time to do its job, otherwise it will + // cancel jobs as obsolete: + Delay::new(Duration::from_millis(20)).await; + } } - }.boxed()); + .boxed(), + ); - while remaining_stores > 0 - { + while remaining_stores > 0 { tracing::trace!(target: LOG_TARGET, remaining_stores, "Stores left to go"); let msg = overseer_recv(&mut rx).await; match msg { - AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests(reqs, IfDisconnected::TryConnect)) => { + AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests( + reqs, + IfDisconnected::TryConnect, + )) => { for req in reqs { // Forward requests: let in_req = to_incoming_req(&executor, req); @@ -215,50 +224,61 @@ impl TestState { executor.spawn( "Request forwarding", overseer_send( - tx.clone(), - AvailabilityDistributionMessage::ChunkFetchingRequest(in_req) - ).boxed() + tx.clone(), + AvailabilityDistributionMessage::ChunkFetchingRequest(in_req), + ) + .boxed(), ); } - } - AllMessages::AvailabilityStore(AvailabilityStoreMessage::QueryChunk(candidate_hash, validator_index, tx)) => { - let chunk = self.chunks.get_mut(&(candidate_hash, validator_index)).map(Vec::pop).flatten().flatten(); - tx.send(chunk) - .expect("Receiver is expected to be alive"); - } - AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreChunk{candidate_hash, chunk, tx, ..}) => { + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::QueryChunk( + candidate_hash, + validator_index, + tx, + )) => { + let chunk = self + .chunks + .get_mut(&(candidate_hash, validator_index)) + .map(Vec::pop) + .flatten() + .flatten(); + tx.send(chunk).expect("Receiver is expected to be alive"); + }, + AllMessages::AvailabilityStore(AvailabilityStoreMessage::StoreChunk { + candidate_hash, + chunk, + tx, + .. + }) => { assert!( self.valid_chunks.contains(&(candidate_hash, chunk.index)), "Only valid chunks should ever get stored." ); - tx.send(Ok(())) - .expect("Receiver is expected to be alive"); + tx.send(Ok(())).expect("Receiver is expected to be alive"); tracing::trace!(target: LOG_TARGET, "'Stored' fetched chunk."); remaining_stores -= 1; - } + }, AllMessages::RuntimeApi(RuntimeApiMessage::Request(hash, req)) => { match req { RuntimeApiRequest::SessionIndexForChild(tx) => { // Always session index 1 for now: - tx.send(Ok(1)) - .expect("Receiver should still be alive"); - } + tx.send(Ok(1)).expect("Receiver should still be alive"); + }, RuntimeApiRequest::SessionInfo(_, tx) => { tx.send(Ok(Some(self.session_info.clone()))) - .expect("Receiver should be alive."); - } + .expect("Receiver should be alive."); + }, RuntimeApiRequest::AvailabilityCores(tx) => { tracing::trace!(target: LOG_TARGET, cores= ?self.cores[&hash], hash = ?hash, "Sending out cores for hash"); tx.send(Ok(self.cores[&hash].clone())) - .expect("Receiver should still be alive"); - } + .expect("Receiver should still be alive"); + }, _ => { panic!("Unexpected runtime request: {:?}", req); - } + }, } - } - _ => { - } + }, + _ => {}, } } @@ -272,9 +292,7 @@ async fn overseer_signal( ) { let msg = msg.into(); tracing::trace!(target: LOG_TARGET, msg = ?msg, "sending message"); - tx.send(FromOverseer::Signal(msg)) - .await - .expect("Test subsystem no longer live"); + tx.send(FromOverseer::Signal(msg)).await.expect("Test subsystem no longer live"); } async fn overseer_send( @@ -283,42 +301,44 @@ async fn overseer_send( ) { let msg = msg.into(); tracing::trace!(target: LOG_TARGET, msg = ?msg, "sending message"); - tx.send(FromOverseer::Communication { msg }).await + tx.send(FromOverseer::Communication { msg }) + .await .expect("Test subsystem no longer live"); tracing::trace!(target: LOG_TARGET, "sent message"); } - -async fn overseer_recv( - rx: &mut mpsc::UnboundedReceiver, -) -> AllMessages { +async fn overseer_recv(rx: &mut mpsc::UnboundedReceiver) -> AllMessages { tracing::trace!(target: LOG_TARGET, "waiting for message ..."); rx.next().await.expect("Test subsystem no longer live") } fn to_incoming_req( executor: &TaskExecutor, - outgoing: Requests + outgoing: Requests, ) -> IncomingRequest { match outgoing { Requests::ChunkFetching(OutgoingRequest { payload, pending_response, .. }) => { - let (tx, rx): (oneshot::Sender, oneshot::Receiver<_>) - = oneshot::channel(); - executor.spawn("Message forwarding", async { - let response = rx.await; - let payload = response.expect("Unexpected canceled request").result; - pending_response.send(payload.map_err(|_| network::RequestFailure::Refused)) - .expect("Sending response is expected to work"); - }.boxed() + let (tx, rx): (oneshot::Sender, oneshot::Receiver<_>) = + oneshot::channel(); + executor.spawn( + "Message forwarding", + async { + let response = rx.await; + let payload = response.expect("Unexpected canceled request").result; + pending_response + .send(payload.map_err(|_| network::RequestFailure::Refused)) + .expect("Sending response is expected to work"); + } + .boxed(), ); IncomingRequest::new( // We don't really care: network::PeerId::random(), payload, - tx + tx, ) - } + }, _ => panic!("Unexpected request!"), } } diff --git a/polkadot/node/network/availability-recovery/src/lib.rs b/polkadot/node/network/availability-recovery/src/lib.rs index b164675083d..bf0d73ba2f9 100644 --- a/polkadot/node/network/availability-recovery/src/lib.rs +++ b/polkadot/node/network/availability-recovery/src/lib.rs @@ -18,40 +18,42 @@ #![warn(missing_docs)] -use std::collections::{HashMap, VecDeque}; -use std::pin::Pin; +use std::{ + collections::{HashMap, VecDeque}, + pin::Pin, +}; -use futures::{channel::oneshot, prelude::*, stream::FuturesUnordered}; -use futures::future::{BoxFuture, RemoteHandle, FutureExt}; -use futures::task::{Context, Poll}; +use futures::{ + channel::oneshot, + future::{BoxFuture, FutureExt, RemoteHandle}, + prelude::*, + stream::FuturesUnordered, + task::{Context, Poll}, +}; use lru::LruCache; use rand::seq::SliceRandom; +use polkadot_erasure_coding::{branch_hash, branches, obtain_chunks_v1, recovery_threshold}; +use polkadot_node_network_protocol::{ + request_response::{ + self as req_res, request::RequestError, OutgoingRequest, Recipient, Requests, + }, + IfDisconnected, +}; +use polkadot_node_primitives::{AvailableData, ErasureChunk}; +use polkadot_node_subsystem_util::request_session_info; use polkadot_primitives::v1::{ - AuthorityDiscoveryId, CandidateReceipt, CandidateHash, - Hash, ValidatorId, ValidatorIndex, - SessionInfo, SessionIndex, BlakeTwo256, HashT, GroupIndex, BlockNumber, + AuthorityDiscoveryId, BlakeTwo256, BlockNumber, CandidateHash, CandidateReceipt, GroupIndex, + Hash, HashT, SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, }; -use polkadot_node_primitives::{ErasureChunk, AvailableData}; use polkadot_subsystem::{ - overseer::{self, Subsystem}, - SubsystemContext, SubsystemResult, SubsystemError, SpawnedSubsystem, FromOverseer, - OverseerSignal, ActiveLeavesUpdate, SubsystemSender, errors::RecoveryError, jaeger, - messages::{ - AvailabilityStoreMessage, AvailabilityRecoveryMessage, NetworkBridgeMessage, - }, -}; -use polkadot_node_network_protocol::{ - IfDisconnected, - request_response::{ - self as req_res, OutgoingRequest, Recipient, Requests, - request::RequestError, - }, + messages::{AvailabilityRecoveryMessage, AvailabilityStoreMessage, NetworkBridgeMessage}, + overseer::{self, Subsystem}, + ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, + SubsystemError, SubsystemResult, SubsystemSender, }; -use polkadot_node_subsystem_util::request_session_info; -use polkadot_erasure_coding::{branches, branch_hash, recovery_threshold, obtain_chunks_v1}; mod error; @@ -82,9 +84,8 @@ struct RequestChunksPhase { // request the chunk from them. shuffling: VecDeque, received_chunks: HashMap, - requesting_chunks: FuturesUnordered, (ValidatorIndex, RequestError)>>, + requesting_chunks: FuturesUnordered< + BoxFuture<'static, Result, (ValidatorIndex, RequestError)>>, >, } @@ -125,9 +126,7 @@ impl RequestFromBackersPhase { fn new(mut backers: Vec) -> Self { backers.shuffle(&mut rand::thread_rng()); - RequestFromBackersPhase { - shuffled_backers: backers, - } + RequestFromBackersPhase { shuffled_backers: backers } } // Run this phase to completion. @@ -144,29 +143,41 @@ impl RequestFromBackersPhase { ); loop { // Pop the next backer, and proceed to next phase if we're out. - let validator_index = self.shuffled_backers.pop().ok_or_else(|| RecoveryError::Unavailable)?; + let validator_index = + self.shuffled_backers.pop().ok_or_else(|| RecoveryError::Unavailable)?; // Request data. let (req, res) = OutgoingRequest::new( - Recipient::Authority(params.validator_authority_keys[validator_index.0 as usize].clone()), + Recipient::Authority( + params.validator_authority_keys[validator_index.0 as usize].clone(), + ), req_res::v1::AvailableDataFetchingRequest { candidate_hash: params.candidate_hash }, ); - sender.send_message(NetworkBridgeMessage::SendRequests( - vec![Requests::AvailableDataFetching(req)], - IfDisconnected::TryConnect, - ).into()).await; + sender + .send_message( + NetworkBridgeMessage::SendRequests( + vec![Requests::AvailableDataFetching(req)], + IfDisconnected::TryConnect, + ) + .into(), + ) + .await; match res.await { Ok(req_res::v1::AvailableDataFetchingResponse::AvailableData(data)) => { - if reconstructed_data_matches_root(params.validators.len(), ¶ms.erasure_root, &data) { + if reconstructed_data_matches_root( + params.validators.len(), + ¶ms.erasure_root, + &data, + ) { tracing::trace!( target: LOG_TARGET, candidate_hash = ?params.candidate_hash, "Received full data", ); - return Ok(data); + return Ok(data) } else { tracing::debug!( target: LOG_TARGET, @@ -177,8 +188,8 @@ impl RequestFromBackersPhase { // it doesn't help to report the peer with req/res. } - } - Ok(req_res::v1::AvailableDataFetchingResponse::NoSuchData) => {} + }, + Ok(req_res::v1::AvailableDataFetchingResponse::NoSuchData) => {}, Err(e) => tracing::debug!( target: LOG_TARGET, candidate_hash = ?params.candidate_hash, @@ -239,34 +250,34 @@ impl RequestChunksPhase { index: validator_index, }; - let (req, res) = OutgoingRequest::new( - Recipient::Authority(validator), - raw_request.clone(), - ); + let (req, res) = + OutgoingRequest::new(Recipient::Authority(validator), raw_request.clone()); - sender.send_message(NetworkBridgeMessage::SendRequests( - vec![Requests::ChunkFetching(req)], - IfDisconnected::TryConnect, - ).into()).await; + sender + .send_message( + NetworkBridgeMessage::SendRequests( + vec![Requests::ChunkFetching(req)], + IfDisconnected::TryConnect, + ) + .into(), + ) + .await; self.requesting_chunks.push(Box::pin(async move { match res.await { - Ok(req_res::v1::ChunkFetchingResponse::Chunk(chunk)) - => Ok(Some(chunk.recombine_into_chunk(&raw_request))), + Ok(req_res::v1::ChunkFetchingResponse::Chunk(chunk)) => + Ok(Some(chunk.recombine_into_chunk(&raw_request))), Ok(req_res::v1::ChunkFetchingResponse::NoSuchChunk) => Ok(None), Err(e) => Err((validator_index, e)), } })); } else { - break; + break } } } - async fn wait_for_chunks( - &mut self, - params: &InteractionParams, - ) { + async fn wait_for_chunks(&mut self, params: &InteractionParams) { // Wait for all current requests to conclude or time-out, or until we reach enough chunks. while let Some(request_result) = self.requesting_chunks.next().await { match request_result { @@ -275,11 +286,9 @@ impl RequestChunksPhase { let validator_index = chunk.index; - if let Ok(anticipated_hash) = branch_hash( - ¶ms.erasure_root, - &chunk.proof, - chunk.index.0 as usize, - ) { + if let Ok(anticipated_hash) = + branch_hash(¶ms.erasure_root, &chunk.proof, chunk.index.0 as usize) + { let erasure_chunk_hash = BlakeTwo256::hash(&chunk.chunk); if erasure_chunk_hash != anticipated_hash { @@ -303,8 +312,8 @@ impl RequestChunksPhase { "Invalid Merkle proof", ); } - } - Ok(None) => {} + }, + Ok(None) => {}, Err((validator_index, e)) => { tracing::debug!( target: LOG_TARGET, @@ -314,17 +323,19 @@ impl RequestChunksPhase { ); match e { - RequestError::InvalidResponse(_) => {} + RequestError::InvalidResponse(_) => {}, RequestError::NetworkError(_) | RequestError::Canceled(_) => { self.shuffling.push_front(validator_index); - } + }, } - } + }, } // Stop waiting for requests when we either can already recover the data // or have gotten firm 'No' responses from enough validators. - if self.can_conclude(params) { break } + if self.can_conclude(params) { + break + } } } @@ -336,9 +347,11 @@ impl RequestChunksPhase { // First query the store for any chunks we've got. { let (tx, rx) = oneshot::channel(); - sender.send_message( - AvailabilityStoreMessage::QueryAllChunks(params.candidate_hash, tx).into() - ).await; + sender + .send_message( + AvailabilityStoreMessage::QueryAllChunks(params.candidate_hash, tx).into(), + ) + .await; match rx.await { Ok(chunks) => { @@ -350,14 +363,14 @@ impl RequestChunksPhase { for chunk in chunks { self.received_chunks.insert(chunk.index, chunk); } - } + }, Err(oneshot::Canceled) => { tracing::warn!( target: LOG_TARGET, candidate_hash = ?params.candidate_hash, "Failed to reach the availability store" ); - } + }, } } @@ -373,7 +386,7 @@ impl RequestChunksPhase { "Data recovery is not possible", ); - return Err(RecoveryError::Unavailable); + return Err(RecoveryError::Unavailable) } self.launch_parallel_requests(params, sender).await; @@ -388,7 +401,11 @@ impl RequestChunksPhase { self.received_chunks.values().map(|c| (&c.chunk[..], c.index.0 as usize)), ) { Ok(data) => { - if reconstructed_data_matches_root(params.validators.len(), ¶ms.erasure_root, &data) { + if reconstructed_data_matches_root( + params.validators.len(), + ¶ms.erasure_root, + &data, + ) { tracing::trace!( target: LOG_TARGET, candidate_hash = ?params.candidate_hash, @@ -407,7 +424,7 @@ impl RequestChunksPhase { Err(RecoveryError::Invalid) } - } + }, Err(err) => { tracing::trace!( target: LOG_TARGET, @@ -419,7 +436,7 @@ impl RequestChunksPhase { Err(RecoveryError::Invalid) }, - }; + } } } } @@ -447,8 +464,8 @@ fn reconstructed_data_matches_root( err = ?e, "Failed to obtain chunks", ); - return false; - } + return false + }, }; let branches = branches(&chunks); @@ -461,20 +478,23 @@ impl Interaction { // First just see if we have the data available locally. { let (tx, rx) = oneshot::channel(); - self.sender.send_message( - AvailabilityStoreMessage::QueryAvailableData(self.params.candidate_hash, tx).into() - ).await; + self.sender + .send_message( + AvailabilityStoreMessage::QueryAvailableData(self.params.candidate_hash, tx) + .into(), + ) + .await; match rx.await { Ok(Some(data)) => return Ok(data), - Ok(None) => {} + Ok(None) => {}, Err(oneshot::Canceled) => { tracing::warn!( target: LOG_TARGET, candidate_hash = ?self.params.candidate_hash, "Failed to reach the availability store", ) - } + }, } } @@ -486,16 +506,14 @@ impl Interaction { match from_backers.run(&self.params, &mut self.sender).await { Ok(data) => break Ok(data), Err(RecoveryError::Invalid) => break Err(RecoveryError::Invalid), - Err(RecoveryError::Unavailable) => { - self.phase = InteractionPhase::RequestChunks( - RequestChunksPhase::new(self.params.validators.len() as _) - ) - } + Err(RecoveryError::Unavailable) => + self.phase = InteractionPhase::RequestChunks(RequestChunksPhase::new( + self.params.validators.len() as _, + )), } - } - InteractionPhase::RequestChunks(ref mut from_all) => { - break from_all.run(&self.params, &mut self.sender).await; - } + }, + InteractionPhase::RequestChunks(ref mut from_all) => + break from_all.run(&self.params, &mut self.sender).await, } } } @@ -514,7 +532,7 @@ impl Future for InteractionHandle { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut indices_to_remove = Vec::new(); for (i, awaiting) in self.awaiting.iter_mut().enumerate().rev() { - if let Poll::Ready(()) = awaiting.poll_canceled(cx) { + if let Poll::Ready(()) = awaiting.poll_canceled(cx) { indices_to_remove.push(i); } } @@ -537,7 +555,7 @@ impl Future for InteractionHandle { "All receivers for available data dropped.", ); - return Poll::Ready(None); + return Poll::Ready(None) } let remote = &mut self.remote; @@ -580,21 +598,16 @@ where Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { - let future = self.run(ctx) + let future = self + .run(ctx) .map_err(|e| SubsystemError::with_origin("availability-recovery", e)) .boxed(); - SpawnedSubsystem { - name: "availability-recovery-subsystem", - future, - } + SpawnedSubsystem { name: "availability-recovery-subsystem", future } } } /// Handles a signal from the overseer. -async fn handle_signal( - state: &mut State, - signal: OverseerSignal, -) -> SubsystemResult { +async fn handle_signal(state: &mut State, signal: OverseerSignal) -> SubsystemResult { match signal { OverseerSignal::Conclude => Ok(true), OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { activated, .. }) => { @@ -606,8 +619,8 @@ async fn handle_signal( } Ok(false) - } - OverseerSignal::BlockFinalized(_, _) => Ok(false) + }, + OverseerSignal::BlockFinalized(_, _) => Ok(false), } } @@ -636,18 +649,14 @@ where let phase = backing_group .and_then(|g| session_info.validator_groups.get(g.0 as usize)) - .map(|group| InteractionPhase::RequestFromBackers( - RequestFromBackersPhase::new(group.clone()) - )) - .unwrap_or_else(|| InteractionPhase::RequestChunks( - RequestChunksPhase::new(params.validators.len() as _) - )); - - let interaction = Interaction { - sender: ctx.sender().clone(), - params, - phase, - }; + .map(|group| { + InteractionPhase::RequestFromBackers(RequestFromBackersPhase::new(group.clone())) + }) + .unwrap_or_else(|| { + InteractionPhase::RequestChunks(RequestChunksPhase::new(params.validators.len() as _)) + }); + + let interaction = Interaction { sender: ctx.sender().clone(), params, phase }; let (remote, remote_handle) = interaction.run().remote_handle(); @@ -694,43 +703,32 @@ where "Error responding with an availability recovery result", ); } - return Ok(()); + return Ok(()) } if let Some(i) = state.interactions.iter_mut().find(|i| i.candidate_hash == candidate_hash) { i.awaiting.push(response_sender); - return Ok(()); + return Ok(()) } let _span = span.child("not-cached"); - let session_info = request_session_info( - state.live_block.1, - session_index, - ctx.sender(), - ).await.await.map_err(error::Error::CanceledSessionInfo)??; + let session_info = request_session_info(state.live_block.1, session_index, ctx.sender()) + .await + .await + .map_err(error::Error::CanceledSessionInfo)??; let _span = span.child("session-info-ctx-received"); match session_info { - Some(session_info) => { - launch_interaction( - state, - ctx, - session_info, - receipt, - backing_group, - response_sender, - ).await - } + Some(session_info) => + launch_interaction(state, ctx, session_info, receipt, backing_group, response_sender) + .await, None => { - tracing::warn!( - target: LOG_TARGET, - "SessionInfo is `None` at {:?}", state.live_block, - ); + tracing::warn!(target: LOG_TARGET, "SessionInfo is `None` at {:?}", state.live_block,); response_sender .send(Err(RecoveryError::Unavailable)) .map_err(|_| error::Error::CanceledResponseSender)?; Ok(()) - } + }, } } @@ -744,9 +742,8 @@ where Context: overseer::SubsystemContext, { let (tx, rx) = oneshot::channel(); - ctx.send_message( - AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx), - ).await; + ctx.send_message(AvailabilityStoreMessage::QueryAvailableData(candidate_hash, tx)) + .await; Ok(rx.await.map_err(error::Error::CanceledQueryFullData)?) } @@ -762,10 +759,7 @@ impl AvailabilityRecoverySubsystem { Self { fast_path: false } } - async fn run( - self, - mut ctx: Context, - ) -> SubsystemResult<()> + async fn run(self, mut ctx: Context) -> SubsystemResult<()> where Context: SubsystemContext, Context: overseer::SubsystemContext, diff --git a/polkadot/node/network/availability-recovery/src/tests.rs b/polkadot/node/network/availability-recovery/src/tests.rs index 3a72e222ed6..e59cd858893 100644 --- a/polkadot/node/network/availability-recovery/src/tests.rs +++ b/polkadot/node/network/availability-recovery/src/tests.rs @@ -14,27 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::time::Duration; -use std::sync::Arc; +use std::{sync::Arc, time::Duration}; +use assert_matches::assert_matches; use futures::{executor, future}; use futures_timer::Delay; -use assert_matches::assert_matches; use parity_scale_codec::Encode; use super::*; -use polkadot_primitives::v1::{ - AuthorityDiscoveryId, PersistedValidationData, HeadData, -}; -use polkadot_node_primitives::{PoV, BlockData}; use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks}; +use polkadot_node_primitives::{BlockData, PoV}; use polkadot_node_subsystem_util::TimeoutExt; -use polkadot_subsystem_testhelpers as test_helpers; +use polkadot_primitives::v1::{AuthorityDiscoveryId, HeadData, PersistedValidationData}; use polkadot_subsystem::{ - messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, jaeger, ActivatedLeaf, LeafStatus, + jaeger, + messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, LeafStatus, }; +use polkadot_subsystem_testhelpers as test_helpers; type VirtualOverseer = test_helpers::TestSubsystemContextHandle; @@ -43,10 +42,7 @@ fn test_harness_fast_path>( ) { let _ = env_logger::builder() .is_test(true) - .filter( - Some("polkadot_availability_recovery"), - log::LevelFilter::Trace, - ) + .filter(Some("polkadot_availability_recovery"), log::LevelFilter::Trace) .try_init(); let pool = sp_core::testing::TaskExecutor::new(); @@ -61,10 +57,15 @@ fn test_harness_fast_path>( futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer_signal(&mut overseer, OverseerSignal::Conclude).await; - }, subsystem)).1.unwrap(); + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); } fn test_harness_chunks_only>( @@ -72,10 +73,7 @@ fn test_harness_chunks_only>( ) { let _ = env_logger::builder() .is_test(true) - .filter( - Some("polkadot_availability_recovery"), - log::LevelFilter::Trace, - ) + .filter(Some("polkadot_availability_recovery"), log::LevelFilter::Trace) .try_init(); let pool = sp_core::testing::TaskExecutor::new(); @@ -90,10 +88,15 @@ fn test_harness_chunks_only>( futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer_signal(&mut overseer, OverseerSignal::Conclude).await; - }, subsystem)).1.unwrap(); + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); } const TIMEOUT: Duration = Duration::from_millis(100); @@ -132,16 +135,11 @@ async fn overseer_recv( overseer: &mut test_helpers::TestSubsystemContextHandle, ) -> AllMessages { tracing::trace!("waiting for message ..."); - let msg = overseer - .recv() - .timeout(TIMEOUT) - .await - .expect("TIMEOUT is enough to recv."); + let msg = overseer.recv().timeout(TIMEOUT).await.expect("TIMEOUT is enough to recv."); tracing::trace!(msg = ?msg, "received message"); msg } - use sp_keyring::Sr25519Keyring; #[derive(Debug)] @@ -153,9 +151,7 @@ enum Has { impl Has { fn timeout() -> Self { - Has::NetworkError(sc_network::RequestFailure::Network( - sc_network::OutboundFailure::Timeout - )) + Has::NetworkError(sc_network::RequestFailure::Network(sc_network::OutboundFailure::Timeout)) } } @@ -183,10 +179,7 @@ impl TestState { self.validators.len() - self.threshold() + 1 } - async fn test_runtime_api( - &self, - virtual_overseer: &mut VirtualOverseer, - ) { + async fn test_runtime_api(&self, virtual_overseer: &mut VirtualOverseer) { assert_matches!( overseer_recv(virtual_overseer).await, AllMessages::RuntimeApi(RuntimeApiMessage::Request( @@ -233,7 +226,7 @@ impl TestState { async fn respond_to_query_all_request( &self, virtual_overseer: &mut VirtualOverseer, - send_chunk: impl Fn(usize) -> bool + send_chunk: impl Fn(usize) -> bool, ) { assert_matches!( overseer_recv(virtual_overseer).await, @@ -344,7 +337,6 @@ impl TestState { } } - fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { val_ids.iter().map(|v| v.public().into()).collect() } @@ -406,9 +398,7 @@ impl Default for TestState { relay_parent_storage_root: Default::default(), }; - let pov = PoV { - block_data: BlockData(vec![42; 64]), - }; + let pov = PoV { block_data: BlockData(vec![42; 64]) }; let available_data = AvailableData { validation_data: persisted_validation_data.clone(), @@ -451,7 +441,8 @@ fn availability_is_recovered_from_chunks_if_no_group_provided() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -462,8 +453,9 @@ fn availability_is_recovered_from_chunks_if_no_group_provided() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -472,12 +464,14 @@ fn availability_is_recovered_from_chunks_if_no_group_provided() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.threshold(), - |_| Has::Yes, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); @@ -496,20 +490,23 @@ fn availability_is_recovered_from_chunks_if_no_group_provided() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - new_candidate.hash(), - &mut virtual_overseer, - test_state.impossibility_threshold(), - |_| Has::No, - ).await; + test_state + .test_chunk_requests( + new_candidate.hash(), + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; // A request times out with `Unavailable` error. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); @@ -530,7 +527,8 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -541,8 +539,9 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk test_state.session_index, Some(GroupIndex(0)), tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -551,12 +550,14 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.threshold(), - |_| Has::Yes, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); @@ -575,20 +576,23 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - new_candidate.hash(), - &mut virtual_overseer, - test_state.impossibility_threshold(), - |_| Has::No, - ).await; + test_state + .test_chunk_requests( + new_candidate.hash(), + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; // A request times out with `Unavailable` error. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); @@ -609,7 +613,8 @@ fn bad_merkle_path_leads_to_recovery_error() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -620,8 +625,9 @@ fn bad_merkle_path_leads_to_recovery_error() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -637,12 +643,14 @@ fn bad_merkle_path_leads_to_recovery_error() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.impossibility_threshold(), - |_| Has::Yes, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::Yes, + ) + .await; // A request times out with `Unavailable` error. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); @@ -663,7 +671,8 @@ fn wrong_chunk_index_leads_to_recovery_error() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -674,8 +683,9 @@ fn wrong_chunk_index_leads_to_recovery_error() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -690,12 +700,14 @@ fn wrong_chunk_index_leads_to_recovery_error() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.impossibility_threshold(), - |_| Has::No, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; // A request times out with `Unavailable` error as there are no good peers. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); @@ -708,9 +720,7 @@ fn invalid_erasure_coding_leads_to_invalid_error() { let mut test_state = TestState::default(); test_harness_fast_path(|mut virtual_overseer| async move { - let pov = PoV { - block_data: BlockData(vec![69; 64]), - }; + let pov = PoV { block_data: BlockData(vec![69; 64]) }; let (bad_chunks, bad_erasure_root) = derive_erasure_chunks_with_proofs_and_root( test_state.chunks.len(), @@ -734,7 +744,8 @@ fn invalid_erasure_coding_leads_to_invalid_error() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -745,20 +756,23 @@ fn invalid_erasure_coding_leads_to_invalid_error() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.threshold(), - |_| Has::Yes, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; // f+1 'valid' chunks can't produce correct data. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Invalid); @@ -779,7 +793,8 @@ fn fast_path_backing_group_recovers() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -790,8 +805,9 @@ fn fast_path_backing_group_recovers() { test_state.session_index, Some(GroupIndex(0)), tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -804,11 +820,9 @@ fn fast_path_backing_group_recovers() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; - test_state.test_full_data_requests( - candidate_hash, - &mut virtual_overseer, - who_has, - ).await; + test_state + .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .await; // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); @@ -829,7 +843,8 @@ fn no_answers_in_fast_path_causes_chunk_requests() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -840,8 +855,9 @@ fn no_answers_in_fast_path_causes_chunk_requests() { test_state.session_index, Some(GroupIndex(0)), tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -855,20 +871,20 @@ fn no_answers_in_fast_path_causes_chunk_requests() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; - test_state.test_full_data_requests( - candidate_hash, - &mut virtual_overseer, - who_has, - ).await; + test_state + .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.threshold(), - |_| Has::Yes, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold(), + |_| Has::Yes, + ) + .await; // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); @@ -889,7 +905,8 @@ fn task_canceled_when_receivers_dropped() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, _) = oneshot::channel(); @@ -900,8 +917,9 @@ fn task_canceled_when_receivers_dropped() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -929,7 +947,8 @@ fn chunks_retry_until_all_nodes_respond() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -940,8 +959,9 @@ fn chunks_retry_until_all_nodes_respond() { test_state.session_index, Some(GroupIndex(0)), tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; @@ -950,21 +970,25 @@ fn chunks_retry_until_all_nodes_respond() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.validators.len(), - |_| Has::timeout(), - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.validators.len(), + |_| Has::timeout(), + ) + .await; // we get to go another round! - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.impossibility_threshold(), - |_| Has::No, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.impossibility_threshold(), + |_| Has::No, + ) + .await; // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); @@ -985,7 +1009,8 @@ fn returns_early_if_we_have_the_data() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -996,8 +1021,9 @@ fn returns_early_if_we_have_the_data() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; test_state.respond_to_available_data_query(&mut virtual_overseer, true).await; @@ -1020,7 +1046,8 @@ fn does_not_query_local_validator() { status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; let (tx, rx) = oneshot::channel(); @@ -1031,8 +1058,9 @@ fn does_not_query_local_validator() { test_state.session_index, None, tx, - ) - ).await; + ), + ) + .await; test_state.test_runtime_api(&mut virtual_overseer).await; test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; @@ -1040,28 +1068,24 @@ fn does_not_query_local_validator() { let candidate_hash = test_state.candidate.hash(); - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.validators.len(), - |i| if i == 0 { - panic!("requested from local validator") - } else { - Has::timeout() - }, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.validators.len(), + |i| if i == 0 { panic!("requested from local validator") } else { Has::timeout() }, + ) + .await; // second round, make sure it uses the local chunk. - test_state.test_chunk_requests( - candidate_hash, - &mut virtual_overseer, - test_state.threshold() - 1, - |i| if i == 0 { - panic!("requested from local validator") - } else { - Has::Yes - }, - ).await; + test_state + .test_chunk_requests( + candidate_hash, + &mut virtual_overseer, + test_state.threshold() - 1, + |i| if i == 0 { panic!("requested from local validator") } else { Has::Yes }, + ) + .await; assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); virtual_overseer diff --git a/polkadot/node/network/bitfield-distribution/src/lib.rs b/polkadot/node/network/bitfield-distribution/src/lib.rs index e339e6dc66f..d0184fd7148 100644 --- a/polkadot/node/network/bitfield-distribution/src/lib.rs +++ b/polkadot/node/network/bitfield-distribution/src/lib.rs @@ -24,19 +24,19 @@ use futures::{channel::oneshot, FutureExt}; -use polkadot_subsystem::messages::*; -use polkadot_subsystem::{ - PerLeafSpan, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, - SubsystemContext, SubsystemResult, SubsystemError, - jaeger, - overseer, +use polkadot_node_network_protocol::{ + v1 as protocol_v1, OurView, PeerId, UnifiedReputationChange as Rep, View, }; use polkadot_node_subsystem_util::{ + self as util, metrics::{self, prometheus}, - self as util, MIN_GOSSIP_PEERS, + MIN_GOSSIP_PEERS, }; use polkadot_primitives::v1::{Hash, SignedAvailabilityBitfield, SigningContext, ValidatorId}; -use polkadot_node_network_protocol::{v1 as protocol_v1, PeerId, View, UnifiedReputationChange as Rep, OurView}; +use polkadot_subsystem::{ + jaeger, messages::*, overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, PerLeafSpan, + SpawnedSubsystem, SubsystemContext, SubsystemError, SubsystemResult, +}; use std::collections::{HashMap, HashSet}; #[cfg(test)] @@ -46,8 +46,10 @@ const COST_SIGNATURE_INVALID: Rep = Rep::CostMajor("Bitfield signature invalid") const COST_VALIDATOR_INDEX_INVALID: Rep = Rep::CostMajor("Bitfield validator index invalid"); const COST_MISSING_PEER_SESSION_KEY: Rep = Rep::CostMinor("Missing peer session key"); const COST_NOT_IN_VIEW: Rep = Rep::CostMinor("Not interested in that parent hash"); -const COST_PEER_DUPLICATE_MESSAGE: Rep = Rep::CostMinorRepeated("Peer sent the same message multiple times"); -const BENEFIT_VALID_MESSAGE_FIRST: Rep = Rep::BenefitMinorFirst("Valid message with new information"); +const COST_PEER_DUPLICATE_MESSAGE: Rep = + Rep::CostMinorRepeated("Peer sent the same message multiple times"); +const BENEFIT_VALID_MESSAGE_FIRST: Rep = + Rep::BenefitMinorFirst("Valid message with new information"); const BENEFIT_VALID_MESSAGE: Rep = Rep::BenefitMinor("Valid message"); /// Checked signed availability bitfield that is distributed @@ -62,14 +64,10 @@ struct BitfieldGossipMessage { impl BitfieldGossipMessage { fn into_validation_protocol(self) -> protocol_v1::ValidationProtocol { - protocol_v1::ValidationProtocol::BitfieldDistribution( - self.into_network_message() - ) + protocol_v1::ValidationProtocol::BitfieldDistribution(self.into_network_message()) } - fn into_network_message(self) - -> protocol_v1::BitfieldDistributionMessage - { + fn into_network_message(self) -> protocol_v1::BitfieldDistributionMessage { protocol_v1::BitfieldDistributionMessage::Bitfield( self.relay_parent, self.signed_availability.into(), @@ -124,7 +122,11 @@ struct PerRelayParentData { impl PerRelayParentData { /// Create a new instance. - fn new(signing_context: SigningContext, validator_set: Vec, span: PerLeafSpan) -> Self { + fn new( + signing_context: SigningContext, + validator_set: Vec, + span: PerLeafSpan, + ) -> Self { Self { signing_context, validator_set, @@ -141,8 +143,14 @@ impl PerRelayParentData { peer: &PeerId, validator: &ValidatorId, ) -> bool { - self.message_sent_to_peer.get(peer).map(|v| !v.contains(validator)).unwrap_or(true) - && self.message_received_from_peer.get(peer).map(|v| !v.contains(validator)).unwrap_or(true) + self.message_sent_to_peer + .get(peer) + .map(|v| !v.contains(validator)) + .unwrap_or(true) && + self.message_received_from_peer + .get(peer) + .map(|v| !v.contains(validator)) + .unwrap_or(true) } } @@ -172,34 +180,34 @@ impl BitfieldDistribution { Ok(message) => message, Err(e) => { tracing::debug!(target: LOG_TARGET, err = ?e, "Failed to receive a message from Overseer, exiting"); - return; + return }, }; match message { FromOverseer::Communication { msg: BitfieldDistributionMessage::DistributeBitfield(hash, signed_availability), } => { - tracing::trace!( - target: LOG_TARGET, - ?hash, - "Processing DistributeBitfield" - ); + tracing::trace!(target: LOG_TARGET, ?hash, "Processing DistributeBitfield"); handle_bitfield_distribution( &mut ctx, &mut state, &self.metrics, hash, signed_availability, - ).await; - } + ) + .await; + }, FromOverseer::Communication { msg: BitfieldDistributionMessage::NetworkBridgeUpdateV1(event), } => { tracing::trace!(target: LOG_TARGET, "Processing NetworkMessage"); // a network message was received handle_network_msg(&mut ctx, &mut state, &self.metrics, event).await; - } - FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { activated, .. })) => { + }, + FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + .. + })) => { let _timer = self.metrics.time_active_leaves_update(); for activated in activated { @@ -221,41 +229,34 @@ impl BitfieldDistribution { relay_parent, PerRelayParentData::new(signing_context, validator_set, span), ); - } + }, Err(e) => { tracing::warn!(target: LOG_TARGET, err = ?e, "query_basics has failed"); - } + }, _ => {}, } } - } + }, FromOverseer::Signal(OverseerSignal::BlockFinalized(hash, number)) => { tracing::trace!(target: LOG_TARGET, hash = %hash, number = %number, "block finalized"); - } + }, FromOverseer::Signal(OverseerSignal::Conclude) => { tracing::trace!(target: LOG_TARGET, "Conclude"); - return; - } + return + }, } } } } /// Modify the reputation of a peer based on its behavior. -async fn modify_reputation( - ctx: &mut Context, - peer: PeerId, - rep: Rep, -) +async fn modify_reputation(ctx: &mut Context, peer: PeerId, rep: Rep) where Context: SubsystemContext, { tracing::trace!(target: LOG_TARGET, ?rep, peer_id = %peer, "reputation change"); - ctx.send_message( - NetworkBridgeMessage::ReportPeer(peer, rep), - ) - .await + ctx.send_message(NetworkBridgeMessage::ReportPeer(peer, rep)).await } /// Distribute a given valid and signature checked bitfield message. @@ -267,8 +268,7 @@ async fn handle_bitfield_distribution( metrics: &Metrics, relay_parent: Hash, signed_availability: SignedAvailabilityBitfield, -) -where +) where Context: SubsystemContext, { let _timer = metrics.time_handle_bitfield_distribution(); @@ -284,26 +284,27 @@ where "Not supposed to work on relay parent related data", ); - return; + return }; let validator_set = &job_data.validator_set; if validator_set.is_empty() { tracing::trace!(target: LOG_TARGET, relay_parent = %relay_parent, "validator set is empty"); - return; + return } let validator_index = signed_availability.validator_index().0 as usize; let validator = if let Some(validator) = validator_set.get(validator_index) { validator.clone() } else { - tracing::trace!(target: LOG_TARGET, "Could not find a validator for index {}", validator_index); - return; + tracing::trace!( + target: LOG_TARGET, + "Could not find a validator for index {}", + validator_index + ); + return }; - let msg = BitfieldGossipMessage { - relay_parent, - signed_availability, - }; + let msg = BitfieldGossipMessage { relay_parent, signed_availability }; let gossip_peers = &state.gossip_peers; let peer_views = &mut state.peer_views; @@ -322,23 +323,17 @@ async fn relay_message( peer_views: &mut HashMap, validator: ValidatorId, message: BitfieldGossipMessage, -) -where +) where Context: SubsystemContext, { let span = job_data.span.child("relay-msg"); let _span = span.child("provisionable"); // notify the overseer about a new and valid signed bitfield - ctx.send_message( - ProvisionerMessage::ProvisionableData( - message.relay_parent, - ProvisionableData::Bitfield( - message.relay_parent, - message.signed_availability.clone(), - ), - ), - ) + ctx.send_message(ProvisionerMessage::ProvisionableData( + message.relay_parent, + ProvisionableData::Bitfield(message.relay_parent, message.signed_availability.clone()), + )) .await; drop(_span); @@ -350,7 +345,8 @@ where .filter_map(|(peer, view)| { // check interest in the peer in this message's relay parent if view.contains(&message.relay_parent) { - let message_needed = job_data.message_from_validator_needed_by_peer(&peer, &validator); + let message_needed = + job_data.message_from_validator_needed_by_peer(&peer, &validator); if message_needed { Some(peer.clone()) } else { @@ -366,14 +362,14 @@ where interested_peers, MIN_GOSSIP_PEERS, ); - interested_peers.iter() - .for_each(|peer|{ - // track the message as sent for this peer - job_data.message_sent_to_peer - .entry(peer.clone()) - .or_default() - .insert(validator.clone()); - }); + interested_peers.iter().for_each(|peer| { + // track the message as sent for this peer + job_data + .message_sent_to_peer + .entry(peer.clone()) + .or_default() + .insert(validator.clone()); + }); drop(_span); @@ -385,12 +381,10 @@ where ); } else { let _span = span.child("gossip"); - ctx.send_message( - NetworkBridgeMessage::SendValidationMessage( - interested_peers, - message.into_validation_protocol(), - ), - ) + ctx.send_message(NetworkBridgeMessage::SendValidationMessage( + interested_peers, + message.into_validation_protocol(), + )) .await; } } @@ -402,8 +396,7 @@ async fn process_incoming_peer_message( metrics: &Metrics, origin: PeerId, message: protocol_v1::BitfieldDistributionMessage, -) -where +) where Context: SubsystemContext, { let protocol_v1::BitfieldDistributionMessage::Bitfield(relay_parent, bitfield) = message; @@ -416,7 +409,7 @@ where // we don't care about this, not part of our view. if !state.view.contains(&relay_parent) { modify_reputation(ctx, origin, COST_NOT_IN_VIEW).await; - return; + return } // Ignore anything the overseer did not tell this subsystem to work on. @@ -425,16 +418,17 @@ where job_data } else { modify_reputation(ctx, origin, COST_NOT_IN_VIEW).await; - return; + return }; let validator_index = bitfield.unchecked_validator_index(); - let mut _span = job_data.span - .child("msg-received") - .with_peer_id(&origin) - .with_claimed_validator_index(validator_index) - .with_stage(jaeger::Stage::BitfieldDistribution); + let mut _span = job_data + .span + .child("msg-received") + .with_peer_id(&origin) + .with_claimed_validator_index(validator_index) + .with_stage(jaeger::Stage::BitfieldDistribution); let validator_set = &job_data.validator_set; if validator_set.is_empty() { @@ -445,7 +439,7 @@ where "Validator set is empty", ); modify_reputation(ctx, origin, COST_MISSING_PEER_SESSION_KEY).await; - return; + return } // Use the (untrusted) validator index provided by the signed payload @@ -455,28 +449,20 @@ where validator.clone() } else { modify_reputation(ctx, origin, COST_VALIDATOR_INDEX_INVALID).await; - return; + return }; // Check if the peer already sent us a message for the validator denoted in the message earlier. // Must be done after validator index verification, in order to avoid storing an unbounded // number of set entries. - let received_set = job_data - .message_received_from_peer - .entry(origin.clone()) - .or_default(); + let received_set = job_data.message_received_from_peer.entry(origin.clone()).or_default(); if !received_set.contains(&validator) { received_set.insert(validator.clone()); } else { - tracing::trace!( - target: LOG_TARGET, - ?validator_index, - ?origin, - "Duplicate message", - ); + tracing::trace!(target: LOG_TARGET, ?validator_index, ?origin, "Duplicate message",); modify_reputation(ctx, origin, COST_PEER_DUPLICATE_MESSAGE).await; - return; + return }; let one_per_validator = &mut (job_data.one_per_validator); @@ -491,25 +477,23 @@ where if old_message.signed_availability.as_unchecked() == &bitfield { modify_reputation(ctx, origin, BENEFIT_VALID_MESSAGE).await; } - return; + return } let signed_availability = match bitfield.try_into_checked(&signing_context, &validator) { Err(_) => { modify_reputation(ctx, origin, COST_SIGNATURE_INVALID).await; - return; + return }, Ok(bitfield) => bitfield, }; - let message = BitfieldGossipMessage { - relay_parent, - signed_availability, - }; + let message = BitfieldGossipMessage { relay_parent, signed_availability }; metrics.on_bitfield_received(); one_per_validator.insert(validator.clone(), message.clone()); - relay_message(ctx, job_data, &state.gossip_peers, &mut state.peer_views, validator, message).await; + relay_message(ctx, job_data, &state.gossip_peers, &mut state.peer_views, validator, message) + .await; modify_reputation(ctx, origin, BENEFIT_VALID_MESSAGE_FIRST).await } @@ -521,32 +505,22 @@ async fn handle_network_msg( state: &mut ProtocolState, metrics: &Metrics, bridge_message: NetworkBridgeEvent, -) -where +) where Context: SubsystemContext, { let _timer = metrics.time_handle_network_msg(); match bridge_message { NetworkBridgeEvent::PeerConnected(peerid, role, _) => { - tracing::trace!( - target: LOG_TARGET, - ?peerid, - ?role, - "Peer connected", - ); + tracing::trace!(target: LOG_TARGET, ?peerid, ?role, "Peer connected",); // insert if none already present state.peer_views.entry(peerid).or_default(); - } + }, NetworkBridgeEvent::PeerDisconnected(peerid) => { - tracing::trace!( - target: LOG_TARGET, - ?peerid, - "Peer disconnected", - ); + tracing::trace!(target: LOG_TARGET, ?peerid, "Peer disconnected",); // get rid of superfluous data state.peer_views.remove(&peerid); - } + }, NetworkBridgeEvent::NewGossipTopology(peers) => { let newly_added: Vec = peers.difference(&state.gossip_peers).cloned().collect(); state.gossip_peers = peers; @@ -555,24 +529,15 @@ where handle_peer_view_change(ctx, state, peer, view).await; } } - } + }, NetworkBridgeEvent::PeerViewChange(peerid, view) => { - tracing::trace!( - target: LOG_TARGET, - ?peerid, - ?view, - "Peer view change", - ); + tracing::trace!(target: LOG_TARGET, ?peerid, ?view, "Peer view change",); handle_peer_view_change(ctx, state, peerid, view).await; - } + }, NetworkBridgeEvent::OurViewChange(view) => { - tracing::trace!( - target: LOG_TARGET, - ?view, - "Our view change", - ); + tracing::trace!(target: LOG_TARGET, ?view, "Our view change",); handle_our_view_change(state, view); - } + }, NetworkBridgeEvent::PeerMessage(remote, message) => process_incoming_peer_message(ctx, state, metrics, remote, message).await, } @@ -598,7 +563,6 @@ fn handle_our_view_change(state: &mut ProtocolState, view: OurView) { } } - // Send the difference between two views which were not sent // to that particular peer. async fn handle_peer_view_change( @@ -606,25 +570,27 @@ async fn handle_peer_view_change( state: &mut ProtocolState, origin: PeerId, view: View, -) -where +) where Context: SubsystemContext, { - let added = state.peer_views.entry(origin.clone()).or_default().replace_difference(view).cloned().collect::>(); + let added = state + .peer_views + .entry(origin.clone()) + .or_default() + .replace_difference(view) + .cloned() + .collect::>(); let is_gossip_peer = state.gossip_peers.contains(&origin); - let lucky = is_gossip_peer || util::gen_ratio( - util::MIN_GOSSIP_PEERS.saturating_sub(state.gossip_peers.len()), - util::MIN_GOSSIP_PEERS, - ); + let lucky = is_gossip_peer || + util::gen_ratio( + util::MIN_GOSSIP_PEERS.saturating_sub(state.gossip_peers.len()), + util::MIN_GOSSIP_PEERS, + ); if !lucky { - tracing::trace!( - target: LOG_TARGET, - ?origin, - "Peer view change is ignored", - ); - return; + tracing::trace!(target: LOG_TARGET, ?origin, "Peer view change is ignored",); + return } // Send all messages we've seen before and the peer is now interested @@ -637,14 +603,10 @@ where // to the peer `origin`... let one_per_validator = job_data.one_per_validator.clone(); let origin = origin.clone(); - Some( - one_per_validator - .into_iter() - .filter(move |(validator, _message)| { - // ..except for the ones the peer already has. - job_data.message_from_validator_needed_by_peer(&origin, validator) - }), - ) + Some(one_per_validator.into_iter().filter(move |(validator, _message)| { + // ..except for the ones the peer already has. + job_data.message_from_validator_needed_by_peer(&origin, validator) + })) } else { // A relay parent is in the peers view, which is not in ours, ignore those. None @@ -665,14 +627,13 @@ async fn send_tracked_gossip_message( dest: PeerId, validator: ValidatorId, message: BitfieldGossipMessage, -) -where +) where Context: SubsystemContext, { let job_data = if let Some(job_data) = state.per_relay_parent.get_mut(&message.relay_parent) { job_data } else { - return; + return }; let _span = job_data.span.child("gossip"); @@ -684,17 +645,17 @@ where "Sending gossip message" ); - job_data.message_sent_to_peer + job_data + .message_sent_to_peer .entry(dest.clone()) .or_default() .insert(validator.clone()); - ctx.send_message( - NetworkBridgeMessage::SendValidationMessage( - vec![dest], - message.into_validation_protocol(), - ), - ).await; + ctx.send_message(NetworkBridgeMessage::SendValidationMessage( + vec![dest], + message.into_validation_protocol(), + )) + .await; } impl overseer::Subsystem for BitfieldDistribution @@ -703,14 +664,9 @@ where Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { - let future = self.run(ctx) - .map(|_| Ok(())) - .boxed(); + let future = self.run(ctx).map(|_| Ok(())).boxed(); - SpawnedSubsystem { - name: "bitfield-distribution-subsystem", - future, - } + SpawnedSubsystem { name: "bitfield-distribution-subsystem", future } } } @@ -729,23 +685,23 @@ where ctx.send_message(RuntimeApiMessage::Request( relay_parent.clone(), RuntimeApiRequest::Validators(validators_tx), - )).await; + )) + .await; // query signing context ctx.send_message(RuntimeApiMessage::Request( relay_parent.clone(), RuntimeApiRequest::SessionIndexForChild(session_tx), - )).await; + )) + .await; match (validators_rx.await?, session_rx.await?) { - (Ok(v), Ok(s)) => Ok(Some(( - v, - SigningContext { parent_hash: relay_parent, session_index: s }, - ))), + (Ok(v), Ok(s)) => + Ok(Some((v, SigningContext { parent_hash: relay_parent, session_index: s }))), (Err(e), _) | (_, Err(e)) => { tracing::warn!(target: LOG_TARGET, err = ?e, "Failed to fetch basics from runtime API"); Ok(None) - } + }, } } @@ -781,8 +737,12 @@ impl Metrics { } /// Provide a timer for `handle_bitfield_distribution` which observes on drop. - fn time_handle_bitfield_distribution(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.handle_bitfield_distribution.start_timer()) + fn time_handle_bitfield_distribution( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.handle_bitfield_distribution.start_timer()) } /// Provide a timer for `handle_network_msg` which observes on drop. @@ -797,42 +757,36 @@ impl metrics::Metrics for Metrics { gossipped_own_availability_bitfields: prometheus::register( prometheus::Counter::new( "parachain_gossipped_own_availabilty_bitfields_total", - "Number of own availability bitfields sent to other peers." + "Number of own availability bitfields sent to other peers.", )?, registry, )?, received_availability_bitfields: prometheus::register( prometheus::Counter::new( "parachain_received_availabilty_bitfields_total", - "Number of valid availability bitfields received from other peers." + "Number of valid availability bitfields received from other peers.", )?, registry, )?, active_leaves_update: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_bitfield_distribution_active_leaves_update", - "Time spent within `bitfield_distribution::active_leaves_update`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_bitfield_distribution_active_leaves_update", + "Time spent within `bitfield_distribution::active_leaves_update`", + ))?, registry, )?, handle_bitfield_distribution: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_bitfield_distribution_handle_bitfield_distribution", - "Time spent within `bitfield_distribution::handle_bitfield_distribution`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_bitfield_distribution_handle_bitfield_distribution", + "Time spent within `bitfield_distribution::handle_bitfield_distribution`", + ))?, registry, )?, handle_network_msg: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_bitfield_distribution_handle_network_msg", - "Time spent within `bitfield_distribution::handle_network_msg`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_bitfield_distribution_handle_network_msg", + "Time spent within `bitfield_distribution::handle_network_msg`", + ))?, registry, )?, }; diff --git a/polkadot/node/network/bitfield-distribution/src/tests.rs b/polkadot/node/network/bitfield-distribution/src/tests.rs index de2da9316b9..94b200a4a85 100644 --- a/polkadot/node/network/bitfield-distribution/src/tests.rs +++ b/polkadot/node/network/bitfield-distribution/src/tests.rs @@ -15,28 +15,24 @@ // along with Polkadot. If not, see . use super::*; +use assert_matches::assert_matches; use bitvec::bitvec; use futures::executor; use maplit::hashmap; -use polkadot_primitives::v1::{Signed, AvailabilityBitfield, ValidatorIndex}; +use polkadot_node_network_protocol::{our_view, view, ObservedRole}; use polkadot_node_subsystem_test_helpers::make_subsystem_context; use polkadot_node_subsystem_util::TimeoutExt; -use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; -use sp_application_crypto::AppKey; -use sp_keystore::testing::KeyStore; -use std::sync::Arc; -use std::time::Duration; -use std::iter::FromIterator as _; -use assert_matches::assert_matches; -use polkadot_node_network_protocol::{view, ObservedRole, our_view}; +use polkadot_primitives::v1::{AvailabilityBitfield, Signed, ValidatorIndex}; use polkadot_subsystem::jaeger; +use sp_application_crypto::AppKey; +use sp_keystore::{testing::KeyStore, SyncCryptoStore, SyncCryptoStorePtr}; +use std::{iter::FromIterator as _, sync::Arc, time::Duration}; macro_rules! launch { ($fut:expr) => { - $fut - .timeout(Duration::from_millis(10)) - .await - .expect("10ms is more than enough for sending messages.") + $fut.timeout(Duration::from_millis(10)) + .await + .expect("10ms is more than enough for sending messages.") }; } @@ -64,11 +60,7 @@ fn prewarmed_state( span: PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"), }, }, - peer_views: peers - .iter() - .cloned() - .map(|peer| (peer, view!(relay_parent))) - .collect(), + peer_views: peers.iter().cloned().map(|peer| (peer, view!(relay_parent))).collect(), gossip_peers: peers.into_iter().collect(), view: our_view!(relay_parent), } @@ -80,26 +72,28 @@ fn state_with_view( ) -> (ProtocolState, SigningContext, SyncCryptoStorePtr, ValidatorId) { let mut state = ProtocolState::default(); - let signing_context = SigningContext { - session_index: 1, - parent_hash: relay_parent.clone(), - }; + let signing_context = SigningContext { session_index: 1, parent_hash: relay_parent.clone() }; - let keystore : SyncCryptoStorePtr = Arc::new(KeyStore::new()); + let keystore: SyncCryptoStorePtr = Arc::new(KeyStore::new()); let validator = SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, None) .expect("generating sr25519 key not to fail"); - state.per_relay_parent = view.iter().map(|relay_parent| {( - relay_parent.clone(), - PerRelayParentData { - signing_context: signing_context.clone(), - validator_set: vec![validator.clone().into()], - one_per_validator: hashmap!{}, - message_received_from_peer: hashmap!{}, - message_sent_to_peer: hashmap!{}, - span: PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"), - }) - }).collect(); + state.per_relay_parent = view + .iter() + .map(|relay_parent| { + ( + relay_parent.clone(), + PerRelayParentData { + signing_context: signing_context.clone(), + validator_set: vec![validator.clone().into()], + one_per_validator: hashmap! {}, + message_received_from_peer: hashmap! {}, + message_sent_to_peer: hashmap! {}, + span: PerLeafSpan::new(Arc::new(jaeger::Span::Disabled), "test"), + }, + ) + }) + .collect(); state.view = view; @@ -119,13 +113,10 @@ fn receive_invalid_signature() { let peer_b = PeerId::random(); assert_ne!(peer_a, peer_b); - let signing_context = SigningContext { - session_index: 1, - parent_hash: hash_a.clone(), - }; + let signing_context = SigningContext { session_index: 1, parent_hash: hash_a.clone() }; // another validator not part of the validatorset - let keystore : SyncCryptoStorePtr = Arc::new(KeyStore::new()); + let keystore: SyncCryptoStorePtr = Arc::new(KeyStore::new()); let malicious = SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, None) .expect("Malicious key created"); let validator_0 = SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, None) @@ -140,14 +131,20 @@ fn receive_invalid_signature() { &signing_context, ValidatorIndex(0), &malicious.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); let invalid_signed_2 = executor::block_on(Signed::::sign( &keystore, payload.clone(), &signing_context, ValidatorIndex(1), &malicious.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); let valid_signed = executor::block_on(Signed::::sign( &keystore, @@ -155,7 +152,10 @@ fn receive_invalid_signature() { &signing_context, ValidatorIndex(0), &validator_0.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); let invalid_msg = BitfieldGossipMessage { relay_parent: hash_a.clone(), @@ -171,8 +171,7 @@ fn receive_invalid_signature() { }; let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - make_subsystem_context::(pool); + let (mut ctx, mut handle) = make_subsystem_context::(pool); let mut state = prewarmed_state( validator_0.into(), @@ -180,7 +179,9 @@ fn receive_invalid_signature() { valid_msg, vec![peer_b.clone()], ); - state.per_relay_parent.get_mut(&hash_a) + state + .per_relay_parent + .get_mut(&hash_a) .unwrap() .validator_set .push(validator_1.into()); @@ -230,7 +231,8 @@ fn receive_invalid_validator_index() { assert_ne!(peer_a, peer_b); // validator 0 key pair - let (mut state, signing_context, keystore, validator) = state_with_view(our_view![hash_a, hash_b], hash_a.clone()); + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a.clone()); state.peer_views.insert(peer_b.clone(), view![hash_a]); @@ -241,16 +243,16 @@ fn receive_invalid_validator_index() { &signing_context, ValidatorIndex(42), &validator, - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); - let msg = BitfieldGossipMessage { - relay_parent: hash_a.clone(), - signed_availability: signed.clone(), - }; + let msg = + BitfieldGossipMessage { relay_parent: hash_a.clone(), signed_availability: signed.clone() }; let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - make_subsystem_context::(pool); + let (mut ctx, mut handle) = make_subsystem_context::(pool); executor::block_on(async move { launch!(handle_network_msg( @@ -288,7 +290,8 @@ fn receive_duplicate_messages() { assert_ne!(peer_a, peer_b); // validator 0 key pair - let (mut state, signing_context, keystore, validator) = state_with_view(our_view![hash_a, hash_b], hash_a.clone()); + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a.clone()); // create a signed message by validator 0 let payload = AvailabilityBitfield(bitvec![bitvec::order::Lsb0, u8; 1u8; 32]); @@ -298,7 +301,10 @@ fn receive_duplicate_messages() { &signing_context, ValidatorIndex(0), &validator, - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); let msg = BitfieldGossipMessage { relay_parent: hash_a.clone(), @@ -306,8 +312,7 @@ fn receive_duplicate_messages() { }; let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - make_subsystem_context::(pool); + let (mut ctx, mut handle) = make_subsystem_context::(pool); executor::block_on(async move { // send a first message @@ -315,10 +320,7 @@ fn receive_duplicate_messages() { &mut ctx, &mut state, &Default::default(), - NetworkBridgeEvent::PeerMessage( - peer_b.clone(), - msg.clone().into_network_message(), - ), + NetworkBridgeEvent::PeerMessage(peer_b.clone(), msg.clone().into_network_message(),), )); // none of our peers has any interest in any messages @@ -350,10 +352,7 @@ fn receive_duplicate_messages() { &mut ctx, &mut state, &Default::default(), - NetworkBridgeEvent::PeerMessage( - peer_a.clone(), - msg.clone().into_network_message(), - ), + NetworkBridgeEvent::PeerMessage(peer_a.clone(), msg.clone().into_network_message(),), )); assert_matches!( @@ -371,10 +370,7 @@ fn receive_duplicate_messages() { &mut ctx, &mut state, &Default::default(), - NetworkBridgeEvent::PeerMessage( - peer_b.clone(), - msg.clone().into_network_message(), - ), + NetworkBridgeEvent::PeerMessage(peer_b.clone(), msg.clone().into_network_message(),), )); assert_matches!( @@ -403,7 +399,8 @@ fn do_not_relay_message_twice() { assert_ne!(peer_a, peer_b); // validator 0 key pair - let (mut state, signing_context, keystore, validator) = state_with_view(our_view![hash], hash.clone()); + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash], hash.clone()); // create a signed message by validator 0 let payload = AvailabilityBitfield(bitvec![bitvec::order::Lsb0, u8; 1u8; 32]); @@ -413,7 +410,10 @@ fn do_not_relay_message_twice() { &signing_context, ValidatorIndex(0), &validator, - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); state.peer_views.insert(peer_b.clone(), view![hash]); state.peer_views.insert(peer_a.clone(), view![hash]); @@ -424,13 +424,10 @@ fn do_not_relay_message_twice() { }; let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - make_subsystem_context::(pool); + let (mut ctx, mut handle) = make_subsystem_context::(pool); executor::block_on(async move { - let gossip_peers = HashSet::from_iter(vec![ - peer_a.clone(), peer_b.clone(), - ].into_iter()); + let gossip_peers = HashSet::from_iter(vec![peer_a.clone(), peer_b.clone()].into_iter()); relay_message( &mut ctx, state.per_relay_parent.get_mut(&hash).unwrap(), @@ -438,7 +435,8 @@ fn do_not_relay_message_twice() { &mut state.peer_views, validator.clone(), msg.clone(), - ).await; + ) + .await; assert_matches!( handle.recv().await, @@ -471,7 +469,8 @@ fn do_not_relay_message_twice() { &mut state.peer_views, validator.clone(), msg.clone(), - ).await; + ) + .await; assert_matches!( handle.recv().await, @@ -504,7 +503,8 @@ fn changing_view() { assert_ne!(peer_a, peer_b); // validator 0 key pair - let (mut state, signing_context, keystore, validator) = state_with_view(our_view![hash_a, hash_b], hash_a.clone()); + let (mut state, signing_context, keystore, validator) = + state_with_view(our_view![hash_a, hash_b], hash_a.clone()); // create a signed message by validator 0 let payload = AvailabilityBitfield(bitvec![bitvec::order::Lsb0, u8; 1u8; 32]); @@ -514,7 +514,10 @@ fn changing_view() { &signing_context, ValidatorIndex(0), &validator, - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); let msg = BitfieldGossipMessage { relay_parent: hash_a.clone(), @@ -522,8 +525,7 @@ fn changing_view() { }; let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - make_subsystem_context::(pool); + let (mut ctx, mut handle) = make_subsystem_context::(pool); executor::block_on(async move { launch!(handle_network_msg( @@ -548,10 +550,7 @@ fn changing_view() { &mut ctx, &mut state, &Default::default(), - NetworkBridgeEvent::PeerMessage( - peer_b.clone(), - msg.clone().into_network_message(), - ), + NetworkBridgeEvent::PeerMessage(peer_b.clone(), msg.clone().into_network_message(),), )); // gossip to the overseer @@ -585,10 +584,7 @@ fn changing_view() { )); assert!(state.peer_views.contains_key(&peer_b)); - assert_eq!( - state.peer_views.get(&peer_b).expect("Must contain value for peer B"), - &view![] - ); + assert_eq!(state.peer_views.get(&peer_b).expect("Must contain value for peer B"), &view![]); // on rx of the same message, since we are not interested, // should give penalty @@ -596,10 +592,7 @@ fn changing_view() { &mut ctx, &mut state, &Default::default(), - NetworkBridgeEvent::PeerMessage( - peer_b.clone(), - msg.clone().into_network_message(), - ), + NetworkBridgeEvent::PeerMessage(peer_b.clone(), msg.clone().into_network_message(),), )); // reputation change for peer B @@ -629,10 +622,7 @@ fn changing_view() { &mut ctx, &mut state, &Default::default(), - NetworkBridgeEvent::PeerMessage( - peer_a.clone(), - msg.clone().into_network_message(), - ), + NetworkBridgeEvent::PeerMessage(peer_a.clone(), msg.clone().into_network_message(),), )); // reputation change for peer B @@ -645,7 +635,6 @@ fn changing_view() { assert_eq!(rep, COST_NOT_IN_VIEW) } ); - }); } @@ -673,7 +662,10 @@ fn do_not_send_message_back_to_origin() { &signing_context, ValidatorIndex(0), &validator, - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); state.peer_views.insert(peer_b.clone(), view![hash]); state.peer_views.insert(peer_a.clone(), view![hash]); @@ -684,8 +676,7 @@ fn do_not_send_message_back_to_origin() { }; let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - make_subsystem_context::(pool); + let (mut ctx, mut handle) = make_subsystem_context::(pool); executor::block_on(async move { // send a first message @@ -693,10 +684,7 @@ fn do_not_send_message_back_to_origin() { &mut ctx, &mut state, &Default::default(), - NetworkBridgeEvent::PeerMessage( - peer_b.clone(), - msg.clone().into_network_message(), - ), + NetworkBridgeEvent::PeerMessage(peer_b.clone(), msg.clone().into_network_message(),), )); assert_matches!( diff --git a/polkadot/node/network/bridge/src/lib.rs b/polkadot/node/network/bridge/src/lib.rs index e5efcd6c502..a02b85076a7 100644 --- a/polkadot/node/network/bridge/src/lib.rs +++ b/polkadot/node/network/bridge/src/lib.rs @@ -19,48 +19,39 @@ #![deny(unused_crate_dependencies)] #![warn(missing_docs)] - -use parity_scale_codec::{Encode, Decode}; +use futures::{prelude::*, stream::BoxStream}; +use parity_scale_codec::{Decode, Encode}; use parking_lot::Mutex; -use futures::prelude::*; -use futures::stream::BoxStream; use polkadot_subsystem::messages::DisputeDistributionMessage; use sc_network::Event as NetworkEvent; use sp_consensus::SyncOracle; -use polkadot_overseer::gen::{ - Subsystem, - OverseerError, +use polkadot_node_network_protocol::{ + peer_set::PeerSet, v1 as protocol_v1, ObservedRole, OurView, PeerId, + UnifiedReputationChange as Rep, View, }; +use polkadot_node_subsystem_util::metrics::{self, prometheus}; +use polkadot_overseer::gen::{OverseerError, Subsystem}; +use polkadot_primitives::v1::{BlockNumber, Hash}; use polkadot_subsystem::{ - overseer, - OverseerSignal, - FromOverseer, - SpawnedSubsystem, - SubsystemContext, - SubsystemSender, errors::{SubsystemError, SubsystemResult}, - ActivatedLeaf, ActiveLeavesUpdate, messages::{ - AllMessages, StatementDistributionMessage, - NetworkBridgeMessage, CollatorProtocolMessage, NetworkBridgeEvent, + AllMessages, CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeMessage, + StatementDistributionMessage, }, + overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, + SubsystemContext, SubsystemSender, }; -use polkadot_primitives::v1::{Hash, BlockNumber}; -use polkadot_node_network_protocol::{ - PeerId, peer_set::PeerSet, View, v1 as protocol_v1, OurView, UnifiedReputationChange as Rep, - ObservedRole, -}; -use polkadot_node_subsystem_util::metrics::{self, prometheus}; /// Peer set info for network initialization. /// /// To be added to [`NetworkConfiguration::extra_sets`]. pub use polkadot_node_network_protocol::peer_set::{peer_sets_info, IsAuthority}; -use std::collections::HashSet; -use std::collections::{HashMap, hash_map}; -use std::sync::Arc; +use std::{ + collections::{hash_map, HashMap, HashSet}, + sync::Arc, +}; mod validator_discovery; @@ -68,7 +59,7 @@ mod validator_discovery; /// /// Defines the `Network` trait with an implementation for an `Arc`. mod network; -use network::{Network, send_message}; +use network::{send_message, Network}; /// Request multiplexer for combining the multiple request sources into a single `Stream` of `AllMessages`. mod multiplexer; @@ -84,7 +75,6 @@ mod tests; /// We use the same limit to compute the view sent to peers locally. const MAX_VIEW_HEADS: usize = 5; - const MALFORMED_MESSAGE_COST: Rep = Rep::CostMajor("Malformed Network-bridge message"); const UNCONNECTED_PEERSET_COST: Rep = Rep::CostMinor("Message sent to un-connected peer-set"); const MALFORMED_VIEW_COST: Rep = Rep::CostMajor("Malformed view"); @@ -99,36 +89,41 @@ pub struct Metrics(Option); impl Metrics { fn on_peer_connected(&self, peer_set: PeerSet) { - self.0.as_ref().map(|metrics| metrics - .connected_events - .with_label_values(&[peer_set.get_protocol_name_static()]) - .inc() - ); + self.0.as_ref().map(|metrics| { + metrics + .connected_events + .with_label_values(&[peer_set.get_protocol_name_static()]) + .inc() + }); } fn on_peer_disconnected(&self, peer_set: PeerSet) { - self.0.as_ref().map(|metrics| metrics - .disconnected_events - .with_label_values(&[peer_set.get_protocol_name_static()]) - .inc() - ); + self.0.as_ref().map(|metrics| { + metrics + .disconnected_events + .with_label_values(&[peer_set.get_protocol_name_static()]) + .inc() + }); } fn note_peer_count(&self, peer_set: PeerSet, count: usize) { - self.0.as_ref().map(|metrics| metrics - .peer_count - .with_label_values(&[peer_set.get_protocol_name_static()]) - .set(count as u64) - ); + self.0.as_ref().map(|metrics| { + metrics + .peer_count + .with_label_values(&[peer_set.get_protocol_name_static()]) + .set(count as u64) + }); } fn on_notification_received(&self, peer_set: PeerSet, size: usize) { if let Some(metrics) = self.0.as_ref() { - metrics.notifications_received + metrics + .notifications_received .with_label_values(&[peer_set.get_protocol_name_static()]) .inc(); - metrics.bytes_received + metrics + .bytes_received .with_label_values(&[peer_set.get_protocol_name_static()]) .inc_by(size as u64); } @@ -136,22 +131,25 @@ impl Metrics { fn on_notification_sent(&self, peer_set: PeerSet, size: usize, to_peers: usize) { if let Some(metrics) = self.0.as_ref() { - metrics.notifications_sent + metrics + .notifications_sent .with_label_values(&[peer_set.get_protocol_name_static()]) .inc_by(to_peers as u64); - metrics.bytes_sent + metrics + .bytes_sent .with_label_values(&[peer_set.get_protocol_name_static()]) .inc_by((size * to_peers) as u64); } } fn note_desired_peer_count(&self, peer_set: PeerSet, size: usize) { - self.0.as_ref().map(|metrics| metrics - .desired_peer_count - .with_label_values(&[peer_set.get_protocol_name_static()]) - .set(size as u64) - ); + self.0.as_ref().map(|metrics| { + metrics + .desired_peer_count + .with_label_values(&[peer_set.get_protocol_name_static()]) + .set(size as u64) + }); } } @@ -170,9 +168,9 @@ struct MetricsInner { } impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) - -> std::result::Result - { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { let metrics = MetricsInner { peer_count: prometheus::register( prometheus::GaugeVec::new( @@ -306,10 +304,11 @@ impl NetworkBridge { } impl Subsystem for NetworkBridge - where - Net: Network + Sync, - AD: validator_discovery::AuthorityDiscovery + Clone, - Context: SubsystemContext + overseer::SubsystemContext, +where + Net: Network + Sync, + AD: validator_discovery::AuthorityDiscovery + Clone, + Context: SubsystemContext + + overseer::SubsystemContext, { fn start(mut self, ctx: Context) -> SpawnedSubsystem { // The stream of networking events has to be created at initialization, otherwise the @@ -319,14 +318,9 @@ impl Subsystem for NetworkBridge( where N: Network, AD: validator_discovery::AuthorityDiscovery + Clone, - Context: SubsystemContext + overseer::SubsystemContext, + Context: SubsystemContext + + overseer::SubsystemContext, { let shared = Shared::default(); @@ -902,7 +897,7 @@ where .get_dispute_sending() .expect("Gets initialized, must be `Some` on startup. qed."); - let (remote, network_event_handler) = handle_network_messages::<>( + let (remote, network_event_handler) = handle_network_messages( ctx.sender().clone(), network_service.clone(), network_stream, @@ -910,16 +905,15 @@ where request_multiplexer, metrics.clone(), shared.clone(), - ).remote_handle(); + ) + .remote_handle(); ctx.spawn("network-bridge-network-worker", Box::pin(remote))?; - ctx.send_message( - DisputeDistributionMessage::DisputeSendingReceiver(dispute_receiver) - ).await; - ctx.send_message( - StatementDistributionMessage::StatementFetchingReceiver(statement_receiver) - ).await; + ctx.send_message(DisputeDistributionMessage::DisputeSendingReceiver(dispute_receiver)) + .await; + ctx.send_message(StatementDistributionMessage::StatementFetchingReceiver(statement_receiver)) + .await; let subsystem_event_handler = handle_subsystem_messages( ctx, @@ -949,38 +943,34 @@ where "Received SubsystemError from overseer: {:?}", err ))) - } + }, Err(UnexpectedAbort::EventStreamConcluded) => { tracing::info!( target: LOG_TARGET, "Shutting down Network Bridge: underlying request stream concluded" ); - Err(SubsystemError::Context( - "Incoming network event stream concluded.".to_string(), - )) - } + Err(SubsystemError::Context("Incoming network event stream concluded.".to_string())) + }, Err(UnexpectedAbort::RequestStreamConcluded) => { tracing::info!( target: LOG_TARGET, "Shutting down Network Bridge: underlying request stream concluded" ); - Err(SubsystemError::Context( - "Incoming network request stream concluded".to_string(), - )) - } + Err(SubsystemError::Context("Incoming network request stream concluded".to_string())) + }, } } -fn construct_view(live_heads: impl DoubleEndedIterator, finalized_number: BlockNumber) -> View { - View::new( - live_heads.take(MAX_VIEW_HEADS), - finalized_number, - ) +fn construct_view( + live_heads: impl DoubleEndedIterator, + finalized_number: BlockNumber, +) -> View { + View::new(live_heads.take(MAX_VIEW_HEADS), finalized_number) } fn update_our_view( net: &mut impl Network, - ctx: &mut impl SubsystemContext, + ctx: &mut impl SubsystemContext, live_heads: &[ActivatedLeaf], shared: &Shared, finalized_number: BlockNumber, @@ -997,17 +987,14 @@ fn update_our_view( // If this is the first view update since becoming active, but our view is empty, // there is no need to send anything. match shared.local_view { - Some(ref v) if v.check_heads_eq(&new_view) => { - return; - } + Some(ref v) if v.check_heads_eq(&new_view) => return, None if live_heads.is_empty() => { shared.local_view = Some(new_view); - return; - } + return + }, _ => { shared.local_view = Some(new_view.clone()); - } - + }, } ( @@ -1023,12 +1010,7 @@ fn update_our_view( metrics, ); - send_collation_message( - net, - collation_peers, - WireMessage::ViewUpdate(new_view), - metrics, - ); + send_collation_message(net, collation_peers, WireMessage::ViewUpdate(new_view), metrics); let our_view = OurView::new( live_heads.iter().take(MAX_VIEW_HEADS).cloned().map(|a| (a.hash, a.span)), @@ -1056,9 +1038,7 @@ fn handle_peer_messages( metrics: &Metrics, ) -> (Vec>, Vec) { let peer_data = match peers.get_mut(&peer) { - None => { - return (Vec::new(), vec![UNCONNECTED_PEERSET_COST]); - }, + None => return (Vec::new(), vec![UNCONNECTED_PEERSET_COST]), Some(d) => d, }; @@ -1083,15 +1063,11 @@ fn handle_peer_messages( } else { peer_data.view = new_view; - NetworkBridgeEvent::PeerViewChange( - peer.clone(), - peer_data.view.clone(), - ) + NetworkBridgeEvent::PeerViewChange(peer.clone(), peer_data.view.clone()) } - } - WireMessage::ProtocolMessage(message) => { - NetworkBridgeEvent::PeerMessage(peer.clone(), message) - } + }, + WireMessage::ProtocolMessage(message) => + NetworkBridgeEvent::PeerMessage(peer.clone(), message), }) } @@ -1116,24 +1092,23 @@ fn send_collation_message( send_message(net, peers, PeerSet::Collation, message, metrics) } - async fn dispatch_validation_event_to_all( event: NetworkBridgeEvent, - ctx: &mut impl SubsystemSender + ctx: &mut impl SubsystemSender, ) { dispatch_validation_events_to_all(std::iter::once(event), ctx).await } async fn dispatch_collation_event_to_all( event: NetworkBridgeEvent, - ctx: &mut impl SubsystemSender + ctx: &mut impl SubsystemSender, ) { dispatch_collation_events_to_all(std::iter::once(event), ctx).await } fn dispatch_validation_event_to_all_unbounded( event: NetworkBridgeEvent, - ctx: &mut impl SubsystemSender + ctx: &mut impl SubsystemSender, ) { for msg in AllMessages::dispatch_iter(event) { ctx.send_unbounded_message(msg); @@ -1142,36 +1117,30 @@ fn dispatch_validation_event_to_all_unbounded( fn dispatch_collation_event_to_all_unbounded( event: NetworkBridgeEvent, - ctx: &mut impl SubsystemSender + ctx: &mut impl SubsystemSender, ) { if let Some(msg) = event.focus().ok().map(CollatorProtocolMessage::NetworkBridgeUpdateV1) { ctx.send_unbounded_message(msg.into()); } } -async fn dispatch_validation_events_to_all( - events: I, - ctx: &mut impl SubsystemSender -) - where - I: IntoIterator>, - I::IntoIter: Send, +async fn dispatch_validation_events_to_all(events: I, ctx: &mut impl SubsystemSender) +where + I: IntoIterator>, + I::IntoIter: Send, { ctx.send_messages(events.into_iter().flat_map(AllMessages::dispatch_iter)).await } -async fn dispatch_collation_events_to_all( - events: I, - ctx: &mut impl SubsystemSender -) - where - I: IntoIterator>, - I::IntoIter: Send, +async fn dispatch_collation_events_to_all(events: I, ctx: &mut impl SubsystemSender) +where + I: IntoIterator>, + I::IntoIter: Send, { let messages_for = |event: NetworkBridgeEvent| { - event.focus().ok().map(|m| AllMessages::CollatorProtocol( - CollatorProtocolMessage::NetworkBridgeUpdateV1(m) - )) + event.focus().ok().map(|m| { + AllMessages::CollatorProtocol(CollatorProtocolMessage::NetworkBridgeUpdateV1(m)) + }) }; ctx.send_messages(events.into_iter().flat_map(messages_for)).await diff --git a/polkadot/node/network/bridge/src/multiplexer.rs b/polkadot/node/network/bridge/src/multiplexer.rs index ca8102bdec0..0d8c8b63595 100644 --- a/polkadot/node/network/bridge/src/multiplexer.rs +++ b/polkadot/node/network/bridge/src/multiplexer.rs @@ -14,18 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::pin::Pin; -use std::unreachable; +use std::{pin::Pin, unreachable}; -use futures::channel::mpsc; -use futures::stream::{FusedStream, Stream}; -use futures::task::{Context, Poll}; +use futures::{ + channel::mpsc, + stream::{FusedStream, Stream}, + task::{Context, Poll}, +}; use strum::IntoEnumIterator; use parity_scale_codec::{Decode, Error as DecodingError}; -use sc_network::config as network; -use sc_network::PeerId; +use sc_network::{config as network, PeerId}; use polkadot_node_network_protocol::request_response::{ request::IncomingRequest, v1, Protocol, RequestResponseConfig, @@ -72,33 +72,23 @@ impl RequestMultiplexer { // Ok this code is ugly as hell, it is also a hack, see https://github.com/paritytech/polkadot/issues/2842. // But it works and is executed on startup so, if anything is wrong here it will be noticed immediately. - let index = receivers.iter().enumerate().find_map(|(i, (p, _))| - if let Protocol::StatementFetching = p { - Some(i) - } else { - None - } - ).expect("Statement fetching must be registered. qed."); + let index = receivers + .iter() + .enumerate() + .find_map( + |(i, (p, _))| if let Protocol::StatementFetching = p { Some(i) } else { None }, + ) + .expect("Statement fetching must be registered. qed."); let statement_fetching = Some(receivers.remove(index).1); - let index = receivers.iter().enumerate().find_map(|(i, (p, _))| - if let Protocol::DisputeSending = p { - Some(i) - } else { - None - } - ).expect("Dispute sending must be registered. qed."); + let index = receivers + .iter() + .enumerate() + .find_map(|(i, (p, _))| if let Protocol::DisputeSending = p { Some(i) } else { None }) + .expect("Dispute sending must be registered. qed."); let dispute_sending = Some(receivers.remove(index).1); - ( - Self { - receivers, - statement_fetching, - dispute_sending, - next_poll: 0, - }, - cfgs, - ) + (Self { receivers, statement_fetching, dispute_sending, next_poll: 0 }, cfgs) } /// Get the receiver for handling statement fetching requests. @@ -132,7 +122,7 @@ impl Stream for RequestMultiplexer { // Avoid panic: if rx.is_terminated() { // Early return, we don't want to update next_poll. - return Poll::Ready(None); + return Poll::Ready(None) } i += 1; count -= 1; @@ -142,8 +132,8 @@ impl Stream for RequestMultiplexer { Poll::Ready(None) => return Poll::Ready(None), Poll::Ready(Some(v)) => { result = Poll::Ready(Some(multiplex_single(*p, v))); - break; - } + break + }, } } self.next_poll = i; @@ -155,7 +145,7 @@ impl FusedStream for RequestMultiplexer { fn is_terminated(&self) -> bool { let len = self.receivers.len(); if len == 0 { - return true; + return true } let (_, rx) = &self.receivers[self.next_poll % len]; rx.is_terminated() @@ -165,11 +155,7 @@ impl FusedStream for RequestMultiplexer { /// Convert a single raw incoming request into a `MultiplexMessage`. fn multiplex_single( p: Protocol, - network::IncomingRequest { - payload, - peer, - pending_response, - }: network::IncomingRequest, + network::IncomingRequest { payload, peer, pending_response }: network::IncomingRequest, ) -> Result { let r = match p { Protocol::ChunkFetching => AllMessages::from(IncomingRequest::new( @@ -194,10 +180,10 @@ fn multiplex_single( )), Protocol::StatementFetching => { unreachable!("Statement fetching requests are handled directly. qed."); - } + }, Protocol::DisputeSending => { unreachable!("Dispute sending request are handled directly. qed."); - } + }, }; Ok(r) } @@ -211,8 +197,7 @@ fn decode_with_peer( #[cfg(test)] mod tests { - use futures::prelude::*; - use futures::stream::FusedStream; + use futures::{prelude::*, stream::FusedStream}; use super::RequestMultiplexer; #[test] diff --git a/polkadot/node/network/bridge/src/network.rs b/polkadot/node/network/bridge/src/network.rs index 4c0139f022c..036254cb558 100644 --- a/polkadot/node/network/bridge/src/network.rs +++ b/polkadot/node/network/bridge/src/network.rs @@ -14,23 +14,21 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::borrow::Cow; -use std::collections::HashSet; -use std::sync::Arc; +use std::{borrow::Cow, collections::HashSet, sync::Arc}; use async_trait::async_trait; -use futures::prelude::*; -use futures::stream::BoxStream; +use futures::{prelude::*, stream::BoxStream}; use parity_scale_codec::Encode; -use sc_network::Event as NetworkEvent; -use sc_network::{IfDisconnected, NetworkService, OutboundFailure, RequestFailure}; -use sc_network::{config::parse_addr, multiaddr::Multiaddr}; +use sc_network::{ + config::parse_addr, multiaddr::Multiaddr, Event as NetworkEvent, IfDisconnected, + NetworkService, OutboundFailure, RequestFailure, +}; use polkadot_node_network_protocol::{ peer_set::PeerSet, - request_response::{OutgoingRequest, Requests, Recipient}, + request_response::{OutgoingRequest, Recipient, Requests}, PeerId, UnifiedReputationChange as Rep, }; use polkadot_primitives::v1::{AuthorityDiscoveryId, Block, Hash}; @@ -50,8 +48,7 @@ pub(crate) fn send_message( peer_set: PeerSet, message: M, metrics: &super::Metrics, -) -where +) where M: Encode + Clone, { let message = { @@ -112,12 +109,7 @@ pub trait Network: Clone + Send + 'static { fn disconnect_peer(&self, who: PeerId, peer_set: PeerSet); /// Write a notification to a peer on the given peer-set's protocol. - fn write_notification( - &self, - who: PeerId, - peer_set: PeerSet, - message: Vec, - ); + fn write_notification(&self, who: PeerId, peer_set: PeerSet, message: Vec); } #[async_trait] @@ -170,38 +162,29 @@ impl Network for Arc> { req: Requests, if_disconnected: IfDisconnected, ) { - let ( - protocol, - OutgoingRequest { - peer, - payload, - pending_response, - }, - ) = req.encode_request(); + let (protocol, OutgoingRequest { peer, payload, pending_response }) = req.encode_request(); let peer_id = match peer { - Recipient::Peer(peer_id) => Some(peer_id), + Recipient::Peer(peer_id) => Some(peer_id), Recipient::Authority(authority) => { let mut found_peer_id = None; // Note: `get_addresses_by_authority_id` searched in a cache, and it thus expected // to be very quick. for addr in authority_discovery - .get_addresses_by_authority_id(authority).await - .into_iter().flat_map(|list| list.into_iter()) + .get_addresses_by_authority_id(authority) + .await + .into_iter() + .flat_map(|list| list.into_iter()) { let (peer_id, addr) = match parse_addr(addr) { Ok(v) => v, Err(_) => continue, }; - NetworkService::add_known_address( - &*self, - peer_id.clone(), - addr, - ); + NetworkService::add_known_address(&*self, peer_id.clone(), addr); found_peer_id = Some(peer_id); } found_peer_id - } + }, }; let peer_id = match peer_id { @@ -214,10 +197,10 @@ impl Network for Arc> { target: LOG_TARGET, "Sending failed request response failed." ), - Ok(_) => {} + Ok(_) => {}, } - return; - } + return + }, Some(peer_id) => peer_id, }; @@ -240,7 +223,8 @@ pub async fn get_peer_id_by_authority_id( // Note: `get_addresses_by_authority_id` searched in a cache, and it thus expected // to be very quick. authority_discovery - .get_addresses_by_authority_id(authority).await + .get_addresses_by_authority_id(authority) + .await .into_iter() .flat_map(|list| list.into_iter()) .find_map(|addr| parse_addr(addr).ok().map(|(p, _)| p)) diff --git a/polkadot/node/network/bridge/src/tests.rs b/polkadot/node/network/bridge/src/tests.rs index 06f110176bf..5957b957f93 100644 --- a/polkadot/node/network/bridge/src/tests.rs +++ b/polkadot/node/network/bridge/src/tests.rs @@ -15,39 +15,36 @@ // along with Polkadot. If not, see . use super::*; -use futures::executor; -use futures::stream::BoxStream; -use futures::channel::oneshot; +use futures::{channel::oneshot, executor, stream::BoxStream}; -use std::borrow::Cow; -use std::collections::HashSet; -use std::sync::atomic::{AtomicBool, Ordering}; +use assert_matches::assert_matches; use async_trait::async_trait; use parking_lot::Mutex; -use assert_matches::assert_matches; +use std::{ + borrow::Cow, + collections::HashSet, + sync::atomic::{AtomicBool, Ordering}, +}; use sc_network::{Event as NetworkEvent, IfDisconnected}; -use polkadot_subsystem::{jaeger, ActiveLeavesUpdate, FromOverseer, OverseerSignal, LeafStatus}; -use polkadot_subsystem::messages::{ - ApprovalDistributionMessage, - BitfieldDistributionMessage, - StatementDistributionMessage -}; +use polkadot_node_network_protocol::{request_response::request::Requests, view, ObservedRole}; use polkadot_node_subsystem_test_helpers::{ SingleItemSink, SingleItemStream, TestSubsystemContextHandle, }; use polkadot_node_subsystem_util::metered; -use polkadot_node_network_protocol::view; -use sc_network::Multiaddr; -use sc_network::config::RequestResponseConfig; -use sp_keyring::Sr25519Keyring; use polkadot_primitives::v1::AuthorityDiscoveryId; -use polkadot_node_network_protocol::{ObservedRole, request_response::request::Requests}; +use polkadot_subsystem::{ + jaeger, + messages::{ + ApprovalDistributionMessage, BitfieldDistributionMessage, StatementDistributionMessage, + }, + ActiveLeavesUpdate, FromOverseer, LeafStatus, OverseerSignal, +}; +use sc_network::{config::RequestResponseConfig, Multiaddr}; +use sp_keyring::Sr25519Keyring; -use crate::network::Network; -use crate::validator_discovery::AuthorityDiscovery; -use crate::Rep; +use crate::{network::Network, validator_discovery::AuthorityDiscovery, Rep}; #[derive(Debug, PartialEq)] pub enum NetworkAction { @@ -63,7 +60,7 @@ pub enum NetworkAction { #[derive(Clone)] struct TestNetwork { net_events: Arc>>>, - action_tx: Arc>>, + action_tx: Arc>>, _req_configs: Vec, } @@ -77,11 +74,9 @@ struct TestNetworkHandle { net_tx: SingleItemSink, } -fn new_test_network(req_configs: Vec) -> ( - TestNetwork, - TestNetworkHandle, - TestAuthorityDiscovery, -) { +fn new_test_network( + req_configs: Vec, +) -> (TestNetwork, TestNetworkHandle, TestAuthorityDiscovery) { let (net_tx, net_rx) = polkadot_node_subsystem_test_helpers::single_item_sink(); let (action_tx, action_rx) = metered::unbounded(); @@ -91,10 +86,7 @@ fn new_test_network(req_configs: Vec) -> ( action_tx: Arc::new(Mutex::new(action_tx)), _req_configs: req_configs, }, - TestNetworkHandle { - action_rx, - net_tx, - }, + TestNetworkHandle { action_rx, net_tx }, TestAuthorityDiscovery, ) } @@ -102,54 +94,72 @@ fn new_test_network(req_configs: Vec) -> ( #[async_trait] impl Network for TestNetwork { fn event_stream(&mut self) -> BoxStream<'static, NetworkEvent> { - self.net_events.lock() + self.net_events + .lock() .take() .expect("Subsystem made more than one call to `event_stream`") .boxed() } - async fn add_to_peers_set(&mut self, _protocol: Cow<'static, str>, _: HashSet) -> Result<(), String> { + async fn add_to_peers_set( + &mut self, + _protocol: Cow<'static, str>, + _: HashSet, + ) -> Result<(), String> { Ok(()) } - async fn remove_from_peers_set(&mut self, _protocol: Cow<'static, str>, _: HashSet) -> Result<(), String> { + async fn remove_from_peers_set( + &mut self, + _protocol: Cow<'static, str>, + _: HashSet, + ) -> Result<(), String> { Ok(()) } - async fn start_request(&self, _: &mut AD, _: Requests, _: IfDisconnected) { + async fn start_request( + &self, + _: &mut AD, + _: Requests, + _: IfDisconnected, + ) { } fn report_peer(&self, who: PeerId, cost_benefit: Rep) { - self.action_tx.lock().unbounded_send( - NetworkAction::ReputationChange(who, cost_benefit) - ).unwrap(); + self.action_tx + .lock() + .unbounded_send(NetworkAction::ReputationChange(who, cost_benefit)) + .unwrap(); } fn disconnect_peer(&self, who: PeerId, peer_set: PeerSet) { - self.action_tx.lock().unbounded_send( - NetworkAction::DisconnectPeer(who, peer_set) - ).unwrap(); + self.action_tx + .lock() + .unbounded_send(NetworkAction::DisconnectPeer(who, peer_set)) + .unwrap(); } - fn write_notification( - &self, - who: PeerId, - peer_set: PeerSet, - message: Vec, - ) { - self.action_tx.lock().unbounded_send( - NetworkAction::WriteNotification(who, peer_set, message) - ).unwrap(); + fn write_notification(&self, who: PeerId, peer_set: PeerSet, message: Vec) { + self.action_tx + .lock() + .unbounded_send(NetworkAction::WriteNotification(who, peer_set, message)) + .unwrap(); } } #[async_trait] impl validator_discovery::AuthorityDiscovery for TestAuthorityDiscovery { - async fn get_addresses_by_authority_id(&mut self, _authority: AuthorityDiscoveryId) -> Option> { + async fn get_addresses_by_authority_id( + &mut self, + _authority: AuthorityDiscoveryId, + ) -> Option> { None } - async fn get_authority_id_by_peer_id(&mut self, _peer_id: PeerId) -> Option { + async fn get_authority_id_by_peer_id( + &mut self, + _peer_id: PeerId, + ) -> Option { None } } @@ -176,21 +186,24 @@ impl TestNetworkHandle { protocol: peer_set.into_protocol_name(), negotiated_fallback: None, role: role.into(), - }).await; + }) + .await; } async fn disconnect_peer(&mut self, peer: PeerId, peer_set: PeerSet) { self.send_network_event(NetworkEvent::NotificationStreamClosed { remote: peer, protocol: peer_set.into_protocol_name(), - }).await; + }) + .await; } async fn peer_message(&mut self, peer: PeerId, peer_set: PeerSet, message: Vec) { self.send_network_event(NetworkEvent::NotificationsReceived { remote: peer, messages: vec![(peer_set.into_protocol_name(), message.into())], - }).await; + }) + .await; } async fn send_network_event(&mut self, event: NetworkEvent) { @@ -250,14 +263,8 @@ fn make_sync_oracle(val: bool) -> (TestSyncOracle, TestSyncOracleHandle) { let flag = Arc::new(AtomicBool::new(val)); ( - TestSyncOracle { - flag: flag.clone(), - done_syncing_sender: Arc::new(Mutex::new(Some(tx))), - }, - TestSyncOracleHandle { - flag, - done_syncing_receiver: rx, - } + TestSyncOracle { flag: flag.clone(), done_syncing_sender: Arc::new(Mutex::new(Some(tx))) }, + TestSyncOracleHandle { flag, done_syncing_receiver: rx }, ) } @@ -273,14 +280,15 @@ struct TestHarness { virtual_overseer: VirtualOverseer, } -fn test_harness>( +fn test_harness>( sync_oracle: Box, test: impl FnOnce(TestHarness) -> T, ) { let pool = sp_core::testing::TaskExecutor::new(); let (request_multiplexer, req_configs) = RequestMultiplexer::new(); let (mut network, network_handle, discovery) = new_test_network(req_configs); - let (context, virtual_overseer) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); + let (context, virtual_overseer) = + polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); let network_stream = network.event_stream(); let bridge = NetworkBridge { @@ -291,26 +299,22 @@ fn test_harness>( sync_oracle, }; - let network_bridge = run_network( - bridge, - context, - network_stream, - ) + let network_bridge = run_network(bridge, context, network_stream) .map_err(|_| panic!("subsystem execution failed")) .map(|_| ()); - let test_fut = test(TestHarness { - network_handle, - virtual_overseer, - }); + let test_fut = test(TestHarness { network_handle, virtual_overseer }); futures::pin_mut!(test_fut); futures::pin_mut!(network_bridge); - let _ = executor::block_on(future::join(async move { - let mut virtual_overseer = test_fut.await; - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }, network_bridge)); + let _ = executor::block_on(future::join( + async move { + let mut virtual_overseer = test_fut.await; + virtual_overseer.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }, + network_bridge, + )); } async fn assert_sends_validation_event_to_all( @@ -357,29 +361,30 @@ async fn assert_sends_collation_event_to_all( fn send_our_view_upon_connection() { let (oracle, handle) = make_sync_oracle(false); test_harness(Box::new(oracle), |test_harness| async move { - let TestHarness { - mut network_handle, - mut virtual_overseer, - } = test_harness; + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; let peer = PeerId::random(); let head = Hash::repeat_byte(1); - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash: head, number: 1, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), - }) - )) - ).await; + }), + ))) + .await; handle.await_mode_switch().await; - network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await; - network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await; + network_handle + .connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full) + .await; let view = view![head]; let actions = network_handle.next_network_actions(2).await; @@ -388,9 +393,7 @@ fn send_our_view_upon_connection() { &NetworkAction::WriteNotification( peer.clone(), PeerSet::Validation, - WireMessage::::ViewUpdate( - view.clone(), - ).encode(), + WireMessage::::ViewUpdate(view.clone()).encode(), ), ); assert_network_actions_contains( @@ -398,9 +401,7 @@ fn send_our_view_upon_connection() { &NetworkAction::WriteNotification( peer.clone(), PeerSet::Collation, - WireMessage::::ViewUpdate( - view.clone(), - ).encode(), + WireMessage::::ViewUpdate(view.clone()).encode(), ), ); virtual_overseer @@ -416,85 +417,61 @@ fn sends_view_updates_to_peers() { let peer_a = PeerId::random(); let peer_b = PeerId::random(); - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( - ActiveLeavesUpdate { - activated: Default::default(), - deactivated: Default::default(), - } - )) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Default::default(), + deactivated: Default::default(), + }))) + .await; handle.await_mode_switch().await; - network_handle.connect_peer( - peer_a.clone(), - PeerSet::Validation, - ObservedRole::Full, - ).await; - network_handle.connect_peer( - peer_b.clone(), - PeerSet::Collation, - ObservedRole::Full, - ).await; + network_handle + .connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b.clone(), PeerSet::Collation, ObservedRole::Full) + .await; let actions = network_handle.next_network_actions(2).await; - let wire_message = WireMessage::::ViewUpdate( - View::default(), - ).encode(); + let wire_message = + WireMessage::::ViewUpdate(View::default()).encode(); assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_a, - PeerSet::Validation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_a, PeerSet::Validation, wire_message.clone()), ); assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_b, - PeerSet::Collation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), ); let hash_a = Hash::repeat_byte(1); - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash: hash_a, number: 1, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), - }) - )) - ).await; + }), + ))) + .await; let actions = network_handle.next_network_actions(2).await; - let wire_message = WireMessage::::ViewUpdate( - view![hash_a] - ).encode(); + let wire_message = + WireMessage::::ViewUpdate(view![hash_a]).encode(); assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_a, - PeerSet::Validation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_a, PeerSet::Validation, wire_message.clone()), ); assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_b, - PeerSet::Collation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), ); virtual_overseer }); @@ -509,22 +486,18 @@ fn do_not_send_view_update_until_synced() { let peer_a = PeerId::random(); let peer_b = PeerId::random(); - network_handle.connect_peer( - peer_a.clone(), - PeerSet::Validation, - ObservedRole::Full, - ).await; - network_handle.connect_peer( - peer_b.clone(), - PeerSet::Collation, - ObservedRole::Full, - ).await; + network_handle + .connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b.clone(), PeerSet::Collation, ObservedRole::Full) + .await; { let actions = network_handle.next_network_actions(2).await; - let wire_message = WireMessage::::ViewUpdate( - View::default(), - ).encode(); + let wire_message = + WireMessage::::ViewUpdate(View::default()) + .encode(); assert_network_actions_contains( &actions, @@ -537,52 +510,48 @@ fn do_not_send_view_update_until_synced() { assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_b, - PeerSet::Collation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), ); } let hash_a = Hash::repeat_byte(1); let hash_b = Hash::repeat_byte(1); - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash: hash_a, number: 1, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), - }) - )) - ).await; + }), + ))) + .await; // delay until the previous update has certainly been processed. futures_timer::Delay::new(std::time::Duration::from_millis(100)).await; handle.set_done(); - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash: hash_b, number: 1, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), - }) - )) - ).await; + }), + ))) + .await; handle.await_mode_switch().await; // There should be a mode switch only for the second view update. { let actions = network_handle.next_network_actions(2).await; - let wire_message = WireMessage::::ViewUpdate( - view![hash_a, hash_b] - ).encode(); + let wire_message = + WireMessage::::ViewUpdate(view![hash_a, hash_b]) + .encode(); assert_network_actions_contains( &actions, @@ -595,11 +564,7 @@ fn do_not_send_view_update_until_synced() { assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_b, - PeerSet::Collation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_b, PeerSet::Collation, wire_message.clone()), ); } virtual_overseer @@ -614,61 +579,51 @@ fn do_not_send_view_update_when_only_finalized_block_changed() { let peer_a = PeerId::random(); let peer_b = PeerId::random(); - network_handle.connect_peer( - peer_a.clone(), - PeerSet::Validation, - ObservedRole::Full, - ).await; - network_handle.connect_peer( - peer_b.clone(), - PeerSet::Validation, - ObservedRole::Full, - ).await; + network_handle + .connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b.clone(), PeerSet::Validation, ObservedRole::Full) + .await; let hash_a = Hash::repeat_byte(1); - virtual_overseer.send(FromOverseer::Signal(OverseerSignal::BlockFinalized(Hash::random(), 5))).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::BlockFinalized(Hash::random(), 5))) + .await; // Send some empty active leaves update // // This should not trigger a view update to our peers. - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::default())) - ).await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::default()))) + .await; // This should trigger the view update to our peers. - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash: hash_a, number: 1, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), - }) - )) - ).await; + }), + ))) + .await; let actions = network_handle.next_network_actions(4).await; - let wire_message = WireMessage::::ViewUpdate( - View::new(vec![hash_a], 5) - ).encode(); + let wire_message = + WireMessage::::ViewUpdate(View::new(vec![hash_a], 5)) + .encode(); assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_a, - PeerSet::Validation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_a, PeerSet::Validation, wire_message.clone()), ); assert_network_actions_contains( &actions, - &NetworkAction::WriteNotification( - peer_b, - PeerSet::Validation, - wire_message.clone(), - ), + &NetworkAction::WriteNotification(peer_b, PeerSet::Validation, wire_message.clone()), ); virtual_overseer }); @@ -677,22 +632,19 @@ fn do_not_send_view_update_when_only_finalized_block_changed() { #[test] fn peer_view_updates_sent_via_overseer() { test_harness(done_syncing_oracle(), |test_harness| async move { - let TestHarness { - mut network_handle, - mut virtual_overseer, - } = test_harness; + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; let peer = PeerId::random(); - network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await; + network_handle + .connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full) + .await; let view = view![Hash::repeat_byte(1)]; assert_matches!( virtual_overseer.recv().await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::DisputeSendingReceiver(_) - ) + AllMessages::DisputeDistribution(DisputeDistributionMessage::DisputeSendingReceiver(_)) ); assert_matches!( virtual_overseer.recv().await, @@ -706,26 +658,29 @@ fn peer_view_updates_sent_via_overseer() { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } - network_handle.peer_message( - peer.clone(), - PeerSet::Validation, - WireMessage::::ViewUpdate( - view.clone(), - ).encode(), - ).await; + network_handle + .peer_message( + peer.clone(), + PeerSet::Validation, + WireMessage::::ViewUpdate(view.clone()).encode(), + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), view), &mut virtual_overseer, - ).await; + ) + .await; virtual_overseer }); } @@ -733,24 +688,17 @@ fn peer_view_updates_sent_via_overseer() { #[test] fn peer_messages_sent_via_overseer() { test_harness(done_syncing_oracle(), |test_harness| async move { - let TestHarness { - mut network_handle, - mut virtual_overseer, - } = test_harness; + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; let peer = PeerId::random(); - network_handle.connect_peer( - peer.clone(), - PeerSet::Validation, - ObservedRole::Full, - ).await; + network_handle + .connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full) + .await; assert_matches!( virtual_overseer.recv().await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::DisputeSendingReceiver(_) - ) + AllMessages::DisputeDistribution(DisputeDistributionMessage::DisputeSendingReceiver(_)) ); assert_matches!( virtual_overseer.recv().await, @@ -764,27 +712,30 @@ fn peer_messages_sent_via_overseer() { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } - let approval_distribution_message = protocol_v1::ApprovalDistributionMessage::Approvals( - Vec::new() - ); + let approval_distribution_message = + protocol_v1::ApprovalDistributionMessage::Approvals(Vec::new()); let message = protocol_v1::ValidationProtocol::ApprovalDistribution( approval_distribution_message.clone(), ); - network_handle.peer_message( - peer.clone(), - PeerSet::Validation, - WireMessage::ProtocolMessage(message.clone()).encode(), - ).await; + network_handle + .peer_message( + peer.clone(), + PeerSet::Validation, + WireMessage::ProtocolMessage(message.clone()).encode(), + ) + .await; network_handle.disconnect_peer(peer.clone(), PeerSet::Validation).await; @@ -806,7 +757,8 @@ fn peer_messages_sent_via_overseer() { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerDisconnected(peer), &mut virtual_overseer, - ).await; + ) + .await; virtual_overseer }); } @@ -814,21 +766,20 @@ fn peer_messages_sent_via_overseer() { #[test] fn peer_disconnect_from_just_one_peerset() { test_harness(done_syncing_oracle(), |test_harness| async move { - let TestHarness { - mut network_handle, - mut virtual_overseer, - } = test_harness; + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; let peer = PeerId::random(); - network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await; - network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await; + network_handle + .connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full) + .await; assert_matches!( virtual_overseer.recv().await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::DisputeSendingReceiver(_) - ) + AllMessages::DisputeDistribution(DisputeDistributionMessage::DisputeSendingReceiver(_)) ); assert_matches!( virtual_overseer.recv().await, @@ -842,24 +793,28 @@ fn peer_disconnect_from_just_one_peerset() { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } { assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } network_handle.disconnect_peer(peer.clone(), PeerSet::Validation).await; @@ -867,27 +822,27 @@ fn peer_disconnect_from_just_one_peerset() { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerDisconnected(peer.clone()), &mut virtual_overseer, - ).await; + ) + .await; // to show that we're still connected on the collation protocol, send a view update. let hash_a = Hash::repeat_byte(1); - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash: hash_a, number: 1, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), - }) - )) - ).await; + }), + ))) + .await; let actions = network_handle.next_network_actions(3).await; - let wire_message = WireMessage::::ViewUpdate( - view![hash_a] - ).encode(); + let wire_message = + WireMessage::::ViewUpdate(view![hash_a]).encode(); assert_network_actions_contains( &actions, @@ -904,19 +859,14 @@ fn peer_disconnect_from_just_one_peerset() { #[test] fn relays_collation_protocol_messages() { test_harness(done_syncing_oracle(), |test_harness| async move { - let TestHarness { - mut network_handle, - mut virtual_overseer, - } = test_harness; + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; let peer_a = PeerId::random(); let peer_b = PeerId::random(); assert_matches!( virtual_overseer.recv().await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::DisputeSendingReceiver(_) - ) + AllMessages::DisputeDistribution(DisputeDistributionMessage::DisputeSendingReceiver(_)) ); assert_matches!( virtual_overseer.recv().await, @@ -925,32 +875,40 @@ fn relays_collation_protocol_messages() { ) ); - network_handle.connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full).await; - network_handle.connect_peer(peer_b.clone(), PeerSet::Collation, ObservedRole::Full).await; + network_handle + .connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer_b.clone(), PeerSet::Collation, ObservedRole::Full) + .await; // bridge will inform about all connected peers. { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerConnected(peer_a.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer_a.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } { assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerConnected(peer_b.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer_b.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } // peer A gets reported for sending a collation message. @@ -961,32 +919,32 @@ fn relays_collation_protocol_messages() { Default::default(), ); - let message = protocol_v1::CollationProtocol::CollatorProtocol( - collator_protocol_message.clone() - ); + let message = + protocol_v1::CollationProtocol::CollatorProtocol(collator_protocol_message.clone()); - network_handle.peer_message( - peer_a.clone(), - PeerSet::Collation, - WireMessage::ProtocolMessage(message.clone()).encode(), - ).await; + network_handle + .peer_message( + peer_a.clone(), + PeerSet::Collation, + WireMessage::ProtocolMessage(message.clone()).encode(), + ) + .await; let actions = network_handle.next_network_actions(3).await; assert_network_actions_contains( &actions, - &NetworkAction::ReputationChange( - peer_a.clone(), - UNCONNECTED_PEERSET_COST, - ), + &NetworkAction::ReputationChange(peer_a.clone(), UNCONNECTED_PEERSET_COST), ); // peer B has the message relayed. - network_handle.peer_message( - peer_b.clone(), - PeerSet::Collation, - WireMessage::ProtocolMessage(message.clone()).encode(), - ).await; + network_handle + .peer_message( + peer_b.clone(), + PeerSet::Collation, + WireMessage::ProtocolMessage(message.clone()).encode(), + ) + .await; assert_matches!( virtual_overseer.recv().await, @@ -1006,21 +964,20 @@ fn relays_collation_protocol_messages() { #[test] fn different_views_on_different_peer_sets() { test_harness(done_syncing_oracle(), |test_harness| async move { - let TestHarness { - mut network_handle, - mut virtual_overseer, - } = test_harness; + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; let peer = PeerId::random(); - network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await; - network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await; + network_handle + .connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full) + .await; assert_matches!( virtual_overseer.recv().await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::DisputeSendingReceiver(_) - ) + AllMessages::DisputeDistribution(DisputeDistributionMessage::DisputeSendingReceiver(_)) ); assert_matches!( virtual_overseer.recv().await, @@ -1034,50 +991,60 @@ fn different_views_on_different_peer_sets() { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } { assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } let view_a = view![Hash::repeat_byte(1)]; let view_b = view![Hash::repeat_byte(2)]; - network_handle.peer_message( - peer.clone(), - PeerSet::Validation, - WireMessage::::ViewUpdate(view_a.clone()).encode(), - ).await; + network_handle + .peer_message( + peer.clone(), + PeerSet::Validation, + WireMessage::::ViewUpdate(view_a.clone()).encode(), + ) + .await; - network_handle.peer_message( - peer.clone(), - PeerSet::Collation, - WireMessage::::ViewUpdate(view_b.clone()).encode(), - ).await; + network_handle + .peer_message( + peer.clone(), + PeerSet::Collation, + WireMessage::::ViewUpdate(view_b.clone()).encode(), + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), view_a.clone()), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), view_b.clone()), &mut virtual_overseer, - ).await; + ) + .await; virtual_overseer }); } @@ -1089,33 +1056,31 @@ fn sent_views_include_finalized_number_update() { let peer_a = PeerId::random(); - network_handle.connect_peer( - peer_a.clone(), - PeerSet::Validation, - ObservedRole::Full, - ).await; + network_handle + .connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full) + .await; let hash_a = Hash::repeat_byte(1); let hash_b = Hash::repeat_byte(2); - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::BlockFinalized(hash_a, 1)) - ).await; - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::BlockFinalized(hash_a, 1))) + .await; + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash: hash_b, number: 1, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), - }) - )) - ).await; + }), + ))) + .await; let actions = network_handle.next_network_actions(2).await; - let wire_message = WireMessage::::ViewUpdate( - View::new(vec![hash_b], 1) - ).encode(); + let wire_message = + WireMessage::::ViewUpdate(View::new(vec![hash_b], 1)) + .encode(); assert_network_actions_contains( &actions, @@ -1136,35 +1101,35 @@ fn view_finalized_number_can_not_go_down() { let peer_a = PeerId::random(); - network_handle.connect_peer( - peer_a.clone(), - PeerSet::Validation, - ObservedRole::Full, - ).await; - - network_handle.peer_message( - peer_a.clone(), - PeerSet::Validation, - WireMessage::::ViewUpdate( - View::new(vec![Hash::repeat_byte(0x01)], 1), - ).encode(), - ).await; - - network_handle.peer_message( - peer_a.clone(), - PeerSet::Validation, - WireMessage::::ViewUpdate( - View::new(vec![], 0), - ).encode(), - ).await; + network_handle + .connect_peer(peer_a.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + + network_handle + .peer_message( + peer_a.clone(), + PeerSet::Validation, + WireMessage::::ViewUpdate(View::new( + vec![Hash::repeat_byte(0x01)], + 1, + )) + .encode(), + ) + .await; + + network_handle + .peer_message( + peer_a.clone(), + PeerSet::Validation, + WireMessage::::ViewUpdate(View::new(vec![], 0)) + .encode(), + ) + .await; let actions = network_handle.next_network_actions(2).await; assert_network_actions_contains( &actions, - &NetworkAction::ReputationChange( - peer_a.clone(), - MALFORMED_VIEW_COST, - ), + &NetworkAction::ReputationChange(peer_a.clone(), MALFORMED_VIEW_COST), ); virtual_overseer }); @@ -1173,21 +1138,20 @@ fn view_finalized_number_can_not_go_down() { #[test] fn send_messages_to_peers() { test_harness(done_syncing_oracle(), |test_harness| async move { - let TestHarness { - mut network_handle, - mut virtual_overseer, - } = test_harness; + let TestHarness { mut network_handle, mut virtual_overseer } = test_harness; let peer = PeerId::random(); - network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await; - network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await; + network_handle + .connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full) + .await; + network_handle + .connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full) + .await; assert_matches!( virtual_overseer.recv().await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::DisputeSendingReceiver(_) - ) + AllMessages::DisputeDistribution(DisputeDistributionMessage::DisputeSendingReceiver(_)) ); assert_matches!( virtual_overseer.recv().await, @@ -1201,24 +1165,28 @@ fn send_messages_to_peers() { assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_validation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } { assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerConnected(peer.clone(), ObservedRole::Full, None), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_collation_event_to_all( NetworkBridgeEvent::PeerViewChange(peer.clone(), View::default()), &mut virtual_overseer, - ).await; + ) + .await; } // consume peer view changes @@ -1229,20 +1197,21 @@ fn send_messages_to_peers() { // send a validation protocol message. { - let approval_distribution_message = protocol_v1::ApprovalDistributionMessage::Approvals( - Vec::new() - ); + let approval_distribution_message = + protocol_v1::ApprovalDistributionMessage::Approvals(Vec::new()); let message = protocol_v1::ValidationProtocol::ApprovalDistribution( approval_distribution_message.clone(), ); - virtual_overseer.send(FromOverseer::Communication { - msg: NetworkBridgeMessage::SendValidationMessage( - vec![peer.clone()], - message.clone(), - ) - }).await; + virtual_overseer + .send(FromOverseer::Communication { + msg: NetworkBridgeMessage::SendValidationMessage( + vec![peer.clone()], + message.clone(), + ), + }) + .await; assert_eq!( network_handle.next_network_action().await, @@ -1263,16 +1232,17 @@ fn send_messages_to_peers() { Default::default(), ); - let message = protocol_v1::CollationProtocol::CollatorProtocol( - collator_protocol_message.clone() - ); + let message = + protocol_v1::CollationProtocol::CollatorProtocol(collator_protocol_message.clone()); - virtual_overseer.send(FromOverseer::Communication { - msg: NetworkBridgeMessage::SendCollationMessage( - vec![peer.clone()], - message.clone(), - ) - }).await; + virtual_overseer + .send(FromOverseer::Communication { + msg: NetworkBridgeMessage::SendCollationMessage( + vec![peer.clone()], + message.clone(), + ), + }) + .await; assert_eq!( network_handle.next_network_action().await, @@ -1301,10 +1271,16 @@ fn spread_event_to_subsystems_is_up_to_date() { AllMessages::CandidateBacking(_) => unreachable!("Not interested in network events"), AllMessages::ChainApi(_) => unreachable!("Not interested in network events"), AllMessages::CollatorProtocol(_) => unreachable!("Not interested in network events"), - AllMessages::StatementDistribution(_) => { cnt += 1; } - AllMessages::AvailabilityDistribution(_) => unreachable!("Not interested in network events"), - AllMessages::AvailabilityRecovery(_) => unreachable!("Not interested in network events"), - AllMessages::BitfieldDistribution(_) => { cnt += 1; } + AllMessages::StatementDistribution(_) => { + cnt += 1; + }, + AllMessages::AvailabilityDistribution(_) => + unreachable!("Not interested in network events"), + AllMessages::AvailabilityRecovery(_) => + unreachable!("Not interested in network events"), + AllMessages::BitfieldDistribution(_) => { + cnt += 1; + }, AllMessages::BitfieldSigning(_) => unreachable!("Not interested in network events"), AllMessages::Provisioner(_) => unreachable!("Not interested in network events"), AllMessages::RuntimeApi(_) => unreachable!("Not interested in network events"), @@ -1312,10 +1288,13 @@ fn spread_event_to_subsystems_is_up_to_date() { AllMessages::NetworkBridge(_) => unreachable!("Not interested in network events"), AllMessages::CollationGeneration(_) => unreachable!("Not interested in network events"), AllMessages::ApprovalVoting(_) => unreachable!("Not interested in network events"), - AllMessages::ApprovalDistribution(_) => { cnt += 1; } + AllMessages::ApprovalDistribution(_) => { + cnt += 1; + }, AllMessages::GossipSupport(_) => unreachable!("Not interested in network events"), AllMessages::DisputeCoordinator(_) => unreachable!("Not interested in network events"), - AllMessages::DisputeParticipation(_) => unreachable!("Not interested in network events"), + AllMessages::DisputeParticipation(_) => + unreachable!("Not interested in network events"), AllMessages::DisputeDistribution(_) => unreachable!("Not interested in network events"), AllMessages::ChainSelection(_) => unreachable!("Not interested in network events"), // Add variants here as needed, `{ cnt += 1; }` for those that need to be @@ -1328,11 +1307,7 @@ fn spread_event_to_subsystems_is_up_to_date() { #[test] fn our_view_updates_decreasing_order_and_limited_to_max() { test_harness(done_syncing_oracle(), |test_harness| async move { - let TestHarness { - mut virtual_overseer, - .. - } = test_harness; - + let TestHarness { mut virtual_overseer, .. } = test_harness; // to show that we're still connected on the collation protocol, send a view update. @@ -1341,23 +1316,21 @@ fn our_view_updates_decreasing_order_and_limited_to_max() { for (i, hash) in hashes.enumerate().rev() { // These are in reverse order, so the subsystem must sort internally to // get the correct view. - virtual_overseer.send( - FromOverseer::Signal(OverseerSignal::ActiveLeaves( + virtual_overseer + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::start_work(ActivatedLeaf { hash, number: i as _, status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), }), - )) - ).await; + ))) + .await; } assert_matches!( virtual_overseer.recv().await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::DisputeSendingReceiver(_) - ) + AllMessages::DisputeDistribution(DisputeDistributionMessage::DisputeSendingReceiver(_)) ); assert_matches!( virtual_overseer.recv().await, @@ -1366,24 +1339,27 @@ fn our_view_updates_decreasing_order_and_limited_to_max() { ) ); - let our_views = (1..=MAX_VIEW_HEADS).rev() - .map(|start| OurView::new( + let our_views = (1..=MAX_VIEW_HEADS).rev().map(|start| { + OurView::new( (start..=MAX_VIEW_HEADS) .rev() .map(|i| (Hash::repeat_byte(i as u8), Arc::new(jaeger::Span::Disabled))), 0, - )); + ) + }); for our_view in our_views { assert_sends_validation_event_to_all( NetworkBridgeEvent::OurViewChange(our_view.clone()), &mut virtual_overseer, - ).await; + ) + .await; assert_sends_collation_event_to_all( NetworkBridgeEvent::OurViewChange(our_view), &mut virtual_overseer, - ).await; + ) + .await; } virtual_overseer diff --git a/polkadot/node/network/bridge/src/validator_discovery.rs b/polkadot/node/network/bridge/src/validator_discovery.rs index 46f575c0f38..051aeed747b 100644 --- a/polkadot/node/network/bridge/src/validator_discovery.rs +++ b/polkadot/node/network/bridge/src/validator_discovery.rs @@ -25,9 +25,9 @@ use futures::channel::oneshot; use sc_network::multiaddr::Multiaddr; -use polkadot_primitives::v1::AuthorityDiscoveryId; -use polkadot_node_network_protocol::peer_set::{PeerSet, PerPeerSet}; pub use polkadot_node_network_protocol::authority_discovery::AuthorityDiscovery; +use polkadot_node_network_protocol::peer_set::{PeerSet, PerPeerSet}; +use polkadot_primitives::v1::AuthorityDiscoveryId; const LOG_TARGET: &str = "parachain::validator-discovery"; @@ -44,10 +44,7 @@ struct StatePerPeerSet { impl Service { pub fn new() -> Self { - Self { - state: Default::default(), - _phantom: PhantomData, - } + Self { state: Default::default(), _phantom: PhantomData } } /// On a new connection request, a peer set update will be issued. @@ -70,24 +67,27 @@ impl Service { let mut newly_requested = HashSet::new(); let requested = validator_ids.len(); for authority in validator_ids.into_iter() { - let result = authority_discovery_service.get_addresses_by_authority_id(authority.clone()).await; + let result = authority_discovery_service + .get_addresses_by_authority_id(authority.clone()) + .await; if let Some(addresses) = result { newly_requested.extend(addresses); } else { failed_to_resolve += 1; - tracing::debug!(target: LOG_TARGET, "Authority Discovery couldn't resolve {:?}", authority); + tracing::debug!( + target: LOG_TARGET, + "Authority Discovery couldn't resolve {:?}", + authority + ); } } let state = &mut self.state[peer_set]; // clean up revoked requests - let multiaddr_to_remove: HashSet<_> = state.previously_requested - .difference(&newly_requested) - .cloned() - .collect(); - let multiaddr_to_add: HashSet<_> = newly_requested.difference(&state.previously_requested) - .cloned() - .collect(); + let multiaddr_to_remove: HashSet<_> = + state.previously_requested.difference(&newly_requested).cloned().collect(); + let multiaddr_to_add: HashSet<_> = + newly_requested.difference(&state.previously_requested).cloned().collect(); state.previously_requested = newly_requested; tracing::debug!( @@ -101,17 +101,16 @@ impl Service { ); // ask the network to connect to these nodes and not disconnect // from them until removed from the set - if let Err(e) = network_service.add_to_peers_set( - peer_set.into_protocol_name(), - multiaddr_to_add, - ).await { + if let Err(e) = network_service + .add_to_peers_set(peer_set.into_protocol_name(), multiaddr_to_add) + .await + { tracing::warn!(target: LOG_TARGET, err = ?e, "AuthorityDiscoveryService returned an invalid multiaddress"); } // the addresses are known to be valid - let _ = network_service.remove_from_peers_set( - peer_set.into_protocol_name(), - multiaddr_to_remove - ).await; + let _ = network_service + .remove_from_peers_set(peer_set.into_protocol_name(), multiaddr_to_remove) + .await; let _ = failed.send(failed_to_resolve); @@ -124,12 +123,12 @@ mod tests { use super::*; use crate::network::Network; - use std::{borrow::Cow, collections::HashMap}; - use futures::stream::BoxStream; use async_trait::async_trait; + use futures::stream::BoxStream; + use polkadot_node_network_protocol::{request_response::request::Requests, PeerId}; use sc_network::{Event as NetworkEvent, IfDisconnected}; use sp_keyring::Sr25519Keyring; - use polkadot_node_network_protocol::{PeerId, request_response::request::Requests}; + use std::{borrow::Cow, collections::HashMap}; fn new_service() -> Service { Service::new() @@ -156,13 +155,8 @@ mod tests { let authorities = known_authorities(); let multiaddr = known_multiaddr(); Self { - by_authority_id: authorities.iter() - .cloned() - .zip(multiaddr.into_iter()) - .collect(), - by_peer_id: peer_ids.into_iter() - .zip(authorities.into_iter()) - .collect(), + by_authority_id: authorities.iter().cloned().zip(multiaddr.into_iter()).collect(), + by_peer_id: peer_ids.into_iter().zip(authorities.into_iter()).collect(), } } } @@ -173,17 +167,30 @@ mod tests { panic!() } - async fn add_to_peers_set(&mut self, _protocol: Cow<'static, str>, multiaddresses: HashSet) -> Result<(), String> { + async fn add_to_peers_set( + &mut self, + _protocol: Cow<'static, str>, + multiaddresses: HashSet, + ) -> Result<(), String> { self.peers_set.extend(multiaddresses.into_iter()); Ok(()) } - async fn remove_from_peers_set(&mut self, _protocol: Cow<'static, str>, multiaddresses: HashSet) -> Result<(), String> { + async fn remove_from_peers_set( + &mut self, + _protocol: Cow<'static, str>, + multiaddresses: HashSet, + ) -> Result<(), String> { self.peers_set.retain(|elem| !multiaddresses.contains(elem)); Ok(()) } - async fn start_request(&self, _: &mut AD, _: Requests, _: IfDisconnected) { + async fn start_request( + &self, + _: &mut AD, + _: Requests, + _: IfDisconnected, + ) { } fn report_peer(&self, _: PeerId, _: crate::Rep) { @@ -194,33 +201,33 @@ mod tests { panic!() } - fn write_notification( - &self, - _: PeerId, - _: PeerSet, - _: Vec, - ) { + fn write_notification(&self, _: PeerId, _: PeerSet, _: Vec) { panic!() } } #[async_trait] impl AuthorityDiscovery for TestAuthorityDiscovery { - async fn get_addresses_by_authority_id(&mut self, authority: AuthorityDiscoveryId) -> Option> { + async fn get_addresses_by_authority_id( + &mut self, + authority: AuthorityDiscoveryId, + ) -> Option> { self.by_authority_id.get(&authority).cloned().map(|addr| vec![addr]) } - async fn get_authority_id_by_peer_id(&mut self, peer_id: PeerId) -> Option { + async fn get_authority_id_by_peer_id( + &mut self, + peer_id: PeerId, + ) -> Option { self.by_peer_id.get(&peer_id).cloned() } } fn known_authorities() -> Vec { - [ - Sr25519Keyring::Alice, - Sr25519Keyring::Bob, - Sr25519Keyring::Charlie, - ].iter().map(|k| k.public().into()).collect() + [Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie] + .iter() + .map(|k| k.public().into()) + .collect() } fn known_peer_ids() -> Vec { @@ -245,26 +252,20 @@ mod tests { futures::executor::block_on(async move { let (failed, _) = oneshot::channel(); - let (ns, ads) = service.on_request( - vec![authority_ids[0].clone()], - PeerSet::Validation, - failed, - ns, - ads, - ).await; + let (ns, ads) = service + .on_request(vec![authority_ids[0].clone()], PeerSet::Validation, failed, ns, ads) + .await; let (failed, _) = oneshot::channel(); - let (_, ads) = service.on_request( - vec![authority_ids[1].clone()], - PeerSet::Validation, - failed, - ns, - ads, - ).await; + let (_, ads) = service + .on_request(vec![authority_ids[1].clone()], PeerSet::Validation, failed, ns, ads) + .await; let state = &service.state[PeerSet::Validation]; assert_eq!(state.previously_requested.len(), 1); - assert!(state.previously_requested.contains(ads.by_authority_id.get(&authority_ids[1]).unwrap())); + assert!(state + .previously_requested + .contains(ads.by_authority_id.get(&authority_ids[1]).unwrap())); }); } @@ -279,17 +280,21 @@ mod tests { futures::executor::block_on(async move { let (failed, failed_rx) = oneshot::channel(); let unknown = Sr25519Keyring::Ferdie.public().into(); - let (_, ads) = service.on_request( - vec![authority_ids[0].clone(), unknown], - PeerSet::Validation, - failed, - ns, - ads, - ).await; + let (_, ads) = service + .on_request( + vec![authority_ids[0].clone(), unknown], + PeerSet::Validation, + failed, + ns, + ads, + ) + .await; let state = &service.state[PeerSet::Validation]; assert_eq!(state.previously_requested.len(), 1); - assert!(state.previously_requested.contains(ads.by_authority_id.get(&authority_ids[0]).unwrap())); + assert!(state + .previously_requested + .contains(ads.by_authority_id.get(&authority_ids[0]).unwrap())); let failed = failed_rx.await.unwrap(); assert_eq!(failed, 1); diff --git a/polkadot/node/network/collator-protocol/src/collator_side/mod.rs b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs index 51cf87ea913..5713ad647c6 100644 --- a/polkadot/node/network/collator-protocol/src/collator_side/mod.rs +++ b/polkadot/node/network/collator-protocol/src/collator_side/mod.rs @@ -14,44 +14,49 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::{collections::{HashMap, HashSet, VecDeque}, pin::Pin, time::Duration}; +use std::{ + collections::{HashMap, HashSet, VecDeque}, + pin::Pin, + time::Duration, +}; -use futures::{FutureExt, StreamExt, channel::oneshot, stream::FuturesUnordered, select, Future}; +use futures::{channel::oneshot, select, stream::FuturesUnordered, Future, FutureExt, StreamExt}; use sp_core::Pair; -use polkadot_primitives::v1::{ - AuthorityDiscoveryId, CandidateHash, CandidateReceipt, CollatorPair, CoreIndex, CoreState, GroupIndex, Hash, - Id as ParaId, -}; -use polkadot_subsystem::{ - overseer, - FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, jaeger, - messages::{ - CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeMessage, - }, -}; use polkadot_node_network_protocol::{ - OurView, PeerId, UnifiedReputationChange as Rep, View, peer_set::PeerSet, + peer_set::PeerSet, request_response::{ - IncomingRequest, request::OutgoingResponse, v1::{CollationFetchingRequest, CollationFetchingResponse} + request::OutgoingResponse, + v1::{CollationFetchingRequest, CollationFetchingResponse}, + IncomingRequest, }, - v1 as protocol_v1, + v1 as protocol_v1, OurView, PeerId, UnifiedReputationChange as Rep, View, }; +use polkadot_node_primitives::{PoV, SignedFullStatement, Statement}; use polkadot_node_subsystem_util::{ - TimeoutExt, metrics::{self, prometheus}, - runtime::{RuntimeInfo, get_availability_cores, get_group_rotation_info} + runtime::{get_availability_cores, get_group_rotation_info, RuntimeInfo}, + TimeoutExt, +}; +use polkadot_primitives::v1::{ + AuthorityDiscoveryId, CandidateHash, CandidateReceipt, CollatorPair, CoreIndex, CoreState, + GroupIndex, Hash, Id as ParaId, +}; +use polkadot_subsystem::{ + jaeger, + messages::{CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeMessage}, + overseer, FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, }; -use polkadot_node_primitives::{SignedFullStatement, Statement, PoV}; -use crate::error::{Fatal, NonFatal, log_error}; -use super::{LOG_TARGET, Result}; +use super::{Result, LOG_TARGET}; +use crate::error::{log_error, Fatal, NonFatal}; #[cfg(test)] mod tests; const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("An unexpected message"); -const COST_APPARENT_FLOOD: Rep = Rep::CostMinor("Message received when previous one was still being processed"); +const COST_APPARENT_FLOOD: Rep = + Rep::CostMinor("Message received when previous one was still being processed"); /// Time after starting an upload to a validator we will start another one to the next validator, /// even if the upload was not finished yet. @@ -102,9 +107,9 @@ struct MetricsInner { } impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) - -> std::result::Result - { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { let metrics = MetricsInner { advertisements_made: prometheus::register( prometheus::Counter::new( @@ -128,12 +133,10 @@ impl metrics::Metrics for Metrics { registry, )?, process_msg: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_collator_protocol_collator_process_msg", - "Time spent within `collator_protocol_collator::process_msg`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_collator_protocol_collator_process_msg", + "Time spent within `collator_protocol_collator::process_msg`", + ))?, registry, )?, }; @@ -157,8 +160,11 @@ struct ValidatorGroup { impl ValidatorGroup { /// Returns `true` if we should advertise our collation to the given peer. - fn should_advertise_to(&self, peer_ids: &HashMap, peer: &PeerId) - -> bool { + fn should_advertise_to( + &self, + peer_ids: &HashMap, + peer: &PeerId, + ) -> bool { match peer_ids.get(peer) { Some(discovery_id) => !self.advertised_to.contains(discovery_id), None => false, @@ -166,7 +172,11 @@ impl ValidatorGroup { } /// Should be called after we advertised our collation to the given `peer` to keep track of it. - fn advertised_to_peer(&mut self, peer_ids: &HashMap, peer: &PeerId) { + fn advertised_to_peer( + &mut self, + peer_ids: &HashMap, + peer: &PeerId, + ) { if let Some(validator_id) = peer_ids.get(peer) { self.advertised_to.insert(validator_id.clone()); } @@ -175,10 +185,7 @@ impl ValidatorGroup { impl From> for ValidatorGroup { fn from(discovery_ids: HashSet) -> Self { - Self { - discovery_ids, - advertised_to: HashSet::new(), - } + Self { discovery_ids, advertised_to: HashSet::new() } } } @@ -229,7 +236,8 @@ struct WaitingCollationFetches { waiting_peers: HashSet, } -type ActiveCollationFetches = FuturesUnordered + Send + 'static>>>; +type ActiveCollationFetches = + FuturesUnordered + Send + 'static>>>; struct State { /// Our network peer id. @@ -344,12 +352,12 @@ where "distribute collation message parent is outside of our view", ); - return Ok(()); + return Ok(()) } // We have already seen collation for this relay parent. if state.collations.contains_key(&relay_parent) { - return Ok(()); + return Ok(()) } // Determine which core the para collated-on is assigned to. @@ -365,12 +373,12 @@ where ); return Ok(()) - } + }, }; // Determine the group on that core and the next group on that core. let (current_validators, next_validators) = - determine_our_validators(ctx, runtime, our_core, num_cores, relay_parent,).await?; + determine_our_validators(ctx, runtime, our_core, num_cores, relay_parent).await?; if current_validators.validators.is_empty() && next_validators.validators.is_empty() { tracing::warn!( @@ -379,7 +387,7 @@ where "there are no validators assigned to core", ); - return Ok(()); + return Ok(()) } tracing::debug!( @@ -394,16 +402,19 @@ where "Accepted collation, connecting to validators." ); - let validator_group: HashSet<_> = current_validators.validators.iter().map(Clone::clone).collect(); + let validator_group: HashSet<_> = + current_validators.validators.iter().map(Clone::clone).collect(); // Issue a discovery request for the validators of the current group and the next group: connect_to_validators( ctx, - current_validators.validators + current_validators + .validators .into_iter() .chain(next_validators.validators.into_iter()) .collect(), - ).await; + ) + .await; state.our_validators_groups.insert(relay_parent, validator_group.into()); @@ -411,7 +422,9 @@ where state.collation_result_senders.insert(receipt.hash(), result_sender); } - state.collations.insert(relay_parent, Collation { receipt, pov, status: CollationStatus::Created }); + state + .collations + .insert(relay_parent, Collation { receipt, pov, status: CollationStatus::Created }); let interested = state.peers_interested_in_leaf(&relay_parent); // Make sure already connected peers get collations: @@ -438,7 +451,7 @@ where for (idx, core) in cores.iter().enumerate() { if let CoreState::Scheduled(occupied) = core { if occupied.para_id == para_id { - return Ok(Some(((idx as u32).into(), cores.len()))); + return Ok(Some(((idx as u32).into(), cores.len()))) } } } @@ -470,7 +483,8 @@ where Context: overseer::SubsystemContext, { let session_index = runtime.get_session_index(ctx.sender(), relay_parent).await?; - let info = &runtime.get_session_info_by_index(ctx.sender(), relay_parent, session_index) + let info = &runtime + .get_session_info_by_index(ctx.sender(), relay_parent, session_index) .await? .session_info; tracing::debug!(target: LOG_TARGET, ?session_index, "Received session info"); @@ -478,34 +492,31 @@ where let rotation_info = get_group_rotation_info(ctx, relay_parent).await?; let current_group_index = rotation_info.group_for_core(core_index, cores); - let current_validators = groups.get(current_group_index.0 as usize).map(|v| v.as_slice()).unwrap_or_default(); + let current_validators = groups + .get(current_group_index.0 as usize) + .map(|v| v.as_slice()) + .unwrap_or_default(); let next_group_idx = (current_group_index.0 as usize + 1) % groups.len(); let next_validators = groups.get(next_group_idx).map(|v| v.as_slice()).unwrap_or_default(); let validators = &info.discovery_keys; - let current_validators = current_validators.iter().map(|i| validators[i.0 as usize].clone()).collect(); - let next_validators = next_validators.iter().map(|i| validators[i.0 as usize].clone()).collect(); + let current_validators = + current_validators.iter().map(|i| validators[i.0 as usize].clone()).collect(); + let next_validators = + next_validators.iter().map(|i| validators[i.0 as usize].clone()).collect(); - let current_validators = GroupValidators { - group: current_group_index, - validators: current_validators, - }; - let next_validators = GroupValidators { - group: GroupIndex(next_group_idx as u32), - validators: next_validators, - }; + let current_validators = + GroupValidators { group: current_group_index, validators: current_validators }; + let next_validators = + GroupValidators { group: GroupIndex(next_group_idx as u32), validators: next_validators }; Ok((current_validators, next_validators)) } /// Issue a `Declare` collation message to the given `peer`. -async fn declare( - ctx: &mut Context, - state: &mut State, - peer: PeerId, -) +async fn declare(ctx: &mut Context, state: &mut State, peer: PeerId) where Context: SubsystemContext, Context: overseer::SubsystemContext, @@ -519,21 +530,17 @@ where state.collator_pair.sign(&declare_signature_payload), ); - ctx.send_message( - NetworkBridgeMessage::SendCollationMessage( - vec![peer], - protocol_v1::CollationProtocol::CollatorProtocol(wire_message), - ) - ).await; + ctx.send_message(NetworkBridgeMessage::SendCollationMessage( + vec![peer], + protocol_v1::CollationProtocol::CollatorProtocol(wire_message), + )) + .await; } } /// Issue a connection request to a set of validators and /// revoke the previous connection request. -async fn connect_to_validators( - ctx: &mut Context, - validator_ids: Vec, -) +async fn connect_to_validators(ctx: &mut Context, validator_ids: Vec) where Context: SubsystemContext, Context: overseer::SubsystemContext, @@ -542,8 +549,11 @@ where // will reissue a new request on new collation let (failed, _) = oneshot::channel(); ctx.send_message(NetworkBridgeMessage::ConnectToValidators { - validator_ids, peer_set: PeerSet::Collation, failed, - }).await; + validator_ids, + peer_set: PeerSet::Collation, + failed, + }) + .await; } /// Advertise collation to the given `peer`. @@ -555,12 +565,12 @@ async fn advertise_collation( state: &mut State, relay_parent: Hash, peer: PeerId, -) -where +) where Context: SubsystemContext, Context: overseer::SubsystemContext, { - let should_advertise = state.our_validators_groups + let should_advertise = state + .our_validators_groups .get(&relay_parent) .map(|g| g.should_advertise_to(&state.peer_ids, &peer)) .unwrap_or(false); @@ -583,7 +593,7 @@ where "Not advertising collation as we already advertised it to this validator.", ); return - } + }, (Some(collation), true) => { tracing::debug!( target: LOG_TARGET, @@ -595,16 +605,13 @@ where }, } - let wire_message = protocol_v1::CollatorProtocolMessage::AdvertiseCollation( - relay_parent, - ); + let wire_message = protocol_v1::CollatorProtocolMessage::AdvertiseCollation(relay_parent); - ctx.send_message( - NetworkBridgeMessage::SendCollationMessage( - vec![peer.clone()], - protocol_v1::CollationProtocol::CollatorProtocol(wire_message), - ) - ).await; + ctx.send_message(NetworkBridgeMessage::SendCollationMessage( + vec![peer.clone()], + protocol_v1::CollationProtocol::CollatorProtocol(wire_message), + )) + .await; if let Some(validators) = state.our_validators_groups.get_mut(&relay_parent) { validators.advertised_to_peer(&state.peer_ids, &peer); @@ -631,10 +638,12 @@ where match msg { CollateOn(id) => { state.collating_on = Some(id); - } + }, DistributeCollation(receipt, pov, result_sender) => { - let _span1 = state.span_per_relay_parent - .get(&receipt.descriptor.relay_parent).map(|s| s.child("distributing-collation")); + let _span1 = state + .span_per_relay_parent + .get(&receipt.descriptor.relay_parent) + .map(|s| s.child("distributing-collation")); let _span2 = jaeger::Span::new(&pov, "distributing-collation"); match state.collating_on { Some(id) if receipt.descriptor.para_id != id => { @@ -646,32 +655,28 @@ where collating_on = %id, "DistributeCollation for unexpected para_id", ); - } + }, Some(id) => { - distribute_collation(ctx, runtime, state, id, receipt, pov, result_sender).await?; - } + distribute_collation(ctx, runtime, state, id, receipt, pov, result_sender) + .await?; + }, None => { tracing::warn!( target: LOG_TARGET, para_id = %receipt.descriptor.para_id, "DistributeCollation message while not collating on any", ); - } + }, } - } + }, ReportCollator(_) => { tracing::warn!( target: LOG_TARGET, "ReportCollator message is not expected on the collator side of the protocol", ); - } + }, NetworkBridgeUpdateV1(event) => { - if let Err(e) = handle_network_msg( - ctx, - runtime, - state, - event, - ).await { + if let Err(e) = handle_network_msg(ctx, runtime, state, event).await { tracing::warn!( target: LOG_TARGET, err = ?e, @@ -680,11 +685,16 @@ where } }, CollationFetchingRequest(incoming) => { - let _span = state.span_per_relay_parent.get(&incoming.payload.relay_parent).map(|s| s.child("request-collation")); + let _span = state + .span_per_relay_parent + .get(&incoming.payload.relay_parent) + .map(|s| s.child("request-collation")); match state.collating_on { - Some(our_para_id) => { + Some(our_para_id) => if our_para_id == incoming.payload.para_id { - let (receipt, pov) = if let Some(collation) = state.collations.get_mut(&incoming.payload.relay_parent) { + let (receipt, pov) = if let Some(collation) = + state.collations.get_mut(&incoming.payload.relay_parent) + { collation.status.advance_to_requested(); (collation.receipt.clone(), collation.pov.clone()) } else { @@ -694,23 +704,28 @@ where "received a `RequestCollation` for a relay parent we don't have collation stored.", ); - return Ok(()); + return Ok(()) }; state.metrics.on_collation_sent_requested(); let _span = _span.as_ref().map(|s| s.child("sending")); - let waiting = state.waiting_collation_fetches.entry(incoming.payload.relay_parent).or_default(); + let waiting = state + .waiting_collation_fetches + .entry(incoming.payload.relay_parent) + .or_default(); if !waiting.waiting_peers.insert(incoming.peer) { tracing::debug!( target: LOG_TARGET, "Dropping incoming request as peer has a request in flight already." ); - ctx.send_message( - NetworkBridgeMessage::ReportPeer(incoming.peer, COST_APPARENT_FLOOD) - ).await; + ctx.send_message(NetworkBridgeMessage::ReportPeer( + incoming.peer, + COST_APPARENT_FLOOD, + )) + .await; return Ok(()) } @@ -727,17 +742,16 @@ where our_para_id = %our_para_id, "received a `CollationFetchingRequest` for unexpected para_id", ); - } - } + }, None => { tracing::warn!( target: LOG_TARGET, for_para_id = %incoming.payload.para_id, "received a `RequestCollation` while not collating on any para", ); - } + }, } - } + }, _ => {}, } @@ -763,24 +777,24 @@ async fn send_collation( }; if let Err(_) = request.send_outgoing_response(response) { - tracing::warn!( - target: LOG_TARGET, - "Sending collation response failed", - ); + tracing::warn!(target: LOG_TARGET, "Sending collation response failed",); } - state.active_collation_fetches.push(async move { - let r = rx.timeout(MAX_UNSHARED_UPLOAD_TIME).await; - if r.is_none() { - tracing::debug!( - target: LOG_TARGET, - ?relay_parent, - ?peer_id, - "Sending collation to validator timed out, carrying on with next validator." - ); + state.active_collation_fetches.push( + async move { + let r = rx.timeout(MAX_UNSHARED_UPLOAD_TIME).await; + if r.is_none() { + tracing::debug!( + target: LOG_TARGET, + ?relay_parent, + ?peer_id, + "Sending collation to validator timed out, carrying on with next validator." + ); + } + (relay_parent, peer_id) } - (relay_parent, peer_id) - }.boxed()); + .boxed(), + ); state.metrics.on_collation_sent(); } @@ -808,10 +822,9 @@ where ); // If we are declared to, this is another collator, and we should disconnect. - ctx.send_message( - NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation) - ).await; - } + ctx.send_message(NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation)) + .await; + }, AdvertiseCollation(_) => { tracing::trace!( target: LOG_TARGET, @@ -819,15 +832,16 @@ where "AdvertiseCollation message is not expected on the collator side of the protocol", ); - ctx.send_message( - NetworkBridgeMessage::ReportPeer(origin.clone(), COST_UNEXPECTED_MESSAGE) - ).await; + ctx.send_message(NetworkBridgeMessage::ReportPeer( + origin.clone(), + COST_UNEXPECTED_MESSAGE, + )) + .await; // If we are advertised to, this is another collator, and we should disconnect. - ctx.send_message( - NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation) - ).await; - } + ctx.send_message(NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation)) + .await; + }, CollationSeconded(relay_parent, statement) => { if !matches!(statement.unchecked_payload(), Statement::Seconded(_)) { tracing::warn!( @@ -837,12 +851,13 @@ where "Collation seconded message received with none-seconded statement.", ); } else { - let statement = runtime.check_signature(ctx.sender(), relay_parent, statement) + let statement = runtime + .check_signature(ctx.sender(), relay_parent, statement) .await? .map_err(NonFatal::InvalidStatementSignature)?; - let removed = state.collation_result_senders - .remove(&statement.payload().candidate_hash()); + let removed = + state.collation_result_senders.remove(&statement.payload().candidate_hash()); if let Some(sender) = removed { tracing::trace!( @@ -854,7 +869,7 @@ where let _ = sender.send(statement); } } - } + }, } Ok(()) @@ -866,8 +881,7 @@ async fn handle_peer_view_change( state: &mut State, peer_id: PeerId, view: View, -) -where +) where Context: SubsystemContext, Context: overseer::SubsystemContext, { @@ -899,12 +913,7 @@ where PeerConnected(peer_id, observed_role, maybe_authority) => { // If it is possible that a disconnected validator would attempt a reconnect // it should be handled here. - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - ?observed_role, - "Peer connected", - ); + tracing::trace!(target: LOG_TARGET, ?peer_id, ?observed_role, "Peer connected",); if let Some(authority) = maybe_authority { tracing::trace!( target: LOG_TARGET, @@ -916,49 +925,33 @@ where declare(ctx, state, peer_id).await; } - } + }, PeerViewChange(peer_id, view) => { - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - ?view, - "Peer view change", - ); + tracing::trace!(target: LOG_TARGET, ?peer_id, ?view, "Peer view change",); handle_peer_view_change(ctx, state, peer_id, view).await; - } + }, PeerDisconnected(peer_id) => { - tracing::trace!( - target: LOG_TARGET, - ?peer_id, - "Peer disconnected", - ); + tracing::trace!(target: LOG_TARGET, ?peer_id, "Peer disconnected",); state.peer_views.remove(&peer_id); state.peer_ids.remove(&peer_id); - } + }, OurViewChange(view) => { - tracing::trace!( - target: LOG_TARGET, - ?view, - "Own view change", - ); + tracing::trace!(target: LOG_TARGET, ?view, "Own view change",); handle_our_view_change(state, view).await?; - } + }, PeerMessage(remote, msg) => { handle_incoming_peer_message(ctx, runtime, state, remote, msg).await?; - } + }, NewGossipTopology(..) => { // impossibru! - } + }, } Ok(()) } /// Handles our view changes. -async fn handle_our_view_change( - state: &mut State, - view: OurView, -) -> Result<()> { +async fn handle_our_view_change(state: &mut State, view: OurView) -> Result<()> { for removed in state.view.difference(&view) { tracing::debug!(target: LOG_TARGET, relay_parent = ?removed, "Removing relay parent because our view changed."); @@ -983,7 +976,7 @@ async fn handle_our_view_change( candidate_hash = ?collation.receipt.hash(), pov_hash = ?collation.pov.hash(), "Collation was requested.", - ) + ), } } state.our_validators_groups.remove(removed); @@ -1005,7 +998,7 @@ pub(crate) async fn run( ) -> Result<()> where Context: SubsystemContext, - Context: overseer::SubsystemContext + Context: overseer::SubsystemContext, { use OverseerSignal::*; diff --git a/polkadot/node/network/collator-protocol/src/collator_side/tests.rs b/polkadot/node/network/collator-protocol/src/collator_side/tests.rs index cb97da8b939..acb96749e8b 100644 --- a/polkadot/node/network/collator-protocol/src/collator_side/tests.rs +++ b/polkadot/node/network/collator-protocol/src/collator_side/tests.rs @@ -26,21 +26,17 @@ use sp_core::{crypto::Pair, Decode}; use sp_keyring::Sr25519Keyring; use sp_runtime::traits::AppVerify; -use polkadot_node_network_protocol::{ - our_view, - view, - request_response::request::IncomingRequest, -}; +use polkadot_node_network_protocol::{our_view, request_response::request::IncomingRequest, view}; +use polkadot_node_primitives::BlockData; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_primitives::v1::{ - AuthorityDiscoveryId, CandidateDescriptor, CollatorPair, GroupRotationInfo, ScheduledCore, SessionIndex, - SessionInfo, ValidatorId, ValidatorIndex, + AuthorityDiscoveryId, CandidateDescriptor, CollatorPair, GroupRotationInfo, ScheduledCore, + SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, }; -use polkadot_node_primitives::BlockData; use polkadot_subsystem::{ jaeger, messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, - ActiveLeavesUpdate, ActivatedLeaf, LeafStatus, + ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, }; use polkadot_subsystem_testhelpers as test_helpers; @@ -103,22 +99,17 @@ impl Default for TestState { let validator_public = validator_pubkeys(&validators); let discovery_keys = validator_authority_id(&validators); - let validator_peer_id = std::iter::repeat_with(|| PeerId::random()) - .take(discovery_keys.len()) - .collect(); + let validator_peer_id = + std::iter::repeat_with(|| PeerId::random()).take(discovery_keys.len()).collect(); let validator_groups = vec![vec![2, 0, 4], vec![3, 2, 4]] - .into_iter().map(|g| g.into_iter().map(ValidatorIndex).collect()).collect(); - let group_rotation_info = GroupRotationInfo { - session_start_block: 0, - group_rotation_frequency: 100, - now: 1, - }; + .into_iter() + .map(|g| g.into_iter().map(ValidatorIndex).collect()) + .collect(); + let group_rotation_info = + GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 100, now: 1 }; - let availability_core = CoreState::Scheduled(ScheduledCore { - para_id, - collator: None, - }); + let availability_core = CoreState::Scheduled(ScheduledCore { para_id, collator: None }); let relay_parent = Hash::random(); @@ -155,7 +146,10 @@ impl TestState { } fn current_group_validator_peer_ids(&self) -> Vec { - self.current_group_validator_indices().iter().map(|i| self.validator_peer_id[i.0 as usize].clone()).collect() + self.current_group_validator_indices() + .iter() + .map(|i| self.validator_peer_id[i.0 as usize].clone()) + .collect() } fn current_group_validator_authority_ids(&self) -> Vec { @@ -169,7 +163,11 @@ impl TestState { /// /// If `merge_views == true` it means the subsystem will be informed that we are working on the old `relay_parent` /// and the new one. - async fn advance_to_new_round(&mut self, virtual_overseer: &mut VirtualOverseer, merge_views: bool) { + async fn advance_to_new_round( + &mut self, + virtual_overseer: &mut VirtualOverseer, + merge_views: bool, + ) { let old_relay_parent = self.relay_parent; while self.relay_parent == old_relay_parent { @@ -184,8 +182,11 @@ impl TestState { overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(our_view)), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view, + )), + ) + .await; } } @@ -202,14 +203,8 @@ fn test_harness>( ) { let _ = env_logger::builder() .is_test(true) - .filter( - Some("polkadot_collator_protocol"), - log::LevelFilter::Trace, - ) - .filter( - Some(LOG_TARGET), - log::LevelFilter::Trace, - ) + .filter(Some("polkadot_collator_protocol"), log::LevelFilter::Trace) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) .try_init(); let pool = sp_core::testing::TaskExecutor::new(); @@ -223,18 +218,20 @@ fn test_harness>( futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer_signal(&mut overseer, OverseerSignal::Conclude).await; - }, subsystem)).1.unwrap(); + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); } const TIMEOUT: Duration = Duration::from_millis(100); -async fn overseer_send( - overseer: &mut VirtualOverseer, - msg: CollatorProtocolMessage, -) { +async fn overseer_send(overseer: &mut VirtualOverseer, msg: CollatorProtocolMessage) { tracing::trace!(?msg, "sending message"); overseer .send(FromOverseer::Communication { msg }) @@ -243,9 +240,7 @@ async fn overseer_send( .expect(&format!("{:?} is more than enough for sending messages.", TIMEOUT)); } -async fn overseer_recv( - overseer: &mut VirtualOverseer, -) -> AllMessages { +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { let msg = overseer_recv_with_timeout(overseer, TIMEOUT) .await .expect(&format!("{:?} is more than enough to receive messages", TIMEOUT)); @@ -260,16 +255,10 @@ async fn overseer_recv_with_timeout( timeout: Duration, ) -> Option { tracing::trace!("waiting for message..."); - overseer - .recv() - .timeout(timeout) - .await + overseer.recv().timeout(timeout).await } -async fn overseer_signal( - overseer: &mut VirtualOverseer, - signal: OverseerSignal, -) { +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { overseer .send(FromOverseer::Signal(signal)) .timeout(TIMEOUT) @@ -279,10 +268,7 @@ async fn overseer_signal( // Setup the system by sending the `CollateOn`, `ActiveLeaves` and `OurViewChange` messages. async fn setup_system(virtual_overseer: &mut VirtualOverseer, test_state: &TestState) { - overseer_send( - virtual_overseer, - CollatorProtocolMessage::CollateOn(test_state.para_id), - ).await; + overseer_send(virtual_overseer, CollatorProtocolMessage::CollateOn(test_state.para_id)).await; overseer_signal( virtual_overseer, @@ -292,14 +278,16 @@ async fn setup_system(virtual_overseer: &mut VirtualOverseer, test_state: &TestS status: LeafStatus::Fresh, span: Arc::new(jaeger::Span::Disabled), })), - ).await; + ) + .await; overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent]), - ), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; } /// Result of [`distribute_collation`] @@ -316,9 +304,7 @@ async fn distribute_collation( should_connect: bool, ) -> DistributeCollation { // Now we want to distribute a PoVBlock - let pov_block = PoV { - block_data: BlockData(vec![42, 43, 44]), - }; + let pov_block = PoV { block_data: BlockData(vec![42, 43, 44]) }; let pov_hash = pov_block.hash(); @@ -327,12 +313,14 @@ async fn distribute_collation( relay_parent: test_state.relay_parent, pov_hash, ..Default::default() - }.build(); + } + .build(); overseer_send( virtual_overseer, CollatorProtocolMessage::DistributeCollation(candidate.clone(), pov_block.clone(), None), - ).await; + ) + .await; // obtain the availability cores. assert_matches!( @@ -355,7 +343,7 @@ async fn distribute_collation( )) => { assert_eq!(relay_parent, test_state.relay_parent); tx.send(Ok(test_state.current_session_index())).unwrap(); - } + }, AllMessages::RuntimeApi(RuntimeApiMessage::Request( relay_parent, @@ -365,22 +353,22 @@ async fn distribute_collation( assert_eq!(index, test_state.current_session_index()); tx.send(Ok(Some(test_state.session_info.clone()))).unwrap(); - } + }, AllMessages::RuntimeApi(RuntimeApiMessage::Request( relay_parent, - RuntimeApiRequest::ValidatorGroups(tx) + RuntimeApiRequest::ValidatorGroups(tx), )) => { assert_eq!(relay_parent, test_state.relay_parent); tx.send(Ok(( test_state.session_info.validator_groups.clone(), test_state.group_rotation_info.clone(), - ))).unwrap(); + ))) + .unwrap(); // This call is mandatory - we are done: - break; - } - other => - panic!("Unexpected message received: {:?}", other), + break + }, + other => panic!("Unexpected message received: {:?}", other), } } @@ -395,35 +383,33 @@ async fn distribute_collation( ); } - DistributeCollation { - candidate, - pov_block, - } + DistributeCollation { candidate, pov_block } } /// Connect a peer async fn connect_peer( virtual_overseer: &mut VirtualOverseer, peer: PeerId, - authority_id: Option + authority_id: Option, ) { overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer.clone(), - polkadot_node_network_protocol::ObservedRole::Authority, - authority_id, - ), - ), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected( + peer.clone(), + polkadot_node_network_protocol::ObservedRole::Authority, + authority_id, + )), + ) + .await; overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer, view![]), - ), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer, + view![], + )), + ) + .await; } /// Disconnect a peer @@ -431,7 +417,8 @@ async fn disconnect_peer(virtual_overseer: &mut VirtualOverseer, peer: PeerId) { overseer_send( virtual_overseer, CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(peer)), - ).await; + ) + .await; } /// Check that the next received message is a `Declare` message. @@ -496,13 +483,19 @@ async fn expect_advertise_collation_msg( } /// Send a message that the given peer's view changed. -async fn send_peer_view_change(virtual_overseer: &mut VirtualOverseer, peer: &PeerId, hashes: Vec) { +async fn send_peer_view_change( + virtual_overseer: &mut VirtualOverseer, + peer: &PeerId, + hashes: Vec, +) { overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer.clone(), View::new(hashes, 0)), - ), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer.clone(), + View::new(hashes, 0), + )), + ) + .await; } #[test] @@ -519,7 +512,8 @@ fn advertise_and_send_collation() { let DistributeCollation { candidate, pov_block } = distribute_collation(&mut virtual_overseer, &test_state, true).await; - for (val, peer) in test_state.current_group_validator_authority_ids() + for (val, peer) in test_state + .current_group_validator_authority_ids() .into_iter() .zip(test_state.current_group_validator_peer_ids()) { @@ -546,33 +540,31 @@ fn advertise_and_send_collation() { let (tx, rx) = oneshot::channel(); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::CollationFetchingRequest( - IncomingRequest::new( + CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new( + peer, + CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + }, + tx, + )), + ) + .await; + // Second request by same validator should get dropped and peer reported: + { + let (tx, rx) = oneshot::channel(); + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new( peer, CollationFetchingRequest { relay_parent: test_state.relay_parent, para_id: test_state.para_id, }, tx, - ) + )), ) - ).await; - // Second request by same validator should get dropped and peer reported: - { - let (tx, rx) = oneshot::channel(); - overseer_send( - &mut virtual_overseer, - CollatorProtocolMessage::CollationFetchingRequest( - IncomingRequest::new( - peer, - CollationFetchingRequest { - relay_parent: test_state.relay_parent, - para_id: test_state.para_id, - }, - tx, - ) - ) - ).await; + .await; assert_matches!( overseer_recv(&mut virtual_overseer).await, AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(bad_peer, _)) => { @@ -609,17 +601,16 @@ fn advertise_and_send_collation() { let (tx, rx) = oneshot::channel(); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::CollationFetchingRequest( - IncomingRequest::new( - peer, - CollationFetchingRequest { - relay_parent: old_relay_parent, - para_id: test_state.para_id, - }, - tx, - ) - ) - ).await; + CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new( + peer, + CollationFetchingRequest { + relay_parent: old_relay_parent, + para_id: test_state.para_id, + }, + tx, + )), + ) + .await; // Re-requesting collation should fail: rx.await.unwrap_err(); @@ -630,13 +621,12 @@ fn advertise_and_send_collation() { // Send info about peer's view. overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange( - peer.clone(), - view![test_state.relay_parent], - ) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange( + peer.clone(), + view![test_state.relay_parent], + )), + ) + .await; expect_advertise_collation_msg(&mut virtual_overseer, &peer, test_state.relay_parent).await; virtual_overseer @@ -646,29 +636,26 @@ fn advertise_and_send_collation() { #[test] fn send_only_one_collation_per_relay_parent_at_a_time() { test_validator_send_sequence(|mut second_response_receiver, feedback_first_tx| async move { - Delay::new(Duration::from_millis(100)).await; - assert!( - second_response_receiver.try_recv().unwrap().is_none(), - "We should not have send the collation yet to the second validator", - ); + Delay::new(Duration::from_millis(100)).await; + assert!( + second_response_receiver.try_recv().unwrap().is_none(), + "We should not have send the collation yet to the second validator", + ); - // Signal that the collation fetch is finished - feedback_first_tx.send(()).expect("Sending collation fetch finished"); - second_response_receiver - } - ); + // Signal that the collation fetch is finished + feedback_first_tx.send(()).expect("Sending collation fetch finished"); + second_response_receiver + }); } #[test] fn send_next_collation_after_max_unshared_upload_time() { test_validator_send_sequence(|second_response_receiver, _| async move { - Delay::new(MAX_UNSHARED_UPLOAD_TIME + Duration::from_millis(50)).await; - second_response_receiver - } - ); + Delay::new(MAX_UNSHARED_UPLOAD_TIME + Duration::from_millis(50)).await; + second_response_receiver + }); } - #[test] fn collators_declare_to_connected_peers() { let test_state = TestState::default(); @@ -721,7 +708,8 @@ fn collations_are_only_advertised_to_validators_with_correct_view() { distribute_collation(&mut virtual_overseer, &test_state, true).await; - expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent).await; + expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent) + .await; // The other validator announces that it changed its view. send_peer_view_change(&mut virtual_overseer, &peer, vec![test_state.relay_parent]).await; @@ -772,7 +760,8 @@ fn collate_on_two_different_relay_chain_blocks() { send_peer_view_change(&mut virtual_overseer, &peer2, vec![test_state.relay_parent]).await; - expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent).await; + expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent) + .await; virtual_overseer }) } @@ -833,17 +822,16 @@ fn collators_reject_declare_messages() { overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer.clone(), - protocol_v1::CollatorProtocolMessage::Declare( - collator_pair2.public(), - ParaId::from(5), - collator_pair2.sign(b"garbage"), - ), - ) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage( + peer.clone(), + protocol_v1::CollatorProtocolMessage::Declare( + collator_pair2.public(), + ParaId::from(5), + collator_pair2.sign(b"garbage"), + ), + )), + ) + .await; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -868,7 +856,7 @@ fn collators_reject_declare_messages() { fn test_validator_send_sequence(handle_first_response: T) where T: FnOnce(oneshot::Receiver, oneshot::Sender<()>) -> F, - F: Future> + F: Future>, { let test_state = TestState::default(); let local_peer_id = test_state.local_peer_id.clone(); @@ -882,7 +870,8 @@ where let DistributeCollation { candidate, pov_block } = distribute_collation(&mut virtual_overseer, &test_state, true).await; - for (val, peer) in test_state.current_group_validator_authority_ids() + for (val, peer) in test_state + .current_group_validator_authority_ids() .into_iter() .zip(test_state.current_group_validator_peer_ids()) { @@ -900,29 +889,40 @@ where let validator_1 = test_state.current_group_validator_peer_ids()[1].clone(); // Send info about peer's view. - send_peer_view_change(&mut virtual_overseer, &validator_0, vec![test_state.relay_parent]).await; - send_peer_view_change(&mut virtual_overseer, &validator_1, vec![test_state.relay_parent]).await; + send_peer_view_change(&mut virtual_overseer, &validator_0, vec![test_state.relay_parent]) + .await; + send_peer_view_change(&mut virtual_overseer, &validator_1, vec![test_state.relay_parent]) + .await; // The peer is interested in a leaf that we have a collation for; // advertise it. - expect_advertise_collation_msg(&mut virtual_overseer, &validator_0, test_state.relay_parent).await; - expect_advertise_collation_msg(&mut virtual_overseer, &validator_1, test_state.relay_parent).await; + expect_advertise_collation_msg( + &mut virtual_overseer, + &validator_0, + test_state.relay_parent, + ) + .await; + expect_advertise_collation_msg( + &mut virtual_overseer, + &validator_1, + test_state.relay_parent, + ) + .await; // Request a collation. let (tx, rx) = oneshot::channel(); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::CollationFetchingRequest( - IncomingRequest::new( - validator_0, - CollationFetchingRequest { - relay_parent: test_state.relay_parent, - para_id: test_state.para_id, - }, - tx, - ) - ) - ).await; + CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new( + validator_0, + CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + }, + tx, + )), + ) + .await; // Keep the feedback channel alive because we need to use it to inform about the finished transfer. let feedback_tx = assert_matches!( @@ -945,17 +945,16 @@ where let (tx, rx) = oneshot::channel(); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::CollationFetchingRequest( - IncomingRequest::new( - validator_1, - CollationFetchingRequest { - relay_parent: test_state.relay_parent, - para_id: test_state.para_id, - }, - tx, - ) - ) - ).await; + CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new( + validator_1, + CollationFetchingRequest { + relay_parent: test_state.relay_parent, + para_id: test_state.para_id, + }, + tx, + )), + ) + .await; let rx = handle_first_response(rx, feedback_tx).await; diff --git a/polkadot/node/network/collator-protocol/src/error.rs b/polkadot/node/network/collator-protocol/src/error.rs index 06fb60d0343..aded43d74d1 100644 --- a/polkadot/node/network/collator-protocol/src/error.rs +++ b/polkadot/node/network/collator-protocol/src/error.rs @@ -21,7 +21,7 @@ use polkadot_node_primitives::UncheckedSignedFullStatement; use polkadot_subsystem::errors::SubsystemError; use thiserror::Error; -use polkadot_node_subsystem_util::{Fault, runtime, unwrap_non_fatal}; +use polkadot_node_subsystem_util::{runtime, unwrap_non_fatal, Fault}; use crate::LOG_TARGET; @@ -82,9 +82,7 @@ pub enum NonFatal { /// /// We basically always want to try and continue on error. This utility function is meant to /// consume top-level errors by simply logging them. -pub fn log_error(result: Result<()>, ctx: &'static str) - -> FatalResult<()> -{ +pub fn log_error(result: Result<()>, ctx: &'static str) -> FatalResult<()> { if let Some(error) = unwrap_non_fatal(result.map_err(|e| e.0))? { tracing::warn!(target: LOG_TARGET, error = ?error, ctx) } diff --git a/polkadot/node/network/collator-protocol/src/lib.rs b/polkadot/node/network/collator-protocol/src/lib.rs index 96af19aa1e5..12305fd0957 100644 --- a/polkadot/node/network/collator-protocol/src/lib.rs +++ b/polkadot/node/network/collator-protocol/src/lib.rs @@ -18,7 +18,7 @@ //! This subsystem implements both sides of the collator protocol. #![deny(missing_docs, unused_crate_dependencies)] -#![recursion_limit="256"] +#![recursion_limit = "256"] use std::time::Duration; @@ -30,14 +30,9 @@ use polkadot_node_network_protocol::{PeerId, UnifiedReputationChange as Rep}; use polkadot_primitives::v1::CollatorPair; use polkadot_subsystem::{ - SpawnedSubsystem, - SubsystemContext, - SubsystemSender, - overseer, - messages::{ - CollatorProtocolMessage, NetworkBridgeMessage, - }, errors::SubsystemError, + messages::{CollatorProtocolMessage, NetworkBridgeMessage}, + overseer, SpawnedSubsystem, SubsystemContext, SubsystemSender, }; mod error; @@ -92,29 +87,19 @@ impl CollatorProtocolSubsystem { /// If `id` is `None` this is a validator side of the protocol. /// Caller must provide a registry for prometheus metrics. pub fn new(protocol_side: ProtocolSide) -> Self { - Self { - protocol_side, - } + Self { protocol_side } } async fn run(self, ctx: Context) -> Result<()> where - Context: overseer::SubsystemContext, - Context: SubsystemContext, + Context: overseer::SubsystemContext, + Context: SubsystemContext, { match self.protocol_side { - ProtocolSide::Validator { keystore, eviction_policy, metrics } => validator_side::run( - ctx, - keystore, - eviction_policy, - metrics, - ).await, - ProtocolSide::Collator(local_peer_id, collator_pair, metrics) => collator_side::run( - ctx, - local_peer_id, - collator_pair, - metrics, - ).await, + ProtocolSide::Validator { keystore, eviction_policy, metrics } => + validator_side::run(ctx, keystore, eviction_policy, metrics).await, + ProtocolSide::Collator(local_peer_id, collator_pair, metrics) => + collator_side::run(ctx, local_peer_id, collator_pair, metrics).await, } } } @@ -131,10 +116,7 @@ where .map_err(|e| SubsystemError::with_origin("collator-protocol", e)) .boxed(); - SpawnedSubsystem { - name: "collator-protocol-subsystem", - future, - } + SpawnedSubsystem { name: "collator-protocol-subsystem", future } } } @@ -150,7 +132,5 @@ where "reputation change for peer", ); - ctx.send_message( - NetworkBridgeMessage::ReportPeer(peer, rep), - ).await; + ctx.send_message(NetworkBridgeMessage::ReportPeer(peer, rep)).await; } diff --git a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs index 3795c0488b6..577d0fb91b8 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs @@ -14,39 +14,44 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::{collections::{HashMap, HashSet}, sync::Arc, task::Poll}; -use std::collections::hash_map::Entry; -use std::time::{Duration, Instant}; use always_assert::never; use futures::{ - channel::oneshot, future::{BoxFuture, Fuse, FusedFuture}, FutureExt, StreamExt, - stream::FuturesUnordered, select, + channel::oneshot, + future::{BoxFuture, Fuse, FusedFuture}, + select, + stream::FuturesUnordered, + FutureExt, StreamExt, }; use futures_timer::Delay; +use std::{ + collections::{hash_map::Entry, HashMap, HashSet}, + sync::Arc, + task::Poll, + time::{Duration, Instant}, +}; use sp_keystore::SyncCryptoStorePtr; use polkadot_node_network_protocol::{ - request_response as req_res, v1 as protocol_v1, peer_set::PeerSet, + request_response as req_res, request_response::{ request::{Recipient, RequestError}, v1::{CollationFetchingRequest, CollationFetchingResponse}, OutgoingRequest, Requests, }, - OurView, PeerId, UnifiedReputationChange as Rep, View, + v1 as protocol_v1, OurView, PeerId, UnifiedReputationChange as Rep, View, }; -use polkadot_node_primitives::{SignedFullStatement, PoV}; +use polkadot_node_primitives::{PoV, SignedFullStatement}; use polkadot_node_subsystem_util::metrics::{self, prometheus}; use polkadot_primitives::v1::{CandidateReceipt, CollatorId, Hash, Id as ParaId}; use polkadot_subsystem::{ - overseer, jaeger, messages::{ - CollatorProtocolMessage, IfDisconnected, - NetworkBridgeEvent, NetworkBridgeMessage, CandidateBackingMessage, + CandidateBackingMessage, CollatorProtocolMessage, IfDisconnected, NetworkBridgeEvent, + NetworkBridgeMessage, }, - FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, SubsystemSender, + overseer, FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, SubsystemSender, }; use super::{modify_reputation, Result, LOG_TARGET}; @@ -64,7 +69,8 @@ const COST_INVALID_SIGNATURE: Rep = Rep::Malicious("Invalid network message sign const COST_REPORT_BAD: Rep = Rep::Malicious("A collator was reported by another subsystem"); const COST_WRONG_PARA: Rep = Rep::Malicious("A collator provided a collation for the wrong para"); const COST_UNNEEDED_COLLATOR: Rep = Rep::CostMinor("An unneeded collator connected"); -const BENEFIT_NOTIFY_GOOD: Rep = Rep::BenefitMinor("A collator was noted good by another subsystem"); +const BENEFIT_NOTIFY_GOOD: Rep = + Rep::BenefitMinor("A collator was noted good by another subsystem"); /// Time after starting a collation download from a collator we will start another one from the /// next collator even if the upload was not finished yet. @@ -105,13 +111,19 @@ impl Metrics { } /// Provide a timer for `handle_collation_request_result` which observes on drop. - fn time_handle_collation_request_result(&self) -> Option { - self.0.as_ref().map(|metrics| metrics.handle_collation_request_result.start_timer()) + fn time_handle_collation_request_result( + &self, + ) -> Option { + self.0 + .as_ref() + .map(|metrics| metrics.handle_collation_request_result.start_timer()) } /// Note the current number of collator peers. fn note_collator_peer_count(&self, collator_peers: usize) { - self.0.as_ref().map(|metrics| metrics.collator_peer_count.set(collator_peers as u64)); + self.0 + .as_ref() + .map(|metrics| metrics.collator_peer_count.set(collator_peers as u64)); } } @@ -124,9 +136,9 @@ struct MetricsInner { } impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) - -> std::result::Result - { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { let metrics = MetricsInner { collation_requests: prometheus::register( prometheus::CounterVec::new( @@ -210,10 +222,7 @@ struct PeerData { impl PeerData { fn new(view: View) -> Self { - PeerData { - view, - state: PeerState::Connected(Instant::now()), - } + PeerData { view, state: PeerState::Connected(Instant::now()) } } /// Update the view, clearing all advertisements that are no longer in the @@ -241,20 +250,17 @@ impl PeerData { &mut self, on_relay_parent: Hash, our_view: &View, - ) - -> std::result::Result<(CollatorId, ParaId), AdvertisementError> - { + ) -> std::result::Result<(CollatorId, ParaId), AdvertisementError> { match self.state { PeerState::Connected(_) => Err(AdvertisementError::UndeclaredCollator), _ if !our_view.contains(&on_relay_parent) => Err(AdvertisementError::OutOfOurView), - PeerState::Collating(ref mut state) => { + PeerState::Collating(ref mut state) => if state.advertisements.insert(on_relay_parent) { state.last_active = Instant::now(); Ok((state.collator_id.clone(), state.para_id.clone())) } else { Err(AdvertisementError::Duplicate) - } - } + }, } } @@ -305,7 +311,8 @@ impl PeerData { fn is_inactive(&self, policy: &crate::CollatorEvictionPolicy) -> bool { match self.state { PeerState::Connected(connected_at) => connected_at.elapsed() >= policy.undeclared, - PeerState::Collating(ref state) => state.last_active.elapsed() >= policy.inactive_collator, + PeerState::Collating(ref state) => + state.last_active.elapsed() >= policy.inactive_collator, } } } @@ -325,7 +332,7 @@ struct GroupAssignments { struct ActiveParas { relay_parent_assignments: HashMap, current_assignments: HashMap, - next_assignments: HashMap + next_assignments: HashMap, } impl ActiveParas { @@ -350,7 +357,6 @@ impl ActiveParas { .map(|x| x.ok()) .flatten(); - let mc = polkadot_node_subsystem_util::request_availability_cores(relay_parent, sender) .await .await @@ -368,38 +374,32 @@ impl ActiveParas { ); continue - } + }, }; - let (para_now, para_next) = match polkadot_node_subsystem_util - ::signing_key_and_index(&validators, keystore) - .await - .and_then(|(_, index)| polkadot_node_subsystem_util::find_validator_group( - &groups, - index, - )) - { - Some(group) => { - let next_rotation_info = rotation_info.bump_rotation(); - - let core_now = rotation_info.core_for_group(group, cores.len()); - let core_next = next_rotation_info.core_for_group(group, cores.len()); - - ( - cores.get(core_now.0 as usize).and_then(|c| c.para_id()), - cores.get(core_next.0 as usize).and_then(|c| c.para_id()), - ) - } - None => { - tracing::trace!( - target: LOG_TARGET, - ?relay_parent, - "Not a validator", - ); - - continue - } - }; + let (para_now, para_next) = + match polkadot_node_subsystem_util::signing_key_and_index(&validators, keystore) + .await + .and_then(|(_, index)| { + polkadot_node_subsystem_util::find_validator_group(&groups, index) + }) { + Some(group) => { + let next_rotation_info = rotation_info.bump_rotation(); + + let core_now = rotation_info.core_for_group(group, cores.len()); + let core_next = next_rotation_info.core_for_group(group, cores.len()); + + ( + cores.get(core_now.0 as usize).and_then(|c| c.para_id()), + cores.get(core_next.0 as usize).and_then(|c| c.para_id()), + ) + }, + None => { + tracing::trace!(target: LOG_TARGET, ?relay_parent, "Not a validator",); + + continue + }, + }; // This code won't work well, if at all for parathreads. For parathreads we'll // have to be aware of which core the parathread claim is going to be multiplexed @@ -426,17 +426,12 @@ impl ActiveParas { *self.next_assignments.entry(para_next).or_default() += 1; } - self.relay_parent_assignments.insert( - relay_parent, - GroupAssignments { current: para_now, next: para_next }, - ); + self.relay_parent_assignments + .insert(relay_parent, GroupAssignments { current: para_now, next: para_next }); } } - fn remove_outgoing( - &mut self, - old_relay_parents: impl IntoIterator, - ) { + fn remove_outgoing(&mut self, old_relay_parents: impl IntoIterator) { for old_relay_parent in old_relay_parents { if let Some(assignments) = self.relay_parent_assignments.remove(&old_relay_parent) { let GroupAssignments { current, next } = assignments; @@ -482,16 +477,19 @@ struct PendingCollation { impl PendingCollation { fn new(relay_parent: Hash, para_id: &ParaId, peer_id: &PeerId) -> Self { - Self { relay_parent, para_id: para_id.clone(), peer_id: peer_id.clone(), commitments_hash: None } + Self { + relay_parent, + para_id: para_id.clone(), + peer_id: peer_id.clone(), + commitments_hash: None, + } } } type CollationEvent = (CollatorId, PendingCollation); -type PendingCollationFetch = ( - CollationEvent, - std::result::Result<(CandidateReceipt, PoV), oneshot::Canceled>, -); +type PendingCollationFetch = + (CollationEvent, std::result::Result<(CandidateReceipt, PoV), oneshot::Canceled>); /// The status of the collations in [`CollationsPerRelayParent`]. #[derive(Debug, Clone, Copy)] @@ -567,7 +565,7 @@ impl CollationsPerRelayParent { let next = self.unfetched_collations.pop(); self.waiting_collation = next.as_ref().map(|(_, collator_id)| collator_id.clone()); next - } + }, CollationStatus::WaitingOnValidation | CollationStatus::Fetching => unreachable!("We have reset the status above!"), } @@ -622,20 +620,18 @@ fn collator_peer_id( peer_data: &HashMap, collator_id: &CollatorId, ) -> Option { - peer_data.iter() - .find_map(|(peer, data)| - data.collator_id().filter(|c| c == &collator_id).map(|_| peer.clone()) - ) + peer_data.iter().find_map(|(peer, data)| { + data.collator_id().filter(|c| c == &collator_id).map(|_| peer.clone()) + }) } async fn disconnect_peer(ctx: &mut Context, peer_id: PeerId) where - Context: overseer::SubsystemContext, - Context: SubsystemContext, + Context: overseer::SubsystemContext, + Context: SubsystemContext, { - ctx.send_message( - NetworkBridgeMessage::DisconnectPeer(peer_id, PeerSet::Collation) - ).await + ctx.send_message(NetworkBridgeMessage::DisconnectPeer(peer_id, PeerSet::Collation)) + .await } /// Another subsystem has requested to fetch collations on a particular leaf for some para. @@ -644,10 +640,9 @@ async fn fetch_collation( state: &mut State, pc: PendingCollation, id: CollatorId, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { let (tx, rx) = oneshot::channel(); @@ -657,7 +652,9 @@ where Delay::new(MAX_UNSHARED_DOWNLOAD_TIME).await; (collator_id, relay_parent) }; - state.collation_fetch_timeouts.push(timeout(id.clone(), relay_parent.clone()).boxed()); + state + .collation_fetch_timeouts + .push(timeout(id.clone(), relay_parent.clone()).boxed()); if state.peer_data.get(&peer_id).map_or(false, |d| d.has_advertised(&relay_parent)) { request_collation(ctx, state, relay_parent, para_id, peer_id, tx).await; @@ -671,9 +668,8 @@ async fn report_collator( ctx: &mut Context, peer_data: &HashMap, id: CollatorId, -) -where - Context: SubsystemContext +) where + Context: SubsystemContext, { if let Some(peer_id) = collator_peer_id(peer_data, &id) { modify_reputation(ctx, peer_id, COST_REPORT_BAD).await; @@ -685,10 +681,9 @@ async fn note_good_collation( ctx: &mut Context, peer_data: &HashMap, id: CollatorId, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { if let Some(peer_id) = collator_peer_id(peer_data, &id) { modify_reputation(ctx, peer_id, BENEFIT_NOTIFY_GOOD).await; @@ -701,18 +696,17 @@ async fn notify_collation_seconded( peer_id: PeerId, relay_parent: Hash, statement: SignedFullStatement, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { - let wire_message = protocol_v1::CollatorProtocolMessage::CollationSeconded(relay_parent, statement.into()); - ctx.send_message( - NetworkBridgeMessage::SendCollationMessage( - vec![peer_id], - protocol_v1::CollationProtocol::CollatorProtocol(wire_message), - ) - ).await; + let wire_message = + protocol_v1::CollatorProtocolMessage::CollationSeconded(relay_parent, statement.into()); + ctx.send_message(NetworkBridgeMessage::SendCollationMessage( + vec![peer_id], + protocol_v1::CollationProtocol::CollatorProtocol(wire_message), + )) + .await; modify_reputation(ctx, peer_id, BENEFIT_NOTIFY_GOOD).await; } @@ -720,15 +714,12 @@ where /// A peer's view has changed. A number of things should be done: /// - Ongoing collation requests have to be canceled. /// - Advertisements by this peer that are no longer relevant have to be removed. -async fn handle_peer_view_change( - state: &mut State, - peer_id: PeerId, - view: View, -) -> Result<()> { +async fn handle_peer_view_change(state: &mut State, peer_id: PeerId, view: View) -> Result<()> { let peer_data = state.peer_data.entry(peer_id.clone()).or_default(); peer_data.update_view(view); - state.requested_collations + state + .requested_collations .retain(|pc, _| pc.peer_id != peer_id || !peer_data.has_advertised(&pc.relay_parent)); Ok(()) @@ -747,10 +738,9 @@ async fn request_collation( para_id: ParaId, peer_id: PeerId, result: oneshot::Sender<(CandidateReceipt, PoV)>, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { if !state.view.contains(&relay_parent) { tracing::debug!( @@ -760,7 +750,7 @@ where relay_parent = %relay_parent, "collation is no longer in view", ); - return; + return } let pending_collation = PendingCollation::new(relay_parent, ¶_id, &peer_id); if state.requested_collations.contains_key(&pending_collation) { @@ -771,29 +761,27 @@ where ?pending_collation.relay_parent, "collation has already been requested", ); - return; + return } - let (full_request, response_recv) = - OutgoingRequest::new(Recipient::Peer(peer_id), CollationFetchingRequest { - relay_parent, - para_id, - }); + let (full_request, response_recv) = OutgoingRequest::new( + Recipient::Peer(peer_id), + CollationFetchingRequest { relay_parent, para_id }, + ); let requests = Requests::CollationFetching(full_request); let per_request = PerRequest { from_collator: response_recv.boxed().fuse(), to_requester: result, - span: state.span_per_relay_parent.get(&relay_parent).map(|s| { - s.child("collation-request") - .with_para_id(para_id) - }), + span: state + .span_per_relay_parent + .get(&relay_parent) + .map(|s| s.child("collation-request").with_para_id(para_id)), }; - state.requested_collations.insert( - PendingCollation::new(relay_parent, ¶_id, &peer_id), - per_request - ); + state + .requested_collations + .insert(PendingCollation::new(relay_parent, ¶_id, &peer_id), per_request); tracing::debug!( target: LOG_TARGET, @@ -803,9 +791,11 @@ where "Requesting collation", ); - ctx.send_message( - NetworkBridgeMessage::SendRequests(vec![requests], IfDisconnected::ImmediateError) - ).await; + ctx.send_message(NetworkBridgeMessage::SendRequests( + vec![requests], + IfDisconnected::ImmediateError, + )) + .await; } /// Networking message has been received. @@ -814,10 +804,9 @@ async fn process_incoming_peer_message( state: &mut State, origin: PeerId, msg: protocol_v1::CollatorProtocolMessage, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { use protocol_v1::CollatorProtocolMessage::*; use sp_runtime::traits::AppVerify; @@ -833,7 +822,7 @@ where None => { modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await; return - } + }, }; if peer_data.is_collating() { @@ -869,9 +858,12 @@ where tracing::trace!(target: LOG_TARGET, "Disconnecting unneeded collator"); disconnect_peer(ctx, origin).await; } - } + }, AdvertiseCollation(relay_parent) => { - let _span = state.span_per_relay_parent.get(&relay_parent).map(|s| s.child("advertise-collation")); + let _span = state + .span_per_relay_parent + .get(&relay_parent) + .map(|s| s.child("advertise-collation")); if !state.view.contains(&relay_parent) { tracing::debug!( target: LOG_TARGET, @@ -881,14 +873,14 @@ where ); modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await; - return; + return } let peer_data = match state.peer_data.get_mut(&origin) { None => { modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await; - return; - } + return + }, Some(p) => p, }; @@ -902,13 +894,10 @@ where "Received advertise collation", ); - let pending_collation = PendingCollation::new( - relay_parent, - ¶_id, - &origin, - ); + let pending_collation = PendingCollation::new(relay_parent, ¶_id, &origin); - let collations = state.collations_per_relay_parent.entry(relay_parent).or_default(); + let collations = + state.collations_per_relay_parent.entry(relay_parent).or_default(); match collations.status { CollationStatus::Fetching | CollationStatus::WaitingOnValidation => @@ -921,7 +910,7 @@ where }, CollationStatus::Seconded => {}, } - } + }, Err(error) => { tracing::debug!( target: LOG_TARGET, @@ -932,33 +921,26 @@ where ); modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await; - } + }, } - } + }, CollationSeconded(_, _) => { tracing::warn!( target: LOG_TARGET, peer_id = ?origin, "Unexpected `CollationSeconded` message, decreasing reputation", ); - } + }, } } /// A leaf has become inactive so we want to /// - Cancel all ongoing collation requests that are on top of that leaf. /// - Remove all stored collations relevant to that leaf. -async fn remove_relay_parent( - state: &mut State, - relay_parent: Hash, -) -> Result<()> { - state.requested_collations.retain(|k, _| { - k.relay_parent != relay_parent - }); +async fn remove_relay_parent(state: &mut State, relay_parent: Hash) -> Result<()> { + state.requested_collations.retain(|k, _| k.relay_parent != relay_parent); - state.pending_candidates.retain(|k, _| { - k != &relay_parent - }); + state.pending_candidates.retain(|k, _| k != &relay_parent); state.collations_per_relay_parent.remove(&relay_parent); Ok(()) @@ -972,12 +954,13 @@ async fn handle_our_view_change( view: OurView, ) -> Result<()> where - Context: overseer::SubsystemContext, - Context: SubsystemContext, + Context: overseer::SubsystemContext, + Context: SubsystemContext, { let old_view = std::mem::replace(&mut state.view, view); - let added: HashMap> = state.view + let added: HashMap> = state + .view .span_per_head() .iter() .filter(|v| !old_view.contains(&v.0)) @@ -989,10 +972,7 @@ where }); let added = state.view.difference(&old_view).cloned().collect::>(); - let removed = old_view - .difference(&state.view) - .cloned() - .collect::>(); + let removed = old_view.difference(&state.view).cloned().collect::>(); for removed in removed.iter().cloned() { remove_relay_parent(state, removed).await?; @@ -1028,8 +1008,8 @@ async fn handle_network_msg( bridge_message: NetworkBridgeEvent, ) -> Result<()> where - Context: overseer::SubsystemContext, - Context: SubsystemContext, + Context: overseer::SubsystemContext, + Context: SubsystemContext, { use NetworkBridgeEvent::*; @@ -1044,7 +1024,7 @@ where }, NewGossipTopology(..) => { // impossibru! - } + }, PeerViewChange(peer_id, view) => { handle_peer_view_change(state, peer_id, view).await?; }, @@ -1053,7 +1033,7 @@ where }, PeerMessage(remote, msg) => { process_incoming_peer_message(ctx, state, remote, msg).await; - } + }, } Ok(()) @@ -1065,10 +1045,9 @@ async fn process_msg( keystore: &SyncCryptoStorePtr, msg: CollatorProtocolMessage, state: &mut State, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { use CollatorProtocolMessage::*; @@ -1081,36 +1060,31 @@ where para_id = %id, "CollateOn message is not expected on the validator side of the protocol", ); - } + }, DistributeCollation(_, _, _) => { tracing::warn!( target: LOG_TARGET, "DistributeCollation message is not expected on the validator side of the protocol", ); - } + }, ReportCollator(id) => { report_collator(ctx, &state.peer_data, id).await; - } + }, NetworkBridgeUpdateV1(event) => { - if let Err(e) = handle_network_msg( - ctx, - state, - keystore, - event, - ).await { + if let Err(e) = handle_network_msg(ctx, state, keystore, event).await { tracing::warn!( target: LOG_TARGET, err = ?e, "Failed to handle incoming network message", ); } - } + }, CollationFetchingRequest(_) => { tracing::warn!( target: LOG_TARGET, "CollationFetchingRequest message is not expected on the validator side of the protocol", ); - } + }, Seconded(parent, stmt) => { if let Some(collation_event) = state.pending_candidates.remove(&parent) { let (collator_id, pending_collation) = collation_event; @@ -1128,11 +1102,13 @@ where "Collation has been seconded, but the relay parent is deactivated", ); } - } + }, Invalid(parent, candidate_receipt) => { let id = match state.pending_candidates.entry(parent) { Entry::Occupied(entry) - if entry.get().1.commitments_hash == Some(candidate_receipt.commitments_hash) => entry.remove().0, + if entry.get().1.commitments_hash == + Some(candidate_receipt.commitments_hash) => + entry.remove().0, Entry::Occupied(_) => { tracing::error!( target: LOG_TARGET, @@ -1141,14 +1117,14 @@ where "Reported invalid candidate for unknown `pending_candidate`!", ); return - } + }, Entry::Vacant(_) => return, }; report_collator(ctx, &state.peer_data, id.clone()).await; dequeue_next_collation_and_fetch(ctx, state, parent, id).await; - } + }, } } @@ -1172,20 +1148,18 @@ pub(crate) async fn run( metrics: Metrics, ) -> Result<()> where - Context: overseer::SubsystemContext, - Context: SubsystemContext, + Context: overseer::SubsystemContext, + Context: SubsystemContext, { use OverseerSignal::*; - let mut state = State { - metrics, - ..Default::default() - }; + let mut state = State { metrics, ..Default::default() }; - let next_inactivity_stream = futures::stream::unfold( - Instant::now() + ACTIVITY_POLL, - |next_check| async move { Some(((), wait_until_next_check(next_check).await)) } - ).fuse(); + let next_inactivity_stream = + futures::stream::unfold(Instant::now() + ACTIVITY_POLL, |next_check| async move { + Some(((), wait_until_next_check(next_check).await)) + }) + .fuse(); futures::pin_mut!(next_inactivity_stream); @@ -1227,8 +1201,13 @@ where for (pending_collation, per_req) in state.requested_collations.iter_mut() { // Despite the await, this won't block on the response itself. let finished = poll_collation_response( - &mut ctx, &state.metrics, &state.span_per_relay_parent, pending_collation, per_req, - ).await; + &mut ctx, + &state.metrics, + &state.span_per_relay_parent, + pending_collation, + per_req, + ) + .await; if !finished { retained_requested.insert(pending_collation.clone()); } @@ -1240,13 +1219,15 @@ where /// Dequeue another collation and fetch. async fn dequeue_next_collation_and_fetch( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), state: &mut State, relay_parent: Hash, // The collator we tried to fetch from last. previous_fetch: CollatorId, ) { - if let Some((next, id)) = state.collations_per_relay_parent + if let Some((next, id)) = state + .collations_per_relay_parent .get_mut(&relay_parent) .and_then(|c| c.get_next_collation_to_fetch(Some(previous_fetch))) { @@ -1259,10 +1240,9 @@ async fn handle_collation_fetched_result( ctx: &mut Context, state: &mut State, (mut collation_event, res): PendingCollationFetch, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { // If no prior collation for this relay parent has been seconded, then // memoize the collation_event for that relay_parent, such that we may @@ -1301,13 +1281,12 @@ where if let Entry::Vacant(entry) = state.pending_candidates.entry(relay_parent) { collation_event.1.commitments_hash = Some(candidate_receipt.commitments_hash); - ctx.send_message( - CandidateBackingMessage::Second( - relay_parent.clone(), - candidate_receipt, - pov, - ) - ).await; + ctx.send_message(CandidateBackingMessage::Second( + relay_parent.clone(), + candidate_receipt, + pov, + )) + .await; entry.insert(collation_event); } else { @@ -1327,10 +1306,9 @@ async fn disconnect_inactive_peers( ctx: &mut Context, eviction_policy: &crate::CollatorEvictionPolicy, peers: &HashMap, -) -where - Context: overseer::SubsystemContext, - Context: SubsystemContext, +) where + Context: overseer::SubsystemContext, + Context: SubsystemContext, { for (peer, peer_data) in peers { if peer_data.is_inactive(&eviction_policy) { @@ -1352,10 +1330,9 @@ async fn poll_collation_response( spans: &HashMap, pending_collation: &PendingCollation, per_req: &mut PerRequest, -) --> bool +) -> bool where - Context: overseer::SubsystemContext, + Context: overseer::SubsystemContext, Context: SubsystemContext, { if never!(per_req.from_collator.is_terminated()) { @@ -1367,8 +1344,9 @@ where } if let Poll::Ready(response) = futures::poll!(&mut per_req.from_collator) { - let _span = spans.get(&pending_collation.relay_parent) - .map(|s| s.child("received-collation")); + let _span = spans + .get(&pending_collation.relay_parent) + .map(|s| s.child("received-collation")); let _timer = metrics.time_handle_collation_request_result(); let mut metrics_result = Err(()); @@ -1384,12 +1362,9 @@ where err = ?err, "Collator provided response that could not be decoded" ); - modify_reputation( - ctx, - pending_collation.peer_id.clone(), - COST_CORRUPTED_MESSAGE - ).await; - } + modify_reputation(ctx, pending_collation.peer_id.clone(), COST_CORRUPTED_MESSAGE) + .await; + }, Err(RequestError::NetworkError(err)) => { tracing::warn!( target: LOG_TARGET, @@ -1404,7 +1379,7 @@ where // which would result in reduced reputation for proper nodes, but the // same can happen for penalties on timeouts, which we also have. modify_reputation(ctx, pending_collation.peer_id.clone(), COST_NETWORK_ERROR).await; - } + }, Err(RequestError::Canceled(_)) => { tracing::warn!( target: LOG_TARGET, @@ -1417,8 +1392,9 @@ where // sensible. In theory this could be exploited, by DoSing this node, // which would result in reduced reputation for proper nodes, but the // same can happen for penalties on timeouts, which we also have. - modify_reputation(ctx, pending_collation.peer_id.clone(), COST_REQUEST_TIMED_OUT).await; - } + modify_reputation(ctx, pending_collation.peer_id.clone(), COST_REQUEST_TIMED_OUT) + .await; + }, Ok(CollationFetchingResponse::Collation(receipt, _)) if receipt.descriptor().para_id != pending_collation.para_id => { @@ -1446,7 +1422,7 @@ where std::mem::swap(&mut tx, &mut (per_req.to_requester)); let result = tx.send((receipt, pov)); - if let Err(_) = result { + if let Err(_) = result { tracing::warn!( target: LOG_TARGET, hash = ?pending_collation.relay_parent, @@ -1458,7 +1434,7 @@ where metrics_result = Ok(()); success = "true"; } - } + }, }; metrics.on_request(metrics_result); per_req.span.as_mut().map(|s| s.add_string_tag("success", success)); diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests.rs index f122aca0b93..a4bc8cac682 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests.rs @@ -15,26 +15,26 @@ // along with Polkadot. If not, see . use super::*; -use std::{iter, time::Duration}; -use std::sync::Arc; +use assert_matches::assert_matches; use futures::{executor, future, Future}; use sp_core::{crypto::Pair, Encode}; -use sp_keystore::SyncCryptoStore; -use sp_keystore::testing::KeyStore as TestKeyStore; use sp_keyring::Sr25519Keyring; -use assert_matches::assert_matches; +use sp_keystore::{testing::KeyStore as TestKeyStore, SyncCryptoStore}; +use std::{iter, sync::Arc, time::Duration}; -use polkadot_primitives::v1::{ - CollatorPair, ValidatorId, ValidatorIndex, CoreState, CandidateDescriptor, - GroupRotationInfo, ScheduledCore, OccupiedCore, GroupIndex, +use polkadot_node_network_protocol::{ + our_view, + request_response::{Requests, ResponseSender}, + ObservedRole, }; use polkadot_node_primitives::BlockData; use polkadot_node_subsystem_util::TimeoutExt; -use polkadot_subsystem_testhelpers as test_helpers; -use polkadot_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}; -use polkadot_node_network_protocol::{ - our_view, ObservedRole, request_response::{Requests, ResponseSender}, +use polkadot_primitives::v1::{ + CandidateDescriptor, CollatorPair, CoreState, GroupIndex, GroupRotationInfo, OccupiedCore, + ScheduledCore, ValidatorId, ValidatorIndex, }; +use polkadot_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}; +use polkadot_subsystem_testhelpers as test_helpers; const ACTIVITY_TIMEOUT: Duration = Duration::from_millis(500); const DECLARE_TIMEOUT: Duration = Duration::from_millis(25); @@ -58,10 +58,7 @@ impl Default for TestState { let chain_ids = vec![chain_a, chain_b]; let relay_parent = Hash::repeat_byte(0x05); - let collators = iter::repeat(()) - .map(|_| CollatorPair::generate().0) - .take(5) - .collect(); + let collators = iter::repeat(()).map(|_| CollatorPair::generate().0).take(5).collect(); let validators = vec![ Sr25519Keyring::Alice, @@ -78,17 +75,11 @@ impl Default for TestState { vec![ValidatorIndex(4)], ]; - let group_rotation_info = GroupRotationInfo { - session_start_block: 0, - group_rotation_frequency: 1, - now: 0, - }; + let group_rotation_info = + GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 1, now: 0 }; let cores = vec![ - CoreState::Scheduled(ScheduledCore { - para_id: chain_ids[0], - collator: None, - }), + CoreState::Scheduled(ScheduledCore { para_id: chain_ids[0], collator: None }), CoreState::Free, CoreState::Occupied(OccupiedCore { next_up_on_available: None, @@ -129,14 +120,8 @@ struct TestHarness { fn test_harness>(test: impl FnOnce(TestHarness) -> T) { let _ = env_logger::builder() .is_test(true) - .filter( - Some("polkadot_collator_protocol"), - log::LevelFilter::Trace, - ) - .filter( - Some(LOG_TARGET), - log::LevelFilter::Trace, - ) + .filter(Some("polkadot_collator_protocol"), log::LevelFilter::Trace) + .filter(Some(LOG_TARGET), log::LevelFilter::Trace) .try_init(); let pool = sp_core::testing::TaskExecutor::new(); @@ -144,10 +129,12 @@ fn test_harness>(test: impl FnOnce(TestHarne let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); let keystore = TestKeyStore::new(); - keystore.sr25519_generate_new( - polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID, - Some(&Sr25519Keyring::Alice.to_seed()), - ).unwrap(); + keystore + .sr25519_generate_new( + polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); let subsystem = run( context, @@ -164,18 +151,20 @@ fn test_harness>(test: impl FnOnce(TestHarne futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer_signal(&mut overseer, OverseerSignal::Conclude).await; - }, subsystem)).1.unwrap(); + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer_signal(&mut overseer, OverseerSignal::Conclude).await; + }, + subsystem, + )) + .1 + .unwrap(); } const TIMEOUT: Duration = Duration::from_millis(200); -async fn overseer_send( - overseer: &mut VirtualOverseer, - msg: CollatorProtocolMessage, -) { +async fn overseer_send(overseer: &mut VirtualOverseer, msg: CollatorProtocolMessage) { tracing::trace!("Sending message:\n{:?}", &msg); overseer .send(FromOverseer::Communication { msg }) @@ -184,9 +173,7 @@ async fn overseer_send( .expect(&format!("{:?} is enough for sending messages.", TIMEOUT)); } -async fn overseer_recv( - overseer: &mut VirtualOverseer, -) -> AllMessages { +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { let msg = overseer_recv_with_timeout(overseer, TIMEOUT) .await .expect(&format!("{:?} is enough to receive messages.", TIMEOUT)); @@ -201,16 +188,10 @@ async fn overseer_recv_with_timeout( timeout: Duration, ) -> Option { tracing::trace!("Waiting for message..."); - overseer - .recv() - .timeout(timeout) - .await + overseer.recv().timeout(timeout).await } -async fn overseer_signal( - overseer: &mut VirtualOverseer, - signal: OverseerSignal, -) { +async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) { overseer .send(FromOverseer::Signal(signal)) .timeout(TIMEOUT) @@ -275,10 +256,7 @@ async fn assert_candidate_backing_second( } /// Assert that a collator got disconnected. -async fn assert_collator_disconnect( - virtual_overseer: &mut VirtualOverseer, - expected_peer: PeerId, -) { +async fn assert_collator_disconnect(virtual_overseer: &mut VirtualOverseer, expected_peer: PeerId) { assert_matches!( overseer_recv(virtual_overseer).await, AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer( @@ -324,28 +302,26 @@ async fn connect_and_declare_collator( ) { overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer.clone(), - ObservedRole::Full, - None, - ), - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected( + peer.clone(), + ObservedRole::Full, + None, + )), + ) + .await; overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer.clone(), - protocol_v1::CollatorProtocolMessage::Declare( - collator.public(), - para_id, - collator.sign(&protocol_v1::declare_signature_payload(&peer)), - ) - ) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage( + peer.clone(), + protocol_v1::CollatorProtocolMessage::Declare( + collator.public(), + para_id, + collator.sign(&protocol_v1::declare_signature_payload(&peer)), + ), + )), + ) + .await; } /// Advertise a collation. @@ -356,15 +332,12 @@ async fn advertise_collation( ) { overseer_send( virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer, - protocol_v1::CollatorProtocolMessage::AdvertiseCollation( - relay_parent, - ) - ) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage( + peer, + protocol_v1::CollatorProtocolMessage::AdvertiseCollation(relay_parent), + )), + ) + .await; } // As we receive a relevant advertisement act on it and issue a collation request. @@ -373,29 +346,39 @@ fn act_on_advertisement() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let pair = CollatorPair::generate().0; tracing::trace!("activating"); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; let peer_b = PeerId::random(); - connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await; + connect_and_declare_collator( + &mut virtual_overseer, + peer_b.clone(), + pair.clone(), + test_state.chain_ids[0], + ) + .await; advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await; - assert_fetch_collation_request(&mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0]).await; + assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + ) + .await; virtual_overseer }); @@ -407,16 +390,15 @@ fn collator_reporting_works() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; @@ -428,19 +410,22 @@ fn collator_reporting_works() { peer_b.clone(), test_state.collators[0].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; connect_and_declare_collator( &mut virtual_overseer, peer_c.clone(), test_state.collators[1].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; overseer_send( &mut virtual_overseer, CollatorProtocolMessage::ReportCollator(test_state.collators[0].public()), - ).await; + ) + .await; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -462,22 +447,19 @@ fn collator_authentication_verification_works() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let peer_b = PeerId::random(); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_b, - ObservedRole::Full, - None, - ), - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected( + peer_b, + ObservedRole::Full, + None, + )), + ) + .await; // the peer sends a declare message but sign the wrong payload overseer_send( @@ -521,18 +503,17 @@ fn fetch_collations_works() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let second = Hash::random(); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent, second]) - ), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent, second], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; @@ -545,14 +526,16 @@ fn fetch_collations_works() { peer_b.clone(), test_state.collators[0].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; connect_and_declare_collator( &mut virtual_overseer, peer_c.clone(), test_state.collators[1].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await; advertise_collation(&mut virtual_overseer, peer_c.clone(), test_state.relay_parent).await; @@ -561,7 +544,8 @@ fn fetch_collations_works() { &mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0], - ).await; + ) + .await; assert!( overseer_recv_with_timeout(&mut &mut virtual_overseer, Duration::from_millis(30)).await.is_none(), @@ -572,29 +556,35 @@ fn fetch_collations_works() { let mut candidate_a = CandidateReceipt::default(); candidate_a.descriptor.para_id = test_state.chain_ids[0]; candidate_a.descriptor.relay_parent = test_state.relay_parent; - response_channel.send(Ok( - CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ).encode() - )).expect("Sending response should succeed"); + response_channel + .send(Ok( + CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode() + )) + .expect("Sending response should succeed"); assert_candidate_backing_second( &mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0], &pov, - ).await; + ) + .await; overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(peer_b.clone())), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected( + peer_b.clone(), + )), + ) + .await; overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(peer_c.clone())), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected( + peer_c.clone(), + )), + ) + .await; let peer_b = PeerId::random(); let peer_c = PeerId::random(); @@ -605,32 +595,32 @@ fn fetch_collations_works() { peer_b.clone(), test_state.collators[2].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; connect_and_declare_collator( &mut virtual_overseer, peer_c.clone(), test_state.collators[3].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; connect_and_declare_collator( &mut virtual_overseer, peer_d.clone(), test_state.collators[4].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; advertise_collation(&mut virtual_overseer, peer_b.clone(), second).await; advertise_collation(&mut virtual_overseer, peer_c.clone(), second).await; advertise_collation(&mut virtual_overseer, peer_d.clone(), second).await; // Dropping the response channel should lead to fetching the second collation. - assert_fetch_collation_request( - &mut virtual_overseer, - second, - test_state.chain_ids[0], - ).await; + assert_fetch_collation_request(&mut virtual_overseer, second, test_state.chain_ids[0]) + .await; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -643,20 +633,16 @@ fn fetch_collations_works() { } ); - let response_channel_non_exclusive = assert_fetch_collation_request( - &mut virtual_overseer, - second, - test_state.chain_ids[0], - ).await; + let response_channel_non_exclusive = + assert_fetch_collation_request(&mut virtual_overseer, second, test_state.chain_ids[0]) + .await; // Third collator should receive response after that timeout: Delay::new(MAX_UNSHARED_DOWNLOAD_TIME + Duration::from_millis(50)).await; - let response_channel = assert_fetch_collation_request( - &mut virtual_overseer, - second, - test_state.chain_ids[0], - ).await; + let response_channel = + assert_fetch_collation_request(&mut virtual_overseer, second, test_state.chain_ids[0]) + .await; let pov = PoV { block_data: BlockData(vec![1]) }; let mut candidate_a = CandidateReceipt::default(); @@ -664,26 +650,25 @@ fn fetch_collations_works() { candidate_a.descriptor.relay_parent = second; // First request finishes now: - response_channel_non_exclusive.send(Ok( - CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ).encode() - )).expect("Sending response should succeed"); - - response_channel.send(Ok( - CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ).encode() - )).expect("Sending response should succeed"); + response_channel_non_exclusive + .send(Ok( + CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode() + )) + .expect("Sending response should succeed"); + + response_channel + .send(Ok( + CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode() + )) + .expect("Sending response should succeed"); assert_candidate_backing_second( &mut virtual_overseer, second, test_state.chain_ids[0], &pov, - ).await; + ) + .await; virtual_overseer }); @@ -695,18 +680,17 @@ fn fetch_next_collation_on_invalid_collation() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let second = Hash::random(); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent, second]) - ), - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent, second], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; @@ -719,14 +703,16 @@ fn fetch_next_collation_on_invalid_collation() { peer_b.clone(), test_state.collators[0].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; connect_and_declare_collator( &mut virtual_overseer, peer_c.clone(), test_state.collators[1].clone(), test_state.chain_ids[0].clone(), - ).await; + ) + .await; advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await; advertise_collation(&mut virtual_overseer, peer_c.clone(), test_state.relay_parent).await; @@ -735,28 +721,33 @@ fn fetch_next_collation_on_invalid_collation() { &mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0], - ).await; + ) + .await; let pov = PoV { block_data: BlockData(vec![]) }; let mut candidate_a = CandidateReceipt::default(); candidate_a.descriptor.para_id = test_state.chain_ids[0]; candidate_a.descriptor.relay_parent = test_state.relay_parent; - response_channel.send(Ok( - CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ).encode() - )).expect("Sending response should succeed"); + response_channel + .send(Ok( + CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode() + )) + .expect("Sending response should succeed"); let receipt = assert_candidate_backing_second( &mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0], &pov, - ).await; + ) + .await; // Inform that the candidate was invalid. - overseer_send(&mut virtual_overseer, CollatorProtocolMessage::Invalid(test_state.relay_parent, receipt)).await; + overseer_send( + &mut virtual_overseer, + CollatorProtocolMessage::Invalid(test_state.relay_parent, receipt), + ) + .await; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -774,7 +765,8 @@ fn fetch_next_collation_on_invalid_collation() { &mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0], - ).await; + ) + .await; virtual_overseer }); @@ -785,9 +777,7 @@ fn inactive_disconnected() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let pair = CollatorPair::generate().0; @@ -795,19 +785,31 @@ fn inactive_disconnected() { overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![hash_a]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![hash_a], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; let peer_b = PeerId::random(); - connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await; + connect_and_declare_collator( + &mut virtual_overseer, + peer_b.clone(), + pair.clone(), + test_state.chain_ids[0], + ) + .await; advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await; - assert_fetch_collation_request(&mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0]).await; + assert_fetch_collation_request( + &mut virtual_overseer, + test_state.relay_parent, + test_state.chain_ids[0], + ) + .await; Delay::new(ACTIVITY_TIMEOUT * 3).await; @@ -832,9 +834,7 @@ fn activity_extends_life() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let pair = CollatorPair::generate().0; @@ -844,10 +844,11 @@ fn activity_extends_life() { overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![hash_a, hash_b, hash_c]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![hash_a, hash_b, hash_c], + )), + ) + .await; // 3 heads, 3 times. respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; @@ -856,13 +857,20 @@ fn activity_extends_life() { let peer_b = PeerId::random(); - connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await; + connect_and_declare_collator( + &mut virtual_overseer, + peer_b.clone(), + pair.clone(), + test_state.chain_ids[0], + ) + .await; Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await; advertise_collation(&mut virtual_overseer, peer_b.clone(), hash_a).await; - assert_fetch_collation_request(&mut virtual_overseer, hash_a, test_state.chain_ids[0]).await; + assert_fetch_collation_request(&mut virtual_overseer, hash_a, test_state.chain_ids[0]) + .await; Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await; @@ -879,7 +887,8 @@ fn activity_extends_life() { } ); - assert_fetch_collation_request(&mut virtual_overseer, hash_b, test_state.chain_ids[0]).await; + assert_fetch_collation_request(&mut virtual_overseer, hash_b, test_state.chain_ids[0]) + .await; Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await; @@ -896,7 +905,8 @@ fn activity_extends_life() { } ); - assert_fetch_collation_request(&mut virtual_overseer, hash_c, test_state.chain_ids[0]).await; + assert_fetch_collation_request(&mut virtual_overseer, hash_c, test_state.chain_ids[0]) + .await; Delay::new(ACTIVITY_TIMEOUT * 3 / 2).await; @@ -922,16 +932,15 @@ fn disconnect_if_no_declare() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; @@ -939,14 +948,13 @@ fn disconnect_if_no_declare() { overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_b.clone(), - ObservedRole::Full, - None, - ) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected( + peer_b.clone(), + ObservedRole::Full, + None, + )), + ) + .await; assert_collator_disconnect(&mut virtual_overseer, peer_b.clone()).await; @@ -959,18 +967,17 @@ fn disconnect_if_wrong_declare() { let test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let pair = CollatorPair::generate().0; overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; @@ -978,28 +985,26 @@ fn disconnect_if_wrong_declare() { overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_b.clone(), - ObservedRole::Full, - None, - ) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected( + peer_b.clone(), + ObservedRole::Full, + None, + )), + ) + .await; overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer_b.clone(), - protocol_v1::CollatorProtocolMessage::Declare( - pair.public(), - ParaId::from(69), - pair.sign(&protocol_v1::declare_signature_payload(&peer_b)), - ) - ) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage( + peer_b.clone(), + protocol_v1::CollatorProtocolMessage::Declare( + pair.public(), + ParaId::from(69), + pair.sign(&protocol_v1::declare_signature_payload(&peer_b)), + ), + )), + ) + .await; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -1023,33 +1028,39 @@ fn view_change_clears_old_collators() { let mut test_state = TestState::default(); test_harness(|test_harness| async move { - let TestHarness { - mut virtual_overseer, - } = test_harness; + let TestHarness { mut virtual_overseer } = test_harness; let pair = CollatorPair::generate().0; overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![test_state.relay_parent], + )), + ) + .await; respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; let peer_b = PeerId::random(); - connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await; + connect_and_declare_collator( + &mut virtual_overseer, + peer_b.clone(), + pair.clone(), + test_state.chain_ids[0], + ) + .await; let hash_b = Hash::repeat_byte(69); overseer_send( &mut virtual_overseer, - CollatorProtocolMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::OurViewChange(our_view![hash_b]) - ) - ).await; + CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange( + our_view![hash_b], + )), + ) + .await; test_state.group_rotation_info = test_state.group_rotation_info.bump_rotation(); respond_to_core_info_queries(&mut virtual_overseer, &test_state).await; diff --git a/polkadot/node/network/dispute-distribution/src/error.rs b/polkadot/node/network/dispute-distribution/src/error.rs index 5c0690139d2..8d236ced431 100644 --- a/polkadot/node/network/dispute-distribution/src/error.rs +++ b/polkadot/node/network/dispute-distribution/src/error.rs @@ -19,11 +19,10 @@ use thiserror::Error; -use polkadot_node_subsystem_util::{Fault, runtime, unwrap_non_fatal}; +use polkadot_node_subsystem_util::{runtime, unwrap_non_fatal, Fault}; use polkadot_subsystem::SubsystemError; -use crate::LOG_TARGET; -use crate::sender; +use crate::{sender, LOG_TARGET}; #[derive(Debug, Error)] #[error(transparent)] @@ -53,7 +52,6 @@ impl From for Error { /// Fatal errors of this subsystem. #[derive(Debug, Error)] pub enum Fatal { - /// Receiving subsystem message from overseer failed. #[error("Receiving message from overseer failed")] SubsystemReceive(#[source] SubsystemError), @@ -91,9 +89,7 @@ pub type FatalResult = std::result::Result; /// /// We basically always want to try and continue on error. This utility function is meant to /// consume top-level errors by simply logging them -pub fn log_error(result: Result<()>, ctx: &'static str) - -> std::result::Result<(), Fatal> -{ +pub fn log_error(result: Result<()>, ctx: &'static str) -> std::result::Result<(), Fatal> { if let Some(error) = unwrap_non_fatal(result.map_err(|e| e.0))? { tracing::warn!(target: LOG_TARGET, error = ?error, ctx); } diff --git a/polkadot/node/network/dispute-distribution/src/lib.rs b/polkadot/node/network/dispute-distribution/src/lib.rs index 2f5d6de0a56..702639ff635 100644 --- a/polkadot/node/network/dispute-distribution/src/lib.rs +++ b/polkadot/node/network/dispute-distribution/src/lib.rs @@ -24,21 +24,17 @@ //! The sender is responsible for getting our vote out, see [`sender`]. The receiver handles //! incoming [`DisputeRequest`]s and offers spam protection, see [`receiver`]. -use futures::channel::{mpsc}; -use futures::{FutureExt, StreamExt, TryFutureExt}; +use futures::{channel::mpsc, FutureExt, StreamExt, TryFutureExt}; use polkadot_node_network_protocol::authority_discovery::AuthorityDiscovery; use sp_keystore::SyncCryptoStorePtr; use polkadot_node_primitives::DISPUTE_WINDOW; +use polkadot_node_subsystem_util::{runtime, runtime::RuntimeInfo}; use polkadot_subsystem::{ - overseer, messages::DisputeDistributionMessage, FromOverseer, OverseerSignal, SpawnedSubsystem, + messages::DisputeDistributionMessage, overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, }; -use polkadot_node_subsystem_util::{ - runtime, - runtime::RuntimeInfo, -}; /// ## The sender [`DisputeSender`] /// @@ -85,8 +81,7 @@ use self::receiver::DisputesReceiver; /// Error and [`Result`] type for this subsystem. mod error; -use error::{Fatal, FatalResult}; -use error::{Result, log_error}; +use error::{log_error, Fatal, FatalResult, Result}; #[cfg(test)] mod tests; @@ -119,7 +114,8 @@ impl overseer::Subsystem for DisputeDistri where Context: SubsystemContext + overseer::SubsystemContext - + Sync + Send, + + Sync + + Send, AD: AuthorityDiscovery + Clone, { fn start(self, ctx: Context) -> SpawnedSubsystem { @@ -128,10 +124,7 @@ where .map_err(|e| SubsystemError::with_origin("dispute-distribution", e)) .boxed(); - SpawnedSubsystem { - name: "dispute-distribution-subsystem", - future, - } + SpawnedSubsystem { name: "dispute-distribution-subsystem", future } } } @@ -155,7 +148,8 @@ where where Context: SubsystemContext + overseer::SubsystemContext - + Sync + Send, + + Sync + + Send, { loop { let message = MuxedMessage::receive(&mut ctx, &mut self.sender_rx).await; @@ -168,52 +162,43 @@ where Ok(SignalResult::Continue) => Ok(()), Err(f) => Err(f), } - } + }, FromOverseer::Communication { msg } => self.handle_subsystem_message(&mut ctx, msg).await, }; log_error(result, "on FromOverseer")?; - } + }, MuxedMessage::Sender(result) => { - self.disputes_sender.on_task_message( - result.ok_or(Fatal::SenderExhausted)? - ) - .await; - } + self.disputes_sender + .on_task_message(result.ok_or(Fatal::SenderExhausted)?) + .await; + }, } } } /// Handle overseer signals. - async fn handle_signals ( + async fn handle_signals( &mut self, ctx: &mut Context, signal: OverseerSignal, - ) -> Result - { + ) -> Result { match signal { - OverseerSignal::Conclude => - return Ok(SignalResult::Conclude), + OverseerSignal::Conclude => return Ok(SignalResult::Conclude), OverseerSignal::ActiveLeaves(update) => { - self.disputes_sender.update_leaves( - ctx, - &mut self.runtime, - update - ) - .await?; - } - OverseerSignal::BlockFinalized(_,_) => {} + self.disputes_sender.update_leaves(ctx, &mut self.runtime, update).await?; + }, + OverseerSignal::BlockFinalized(_, _) => {}, }; Ok(SignalResult::Continue) } /// Handle `DisputeDistributionMessage`s. - async fn handle_subsystem_message ( + async fn handle_subsystem_message( &mut self, ctx: &mut Context, - msg: DisputeDistributionMessage - ) -> Result<()> - { + msg: DisputeDistributionMessage, + ) -> Result<()> { match msg { DisputeDistributionMessage::SendDispute(dispute_msg) => self.disputes_sender.start_sender(ctx, &mut self.runtime, dispute_msg).await?, @@ -223,14 +208,12 @@ where ctx.sender().clone(), receiver, self.authority_discovery.clone(), - self.metrics.clone() + self.metrics.clone(), ); - ctx - .spawn("disputes-receiver", receiver.run().boxed(),) + ctx.spawn("disputes-receiver", receiver.run().boxed()) .map_err(Fatal::SpawnTask)?; }, - } Ok(()) } @@ -247,7 +230,8 @@ enum MuxedMessage { impl MuxedMessage { async fn receive( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), from_sender: &mut mpsc::Receiver, ) -> Self { // We are only fusing here to make `select` happy, in reality we will quit if the stream diff --git a/polkadot/node/network/dispute-distribution/src/metrics.rs b/polkadot/node/network/dispute-distribution/src/metrics.rs index 585c34a988d..9b891b47b79 100644 --- a/polkadot/node/network/dispute-distribution/src/metrics.rs +++ b/polkadot/node/network/dispute-distribution/src/metrics.rs @@ -14,9 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use polkadot_node_subsystem_util::metrics::prometheus::{Counter, U64, Registry, PrometheusError, CounterVec, Opts}; -use polkadot_node_subsystem_util::metrics::prometheus; -use polkadot_node_subsystem_util::metrics; +use polkadot_node_subsystem_util::{ + metrics, + metrics::{ + prometheus, + prometheus::{Counter, CounterVec, Opts, PrometheusError, Registry, U64}, + }, +}; /// Label for success counters. pub const SUCCEEDED: &'static str = "succeeded"; @@ -81,7 +85,7 @@ impl metrics::Metrics for Metrics { "parachain_dispute_distribution_sent_requests", "Total number of sent requests.", ), - &["success"] + &["success"], )?, registry, )?, @@ -98,7 +102,7 @@ impl metrics::Metrics for Metrics { "parachain_dispute_distribution_imported_requests", "Total number of imported requests.", ), - &["success"] + &["success"], )?, registry, )?, @@ -106,4 +110,3 @@ impl metrics::Metrics for Metrics { Ok(Metrics(Some(metrics))) } } - diff --git a/polkadot/node/network/dispute-distribution/src/receiver/error.rs b/polkadot/node/network/dispute-distribution/src/receiver/error.rs index 1106671c9ec..9134adf9576 100644 --- a/polkadot/node/network/dispute-distribution/src/receiver/error.rs +++ b/polkadot/node/network/dispute-distribution/src/receiver/error.rs @@ -19,9 +19,8 @@ use thiserror::Error; -use polkadot_node_network_protocol::PeerId; -use polkadot_node_network_protocol::request_response::request::ReceiveError; -use polkadot_node_subsystem_util::{Fault, runtime, unwrap_non_fatal}; +use polkadot_node_network_protocol::{request_response::request::ReceiveError, PeerId}; +use polkadot_node_subsystem_util::{runtime, unwrap_non_fatal, Fault}; use crate::LOG_TARGET; @@ -100,9 +99,7 @@ pub type NonFatalResult = std::result::Result; /// /// We basically always want to try and continue on error. This utility function is meant to /// consume top-level errors by simply logging them -pub fn log_error(result: Result<()>) - -> std::result::Result<(), Fatal> -{ +pub fn log_error(result: Result<()>) -> std::result::Result<(), Fatal> { if let Some(error) = unwrap_non_fatal(result.map_err(|e| e.0))? { tracing::warn!(target: LOG_TARGET, error = ?error); } diff --git a/polkadot/node/network/dispute-distribution/src/receiver/mod.rs b/polkadot/node/network/dispute-distribution/src/receiver/mod.rs index a01afae91bf..1d7c61164ac 100644 --- a/polkadot/node/network/dispute-distribution/src/receiver/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/receiver/mod.rs @@ -14,47 +14,43 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use std::{ + collections::HashSet, + pin::Pin, + task::{Context, Poll}, +}; -use std::collections::HashSet; -use std::pin::Pin; -use std::task::{Context, Poll}; - -use futures::FutureExt; -use futures::Stream; -use futures::future::{BoxFuture, poll_fn}; -use futures::stream::FusedStream; +use futures::{ + channel::{mpsc, oneshot}, + future::{poll_fn, BoxFuture}, + stream::{FusedStream, FuturesUnordered, StreamExt}, + FutureExt, Stream, +}; use lru::LruCache; -use futures::{channel::mpsc, channel::oneshot, stream::StreamExt, stream::FuturesUnordered}; use polkadot_node_network_protocol::{ - PeerId, - UnifiedReputationChange as Rep, authority_discovery::AuthorityDiscovery, request_response::{ + request::{OutgoingResponse, OutgoingResponseSender}, + v1::{DisputeRequest, DisputeResponse}, IncomingRequest, - request::OutgoingResponse, - request::OutgoingResponseSender, - v1::DisputeRequest, - v1::DisputeResponse, }, + PeerId, UnifiedReputationChange as Rep, }; use polkadot_node_primitives::DISPUTE_WINDOW; -use polkadot_node_subsystem_util::{ - runtime, - runtime::RuntimeInfo, -}; +use polkadot_node_subsystem_util::{runtime, runtime::RuntimeInfo}; use polkadot_subsystem::{ + messages::{AllMessages, DisputeCoordinatorMessage, ImportStatementsResult}, SubsystemSender, - messages::{ - AllMessages, DisputeCoordinatorMessage, ImportStatementsResult, - }, }; -use crate::metrics::{FAILED, SUCCEEDED}; -use crate::{LOG_TARGET, Metrics}; +use crate::{ + metrics::{FAILED, SUCCEEDED}, + Metrics, LOG_TARGET, +}; mod error; -use self::error::{log_error, FatalResult, NonFatalResult, NonFatal, Fatal, Result}; +use self::error::{log_error, Fatal, FatalResult, NonFatal, NonFatalResult, Result}; const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Received message could not be decoded."); const COST_INVALID_SIGNATURE: Rep = Rep::Malicious("Signatures were invalid."); @@ -129,12 +125,13 @@ impl MuxedMessage { return Poll::Ready(Ok(MuxedMessage::ConfirmedImport(v))) } Poll::Pending - }).await + }) + .await } } impl DisputesReceiver -where +where AD: AuthorityDiscovery, { /// Create a new receiver which can be `run`. @@ -167,41 +164,32 @@ where pub async fn run(mut self) { loop { match log_error(self.run_inner().await) { - Ok(()) => {} + Ok(()) => {}, Err(Fatal::RequestChannelFinished) => { tracing::debug!( target: LOG_TARGET, "Incoming request stream exhausted - shutting down?" ); return - } - Err(err) => { - tracing::warn!( - target: LOG_TARGET, - ?err, - "Dispute receiver died." - ); + }, + Err(err) => { + tracing::warn!(target: LOG_TARGET, ?err, "Dispute receiver died."); return - } + }, } } } /// Actual work happening here. async fn run_inner(&mut self) -> Result<()> { - - let msg = MuxedMessage::receive( - &mut self.pending_imports, - &mut self.receiver - ) - .await?; + let msg = MuxedMessage::receive(&mut self.pending_imports, &mut self.receiver).await?; let raw = match msg { // We need to clean up futures, to make sure responses are sent: MuxedMessage::ConfirmedImport(m_bad) => { self.ban_bad_peer(m_bad)?; return Ok(()) - } + }, MuxedMessage::NewRequest(req) => req, }; @@ -211,23 +199,20 @@ where // Only accept messages from validators: if self.authority_discovery.get_authority_id_by_peer_id(raw.peer).await.is_none() { - raw.pending_response.send( - sc_network::config::OutgoingResponse { + raw.pending_response + .send(sc_network::config::OutgoingResponse { result: Err(()), reputation_changes: vec![COST_NOT_A_VALIDATOR.into_base_rep()], sent_feedback: None, - } - ) - .map_err(|_| NonFatal::SendResponse(peer))?; + }) + .map_err(|_| NonFatal::SendResponse(peer))?; return Err(NonFatal::NotAValidator(peer).into()) } - let incoming = IncomingRequest::::try_from_raw( - raw, - vec![COST_INVALID_REQUEST] - ) - .map_err(NonFatal::FromRawRequest)?; + let incoming = + IncomingRequest::::try_from_raw(raw, vec![COST_INVALID_REQUEST]) + .map_err(NonFatal::FromRawRequest)?; // Immediately drop requests from peers that already have requests in flight or have // been banned recently (flood protection): @@ -252,54 +237,49 @@ where } /// Start importing votes for the given request. - async fn start_import( - &mut self, - incoming: IncomingRequest, - ) -> Result<()> { - - let IncomingRequest { - peer, payload, pending_response, - } = incoming; - - let info = self.runtime.get_session_info_by_index( - &mut self.sender, - payload.0.candidate_receipt.descriptor.relay_parent, - payload.0.session_index - ) - .await?; + async fn start_import(&mut self, incoming: IncomingRequest) -> Result<()> { + let IncomingRequest { peer, payload, pending_response } = incoming; + + let info = self + .runtime + .get_session_info_by_index( + &mut self.sender, + payload.0.candidate_receipt.descriptor.relay_parent, + payload.0.session_index, + ) + .await?; let votes_result = payload.0.try_into_signed_votes(&info.session_info); let (candidate_receipt, valid_vote, invalid_vote) = match votes_result { - Err(()) => { // Signature invalid: - pending_response.send_outgoing_response( - OutgoingResponse { + Err(()) => { + // Signature invalid: + pending_response + .send_outgoing_response(OutgoingResponse { result: Err(()), reputation_changes: vec![COST_INVALID_SIGNATURE], sent_feedback: None, - } - ) - .map_err(|_| NonFatal::SetPeerReputation(peer))?; + }) + .map_err(|_| NonFatal::SetPeerReputation(peer))?; return Err(From::from(NonFatal::InvalidSignature(peer))) - } + }, Ok(votes) => votes, }; let (pending_confirmation, confirmation_rx) = oneshot::channel(); let candidate_hash = candidate_receipt.hash(); - self.sender.send_message( - AllMessages::DisputeCoordinator( + self.sender + .send_message(AllMessages::DisputeCoordinator( DisputeCoordinatorMessage::ImportStatements { candidate_hash, candidate_receipt, session: valid_vote.0.session_index(), statements: vec![valid_vote, invalid_vote], pending_confirmation, - } - ) - ) - .await; + }, + )) + .await; self.pending_imports.push(peer, confirmation_rx, pending_response); Ok(()) @@ -310,16 +290,16 @@ where /// In addition we report import metrics. fn ban_bad_peer( &mut self, - result: NonFatalResult<(PeerId, ImportStatementsResult)> + result: NonFatalResult<(PeerId, ImportStatementsResult)>, ) -> NonFatalResult<()> { match result? { - (_, ImportStatementsResult::ValidImport) => { + (_, ImportStatementsResult::ValidImport) => { self.metrics.on_imported(SUCCEEDED); - } + }, (bad_peer, ImportStatementsResult::InvalidImport) => { self.metrics.on_imported(FAILED); self.banned_peers.put(bad_peer, ()); - } + }, } Ok(()) } @@ -335,24 +315,22 @@ struct PendingImports { impl PendingImports { pub fn new() -> Self { - Self { - futures: FuturesUnordered::new(), - peers: HashSet::new(), - } + Self { futures: FuturesUnordered::new(), peers: HashSet::new() } } pub fn push( &mut self, peer: PeerId, handled: oneshot::Receiver, - pending_response: OutgoingResponseSender + pending_response: OutgoingResponseSender, ) { self.peers.insert(peer); self.futures.push( async move { let r = respond_to_request(peer, handled, pending_response).await; (peer, r) - }.boxed() + } + .boxed(), ) } @@ -369,23 +347,19 @@ impl PendingImports { impl Stream for PendingImports { type Item = NonFatalResult<(PeerId, ImportStatementsResult)>; - fn poll_next( - mut self: Pin<&mut Self>, - ctx: &mut Context<'_> - ) -> Poll> { + fn poll_next(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll> { match Pin::new(&mut self.futures).poll_next(ctx) { Poll::Pending => Poll::Pending, Poll::Ready(None) => Poll::Ready(None), Poll::Ready(Some((peer, result))) => { self.peers.remove(&peer); - Poll::Ready(Some(result.map(|r| (peer,r)))) - } + Poll::Ready(Some(result.map(|r| (peer, r)))) + }, } } - } impl FusedStream for PendingImports { - fn is_terminated(&self) -> bool { + fn is_terminated(&self) -> bool { self.futures.is_terminated() } } @@ -398,27 +372,21 @@ impl FusedStream for PendingImports { async fn respond_to_request( peer: PeerId, handled: oneshot::Receiver, - pending_response: OutgoingResponseSender + pending_response: OutgoingResponseSender, ) -> NonFatalResult { - - let result = handled - .await - .map_err(|_| NonFatal::ImportCanceled(peer))? - ; + let result = handled.await.map_err(|_| NonFatal::ImportCanceled(peer))?; let response = match result { - ImportStatementsResult::ValidImport => - OutgoingResponse { - result: Ok(DisputeResponse::Confirmed), - reputation_changes: Vec::new(), - sent_feedback: None, - }, - ImportStatementsResult::InvalidImport => - OutgoingResponse { - result: Err(()), - reputation_changes: vec![COST_INVALID_CANDIDATE], - sent_feedback: None, - }, + ImportStatementsResult::ValidImport => OutgoingResponse { + result: Ok(DisputeResponse::Confirmed), + reputation_changes: Vec::new(), + sent_feedback: None, + }, + ImportStatementsResult::InvalidImport => OutgoingResponse { + result: Err(()), + reputation_changes: vec![COST_INVALID_CANDIDATE], + sent_feedback: None, + }, }; pending_response diff --git a/polkadot/node/network/dispute-distribution/src/sender/error.rs b/polkadot/node/network/dispute-distribution/src/sender/error.rs index 1d24496e9cd..72bba74b600 100644 --- a/polkadot/node/network/dispute-distribution/src/sender/error.rs +++ b/polkadot/node/network/dispute-distribution/src/sender/error.rs @@ -19,11 +19,9 @@ use thiserror::Error; - -use polkadot_node_subsystem_util::{Fault, runtime}; -use polkadot_subsystem::SubsystemError; use polkadot_node_primitives::disputes::DisputeMessageCheckError; - +use polkadot_node_subsystem_util::{runtime, Fault}; +use polkadot_subsystem::SubsystemError; #[derive(Debug, Error)] #[error(transparent)] diff --git a/polkadot/node/network/dispute-distribution/src/sender/mod.rs b/polkadot/node/network/dispute-distribution/src/sender/mod.rs index 93e4879272f..c640d537424 100644 --- a/polkadot/node/network/dispute-distribution/src/sender/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/sender/mod.rs @@ -14,8 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . - -use std::collections::{HashMap, HashSet, hash_map::Entry}; +use std::collections::{hash_map::Entry, HashMap, HashSet}; use futures::channel::{mpsc, oneshot}; @@ -24,11 +23,10 @@ use polkadot_node_primitives::{CandidateVotes, DisputeMessage, SignedDisputeStat use polkadot_node_subsystem_util::runtime::RuntimeInfo; use polkadot_primitives::v1::{CandidateHash, DisputeStatement, Hash, SessionIndex}; use polkadot_subsystem::{ + messages::{AllMessages, DisputeCoordinatorMessage}, ActiveLeavesUpdate, SubsystemContext, - messages::{AllMessages, DisputeCoordinatorMessage} }; - /// For each ongoing dispute we have a `SendTask` which takes care of it. /// /// It is going to spawn real tasks as it sees fit for getting the votes of the particular dispute @@ -39,10 +37,10 @@ pub use send_task::TaskFinish; /// Error and [`Result`] type for sender mod error; -pub use error::{Result, Error, Fatal, NonFatal}; +pub use error::{Error, Fatal, NonFatal, Result}; -use crate::{LOG_TARGET, Metrics}; use self::error::NonFatalResult; +use crate::{Metrics, LOG_TARGET}; /// The `DisputeSender` keeps track of all ongoing disputes we need to send statements out. /// @@ -68,8 +66,7 @@ pub struct DisputeSender { metrics: Metrics, } -impl DisputeSender -{ +impl DisputeSender { /// Create a new `DisputeSender` which can be used to start dispute sendings. pub fn new(tx: mpsc::Sender, metrics: Metrics) -> Self { Self { @@ -98,18 +95,13 @@ impl DisputeSender "Dispute sending already active." ); return Ok(()) - } + }, Entry::Vacant(vacant) => { - let send_task = SendTask::new( - ctx, - runtime, - &self.active_sessions, - self.tx.clone(), - req, - ) - .await?; + let send_task = + SendTask::new(ctx, runtime, &self.active_sessions, self.tx.clone(), req) + .await?; vacant.insert(send_task); - } + }, } Ok(()) } @@ -143,9 +135,8 @@ impl DisputeSender let active_disputes: HashSet<_> = active_disputes.into_iter().map(|(_, c)| c).collect(); // Cleanup obsolete senders: - self.disputes.retain( - |candidate_hash, _| active_disputes.contains(candidate_hash) - ); + self.disputes + .retain(|candidate_hash, _| active_disputes.contains(candidate_hash)); for dispute in self.disputes.values_mut() { if have_new_sessions || dispute.has_failed_sends() { @@ -162,7 +153,6 @@ impl DisputeSender /// Receive message from a sending task. pub async fn on_task_message(&mut self, msg: TaskFinish) { - let TaskFinish { candidate_hash, receiver, result } = msg; self.metrics.on_sent_request(result.as_metrics_label()); @@ -176,7 +166,7 @@ impl DisputeSender "Received `FromSendingTask::Finished` for non existing dispute." ); return - } + }, Some(task) => task, }; task.on_finished_send(&receiver, result); @@ -194,7 +184,9 @@ impl DisputeSender let (session_index, candidate_hash) = dispute; // We need some relay chain head for context for receiving session info information: let ref_head = self.active_sessions.values().next().ok_or(NonFatal::NoActiveHeads)?; - let info = runtime.get_session_info_by_index(ctx.sender(), *ref_head, session_index).await?; + let info = runtime + .get_session_info_by_index(ctx.sender(), *ref_head, session_index) + .await?; let our_index = match info.validator_info.our_index { None => { tracing::trace!( @@ -202,7 +194,7 @@ impl DisputeSender "Not a validator in that session - not starting dispute sending." ); return Ok(()) - } + }, Some(index) => index, }; @@ -215,39 +207,25 @@ impl DisputeSender "No votes for active dispute?! - possible, due to race." ); return Ok(()) - } + }, Some(votes) => votes, }; - let our_valid_vote = votes - .valid - .iter() - .find(|(_, i, _)| *i == our_index); - - let our_invalid_vote = votes - .invalid - .iter() - .find(|(_, i, _)| *i == our_index); - - let (valid_vote, invalid_vote) = - if let Some(our_valid_vote) = our_valid_vote { - // Get some invalid vote as well: - let invalid_vote = votes - .invalid - .get(0) - .ok_or(NonFatal::MissingVotesFromCoordinator)?; - (our_valid_vote, invalid_vote) - } else if let Some(our_invalid_vote) = our_invalid_vote { - // Get some valid vote as well: - let valid_vote = votes - .valid - .get(0) - .ok_or(NonFatal::MissingVotesFromCoordinator)?; - (valid_vote, our_invalid_vote) - } else { - return Err(From::from(NonFatal::MissingVotesFromCoordinator)) - } - ; + let our_valid_vote = votes.valid.iter().find(|(_, i, _)| *i == our_index); + + let our_invalid_vote = votes.invalid.iter().find(|(_, i, _)| *i == our_index); + + let (valid_vote, invalid_vote) = if let Some(our_valid_vote) = our_valid_vote { + // Get some invalid vote as well: + let invalid_vote = votes.invalid.get(0).ok_or(NonFatal::MissingVotesFromCoordinator)?; + (our_valid_vote, invalid_vote) + } else if let Some(our_invalid_vote) = our_invalid_vote { + // Get some valid vote as well: + let valid_vote = votes.valid.get(0).ok_or(NonFatal::MissingVotesFromCoordinator)?; + (valid_vote, our_invalid_vote) + } else { + return Err(From::from(NonFatal::MissingVotesFromCoordinator)) + }; let (kind, valid_index, signature) = valid_vote; let valid_public = info .session_info @@ -290,7 +268,7 @@ impl DisputeSender invalid_signed, *invalid_index, votes.candidate_receipt, - &info.session_info + &info.session_info, ) .map_err(NonFatal::InvalidDisputeFromCoordinator)?; @@ -333,12 +311,13 @@ async fn get_active_session_indeces( } /// Retrieve Set of active disputes from the dispute coordinator. -async fn get_active_disputes(ctx: &mut Context) - -> NonFatalResult> { +async fn get_active_disputes( + ctx: &mut Context, +) -> NonFatalResult> { let (tx, rx) = oneshot::channel(); - ctx.send_message(AllMessages::DisputeCoordinator( - DisputeCoordinatorMessage::ActiveDisputes(tx) - )) + ctx.send_message(AllMessages::DisputeCoordinator(DisputeCoordinatorMessage::ActiveDisputes( + tx, + ))) .await; rx.await.map_err(|_| NonFatal::AskActiveDisputesCanceled) } @@ -351,10 +330,7 @@ async fn get_candidate_votes( ) -> NonFatalResult> { let (tx, rx) = oneshot::channel(); ctx.send_message(AllMessages::DisputeCoordinator( - DisputeCoordinatorMessage::QueryCandidateVotes( - vec![(session_index, candidate_hash)], - tx - ) + DisputeCoordinatorMessage::QueryCandidateVotes(vec![(session_index, candidate_hash)], tx), )) .await; rx.await diff --git a/polkadot/node/network/dispute-distribution/src/sender/send_task.rs b/polkadot/node/network/dispute-distribution/src/sender/send_task.rs index 770ed6a83e8..0c3681a30a9 100644 --- a/polkadot/node/network/dispute-distribution/src/sender/send_task.rs +++ b/polkadot/node/network/dispute-distribution/src/sender/send_task.rs @@ -14,37 +14,32 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use std::collections::{HashMap, HashSet}; -use std::collections::HashMap; -use std::collections::HashSet; - -use futures::Future; -use futures::FutureExt; -use futures::SinkExt; -use futures::channel::mpsc; -use futures::future::RemoteHandle; +use futures::{channel::mpsc, future::RemoteHandle, Future, FutureExt, SinkExt}; use polkadot_node_network_protocol::{ - IfDisconnected, request_response::{ - OutgoingRequest, OutgoingResult, Recipient, Requests, v1::{DisputeRequest, DisputeResponse}, - } + OutgoingRequest, OutgoingResult, Recipient, Requests, + }, + IfDisconnected, }; use polkadot_node_subsystem_util::runtime::RuntimeInfo; use polkadot_primitives::v1::{ AuthorityDiscoveryId, CandidateHash, Hash, SessionIndex, ValidatorIndex, }; use polkadot_subsystem::{ - SubsystemContext, messages::{AllMessages, NetworkBridgeMessage}, + SubsystemContext, }; use super::error::{Fatal, Result}; -use crate::LOG_TARGET; -use crate::metrics::FAILED; -use crate::metrics::SUCCEEDED; +use crate::{ + metrics::{FAILED, SUCCEEDED}, + LOG_TARGET, +}; /// Delivery status for a particular dispute. /// @@ -104,27 +99,18 @@ impl TaskResult { } } -impl SendTask -{ +impl SendTask { /// Initiates sending a dispute message to peers. pub async fn new( ctx: &mut Context, runtime: &mut RuntimeInfo, - active_sessions: &HashMap, + active_sessions: &HashMap, tx: mpsc::Sender, request: DisputeRequest, ) -> Result { - let mut send_task = Self { - request, - deliveries: HashMap::new(), - has_failed_sends: false, - tx, - }; - send_task.refresh_sends( - ctx, - runtime, - active_sessions, - ).await?; + let mut send_task = + Self { request, deliveries: HashMap::new(), has_failed_sends: false, tx }; + send_task.refresh_sends(ctx, runtime, active_sessions).await?; Ok(send_task) } @@ -150,12 +136,8 @@ impl SendTask self.deliveries.retain(|k, _| new_authorities.contains(k)); // Start any new tasks that are needed: - let new_statuses = send_requests( - ctx, - self.tx.clone(), - add_authorities, - self.request.clone(), - ).await?; + let new_statuses = + send_requests(ctx, self.tx.clone(), add_authorities, self.request.clone()).await?; self.deliveries.extend(new_statuses.into_iter()); self.has_failed_sends = false; @@ -180,7 +162,7 @@ impl SendTask self.has_failed_sends = true; // Remove state, so we know what to try again: self.deliveries.remove(authority); - } + }, TaskResult::Succeeded => { let status = match self.deliveries.get_mut(&authority) { None => { @@ -194,16 +176,15 @@ impl SendTask "Received `FromSendingTask::Finished` for non existing task." ); return - } + }, Some(status) => status, }; // We are done here: *status = DeliveryStatus::Succeeded; - } + }, } } - /// Determine all validators that should receive the given dispute requests. /// /// This is all parachain validators of the session the candidate occurred and all authorities @@ -232,7 +213,8 @@ impl SendTask // Current authorities: for (session_index, head) in active_sessions.iter() { - let info = runtime.get_session_info_by_index(ctx.sender(), *head, *session_index).await?; + let info = + runtime.get_session_info_by_index(ctx.sender(), *head, *session_index).await?; let session_info = &info.session_info; let new_set = session_info .discovery_keys @@ -246,7 +228,6 @@ impl SendTask } } - /// Start sending of the given message to all given authorities. /// /// And spawn tasks for handling the response. @@ -260,10 +241,8 @@ async fn send_requests( let mut reqs = Vec::with_capacity(receivers.len()); for receiver in receivers { - let (outgoing, pending_response) = OutgoingRequest::new( - Recipient::Authority(receiver.clone()), - req.clone(), - ); + let (outgoing, pending_response) = + OutgoingRequest::new(Recipient::Authority(receiver.clone()), req.clone()); reqs.push(Requests::DisputeSending(outgoing)); @@ -275,8 +254,7 @@ async fn send_requests( ); let (remote, remote_handle) = fut.remote_handle(); - ctx.spawn("dispute-sender", remote.boxed()) - .map_err(Fatal::SpawnTask)?; + ctx.spawn("dispute-sender", remote.boxed()).map_err(Fatal::SpawnTask)?; statuses.insert(receiver, DeliveryStatus::Pending(remote_handle)); } @@ -306,8 +284,8 @@ async fn wait_response_task( %err, "Error sending dispute statements to node." ); - TaskFinish { candidate_hash, receiver, result: TaskResult::Failed} - } + TaskFinish { candidate_hash, receiver, result: TaskResult::Failed } + }, Ok(DisputeResponse::Confirmed) => { tracing::trace!( target: LOG_TARGET, @@ -316,7 +294,7 @@ async fn wait_response_task( "Sending dispute message succeeded" ); TaskFinish { candidate_hash, receiver, result: TaskResult::Succeeded } - } + }, }; if let Err(err) = tx.feed(msg).await { tracing::debug!( diff --git a/polkadot/node/network/dispute-distribution/src/tests/mock.rs b/polkadot/node/network/dispute-distribution/src/tests/mock.rs index b8d1986cbd1..be3c3c4d40b 100644 --- a/polkadot/node/network/dispute-distribution/src/tests/mock.rs +++ b/polkadot/node/network/dispute-distribution/src/tests/mock.rs @@ -22,16 +22,16 @@ use std::{collections::HashMap, sync::Arc}; use async_trait::async_trait; use lazy_static::lazy_static; -use polkadot_node_network_protocol::{PeerId, authority_discovery::AuthorityDiscovery}; +use polkadot_node_network_protocol::{authority_discovery::AuthorityDiscovery, PeerId}; use sc_keystore::LocalKeystore; use sp_application_crypto::AppKey; -use sp_keyring::{Sr25519Keyring}; +use sp_keyring::Sr25519Keyring; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; use polkadot_node_primitives::{DisputeMessage, SignedDisputeStatement}; use polkadot_primitives::v1::{ - CandidateDescriptor, CandidateHash, CandidateReceipt, Hash, - SessionIndex, SessionInfo, ValidatorId, ValidatorIndex, AuthorityDiscoveryId, + AuthorityDiscoveryId, CandidateDescriptor, CandidateHash, CandidateReceipt, Hash, SessionIndex, + SessionInfo, ValidatorId, ValidatorIndex, }; pub const MOCK_SESSION_INDEX: SessionIndex = 1; @@ -45,22 +45,19 @@ pub const MOCK_VALIDATORS: [Sr25519Keyring; 6] = [ Sr25519Keyring::Eve, ]; -pub const MOCK_AUTHORITIES_NEXT_SESSION: [Sr25519Keyring;2] = [ - Sr25519Keyring::One, - Sr25519Keyring::Two, -]; +pub const MOCK_AUTHORITIES_NEXT_SESSION: [Sr25519Keyring; 2] = + [Sr25519Keyring::One, Sr25519Keyring::Two]; pub const FERDIE_INDEX: ValidatorIndex = ValidatorIndex(0); pub const ALICE_INDEX: ValidatorIndex = ValidatorIndex(1); - lazy_static! { /// Mocked `AuthorityDiscovery` service. pub static ref MOCK_AUTHORITY_DISCOVERY: MockAuthorityDiscovery = MockAuthorityDiscovery::new(); // Creating an innocent looking `SessionInfo` is really expensive in a debug build. Around // 700ms on my machine, We therefore cache those keys here: -pub static ref MOCK_VALIDATORS_DISCOVERY_KEYS: HashMap = +pub static ref MOCK_VALIDATORS_DISCOVERY_KEYS: HashMap = MOCK_VALIDATORS .iter() .chain(MOCK_AUTHORITIES_NEXT_SESSION.iter()) @@ -92,13 +89,9 @@ pub static ref MOCK_NEXT_SESSION_INFO: SessionInfo = }; } - pub fn make_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { CandidateReceipt { - descriptor: CandidateDescriptor { - relay_parent, - ..Default::default() - }, + descriptor: CandidateDescriptor { relay_parent, ..Default::default() }, commitments_hash: Hash::random(), } } @@ -106,15 +99,11 @@ pub fn make_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { pub async fn make_explicit_signed( validator: Sr25519Keyring, candidate_hash: CandidateHash, - valid: bool + valid: bool, ) -> SignedDisputeStatement { let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); - SyncCryptoStore::sr25519_generate_new( - &*keystore, - ValidatorId::ID, - Some(&validator.to_seed()), - ) - .expect("Insert key into keystore"); + SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, Some(&validator.to_seed())) + .expect("Insert key into keystore"); SignedDisputeStatement::sign_explicit( &keystore, @@ -128,17 +117,18 @@ pub async fn make_explicit_signed( .expect("Signing should work.") } - pub async fn make_dispute_message( candidate: CandidateReceipt, valid_validator: ValidatorIndex, invalid_validator: ValidatorIndex, ) -> DisputeMessage { let candidate_hash = candidate.hash(); - let valid_vote = - make_explicit_signed(MOCK_VALIDATORS[valid_validator.0 as usize], candidate_hash, true).await; + let valid_vote = + make_explicit_signed(MOCK_VALIDATORS[valid_validator.0 as usize], candidate_hash, true) + .await; let invalid_vote = - make_explicit_signed(MOCK_VALIDATORS[invalid_validator.0 as usize], candidate_hash, false).await; + make_explicit_signed(MOCK_VALIDATORS[invalid_validator.0 as usize], candidate_hash, false) + .await; DisputeMessage::from_signed_statements( valid_vote, valid_validator, @@ -153,7 +143,7 @@ pub async fn make_dispute_message( /// Dummy `AuthorityDiscovery` service. #[derive(Debug, Clone)] pub struct MockAuthorityDiscovery { - peer_ids: HashMap + peer_ids: HashMap, } impl MockAuthorityDiscovery { @@ -178,13 +168,17 @@ impl MockAuthorityDiscovery { #[async_trait] impl AuthorityDiscovery for MockAuthorityDiscovery { - async fn get_addresses_by_authority_id(&mut self, _authority: polkadot_primitives::v1::AuthorityDiscoveryId) - -> Option> { - panic!("Not implemented"); + async fn get_addresses_by_authority_id( + &mut self, + _authority: polkadot_primitives::v1::AuthorityDiscoveryId, + ) -> Option> { + panic!("Not implemented"); } - async fn get_authority_id_by_peer_id(&mut self, peer_id: polkadot_node_network_protocol::PeerId) - -> Option { + async fn get_authority_id_by_peer_id( + &mut self, + peer_id: polkadot_node_network_protocol::PeerId, + ) -> Option { for (a, p) in self.peer_ids.iter() { if p == &peer_id { return Some(MOCK_VALIDATORS_DISCOVERY_KEYS.get(&a).unwrap().clone()) diff --git a/polkadot/node/network/dispute-distribution/src/tests/mod.rs b/polkadot/node/network/dispute-distribution/src/tests/mod.rs index 1a8b0468066..9eb6363c3b9 100644 --- a/polkadot/node/network/dispute-distribution/src/tests/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/tests/mod.rs @@ -17,451 +17,448 @@ //! Subsystem unit tests -use std::collections::HashSet; -use std::sync::Arc; -use std::task::Poll; -use std::time::Duration; +use std::{collections::HashSet, sync::Arc, task::Poll, time::Duration}; use assert_matches::assert_matches; use futures::{ - channel::{oneshot, mpsc}, + channel::{mpsc, oneshot}, future::poll_fn, - pin_mut, - SinkExt, Future + pin_mut, Future, SinkExt, }; use futures_timer::Delay; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; -use polkadot_node_network_protocol::PeerId; -use polkadot_node_network_protocol::request_response::v1::DisputeRequest; +use polkadot_node_network_protocol::{request_response::v1::DisputeRequest, PeerId}; use sp_keyring::Sr25519Keyring; -use polkadot_node_network_protocol::{IfDisconnected, request_response::{Recipient, Requests, v1::DisputeResponse}}; +use polkadot_node_network_protocol::{ + request_response::{v1::DisputeResponse, Recipient, Requests}, + IfDisconnected, +}; use polkadot_node_primitives::{CandidateVotes, UncheckedDisputeMessage}; -use polkadot_primitives::v1::{AuthorityDiscoveryId, CandidateHash, Hash, SessionIndex, SessionInfo}; -use polkadot_subsystem::messages::{DisputeCoordinatorMessage, ImportStatementsResult}; +use polkadot_primitives::v1::{ + AuthorityDiscoveryId, CandidateHash, Hash, SessionIndex, SessionInfo, +}; use polkadot_subsystem::{ - ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, LeafStatus, OverseerSignal, Span, messages::{ - AllMessages, DisputeDistributionMessage, NetworkBridgeMessage, RuntimeApiMessage, RuntimeApiRequest + AllMessages, DisputeCoordinatorMessage, DisputeDistributionMessage, ImportStatementsResult, + NetworkBridgeMessage, RuntimeApiMessage, RuntimeApiRequest, }, + ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, LeafStatus, OverseerSignal, Span, +}; +use polkadot_subsystem_testhelpers::{ + mock::make_ferdie_keystore, subsystem_test_harness, TestSubsystemContextHandle, }; -use polkadot_subsystem_testhelpers::{TestSubsystemContextHandle, mock::make_ferdie_keystore, subsystem_test_harness}; -use crate::{DisputeDistributionSubsystem, LOG_TARGET, Metrics}; use self::mock::{ - ALICE_INDEX, FERDIE_INDEX, make_candidate_receipt, make_dispute_message, - MOCK_AUTHORITY_DISCOVERY, MOCK_SESSION_INDEX, MOCK_SESSION_INFO, MOCK_NEXT_SESSION_INDEX, - MOCK_NEXT_SESSION_INFO, FERDIE_DISCOVERY_KEY, + make_candidate_receipt, make_dispute_message, ALICE_INDEX, FERDIE_DISCOVERY_KEY, FERDIE_INDEX, + MOCK_AUTHORITY_DISCOVERY, MOCK_NEXT_SESSION_INDEX, MOCK_NEXT_SESSION_INFO, MOCK_SESSION_INDEX, + MOCK_SESSION_INFO, }; +use crate::{DisputeDistributionSubsystem, Metrics, LOG_TARGET}; /// Useful mock providers. pub mod mock; #[test] fn send_dispute_sends_dispute() { - let test = |mut handle: TestSubsystemContextHandle| - async move { - - let (_, _) = handle_subsystem_startup(&mut handle, None).await; - - let relay_parent = Hash::random(); - let candidate = make_candidate_receipt(relay_parent); - let message = - make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX,).await; - handle.send( - FromOverseer::Communication { - msg: DisputeDistributionMessage::SendDispute(message.clone()) - } - ).await; - // Requests needed session info: - assert_matches!( - handle.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request( - hash, - RuntimeApiRequest::SessionInfo(session_index, tx) - ) - ) => { - assert_eq!(session_index, MOCK_SESSION_INDEX); - assert_eq!( - hash, - message.candidate_receipt().descriptor.relay_parent - ); - tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))).expect("Receiver should stay alive."); - } - ); - - let expected_receivers = { - let info = &MOCK_SESSION_INFO; - info.discovery_keys - .clone() - .into_iter() - .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) - .collect() - // All validators are also authorities in the first session, so we are - // done here. - }; - check_sent_requests(&mut handle, expected_receivers, true).await; - - conclude(&mut handle).await; + let test = |mut handle: TestSubsystemContextHandle| async move { + let (_, _) = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX).await; + handle + .send(FromOverseer::Communication { + msg: DisputeDistributionMessage::SendDispute(message.clone()), + }) + .await; + // Requests needed session info: + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::SessionInfo(session_index, tx) + ) + ) => { + assert_eq!(session_index, MOCK_SESSION_INDEX); + assert_eq!( + hash, + message.candidate_receipt().descriptor.relay_parent + ); + tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))).expect("Receiver should stay alive."); + } + ); + + let expected_receivers = { + let info = &MOCK_SESSION_INFO; + info.discovery_keys + .clone() + .into_iter() + .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) + .collect() + // All validators are also authorities in the first session, so we are + // done here. + }; + check_sent_requests(&mut handle, expected_receivers, true).await; + + conclude(&mut handle).await; }; test_harness(test); } #[test] fn received_request_triggers_import() { - let test = |mut handle: TestSubsystemContextHandle| - async move { - let (_, mut req_tx) = handle_subsystem_startup(&mut handle, None).await; + let test = |mut handle: TestSubsystemContextHandle| async move { + let (_, mut req_tx) = handle_subsystem_startup(&mut handle, None).await; - let relay_parent = Hash::random(); - let candidate = make_candidate_receipt(relay_parent); - let message = - make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX,).await; + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX).await; + + // Non validator request should get dropped: + let rx_response = + send_network_dispute_request(&mut req_tx, PeerId::random(), message.clone().into()) + .await; + + assert_matches!( + rx_response.await, + Ok(resp) => { + let sc_network::config::OutgoingResponse { + result: _, + reputation_changes, + sent_feedback: _, + } = resp; + // Peer should get punished: + assert_eq!(reputation_changes.len(), 1); + } + ); + + // Nested valid and invalid import. + // + // Nested requests from same peer should get dropped. For the invalid request even + // subsequent requests should get dropped. + nested_network_dispute_request( + &mut handle, + &mut req_tx, + MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), + message.clone().into(), + ImportStatementsResult::InvalidImport, + true, + move |handle, req_tx, message| { + nested_network_dispute_request( + handle, + req_tx, + MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob), + message.clone().into(), + ImportStatementsResult::ValidImport, + false, + move |_, req_tx, message| async move { + // Another request from Alice should get dropped (request already in + // flight): + { + let rx_response = send_network_dispute_request( + req_tx, + MOCK_AUTHORITY_DISCOVERY + .get_peer_id_by_authority(Sr25519Keyring::Alice), + message.clone(), + ) + .await; + + assert_matches!( + rx_response.await, + Err(err) => { + tracing::trace!( + target: LOG_TARGET, + ?err, + "Request got dropped - other request already in flight" + ); + } + ); + } + // Another request from Bob should get dropped (request already in + // flight): + { + let rx_response = send_network_dispute_request( + req_tx, + MOCK_AUTHORITY_DISCOVERY + .get_peer_id_by_authority(Sr25519Keyring::Bob), + message.clone(), + ) + .await; + + assert_matches!( + rx_response.await, + Err(err) => { + tracing::trace!( + target: LOG_TARGET, + ?err, + "Request got dropped - other request already in flight" + ); + } + ); + } + }, + ) + }, + ) + .await; - // Non validator request should get dropped: + // Subsequent sends from Alice should fail (peer is banned): + { let rx_response = send_network_dispute_request( &mut req_tx, - PeerId::random(), - message.clone().into() - ).await; + MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), + message.clone().into(), + ) + .await; assert_matches!( rx_response.await, - Ok(resp) => { - let sc_network::config::OutgoingResponse { - result: _, - reputation_changes, - sent_feedback: _, - } = resp; - // Peer should get punished: - assert_eq!(reputation_changes.len(), 1); + Err(err) => { + tracing::trace!( + target: LOG_TARGET, + ?err, + "Request got dropped - peer is banned." + ); } ); + } - // Nested valid and invalid import. - // - // Nested requests from same peer should get dropped. For the invalid request even - // subsequent requests should get dropped. - nested_network_dispute_request( - &mut handle, - &mut req_tx, - MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), - message.clone().into(), - ImportStatementsResult::InvalidImport, - true, - move |handle, req_tx, message| - nested_network_dispute_request( - handle, - req_tx, - MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob), - message.clone().into(), - ImportStatementsResult::ValidImport, - false, - move |_, req_tx, message| async move { - // Another request from Alice should get dropped (request already in - // flight): - { - let rx_response = send_network_dispute_request( - req_tx, - MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), - message.clone(), - ).await; - - assert_matches!( - rx_response.await, - Err(err) => { - tracing::trace!( - target: LOG_TARGET, - ?err, - "Request got dropped - other request already in flight" - ); - } - ); - } - // Another request from Bob should get dropped (request already in - // flight): - { - let rx_response = send_network_dispute_request( - req_tx, - MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob), - message.clone(), - ).await; - - assert_matches!( - rx_response.await, - Err(err) => { - tracing::trace!( - target: LOG_TARGET, - ?err, - "Request got dropped - other request already in flight" - ); - } - ); - } - } - ) - ).await; - - // Subsequent sends from Alice should fail (peer is banned): - { - let rx_response = send_network_dispute_request( - &mut req_tx, - MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Alice), - message.clone().into() - ).await; - - assert_matches!( - rx_response.await, - Err(err) => { - tracing::trace!( - target: LOG_TARGET, - ?err, - "Request got dropped - peer is banned." - ); - } - ); - } - - // But should work fine for Bob: - nested_network_dispute_request( - &mut handle, - &mut req_tx, - MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob), - message.clone().into(), - ImportStatementsResult::ValidImport, - false, - |_, _, _| async {} - ).await; - - tracing::trace!(target: LOG_TARGET, "Concluding."); - conclude(&mut handle).await; + // But should work fine for Bob: + nested_network_dispute_request( + &mut handle, + &mut req_tx, + MOCK_AUTHORITY_DISCOVERY.get_peer_id_by_authority(Sr25519Keyring::Bob), + message.clone().into(), + ImportStatementsResult::ValidImport, + false, + |_, _, _| async {}, + ) + .await; + + tracing::trace!(target: LOG_TARGET, "Concluding."); + conclude(&mut handle).await; }; test_harness(test); } #[test] fn disputes_are_recovered_at_startup() { - let test = |mut handle: TestSubsystemContextHandle| - async move { - - let relay_parent = Hash::random(); - let candidate = make_candidate_receipt(relay_parent); + let test = |mut handle: TestSubsystemContextHandle| async move { + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); - let (_, _) = handle_subsystem_startup(&mut handle, Some(candidate.hash())).await; + let (_, _) = handle_subsystem_startup(&mut handle, Some(candidate.hash())).await; - let message = - make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX,).await; - // Requests needed session info: - assert_matches!( - handle.recv().await, - AllMessages::DisputeCoordinator( - DisputeCoordinatorMessage::QueryCandidateVotes( - query, - tx, - ) - ) => { - let (session_index, candidate_hash) = query.get(0).unwrap().clone(); - assert_eq!(session_index, MOCK_SESSION_INDEX); - assert_eq!(candidate_hash, candidate.hash()); - let unchecked: UncheckedDisputeMessage = message.into(); - tx.send(vec![(session_index, candidate_hash, CandidateVotes { - candidate_receipt: candidate, - valid: vec![( - unchecked.valid_vote.kind, - unchecked.valid_vote.validator_index, - unchecked.valid_vote.signature - )], - invalid: vec![( - unchecked.invalid_vote.kind, - unchecked.invalid_vote.validator_index, - unchecked.invalid_vote.signature - )], - })]) - .expect("Receiver should stay alive."); - } - ); - - let expected_receivers = { - let info = &MOCK_SESSION_INFO; - info.discovery_keys - .clone() - .into_iter() - .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) - .collect() - // All validators are also authorities in the first session, so we are - // done here. - }; - check_sent_requests(&mut handle, expected_receivers, true).await; - - conclude(&mut handle).await; + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX).await; + // Requests needed session info: + assert_matches!( + handle.recv().await, + AllMessages::DisputeCoordinator( + DisputeCoordinatorMessage::QueryCandidateVotes( + query, + tx, + ) + ) => { + let (session_index, candidate_hash) = query.get(0).unwrap().clone(); + assert_eq!(session_index, MOCK_SESSION_INDEX); + assert_eq!(candidate_hash, candidate.hash()); + let unchecked: UncheckedDisputeMessage = message.into(); + tx.send(vec![(session_index, candidate_hash, CandidateVotes { + candidate_receipt: candidate, + valid: vec![( + unchecked.valid_vote.kind, + unchecked.valid_vote.validator_index, + unchecked.valid_vote.signature + )], + invalid: vec![( + unchecked.invalid_vote.kind, + unchecked.invalid_vote.validator_index, + unchecked.invalid_vote.signature + )], + })]) + .expect("Receiver should stay alive."); + } + ); + + let expected_receivers = { + let info = &MOCK_SESSION_INFO; + info.discovery_keys + .clone() + .into_iter() + .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) + .collect() + // All validators are also authorities in the first session, so we are + // done here. + }; + check_sent_requests(&mut handle, expected_receivers, true).await; + + conclude(&mut handle).await; }; test_harness(test); } #[test] fn send_dispute_gets_cleaned_up() { - let test = |mut handle: TestSubsystemContextHandle| - async move { - - let (old_head, _) = handle_subsystem_startup(&mut handle, None).await; - - let relay_parent = Hash::random(); - let candidate = make_candidate_receipt(relay_parent); - let message = - make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX,).await; - handle.send( - FromOverseer::Communication { - msg: DisputeDistributionMessage::SendDispute(message.clone()) - } - ).await; - // Requests needed session info: - assert_matches!( - handle.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request( - hash, - RuntimeApiRequest::SessionInfo(session_index, tx) - ) - ) => { - assert_eq!(session_index, MOCK_SESSION_INDEX); - assert_eq!( - hash, - message.candidate_receipt().descriptor.relay_parent - ); - tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))).expect("Receiver should stay alive."); - } - ); - - let expected_receivers = { - let info = &MOCK_SESSION_INFO; - info.discovery_keys - .clone() - .into_iter() - .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) - .collect() - // All validators are also authorities in the first session, so we are - // done here. - }; - check_sent_requests(&mut handle, expected_receivers, false).await; - - // Give tasks a chance to finish: - Delay::new(Duration::from_millis(20)).await; - - activate_leaf( - &mut handle, - Hash::random(), - Some(old_head), - MOCK_SESSION_INDEX, - None, - // No disputes any more: - Vec::new(), - ).await; - - // Yield, so subsystem can make progess: - Delay::new(Duration::from_millis(2)).await; - - conclude(&mut handle).await; + let test = |mut handle: TestSubsystemContextHandle| async move { + let (old_head, _) = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX).await; + handle + .send(FromOverseer::Communication { + msg: DisputeDistributionMessage::SendDispute(message.clone()), + }) + .await; + // Requests needed session info: + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::SessionInfo(session_index, tx) + ) + ) => { + assert_eq!(session_index, MOCK_SESSION_INDEX); + assert_eq!( + hash, + message.candidate_receipt().descriptor.relay_parent + ); + tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))).expect("Receiver should stay alive."); + } + ); + + let expected_receivers = { + let info = &MOCK_SESSION_INFO; + info.discovery_keys + .clone() + .into_iter() + .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) + .collect() + // All validators are also authorities in the first session, so we are + // done here. + }; + check_sent_requests(&mut handle, expected_receivers, false).await; + + // Give tasks a chance to finish: + Delay::new(Duration::from_millis(20)).await; + + activate_leaf( + &mut handle, + Hash::random(), + Some(old_head), + MOCK_SESSION_INDEX, + None, + // No disputes any more: + Vec::new(), + ) + .await; + + // Yield, so subsystem can make progess: + Delay::new(Duration::from_millis(2)).await; + + conclude(&mut handle).await; }; test_harness(test); } #[test] fn dispute_retries_and_works_across_session_boundaries() { - let test = |mut handle: TestSubsystemContextHandle| - async move { - - let (old_head, _) = handle_subsystem_startup(&mut handle, None).await; - - let relay_parent = Hash::random(); - let candidate = make_candidate_receipt(relay_parent); - let message = - make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX,).await; - handle.send( - FromOverseer::Communication { - msg: DisputeDistributionMessage::SendDispute(message.clone()) - } - ).await; - // Requests needed session info: - assert_matches!( - handle.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request( - hash, - RuntimeApiRequest::SessionInfo(session_index, tx) - ) - ) => { - assert_eq!(session_index, MOCK_SESSION_INDEX); - assert_eq!( - hash, - message.candidate_receipt().descriptor.relay_parent - ); - tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))).expect("Receiver should stay alive."); - } - ); - - let expected_receivers: HashSet<_> = { - let info = &MOCK_SESSION_INFO; - info.discovery_keys - .clone() - .into_iter() - .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) - .collect() - // All validators are also authorities in the first session, so we are - // done here. - }; - // Requests don't get confirmed - dispute is carried over to next session. - check_sent_requests(&mut handle, expected_receivers.clone(), false).await; - - // Give tasks a chance to finish: - Delay::new(Duration::from_millis(20)).await; - - // Trigger retry: - let old_head2 = Hash::random(); - activate_leaf( - &mut handle, - old_head2, - Some(old_head), - MOCK_SESSION_INDEX, - None, - vec![(MOCK_SESSION_INDEX, candidate.hash())] - ).await; - - check_sent_requests(&mut handle, expected_receivers.clone(), false).await; - // Give tasks a chance to finish: - Delay::new(Duration::from_millis(20)).await; - - // Session change: - activate_leaf( - &mut handle, - Hash::random(), - Some(old_head2), - MOCK_NEXT_SESSION_INDEX, - Some(MOCK_NEXT_SESSION_INFO.clone()), - vec![(MOCK_SESSION_INDEX, candidate.hash())] - ).await; - - let expected_receivers = { - let validator_count = MOCK_SESSION_INFO.validators.len(); - let old_validators = MOCK_SESSION_INFO - .discovery_keys - .clone() - .into_iter() - .take(validator_count) - .filter(|a| *a != *FERDIE_DISCOVERY_KEY); - - MOCK_NEXT_SESSION_INFO - .discovery_keys - .clone() - .into_iter() - .filter(|a| *a != *FERDIE_DISCOVERY_KEY) - .chain(old_validators) - .collect() - }; - check_sent_requests(&mut handle, expected_receivers, true).await; - - conclude(&mut handle).await; + let test = |mut handle: TestSubsystemContextHandle| async move { + let (old_head, _) = handle_subsystem_startup(&mut handle, None).await; + + let relay_parent = Hash::random(); + let candidate = make_candidate_receipt(relay_parent); + let message = make_dispute_message(candidate.clone(), ALICE_INDEX, FERDIE_INDEX).await; + handle + .send(FromOverseer::Communication { + msg: DisputeDistributionMessage::SendDispute(message.clone()), + }) + .await; + // Requests needed session info: + assert_matches!( + handle.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + hash, + RuntimeApiRequest::SessionInfo(session_index, tx) + ) + ) => { + assert_eq!(session_index, MOCK_SESSION_INDEX); + assert_eq!( + hash, + message.candidate_receipt().descriptor.relay_parent + ); + tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))).expect("Receiver should stay alive."); + } + ); + + let expected_receivers: HashSet<_> = { + let info = &MOCK_SESSION_INFO; + info.discovery_keys + .clone() + .into_iter() + .filter(|a| a != &Sr25519Keyring::Ferdie.public().into()) + .collect() + // All validators are also authorities in the first session, so we are + // done here. + }; + // Requests don't get confirmed - dispute is carried over to next session. + check_sent_requests(&mut handle, expected_receivers.clone(), false).await; + + // Give tasks a chance to finish: + Delay::new(Duration::from_millis(20)).await; + + // Trigger retry: + let old_head2 = Hash::random(); + activate_leaf( + &mut handle, + old_head2, + Some(old_head), + MOCK_SESSION_INDEX, + None, + vec![(MOCK_SESSION_INDEX, candidate.hash())], + ) + .await; + + check_sent_requests(&mut handle, expected_receivers.clone(), false).await; + // Give tasks a chance to finish: + Delay::new(Duration::from_millis(20)).await; + + // Session change: + activate_leaf( + &mut handle, + Hash::random(), + Some(old_head2), + MOCK_NEXT_SESSION_INDEX, + Some(MOCK_NEXT_SESSION_INFO.clone()), + vec![(MOCK_SESSION_INDEX, candidate.hash())], + ) + .await; + + let expected_receivers = { + let validator_count = MOCK_SESSION_INFO.validators.len(); + let old_validators = MOCK_SESSION_INFO + .discovery_keys + .clone() + .into_iter() + .take(validator_count) + .filter(|a| *a != *FERDIE_DISCOVERY_KEY); + + MOCK_NEXT_SESSION_INFO + .discovery_keys + .clone() + .into_iter() + .filter(|a| *a != *FERDIE_DISCOVERY_KEY) + .chain(old_validators) + .collect() + }; + check_sent_requests(&mut handle, expected_receivers, true).await; + + conclude(&mut handle).await; }; test_harness(test); } @@ -472,11 +469,8 @@ async fn send_network_dispute_request( message: DisputeRequest, ) -> oneshot::Receiver { let (pending_response, rx_response) = oneshot::channel(); - let req = sc_network::config::IncomingRequest { - peer, - payload: message.encode(), - pending_response, - }; + let req = + sc_network::config::IncomingRequest { peer, payload: message.encode(), pending_response }; req_tx.feed(req).await.unwrap(); rx_response } @@ -492,30 +486,27 @@ async fn nested_network_dispute_request<'a, F, O>( import_result: ImportStatementsResult, need_session_info: bool, inner: F, -) - where - F: FnOnce( - &'a mut TestSubsystemContextHandle, - &'a mut mpsc::Sender, - DisputeRequest, - ) -> O + 'a, - O: Future + 'a +) where + F: FnOnce( + &'a mut TestSubsystemContextHandle, + &'a mut mpsc::Sender, + DisputeRequest, + ) -> O + + 'a, + O: Future + 'a, { - let rx_response = send_network_dispute_request( - req_tx, - peer, - message.clone().into() - ).await; + let rx_response = send_network_dispute_request(req_tx, peer, message.clone().into()).await; if need_session_info { // Subsystem might need `SessionInfo` for determining indices: match handle.recv().await { AllMessages::RuntimeApi(RuntimeApiMessage::Request( - _, - RuntimeApiRequest::SessionInfo(_, tx) + _, + RuntimeApiRequest::SessionInfo(_, tx), )) => { - tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))).expect("Receiver should stay alive."); - } + tx.send(Ok(Some(MOCK_SESSION_INFO.clone()))) + .expect("Receiver should stay alive."); + }, unexpected => panic!("Unexpected message {:?}", unexpected), } } @@ -580,21 +571,16 @@ async fn nested_network_dispute_request<'a, F, O>( ); } -async fn conclude( - handle: &mut TestSubsystemContextHandle, -) { +async fn conclude(handle: &mut TestSubsystemContextHandle) { // No more messages should be in the queue: poll_fn(|ctx| { let fut = handle.recv(); pin_mut!(fut); // No requests should be inititated, as there is no longer any dispute active: - assert_matches!( - fut.poll(ctx), - Poll::Pending, - "No requests expected" - ); + assert_matches!(fut.poll(ctx), Poll::Pending, "No requests expected"); Poll::Ready(()) - }).await; + }) + .await; handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; } @@ -612,19 +598,17 @@ async fn activate_leaf( active_disputes: Vec<(SessionIndex, CandidateHash)>, ) { let has_active_disputes = !active_disputes.is_empty(); - handle.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves( - ActiveLeavesUpdate { - activated: Some(ActivatedLeaf { - hash: activate, - number: 10, - status: LeafStatus::Fresh, - span: Arc::new(Span::Disabled), - }), - deactivated: deactivate.into_iter().collect(), - } - ))) - .await; + handle + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated: Some(ActivatedLeaf { + hash: activate, + number: 10, + status: LeafStatus::Fresh, + span: Arc::new(Span::Disabled), + }), + deactivated: deactivate.into_iter().collect(), + }))) + .await; assert_matches!( handle.recv().await, AllMessages::RuntimeApi(RuntimeApiMessage::Request( @@ -667,10 +651,7 @@ async fn check_sent_requests( confirm_receive: bool, ) { let expected_receivers: HashSet<_> = - expected_receivers - .into_iter() - .map(Recipient::Authority) - .collect(); + expected_receivers.into_iter().map(Recipient::Authority).collect(); // Sends to concerned validators: assert_matches!( @@ -710,11 +691,11 @@ async fn handle_subsystem_startup( ongoing_dispute: Option, ) -> (Hash, mpsc::Sender) { let (request_tx, request_rx) = mpsc::channel(5); - handle.send( - FromOverseer::Communication { + handle + .send(FromOverseer::Communication { msg: DisputeDistributionMessage::DisputeSendingReceiver(request_rx), - } - ).await; + }) + .await; let relay_parent = Hash::random(); activate_leaf( @@ -723,19 +704,19 @@ async fn handle_subsystem_startup( None, MOCK_SESSION_INDEX, Some(MOCK_SESSION_INFO.clone()), - ongoing_dispute.into_iter().map(|c| (MOCK_SESSION_INDEX, c)).collect() - ).await; + ongoing_dispute.into_iter().map(|c| (MOCK_SESSION_INDEX, c)).collect(), + ) + .await; (relay_parent, request_tx) } - /// Launch subsystem and provided test function /// /// which simulates the overseer. fn test_harness(test: TestFn) where TestFn: FnOnce(TestSubsystemContextHandle) -> Fut, - Fut: Future + Fut: Future, { sp_tracing::try_init_simple(); let keystore = make_ferdie_keystore(); @@ -743,7 +724,7 @@ where let subsystem = DisputeDistributionSubsystem::new( keystore, MOCK_AUTHORITY_DISCOVERY.clone(), - Metrics::new_dummy() + Metrics::new_dummy(), ); let subsystem = |ctx| async { @@ -755,9 +736,8 @@ where ?fatal, "Dispute distribution exited with fatal error." ); - } + }, } }; subsystem_test_harness(test, subsystem); } - diff --git a/polkadot/node/network/gossip-support/src/lib.rs b/polkadot/node/network/gossip-support/src/lib.rs index d18334705c2..1cdfaf4f5d9 100644 --- a/polkadot/node/network/gossip-support/src/lib.rs +++ b/polkadot/node/network/gossip-support/src/lib.rs @@ -24,29 +24,20 @@ //! in this graph will be forwarded to the network bridge with //! the `NetworkBridgeMessage::NewGossipTopology` message. -use std::time::{Duration, Instant}; use futures::{channel::oneshot, FutureExt as _}; -use rand::{SeedableRng, seq::SliceRandom as _}; -use rand_chacha::ChaCha20Rng; +use polkadot_node_network_protocol::peer_set::PeerSet; use polkadot_node_subsystem::{ - overseer, + messages::{GossipSupportMessage, NetworkBridgeMessage, RuntimeApiMessage, RuntimeApiRequest}, + overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemError, - FromOverseer, SpawnedSubsystem, SubsystemContext, - messages::{ - GossipSupportMessage, - NetworkBridgeMessage, - RuntimeApiMessage, - RuntimeApiRequest, - }, - ActiveLeavesUpdate, OverseerSignal, }; use polkadot_node_subsystem_util as util; -use polkadot_primitives::v1::{ - Hash, SessionIndex, AuthorityDiscoveryId, -}; -use polkadot_node_network_protocol::peer_set::PeerSet; +use polkadot_primitives::v1::{AuthorityDiscoveryId, Hash, SessionIndex}; +use rand::{seq::SliceRandom as _, SeedableRng}; +use rand_chacha::ChaCha20Rng; +use sp_application_crypto::{AppKey, Public}; use sp_keystore::{CryptoStore, SyncCryptoStorePtr}; -use sp_application_crypto::{Public, AppKey}; +use std::time::{Duration, Instant}; #[cfg(test)] mod tests; @@ -90,9 +81,7 @@ struct State { impl GossipSupport { /// Create a new instance of the [`GossipSupport`] subsystem. pub fn new(keystore: SyncCryptoStorePtr) -> Self { - Self { - keystore, - } + Self { keystore } } async fn run(self, ctx: Context) @@ -119,7 +108,7 @@ impl GossipSupport { err = ?e, "Failed to receive a message from Overseer, exiting", ); - return; + return }, }; match message { @@ -134,11 +123,9 @@ impl GossipSupport { if let Err(e) = state.handle_active_leaves(&mut ctx, &keystore, leaves).await { tracing::debug!(target: LOG_TARGET, error = ?e); } - } + }, FromOverseer::Signal(OverseerSignal::BlockFinalized(_hash, _number)) => {}, - FromOverseer::Signal(OverseerSignal::Conclude) => { - return; - } + FromOverseer::Signal(OverseerSignal::Conclude) => return, } } } @@ -168,11 +155,8 @@ async fn ensure_i_am_an_authority( authorities: &[AuthorityDiscoveryId], ) -> Result { for (i, v) in authorities.iter().enumerate() { - if CryptoStore::has_keys( - &**keystore, - &[(v.to_raw_vec(), AuthorityDiscoveryId::ID)] - ).await { - return Ok(i); + if CryptoStore::has_keys(&**keystore, &[(v.to_raw_vec(), AuthorityDiscoveryId::ID)]).await { + return Ok(i) } } Err(util::Error::NotAValidator) @@ -189,13 +173,8 @@ where Context: overseer::SubsystemContext, { let (failed, failed_rx) = oneshot::channel(); - ctx.send_message( - NetworkBridgeMessage::ConnectToValidators { - validator_ids, - peer_set, - failed, - } - ).await; + ctx.send_message(NetworkBridgeMessage::ConnectToValidators { validator_ids, peer_set, failed }) + .await; failed_rx } @@ -224,7 +203,8 @@ where ctx.send_message(RuntimeApiMessage::Request( relay_parent, RuntimeApiRequest::CurrentBabeEpoch(tx), - )).await; + )) + .await; let randomness = rx.await??.randomness; let mut subject = [0u8; 40]; @@ -238,24 +218,22 @@ where let len = authorities.len(); let mut indices: Vec = (0..len).collect(); indices.shuffle(&mut rng); - let our_shuffled_position = indices.iter() + let our_shuffled_position = indices + .iter() .position(|i| *i == our_index) .expect("our_index < len; indices contains it; qed"); let neighbors = matrix_neighbors(our_shuffled_position, len); let our_neighbors = neighbors.map(|i| authorities[indices[i]].clone()).collect(); - ctx.send_message( - NetworkBridgeMessage::NewGossipTopology { - our_neighbors, - } - ).await; + ctx.send_message(NetworkBridgeMessage::NewGossipTopology { our_neighbors }) + .await; Ok(()) } /// Compute our row and column neighbors in a matrix -fn matrix_neighbors(our_index: usize, len: usize) -> impl Iterator { +fn matrix_neighbors(our_index: usize, len: usize) -> impl Iterator { assert!(our_index < len, "our_index is computed using `enumerate`; qed"); // e.g. for size 11 the matrix would be @@ -291,7 +269,8 @@ impl State { Context: overseer::SubsystemContext, { for leaf in leaves { - let current_index = util::request_session_index_for_child(leaf, ctx.sender()).await.await??; + let current_index = + util::request_session_index_for_child(leaf, ctx.sender()).await.await??; let since_failure = self.last_failure.map(|i| i.elapsed()).unwrap_or_default(); let force_request = since_failure >= BACKOFF_DURATION; let leaf_session = Some((current_index, leaf)); @@ -300,11 +279,8 @@ impl State { _ => leaf_session, }; - let maybe_issue_connection = if force_request { - leaf_session - } else { - maybe_new_session - }; + let maybe_issue_connection = + if force_request { leaf_session } else { maybe_new_session }; if let Some((session_index, relay_parent)) = maybe_issue_connection { let is_new_session = maybe_new_session.is_some(); @@ -326,7 +302,6 @@ impl State { update_gossip_topology(ctx, our_index, authorities, relay_parent).await?; } } - } Ok(()) @@ -344,11 +319,7 @@ impl State { let num = authorities.len(); tracing::debug!(target: LOG_TARGET, %num, "Issuing a connection request"); - let failures = connect_to_authorities( - ctx, - authorities, - PeerSet::Validation, - ).await; + let failures = connect_to_authorities(ctx, authorities, PeerSet::Validation).await; // we await for the request to be processed // this is fine, it should take much less time than one session @@ -367,8 +338,7 @@ impl State { target = ?num, "Low connectivity - authority lookup failed for too many validators." ); - - } + }, Some(_) => { tracing::debug!( target: LOG_TARGET, @@ -376,7 +346,7 @@ impl State { target = ?num, "Low connectivity (due to authority lookup failures) - expected on startup." ); - } + }, } self.last_failure = Some(timestamp); } else { @@ -394,13 +364,8 @@ where Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { - let future = self.run(ctx) - .map(|_| Ok(())) - .boxed(); + let future = self.run(ctx).map(|_| Ok(())).boxed(); - SpawnedSubsystem { - name: "gossip-support-subsystem", - future, - } + SpawnedSubsystem { name: "gossip-support-subsystem", future } } } diff --git a/polkadot/node/network/gossip-support/src/tests.rs b/polkadot/node/network/gossip-support/src/tests.rs index a37b8ac04e4..f858ae1bc9c 100644 --- a/polkadot/node/network/gossip-support/src/tests.rs +++ b/polkadot/node/network/gossip-support/src/tests.rs @@ -18,21 +18,19 @@ use super::*; use polkadot_node_subsystem::{ - jaeger, ActivatedLeaf, LeafStatus, + jaeger, messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, LeafStatus, }; use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_node_subsystem_util::TimeoutExt as _; +use sp_consensus_babe::{AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch}; use sp_keyring::Sr25519Keyring; -use sp_consensus_babe::{ - Epoch as BabeEpoch, BabeEpochConfiguration, AllowedSlots, -}; use test_helpers::mock::make_ferdie_keystore; -use std::sync::Arc; -use std::time::Duration; use assert_matches::assert_matches; -use futures::{Future, executor, future}; +use futures::{executor, future, Future}; +use std::{sync::Arc, time::Duration}; type VirtualOverseer = test_helpers::TestSubsystemContextHandle; @@ -53,14 +51,17 @@ fn test_harness>( futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); - executor::block_on(future::join(async move { - let mut overseer = test_fut.await; - overseer - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .timeout(TIMEOUT) - .await - .expect("Conclude send timeout"); - }, subsystem)); + executor::block_on(future::join( + async move { + let mut overseer = test_fut.await; + overseer + .send(FromOverseer::Signal(OverseerSignal::Conclude)) + .timeout(TIMEOUT) + .await + .expect("Conclude send timeout"); + }, + subsystem, + )); } state @@ -68,10 +69,7 @@ fn test_harness>( const TIMEOUT: Duration = Duration::from_millis(100); -async fn overseer_signal_active_leaves( - overseer: &mut VirtualOverseer, - leaf: Hash, -) { +async fn overseer_signal_active_leaves(overseer: &mut VirtualOverseer, leaf: Hash) { let leaf = ActivatedLeaf { hash: leaf, number: 0xdeadcafe, @@ -79,20 +77,16 @@ async fn overseer_signal_active_leaves( span: Arc::new(jaeger::Span::Disabled), }; overseer - .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(leaf)))) + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work( + leaf, + )))) .timeout(TIMEOUT) .await .expect("signal send timeout"); } -async fn overseer_recv( - overseer: &mut VirtualOverseer, -) -> AllMessages { - let msg = overseer - .recv() - .timeout(TIMEOUT) - .await - .expect("msg recv timeout"); +async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { + let msg = overseer.recv().timeout(TIMEOUT).await.expect("msg recv timeout"); msg } @@ -368,7 +362,9 @@ fn test_matrix_neighbors() { (9, 10, vec![0, 3, 6]), (10, 11, vec![1, 4, 7, 9]), (7, 11, vec![1, 4, 6, 8, 10]), - ].into_iter() { + ] + .into_iter() + { let mut result: Vec<_> = matrix_neighbors(our_index, len).collect(); result.sort(); assert_eq!(result, expected); diff --git a/polkadot/node/network/protocol/src/authority_discovery.rs b/polkadot/node/network/protocol/src/authority_discovery.rs index c9946f5c68d..03e8a5cb298 100644 --- a/polkadot/node/network/protocol/src/authority_discovery.rs +++ b/polkadot/node/network/protocol/src/authority_discovery.rs @@ -31,18 +31,30 @@ use sc_network::{Multiaddr, PeerId}; #[async_trait] pub trait AuthorityDiscovery: Send + Debug + 'static { /// Get the addresses for the given [`AuthorityId`] from the local address cache. - async fn get_addresses_by_authority_id(&mut self, authority: AuthorityDiscoveryId) -> Option>; + async fn get_addresses_by_authority_id( + &mut self, + authority: AuthorityDiscoveryId, + ) -> Option>; /// Get the [`AuthorityId`] for the given [`PeerId`] from the local address cache. - async fn get_authority_id_by_peer_id(&mut self, peer_id: PeerId) -> Option; + async fn get_authority_id_by_peer_id( + &mut self, + peer_id: PeerId, + ) -> Option; } #[async_trait] impl AuthorityDiscovery for AuthorityDiscoveryService { - async fn get_addresses_by_authority_id(&mut self, authority: AuthorityDiscoveryId) -> Option> { + async fn get_addresses_by_authority_id( + &mut self, + authority: AuthorityDiscoveryId, + ) -> Option> { AuthorityDiscoveryService::get_addresses_by_authority_id(self, authority).await } - async fn get_authority_id_by_peer_id(&mut self, peer_id: PeerId) -> Option { + async fn get_authority_id_by_peer_id( + &mut self, + peer_id: PeerId, + ) -> Option { AuthorityDiscoveryService::get_authority_id_by_peer_id(self, peer_id).await } } diff --git a/polkadot/node/network/protocol/src/lib.rs b/polkadot/node/network/protocol/src/lib.rs index 4282489babe..1ed915f1879 100644 --- a/polkadot/node/network/protocol/src/lib.rs +++ b/polkadot/node/network/protocol/src/lib.rs @@ -19,13 +19,13 @@ #![deny(unused_crate_dependencies)] #![warn(missing_docs)] -use polkadot_primitives::v1::{Hash, BlockNumber}; -use parity_scale_codec::{Encode, Decode}; -use std::{fmt, collections::HashMap}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_primitives::v1::{BlockNumber, Hash}; +use std::{collections::HashMap, fmt}; -pub use sc_network::{PeerId, IfDisconnected}; #[doc(hidden)] pub use polkadot_node_jaeger as jaeger; +pub use sc_network::{IfDisconnected, PeerId}; #[doc(hidden)] pub use std::sync::Arc; @@ -46,7 +46,6 @@ pub type ProtocolVersion = u32; /// The minimum amount of peers to send gossip messages to. pub const MIN_GOSSIP_PEERS: usize = 25; - /// An error indicating that this the over-arching message type had the wrong variant #[derive(Debug, Clone, Copy, PartialEq)] pub struct WrongVariant; @@ -117,10 +116,9 @@ macro_rules! impl_try_from { } } } - } + }; } - /// Specialized wrapper around [`View`]. /// /// Besides the access to the view itself, it also gives access to the [`jaeger::Span`] per leave/head. @@ -132,16 +130,13 @@ pub struct OurView { impl OurView { /// Creates a new instance. - pub fn new(heads: impl IntoIterator)>, finalized_number: BlockNumber) -> Self { + pub fn new( + heads: impl IntoIterator)>, + finalized_number: BlockNumber, + ) -> Self { let state_per_head = heads.into_iter().collect::>(); - let view = View::new( - state_per_head.keys().cloned(), - finalized_number, - ); - Self { - view, - span_per_head: state_per_head, - } + let view = View::new(state_per_head.keys().cloned(), finalized_number); + Self { view, span_per_head: state_per_head } } /// Returns the span per head map. @@ -220,22 +215,15 @@ macro_rules! view { impl View { /// Construct a new view based on heads and a finalized block number. - pub fn new(heads: impl IntoIterator, finalized_number: BlockNumber) -> Self - { + pub fn new(heads: impl IntoIterator, finalized_number: BlockNumber) -> Self { let mut heads = heads.into_iter().collect::>(); heads.sort(); - Self { - heads, - finalized_number, - } + Self { heads, finalized_number } } /// Start with no heads, but only a finalized block number. pub fn with_finalized(finalized_number: BlockNumber) -> Self { - Self { - heads: Vec::new(), - finalized_number, - } + Self { heads: Vec::new(), finalized_number } } /// Obtain the number of heads that are in view. @@ -249,12 +237,12 @@ impl View { } /// Obtain an iterator over all heads. - pub fn iter<'a>(&'a self) -> impl Iterator { + pub fn iter<'a>(&'a self) -> impl Iterator { self.heads.iter() } /// Obtain an iterator over all heads. - pub fn into_iter(self) -> impl Iterator { + pub fn into_iter(self) -> impl Iterator { self.heads.into_iter() } @@ -293,13 +281,12 @@ impl View { /// v1 protocol types. pub mod v1 { - use parity_scale_codec::{Encode, Decode}; + use parity_scale_codec::{Decode, Encode}; use std::convert::TryFrom; use polkadot_primitives::v1::{ - CandidateHash, CandidateIndex, CollatorId, CollatorSignature, - CompactStatement, Hash, Id as ParaId, UncheckedSignedAvailabilityBitfield, - ValidatorIndex, ValidatorSignature, + CandidateHash, CandidateIndex, CollatorId, CollatorSignature, CompactStatement, Hash, + Id as ParaId, UncheckedSignedAvailabilityBitfield, ValidatorIndex, ValidatorSignature, }; use polkadot_node_primitives::{ @@ -307,7 +294,6 @@ pub mod v1 { UncheckedSignedFullStatement, }; - /// Network messages used by the bitfield distribution subsystem. #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)] pub enum BitfieldDistributionMessage { @@ -360,8 +346,10 @@ pub mod v1 { /// Get fingerprint describing the contained statement uniquely. pub fn get_fingerprint(&self) -> (CompactStatement, ValidatorIndex) { match self { - Self::Statement(_, statement) => - (statement.unchecked_payload().to_compact(), statement.unchecked_validator_index()), + Self::Statement(_, statement) => ( + statement.unchecked_payload().to_compact(), + statement.unchecked_validator_index(), + ), Self::LargeStatement(meta) => (CompactStatement::Seconded(meta.candidate_hash), meta.signed_by), } diff --git a/polkadot/node/network/protocol/src/peer_set.rs b/polkadot/node/network/protocol/src/peer_set.rs index e83019d5d38..3d2f133163f 100644 --- a/polkadot/node/network/protocol/src/peer_set.rs +++ b/polkadot/node/network/protocol/src/peer_set.rs @@ -17,7 +17,10 @@ //! All peersets and protocols used for parachains. use sc_network::config::{NonDefaultSetConfig, SetConfig}; -use std::{borrow::Cow, ops::{Index, IndexMut}}; +use std::{ + borrow::Cow, + ops::{Index, IndexMut}, +}; use strum::{EnumIter, IntoEnumIterator}; /// The peer-sets and thus the protocols which are used for the network. @@ -79,7 +82,7 @@ impl PeerSet { sc_network::config::NonReservedPeerMode::Accept } else { sc_network::config::NonReservedPeerMode::Deny - } + }, }, }, } diff --git a/polkadot/node/network/protocol/src/reputation.rs b/polkadot/node/network/protocol/src/reputation.rs index 0eb0b105d27..6a98efe1d08 100644 --- a/polkadot/node/network/protocol/src/reputation.rs +++ b/polkadot/node/network/protocol/src/reputation.rs @@ -68,9 +68,6 @@ impl UnifiedReputationChange { /// Convert into a base reputation as used with substrate. pub const fn into_base_rep(self) -> ReputationChange { - ReputationChange::new( - self.cost_or_benefit(), - self.description() - ) + ReputationChange::new(self.cost_or_benefit(), self.description()) } } diff --git a/polkadot/node/network/protocol/src/request_response/mod.rs b/polkadot/node/network/protocol/src/request_response/mod.rs index c2de3e52686..6ee276ecd73 100644 --- a/polkadot/node/network/protocol/src/request_response/mod.rs +++ b/polkadot/node/network/protocol/src/request_response/mod.rs @@ -32,19 +32,19 @@ //! //! Versioned (v1 module): The actual requests and responses as sent over the network. -use std::{borrow::Cow, u64}; -use std::time::Duration; +use std::{borrow::Cow, time::Duration, u64}; use futures::channel::mpsc; use polkadot_primitives::v1::{MAX_CODE_SIZE, MAX_POV_SIZE}; use strum::EnumIter; -pub use sc_network::config as network; -pub use sc_network::config::RequestResponseConfig; +pub use sc_network::{config as network, config::RequestResponseConfig}; /// All requests that can be sent to the network bridge. pub mod request; -pub use request::{IncomingRequest, OutgoingRequest, Requests, Recipient, OutgoingResult, ResponseSender}; +pub use request::{ + IncomingRequest, OutgoingRequest, OutgoingResult, Recipient, Requests, ResponseSender, +}; ///// Multiplexer for incoming requests. // pub mod multiplexer; @@ -70,10 +70,9 @@ pub enum Protocol { DisputeSending, } - /// Minimum bandwidth we expect for validators - 500Mbit/s is the recommendation, so approximately /// 50MB per second: -const MIN_BANDWIDTH_BYTES: u64 = 50 * 1024 * 1024; +const MIN_BANDWIDTH_BYTES: u64 = 50 * 1024 * 1024; /// Default request timeout in seconds. /// @@ -108,12 +107,7 @@ impl Protocol { /// /// Returns a receiver for messages received on this protocol and the requested /// `ProtocolConfig`. - pub fn get_config( - self, - ) -> ( - mpsc::Receiver, - RequestResponseConfig, - ) { + pub fn get_config(self) -> (mpsc::Receiver, RequestResponseConfig) { let p_name = self.into_protocol_name(); let (tx, rx) = mpsc::channel(self.get_channel_size()); let cfg = match self { @@ -208,15 +202,16 @@ impl Protocol { // wasting precious time. let available_bandwidth = 7 * MIN_BANDWIDTH_BYTES / 10; let size = u64::saturating_sub( - STATEMENTS_TIMEOUT.as_millis() as u64 * available_bandwidth / (1000 * MAX_CODE_SIZE as u64), - MAX_PARALLEL_STATEMENT_REQUESTS as u64 + STATEMENTS_TIMEOUT.as_millis() as u64 * available_bandwidth / + (1000 * MAX_CODE_SIZE as u64), + MAX_PARALLEL_STATEMENT_REQUESTS as u64, ); debug_assert!( size > 0, "We should have a channel size greater zero, otherwise we won't accept any requests." ); size as usize - } + }, // Incoming requests can get bursty, we should also be able to handle them fast on // average, so something in the ballpark of 100 should be fine. Nodes will retry on // failure, so having a good value here is mostly about performance tuning. diff --git a/polkadot/node/network/protocol/src/request_response/request.rs b/polkadot/node/network/protocol/src/request_response/request.rs index 736b93389c3..8e39c7204eb 100644 --- a/polkadot/node/network/protocol/src/request_response/request.rs +++ b/polkadot/node/network/protocol/src/request_response/request.rs @@ -16,14 +16,12 @@ use std::marker::PhantomData; -use futures::channel::oneshot; -use futures::prelude::Future; +use futures::{channel::oneshot, prelude::Future}; -use thiserror::Error; use parity_scale_codec::{Decode, Encode, Error as DecodingError}; use sc_network as network; -use sc_network::config as netconfig; -use sc_network::PeerId; +use sc_network::{config as netconfig, PeerId}; +use thiserror::Error; use polkadot_primitives::v1::AuthorityDiscoveryId; @@ -164,16 +162,9 @@ where pub fn new( peer: Recipient, payload: Req, - ) -> ( - Self, - impl Future>, - ) { + ) -> (Self, impl Future>) { let (tx, rx) = oneshot::channel(); - let r = Self { - peer, - payload, - pending_response: tx, - }; + let r = Self { peer, payload, pending_response: tx }; (r, receive_response::(rx)) } @@ -182,16 +173,8 @@ where /// As this throws away type information, we also return the `Protocol` this encoded request /// adheres to. pub fn encode_request(self) -> (Protocol, OutgoingRequest>) { - let OutgoingRequest { - peer, - payload, - pending_response, - } = self; - let encoded = OutgoingRequest { - peer, - payload: payload.encode(), - pending_response, - }; + let OutgoingRequest { peer, payload, pending_response } = self; + let encoded = OutgoingRequest { peer, payload: payload.encode(), pending_response }; (Req::PROTOCOL, encoded) } } @@ -229,12 +212,12 @@ pub struct IncomingRequest { /// Sender for sending back responses on an `IncomingRequest`. #[derive(Debug)] -pub struct OutgoingResponseSender{ +pub struct OutgoingResponseSender { pending_response: oneshot::Sender, phantom: PhantomData, } -impl OutgoingResponseSender +impl OutgoingResponseSender where Req: IsRequest + Decode, Req::Response: Encode, @@ -260,20 +243,15 @@ where /// This variant allows for waiting for the response to be sent out, allows for changing peer's /// reputation and allows for not sending a response at all (for only changing the peer's /// reputation). - pub fn send_outgoing_response(self, resp: OutgoingResponse<::Response>) - -> Result<(), ()> { - let OutgoingResponse { - result, - reputation_changes, - sent_feedback, - } = resp; + pub fn send_outgoing_response( + self, + resp: OutgoingResponse<::Response>, + ) -> Result<(), ()> { + let OutgoingResponse { result, reputation_changes, sent_feedback } = resp; let response = netconfig::OutgoingResponse { result: result.map(|v| v.encode()), - reputation_changes: reputation_changes - .into_iter() - .map(|c| c.into_base_rep()) - .collect(), + reputation_changes: reputation_changes.into_iter().map(|c| c.into_base_rep()).collect(), sent_feedback, }; @@ -313,10 +291,7 @@ where Self { peer, payload, - pending_response: OutgoingResponseSender { - pending_response, - phantom: PhantomData {}, - }, + pending_response: OutgoingResponseSender { pending_response, phantom: PhantomData {} }, } } @@ -330,20 +305,14 @@ where /// - Reputation changes to apply for the peer in case decoding fails. pub fn try_from_raw( raw: sc_network::config::IncomingRequest, - reputation_changes: Vec + reputation_changes: Vec, ) -> Result { - let sc_network::config::IncomingRequest { - payload, - peer, - pending_response, - } = raw; + let sc_network::config::IncomingRequest { payload, peer, pending_response } = raw; let payload = match Req::decode(&mut payload.as_ref()) { Ok(payload) => payload, Err(err) => { - let reputation_changes = reputation_changes - .into_iter() - .map(|r| r.into_base_rep()) - .collect(); + let reputation_changes = + reputation_changes.into_iter().map(|r| r.into_base_rep()).collect(); let response = sc_network::config::OutgoingResponse { result: Err(()), reputation_changes, @@ -354,7 +323,7 @@ where return Err(ReceiveError::DecodingErrorNoReputationChange(peer, err)) } return Err(ReceiveError::DecodingError(peer, err)) - } + }, }; Ok(Self::new(peer, payload, pending_response)) } @@ -369,8 +338,10 @@ where /// Send response with additional options. /// /// Calls [`OutgoingResponseSender::send_outgoing_response`]. - pub fn send_outgoing_response(self, resp: OutgoingResponse<::Response>) - -> Result<(), ()> { + pub fn send_outgoing_response( + self, + resp: OutgoingResponse<::Response>, + ) -> Result<(), ()> { self.pending_response.send_outgoing_response(resp) } } diff --git a/polkadot/node/network/protocol/src/request_response/v1.rs b/polkadot/node/network/protocol/src/request_response/v1.rs index 6dcc3552e68..c94fcc79d6e 100644 --- a/polkadot/node/network/protocol/src/request_response/v1.rs +++ b/polkadot/node/network/protocol/src/request_response/v1.rs @@ -18,12 +18,14 @@ use parity_scale_codec::{Decode, Encode}; -use polkadot_primitives::v1::{CandidateHash, CandidateReceipt, CommittedCandidateReceipt, Hash, ValidatorIndex}; -use polkadot_primitives::v1::Id as ParaId; -use polkadot_node_primitives::{AvailableData, DisputeMessage, ErasureChunk, PoV, UncheckedDisputeMessage}; +use polkadot_node_primitives::{ + AvailableData, DisputeMessage, ErasureChunk, PoV, UncheckedDisputeMessage, +}; +use polkadot_primitives::v1::{ + CandidateHash, CandidateReceipt, CommittedCandidateReceipt, Hash, Id as ParaId, ValidatorIndex, +}; -use super::request::IsRequest; -use super::Protocol; +use super::{request::IsRequest, Protocol}; /// Request an availability chunk. #[derive(Debug, Copy, Clone, Encode, Decode)] @@ -69,19 +71,15 @@ pub struct ChunkResponse { } impl From for ChunkResponse { - fn from(ErasureChunk {chunk, index: _, proof}: ErasureChunk) -> Self { - ChunkResponse {chunk, proof} + fn from(ErasureChunk { chunk, index: _, proof }: ErasureChunk) -> Self { + ChunkResponse { chunk, proof } } } impl ChunkResponse { /// Re-build an `ErasureChunk` from response and request. pub fn recombine_into_chunk(self, req: &ChunkFetchingRequest) -> ErasureChunk { - ErasureChunk { - chunk: self.chunk, - proof: self.proof, - index: req.index, - } + ErasureChunk { chunk: self.chunk, proof: self.proof, index: req.index } } } @@ -210,7 +208,7 @@ impl From for DisputeRequest { pub enum DisputeResponse { /// Recipient successfully processed the dispute request. #[codec(index = 0)] - Confirmed + Confirmed, } impl IsRequest for DisputeRequest { diff --git a/polkadot/node/network/statement-distribution/src/error.rs b/polkadot/node/network/statement-distribution/src/error.rs index f9767816f70..32adecf24f8 100644 --- a/polkadot/node/network/statement-distribution/src/error.rs +++ b/polkadot/node/network/statement-distribution/src/error.rs @@ -22,7 +22,7 @@ use polkadot_primitives::v1::{CandidateHash, Hash}; use polkadot_subsystem::SubsystemError; use thiserror::Error; -use polkadot_node_subsystem_util::{Fault, runtime, unwrap_non_fatal}; +use polkadot_node_subsystem_util::{runtime, unwrap_non_fatal, Fault}; use crate::LOG_TARGET; @@ -112,9 +112,7 @@ pub enum NonFatal { /// /// We basically always want to try and continue on error. This utility function is meant to /// consume top-level errors by simply logging them. -pub fn log_error(result: Result<()>, ctx: &'static str) - -> FatalResult<()> -{ +pub fn log_error(result: Result<()>, ctx: &'static str) -> FatalResult<()> { if let Some(error) = unwrap_non_fatal(result.map_err(|e| e.0))? { tracing::debug!(target: LOG_TARGET, error = ?error, ctx) } diff --git a/polkadot/node/network/statement-distribution/src/lib.rs b/polkadot/node/network/statement-distribution/src/lib.rs index b8974497955..ddb9a082d01 100644 --- a/polkadot/node/network/statement-distribution/src/lib.rs +++ b/polkadot/node/network/statement-distribution/src/lib.rs @@ -22,71 +22,73 @@ #![deny(unused_crate_dependencies)] #![warn(missing_docs)] -use error::{FatalResult, NonFatalResult, log_error}; +use error::{log_error, FatalResult, NonFatalResult}; use parity_scale_codec::Encode; -use polkadot_subsystem::{ - overseer, - ActiveLeavesUpdate, FromOverseer, OverseerSignal, PerLeafSpan, SpawnedSubsystem, - SubsystemContext, SubsystemError, jaeger, - messages::{ - AllMessages, NetworkBridgeMessage, StatementDistributionMessage, - CandidateBackingMessage, NetworkBridgeEvent, - }, +use polkadot_node_network_protocol::{ + peer_set::{IsAuthority, PeerSet}, + v1::{self as protocol_v1, StatementMetadata}, + IfDisconnected, PeerId, UnifiedReputationChange as Rep, View, }; +use polkadot_node_primitives::{SignedFullStatement, Statement, UncheckedSignedFullStatement}; use polkadot_node_subsystem_util::{ + self as util, metrics::{self, prometheus}, - self as util, MIN_GOSSIP_PEERS, + MIN_GOSSIP_PEERS, }; -use polkadot_node_primitives::{SignedFullStatement, UncheckedSignedFullStatement, Statement}; use polkadot_primitives::v1::{ - CandidateHash, CommittedCandidateReceipt, CompactStatement, Hash, - SigningContext, ValidatorId, ValidatorIndex, ValidatorSignature, AuthorityDiscoveryId, + AuthorityDiscoveryId, CandidateHash, CommittedCandidateReceipt, CompactStatement, Hash, + SigningContext, ValidatorId, ValidatorIndex, ValidatorSignature, }; -use polkadot_node_network_protocol::{ - IfDisconnected, PeerId, UnifiedReputationChange as Rep, View, - peer_set::{ - IsAuthority, PeerSet +use polkadot_subsystem::{ + jaeger, + messages::{ + AllMessages, CandidateBackingMessage, NetworkBridgeEvent, NetworkBridgeMessage, + StatementDistributionMessage, }, - v1::{ - self as protocol_v1, StatementMetadata - } + overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, PerLeafSpan, SpawnedSubsystem, + SubsystemContext, SubsystemError, }; -use futures::{channel::mpsc, future::RemoteHandle, prelude::*}; -use futures::channel::oneshot; -use indexmap::{IndexMap, map::Entry as IEntry}; +use futures::{ + channel::{mpsc, oneshot}, + future::RemoteHandle, + prelude::*, +}; +use indexmap::{map::Entry as IEntry, IndexMap}; use sp_keystore::SyncCryptoStorePtr; -use util::{Fault, runtime::RuntimeInfo}; +use util::{runtime::RuntimeInfo, Fault}; -use std::collections::{HashMap, HashSet, hash_map::Entry}; +use std::collections::{hash_map::Entry, HashMap, HashSet}; mod error; -pub use error::{Error, NonFatal, Fatal, Result}; +pub use error::{Error, Fatal, NonFatal, Result}; /// Background task logic for requesting of large statements. mod requester; -use requester::{RequesterMessage, fetch}; +use requester::{fetch, RequesterMessage}; /// Background task logic for responding for large statements. mod responder; -use responder::{ResponderMessage, respond}; +use responder::{respond, ResponderMessage}; #[cfg(test)] mod tests; const COST_UNEXPECTED_STATEMENT: Rep = Rep::CostMinor("Unexpected Statement"); -const COST_FETCH_FAIL: Rep = Rep::CostMinor("Requesting `CommittedCandidateReceipt` from peer failed"); +const COST_FETCH_FAIL: Rep = + Rep::CostMinor("Requesting `CommittedCandidateReceipt` from peer failed"); const COST_INVALID_SIGNATURE: Rep = Rep::CostMajor("Invalid Statement Signature"); const COST_WRONG_HASH: Rep = Rep::CostMajor("Received candidate had wrong hash"); -const COST_DUPLICATE_STATEMENT: Rep = Rep::CostMajorRepeated("Statement sent more than once by peer"); +const COST_DUPLICATE_STATEMENT: Rep = + Rep::CostMajorRepeated("Statement sent more than once by peer"); const COST_APPARENT_FLOOD: Rep = Rep::Malicious("Peer appears to be flooding us with statements"); const BENEFIT_VALID_STATEMENT: Rep = Rep::BenefitMajor("Peer provided a valid statement"); -const BENEFIT_VALID_STATEMENT_FIRST: Rep = Rep::BenefitMajorFirst( - "Peer was the first to provide a valid statement", -); -const BENEFIT_VALID_RESPONSE: Rep = Rep::BenefitMajor("Peer provided a valid large statement response"); +const BENEFIT_VALID_STATEMENT_FIRST: Rep = + Rep::BenefitMajorFirst("Peer was the first to provide a valid statement"); +const BENEFIT_VALID_RESPONSE: Rep = + Rep::BenefitMajor("Peer provided a valid large statement response"); /// The maximum amount of candidates each validator is allowed to second at any relay-parent. /// Short for "Validator Candidate Threshold". @@ -110,8 +112,8 @@ pub struct StatementDistribution { impl overseer::Subsystem for StatementDistribution where - Context: SubsystemContext, - Context: overseer::SubsystemContext, + Context: SubsystemContext, + Context: overseer::SubsystemContext, { fn start(self, ctx: Context) -> SpawnedSubsystem { // Swallow error because failure is fatal to the node and we log with more precision @@ -129,10 +131,7 @@ where impl StatementDistribution { /// Create a new Statement Distribution Subsystem pub fn new(keystore: SyncCryptoStorePtr, metrics: Metrics) -> StatementDistribution { - StatementDistribution { - keystore, - metrics, - } + StatementDistribution { keystore, metrics } } } @@ -171,8 +170,7 @@ impl VcPerPeerTracker { /// Returns `true` if the peer is allowed to send us such a message, `false` otherwise. fn is_wanted_candidate(&self, h: &CandidateHash) -> bool { - !self.remote_observed.contains(h) && - !self.remote_observed.is_full() + !self.remote_observed.contains(h) && !self.remote_observed.is_full() } } @@ -180,7 +178,9 @@ fn note_hash( observed: &mut arrayvec::ArrayVec<[CandidateHash; VC_THRESHOLD]>, h: CandidateHash, ) -> bool { - if observed.contains(&h) { return true; } + if observed.contains(&h) { + return true + } observed.try_push(h).is_ok() } @@ -204,7 +204,6 @@ struct PeerRelayParentKnowledge { /// How many statements we've received for each candidate that we're aware of. received_message_count: HashMap, - /// How many large statements this peer already sent us. /// /// Flood protection for large statements is rather hard and as soon as we get @@ -246,15 +245,11 @@ impl PeerRelayParentKnowledge { let new_known = match fingerprint.0 { CompactStatement::Seconded(ref h) => { - self.seconded_counts.entry(fingerprint.1) - .or_default() - .note_local(h.clone()); + self.seconded_counts.entry(fingerprint.1).or_default().note_local(h.clone()); self.sent_candidates.insert(h.clone()) }, - CompactStatement::Valid(_) => { - false - } + CompactStatement::Valid(_) => false, }; self.sent_statements.insert(fingerprint.clone()); @@ -265,11 +260,11 @@ impl PeerRelayParentKnowledge { /// This returns `true` if the peer cannot accept this statement, without altering internal /// state, `false` otherwise. fn can_send(&self, fingerprint: &(CompactStatement, ValidatorIndex)) -> bool { - let already_known = self.sent_statements.contains(fingerprint) - || self.received_statements.contains(fingerprint); + let already_known = self.sent_statements.contains(fingerprint) || + self.received_statements.contains(fingerprint); if already_known { - return false; + return false } match fingerprint.0 { @@ -277,10 +272,8 @@ impl PeerRelayParentKnowledge { // The peer can only accept Valid and Invalid statements for which it is aware // of the corresponding candidate. self.is_known_candidate(h) - } - CompactStatement::Seconded(_) => { - true }, + CompactStatement::Seconded(_) => true, } } @@ -308,37 +301,38 @@ impl PeerRelayParentKnowledge { // We don't check `sent_statements` because a statement could be in-flight from both // sides at the same time. if self.received_statements.contains(fingerprint) { - return Err(COST_DUPLICATE_STATEMENT); + return Err(COST_DUPLICATE_STATEMENT) } let candidate_hash = match fingerprint.0 { CompactStatement::Seconded(ref h) => { - let allowed_remote = self.seconded_counts.entry(fingerprint.1) + let allowed_remote = self + .seconded_counts + .entry(fingerprint.1) .or_insert_with(Default::default) .note_remote(h.clone()); if !allowed_remote { - return Err(COST_UNEXPECTED_STATEMENT); + return Err(COST_UNEXPECTED_STATEMENT) } h - } + }, CompactStatement::Valid(ref h) => { if !self.is_known_candidate(&h) { - return Err(COST_UNEXPECTED_STATEMENT); + return Err(COST_UNEXPECTED_STATEMENT) } h - } + }, }; { - let received_per_candidate = self.received_message_count - .entry(*candidate_hash) - .or_insert(0); + let received_per_candidate = + self.received_message_count.entry(*candidate_hash).or_insert(0); if *received_per_candidate >= max_message_count { - return Err(COST_APPARENT_FLOOD); + return Err(COST_APPARENT_FLOOD) } *received_per_candidate += 1; @@ -351,7 +345,7 @@ impl PeerRelayParentKnowledge { /// Note a received large statement metadata. fn receive_large_statement(&mut self) -> std::result::Result<(), Rep> { if self.large_statement_count >= MAX_LARGE_STATEMENTS_PER_SENDER { - return Err(COST_APPARENT_FLOOD); + return Err(COST_APPARENT_FLOOD) } self.large_statement_count += 1; Ok(()) @@ -368,32 +362,32 @@ impl PeerRelayParentKnowledge { // We don't check `sent_statements` because a statement could be in-flight from both // sides at the same time. if self.received_statements.contains(fingerprint) { - return Err(COST_DUPLICATE_STATEMENT); + return Err(COST_DUPLICATE_STATEMENT) } let candidate_hash = match fingerprint.0 { CompactStatement::Seconded(ref h) => { - let allowed_remote = self.seconded_counts.get(&fingerprint.1) + let allowed_remote = self + .seconded_counts + .get(&fingerprint.1) .map_or(true, |r| r.is_wanted_candidate(h)); if !allowed_remote { - return Err(COST_UNEXPECTED_STATEMENT); + return Err(COST_UNEXPECTED_STATEMENT) } h - } + }, CompactStatement::Valid(ref h) => { if !self.is_known_candidate(&h) { - return Err(COST_UNEXPECTED_STATEMENT); + return Err(COST_UNEXPECTED_STATEMENT) } h - } + }, }; - let received_per_candidate = self.received_message_count - .get(candidate_hash) - .unwrap_or(&0); + let received_per_candidate = self.received_message_count.get(candidate_hash).unwrap_or(&0); if *received_per_candidate >= max_message_count { Err(COST_APPARENT_FLOOD) @@ -448,9 +442,7 @@ impl PeerData { relay_parent: &Hash, fingerprint: &(CompactStatement, ValidatorIndex), ) -> bool { - self.view_knowledge - .get(relay_parent) - .map_or(false, |k| k.can_send(fingerprint)) + self.view_knowledge.get(relay_parent).map_or(false, |k| k.can_send(fingerprint)) } /// Attempt to update our view of the peer's knowledge with this statement's fingerprint based on @@ -497,10 +489,7 @@ impl PeerData { } /// Basic flood protection for large statements. - fn receive_large_statement( - &mut self, - relay_parent: &Hash, - ) -> std::result::Result<(), Rep> { + fn receive_large_statement(&mut self, relay_parent: &Hash) -> std::result::Result<(), Rep> { self.view_knowledge .get_mut(relay_parent) .ok_or(COST_UNEXPECTED_STATEMENT)? @@ -529,7 +518,9 @@ struct StoredStatementComparator { } impl<'a> From<(&'a StoredStatementComparator, &'a SignedFullStatement)> for StoredStatement<'a> { - fn from((comparator, statement): (&'a StoredStatementComparator, &'a SignedFullStatement)) -> Self { + fn from( + (comparator, statement): (&'a StoredStatementComparator, &'a SignedFullStatement), + ) -> Self { Self { comparator, statement } } } @@ -548,7 +539,7 @@ impl<'a> StoredStatement<'a> { enum NotedStatement<'a> { NotUseful, Fresh(StoredStatement<'a>), - UsefulButKnown + UsefulButKnown, } /// Large statement fetching status. @@ -586,12 +577,13 @@ enum MuxedMessage { /// Messages from spawned requester background tasks. Requester(Option), /// Messages from spawned responder background task. - Responder(Option) + Responder(Option), } impl MuxedMessage { async fn receive( - ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), + ctx: &mut (impl SubsystemContext + + overseer::SubsystemContext), from_requester: &mut mpsc::Receiver, from_responder: &mut mpsc::Receiver, ) -> MuxedMessage { @@ -684,7 +676,7 @@ impl ActiveHeadData { ?statement, "Extra statement is ignored" ); - return NotedStatement::NotUseful; + return NotedStatement::NotUseful } self.candidates.insert(h); @@ -706,13 +698,14 @@ impl ActiveHeadData { "Noted new statement" ); // This will always return `Some` because it was just inserted. - let key_value = self.statements + let key_value = self + .statements .get_key_value(&comparator) .expect("Statement was just inserted; qed"); NotedStatement::Fresh(key_value.into()) } - } + }, CompactStatement::Valid(h) => { if !self.candidates.contains(&h) { tracing::trace!( @@ -721,7 +714,7 @@ impl ActiveHeadData { ?statement, "Statement for unknown candidate" ); - return NotedStatement::NotUseful; + return NotedStatement::NotUseful } if let Some(old) = self.statements.insert(comparator.clone(), statement) { @@ -744,18 +737,19 @@ impl ActiveHeadData { self.statements .get_key_value(&comparator) .expect("Statement was just inserted; qed") - .into() + .into(), ) } - } + }, } } /// Returns an error if the statement is already known or not useful /// without modifying the internal state. - fn check_useful_or_unknown(&self, statement: &UncheckedSignedFullStatement) - -> std::result::Result<(), DeniedStatement> - { + fn check_useful_or_unknown( + &self, + statement: &UncheckedSignedFullStatement, + ) -> std::result::Result<(), DeniedStatement> { let validator_index = statement.unchecked_validator_index(); let compact = statement.unchecked_payload().to_compact(); let comparator = StoredStatementComparator { @@ -774,7 +768,7 @@ impl ActiveHeadData { ?statement, "Extra statement is ignored", ); - return Err(DeniedStatement::NotUseful); + return Err(DeniedStatement::NotUseful) } if self.statements.contains_key(&comparator) { @@ -784,9 +778,9 @@ impl ActiveHeadData { ?statement, "Known statement", ); - return Err(DeniedStatement::UsefulButKnown); + return Err(DeniedStatement::UsefulButKnown) } - } + }, CompactStatement::Valid(h) => { if !self.candidates.contains(&h) { tracing::trace!( @@ -795,7 +789,7 @@ impl ActiveHeadData { ?statement, "Statement for unknown candidate", ); - return Err(DeniedStatement::NotUseful); + return Err(DeniedStatement::NotUseful) } if self.statements.contains_key(&comparator) { @@ -805,9 +799,9 @@ impl ActiveHeadData { ?statement, "Known statement", ); - return Err(DeniedStatement::UsefulButKnown); + return Err(DeniedStatement::UsefulButKnown) } - } + }, } Ok(()) } @@ -818,9 +812,12 @@ impl ActiveHeadData { } /// Get an iterator over all statements for the active head that are for a particular candidate. - fn statements_about(&self, candidate_hash: CandidateHash) - -> impl Iterator> + '_ { - self.statements().filter(move |s| s.compact().candidate_hash() == &candidate_hash) + fn statements_about( + &self, + candidate_hash: CandidateHash, + ) -> impl Iterator> + '_ { + self.statements() + .filter(move |s| s.compact().candidate_hash() == &candidate_hash) } } @@ -830,10 +827,8 @@ fn check_statement_signature( relay_parent: Hash, statement: UncheckedSignedFullStatement, ) -> std::result::Result { - let signing_context = SigningContext { - session_index: head.session_index, - parent_hash: relay_parent, - }; + let signing_context = + SigningContext { session_index: head.session_index, parent_hash: relay_parent }; head.validators .get(statement.unchecked_validator_index().0 as usize) @@ -860,7 +855,9 @@ async fn circulate_statement_and_dependents( None => return, }; - let _span = active_head.span.child("circulate-statement") + let _span = active_head + .span + .child("circulate-statement") .with_candidate(statement.payload().candidate_hash()) .with_stage(jaeger::Stage::StatementDistribution); @@ -868,20 +865,11 @@ async fn circulate_statement_and_dependents( // The borrow of `active_head` needs to encompass only this (Rust) statement. let outputs: Option<(CandidateHash, Vec)> = { match active_head.note_statement(statement) { - NotedStatement::Fresh(stored) => - { - Some(( - *stored.compact().candidate_hash(), - circulate_statement( - gossip_peers, - peers, - ctx, - relay_parent, - stored, - priority_peers, - ).await, - )) - }, + NotedStatement::Fresh(stored) => Some(( + *stored.compact().candidate_hash(), + circulate_statement(gossip_peers, peers, ctx, relay_parent, stored, priority_peers) + .await, + )), _ => None, } }; @@ -891,8 +879,7 @@ async fn circulate_statement_and_dependents( if let Some((candidate_hash, peers_needing_dependents)) = outputs { for peer in peers_needing_dependents { if let Some(peer_data) = peers.get_mut(&peer) { - let _span_loop = _span.child("to-peer") - .with_peer_id(&peer); + let _span_loop = _span.child("to-peer").with_peer_id(&peer); // defensive: the peer data should always be some because the iterator // of peers is derived from the set of peers. send_statements_about( @@ -903,24 +890,24 @@ async fn circulate_statement_and_dependents( candidate_hash, &*active_head, metrics, - ).await; + ) + .await; } } } } -fn statement_message(relay_parent: Hash, statement: SignedFullStatement) - -> protocol_v1::ValidationProtocol -{ +fn statement_message( + relay_parent: Hash, + statement: SignedFullStatement, +) -> protocol_v1::ValidationProtocol { let msg = if is_statement_large(&statement) { - protocol_v1::StatementDistributionMessage::LargeStatement( - StatementMetadata { - relay_parent, - candidate_hash: statement.payload().candidate_hash(), - signed_by: statement.validator_index(), - signature: statement.signature().clone(), - } - ) + protocol_v1::StatementDistributionMessage::LargeStatement(StatementMetadata { + relay_parent, + candidate_hash: statement.payload().candidate_hash(), + signed_by: statement.validator_index(), + signature: statement.signature().clone(), + }) } else { protocol_v1::StatementDistributionMessage::Statement(relay_parent, statement.into()) }; @@ -941,13 +928,11 @@ fn is_statement_large(statement: &SignedFullStatement) -> bool { // Half max size seems to be a good threshold to start not using notifications: let threshold = - PeerSet::Validation.get_info(IsAuthority::Yes) - .max_notification_size as usize / 2; + PeerSet::Validation.get_info(IsAuthority::Yes).max_notification_size as usize / 2; size >= threshold - } - Statement::Valid(_) => - false, + }, + Statement::Valid(_) => false, } } @@ -963,13 +948,16 @@ async fn circulate_statement<'a>( ) -> Vec { let fingerprint = stored.fingerprint(); - let mut peers_to_send: Vec = peers.iter().filter_map(|(peer, data)| { - if data.can_send(&relay_parent, &fingerprint) { - Some(peer.clone()) - } else { - None - } - }).collect(); + let mut peers_to_send: Vec = peers + .iter() + .filter_map(|(peer, data)| { + if data.can_send(&relay_parent, &fingerprint) { + Some(peer.clone()) + } else { + None + } + }) + .collect(); let good_peers: HashSet<&PeerId> = peers_to_send.iter().collect(); // Only take priority peers we can send data to: @@ -980,11 +968,7 @@ async fn circulate_statement<'a>( peers_to_send.retain(|p| !priority_set.contains(p)); let mut peers_to_send = - util::choose_random_subset( - |e| gossip_peers.contains(e), - peers_to_send, - MIN_GOSSIP_PEERS, - ); + util::choose_random_subset(|e| gossip_peers.contains(e), peers_to_send, MIN_GOSSIP_PEERS); // We don't want to use less peers, than we would without any priority peers: let min_size = std::cmp::max(peers_to_send.len(), MIN_GOSSIP_PEERS); // Make set full: @@ -1002,13 +986,16 @@ async fn circulate_statement<'a>( peers_to_send.len() == peers_to_send.clone().into_iter().collect::>().len(), "We filter out duplicates above. qed.", ); - let peers_to_send: Vec<(PeerId, bool)> = peers_to_send.into_iter() + let peers_to_send: Vec<(PeerId, bool)> = peers_to_send + .into_iter() .map(|peer_id| { - let new = peers.get_mut(&peer_id) + let new = peers + .get_mut(&peer_id) .expect("a subset is taken above, so it exists; qed") .send(&relay_parent, &fingerprint); (peer_id, new) - }).collect(); + }) + .collect(); // Send all these peers the initial statement. if !peers_to_send.is_empty() { @@ -1023,14 +1010,14 @@ async fn circulate_statement<'a>( ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage( peers_to_send.iter().map(|(p, _)| p.clone()).collect(), payload, - ))).await; + ))) + .await; } - peers_to_send.into_iter().filter_map(|(peer, needs_dependent)| if needs_dependent { - Some(peer) - } else { - None - }).collect() + peers_to_send + .into_iter() + .filter_map(|(peer, needs_dependent)| if needs_dependent { Some(peer) } else { None }) + .collect() } /// Send all statements about a given candidate hash to a peer. @@ -1046,13 +1033,10 @@ async fn send_statements_about( for statement in active_head.statements_about(candidate_hash) { let fingerprint = statement.fingerprint(); if !peer_data.can_send(&relay_parent, &fingerprint) { - continue; + continue } peer_data.send(&relay_parent, &fingerprint); - let payload = statement_message( - relay_parent, - statement.statement.clone(), - ); + let payload = statement_message(relay_parent, statement.statement.clone()); tracing::trace!( target: LOG_TARGET, @@ -1062,9 +1046,11 @@ async fn send_statements_about( statement = ?statement.statement, "Sending statement", ); - ctx.send_message(AllMessages::NetworkBridge( - NetworkBridgeMessage::SendValidationMessage(vec![peer.clone()], payload) - )).await; + ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage( + vec![peer.clone()], + payload, + ))) + .await; metrics.on_statement_distributed(); } @@ -1082,13 +1068,10 @@ async fn send_statements( for statement in active_head.statements() { let fingerprint = statement.fingerprint(); if !peer_data.can_send(&relay_parent, &fingerprint) { - continue; + continue } peer_data.send(&relay_parent, &fingerprint); - let payload = statement_message( - relay_parent, - statement.statement.clone(), - ); + let payload = statement_message(relay_parent, statement.statement.clone()); tracing::trace!( target: LOG_TARGET, @@ -1097,9 +1080,11 @@ async fn send_statements( statement = ?statement.statement, "Sending statement" ); - ctx.send_message(AllMessages::NetworkBridge( - NetworkBridgeMessage::SendValidationMessage(vec![peer.clone()], payload) - )).await; + ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage( + vec![peer.clone()], + payload, + ))) + .await; metrics.on_statement_distributed(); } @@ -1110,9 +1095,8 @@ async fn report_peer( peer: PeerId, rep: Rep, ) { - ctx.send_message(AllMessages::NetworkBridge( - NetworkBridgeMessage::ReportPeer(peer, rep) - )).await + ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(peer, rep))) + .await } /// If message contains a statement, then retrieve it, otherwise fork task to fetch it. @@ -1130,38 +1114,34 @@ async fn retrieve_statement_from_message<'a>( req_sender: &mpsc::Sender, metrics: &Metrics, ) -> Option { - let fingerprint = message.get_fingerprint(); let candidate_hash = *fingerprint.0.candidate_hash(); // Immediately return any Seconded statement: - let message = - if let protocol_v1::StatementDistributionMessage::Statement(h, s) = message { - if let Statement::Seconded(_) = s.unchecked_payload() { - return Some(s) - } - protocol_v1::StatementDistributionMessage::Statement(h, s) - } else { - message - }; + let message = if let protocol_v1::StatementDistributionMessage::Statement(h, s) = message { + if let Statement::Seconded(_) = s.unchecked_payload() { + return Some(s) + } + protocol_v1::StatementDistributionMessage::Statement(h, s) + } else { + message + }; match active_head.waiting_large_statements.entry(candidate_hash) { Entry::Occupied(mut occupied) => { match occupied.get_mut() { LargeStatementStatus::Fetching(info) => { - let is_large_statement = message.is_large_statement(); - let is_new_peer = - match info.available_peers.entry(peer) { - IEntry::Occupied(mut occupied) => { - occupied.get_mut().push(message); - false - } - IEntry::Vacant(vacant) => { - vacant.insert(vec![message]); - true - } + let is_new_peer = match info.available_peers.entry(peer) { + IEntry::Occupied(mut occupied) => { + occupied.get_mut().push(message); + false + }, + IEntry::Vacant(vacant) => { + vacant.insert(vec![message]); + true + }, }; if is_new_peer & is_large_statement { @@ -1176,47 +1156,41 @@ async fn retrieve_statement_from_message<'a>( } } } - } + }, LargeStatementStatus::FetchedOrShared(committed) => { match message { protocol_v1::StatementDistributionMessage::Statement(_, s) => { // We can now immediately return any statements (should only be // `Statement::Valid` ones, but we don't care at this point.) return Some(s) - } - protocol_v1::StatementDistributionMessage::LargeStatement(metadata) => { + }, + protocol_v1::StatementDistributionMessage::LargeStatement(metadata) => return Some(UncheckedSignedFullStatement::new( - Statement::Seconded( - committed.clone()), - metadata.signed_by, - metadata.signature.clone(), - )) - } + Statement::Seconded(committed.clone()), + metadata.signed_by, + metadata.signature.clone(), + )), } - } + }, } - } + }, Entry::Vacant(vacant) => { match message { protocol_v1::StatementDistributionMessage::LargeStatement(metadata) => { - if let Some(new_status) = launch_request( - metadata, - peer, - req_sender.clone(), - ctx, - metrics - ).await { + if let Some(new_status) = + launch_request(metadata, peer, req_sender.clone(), ctx, metrics).await + { vacant.insert(new_status); } - } + }, protocol_v1::StatementDistributionMessage::Statement(_, s) => { // No fetch in progress, safe to return any statement immediately (we don't bother // about normal network jitter which might cause `Valid` statements to arrive early // for now.). return Some(s) - } + }, } - } + }, } None } @@ -1231,15 +1205,9 @@ async fn launch_request( ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), metrics: &Metrics, ) -> Option { - - let (task, handle) = fetch( - meta.relay_parent, - meta.candidate_hash, - vec![peer], - req_sender, - metrics.clone(), - ) - .remote_handle(); + let (task, handle) = + fetch(meta.relay_parent, meta.candidate_hash, vec![peer], req_sender, metrics.clone()) + .remote_handle(); let result = ctx.spawn("large-statement-fetcher", task.boxed()); if let Err(err) = result { @@ -1272,17 +1240,9 @@ async fn handle_incoming_message_and_circulate<'a>( metrics: &Metrics, ) { let handled_incoming = match peers.get_mut(&peer) { - Some(data) => { - handle_incoming_message( - peer, - data, - active_heads, - ctx, - message, - req_sender, - metrics, - ).await - } + Some(data) => + handle_incoming_message(peer, data, active_heads, ctx, message, req_sender, metrics) + .await, None => None, }; @@ -1295,14 +1255,8 @@ async fn handle_incoming_message_and_circulate<'a>( // statement before a `Seconded` statement. `Seconded` statements are the only ones // that require dependents. Thus, if this is a `Seconded` statement for a candidate we // were not aware of before, we cannot have any dependent statements from the candidate. - let _ = circulate_statement( - gossip_peers, - peers, - ctx, - relay_parent, - statement, - Vec::new(), - ).await; + let _ = circulate_statement(gossip_peers, peers, ctx, relay_parent, statement, Vec::new()) + .await; } } @@ -1332,7 +1286,7 @@ async fn handle_incoming_message<'a>( ); report_peer(ctx, peer, COST_UNEXPECTED_STATEMENT).await; return None - } + }, }; if let protocol_v1::StatementDistributionMessage::LargeStatement(_) = message { @@ -1345,13 +1299,15 @@ async fn handle_incoming_message<'a>( "Unexpected large statement.", ); report_peer(ctx, peer, rep).await; - return None; + return None } } let fingerprint = message.get_fingerprint(); let candidate_hash = fingerprint.0.candidate_hash().clone(); - let handle_incoming_span = active_head.span.child("handle-incoming") + let handle_incoming_span = active_head + .span + .child("handle-incoming") .with_candidate(candidate_hash) .with_peer_id(&peer); @@ -1368,41 +1324,29 @@ async fn handle_incoming_message<'a>( "Error inserting received statement" ); report_peer(ctx, peer, rep).await; - return None; + return None } - let statement = retrieve_statement_from_message( - peer, - message, - active_head, - ctx, - req_sender, - metrics, - ).await?; + let statement = + retrieve_statement_from_message(peer, message, active_head, ctx, req_sender, metrics) + .await?; match active_head.check_useful_or_unknown(&statement) { Ok(()) => {}, - Err(DeniedStatement::NotUseful) => { - return None; - } + Err(DeniedStatement::NotUseful) => return None, Err(DeniedStatement::UsefulButKnown) => { report_peer(ctx, peer, BENEFIT_VALID_STATEMENT).await; - return None; - } + return None + }, } // check the signature on the statement. let statement = match check_statement_signature(&active_head, relay_parent, statement) { Err(statement) => { - tracing::debug!( - target: LOG_TARGET, - ?peer, - ?statement, - "Invalid statement signature" - ); + tracing::debug!(target: LOG_TARGET, ?peer, ?statement, "Invalid statement signature"); report_peer(ctx, peer, COST_INVALID_SIGNATURE).await; return None - } + }, Ok(statement) => statement, }; @@ -1413,14 +1357,9 @@ async fn handle_incoming_message<'a>( match peer_data.receive(&relay_parent, &fingerprint, max_message_count) { Err(_) => { unreachable!("checked in `check_can_receive` above; qed"); - } + }, Ok(true) => { - tracing::trace!( - target: LOG_TARGET, - ?peer, - ?statement, - "Statement accepted" - ); + tracing::trace!(target: LOG_TARGET, ?peer, ?statement, "Statement accepted"); // Send the peer all statements concerning the candidate that we have, // since it appears to have just learned about the candidate. send_statements_about( @@ -1431,18 +1370,18 @@ async fn handle_incoming_message<'a>( candidate_hash, &*active_head, metrics, - ).await; - } - Ok(false) => {} + ) + .await; + }, + Ok(false) => {}, } // Note: `peer_data.receive` already ensures that the statement is not an unbounded equivocation // or unpinned to a seconded candidate. So it is safe to place it into the storage. match active_head.note_statement(statement) { - NotedStatement::NotUseful | - NotedStatement::UsefulButKnown => { + NotedStatement::NotUseful | NotedStatement::UsefulButKnown => { unreachable!("checked in `is_useful_or_unknown` above; qed"); - } + }, NotedStatement::Fresh(statement) => { report_peer(ctx, peer, BENEFIT_VALID_STATEMENT_FIRST).await; @@ -1450,10 +1389,14 @@ async fn handle_incoming_message<'a>( // When we receive a new message from a peer, we forward it to the // candidate backing subsystem. - ctx.send_message(CandidateBackingMessage::Statement(relay_parent, statement.statement.clone())).await; + ctx.send_message(CandidateBackingMessage::Statement( + relay_parent, + statement.statement.clone(), + )) + .await; Some((relay_parent, statement)) - } + }, } } @@ -1475,10 +1418,11 @@ async fn update_peer_view_and_maybe_send_unlocked( } let is_gossip_peer = gossip_peers.contains(&peer); - let lucky = is_gossip_peer || util::gen_ratio( - util::MIN_GOSSIP_PEERS.saturating_sub(gossip_peers.len()), - util::MIN_GOSSIP_PEERS, - ); + let lucky = is_gossip_peer || + util::gen_ratio( + util::MIN_GOSSIP_PEERS.saturating_sub(gossip_peers.len()), + util::MIN_GOSSIP_PEERS, + ); // Add entries for all relay-parents in the new view but not the old. // Furthermore, send all statements we have for those relay parents. @@ -1486,17 +1430,10 @@ async fn update_peer_view_and_maybe_send_unlocked( for new in new_view.iter().copied() { peer_data.view_knowledge.insert(new, Default::default()); if !lucky { - continue; + continue } if let Some(active_head) = active_heads.get(&new) { - send_statements( - peer.clone(), - peer_data, - ctx, - new, - active_head, - metrics, - ).await; + send_statements(peer.clone(), peer_data, ctx, new, active_head, metrics).await; } } } @@ -1513,31 +1450,25 @@ async fn handle_network_update( ) { match update { NetworkBridgeEvent::PeerConnected(peer, role, maybe_authority) => { - tracing::trace!( - target: LOG_TARGET, - ?peer, - ?role, - "Peer connected", + tracing::trace!(target: LOG_TARGET, ?peer, ?role, "Peer connected",); + peers.insert( + peer, + PeerData { + view: Default::default(), + view_knowledge: Default::default(), + maybe_authority: maybe_authority.clone(), + }, ); - peers.insert(peer, PeerData { - view: Default::default(), - view_knowledge: Default::default(), - maybe_authority: maybe_authority.clone(), - }); if let Some(authority) = maybe_authority { authorities.insert(authority, peer); } - } + }, NetworkBridgeEvent::PeerDisconnected(peer) => { - tracing::trace!( - target: LOG_TARGET, - ?peer, - "Peer disconnected", - ); + tracing::trace!(target: LOG_TARGET, ?peer, "Peer disconnected",); if let Some(auth_id) = peers.remove(&peer).and_then(|p| p.maybe_authority) { authorities.remove(&auth_id); } - } + }, NetworkBridgeEvent::NewGossipTopology(new_peers) => { let newly_added: Vec = new_peers.difference(gossip_peers).cloned().collect(); *gossip_peers = new_peers; @@ -1552,10 +1483,11 @@ async fn handle_network_update( &*active_heads, view, metrics, - ).await + ) + .await } } - } + }, NetworkBridgeEvent::PeerMessage(peer, message) => { handle_incoming_message_and_circulate( peer, @@ -1566,17 +1498,13 @@ async fn handle_network_update( message, req_sender, metrics, - ).await; - } + ) + .await; + }, NetworkBridgeEvent::PeerViewChange(peer, view) => { - tracing::trace!( - target: LOG_TARGET, - ?peer, - ?view, - "Peer view change", - ); + tracing::trace!(target: LOG_TARGET, ?peer, ?view, "Peer view change",); match peers.get_mut(&peer) { - Some(data) => { + Some(data) => update_peer_view_and_maybe_send_unlocked( peer, gossip_peers, @@ -1585,21 +1513,22 @@ async fn handle_network_update( &*active_heads, view, metrics, - ).await - } + ) + .await, None => (), } - } + }, NetworkBridgeEvent::OurViewChange(_view) => { // handled by `ActiveLeavesUpdate` - } + }, } } impl StatementDistribution { async fn run( self, - mut ctx: (impl SubsystemContext + overseer::SubsystemContext), + mut ctx: (impl SubsystemContext + + overseer::SubsystemContext), ) -> std::result::Result<(), Fatal> { let mut peers: HashMap = HashMap::new(); let mut gossip_peers: HashSet = HashSet::new(); @@ -1614,50 +1543,54 @@ impl StatementDistribution { let (res_sender, mut res_receiver) = mpsc::channel(1); loop { - let message = MuxedMessage::receive(&mut ctx, &mut req_receiver, &mut res_receiver).await; + let message = + MuxedMessage::receive(&mut ctx, &mut req_receiver, &mut res_receiver).await; match message { MuxedMessage::Subsystem(result) => { - let result = self.handle_subsystem_message( - &mut ctx, - &mut runtime, - &mut peers, - &mut gossip_peers, - &mut authorities, - &mut active_heads, - &req_sender, - &res_sender, - result?, - ) - .await; + let result = self + .handle_subsystem_message( + &mut ctx, + &mut runtime, + &mut peers, + &mut gossip_peers, + &mut authorities, + &mut active_heads, + &req_sender, + &res_sender, + result?, + ) + .await; match result { Ok(true) => break, - Ok(false) => {} + Ok(false) => {}, Err(Error(Fault::Fatal(f))) => return Err(f), Err(Error(Fault::Err(error))) => - tracing::debug!(target: LOG_TARGET, ?error) + tracing::debug!(target: LOG_TARGET, ?error), } - } + }, MuxedMessage::Requester(result) => { - let result = self.handle_requester_message( - &mut ctx, - &gossip_peers, - &mut peers, - &mut active_heads, - &req_sender, - result.ok_or(Fatal::RequesterReceiverFinished)? - ) - .await; + let result = self + .handle_requester_message( + &mut ctx, + &gossip_peers, + &mut peers, + &mut active_heads, + &req_sender, + result.ok_or(Fatal::RequesterReceiverFinished)?, + ) + .await; log_error(result.map_err(From::from), "handle_requester_message")?; - } + }, MuxedMessage::Responder(result) => { - let result = self.handle_responder_message( - &peers, - &mut active_heads, - result.ok_or(Fatal::ResponderReceiverFinished)? - ) - .await; + let result = self + .handle_responder_message( + &peers, + &mut active_heads, + result.ok_or(Fatal::ResponderReceiverFinished)?, + ) + .await; log_error(result.map_err(From::from), "handle_responder_message")?; - } + }, }; } Ok(()) @@ -1671,38 +1604,33 @@ impl StatementDistribution { message: ResponderMessage, ) -> NonFatalResult<()> { match message { - ResponderMessage::GetData { - requesting_peer, - relay_parent, - candidate_hash, - tx, - } => { + ResponderMessage::GetData { requesting_peer, relay_parent, candidate_hash, tx } => { if !requesting_peer_knows_about_candidate( peers, &requesting_peer, &relay_parent, - &candidate_hash + &candidate_hash, ) { - return Err( - NonFatal::RequestedUnannouncedCandidate(requesting_peer, candidate_hash) - ) + return Err(NonFatal::RequestedUnannouncedCandidate( + requesting_peer, + candidate_hash, + )) } - let active_head = active_heads - .get(&relay_parent) - .ok_or(NonFatal::NoSuchHead(relay_parent))?; + let active_head = + active_heads.get(&relay_parent).ok_or(NonFatal::NoSuchHead(relay_parent))?; let committed = match active_head.waiting_large_statements.get(&candidate_hash) { Some(LargeStatementStatus::FetchedOrShared(committed)) => committed.clone(), - _ => { - return Err( - NonFatal::NoSuchFetchedLargeStatement(relay_parent, candidate_hash) - ) - } + _ => + return Err(NonFatal::NoSuchFetchedLargeStatement( + relay_parent, + candidate_hash, + )), }; tx.send(committed).map_err(|_| NonFatal::ResponderGetDataCanceled)?; - } + }, } Ok(()) } @@ -1733,27 +1661,24 @@ impl StatementDistribution { .get_mut(&relay_parent) .ok_or(NonFatal::NoSuchHead(relay_parent))?; - let status = active_head - .waiting_large_statements - .remove(&candidate_hash); + let status = active_head.waiting_large_statements.remove(&candidate_hash); let info = match status { Some(LargeStatementStatus::Fetching(info)) => info, Some(LargeStatementStatus::FetchedOrShared(_)) => { // We are no longer interested in the data. return Ok(()) - } - None => { - return Err( - NonFatal::NoSuchLargeStatementStatus(relay_parent, candidate_hash) - ) - } + }, + None => + return Err(NonFatal::NoSuchLargeStatementStatus( + relay_parent, + candidate_hash, + )), }; - active_head.waiting_large_statements.insert( - candidate_hash, - LargeStatementStatus::FetchedOrShared(response), - ); + active_head + .waiting_large_statements + .insert(candidate_hash, LargeStatementStatus::FetchedOrShared(response)); // Cache is now populated, send all messages: for (peer, messages) in info.available_peers { @@ -1771,45 +1696,33 @@ impl StatementDistribution { .await; } } - } + }, RequesterMessage::SendRequest(req) => { - ctx.send_message( - AllMessages::NetworkBridge( - NetworkBridgeMessage::SendRequests( - vec![req], - IfDisconnected::ImmediateError, - ) - )) - .await; - } - RequesterMessage::GetMorePeers { - relay_parent, - candidate_hash, - tx, - } => { + ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests( + vec![req], + IfDisconnected::ImmediateError, + ))) + .await; + }, + RequesterMessage::GetMorePeers { relay_parent, candidate_hash, tx } => { let active_head = active_heads .get_mut(&relay_parent) .ok_or(NonFatal::NoSuchHead(relay_parent))?; - let status = active_head - .waiting_large_statements - .get_mut(&candidate_hash); + let status = active_head.waiting_large_statements.get_mut(&candidate_hash); let info = match status { Some(LargeStatementStatus::Fetching(info)) => info, Some(LargeStatementStatus::FetchedOrShared(_)) => { // This task is going to die soon - no need to send it anything. - tracing::debug!( - target: LOG_TARGET, - "Zombie task wanted more peers." - ); + tracing::debug!(target: LOG_TARGET, "Zombie task wanted more peers."); return Ok(()) - } - None => { - return Err( - NonFatal::NoSuchLargeStatementStatus(relay_parent, candidate_hash) - ) - } + }, + None => + return Err(NonFatal::NoSuchLargeStatementStatus( + relay_parent, + candidate_hash, + )), }; if info.peers_to_try.is_empty() { @@ -1821,14 +1734,12 @@ impl StatementDistribution { info.peers_to_try = peers; } } - } - RequesterMessage::ReportPeer(peer, rep) => - report_peer(ctx, peer, rep).await, + }, + RequesterMessage::ReportPeer(peer, rep) => report_peer(ctx, peer, rep).await, } Ok(()) } - async fn handle_subsystem_message( &self, ctx: &mut (impl SubsystemContext + overseer::SubsystemContext), @@ -1844,7 +1755,10 @@ impl StatementDistribution { let metrics = &self.metrics; match message { - FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { activated, deactivated })) => { + FromOverseer::Signal(OverseerSignal::ActiveLeaves(ActiveLeavesUpdate { + activated, + deactivated, + })) => { let _timer = metrics.time_active_leaves_update(); for deactivated in deactivated { @@ -1866,17 +1780,23 @@ impl StatementDistribution { "New active leaf", ); - let session_index = runtime.get_session_index(ctx.sender(), relay_parent).await?; - let info = runtime.get_session_info_by_index(ctx.sender(), relay_parent, session_index).await?; + let session_index = + runtime.get_session_index(ctx.sender(), relay_parent).await?; + let info = runtime + .get_session_info_by_index(ctx.sender(), relay_parent, session_index) + .await?; let session_info = &info.session_info; - active_heads.entry(relay_parent) - .or_insert(ActiveHeadData::new(session_info.validators.clone(), session_index, span)); + active_heads.entry(relay_parent).or_insert(ActiveHeadData::new( + session_info.validators.clone(), + session_index, + span, + )); } - } + }, FromOverseer::Signal(OverseerSignal::BlockFinalized(..)) => { // do nothing - } + }, FromOverseer::Signal(OverseerSignal::Conclude) => return Ok(true), FromOverseer::Communication { msg } => match msg { StatementDistributionMessage::Share(relay_parent, statement) => { @@ -1892,7 +1812,7 @@ impl StatementDistribution { .ok_or(NonFatal::NoSuchHead(relay_parent))?; active_head.waiting_large_statements.insert( statement.payload().candidate_hash(), - LargeStatementStatus::FetchedOrShared(committed.clone()) + LargeStatementStatus::FetchedOrShared(committed.clone()), ); } } @@ -1907,7 +1827,8 @@ impl StatementDistribution { if let Some(our_group) = validator_info.our_group { let our_group = &session_info.validator_groups[our_group.0 as usize]; - our_group.into_iter() + our_group + .into_iter() .filter_map(|i| { if Some(*i) == validator_info.our_index { return None @@ -1929,8 +1850,9 @@ impl StatementDistribution { statement, group_peers, metrics, - ).await; - } + ) + .await; + }, StatementDistributionMessage::NetworkBridgeUpdateV1(event) => { let _timer = metrics.time_network_bridge_update_v1(); @@ -1943,15 +1865,17 @@ impl StatementDistribution { req_sender, event, metrics, - ).await; - } + ) + .await; + }, StatementDistributionMessage::StatementFetchingReceiver(receiver) => { ctx.spawn( "large-statement-responder", - respond(receiver, res_sender.clone()).boxed() - ).map_err(Fatal::SpawnTask)?; - } - } + respond(receiver, res_sender.clone()).boxed(), + ) + .map_err(Fatal::SpawnTask)?; + }, + }, } Ok(false) } @@ -1971,7 +1895,8 @@ fn requesting_peer_knows_about_candidate( requesting_peer, relay_parent, candidate_hash, - ).is_some() + ) + .is_some() } /// Helper function for `requesting_peer_knows_about_statement`. @@ -2032,25 +1957,29 @@ impl Metrics { } /// Provide a timer for `network_bridge_update_v1` which observes on drop. - fn time_network_bridge_update_v1(&self) -> Option { + fn time_network_bridge_update_v1( + &self, + ) -> Option { self.0.as_ref().map(|metrics| metrics.network_bridge_update_v1.start_timer()) } } impl metrics::Metrics for Metrics { - fn try_register(registry: &prometheus::Registry) -> std::result::Result { + fn try_register( + registry: &prometheus::Registry, + ) -> std::result::Result { let metrics = MetricsInner { statements_distributed: prometheus::register( prometheus::Counter::new( "parachain_statements_distributed_total", - "Number of candidate validity statements distributed to other peers." + "Number of candidate validity statements distributed to other peers.", )?, registry, )?, sent_requests: prometheus::register( prometheus::Counter::new( "parachain_statement_distribution_sent_requests_total", - "Number of large statement fetching requests sent." + "Number of large statement fetching requests sent.", )?, registry, )?, @@ -2058,37 +1987,31 @@ impl metrics::Metrics for Metrics { prometheus::CounterVec::new( prometheus::Opts::new( "parachain_statement_distribution_received_responses_total", - "Number of received responses for large statement data." + "Number of received responses for large statement data.", ), &["success"], )?, registry, )?, active_leaves_update: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_statement_distribution_active_leaves_update", - "Time spent within `statement_distribution::active_leaves_update`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_statement_distribution_active_leaves_update", + "Time spent within `statement_distribution::active_leaves_update`", + ))?, registry, )?, share: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_statement_distribution_share", - "Time spent within `statement_distribution::share`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_statement_distribution_share", + "Time spent within `statement_distribution::share`", + ))?, registry, )?, network_bridge_update_v1: prometheus::register( - prometheus::Histogram::with_opts( - prometheus::HistogramOpts::new( - "parachain_statement_distribution_network_bridge_update_v1", - "Time spent within `statement_distribution::network_bridge_update_v1`", - ) - )?, + prometheus::Histogram::with_opts(prometheus::HistogramOpts::new( + "parachain_statement_distribution_network_bridge_update_v1", + "Time spent within `statement_distribution::network_bridge_update_v1`", + ))?, registry, )?, }; diff --git a/polkadot/node/network/statement-distribution/src/requester.rs b/polkadot/node/network/statement-distribution/src/requester.rs index 47201e3ce72..e3a4afd61ac 100644 --- a/polkadot/node/network/statement-distribution/src/requester.rs +++ b/polkadot/node/network/statement-distribution/src/requester.rs @@ -16,21 +16,23 @@ use std::time::Duration; -use futures::{SinkExt, channel::{mpsc, oneshot}}; +use futures::{ + channel::{mpsc, oneshot}, + SinkExt, +}; use polkadot_node_network_protocol::{ - PeerId, UnifiedReputationChange, request_response::{ + v1::{StatementFetchingRequest, StatementFetchingResponse}, OutgoingRequest, Recipient, Requests, - v1::{ - StatementFetchingRequest, StatementFetchingResponse - } - }}; + }, + PeerId, UnifiedReputationChange, +}; use polkadot_node_subsystem_util::TimeoutExt; use polkadot_primitives::v1::{CandidateHash, CommittedCandidateReceipt, Hash}; use polkadot_subsystem::{Span, Stage}; -use crate::{LOG_TARGET, Metrics, COST_WRONG_HASH}; +use crate::{Metrics, COST_WRONG_HASH, LOG_TARGET}; // In case we failed fetching from our known peers, how long we should wait before attempting a // retry, even though we have not yet discovered any new peers. Or in other words how long to @@ -43,7 +45,7 @@ pub enum RequesterMessage { GetMorePeers { relay_parent: Hash, candidate_hash: CandidateHash, - tx: oneshot::Sender> + tx: oneshot::Sender>, }, /// Fetching finished, ask for verification. If verification fails, task will continue asking /// peers for data. @@ -65,7 +67,6 @@ pub enum RequesterMessage { SendRequest(Requests), } - /// A fetching task, taking care of fetching large statements via request/response. /// /// A fetch task does not know about a particular `Statement` instead it just tries fetching a @@ -87,28 +88,21 @@ pub async fn fetch( // Peers left for trying out. let mut new_peers = peers; - let req = StatementFetchingRequest { - relay_parent, - candidate_hash, - }; + let req = StatementFetchingRequest { relay_parent, candidate_hash }; // We retry endlessly (with sleep periods), and rely on the subsystem to kill us eventually. loop { - let span = span.child("try-available-peers"); while let Some(peer) = new_peers.pop() { - - let _span = span.child("try-peer") - .with_peer_id(&peer); - - let (outgoing, pending_response) = OutgoingRequest::new( - Recipient::Peer(peer), - req.clone(), - ); - if let Err(err) = sender.feed( - RequesterMessage::SendRequest(Requests::StatementFetching(outgoing)) - ).await { + let _span = span.child("try-peer").with_peer_id(&peer); + + let (outgoing, pending_response) = + OutgoingRequest::new(Recipient::Peer(peer), req.clone()); + if let Err(err) = sender + .feed(RequesterMessage::SendRequest(Requests::StatementFetching(outgoing))) + .await + { tracing::info!( target: LOG_TARGET, ?err, @@ -121,13 +115,12 @@ pub async fn fetch( match pending_response.await { Ok(StatementFetchingResponse::Statement(statement)) => { - if statement.hash() != candidate_hash { metrics.on_received_response(false); - if let Err(err) = sender.feed( - RequesterMessage::ReportPeer(peer, COST_WRONG_HASH) - ).await { + if let Err(err) = + sender.feed(RequesterMessage::ReportPeer(peer, COST_WRONG_HASH)).await + { tracing::warn!( target: LOG_TARGET, ?err, @@ -138,15 +131,16 @@ pub async fn fetch( continue } - if let Err(err) = sender.feed( - RequesterMessage::Finished { + if let Err(err) = sender + .feed(RequesterMessage::Finished { relay_parent, candidate_hash, from_peer: peer, response: statement, bad_peers: tried_peers, - } - ).await { + }) + .await + { tracing::warn!( target: LOG_TARGET, ?err, @@ -167,7 +161,7 @@ pub async fn fetch( ); metrics.on_received_response(false); - } + }, } tried_peers.push(peer); @@ -178,14 +172,10 @@ pub async fn fetch( // All our peers failed us - try getting new ones before trying again: match try_get_new_peers(relay_parent, candidate_hash, &mut sender, &span).await { Ok(Some(mut peers)) => { - tracing::trace!( - target: LOG_TARGET, - ?peers, - "Received new peers." - ); + tracing::trace!(target: LOG_TARGET, ?peers, "Received new peers."); // New arrivals will be tried first: new_peers.append(&mut peers); - } + }, // No new peers, try the old ones again (if we have any): Ok(None) => { // Note: In case we don't have any more peers, we will just keep asking for new @@ -205,14 +195,14 @@ async fn try_get_new_peers( sender: &mut mpsc::Sender, span: &Span, ) -> Result>, ()> { - let _span = span.child("wait-for-peers"); let (tx, rx) = oneshot::channel(); - if let Err(err) = sender.send( - RequesterMessage::GetMorePeers { relay_parent, candidate_hash, tx } - ).await { + if let Err(err) = sender + .send(RequesterMessage::GetMorePeers { relay_parent, candidate_hash, tx }) + .await + { tracing::debug!( target: LOG_TARGET, ?err, @@ -223,13 +213,9 @@ async fn try_get_new_peers( match rx.timeout(RETRY_TIMEOUT).await.transpose() { Err(_) => { - tracing::debug!( - target: LOG_TARGET, - "Failed fetching more peers." - ); + tracing::debug!(target: LOG_TARGET, "Failed fetching more peers."); Err(()) - } - Ok(val) => Ok(val) + }, + Ok(val) => Ok(val), } } - diff --git a/polkadot/node/network/statement-distribution/src/responder.rs b/polkadot/node/network/statement-distribution/src/responder.rs index bcaefdfcde5..e42302cd82a 100644 --- a/polkadot/node/network/statement-distribution/src/responder.rs +++ b/polkadot/node/network/statement-distribution/src/responder.rs @@ -14,16 +14,19 @@ //! Large statement responding background task logic. -use futures::{SinkExt, StreamExt, channel::{mpsc, oneshot}, stream::FuturesUnordered}; +use futures::{ + channel::{mpsc, oneshot}, + stream::FuturesUnordered, + SinkExt, StreamExt, +}; use polkadot_node_network_protocol::{ - PeerId, UnifiedReputationChange as Rep, request_response::{ - IncomingRequest, MAX_PARALLEL_STATEMENT_REQUESTS, request::OutgoingResponse, - v1::{ - StatementFetchingRequest, StatementFetchingResponse - }, + request::OutgoingResponse, + v1::{StatementFetchingRequest, StatementFetchingResponse}, + IncomingRequest, MAX_PARALLEL_STATEMENT_REQUESTS, }, + PeerId, UnifiedReputationChange as Rep, }; use polkadot_primitives::v1::{CandidateHash, CommittedCandidateReceipt, Hash}; @@ -38,11 +41,10 @@ pub enum ResponderMessage { requesting_peer: PeerId, relay_parent: Hash, candidate_hash: CandidateHash, - tx: oneshot::Sender + tx: oneshot::Sender, }, } - /// A fetching task, taking care of fetching large statements via request/response. /// /// A fetch task does not know about a particular `Statement` instead it just tries fetching a @@ -74,56 +76,41 @@ pub async fn respond( let raw = match receiver.next().await { None => { - tracing::debug!( - target: LOG_TARGET, - "Shutting down request responder" - ); + tracing::debug!(target: LOG_TARGET, "Shutting down request responder"); return - } + }, Some(v) => v, }; - let req = - match IncomingRequest::::try_from_raw( - raw, - vec![COST_INVALID_REQUEST], - ) { + let req = match IncomingRequest::::try_from_raw( + raw, + vec![COST_INVALID_REQUEST], + ) { Err(err) => { - tracing::debug!( - target: LOG_TARGET, - ?err, - "Decoding request failed" - ); + tracing::debug!(target: LOG_TARGET, ?err, "Decoding request failed"); continue - } + }, Ok(payload) => payload, }; let (tx, rx) = oneshot::channel(); - if let Err(err) = sender.feed( - ResponderMessage::GetData { + if let Err(err) = sender + .feed(ResponderMessage::GetData { requesting_peer: req.peer, relay_parent: req.payload.relay_parent, candidate_hash: req.payload.candidate_hash, tx, - } - ).await { - tracing::debug!( - target: LOG_TARGET, - ?err, - "Shutting down responder" - ); + }) + .await + { + tracing::debug!(target: LOG_TARGET, ?err, "Shutting down responder"); return } let response = match rx.await { Err(err) => { - tracing::debug!( - target: LOG_TARGET, - ?err, - "Requested data not found." - ); + tracing::debug!(target: LOG_TARGET, ?err, "Requested data not found."); Err(()) - } + }, Ok(v) => Ok(StatementFetchingResponse::Statement(v)), }; let (pending_sent_tx, pending_sent_rx) = oneshot::channel(); @@ -134,10 +121,7 @@ pub async fn respond( }; pending_out.push(pending_sent_rx); if let Err(_) = req.send_outgoing_response(response) { - tracing::debug!( - target: LOG_TARGET, - "Sending response failed" - ); + tracing::debug!(target: LOG_TARGET, "Sending response failed"); } } } diff --git a/polkadot/node/network/statement-distribution/src/tests.rs b/polkadot/node/network/statement-distribution/src/tests.rs index 5c0b37793de..4fd5a004d30 100644 --- a/polkadot/node/network/statement-distribution/src/tests.rs +++ b/polkadot/node/network/statement-distribution/src/tests.rs @@ -14,32 +14,31 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::time::Duration; -use std::sync::Arc; -use std::iter::FromIterator as _; -use parity_scale_codec::{Decode, Encode}; -use polkadot_node_subsystem_test_helpers::mock::make_ferdie_keystore; use super::*; -use sp_keyring::Sr25519Keyring; -use sp_application_crypto::{AppKey, sr25519::Pair, Pair as TraitPair}; -use polkadot_node_primitives::Statement; -use polkadot_primitives::v1::{CommittedCandidateReceipt, ValidationCode, SessionInfo}; use assert_matches::assert_matches; use futures::executor::{self, block_on}; use futures_timer::Delay; -use sp_keystore::{CryptoStore, SyncCryptoStorePtr, SyncCryptoStore}; -use sc_keystore::LocalKeystore; -use polkadot_node_network_protocol::{view, ObservedRole, request_response::Recipient}; -use polkadot_subsystem::{ - jaeger, ActivatedLeaf, messages::{RuntimeApiMessage, RuntimeApiRequest}, LeafStatus, -}; -use polkadot_node_network_protocol::request_response::{ - Requests, - v1::{ - StatementFetchingRequest, - StatementFetchingResponse, +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_network_protocol::{ + request_response::{ + v1::{StatementFetchingRequest, StatementFetchingResponse}, + Recipient, Requests, }, + view, ObservedRole, +}; +use polkadot_node_primitives::Statement; +use polkadot_node_subsystem_test_helpers::mock::make_ferdie_keystore; +use polkadot_primitives::v1::{CommittedCandidateReceipt, SessionInfo, ValidationCode}; +use polkadot_subsystem::{ + jaeger, + messages::{RuntimeApiMessage, RuntimeApiRequest}, + ActivatedLeaf, LeafStatus, }; +use sc_keystore::LocalKeystore; +use sp_application_crypto::{sr25519::Pair, AppKey, Pair as TraitPair}; +use sp_keyring::Sr25519Keyring; +use sp_keystore::{CryptoStore, SyncCryptoStore, SyncCryptoStorePtr}; +use std::{iter::FromIterator as _, sync::Arc, time::Duration}; #[test] fn active_head_accepts_only_2_seconded_per_validator() { @@ -51,10 +50,7 @@ fn active_head_accepts_only_2_seconded_per_validator() { let parent_hash: Hash = [1; 32].into(); let session_index = 1; - let signing_context = SigningContext { - parent_hash, - session_index, - }; + let signing_context = SigningContext { parent_hash, session_index }; let candidate_a = { let mut c = CommittedCandidateReceipt::default(); @@ -85,11 +81,17 @@ fn active_head_accepts_only_2_seconded_per_validator() { let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); let alice_public = SyncCryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed()) - ).unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); let bob_public = SyncCryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed()) - ).unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Bob.to_seed()), + ) + .unwrap(); // note A let a_seconded_val_0 = block_on(SignedFullStatement::sign( @@ -98,7 +100,10 @@ fn active_head_accepts_only_2_seconded_per_validator() { &signing_context, ValidatorIndex(0), &alice_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert!(head_data.check_useful_or_unknown(&a_seconded_val_0.clone().into()).is_ok()); let noted = head_data.note_statement(a_seconded_val_0.clone()); @@ -120,7 +125,10 @@ fn active_head_accepts_only_2_seconded_per_validator() { &signing_context, ValidatorIndex(0), &alice_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok()); let noted = head_data.note_statement(statement); assert_matches!(noted, NotedStatement::Fresh(_)); @@ -132,7 +140,10 @@ fn active_head_accepts_only_2_seconded_per_validator() { &signing_context, ValidatorIndex(0), &alice_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert_eq!( head_data.check_useful_or_unknown(&statement.clone().into()), Err(DeniedStatement::NotUseful), @@ -147,7 +158,10 @@ fn active_head_accepts_only_2_seconded_per_validator() { &signing_context, ValidatorIndex(1), &bob_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok()); let noted = head_data.note_statement(statement); assert_matches!(noted, NotedStatement::Fresh(_)); @@ -159,7 +173,10 @@ fn active_head_accepts_only_2_seconded_per_validator() { &signing_context, ValidatorIndex(1), &bob_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert!(head_data.check_useful_or_unknown(&statement.clone().into()).is_ok()); let noted = head_data.note_statement(statement); assert_matches!(noted, NotedStatement::Fresh(_)); @@ -238,8 +255,12 @@ fn cant_send_after_receiving() { let mut knowledge = PeerRelayParentKnowledge::default(); let hash_a = CandidateHash([1; 32].into()); - assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).is_ok()); - assert!(knowledge.receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).unwrap()); + assert!(knowledge + .check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3) + .is_ok()); + assert!(knowledge + .receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3) + .unwrap()); assert!(!knowledge.can_send(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)))); } @@ -258,14 +279,18 @@ fn per_peer_relay_parent_knowledge_receive() { Err(COST_UNEXPECTED_STATEMENT), ); - assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3).is_ok()); + assert!(knowledge + .check_can_receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3) + .is_ok()); assert_eq!( knowledge.receive(&(CompactStatement::Seconded(hash_a), ValidatorIndex(0)), 3), Ok(true), ); // Push statements up to the flood limit. - assert!(knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3).is_ok()); + assert!(knowledge + .check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3) + .is_ok()); assert_eq!( knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(1)), 3), Ok(false), @@ -274,7 +299,9 @@ fn per_peer_relay_parent_knowledge_receive() { assert!(knowledge.is_known_candidate(&hash_a)); assert_eq!(*knowledge.received_message_count.get(&hash_a).unwrap(), 2); - assert!(knowledge.check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3).is_ok()); + assert!(knowledge + .check_can_receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3) + .is_ok()); assert_eq!( knowledge.receive(&(CompactStatement::Valid(hash_a), ValidatorIndex(2)), 3), Ok(false), @@ -298,7 +325,9 @@ fn per_peer_relay_parent_knowledge_receive() { let hash_b = CandidateHash([2; 32].into()); let hash_c = CandidateHash([3; 32].into()); - assert!(knowledge.check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3).is_ok()); + assert!(knowledge + .check_can_receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3) + .is_ok()); assert_eq!( knowledge.receive(&(CompactStatement::Seconded(hash_b), ValidatorIndex(0)), 3), Ok(true), @@ -358,22 +387,28 @@ fn peer_view_update_sends_messages() { ]; let session_index = 1; - let signing_context = SigningContext { - parent_hash: hash_c, - session_index, - }; + let signing_context = SigningContext { parent_hash: hash_c, session_index }; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); let alice_public = SyncCryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed()) - ).unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .unwrap(); let bob_public = SyncCryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed()) - ).unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Bob.to_seed()), + ) + .unwrap(); let charlie_public = SyncCryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Charlie.to_seed()) - ).unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Charlie.to_seed()), + ) + .unwrap(); let new_head_data = { let mut data = ActiveHeadData::new( @@ -388,7 +423,10 @@ fn peer_view_update_sends_messages() { &signing_context, ValidatorIndex(0), &alice_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok()); let noted = data.note_statement(statement); @@ -400,7 +438,10 @@ fn peer_view_update_sends_messages() { &signing_context, ValidatorIndex(1), &bob_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok()); let noted = data.note_statement(statement); @@ -412,7 +453,10 @@ fn peer_view_update_sends_messages() { &signing_context, ValidatorIndex(2), &charlie_public.into(), - )).ok().flatten().expect("should be signed"); + )) + .ok() + .flatten() + .expect("should be signed"); assert!(data.check_useful_or_unknown(&statement.clone().into()).is_ok()); let noted = data.note_statement(statement); assert_matches!(noted, NotedStatement::Fresh(_)); @@ -436,10 +480,10 @@ fn peer_view_update_sends_messages() { }; let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - polkadot_node_subsystem_test_helpers - ::make_subsystem_context - ::(pool); + let (mut ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< + StatementDistributionMessage, + _, + >(pool); let peer = PeerId::random(); executor::block_on(async move { @@ -452,7 +496,8 @@ fn peer_view_update_sends_messages() { &active_heads, new_view.clone(), &Default::default(), - ).await; + ) + .await; assert_eq!(peer_data.view, new_view); assert!(!peer_data.view_knowledge.contains_key(&hash_a)); @@ -461,15 +506,15 @@ fn peer_view_update_sends_messages() { let c_knowledge = peer_data.view_knowledge.get(&hash_c).unwrap(); assert!(c_knowledge.is_known_candidate(&candidate_hash)); - assert!(c_knowledge.sent_statements.contains( - &(CompactStatement::Seconded(candidate_hash), ValidatorIndex(0)) - )); - assert!(c_knowledge.sent_statements.contains( - &(CompactStatement::Valid(candidate_hash), ValidatorIndex(1)) - )); - assert!(c_knowledge.sent_statements.contains( - &(CompactStatement::Valid(candidate_hash), ValidatorIndex(2)) - )); + assert!(c_knowledge + .sent_statements + .contains(&(CompactStatement::Seconded(candidate_hash), ValidatorIndex(0)))); + assert!(c_knowledge + .sent_statements + .contains(&(CompactStatement::Valid(candidate_hash), ValidatorIndex(1)))); + assert!(c_knowledge + .sent_statements + .contains(&(CompactStatement::Valid(candidate_hash), ValidatorIndex(2)))); // now see if we got the 3 messages from the active head data. let active_head = active_heads.get(&hash_c).unwrap(); @@ -479,8 +524,7 @@ fn peer_view_update_sends_messages() { for statement in active_head.statements_about(candidate_hash) { let message = handle.recv().await; let expected_to = vec![peer.clone()]; - let expected_payload - = statement_message(hash_c, statement.statement.clone()); + let expected_payload = statement_message(hash_c, statement.statement.clone()); assert_matches!( message, @@ -529,24 +573,27 @@ fn circulated_statement_goes_to_all_peers_with_view() { (peer_a.clone(), peer_data_from_view(peer_a_view)), (peer_b.clone(), peer_data_from_view(peer_b_view)), (peer_c.clone(), peer_data_from_view(peer_c_view)), - ].into_iter().collect(); + ] + .into_iter() + .collect(); let pool = sp_core::testing::TaskExecutor::new(); - let (mut ctx, mut handle) = - polkadot_node_subsystem_test_helpers - ::make_subsystem_context - ::(pool); + let (mut ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context::< + StatementDistributionMessage, + _, + >(pool); executor::block_on(async move { - let signing_context = SigningContext { - parent_hash: hash_b, - session_index, - }; + let signing_context = SigningContext { parent_hash: hash_b, session_index }; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); let alice_public = CryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed()) - ).await.unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .await + .unwrap(); let statement = SignedFullStatement::sign( &keystore, @@ -554,21 +601,21 @@ fn circulated_statement_goes_to_all_peers_with_view() { &signing_context, ValidatorIndex(0), &alice_public.into(), - ).await.ok().flatten().expect("should be signed"); + ) + .await + .ok() + .flatten() + .expect("should be signed"); let comparator = StoredStatementComparator { - compact: statement.payload().to_compact(), - validator_index: ValidatorIndex(0), - signature: statement.signature().clone() - }; - let statement = StoredStatement { - comparator: &comparator, - statement: &statement, + compact: statement.payload().to_compact(), + validator_index: ValidatorIndex(0), + signature: statement.signature().clone(), }; + let statement = StoredStatement { comparator: &comparator, statement: &statement }; - let gossip_peers = HashSet::from_iter(vec![ - peer_a.clone(), peer_b.clone(), peer_c.clone(), - ].into_iter()); + let gossip_peers = + HashSet::from_iter(vec![peer_a.clone(), peer_b.clone(), peer_c.clone()].into_iter()); let needs_dependents = circulate_statement( &gossip_peers, &mut peer_data, @@ -576,7 +623,8 @@ fn circulated_statement_goes_to_all_peers_with_view() { hash_b, statement, Vec::new(), - ).await; + ) + .await; { assert_eq!(needs_dependents.len(), 2); @@ -586,17 +634,23 @@ fn circulated_statement_goes_to_all_peers_with_view() { let fingerprint = (statement.compact().clone(), ValidatorIndex(0)); - assert!( - peer_data.get(&peer_b).unwrap() - .view_knowledge.get(&hash_b).unwrap() - .sent_statements.contains(&fingerprint), - ); - - assert!( - peer_data.get(&peer_c).unwrap() - .view_knowledge.get(&hash_b).unwrap() - .sent_statements.contains(&fingerprint), - ); + assert!(peer_data + .get(&peer_b) + .unwrap() + .view_knowledge + .get(&hash_b) + .unwrap() + .sent_statements + .contains(&fingerprint),); + + assert!(peer_data + .get(&peer_c) + .unwrap() + .view_knowledge + .get(&hash_b) + .unwrap() + .sent_statements + .contains(&fingerprint),); let message = handle.recv().await; assert_matches!( @@ -646,20 +700,25 @@ fn receiving_from_one_sends_to_another_and_to_candidate_backing() { let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); let bg = async move { - let s = StatementDistribution { metrics: Default::default(), keystore: Arc::new(LocalKeystore::in_memory()) }; + let s = StatementDistribution { + metrics: Default::default(), + keystore: Arc::new(LocalKeystore::in_memory()), + }; s.run(ctx).await.unwrap(); }; let test_fut = async move { // register our active heads. - handle.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash: hash_a, - number: 1, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - })), - )).await; + handle + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; assert_matches!( handle.recv().await, @@ -684,42 +743,51 @@ fn receiving_from_one_sends_to_another_and_to_candidate_backing() { ); // notify of peers and view - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected(peer_a.clone(), ObservedRole::Full, None) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected(peer_a.clone(), ObservedRole::Full, None), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected(peer_b.clone(), ObservedRole::Full, None) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected(peer_b.clone(), ObservedRole::Full, None), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a]), + ), + }) + .await; // receive a seconded statement from peer A. it should be propagated onwards to peer B and to // candidate backing. let statement = { - let signing_context = SigningContext { - parent_hash: hash_a, - session_index, - }; + let signing_context = SigningContext { parent_hash: hash_a, session_index }; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); let alice_public = CryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed()) - ).await.unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .await + .unwrap(); SignedFullStatement::sign( &keystore, @@ -727,17 +795,26 @@ fn receiving_from_one_sends_to_another_and_to_candidate_backing() { &signing_context, ValidatorIndex(0), &alice_public.into(), - ).await.ok().flatten().expect("should be signed") + ) + .await + .ok() + .flatten() + .expect("should be signed") }; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer_a.clone(), - protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()), - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerMessage( + peer_a.clone(), + protocol_v1::StatementDistributionMessage::Statement( + hash_a, + statement.clone().into(), + ), + ), + ), + }) + .await; assert_matches!( handle.recv().await, @@ -787,7 +864,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( let mut c = CommittedCandidateReceipt::default(); c.descriptor.relay_parent = hash_a; c.descriptor.para_id = 1.into(); - c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3])); + c.commitments.new_validation_code = Some(ValidationCode(vec![1, 2, 3])); c }; @@ -804,10 +881,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( Sr25519Keyring::Ferdie.pair(), ]; - let session_info = make_session_info( - validators, - vec![vec![0,1,2,4], vec![3]] - ); + let session_info = make_session_info(validators, vec![vec![0, 1, 2, 4], vec![3]]); let session_index = 1; @@ -815,26 +889,31 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); let bg = async move { - let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()}; + let s = + StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore() }; s.run(ctx).await.unwrap(); }; let (mut tx_reqs, rx_reqs) = mpsc::channel(1); let test_fut = async move { - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs), + }) + .await; // register our active heads. - handle.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash: hash_a, - number: 1, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - })), - )).await; + handle + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; assert_matches!( handle.recv().await, @@ -859,75 +938,92 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( ); // notify of peers and view - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_a.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Alice.public().into()) - ) - ) - }).await; - - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_b.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Bob.public().into()) - ) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_c.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Charlie.public().into()) - ) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_a.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Alice.public().into()), + ), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_b.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Bob.public().into()), + ), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_c.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Charlie.public().into()), + ), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a]) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a]) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]), + ), + }) + .await; + + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a]), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a]), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a]), + ), + }) + .await; // receive a seconded statement from peer A, which does not provide the request data, // then get that data from peer C. It should be propagated onwards to peer B and to // candidate backing. let statement = { - let signing_context = SigningContext { - parent_hash: hash_a, - session_index, - }; + let signing_context = SigningContext { parent_hash: hash_a, session_index }; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); let alice_public = CryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed()) - ).await.unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .await + .unwrap(); SignedFullStatement::sign( &keystore, @@ -935,20 +1031,27 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( &signing_context, ValidatorIndex(0), &alice_public.into(), - ).await.ok().flatten().expect("should be signed") + ) + .await + .ok() + .flatten() + .expect("should be signed") }; let metadata = - protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata(); + protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()) + .get_metadata(); - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer_a.clone(), - protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()), - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerMessage( + peer_a.clone(), + protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()), + ), + ), + }) + .await; assert_matches!( handle.recv().await, @@ -975,24 +1078,28 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( // coverage: Delay::new(Duration::from_millis(20)).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer_c.clone(), - protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()), - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerMessage( + peer_c.clone(), + protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()), + ), + ), + }) + .await; // Malicious peer: - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer_bad.clone(), - protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()), - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerMessage( + peer_bad.clone(), + protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()), + ), + ), + }) + .await; // Let c fail once too: assert_matches!( @@ -1142,7 +1249,6 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( ) if r == hash_a && s == statement => {} ); - // Now messages should go out: assert_matches!( handle.recv().await, @@ -1242,7 +1348,7 @@ fn share_prioritizes_backing_group() { let mut c = CommittedCandidateReceipt::default(); c.descriptor.relay_parent = hash_a; c.descriptor.para_id = 1.into(); - c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3])); + c.commitments.new_validation_code = Some(ValidationCode(vec![1, 2, 3])); c }; @@ -1268,17 +1374,16 @@ fn share_prioritizes_backing_group() { // We artificially inflate our group, so there won't be any free slots for other peers. (We // want to test that our group is prioritized): - let dummy_pairs: Vec<_> = std::iter::repeat_with(|| Pair::generate().0).take(dummy_count).collect(); - let dummy_peers: Vec<_> = std::iter::repeat_with(|| PeerId::random()).take(dummy_count).collect(); + let dummy_pairs: Vec<_> = + std::iter::repeat_with(|| Pair::generate().0).take(dummy_count).collect(); + let dummy_peers: Vec<_> = + std::iter::repeat_with(|| PeerId::random()).take(dummy_count).collect(); validators = validators.into_iter().chain(dummy_pairs.clone()).collect(); - let mut first_group = vec![0,1,2,4]; + let mut first_group = vec![0, 1, 2, 4]; first_group.append(&mut (0..dummy_count as u32).map(|v| v + 5).collect()); - let session_info = make_session_info( - validators, - vec![first_group, vec![3]] - ); + let session_info = make_session_info(validators, vec![first_group, vec![3]]); let session_index = 1; @@ -1286,26 +1391,31 @@ fn share_prioritizes_backing_group() { let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); let bg = async move { - let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()}; + let s = + StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore() }; s.run(ctx).await.unwrap(); }; let (mut tx_reqs, rx_reqs) = mpsc::channel(1); let test_fut = async move { - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs), + }) + .await; // register our active heads. - handle.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash: hash_a, - number: 1, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - })), - )).await; + handle + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; assert_matches!( handle.recv().await, @@ -1331,106 +1441,131 @@ fn share_prioritizes_backing_group() { // notify of dummy peers and view for (peer, pair) in dummy_peers.clone().into_iter().zip(dummy_pairs) { - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer, - ObservedRole::Full, - Some(pair.public().into()), - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer, + ObservedRole::Full, + Some(pair.public().into()), + ), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer, view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer, view![hash_a]), + ), + }) + .await; } // notify of peers and view - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_a.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Alice.public().into()) - ) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_b.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Bob.public().into()) - ) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_c.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Charlie.public().into()) - ) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_other_group.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Dave.public().into()) - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_a.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Alice.public().into()), + ), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_b.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Bob.public().into()), + ), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_c.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Charlie.public().into()), + ), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected(peer_bad.clone(), ObservedRole::Full, None), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_other_group.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Dave.public().into()), + ), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a]) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a]) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a]) - ) - }).await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_other_group.clone(), view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_b.clone(), view![hash_a]), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_c.clone(), view![hash_a]), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_bad.clone(), view![hash_a]), + ), + }) + .await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_other_group.clone(), view![hash_a]), + ), + }) + .await; // receive a seconded statement from peer A, which does not provide the request data, // then get that data from peer C. It should be propagated onwards to peer B and to // candidate backing. let statement = { - let signing_context = SigningContext { - parent_hash: hash_a, - session_index, - }; + let signing_context = SigningContext { parent_hash: hash_a, session_index }; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); let ferdie_public = CryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Ferdie.to_seed()) - ).await.unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Ferdie.to_seed()), + ) + .await + .unwrap(); SignedFullStatement::sign( &keystore, @@ -1438,15 +1573,22 @@ fn share_prioritizes_backing_group() { &signing_context, ValidatorIndex(4), &ferdie_public.into(), - ).await.ok().flatten().expect("should be signed") + ) + .await + .ok() + .flatten() + .expect("should be signed") }; let metadata = - protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata(); + protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()) + .get_metadata(); - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::Share(hash_a, statement.clone()) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::Share(hash_a, statement.clone()), + }) + .await; // Messages should go out: assert_matches!( @@ -1513,7 +1655,7 @@ fn peer_cant_flood_with_large_statements() { let mut c = CommittedCandidateReceipt::default(); c.descriptor.relay_parent = hash_a; c.descriptor.para_id = 1.into(); - c.commitments.new_validation_code = Some(ValidationCode(vec![1,2,3])); + c.commitments.new_validation_code = Some(ValidationCode(vec![1, 2, 3])); c }; @@ -1529,11 +1671,8 @@ fn peer_cant_flood_with_large_statements() { Sr25519Keyring::Ferdie.pair(), ]; - let first_group = vec![0,1,2,4]; - let session_info = make_session_info( - validators, - vec![first_group, vec![3]] - ); + let first_group = vec![0, 1, 2, 4]; + let session_info = make_session_info(validators, vec![first_group, vec![3]]); let session_index = 1; @@ -1541,26 +1680,31 @@ fn peer_cant_flood_with_large_statements() { let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); let bg = async move { - let s = StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore()}; + let s = + StatementDistribution { metrics: Default::default(), keystore: make_ferdie_keystore() }; s.run(ctx).await.unwrap(); }; let (_, rx_reqs) = mpsc::channel(1); let test_fut = async move { - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::StatementFetchingReceiver(rx_reqs), + }) + .await; // register our active heads. - handle.send(FromOverseer::Signal( - OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash: hash_a, - number: 1, - status: LeafStatus::Fresh, - span: Arc::new(jaeger::Span::Disabled), - })), - )).await; + handle + .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::start_work(ActivatedLeaf { + hash: hash_a, + number: 1, + status: LeafStatus::Fresh, + span: Arc::new(jaeger::Span::Disabled), + }), + ))) + .await; assert_matches!( handle.recv().await, @@ -1585,33 +1729,38 @@ fn peer_cant_flood_with_large_statements() { ); // notify of peers and view - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerConnected( - peer_a.clone(), - ObservedRole::Full, - Some(Sr25519Keyring::Alice.public().into()) - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerConnected( + peer_a.clone(), + ObservedRole::Full, + Some(Sr25519Keyring::Alice.public().into()), + ), + ), + }) + .await; - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerViewChange(peer_a.clone(), view![hash_a]), + ), + }) + .await; // receive a seconded statement from peer A. let statement = { - let signing_context = SigningContext { - parent_hash: hash_a, - session_index, - }; + let signing_context = SigningContext { parent_hash: hash_a, session_index }; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); let alice_public = CryptoStore::sr25519_generate_new( - &*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed()) - ).await.unwrap(); + &*keystore, + ValidatorId::ID, + Some(&Sr25519Keyring::Alice.to_seed()), + ) + .await + .unwrap(); SignedFullStatement::sign( &keystore, @@ -1619,21 +1768,30 @@ fn peer_cant_flood_with_large_statements() { &signing_context, ValidatorIndex(0), &alice_public.into(), - ).await.ok().flatten().expect("should be signed") + ) + .await + .ok() + .flatten() + .expect("should be signed") }; let metadata = - protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()).get_metadata(); + protocol_v1::StatementDistributionMessage::Statement(hash_a, statement.clone().into()) + .get_metadata(); for _ in 0..MAX_LARGE_STATEMENTS_PER_SENDER + 1 { - handle.send(FromOverseer::Communication { - msg: StatementDistributionMessage::NetworkBridgeUpdateV1( - NetworkBridgeEvent::PeerMessage( - peer_a.clone(), - protocol_v1::StatementDistributionMessage::LargeStatement(metadata.clone()), - ) - ) - }).await; + handle + .send(FromOverseer::Communication { + msg: StatementDistributionMessage::NetworkBridgeUpdateV1( + NetworkBridgeEvent::PeerMessage( + peer_a.clone(), + protocol_v1::StatementDistributionMessage::LargeStatement( + metadata.clone(), + ), + ), + ), + }) + .await; } // We should try to fetch the data and punish the peer (but we don't know what comes @@ -1642,11 +1800,10 @@ fn peer_cant_flood_with_large_statements() { let mut punished = false; for _ in 0..2 { match handle.recv().await { - AllMessages::NetworkBridge( - NetworkBridgeMessage::SendRequests( - mut reqs, IfDisconnected::ImmediateError - ) - ) => { + AllMessages::NetworkBridge(NetworkBridgeMessage::SendRequests( + mut reqs, + IfDisconnected::ImmediateError, + )) => { let reqs = reqs.pop().unwrap(); let outgoing = match reqs { Requests::StatementFetching(outgoing) => outgoing, @@ -1658,11 +1815,11 @@ fn peer_cant_flood_with_large_statements() { assert_eq!(outgoing.peer, Recipient::Peer(peer_a)); // Just drop request - should trigger error. requested = true; - } + }, - AllMessages::NetworkBridge( - NetworkBridgeMessage::ReportPeer(p, r) - ) if p == peer_a && r == COST_APPARENT_FLOOD => { + AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(p, r)) + if p == peer_a && r == COST_APPARENT_FLOOD => + { punished = true; } @@ -1682,9 +1839,10 @@ fn peer_cant_flood_with_large_statements() { } fn make_session_info(validators: Vec, groups: Vec>) -> SessionInfo { - let validator_groups: Vec> = groups - .iter().map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()).collect(); + .iter() + .map(|g| g.into_iter().map(|v| ValidatorIndex(*v)).collect()) + .collect(); SessionInfo { discovery_keys: validators.iter().map(|k| k.public().into()).collect(), diff --git a/polkadot/node/overseer/all-subsystems-gen/src/lib.rs b/polkadot/node/overseer/all-subsystems-gen/src/lib.rs index c15d08bb04f..48228c75b27 100644 --- a/polkadot/node/overseer/all-subsystems-gen/src/lib.rs +++ b/polkadot/node/overseer/all-subsystems-gen/src/lib.rs @@ -19,7 +19,7 @@ use std::collections::HashSet; use proc_macro2::TokenStream; use quote::quote; -use syn::{Error, GenericParam, Ident, Result, Type, parse2}; +use syn::{parse2, Error, GenericParam, Ident, Result, Type}; #[proc_macro_derive(AllSubsystemsGen)] pub fn subsystems_gen(item: proc_macro::TokenStream) -> proc_macro::TokenStream { @@ -40,53 +40,68 @@ fn impl_subsystems_gen(item: TokenStream) -> Result { } let mut orig_generics = ds.generics; // remove default types - orig_generics.params = orig_generics.params.into_iter().map(|mut generic| { - match generic { - GenericParam::Type(ref mut param) => { - param.eq_token = None; - param.default = None; + orig_generics.params = orig_generics + .params + .into_iter() + .map(|mut generic| { + match generic { + GenericParam::Type(ref mut param) => { + param.eq_token = None; + param.default = None; + }, + _ => {}, } - _ => {} - } - generic - }).collect(); + generic + }) + .collect(); // prepare a hashmap of generic type to member that uses it - let generic_types = orig_generics.params.iter().filter_map(|generic| { - if let GenericParam::Type(param) = generic { - Some(param.ident.clone()) - } else { - None - } - }).collect::>(); + let generic_types = orig_generics + .params + .iter() + .filter_map(|generic| { + if let GenericParam::Type(param) = generic { + Some(param.ident.clone()) + } else { + None + } + }) + .collect::>(); let strukt_ty = ds.ident; if generic_types.is_empty() { - return Err(Error::new(strukt_ty.span(), "struct must have at least one generic parameter.")) + return Err(Error::new( + strukt_ty.span(), + "struct must have at least one generic parameter.", + )) } // collect all fields that exist, and all fields that are replaceable let mut replacable_items = Vec::::with_capacity(64); let mut all_fields = replacable_items.clone(); - let mut duplicate_generic_detection = HashSet::::with_capacity(64); for field in named.named { - let field_ident = field.ident.clone().ok_or_else(|| Error::new(span, "Member field must have a name."))?; + let field_ident = field + .ident + .clone() + .ok_or_else(|| Error::new(span, "Member field must have a name."))?; let ty = field.ty.clone(); let ntt = NameTyTup { field: field_ident, ty }; replacable_items.push(ntt.clone()); - // assure every generic is used exactly once let ty_ident = match field.ty { Type::Path(path) => path.path.get_ident().cloned().ok_or_else(|| { - Error::new(proc_macro2::Span::call_site(), "Expected an identifier, but got a path.") + Error::new( + proc_macro2::Span::call_site(), + "Expected an identifier, but got a path.", + ) }), - _ => return Err(Error::new(proc_macro2::Span::call_site(), "Must be path.")) + _ => return Err(Error::new(proc_macro2::Span::call_site(), "Must be path.")), }?; if generic_types.contains(&ty_ident) { @@ -98,34 +113,43 @@ fn impl_subsystems_gen(item: TokenStream) -> Result { all_fields.push(ntt); } - let msg = "Generated by #[derive(AllSubsystemsGen)] derive proc-macro."; let mut additive = TokenStream::new(); // generate an impl of `fn replace_#name` for NameTyTup { field: replacable_item, ty: replacable_item_ty } in replacable_items { - let keeper = all_fields.iter().filter(|ntt| ntt.field != replacable_item).map(|ntt| ntt.field.clone()); + let keeper = all_fields + .iter() + .filter(|ntt| ntt.field != replacable_item) + .map(|ntt| ntt.field.clone()); let strukt_ty = strukt_ty.clone(); let fname = Ident::new(&format!("replace_{}", replacable_item), span); // adjust the generics such that the appropriate member type is replaced let mut modified_generics = orig_generics.clone(); - modified_generics.params = modified_generics.params.into_iter().map(|mut generic| { - match generic { - GenericParam::Type(ref mut param) => { - param.eq_token = None; - param.default = None; - if match &replacable_item_ty { - Type::Path(path) => - path.path.get_ident().filter(|&ident| ident == ¶m.ident).is_some(), - _ => false - } { - param.ident = Ident::new("NEW", span); - } + modified_generics.params = modified_generics + .params + .into_iter() + .map(|mut generic| { + match generic { + GenericParam::Type(ref mut param) => { + param.eq_token = None; + param.default = None; + if match &replacable_item_ty { + Type::Path(path) => path + .path + .get_ident() + .filter(|&ident| ident == ¶m.ident) + .is_some(), + _ => false, + } { + param.ident = Ident::new("NEW", span); + } + }, + _ => {}, } - _ => {} - } - generic - }).collect(); + generic + }) + .collect(); additive.extend(quote! { impl #orig_generics #strukt_ty #orig_generics { @@ -143,11 +167,13 @@ fn impl_subsystems_gen(item: TokenStream) -> Result { } Ok(additive) - } - syn::Fields::Unit => Err(Error::new(span, "Must be a struct with named fields. Not an unit struct.")), - syn::Fields::Unnamed(_) => { - Err(Error::new(span, "Must be a struct with named fields. Not an unnamed fields struct.")) - } + }, + syn::Fields::Unit => + Err(Error::new(span, "Must be a struct with named fields. Not an unit struct.")), + syn::Fields::Unnamed(_) => Err(Error::new( + span, + "Must be a struct with named fields. Not an unnamed fields struct.", + )), } } diff --git a/polkadot/node/overseer/examples/minimal-example.rs b/polkadot/node/overseer/examples/minimal-example.rs index 604ef3358d6..5048fbcb054 100644 --- a/polkadot/node/overseer/examples/minimal-example.rs +++ b/polkadot/node/overseer/examples/minimal-example.rs @@ -18,39 +18,28 @@ //! * Spawning subsystems and subsystem child jobs //! * Establishing message passing -use std::time::Duration; -use futures::{ - channel::oneshot, - pending, pin_mut, select, stream, - FutureExt, StreamExt, -}; +use futures::{channel::oneshot, pending, pin_mut, select, stream, FutureExt, StreamExt}; use futures_timer::Delay; +use std::time::Duration; -use polkadot_node_primitives::{PoV, BlockData}; -use polkadot_primitives::v1::Hash; +use polkadot_node_primitives::{BlockData, PoV}; +use polkadot_node_subsystem_types::messages::{ + CandidateBackingMessage, CandidateValidationMessage, +}; use polkadot_overseer::{ self as overseer, - AllMessages, - AllSubsystems, - HeadSupportsParachains, - Overseer, - OverseerSignal, - SubsystemError, - gen::{ - FromOverseer, - SpawnedSubsystem, - }, -}; -use polkadot_node_subsystem_types::messages::{ - CandidateValidationMessage, CandidateBackingMessage, + gen::{FromOverseer, SpawnedSubsystem}, + AllMessages, AllSubsystems, HeadSupportsParachains, Overseer, OverseerSignal, SubsystemError, }; +use polkadot_primitives::v1::Hash; struct AlwaysSupportsParachains; impl HeadSupportsParachains for AlwaysSupportsParachains { - fn head_supports_parachains(&self, _head: &Hash) -> bool { true } + fn head_supports_parachains(&self, _head: &Hash) -> bool { + true + } } - //////// struct Subsystem1; @@ -58,7 +47,11 @@ struct Subsystem1; impl Subsystem1 { async fn run(mut ctx: Ctx) -> () where - Ctx: overseer::SubsystemContext, + Ctx: overseer::SubsystemContext< + Message = CandidateBackingMessage, + AllMessages = AllMessages, + Signal = OverseerSignal, + >, { 'louy: loop { match ctx.try_recv().await { @@ -66,13 +59,13 @@ impl Subsystem1 { if let FromOverseer::Communication { msg } = msg { tracing::info!("msg {:?}", msg); } - continue 'louy; - } + continue 'louy + }, Ok(None) => (), Err(_) => { tracing::info!("exiting"); - break 'louy; - } + break 'louy + }, } Delay::new(Duration::from_secs(1)).await; @@ -80,21 +73,23 @@ impl Subsystem1 { let msg = CandidateValidationMessage::ValidateFromChainState( Default::default(), - PoV { - block_data: BlockData(Vec::new()), - }.into(), + PoV { block_data: BlockData(Vec::new()) }.into(), tx, ); - ctx.send_message(::AllMessages::from(msg)).await; + ctx.send_message(::AllMessages::from(msg)) + .await; } () } } - -impl overseer::Subsystem for Subsystem1 +impl overseer::Subsystem for Subsystem1 where - Context: overseer::SubsystemContext, + Context: overseer::SubsystemContext< + Message = CandidateBackingMessage, + AllMessages = AllMessages, + Signal = OverseerSignal, + >, { fn start(self, ctx: Context) -> SpawnedSubsystem { let future = Box::pin(async move { @@ -102,10 +97,7 @@ where Ok(()) }); - SpawnedSubsystem { - name: "subsystem-1", - future, - } + SpawnedSubsystem { name: "subsystem-1", future } } } @@ -116,7 +108,11 @@ struct Subsystem2; impl Subsystem2 { async fn run(mut ctx: Ctx) where - Ctx: overseer::SubsystemContext, + Ctx: overseer::SubsystemContext< + Message = CandidateValidationMessage, + AllMessages = AllMessages, + Signal = OverseerSignal, + >, { ctx.spawn( "subsystem-2-job", @@ -126,27 +122,34 @@ impl Subsystem2 { Delay::new(Duration::from_secs(1)).await; } }), - ).unwrap(); + ) + .unwrap(); loop { match ctx.try_recv().await { Ok(Some(msg)) => { tracing::info!("Subsystem2 received message {:?}", msg); - continue; - } - Ok(None) => { pending!(); } + continue + }, + Ok(None) => { + pending!(); + }, Err(_) => { tracing::info!("exiting"); - return; + return }, } } } } -impl overseer::Subsystem for Subsystem2 +impl overseer::Subsystem for Subsystem2 where - Context: overseer::SubsystemContext, + Context: overseer::SubsystemContext< + Message = CandidateValidationMessage, + AllMessages = AllMessages, + Signal = OverseerSignal, + >, { fn start(self, ctx: Context) -> SpawnedSubsystem { let future = Box::pin(async move { @@ -154,10 +157,7 @@ where Ok(()) }); - SpawnedSubsystem { - name: "subsystem-2", - future, - } + SpawnedSubsystem { name: "subsystem-2", future } } } @@ -171,16 +171,10 @@ fn main() { let all_subsystems = AllSubsystems::<()>::dummy() .replace_candidate_validation(Subsystem2) - .replace_candidate_backing(Subsystem1) - ; - - let (overseer, _handle) = Overseer::new( - vec![], - all_subsystems, - None, - AlwaysSupportsParachains, - spawner, - ).unwrap(); + .replace_candidate_backing(Subsystem1); + + let (overseer, _handle) = + Overseer::new(vec![], all_subsystems, None, AlwaysSupportsParachains, spawner).unwrap(); let overseer_fut = overseer.run().fuse(); let timer_stream = timer_stream; diff --git a/polkadot/node/overseer/overseer-gen/examples/dummy.rs b/polkadot/node/overseer/overseer-gen/examples/dummy.rs index 732851ca386..600e874a004 100644 --- a/polkadot/node/overseer/overseer-gen/examples/dummy.rs +++ b/polkadot/node/overseer/overseer-gen/examples/dummy.rs @@ -1,15 +1,14 @@ //! A dummy to be used with cargo expand -use polkadot_overseer_gen::*; use polkadot_node_network_protocol::WrongVariant; - +use polkadot_overseer_gen::*; /// Concrete subsystem implementation for `MsgStrukt` msg type. #[derive(Default)] pub struct AwesomeSubSys; -impl ::polkadot_overseer_gen::Subsystem, Yikes> for AwesomeSubSys { - fn start(self, _ctx: XxxSubsystemContext) -> SpawnedSubsystem < Yikes > { +impl ::polkadot_overseer_gen::Subsystem, Yikes> for AwesomeSubSys { + fn start(self, _ctx: XxxSubsystemContext) -> SpawnedSubsystem { unimplemented!("starting yay!") } } @@ -18,22 +17,19 @@ impl ::polkadot_overseer_gen::Subsystem, Yikes> f pub struct GoblinTower; impl ::polkadot_overseer_gen::Subsystem, Yikes> for GoblinTower { - fn start(self, _ctx: XxxSubsystemContext) -> SpawnedSubsystem < Yikes > { + fn start(self, _ctx: XxxSubsystemContext) -> SpawnedSubsystem { unimplemented!("welcum") } } - /// A signal sent by the overseer. #[derive(Debug, Clone)] pub struct SigSigSig; - /// The external event. #[derive(Debug, Clone)] pub struct EvX; - impl EvX { pub fn focus<'a, T>(&'a self) -> Result { unimplemented!("dispatch") @@ -75,7 +71,6 @@ impl From for MsgStrukt { } } - #[derive(Debug, Clone, Copy)] pub enum NetworkMsg { A, @@ -83,18 +78,15 @@ pub enum NetworkMsg { C, } - impl NetworkMsg { fn focus(&self) -> Result { Ok(match self { Self::B => return Err(WrongVariant), - Self::A | Self::C => self.clone() + Self::A | Self::C => self.clone(), }) } } - - #[overlord(signal=SigSigSig, event=EvX, error=Yikes, network=NetworkMsg, gen=AllMessages)] struct Xxx { #[subsystem(MsgStrukt)] @@ -109,7 +101,7 @@ struct Xxx { #[derive(Debug, Clone)] struct DummySpawner; -impl SpawnNamed for DummySpawner{ +impl SpawnNamed for DummySpawner { fn spawn_blocking(&self, name: &'static str, _future: futures::future::BoxFuture<'static, ()>) { unimplemented!("spawn blocking {}", name) } diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_builder.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_builder.rs index 256288368b8..02e4506c0f8 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_builder.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_builder.rs @@ -80,10 +80,8 @@ pub(crate) fn impl_builder(info: &OverseerInfo) -> proc_macro2::TokenStream { let consumes = &info.consumes(); - let subsyste_ctx_name = Ident::new( - &(overseer_name.to_string() + "SubsystemContext"), - overseer_name.span() - ); + let subsyste_ctx_name = + Ident::new(&(overseer_name.to_string() + "SubsystemContext"), overseer_name.span()); let builder_where_clause = quote! { where diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_dispatch.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_dispatch.rs index 687d094be53..ff7e9d1d5d1 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_dispatch.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_dispatch.rs @@ -15,7 +15,7 @@ // along with Polkadot. If not, see . use super::*; -use proc_macro2::{TokenStream, Ident}; +use proc_macro2::{Ident, TokenStream}; use quote::quote; use syn::Path; diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_message_wrapper.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_message_wrapper.rs index b2cb7ce11f9..6de017e8005 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_message_wrapper.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_message_wrapper.rs @@ -15,8 +15,7 @@ // along with Polkadot. If not, see . use quote::quote; -use syn::Result; -use syn::spanned::Spanned; +use syn::{spanned::Spanned, Result}; use super::*; @@ -30,21 +29,24 @@ pub(crate) fn impl_message_wrapper_enum(info: &OverseerInfo) -> Result for #message_wrapper { - fn from(message: #outgoing) -> Self { - #message_wrapper :: #outgoing_variant ( message ) + let outgoing_variant = outgoing.get_ident().ok_or_else(|| { + syn::Error::new( + outgoing.span(), + "Missing identifier to use as enum variant for outgoing.", + ) + })?; + ( + quote! { + impl ::std::convert::From< #outgoing > for #message_wrapper { + fn from(message: #outgoing) -> Self { + #message_wrapper :: #outgoing_variant ( message ) + } } - } - }, - quote! { - #outgoing_variant ( #outgoing ) , - }) + }, + quote! { + #outgoing_variant ( #outgoing ) , + }, + ) } else { (TokenStream::new(), TokenStream::new()) }; diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_misc.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_misc.rs index 248d6b0fc37..e720f357442 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_misc.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_misc.rs @@ -23,8 +23,10 @@ use super::*; /// which acts as the gateway to constructing the overseer. pub(crate) fn impl_misc(info: &OverseerInfo) -> proc_macro2::TokenStream { let overseer_name = info.overseer_name.clone(); - let subsystem_sender_name = Ident::new(&(overseer_name.to_string() + "SubsystemSender"), overseer_name.span()); - let subsystem_ctx_name = Ident::new(&(overseer_name.to_string() + "SubsystemContext"), overseer_name.span()); + let subsystem_sender_name = + Ident::new(&(overseer_name.to_string() + "SubsystemSender"), overseer_name.span()); + let subsystem_ctx_name = + Ident::new(&(overseer_name.to_string() + "SubsystemContext"), overseer_name.span()); let consumes = &info.consumes(); let signal = &info.extern_signal_ty; let wrapper_message = &info.message_wrapper; diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_overseer.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_overseer.rs index d30f8f6991c..cddd0534c6e 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_overseer.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/impl_overseer.rs @@ -52,7 +52,8 @@ pub(crate) fn impl_overseer_struct(info: &OverseerInfo) -> proc_macro2::TokenStr let message_channel_capacity = info.message_channel_capacity; let signal_channel_capacity = info.signal_channel_capacity; - let log_target = syn::LitStr::new(overseer_name.to_string().to_lowercase().as_str(), overseer_name.span()); + let log_target = + syn::LitStr::new(overseer_name.to_string().to_lowercase().as_str(), overseer_name.span()); let ts = quote! { const STOP_DELAY: ::std::time::Duration = ::std::time::Duration::from_secs(1); diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/lib.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/lib.rs index 9fecfd19241..b967acfe8b6 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/lib.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/lib.rs @@ -16,18 +16,18 @@ #![deny(unused_crate_dependencies)] -use proc_macro2::{Span, Ident, TokenStream}; -use syn::{parse2, Result}; +use proc_macro2::{Ident, Span, TokenStream}; use quote::{quote, ToTokens}; +use syn::{parse2, Result}; mod impl_builder; +mod impl_channels_out; +mod impl_dispatch; +mod impl_message_wrapper; mod impl_misc; mod impl_overseer; mod parse_attr; mod parse_struct; -mod impl_channels_out; -mod impl_dispatch; -mod impl_message_wrapper; use impl_builder::*; use impl_channels_out::*; @@ -42,28 +42,36 @@ use parse_struct::*; mod tests; #[proc_macro_attribute] -pub fn overlord(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn overlord( + attr: proc_macro::TokenStream, + item: proc_macro::TokenStream, +) -> proc_macro::TokenStream { let attr: TokenStream = attr.into(); let item: TokenStream = item.into(); - impl_overseer_gen(attr, item).unwrap_or_else(|err| err.to_compile_error()).into() + impl_overseer_gen(attr, item) + .unwrap_or_else(|err| err.to_compile_error()) + .into() } -pub(crate) fn impl_overseer_gen(attr: TokenStream, orig: TokenStream) -> Result { +pub(crate) fn impl_overseer_gen( + attr: TokenStream, + orig: TokenStream, +) -> Result { let args: AttrArgs = parse2(attr)?; let message_wrapper = args.message_wrapper; let of: OverseerGuts = parse2(orig)?; let support_crate_name = if cfg!(test) { - quote!{crate} + quote! {crate} } else { use proc_macro_crate::{crate_name, FoundCrate}; let crate_name = crate_name("polkadot-overseer-gen") .expect("Support crate polkadot-overseer-gen is present in `Cargo.toml`. qed"); match crate_name { - FoundCrate::Itself => quote!{crate}, - FoundCrate::Name(name) => Ident::new(&name, Span::call_site()).to_token_stream(), - } + FoundCrate::Itself => quote! {crate}, + FoundCrate::Name(name) => Ident::new(&name, Span::call_site()).to_token_stream(), + } }; let info = OverseerInfo { support_crate_name, diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_attr.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_attr.rs index 60fa6ab2276..e688f84f2e3 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_attr.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_attr.rs @@ -15,12 +15,14 @@ // along with Polkadot. If not, see . use proc_macro2::Span; -use std::collections::{hash_map::RandomState, HashMap}; -use syn::parse::{Parse, ParseBuffer}; -use syn::punctuated::Punctuated; -use syn::spanned::Spanned; -use syn::{Error, Ident, LitInt, Path, Result, Token}; use quote::{quote, ToTokens}; +use std::collections::{hash_map::RandomState, HashMap}; +use syn::{ + parse::{Parse, ParseBuffer}, + punctuated::Punctuated, + spanned::Spanned, + Error, Ident, LitInt, Path, Result, Token, +}; mod kw { syn::custom_keyword!(event); @@ -33,62 +35,45 @@ mod kw { syn::custom_keyword!(message_capacity); } - #[derive(Clone, Debug)] enum OverseerAttrItem { - ExternEventType { - tag: kw::event, - eq_token: Token![=], - value: Path - }, - ExternNetworkType { - tag: kw::network, - eq_token: Token![=], - value: Path - }, - ExternOverseerSignalType { - tag: kw::signal, - eq_token: Token![=], - value: Path - }, - ExternErrorType { - tag: kw::error, - eq_token: Token![=], - value: Path - }, - OutgoingType { - tag: kw::outgoing, - eq_token: Token![=], - value: Path - }, - MessageWrapperName { - tag: kw::gen, - eq_token: Token![=], - value: Ident - }, - SignalChannelCapacity { - tag: kw::signal_capacity, - eq_token: Token![=], - value: usize - }, - MessageChannelCapacity { - tag: kw::message_capacity, - eq_token: Token![=], - value: usize - }, + ExternEventType { tag: kw::event, eq_token: Token![=], value: Path }, + ExternNetworkType { tag: kw::network, eq_token: Token![=], value: Path }, + ExternOverseerSignalType { tag: kw::signal, eq_token: Token![=], value: Path }, + ExternErrorType { tag: kw::error, eq_token: Token![=], value: Path }, + OutgoingType { tag: kw::outgoing, eq_token: Token![=], value: Path }, + MessageWrapperName { tag: kw::gen, eq_token: Token![=], value: Ident }, + SignalChannelCapacity { tag: kw::signal_capacity, eq_token: Token![=], value: usize }, + MessageChannelCapacity { tag: kw::message_capacity, eq_token: Token![=], value: usize }, } impl ToTokens for OverseerAttrItem { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { let ts = match self { - Self::ExternEventType { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } - Self::ExternNetworkType { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } - Self::ExternOverseerSignalType { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } - Self::ExternErrorType { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } - Self::OutgoingType { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } - Self::MessageWrapperName { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } - Self::SignalChannelCapacity { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } - Self::MessageChannelCapacity { tag, eq_token, value } => { quote!{ #tag #eq_token, #value } } + Self::ExternEventType { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, + Self::ExternNetworkType { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, + Self::ExternOverseerSignalType { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, + Self::ExternErrorType { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, + Self::OutgoingType { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, + Self::MessageWrapperName { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, + Self::SignalChannelCapacity { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, + Self::MessageChannelCapacity { tag, eq_token, value } => { + quote! { #tag #eq_token, #value } + }, }; tokens.extend(ts.into_iter()); } @@ -137,7 +122,7 @@ impl Parse for OverseerAttrItem { Ok(OverseerAttrItem::SignalChannelCapacity { tag: input.parse::()?, eq_token: input.parse()?, - value: input.parse::()?.base10_parse::()? + value: input.parse::()?.base10_parse::()?, }) } else if lookahead.peek(kw::message_capacity) { Ok(OverseerAttrItem::MessageChannelCapacity { @@ -169,42 +154,47 @@ pub(crate) struct AttrArgs { macro_rules! extract_variant { ($unique:expr, $variant:ident ; default = $fallback:expr) => { - extract_variant!($unique, $variant) - .unwrap_or_else(|| { $fallback }) + extract_variant!($unique, $variant).unwrap_or_else(|| $fallback) }; ($unique:expr, $variant:ident ; err = $err:expr) => { - extract_variant!($unique, $variant) - .ok_or_else(|| { - Error::new(Span::call_site(), $err) - }) + extract_variant!($unique, $variant).ok_or_else(|| Error::new(Span::call_site(), $err)) }; ($unique:expr, $variant:ident) => { - $unique.values() - .find_map(|item| { - if let OverseerAttrItem:: $variant { value, ..} = item { - Some(value.clone()) - } else { - None - } - }) + $unique.values().find_map(|item| { + if let OverseerAttrItem::$variant { value, .. } = item { + Some(value.clone()) + } else { + None + } + }) }; } impl Parse for AttrArgs { fn parse(input: &ParseBuffer) -> Result { - let items: Punctuated = input.parse_terminated(OverseerAttrItem::parse)?; - - let mut unique = HashMap::, OverseerAttrItem, RandomState>::default(); + let items: Punctuated = + input.parse_terminated(OverseerAttrItem::parse)?; + + let mut unique = HashMap::< + std::mem::Discriminant, + OverseerAttrItem, + RandomState, + >::default(); for item in items { if let Some(first) = unique.insert(std::mem::discriminant(&item), item.clone()) { - let mut e = Error::new(item.span(), format!("Duplicate definition of overseer generation type found")); + let mut e = Error::new( + item.span(), + format!("Duplicate definition of overseer generation type found"), + ); e.combine(Error::new(first.span(), "previously defined here.")); - return Err(e); + return Err(e) } } - let signal_channel_capacity = extract_variant!(unique, SignalChannelCapacity; default = 64_usize); - let message_channel_capacity = extract_variant!(unique, MessageChannelCapacity; default = 1024_usize); + let signal_channel_capacity = + extract_variant!(unique, SignalChannelCapacity; default = 64_usize); + let message_channel_capacity = + extract_variant!(unique, MessageChannelCapacity; default = 1024_usize); let error = extract_variant!(unique, ExternErrorType; err = "Must declare the overseer error type via `error=..`.")?; let event = extract_variant!(unique, ExternEventType; err = "Must declare the overseer event type via `event=..`.")?; diff --git a/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_struct.rs b/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_struct.rs index 280b0cb6a9b..f06c09061f5 100644 --- a/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_struct.rs +++ b/polkadot/node/overseer/overseer-gen/proc-macro/src/parse_struct.rs @@ -15,13 +15,13 @@ // along with Polkadot. If not, see . use proc_macro2::{Span, TokenStream}; -use std::collections::{hash_map::RandomState, HashSet, HashMap}; -use syn::punctuated::Punctuated; -use syn::spanned::Spanned; -use syn::parse::{Parse, ParseStream}; +use std::collections::{hash_map::RandomState, HashMap, HashSet}; use syn::{ - Attribute, Field, FieldsNamed, Ident, Token, Type, AttrStyle, Path, - Error, GenericParam, ItemStruct, Result, Visibility + parse::{Parse, ParseStream}, + punctuated::Punctuated, + spanned::Spanned, + AttrStyle, Attribute, Error, Field, FieldsNamed, GenericParam, Ident, ItemStruct, Path, Result, + Token, Type, Visibility, }; use quote::{quote, ToTokens}; @@ -32,7 +32,6 @@ mod kw { syn::custom_keyword!(blocking); } - #[derive(Clone, Debug)] enum SubSysAttrItem { /// The subsystem is still a work in progress @@ -64,15 +63,20 @@ impl Parse for SubSysAttrItem { impl ToTokens for SubSysAttrItem { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { let ts = match self { - Self::Wip(wip) => { quote!{ #wip } } - Self::Blocking(blocking) => { quote!{ #blocking } } - Self::NoDispatch(no_dispatch) => { quote!{ #no_dispatch } } + Self::Wip(wip) => { + quote! { #wip } + }, + Self::Blocking(blocking) => { + quote! { #blocking } + }, + Self::NoDispatch(no_dispatch) => { + quote! { #no_dispatch } + }, }; tokens.extend(ts.into_iter()); } } - /// A field of the struct annotated with /// `#[subsystem(no_dispatch, , A | B | C)]` #[derive(Clone, Debug)] @@ -106,28 +110,22 @@ fn try_type_to_path(ty: Type, span: Span) -> Result { macro_rules! extract_variant { ($unique:expr, $variant:ident ; default = $fallback:expr) => { - extract_variant!($unique, $variant) - .unwrap_or_else(|| { $fallback }) + extract_variant!($unique, $variant).unwrap_or_else(|| $fallback) }; ($unique:expr, $variant:ident ; err = $err:expr) => { - extract_variant!($unique, $variant) - .ok_or_else(|| { - Error::new(Span::call_site(), $err) - }) + extract_variant!($unique, $variant).ok_or_else(|| Error::new(Span::call_site(), $err)) }; ($unique:expr, $variant:ident) => { - $unique.values() - .find_map(|item| { - if let SubSysAttrItem:: $variant ( _ ) = item { - Some(true) - } else { - None - } - }) + $unique.values().find_map(|item| { + if let SubSysAttrItem::$variant(_) = item { + Some(true) + } else { + None + } + }) }; } - pub(crate) struct SubSystemTags { #[allow(dead_code)] pub(crate) attrs: Vec, @@ -158,12 +156,19 @@ impl Parse for SubSystemTags { let consumes = content.parse::()?; - let mut unique = HashMap::, SubSysAttrItem, RandomState>::default(); + let mut unique = HashMap::< + std::mem::Discriminant, + SubSysAttrItem, + RandomState, + >::default(); for item in items { if let Some(first) = unique.insert(std::mem::discriminant(&item), item.clone()) { - let mut e = Error::new(item.span(), format!("Duplicate definition of subsystem attribute found")); + let mut e = Error::new( + item.span(), + format!("Duplicate definition of subsystem attribute found"), + ); e.combine(Error::new(first.span(), "previously defined here.")); - return Err(e); + return Err(e) } } @@ -228,10 +233,7 @@ impl OverseerInfo { } pub(crate) fn variant_names(&self) -> Vec { - self.subsystems - .iter() - .map(|ssf| ssf.generic.clone()) - .collect::>() + self.subsystems.iter().map(|ssf| ssf.generic.clone()).collect::>() } pub(crate) fn variant_names_without_wip(&self) -> Vec { @@ -272,13 +274,8 @@ impl OverseerInfo { self.baggage .iter() .map(|bag| { - let BaggageField { - vis, - field_ty, - field_name, - .. - } = bag; - quote!{ #vis #field_name: #field_ty } + let BaggageField { vis, field_ty, field_name, .. } = bag; + quote! { #vis #field_name: #field_ty } }) .collect::>() } @@ -330,7 +327,11 @@ pub(crate) struct OverseerGuts { } impl OverseerGuts { - pub(crate) fn parse_fields(name: Ident, baggage_generics: HashSet, fields: FieldsNamed) -> Result { + pub(crate) fn parse_fields( + name: Ident, + baggage_generics: HashSet, + fields: FieldsNamed, + ) -> Result { let n = fields.named.len(); let mut subsystems = Vec::with_capacity(n); let mut baggage = Vec::with_capacity(n); @@ -340,14 +341,16 @@ impl OverseerGuts { // for the builder pattern besides other places. let mut unique_subsystem_idents = HashSet::::new(); for Field { attrs, vis, ident, ty, .. } in fields.named.into_iter() { - let mut consumes = attrs.iter().filter(|attr| attr.style == AttrStyle::Outer).filter_map(|attr| { - let span = attr.path.span(); - attr.path.get_ident().filter(|ident| *ident == "subsystem").map(move |_ident| { - let attr_tokens = attr.tokens.clone(); - (attr_tokens, span) - }) - }); - let ident = ident.ok_or_else(|| Error::new(ty.span(), "Missing identifier for member. BUG"))?; + let mut consumes = + attrs.iter().filter(|attr| attr.style == AttrStyle::Outer).filter_map(|attr| { + let span = attr.path.span(); + attr.path.get_ident().filter(|ident| *ident == "subsystem").map(move |_ident| { + let attr_tokens = attr.tokens.clone(); + (attr_tokens, span) + }) + }); + let ident = + ident.ok_or_else(|| Error::new(ty.span(), "Missing identifier for member. BUG"))?; if let Some((attr_tokens, span)) = consumes.next() { if let Some((_attr_tokens2, span2)) = consumes.next() { @@ -355,7 +358,7 @@ impl OverseerGuts { let mut err = Error::new(span, "The first subsystem annotation is at"); err.combine(Error::new(span2, "but another here for the same field.")); err - }); + }) } let mut consumes_paths = Vec::with_capacity(attrs.len()); let attr_tokens = attr_tokens.clone(); @@ -363,9 +366,17 @@ impl OverseerGuts { consumes_paths.push(variant.consumes); let field_ty = try_type_to_path(ty, span)?; - let generic = field_ty.get_ident().ok_or_else(|| Error::new(field_ty.span(), "Must be an identifier, not a path."))?.clone(); + let generic = field_ty + .get_ident() + .ok_or_else(|| { + Error::new(field_ty.span(), "Must be an identifier, not a path.") + })? + .clone(); if let Some(previous) = unique_subsystem_idents.get(&generic) { - let mut e = Error::new(generic.span(), format!("Duplicate subsystem names `{}`", generic)); + let mut e = Error::new( + generic.span(), + format!("Duplicate subsystem names `{}`", generic), + ); e.combine(Error::new(previous.span(), "previously defined here.")); return Err(e) } @@ -381,7 +392,10 @@ impl OverseerGuts { }); } else { let field_ty = try_type_to_path(ty, ident.span())?; - let generic = field_ty.get_ident().map(|ident| baggage_generics.contains(ident)).unwrap_or_default(); + let generic = field_ty + .get_ident() + .map(|ident| baggage_generics.contains(ident)) + .unwrap_or_default(); baggage.push(BaggageField { field_name: ident, generic, field_ty, vis }); } } @@ -411,21 +425,23 @@ impl Parse for OverseerGuts { baggage_generic_idents.insert(param.ident.clone()); param.eq_token = None; param.default = None; - } - _ => {} + }, + _ => {}, } generic }) .collect(); Self::parse_fields(name, baggage_generic_idents, named) - } - syn::Fields::Unit => { - Err(Error::new(ds.fields.span(), "Must be a struct with named fields. Not an unit struct.")) - } - syn::Fields::Unnamed(unnamed) => { - Err(Error::new(unnamed.span(), "Must be a struct with named fields. Not an unnamed fields struct.")) - } + }, + syn::Fields::Unit => Err(Error::new( + ds.fields.span(), + "Must be a struct with named fields. Not an unit struct.", + )), + syn::Fields::Unnamed(unnamed) => Err(Error::new( + unnamed.span(), + "Must be a struct with named fields. Not an unnamed fields struct.", + )), } } } diff --git a/polkadot/node/overseer/overseer-gen/src/lib.rs b/polkadot/node/overseer/overseer-gen/src/lib.rs index 6471c180340..f039a970d53 100644 --- a/polkadot/node/overseer/overseer-gen/src/lib.rs +++ b/polkadot/node/overseer/overseer-gen/src/lib.rs @@ -62,39 +62,34 @@ pub use polkadot_overseer_gen_proc_macro::overlord; -#[doc(hidden)] -pub use tracing; #[doc(hidden)] pub use metered; #[doc(hidden)] pub use polkadot_node_primitives::SpawnNamed; +#[doc(hidden)] +pub use tracing; +#[doc(hidden)] +pub use async_trait::async_trait; #[doc(hidden)] pub use futures::{ self, - select, - StreamExt, - FutureExt, - poll, - future::{ - Fuse, Future, BoxFuture - }, - stream::{ - self, select, FuturesUnordered, - }, - task::{ - Poll, Context, - }, channel::{mpsc, oneshot}, + future::{BoxFuture, Fuse, Future}, + poll, select, + stream::{self, select, FuturesUnordered}, + task::{Context, Poll}, + FutureExt, StreamExt, }; #[doc(hidden)] pub use std::pin::Pin; -#[doc(hidden)] -pub use async_trait::async_trait; +use std::sync::{ + atomic::{self, AtomicUsize}, + Arc, +}; #[doc(hidden)] pub use std::time::Duration; -use std::sync::{Arc, atomic::{self, AtomicUsize}}; #[doc(hidden)] pub use futures_timer::Delay; @@ -103,7 +98,6 @@ pub use polkadot_node_network_protocol::WrongVariant; use std::fmt; - #[cfg(test)] mod tests; @@ -134,15 +128,12 @@ pub enum ToOverseer { impl fmt::Debug for ToOverseer { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::SpawnJob{ name, .. } => writeln!(f, "SpawnJob{{ {}, ..}}", name), - Self::SpawnBlockingJob{ name, .. } => writeln!(f, "SpawnBlockingJob{{ {}, ..}}", name), + Self::SpawnJob { name, .. } => writeln!(f, "SpawnJob{{ {}, ..}}", name), + Self::SpawnBlockingJob { name, .. } => writeln!(f, "SpawnBlockingJob{{ {}, ..}}", name), } } - } - - /// A helper trait to map a subsystem to smth. else. pub trait MapSubsystem { /// The output type of the mapping. @@ -152,7 +143,10 @@ pub trait MapSubsystem { fn map_subsystem(&self, sub: T) -> Self::Output; } -impl MapSubsystem for F where F: Fn(T) -> U { +impl MapSubsystem for F +where + F: Fn(T) -> U, +{ type Output = U; fn map_subsystem(&self, sub: T) -> U { @@ -178,10 +172,7 @@ pub struct MessagePacket { /// Create a packet from its parts. pub fn make_packet(signals_received: usize, message: T) -> MessagePacket { - MessagePacket { - signals_received, - message, - } + MessagePacket { signals_received, message } } /// Incoming messages from both the bounded and unbounded channel. @@ -190,7 +181,6 @@ pub type SubsystemIncomingMessages = self::stream::Select< self::metered::UnboundedMeteredReceiver>, >; - /// Watermark to track the received signals. #[derive(Debug, Default, Clone)] pub struct SignalsReceived(Arc); @@ -208,8 +198,6 @@ impl SignalsReceived { } } - - /// A trait to support the origin annotation /// such that errors across subsystems can be easier tracked. pub trait AnnotateErrorOrigin: 'static + Send + Sync + std::error::Error { @@ -227,12 +215,8 @@ pub trait AnnotateErrorOrigin: 'static + Send + Sync + std::error::Error { /// /// In essence it's just a new type wrapping a `BoxFuture`. pub struct SpawnedSubsystem - where - E: std::error::Error - + Send - + Sync - + 'static - + From, +where + E: std::error::Error + Send + Sync + 'static + From, { /// Name of the subsystem being spawned. pub name: &'static str, @@ -274,7 +258,8 @@ pub enum OverseerError { /// An additional annotation tag for the origin of `source`. origin: &'static str, /// The wrapped error. Marked as source for tracking the error chain. - #[source] source: Box + #[source] + source: Box, }, } @@ -303,7 +288,6 @@ impl SubsystemMeters { } } - /// Set of readouts of the `Meter`s of a subsystem. pub struct SubsystemMeterReadouts { #[allow(missing_docs)] @@ -377,7 +361,7 @@ pub trait SubsystemContext: Send + 'static { /// The sender type as provided by `sender()` and underlying. type Sender: SubsystemSender + Send + 'static; /// The error type. - type Error: ::std::error::Error + ::std::convert::From< OverseerError > + Sync + Send + 'static; + type Error: ::std::error::Error + ::std::convert::From + Sync + Send + 'static; /// Try to asynchronously receive a message. /// @@ -392,7 +376,7 @@ pub trait SubsystemContext: Send + 'static { fn spawn( &mut self, name: &'static str, - s: ::std::pin::Pin + Send>> + s: ::std::pin::Pin + Send>>, ) -> Result<(), Self::Error>; /// Spawn a blocking child task on the executor's dedicated thread pool. @@ -404,22 +388,24 @@ pub trait SubsystemContext: Send + 'static { /// Send a direct message to some other `Subsystem`, routed based on message type. async fn send_message(&mut self, msg: X) - where - Self::AllMessages: From, - X: Send, + where + Self::AllMessages: From, + X: Send, { self.sender().send_message(::from(msg)).await } /// Send multiple direct messages to other `Subsystem`s, routed based on message type. async fn send_messages(&mut self, msgs: T) - where - T: IntoIterator + Send, - T::IntoIter: Send, - Self::AllMessages: From, - X: Send, + where + T: IntoIterator + Send, + T::IntoIter: Send, + Self::AllMessages: From, + X: Send, { - self.sender().send_messages(msgs.into_iter().map(|x| ::from(x))).await + self.sender() + .send_messages(msgs.into_iter().map(|x| ::from(x))) + .await } /// Send a message using the unbounded connection. @@ -449,10 +435,9 @@ where E: std::error::Error + Send + Sync + 'static + From, { /// Start this `Subsystem` and return `SpawnedSubsystem`. - fn start(self, ctx: Ctx) -> SpawnedSubsystem < E >; + fn start(self, ctx: Ctx) -> SpawnedSubsystem; } - /// Sender end of a channel to interface with a subsystem. #[async_trait::async_trait] pub trait SubsystemSender: Send + Clone + 'static { @@ -461,7 +446,9 @@ pub trait SubsystemSender: Send + Clone + 'static { /// Send multiple direct messages to other `Subsystem`s, routed based on message type. async fn send_messages(&mut self, msgs: T) - where T: IntoIterator + Send, T::IntoIter: Send; + where + T: IntoIterator + Send, + T::IntoIter: Send; /// Send a message onto the unbounded queue of some other `Subsystem`, routed based on message /// type. @@ -488,27 +475,27 @@ pub trait TimeoutExt: Future { where Self: Sized, { - Timeout { - future: self, - delay: Delay::new(duration), - } + Timeout { future: self, delay: Delay::new(duration) } } } -impl TimeoutExt for F where F: Future{} +impl TimeoutExt for F where F: Future {} -impl Future for Timeout where F: Future { +impl Future for Timeout +where + F: Future, +{ type Output = Option; fn poll(self: Pin<&mut Self>, ctx: &mut Context) -> Poll { let this = self.project(); if this.delay.poll(ctx).is_ready() { - return Poll::Ready(None); + return Poll::Ready(None) } if let Poll::Ready(output) = this.future.poll(ctx) { - return Poll::Ready(Some(output)); + return Poll::Ready(Some(output)) } Poll::Pending diff --git a/polkadot/node/overseer/overseer-gen/src/tests.rs b/polkadot/node/overseer/overseer-gen/src/tests.rs index 1dc1d2e86d5..7e7999c6702 100644 --- a/polkadot/node/overseer/overseer-gen/src/tests.rs +++ b/polkadot/node/overseer/overseer-gen/src/tests.rs @@ -1,4 +1,3 @@ - // The generated code requires quite a bit of surrounding code to work. // Please refer to [the examples](examples/dummy.rs) and // [the minimal usage example](../examples/minimal-example.rs). diff --git a/polkadot/node/overseer/src/lib.rs b/polkadot/node/overseer/src/lib.rs index 8081b2660c7..2e2ddfd2d90 100644 --- a/polkadot/node/overseer/src/lib.rs +++ b/polkadot/node/overseer/src/lib.rs @@ -59,46 +59,36 @@ // yielding false positives #![warn(missing_docs)] -use std::fmt::{self, Debug}; -use std::pin::Pin; -use std::sync::Arc; -use std::time::Duration; -use std::collections::{hash_map, HashMap}; -use std::iter::FromIterator; - -use futures::channel::oneshot; -use futures::{ - select, - future::BoxFuture, - Future, FutureExt, StreamExt, +use std::{ + collections::{hash_map, HashMap}, + fmt::{self, Debug}, + iter::FromIterator, + pin::Pin, + sync::Arc, + time::Duration, }; + +use futures::{channel::oneshot, future::BoxFuture, select, Future, FutureExt, StreamExt}; use lru::LruCache; use parking_lot::RwLock; -use polkadot_primitives::v1::{Block, BlockId,BlockNumber, Hash, ParachainHost}; use client::{BlockImportNotification, BlockchainEvents, FinalityNotification}; +use polkadot_primitives::v1::{Block, BlockId, BlockNumber, Hash, ParachainHost}; use sp_api::{ApiExt, ProvideRuntimeApi}; -use polkadot_node_network_protocol::{ - v1 as protocol_v1, -}; +use polkadot_node_network_protocol::v1 as protocol_v1; use polkadot_node_subsystem_types::messages::{ - CandidateValidationMessage, CandidateBackingMessage, - ChainApiMessage, StatementDistributionMessage, - AvailabilityDistributionMessage, BitfieldSigningMessage, BitfieldDistributionMessage, - ProvisionerMessage, RuntimeApiMessage, - AvailabilityStoreMessage, NetworkBridgeMessage, CollationGenerationMessage, - CollatorProtocolMessage, AvailabilityRecoveryMessage, ApprovalDistributionMessage, - ApprovalVotingMessage, GossipSupportMessage, - NetworkBridgeEvent, - DisputeParticipationMessage, DisputeCoordinatorMessage, ChainSelectionMessage, - DisputeDistributionMessage, + ApprovalDistributionMessage, ApprovalVotingMessage, AvailabilityDistributionMessage, + AvailabilityRecoveryMessage, AvailabilityStoreMessage, BitfieldDistributionMessage, + BitfieldSigningMessage, CandidateBackingMessage, CandidateValidationMessage, ChainApiMessage, + ChainSelectionMessage, CollationGenerationMessage, CollatorProtocolMessage, + DisputeCoordinatorMessage, DisputeDistributionMessage, DisputeParticipationMessage, + GossipSupportMessage, NetworkBridgeEvent, NetworkBridgeMessage, ProvisionerMessage, + RuntimeApiMessage, StatementDistributionMessage, }; pub use polkadot_node_subsystem_types::{ - OverseerSignal, - errors::{SubsystemResult, SubsystemError,}, - ActiveLeavesUpdate, ActivatedLeaf, LeafStatus, - jaeger, + errors::{SubsystemError, SubsystemResult}, + jaeger, ActivatedLeaf, ActiveLeavesUpdate, LeafStatus, OverseerSignal, }; // TODO legacy, to be deleted, left for easier integration @@ -110,30 +100,15 @@ mod metrics; use self::metrics::Metrics; use polkadot_node_metrics::{ - metrics::{ - prometheus, - Metrics as MetricsTrait - }, + metrics::{prometheus, Metrics as MetricsTrait}, Metronome, }; +pub use polkadot_overseer_gen as gen; pub use polkadot_overseer_gen::{ - TimeoutExt, - SpawnNamed, - Subsystem, - SubsystemMeterReadouts, - SubsystemMeters, - SubsystemIncomingMessages, - SubsystemInstance, - SubsystemSender, - SubsystemContext, - overlord, - MessagePacket, - SignalsReceived, - FromOverseer, - ToOverseer, - MapSubsystem, + overlord, FromOverseer, MapSubsystem, MessagePacket, SignalsReceived, SpawnNamed, Subsystem, + SubsystemContext, SubsystemIncomingMessages, SubsystemInstance, SubsystemMeterReadouts, + SubsystemMeters, SubsystemSender, TimeoutExt, ToOverseer, }; -pub use polkadot_overseer_gen as gen; /// Store 2 days worth of blocks, not accounting for forks, /// in the LRU cache. Assumes a 6-second block time. @@ -142,14 +117,14 @@ const KNOWN_LEAVES_CACHE_SIZE: usize = 2 * 24 * 3600 / 6; #[cfg(test)] mod tests; - /// Whether a header supports parachain consensus or not. pub trait HeadSupportsParachains { /// Return true if the given header supports parachain consensus. Otherwise, false. fn head_supports_parachains(&self, head: &Hash) -> bool; } -impl HeadSupportsParachains for Arc where +impl HeadSupportsParachains for Arc +where Client: ProvideRuntimeApi, Client::Api: ParachainHost, { @@ -159,7 +134,6 @@ impl HeadSupportsParachains for Arc where } } - /// A handle used to communicate with the [`Overseer`]. /// /// [`Overseer`]: struct.Overseer.html @@ -205,11 +179,16 @@ impl Handle { /// Note that due the fact the overseer doesn't store the whole active-leaves set, only deltas, /// the response channel may never return if the hash was deactivated before this call. /// In this case, it's the caller's responsibility to ensure a timeout is set. - pub async fn wait_for_activation(&mut self, hash: Hash, response_channel: oneshot::Sender>) { + pub async fn wait_for_activation( + &mut self, + hash: Hash, + response_channel: oneshot::Sender>, + ) { self.send_and_log_error(Event::ExternalRequest(ExternalRequest::WaitForActivation { - hash, - response_channel - })).await; + hash, + response_channel, + })) + .await; } /// Tell `Overseer` to shutdown. @@ -293,21 +272,13 @@ pub struct BlockInfo { impl From> for BlockInfo { fn from(n: BlockImportNotification) -> Self { - BlockInfo { - hash: n.hash, - parent_hash: n.header.parent_hash, - number: n.header.number, - } + BlockInfo { hash: n.hash, parent_hash: n.header.parent_hash, number: n.header.number } } } impl From> for BlockInfo { fn from(n: FinalityNotification) -> Self { - BlockInfo { - hash: n.hash, - parent_hash: n.header.parent_hash, - number: n.header.number, - } + BlockInfo { hash: n.hash, parent_hash: n.header.parent_hash, number: n.header.number } } } @@ -345,10 +316,7 @@ pub enum ExternalRequest { /// Glues together the [`Overseer`] and `BlockchainEvents` by forwarding /// import and finality notifications into the [`OverseerHandle`]. -pub async fn forward_events>( - client: Arc

, - mut handle: Handle, -) { +pub async fn forward_events>(client: Arc

, mut handle: Handle) { let mut finality = client.finality_notification_stream(); let mut imports = client.import_notification_stream(); @@ -594,9 +562,53 @@ where /// # }); /// # } /// ``` - pub fn new( + pub fn new< + CV, + CB, + SD, + AD, + AR, + BS, + BD, + P, + RA, + AS, + NB, + CA, + CG, + CP, + ApD, + ApV, + GS, + DC, + DP, + DD, + CS, + >( leaves: impl IntoIterator, - all_subsystems: AllSubsystems, + all_subsystems: AllSubsystems< + CV, + CB, + SD, + AD, + AR, + BS, + BD, + P, + RA, + AS, + NB, + CA, + CG, + CP, + ApD, + ApV, + GS, + DC, + DP, + DD, + CS, + >, prometheus_registry: Option<&prometheus::Registry>, supports_parachains: SupportsParachains, s: S, @@ -604,8 +616,10 @@ where where CV: Subsystem, SubsystemError> + Send, CB: Subsystem, SubsystemError> + Send, - SD: Subsystem, SubsystemError> + Send, - AD: Subsystem, SubsystemError> + Send, + SD: Subsystem, SubsystemError> + + Send, + AD: Subsystem, SubsystemError> + + Send, AR: Subsystem, SubsystemError> + Send, BS: Subsystem, SubsystemError> + Send, BD: Subsystem, SubsystemError> + Send, @@ -616,7 +630,8 @@ where CA: Subsystem, SubsystemError> + Send, CG: Subsystem, SubsystemError> + Send, CP: Subsystem, SubsystemError> + Send, - ApD: Subsystem, SubsystemError> + Send, + ApD: + Subsystem, SubsystemError> + Send, ApV: Subsystem, SubsystemError> + Send, GS: Subsystem, SubsystemError> + Send, DC: Subsystem, SubsystemError> + Send, @@ -650,7 +665,9 @@ where .dispute_distribution(all_subsystems.dispute_distribution) .chain_selection(all_subsystems.chain_selection) .leaves(Vec::from_iter( - leaves.into_iter().map(|BlockInfo { hash, parent_hash: _, number }| (hash, number)) + leaves + .into_iter() + .map(|BlockInfo { hash, parent_hash: _, number }| (hash, number)), )) .known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE)) .active_leaves(Default::default()) @@ -669,33 +686,29 @@ where type Output = Option<(&'static str, SubsystemMeters)>; fn map_subsystem(&self, subsystem: &'a OverseenSubsystem) -> Self::Output { - subsystem.instance.as_ref().map(|instance| { - ( - instance.name, - instance.meters.clone(), - ) - }) + subsystem + .instance + .as_ref() + .map(|instance| (instance.name, instance.meters.clone())) } } let subsystem_meters = overseer.map_subsystems(ExtractNameAndMeters); let metronome_metrics = metrics.clone(); - let metronome = Metronome::new(std::time::Duration::from_millis(950)) - .for_each(move |_| { - + let metronome = + Metronome::new(std::time::Duration::from_millis(950)).for_each(move |_| { // We combine the amount of messages from subsystems to the overseer // as well as the amount of messages from external sources to the overseer // into one `to_overseer` value. metronome_metrics.channel_fill_level_snapshot( - subsystem_meters.iter() + subsystem_meters + .iter() .cloned() .filter_map(|x| x) - .map(|(name, ref meters)| (name, meters.read())) + .map(|(name, ref meters)| (name, meters.read())), ); - async move { - () - } + async move { () } }); overseer.spawner().spawn("metrics_metronome", Box::pin(metronome)); } @@ -705,10 +718,7 @@ where /// Stop the overseer. async fn stop(mut self) { - let _ = self.wait_terminate( - OverseerSignal::Conclude, - Duration::from_secs(1_u64) - ).await; + let _ = self.wait_terminate(OverseerSignal::Conclude, Duration::from_secs(1_u64)).await; } /// Run the `Overseer`. @@ -717,12 +727,8 @@ where for (hash, number) in std::mem::take(&mut self.leaves) { let _ = self.active_leaves.insert(hash, number); if let Some((span, status)) = self.on_head_activated(&hash, None) { - let update = ActiveLeavesUpdate::start_work(ActivatedLeaf { - hash, - number, - status, - span, - }); + let update = + ActiveLeavesUpdate::start_work(ActivatedLeaf { hash, number, status, span }); self.broadcast_signal(OverseerSignal::ActiveLeaves(update)).await?; } } @@ -778,8 +784,8 @@ where hash_map::Entry::Vacant(entry) => entry.insert(block.number), hash_map::Entry::Occupied(entry) => { debug_assert_eq!(*entry.get(), block.number); - return Ok(()); - } + return Ok(()) + }, }; let mut update = match self.on_head_activated(&block.hash, Some(block.parent_hash)) { @@ -787,7 +793,7 @@ where hash: block.hash, number: block.number, status, - span + span, }), None => ActiveLeavesUpdate::default(), }; @@ -822,7 +828,8 @@ where self.on_head_deactivated(deactivated) } - self.broadcast_signal(OverseerSignal::BlockFinalized(block.hash, block.number)).await?; + self.broadcast_signal(OverseerSignal::BlockFinalized(block.hash, block.number)) + .await?; // If there are no leaves being deactivated, we don't need to send an update. // @@ -836,11 +843,13 @@ where /// Handles a header activation. If the header's state doesn't support the parachains API, /// this returns `None`. - fn on_head_activated(&mut self, hash: &Hash, parent_hash: Option) - -> Option<(Arc, LeafStatus)> - { + fn on_head_activated( + &mut self, + hash: &Hash, + parent_hash: Option, + ) -> Option<(Arc, LeafStatus)> { if !self.supports_parachains.head_supports_parachains(hash) { - return None; + return None } self.metrics.on_head_activated(); @@ -894,9 +903,12 @@ where // it's fine if the listener is no longer interested let _ = response_channel.send(Ok(())); } else { - self.activation_external_listeners.entry(hash).or_default().push(response_channel); + self.activation_external_listeners + .entry(hash) + .or_default() + .push(response_channel); } - } + }, } } @@ -909,15 +921,12 @@ where } } - - - // Additional `From` implementations, in order to deal with incoming network messages. // Kept out of the proc macro, for sake of simplicity reduce the need to make even // more types to the proc macro logic. -use polkadot_node_network_protocol::{ - request_response::{request::IncomingRequest, v1 as req_res_v1}, +use polkadot_node_network_protocol::request_response::{ + request::IncomingRequest, v1 as req_res_v1, }; impl From> for AllMessages { diff --git a/polkadot/node/overseer/src/metrics.rs b/polkadot/node/overseer/src/metrics.rs index 8cf7bb93ecc..a2e3faa050b 100644 --- a/polkadot/node/overseer/src/metrics.rs +++ b/polkadot/node/overseer/src/metrics.rs @@ -33,7 +33,6 @@ struct MetricsInner { signals_received: prometheus::GaugeVec, } - /// A shareable metrics type for usage with the overseer. #[derive(Default, Clone)] pub struct Metrics(Option); @@ -59,30 +58,42 @@ impl Metrics { pub(crate) fn channel_fill_level_snapshot( &self, - collection: impl IntoIterator, + collection: impl IntoIterator, ) { if let Some(metrics) = &self.0 { - collection.into_iter().for_each( - |(name, readouts): (_, SubsystemMeterReadouts)| { - metrics.to_subsystem_bounded_sent.with_label_values(&[name]) - .set(readouts.bounded.sent as u64); - - metrics.to_subsystem_bounded_received.with_label_values(&[name]) - .set(readouts.bounded.received as u64); - - metrics.to_subsystem_unbounded_sent.with_label_values(&[name]) - .set(readouts.unbounded.sent as u64); - - metrics.to_subsystem_unbounded_received.with_label_values(&[name]) - .set(readouts.unbounded.received as u64); - - metrics.signals_sent.with_label_values(&[name]) - .set(readouts.signals.sent as u64); - - metrics.signals_received.with_label_values(&[name]) - .set(readouts.signals.received as u64); - } - ); + collection + .into_iter() + .for_each(|(name, readouts): (_, SubsystemMeterReadouts)| { + metrics + .to_subsystem_bounded_sent + .with_label_values(&[name]) + .set(readouts.bounded.sent as u64); + + metrics + .to_subsystem_bounded_received + .with_label_values(&[name]) + .set(readouts.bounded.received as u64); + + metrics + .to_subsystem_unbounded_sent + .with_label_values(&[name]) + .set(readouts.unbounded.sent as u64); + + metrics + .to_subsystem_unbounded_received + .with_label_values(&[name]) + .set(readouts.unbounded.received as u64); + + metrics + .signals_sent + .with_label_values(&[name]) + .set(readouts.signals.sent as u64); + + metrics + .signals_received + .with_label_values(&[name]) + .set(readouts.signals.received as u64); + }); } } } @@ -93,21 +104,21 @@ impl metrics::Metrics for Metrics { activated_heads_total: prometheus::register( prometheus::Counter::new( "parachain_activated_heads_total", - "Number of activated heads." + "Number of activated heads.", )?, registry, )?, deactivated_heads_total: prometheus::register( prometheus::Counter::new( "parachain_deactivated_heads_total", - "Number of deactivated heads." + "Number of deactivated heads.", )?, registry, )?, messages_relayed_total: prometheus::register( prometheus::Counter::new( "parachain_messages_relayed_total", - "Number of messages relayed by Overseer." + "Number of messages relayed by Overseer.", )?, registry, )?, @@ -117,9 +128,7 @@ impl metrics::Metrics for Metrics { "parachain_subsystem_bounded_sent", "Number of elements sent to subsystems' bounded queues", ), - &[ - "subsystem_name", - ], + &["subsystem_name"], )?, registry, )?, @@ -129,9 +138,7 @@ impl metrics::Metrics for Metrics { "parachain_subsystem_bounded_received", "Number of elements received by subsystems' bounded queues", ), - &[ - "subsystem_name", - ], + &["subsystem_name"], )?, registry, )?, @@ -141,9 +148,7 @@ impl metrics::Metrics for Metrics { "parachain_subsystem_unbounded_sent", "Number of elements sent to subsystems' unbounded queues", ), - &[ - "subsystem_name", - ], + &["subsystem_name"], )?, registry, )?, @@ -153,9 +158,7 @@ impl metrics::Metrics for Metrics { "parachain_subsystem_unbounded_received", "Number of elements received by subsystems' unbounded queues", ), - &[ - "subsystem_name", - ], + &["subsystem_name"], )?, registry, )?, @@ -165,9 +168,7 @@ impl metrics::Metrics for Metrics { "parachain_overseer_signals_sent", "Number of signals sent by overseer to subsystems", ), - &[ - "subsystem_name", - ], + &["subsystem_name"], )?, registry, )?, @@ -177,9 +178,7 @@ impl metrics::Metrics for Metrics { "parachain_overseer_signals_received", "Number of signals received by subsystems from overseer", ), - &[ - "subsystem_name", - ], + &["subsystem_name"], )?, registry, )?, diff --git a/polkadot/node/overseer/src/subsystems.rs b/polkadot/node/overseer/src/subsystems.rs index 192cbb8ba7b..648528730d6 100644 --- a/polkadot/node/overseer/src/subsystems.rs +++ b/polkadot/node/overseer/src/subsystems.rs @@ -19,16 +19,12 @@ //! In the future, everything should be set up using the generated //! overseer builder pattern instead. +use crate::{AllMessages, OverseerSignal}; use polkadot_node_subsystem_types::errors::SubsystemError; +use polkadot_overseer_all_subsystems_gen::AllSubsystemsGen; use polkadot_overseer_gen::{ - MapSubsystem, SubsystemContext, - Subsystem, - SpawnedSubsystem, - FromOverseer, + FromOverseer, MapSubsystem, SpawnedSubsystem, Subsystem, SubsystemContext, }; -use polkadot_overseer_all_subsystems_gen::AllSubsystemsGen; -use crate::OverseerSignal; -use crate::AllMessages; /// A dummy subsystem that implements [`Subsystem`] for all /// types of messages. Used for tests or as a placeholder. @@ -37,7 +33,11 @@ pub struct DummySubsystem; impl Subsystem for DummySubsystem where - Context: SubsystemContext, + Context: SubsystemContext< + Signal = OverseerSignal, + Error = SubsystemError, + AllMessages = AllMessages, + >, { fn start(self, mut ctx: Context) -> SpawnedSubsystem { let future = Box::pin(async move { @@ -51,20 +51,16 @@ where "Discarding a message sent from overseer {:?}", overseer_msg ); - continue; - } + continue + }, } } }); - SpawnedSubsystem { - name: "dummy-subsystem", - future, - } + SpawnedSubsystem { name: "dummy-subsystem", future } } } - /// This struct is passed as an argument to create a new instance of an [`Overseer`]. /// /// As any entity that satisfies the interface may act as a [`Subsystem`] this allows @@ -75,9 +71,27 @@ where /// subsystems are implemented and the rest can be mocked with the [`DummySubsystem`]. #[derive(Debug, Clone, AllSubsystemsGen)] pub struct AllSubsystems< - CV = (), CB = (), SD = (), AD = (), AR = (), BS = (), BD = (), P = (), - RA = (), AS = (), NB = (), CA = (), CG = (), CP = (), ApD = (), ApV = (), - GS = (), DC = (), DP = (), DD = (), CS = (), + CV = (), + CB = (), + SD = (), + AD = (), + AR = (), + BS = (), + BD = (), + P = (), + RA = (), + AS = (), + NB = (), + CA = (), + CG = (), + CP = (), + ApD = (), + ApV = (), + GS = (), + DC = (), + DP = (), + DD = (), + CS = (), > { /// A candidate validation subsystem. pub candidate_validation: CV, @@ -187,7 +201,31 @@ impl AllSubsystems<&'_ CV, &'_ CB, &'_ SD, &'_ AD, &'_ AR, &'_ BS, &'_ BD, &'_ P, &'_ RA, &'_ AS, &'_ NB, &'_ CA, &'_ CG, &'_ CP, &'_ ApD, &'_ ApV, &'_ GS, &'_ DC, &'_ DP, &'_ DD, &'_ CS> { + pub fn as_ref( + &self, + ) -> AllSubsystems< + &'_ CV, + &'_ CB, + &'_ SD, + &'_ AD, + &'_ AR, + &'_ BS, + &'_ BD, + &'_ P, + &'_ RA, + &'_ AS, + &'_ NB, + &'_ CA, + &'_ CG, + &'_ CP, + &'_ ApD, + &'_ ApV, + &'_ GS, + &'_ DC, + &'_ DP, + &'_ DD, + &'_ CS, + > { AllSubsystems { candidate_validation: &self.candidate_validation, candidate_backing: &self.candidate_backing, @@ -214,30 +252,32 @@ impl(self, mapper: Mapper) - -> AllSubsystems< - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - >::Output, - > + pub fn map_subsystems( + self, + mapper: Mapper, + ) -> AllSubsystems< + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + >::Output, + > where Mapper: MapSubsystem, Mapper: MapSubsystem, @@ -262,27 +302,81 @@ impl, { AllSubsystems { - candidate_validation: >::map_subsystem(&mapper, self.candidate_validation), - candidate_backing: >::map_subsystem(&mapper, self.candidate_backing), - statement_distribution: >::map_subsystem(&mapper, self.statement_distribution), - availability_distribution: >::map_subsystem(&mapper, self.availability_distribution), - availability_recovery: >::map_subsystem(&mapper, self.availability_recovery), - bitfield_signing: >::map_subsystem(&mapper, self.bitfield_signing), - bitfield_distribution: >::map_subsystem(&mapper, self.bitfield_distribution), + candidate_validation: >::map_subsystem( + &mapper, + self.candidate_validation, + ), + candidate_backing: >::map_subsystem( + &mapper, + self.candidate_backing, + ), + statement_distribution: >::map_subsystem( + &mapper, + self.statement_distribution, + ), + availability_distribution: >::map_subsystem( + &mapper, + self.availability_distribution, + ), + availability_recovery: >::map_subsystem( + &mapper, + self.availability_recovery, + ), + bitfield_signing: >::map_subsystem( + &mapper, + self.bitfield_signing, + ), + bitfield_distribution: >::map_subsystem( + &mapper, + self.bitfield_distribution, + ), provisioner: >::map_subsystem(&mapper, self.provisioner), runtime_api: >::map_subsystem(&mapper, self.runtime_api), - availability_store: >::map_subsystem(&mapper, self.availability_store), - network_bridge: >::map_subsystem(&mapper, self.network_bridge), + availability_store: >::map_subsystem( + &mapper, + self.availability_store, + ), + network_bridge: >::map_subsystem( + &mapper, + self.network_bridge, + ), chain_api: >::map_subsystem(&mapper, self.chain_api), - collation_generation: >::map_subsystem(&mapper, self.collation_generation), - collator_protocol: >::map_subsystem(&mapper, self.collator_protocol), - approval_distribution: >::map_subsystem(&mapper, self.approval_distribution), - approval_voting: >::map_subsystem(&mapper, self.approval_voting), - gossip_support: >::map_subsystem(&mapper, self.gossip_support), - dispute_coordinator: >::map_subsystem(&mapper, self.dispute_coordinator), - dispute_participation: >::map_subsystem(&mapper, self.dispute_participation), - dispute_distribution: >::map_subsystem(&mapper, self.dispute_distribution), - chain_selection: >::map_subsystem(&mapper, self.chain_selection), + collation_generation: >::map_subsystem( + &mapper, + self.collation_generation, + ), + collator_protocol: >::map_subsystem( + &mapper, + self.collator_protocol, + ), + approval_distribution: >::map_subsystem( + &mapper, + self.approval_distribution, + ), + approval_voting: >::map_subsystem( + &mapper, + self.approval_voting, + ), + gossip_support: >::map_subsystem( + &mapper, + self.gossip_support, + ), + dispute_coordinator: >::map_subsystem( + &mapper, + self.dispute_coordinator, + ), + dispute_participation: >::map_subsystem( + &mapper, + self.dispute_participation, + ), + dispute_distribution: >::map_subsystem( + &mapper, + self.dispute_distribution, + ), + chain_selection: >::map_subsystem( + &mapper, + self.chain_selection, + ), } } } diff --git a/polkadot/node/overseer/src/tests.rs b/polkadot/node/overseer/src/tests.rs index b435dabdaae..d0a79c086e6 100644 --- a/polkadot/node/overseer/src/tests.rs +++ b/polkadot/node/overseer/src/tests.rs @@ -14,47 +14,37 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::sync::atomic; -use std::collections::HashMap; -use std::task::{Poll}; -use futures::{executor, pin_mut, select, FutureExt, pending, poll, stream}; -use futures::channel::mpsc; - -use polkadot_primitives::v1::{CollatorPair, CandidateHash}; -use polkadot_node_primitives::{CollationResult, CollationGenerationConfig, PoV, BlockData}; +use futures::{channel::mpsc, executor, pending, pin_mut, poll, select, stream, FutureExt}; +use std::{collections::HashMap, sync::atomic, task::Poll}; + use polkadot_node_network_protocol::{PeerId, UnifiedReputationChange}; +use polkadot_node_primitives::{BlockData, CollationGenerationConfig, CollationResult, PoV}; use polkadot_node_subsystem_types::{ - ActivatedLeaf, LeafStatus, - messages::{ - RuntimeApiRequest, - NetworkBridgeEvent, - }, jaeger, + messages::{NetworkBridgeEvent, RuntimeApiRequest}, + ActivatedLeaf, LeafStatus, }; +use polkadot_primitives::v1::{CandidateHash, CollatorPair}; -use crate::{ - self as overseer, - Overseer, - HeadSupportsParachains, - gen::Delay, - -}; +use crate::{self as overseer, gen::Delay, HeadSupportsParachains, Overseer}; use metered_channel as metered; -use sp_core::crypto::Pair as _; use assert_matches::assert_matches; +use sp_core::crypto::Pair as _; use super::*; - type SpawnedSubsystem = crate::gen::SpawnedSubsystem; struct TestSubsystem1(metered::MeteredSender); impl overseer::Subsystem for TestSubsystem1 where - C: overseer::SubsystemContext, - + C: overseer::SubsystemContext< + Message = CandidateValidationMessage, + Signal = OverseerSignal, + AllMessages = AllMessages, + >, { fn start(self, mut ctx: C) -> SpawnedSubsystem { let mut sender = self.0; @@ -67,8 +57,8 @@ where Ok(FromOverseer::Communication { .. }) => { let _ = sender.send(i).await; i += 1; - continue; - } + continue + }, Ok(FromOverseer::Signal(OverseerSignal::Conclude)) => return Ok(()), Err(_) => return Ok(()), _ => (), @@ -83,7 +73,11 @@ struct TestSubsystem2(metered::MeteredSender); impl overseer::Subsystem for TestSubsystem2 where - C: overseer::SubsystemContext, + C: overseer::SubsystemContext< + Message = CandidateBackingMessage, + Signal = OverseerSignal, + AllMessages = AllMessages, + >, { fn start(self, mut ctx: C) -> SpawnedSubsystem { let sender = self.0.clone(); @@ -95,25 +89,18 @@ where loop { if c < 10 { let (tx, _) = oneshot::channel(); - ctx.send_message( - CandidateValidationMessage::ValidateFromChainState( - Default::default(), - PoV { - block_data: BlockData(Vec::new()), - }.into(), - tx, - ) - ).await; + ctx.send_message(CandidateValidationMessage::ValidateFromChainState( + Default::default(), + PoV { block_data: BlockData(Vec::new()) }.into(), + tx, + )) + .await; c += 1; - continue; + continue } match ctx.try_recv().await { - Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => { - break; - } - Ok(Some(_)) => { - continue; - } + Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => break, + Ok(Some(_)) => continue, Err(_) => return Ok(()), _ => (), } @@ -130,7 +117,11 @@ struct ReturnOnStart; impl overseer::Subsystem for ReturnOnStart where - C: overseer::SubsystemContext, + C: overseer::SubsystemContext< + Message = CandidateBackingMessage, + Signal = OverseerSignal, + AllMessages = AllMessages, + >, { fn start(self, mut _ctx: C) -> SpawnedSubsystem { SpawnedSubsystem { @@ -167,13 +158,8 @@ fn overseer_works() { .replace_candidate_validation(TestSubsystem1(s1_tx)) .replace_candidate_backing(TestSubsystem2(s2_tx)); - let (overseer, handle) = Overseer::new( - vec![], - all_subsystems, - None, - MockSupportsParachains, - spawner, - ).unwrap(); + let (overseer, handle) = + Overseer::new(vec![], all_subsystems, None, MockSupportsParachains, spawner).unwrap(); let mut handle = Handle::Connected(handle); let overseer_fut = overseer.run().fuse(); @@ -220,21 +206,12 @@ fn overseer_metrics_work() { let second_block_hash = [2; 32].into(); let third_block_hash = [3; 32].into(); - let first_block = BlockInfo { - hash: first_block_hash, - parent_hash: [0; 32].into(), - number: 1, - }; - let second_block = BlockInfo { - hash: second_block_hash, - parent_hash: first_block_hash, - number: 2, - }; - let third_block = BlockInfo { - hash: third_block_hash, - parent_hash: second_block_hash, - number: 3, - }; + let first_block = + BlockInfo { hash: first_block_hash, parent_hash: [0; 32].into(), number: 1 }; + let second_block = + BlockInfo { hash: second_block_hash, parent_hash: first_block_hash, number: 2 }; + let third_block = + BlockInfo { hash: third_block_hash, parent_hash: second_block_hash, number: 3 }; let all_subsystems = AllSubsystems::<()>::dummy(); let registry = prometheus::Registry::new(); @@ -244,7 +221,8 @@ fn overseer_metrics_work() { Some(®istry), MockSupportsParachains, spawner, - ).unwrap(); + ) + .unwrap(); let mut handle = Handle::Connected(handle); let overseer_fut = overseer.run().fuse(); @@ -252,7 +230,9 @@ fn overseer_metrics_work() { handle.block_imported(second_block).await; handle.block_imported(third_block).await; - handle.send_msg_anon(AllMessages::CandidateValidation(test_candidate_validation_msg())).await; + handle + .send_msg_anon(AllMessages::CandidateValidation(test_candidate_validation_msg())) + .await; handle.stop().await; select! { @@ -291,15 +271,9 @@ fn overseer_ends_on_subsystem_exit() { let spawner = sp_core::testing::TaskExecutor::new(); executor::block_on(async move { - let all_subsystems = AllSubsystems::<()>::dummy() - .replace_candidate_backing(ReturnOnStart); - let (overseer, _handle) = Overseer::new( - vec![], - all_subsystems, - None, - MockSupportsParachains, - spawner, - ).unwrap(); + let all_subsystems = AllSubsystems::<()>::dummy().replace_candidate_backing(ReturnOnStart); + let (overseer, _handle) = + Overseer::new(vec![], all_subsystems, None, MockSupportsParachains, spawner).unwrap(); overseer.run().await.unwrap(); }) @@ -309,7 +283,11 @@ struct TestSubsystem5(metered::MeteredSender); impl overseer::Subsystem for TestSubsystem5 where - C: overseer::SubsystemContext, + C: overseer::SubsystemContext< + Message = CandidateValidationMessage, + Signal = OverseerSignal, + AllMessages = AllMessages, + >, { fn start(self, mut ctx: C) -> SpawnedSubsystem { let mut sender = self.0.clone(); @@ -322,7 +300,7 @@ where Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => break, Ok(Some(FromOverseer::Signal(s))) => { sender.send(s).await.unwrap(); - continue; + continue }, Ok(Some(_)) => continue, Err(_) => break, @@ -341,7 +319,11 @@ struct TestSubsystem6(metered::MeteredSender); impl Subsystem for TestSubsystem6 where - C: overseer::SubsystemContext, + C: overseer::SubsystemContext< + Message = CandidateBackingMessage, + Signal = OverseerSignal, + AllMessages = AllMessages, + >, { fn start(self, mut ctx: C) -> SpawnedSubsystem { let mut sender = self.0.clone(); @@ -354,7 +336,7 @@ where Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => break, Ok(Some(FromOverseer::Signal(s))) => { sender.send(s).await.unwrap(); - continue; + continue }, Ok(Some(_)) => continue, Err(_) => break, @@ -380,34 +362,21 @@ fn overseer_start_stop_works() { let second_block_hash = [2; 32].into(); let third_block_hash = [3; 32].into(); - let first_block = BlockInfo { - hash: first_block_hash, - parent_hash: [0; 32].into(), - number: 1, - }; - let second_block = BlockInfo { - hash: second_block_hash, - parent_hash: first_block_hash, - number: 2, - }; - let third_block = BlockInfo { - hash: third_block_hash, - parent_hash: second_block_hash, - number: 3, - }; + let first_block = + BlockInfo { hash: first_block_hash, parent_hash: [0; 32].into(), number: 1 }; + let second_block = + BlockInfo { hash: second_block_hash, parent_hash: first_block_hash, number: 2 }; + let third_block = + BlockInfo { hash: third_block_hash, parent_hash: second_block_hash, number: 3 }; let (tx_5, mut rx_5) = metered::channel(64); let (tx_6, mut rx_6) = metered::channel(64); let all_subsystems = AllSubsystems::<()>::dummy() .replace_candidate_validation(TestSubsystem5(tx_5)) .replace_candidate_backing(TestSubsystem6(tx_6)); - let (overseer, handle) = Overseer::new( - vec![first_block], - all_subsystems, - None, - MockSupportsParachains, - spawner, - ).unwrap(); + let (overseer, handle) = + Overseer::new(vec![first_block], all_subsystems, None, MockSupportsParachains, spawner) + .unwrap(); let mut handle = Handle::Connected(handle); let overseer_fut = overseer.run().fuse(); @@ -466,8 +435,9 @@ fn overseer_start_stop_works() { } if ss5_results.len() == expected_heartbeats.len() && - ss6_results.len() == expected_heartbeats.len() { - handle.stop().await; + ss6_results.len() == expected_heartbeats.len() + { + handle.stop().await; } } @@ -487,21 +457,12 @@ fn overseer_finalize_works() { let second_block_hash = [2; 32].into(); let third_block_hash = [3; 32].into(); - let first_block = BlockInfo { - hash: first_block_hash, - parent_hash: [0; 32].into(), - number: 1, - }; - let second_block = BlockInfo { - hash: second_block_hash, - parent_hash: [42; 32].into(), - number: 2, - }; - let third_block = BlockInfo { - hash: third_block_hash, - parent_hash: second_block_hash, - number: 3, - }; + let first_block = + BlockInfo { hash: first_block_hash, parent_hash: [0; 32].into(), number: 1 }; + let second_block = + BlockInfo { hash: second_block_hash, parent_hash: [42; 32].into(), number: 2 }; + let third_block = + BlockInfo { hash: third_block_hash, parent_hash: second_block_hash, number: 3 }; let (tx_5, mut rx_5) = metered::channel(64); let (tx_6, mut rx_6) = metered::channel(64); @@ -517,7 +478,8 @@ fn overseer_finalize_works() { None, MockSupportsParachains, spawner, - ).unwrap(); + ) + .unwrap(); let mut handle = Handle::Connected(handle); let overseer_fut = overseer.run().fuse(); @@ -568,7 +530,9 @@ fn overseer_finalize_works() { complete => break, } - if ss5_results.len() == expected_heartbeats.len() && ss6_results.len() == expected_heartbeats.len() { + if ss5_results.len() == expected_heartbeats.len() && + ss6_results.len() == expected_heartbeats.len() + { handle.stop().await; } } @@ -590,30 +554,20 @@ fn do_not_send_empty_leaves_update_on_block_finalization() { let spawner = sp_core::testing::TaskExecutor::new(); executor::block_on(async move { - let imported_block = BlockInfo { - hash: Hash::random(), - parent_hash: Hash::random(), - number: 1, - }; + let imported_block = + BlockInfo { hash: Hash::random(), parent_hash: Hash::random(), number: 1 }; - let finalized_block = BlockInfo { - hash: Hash::random(), - parent_hash: Hash::random(), - number: 1, - }; + let finalized_block = + BlockInfo { hash: Hash::random(), parent_hash: Hash::random(), number: 1 }; let (tx_5, mut rx_5) = metered::channel(64); - let all_subsystems = AllSubsystems::<()>::dummy() - .replace_candidate_backing(TestSubsystem6(tx_5)); + let all_subsystems = + AllSubsystems::<()>::dummy().replace_candidate_backing(TestSubsystem6(tx_5)); - let (overseer, handle) = Overseer::new( - Vec::new(), - all_subsystems, - None, - MockSupportsParachains, - spawner, - ).unwrap(); + let (overseer, handle) = + Overseer::new(Vec::new(), all_subsystems, None, MockSupportsParachains, spawner) + .unwrap(); let mut handle = Handle::Connected(handle); let overseer_fut = overseer.run().fuse(); @@ -673,17 +627,13 @@ impl CounterSubsystem { signals_received: Arc, msgs_received: Arc, ) -> Self { - Self { - stop_signals_received, - signals_received, - msgs_received, - } + Self { stop_signals_received, signals_received, msgs_received } } } impl Subsystem for CounterSubsystem where - C: overseer::SubsystemContext, + C: overseer::SubsystemContext, M: Send, { fn start(self, mut ctx: C) -> SpawnedSubsystem { @@ -694,15 +644,15 @@ where match ctx.try_recv().await { Ok(Some(FromOverseer::Signal(OverseerSignal::Conclude))) => { self.stop_signals_received.fetch_add(1, atomic::Ordering::SeqCst); - break; + break }, Ok(Some(FromOverseer::Signal(_))) => { self.signals_received.fetch_add(1, atomic::Ordering::SeqCst); - continue; + continue }, Ok(Some(FromOverseer::Communication { .. })) => { self.msgs_received.fetch_add(1, atomic::Ordering::SeqCst); - continue; + continue }, Err(_) => (), _ => (), @@ -872,47 +822,74 @@ fn overseer_all_subsystems_receive_signals_and_messages() { dispute_distribution: subsystem.clone(), chain_selection: subsystem.clone(), }; - let (overseer, handle) = Overseer::new( - vec![], - all_subsystems, - None, - MockSupportsParachains, - spawner, - ).unwrap(); + let (overseer, handle) = + Overseer::new(vec![], all_subsystems, None, MockSupportsParachains, spawner).unwrap(); let mut handle = Handle::Connected(handle); let overseer_fut = overseer.run().fuse(); pin_mut!(overseer_fut); // send a signal to each subsystem - handle.block_imported(BlockInfo { - hash: Default::default(), - parent_hash: Default::default(), - number: Default::default(), - }).await; + handle + .block_imported(BlockInfo { + hash: Default::default(), + parent_hash: Default::default(), + number: Default::default(), + }) + .await; // send a msg to each subsystem // except for BitfieldSigning and GossipSupport as the messages are not instantiable - handle.send_msg_anon(AllMessages::CandidateValidation(test_candidate_validation_msg())).await; - handle.send_msg_anon(AllMessages::CandidateBacking(test_candidate_backing_msg())).await; - handle.send_msg_anon(AllMessages::CollationGeneration(test_collator_generation_msg())).await; - handle.send_msg_anon(AllMessages::CollatorProtocol(test_collator_protocol_msg())).await; - handle.send_msg_anon(AllMessages::StatementDistribution(test_statement_distribution_msg())).await; - handle.send_msg_anon(AllMessages::AvailabilityRecovery(test_availability_recovery_msg())).await; + handle + .send_msg_anon(AllMessages::CandidateValidation(test_candidate_validation_msg())) + .await; + handle + .send_msg_anon(AllMessages::CandidateBacking(test_candidate_backing_msg())) + .await; + handle + .send_msg_anon(AllMessages::CollationGeneration(test_collator_generation_msg())) + .await; + handle + .send_msg_anon(AllMessages::CollatorProtocol(test_collator_protocol_msg())) + .await; + handle + .send_msg_anon(AllMessages::StatementDistribution(test_statement_distribution_msg())) + .await; + handle + .send_msg_anon(AllMessages::AvailabilityRecovery(test_availability_recovery_msg())) + .await; // handle.send_msg_anon(AllMessages::BitfieldSigning(test_bitfield_signing_msg())).await; // handle.send_msg_anon(AllMessages::GossipSupport(test_bitfield_signing_msg())).await; - handle.send_msg_anon(AllMessages::BitfieldDistribution(test_bitfield_distribution_msg())).await; + handle + .send_msg_anon(AllMessages::BitfieldDistribution(test_bitfield_distribution_msg())) + .await; handle.send_msg_anon(AllMessages::Provisioner(test_provisioner_msg())).await; handle.send_msg_anon(AllMessages::RuntimeApi(test_runtime_api_msg())).await; - handle.send_msg_anon(AllMessages::AvailabilityStore(test_availability_store_msg())).await; - handle.send_msg_anon(AllMessages::NetworkBridge(test_network_bridge_msg())).await; + handle + .send_msg_anon(AllMessages::AvailabilityStore(test_availability_store_msg())) + .await; + handle + .send_msg_anon(AllMessages::NetworkBridge(test_network_bridge_msg())) + .await; handle.send_msg_anon(AllMessages::ChainApi(test_chain_api_msg())).await; - handle.send_msg_anon(AllMessages::ApprovalDistribution(test_approval_distribution_msg())).await; - handle.send_msg_anon(AllMessages::ApprovalVoting(test_approval_voting_msg())).await; - handle.send_msg_anon(AllMessages::DisputeCoordinator(test_dispute_coordinator_msg())).await; - handle.send_msg_anon(AllMessages::DisputeParticipation(test_dispute_participation_msg())).await; - handle.send_msg_anon(AllMessages::DisputeDistribution(test_dispute_distribution_msg())).await; - handle.send_msg_anon(AllMessages::ChainSelection(test_chain_selection_msg())).await; + handle + .send_msg_anon(AllMessages::ApprovalDistribution(test_approval_distribution_msg())) + .await; + handle + .send_msg_anon(AllMessages::ApprovalVoting(test_approval_voting_msg())) + .await; + handle + .send_msg_anon(AllMessages::DisputeCoordinator(test_dispute_coordinator_msg())) + .await; + handle + .send_msg_anon(AllMessages::DisputeParticipation(test_dispute_participation_msg())) + .await; + handle + .send_msg_anon(AllMessages::DisputeDistribution(test_dispute_distribution_msg())) + .await; + handle + .send_msg_anon(AllMessages::ChainSelection(test_chain_selection_msg())) + .await; // Wait until all subsystems have received. Otherwise the messages might race against // the conclude signal. @@ -927,7 +904,7 @@ fn overseer_all_subsystems_receive_signals_and_messages() { } else { break } - } + }, Some(_) => panic!("exited too early"), } } @@ -1055,17 +1032,16 @@ fn context_holds_onto_message_until_enough_signals_received() { assert_matches!(ctx.recv().await.unwrap(), FromOverseer::Signal(OverseerSignal::Conclude)); assert_eq!(ctx.signals_received.load(), 1); - bounded_tx.send(MessagePacket { - signals_received: 2, - message: (), - }).await.unwrap(); - unbounded_tx.unbounded_send(MessagePacket { - signals_received: 2, - message: (), - }).unwrap(); + bounded_tx + .send(MessagePacket { signals_received: 2, message: () }) + .await + .unwrap(); + unbounded_tx + .unbounded_send(MessagePacket { signals_received: 2, message: () }) + .unwrap(); match poll!(ctx.recv()) { - Poll::Pending => {} + Poll::Pending => {}, Poll::Ready(_) => panic!("ready too early"), }; diff --git a/polkadot/node/primitives/src/approval.rs b/polkadot/node/primitives/src/approval.rs index c57b3844e42..73d132a851b 100644 --- a/polkadot/node/primitives/src/approval.rs +++ b/polkadot/node/primitives/src/approval.rs @@ -16,16 +16,16 @@ //! Types relevant for approval. -pub use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof, Randomness}; pub use sp_consensus_babe::Slot; +pub use sp_consensus_vrf::schnorrkel::{Randomness, VRFOutput, VRFProof}; +use parity_scale_codec::{Decode, Encode}; use polkadot_primitives::v1::{ - CandidateHash, Hash, ValidatorIndex, ValidatorSignature, CoreIndex, - Header, BlockNumber, CandidateIndex, + BlockNumber, CandidateHash, CandidateIndex, CoreIndex, Hash, Header, ValidatorIndex, + ValidatorSignature, }; -use parity_scale_codec::{Encode, Decode}; -use sp_consensus_babe as babe_primitives; use sp_application_crypto::Public; +use sp_consensus_babe as babe_primitives; /// Validators assigning to check a particular candidate are split up into tranches. /// Earlier tranches of validators check first, with later tranches serving as backup. @@ -168,13 +168,12 @@ impl UnsafeVRFOutput { let pubkey = schnorrkel::PublicKey::from_bytes(author.as_slice()) .map_err(ApprovalError::SchnorrkelSignature)?; - let transcript = babe_primitives::make_transcript( - randomness, - self.slot, - epoch_index, - ); + let transcript = babe_primitives::make_transcript(randomness, self.slot, epoch_index); - let inout = self.vrf_output.0.attach_input_hash(&pubkey, transcript) + let inout = self + .vrf_output + .0 + .attach_input_hash(&pubkey, transcript) .map_err(ApprovalError::SchnorrkelSignature)?; Ok(RelayVRFStory(inout.make_bytes(RELAY_VRF_STORY_CONTEXT))) } @@ -200,11 +199,7 @@ pub fn babe_unsafe_vrf_info(header: &Header) -> Option { PreDigest::SecondaryPlain(_) => return None, }; - return Some(UnsafeVRFOutput { - vrf_output, - slot, - authority_index, - }); + return Some(UnsafeVRFOutput { vrf_output, slot, authority_index }) } } diff --git a/polkadot/node/primitives/src/disputes/message.rs b/polkadot/node/primitives/src/disputes/message.rs index f5204799925..94e609c30ae 100644 --- a/polkadot/node/primitives/src/disputes/message.rs +++ b/polkadot/node/primitives/src/disputes/message.rs @@ -23,7 +23,9 @@ use thiserror::Error; use parity_scale_codec::{Decode, Encode}; -use polkadot_primitives::v1::{CandidateReceipt, DisputeStatement, SessionIndex, SessionInfo, ValidatorIndex}; +use polkadot_primitives::v1::{ + CandidateReceipt, DisputeStatement, SessionIndex, SessionInfo, ValidatorIndex, +}; use super::{InvalidDisputeVote, SignedDisputeStatement, ValidDisputeVote}; @@ -92,7 +94,6 @@ pub enum Error { } impl DisputeMessage { - /// Build a `SignedDisputeMessage` and check what can be checked. /// /// This function checks that: @@ -156,16 +157,12 @@ impl DisputeMessage { let valid_kind = match valid_statement.statement() { DisputeStatement::Valid(v) => v, - _ => { - return Err(Error::ValidStatementHasInvalidKind) - } + _ => return Err(Error::ValidStatementHasInvalidKind), }; let invalid_kind = match invalid_statement.statement() { DisputeStatement::Invalid(v) => v, - _ => { - return Err(Error::InvalidStatementHasValidKind) - } + _ => return Err(Error::InvalidStatementHasValidKind), }; let valid_vote = ValidDisputeVote { @@ -211,46 +208,51 @@ impl DisputeMessage { impl UncheckedDisputeMessage { /// Try to recover the two signed dispute votes from an `UncheckedDisputeMessage`. - pub fn try_into_signed_votes(self, session_info: &SessionInfo) - -> Result<(CandidateReceipt, (SignedDisputeStatement, ValidatorIndex), (SignedDisputeStatement, ValidatorIndex)), ()> - { - let Self { - candidate_receipt, - session_index, - valid_vote, - invalid_vote, - } = self; + pub fn try_into_signed_votes( + self, + session_info: &SessionInfo, + ) -> Result< + ( + CandidateReceipt, + (SignedDisputeStatement, ValidatorIndex), + (SignedDisputeStatement, ValidatorIndex), + ), + (), + > { + let Self { candidate_receipt, session_index, valid_vote, invalid_vote } = self; let candidate_hash = candidate_receipt.hash(); let vote_valid = { - let ValidDisputeVote { - validator_index, - signature, - kind, - } = valid_vote; - let validator_public = session_info.validators.get(validator_index.0 as usize).ok_or(())?.clone(); + let ValidDisputeVote { validator_index, signature, kind } = valid_vote; + let validator_public = + session_info.validators.get(validator_index.0 as usize).ok_or(())?.clone(); ( SignedDisputeStatement::new_checked( - DisputeStatement::Valid(kind), candidate_hash, session_index, validator_public, signature + DisputeStatement::Valid(kind), + candidate_hash, + session_index, + validator_public, + signature, )?, - validator_index + validator_index, ) }; let vote_invalid = { - let InvalidDisputeVote { - validator_index, - signature, - kind, - } = invalid_vote; - let validator_public = session_info.validators.get(validator_index.0 as usize).ok_or(())?.clone(); + let InvalidDisputeVote { validator_index, signature, kind } = invalid_vote; + let validator_public = + session_info.validators.get(validator_index.0 as usize).ok_or(())?.clone(); ( SignedDisputeStatement::new_checked( - DisputeStatement::Invalid(kind), candidate_hash, session_index, validator_public, signature + DisputeStatement::Invalid(kind), + candidate_hash, + session_index, + validator_public, + signature, )?, - validator_index + validator_index, ) }; diff --git a/polkadot/node/primitives/src/disputes/mod.rs b/polkadot/node/primitives/src/disputes/mod.rs index b302612f00c..a787fdd4dd0 100644 --- a/polkadot/node/primitives/src/disputes/mod.rs +++ b/polkadot/node/primitives/src/disputes/mod.rs @@ -19,18 +19,17 @@ use std::convert::TryInto; use parity_scale_codec::{Decode, Encode}; use sp_application_crypto::AppKey; -use sp_keystore::{CryptoStore, SyncCryptoStorePtr, Error as KeystoreError}; +use sp_keystore::{CryptoStore, Error as KeystoreError, SyncCryptoStorePtr}; +use super::{Statement, UncheckedSignedFullStatement}; use polkadot_primitives::v1::{ - CandidateHash, CandidateReceipt, DisputeStatement, InvalidDisputeStatementKind, - SessionIndex, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, - ValidatorSignature, SigningContext, + CandidateHash, CandidateReceipt, DisputeStatement, InvalidDisputeStatementKind, SessionIndex, + SigningContext, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature, }; -use super::{UncheckedSignedFullStatement, Statement}; /// `DisputeMessage` and related types. mod message; -pub use message::{DisputeMessage, UncheckedDisputeMessage, Error as DisputeMessageCheckError}; +pub use message::{DisputeMessage, Error as DisputeMessageCheckError, UncheckedDisputeMessage}; /// A checked dispute statement from an associated validator. #[derive(Debug, Clone)] @@ -56,9 +55,8 @@ pub struct CandidateVotes { impl CandidateVotes { /// Get the set of all validators who have votes in the set, ascending. pub fn voted_indices(&self) -> Vec { - let mut v: Vec<_> = self.valid.iter().map(|x| x.1).chain( - self.invalid.iter().map(|x| x.1) - ).collect(); + let mut v: Vec<_> = + self.valid.iter().map(|x| x.1).chain(self.invalid.iter().map(|x| x.1)).collect(); v.sort(); v.dedup(); @@ -76,18 +74,15 @@ impl SignedDisputeStatement { validator_public: ValidatorId, validator_signature: ValidatorSignature, ) -> Result { - dispute_statement.check_signature( - &validator_public, - candidate_hash, - session_index, - &validator_signature, - ).map(|_| SignedDisputeStatement { - dispute_statement, - candidate_hash, - validator_public, - validator_signature, - session_index, - }) + dispute_statement + .check_signature(&validator_public, candidate_hash, session_index, &validator_signature) + .map(|_| SignedDisputeStatement { + dispute_statement, + candidate_hash, + validator_public, + validator_signature, + session_index, + }) } /// Sign this statement with the given keystore and key. Pass `valid = true` to @@ -111,10 +106,12 @@ impl SignedDisputeStatement { ValidatorId::ID, &validator_public.clone().into(), &data, - ).await?; + ) + .await?; let signature = match signature { - Some(sig) => sig.try_into().map_err(|_| KeystoreError::KeyNotSupported(ValidatorId::ID))?, + Some(sig) => + sig.try_into().map_err(|_| KeystoreError::KeyNotSupported(ValidatorId::ID))?, None => return Ok(None), }; diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs index 88449e133dd..1ec3291f803 100644 --- a/polkadot/node/primitives/src/lib.rs +++ b/polkadot/node/primitives/src/lib.rs @@ -22,23 +22,22 @@ #![deny(missing_docs)] - use std::pin::Pin; -use serde::{Serialize, Deserialize}; use futures::Future; use parity_scale_codec::{Decode, Encode}; +use serde::{Deserialize, Serialize}; -pub use sp_core::traits::SpawnNamed; pub use sp_consensus_babe::{ - Epoch as BabeEpoch, BabeEpochConfiguration, AllowedSlots as BabeAllowedSlots, + AllowedSlots as BabeAllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch, }; +pub use sp_core::traits::SpawnNamed; use polkadot_primitives::v1::{ BlakeTwo256, CandidateCommitments, CandidateHash, CollatorPair, CommittedCandidateReceipt, CompactStatement, EncodeAs, Hash, HashT, HeadData, Id as ParaId, OutboundHrmpMessage, - PersistedValidationData, Signed, UncheckedSigned, UpwardMessage, ValidationCode, - ValidatorIndex, SessionIndex, MAX_CODE_SIZE, MAX_POV_SIZE, + PersistedValidationData, SessionIndex, Signed, UncheckedSigned, UpwardMessage, ValidationCode, + ValidatorIndex, MAX_CODE_SIZE, MAX_POV_SIZE, }; pub use polkadot_parachain::primitives::BlockData; @@ -48,8 +47,8 @@ pub mod approval; /// Disputes related types. pub mod disputes; pub use disputes::{ - SignedDisputeStatement, UncheckedDisputeMessage, DisputeMessage, CandidateVotes, InvalidDisputeVote, ValidDisputeVote, - DisputeMessageCheckError, + CandidateVotes, DisputeMessage, DisputeMessageCheckError, InvalidDisputeVote, + SignedDisputeStatement, UncheckedDisputeMessage, ValidDisputeVote, }; /// The bomb limit for decompressing code blobs. @@ -230,7 +229,9 @@ pub struct CollationResult { impl CollationResult { /// Convert into the inner values. - pub fn into_inner(self) -> (Collation, Option>) { + pub fn into_inner( + self, + ) -> (Collation, Option>) { (self.collation, self.result_sender) } } @@ -242,7 +243,10 @@ impl CollationResult { /// /// Returns an optional [`CollationResult`]. pub type CollatorFn = Box< - dyn Fn(Hash, &PersistedValidationData) -> Pin> + Send>> + dyn Fn( + Hash, + &PersistedValidationData, + ) -> Pin> + Send>> + Send + Sync, >; @@ -287,8 +291,7 @@ pub struct ErasureChunk { #[cfg(not(target_os = "unknown"))] pub fn maybe_compress_pov(pov: PoV) -> PoV { let PoV { block_data: BlockData(raw) } = pov; - let raw = sp_maybe_compressed_blob::compress(&raw, POV_BOMB_LIMIT) - .unwrap_or(raw); + let raw = sp_maybe_compressed_blob::compress(&raw, POV_BOMB_LIMIT).unwrap_or(raw); let pov = PoV { block_data: BlockData(raw) }; pov diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index 40baba0fc8e..919a822715e 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -16,8 +16,6 @@ //! Polkadot chain configurations. -use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; -use sp_consensus_babe::AuthorityId as BabeId; use beefy_primitives::crypto::AuthorityId as BeefyId; use grandpa::AuthorityId as GrandpaId; #[cfg(feature = "kusama-native")] @@ -29,6 +27,8 @@ use pallet_staking::Forcing; use polkadot::constants::currency::UNITS as DOT; use polkadot_primitives::v1::{AccountId, AccountPublic, AssignmentId, ValidatorId}; use polkadot_runtime as polkadot; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_consensus_babe::AuthorityId as BabeId; #[cfg(feature = "rococo-native")] use rococo_runtime as rococo; @@ -110,10 +110,7 @@ pub struct RococoGenesisExt { #[cfg(feature = "rococo-native")] impl sp_runtime::BuildStorage for RococoGenesisExt { - fn assimilate_storage( - &self, - storage: &mut sp_core::storage::Storage, - ) -> Result<(), String> { + fn assimilate_storage(&self, storage: &mut sp_core::storage::Storage) -> Result<(), String> { sp_state_machine::BasicExternalities::execute_with_storage(storage, || { if let Some(length) = self.session_length_in_blocks.as_ref() { rococo::constants::time::EpochDurationInBlocks::set(length); @@ -146,9 +143,10 @@ pub fn wococo_config() -> Result { /// The default parachains host configuration. #[cfg(any(feature = "rococo-native", feature = "kusama-native", feature = "westend-native"))] -fn default_parachains_host_configuration() -> - polkadot_runtime_parachains::configuration::HostConfiguration -{ +fn default_parachains_host_configuration( +) -> polkadot_runtime_parachains::configuration::HostConfiguration< + polkadot_primitives::v1::BlockNumber, +> { use polkadot_primitives::v1::{MAX_CODE_SIZE, MAX_POV_SIZE}; polkadot_runtime_parachains::configuration::HostConfiguration { @@ -325,14 +323,7 @@ fn polkadot_staging_testnet_config_genesis(wasm_binary: &[u8]) -> polkadot::Gene minimum_validator_count: 4, stakers: initial_authorities .iter() - .map(|x| { - ( - x.0.clone(), - x.1.clone(), - STASH, - polkadot::StakerStatus::Validator, - ) - }) + .map(|x| (x.0.clone(), x.1.clone(), STASH, polkadot::StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), force_era: Forcing::ForceNone, @@ -341,10 +332,7 @@ fn polkadot_staging_testnet_config_genesis(wasm_binary: &[u8]) -> polkadot::Gene }, phragmen_election: Default::default(), democracy: Default::default(), - council: polkadot::CouncilConfig { - members: vec![], - phantom: Default::default(), - }, + council: polkadot::CouncilConfig { members: vec![], phantom: Default::default() }, technical_committee: polkadot::TechnicalCommitteeConfig { members: vec![], phantom: Default::default(), @@ -357,10 +345,7 @@ fn polkadot_staging_testnet_config_genesis(wasm_binary: &[u8]) -> polkadot::Gene grandpa: Default::default(), im_online: Default::default(), authority_discovery: polkadot::AuthorityDiscoveryConfig { keys: vec![] }, - claims: polkadot::ClaimsConfig { - claims: vec![], - vesting: vec![], - }, + claims: polkadot::ClaimsConfig { claims: vec![], vesting: vec![] }, vesting: polkadot::VestingConfig { vesting: vec![] }, treasury: Default::default(), } @@ -386,78 +371,104 @@ fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> westend::Genesi ValidatorId, AssignmentId, AuthorityDiscoveryId, - )> = vec![( - //5ERCqy118nnXDai8g4t3MjdX7ZC5PrQzQpe9vwex5cELWqbt - hex!["681af4f93073484e1acd6b27395d0d258f1a6b158c808846c8fd05ee2435056e"].into(), - //5GTS114cfQNBgpQULhMaNCPXGds6NokegCnikxDe1vqANhtn - hex!["c2463372598ebabd21ee5bc33e1d7e77f391d2df29ce2fbe6bed0d13be629a45"].into(), - //5FhGbceKeH7fuGogcBwd28ZCkAwDGYBADCTeHiYrvx2ztyRd - hex!["a097bfc6a33499ed843b711f52f523f8a7174f798a9f98620e52f4170dbe2948"].unchecked_into(), - //5Es7nDkJt2by5qVCCD7PZJdp76KJw1LdRCiNst5S5f4eecnz - hex!["7bde49dda82c2c9f082b807ef3ceebff96437d67b3e630c584db7a220ecafacf"].unchecked_into(), - //5D4e8zRjaYzFamqChGPPtu26PcKbKgUrhb7WqcNbKa2RDFUR - hex!["2c2fb730a7d9138e6d62fcf516f9ecc2d712af3f2f03ca330c9564b8c0c1bb33"].unchecked_into(), - //5DD3JY5ENkjcgVFbVSgUbZv7WmrnyJ8bxxu56ee6hZFiRdnh - hex!["3297a8622988cc23dd9c131e3fb8746d49e007f6e58a81d43420cd539e250e4c"].unchecked_into(), - //5Gpodowhud8FG9xENXR5YwTFbUAWyoEtw7sYFytFsG4z7SU6 - hex!["d2932edf775088bd088dc5a112ad867c24cc95858f77f8a1ab014de8d4f96a3f"].unchecked_into(), - //5GUMj8tnjL3PJZgXoiWtgLCaMVNHBNeSeTqDsvcxmaVAjKn9 - hex!["c2fb0f74591a00555a292bc4882d3158bafc4c632124cb60681f164ef81bcf72"].unchecked_into(), - ), - ( - //5HgDCznTkHKUjzPkQoTZGWbvbyqB7sqHDBPDKdF1FyVYM7Er - hex!["f8418f189f84814fd40cc1b2e90873e72ea789487f3b98ed42811ba76d10fc37"].into(), - //5GQTryeFwuvgmZ2tH5ZeAKZHRM9ch5WGVGo6ND9P8f9uMsNY - hex!["c002bb4af4a1bd2f33d104aef8a41878fe1ac94ba007029c4dfdefa8b698d043"].into(), - //5C7YkWSVH1zrpsE5KwW1ua1qatyphzYxiZrL24mjkxz7mUbn - hex!["022b14fbcf65a93b81f453105b9892c3fc4aa74c22c53b4abab019e1d58fbd41"].unchecked_into(), - //5GwFC6Tmg4fhj4PxSqHycgJxi3PDfnC9RGDsNHoRwAvXvpnZ - hex!["d77cafd3b32c8b52b0e2780a586a6e527c94f1bdec117c4e4acb0a491461ffa3"].unchecked_into(), - //5DSVrGURuDuh8Luzo8FYq7o2NWiUSLSN6QAVNrj9BtswWH6R - hex!["3cdb36a5a14715999faffd06c5b9e5dcdc24d4b46bc3e4df1aaad266112a7b49"].unchecked_into(), - //5DLEG2AupawCXGwhJtrzBRc3zAhuP8V662dDrUTzAsCiB9Ec - hex!["38134245c9919ecb20bf2eedbe943b69ba92ceb9eb5477b92b0afd3cb6ce2858"].unchecked_into(), - //5D83o9fDgnHxaKPkSx59hk8zYzqcgzN2mrf7cp8fiVEi7V4E - hex!["2ec917690dc1d676002e3504c530b2595490aa5a4603d9cc579b9485b8d0d854"].unchecked_into(), - //5DwBJquZgncRWXFxj2ydbF8LBUPPUbiq86sXWXgm8Z38m8L2 - hex!["52bae9b8dedb8058dda93ec6f57d7e5a517c4c9f002a4636fada70fed0acf376"].unchecked_into(), - ), - ( - //5DMHpkRpQV7NWJFfn2zQxCLiAKv7R12PWFRPHKKk5X3JkYfP - hex!["38e280b35d08db46019a210a944e4b7177665232ab679df12d6a8bbb317a2276"].into(), - //5FbJpSHmFDe5FN3DVGe1R345ZePL9nhcC9V2Cczxo7q8q6rN - hex!["9c0bc0e2469924d718ae683737f818a47c46b0612376ecca06a2ac059fe1f870"].into(), - //5E5Pm3Udzxy26KGkLE5pc8JPfQrvkYHiaXWtuEfmQsBSgep9 - hex!["58fecadc2df8182a27e999e7e1fd7c99f8ec18f2a81f9a0db38b3653613f3f4d"].unchecked_into(), - //5FxcystSLHtaWoy2HEgRNerj9PrUs452B6AvHVnQZm5ZQmqE - hex!["ac4d0c5e8f8486de05135c10a707f58aa29126d5eb28fdaaba00f9a505f5249d"].unchecked_into(), - //5E7KqVXaVGuAqiqMigpuH8oXHLVh4tmijmpJABLYANpjMkem - hex!["5a781385a0235fe8594dd101ec55ef9ba01883f8563a0cdd37b89e0303f6a578"].unchecked_into(), - //5H9AybjkpyZ79yN5nHuBqs6RKuZPgM7aAVVvTQsDFovgXb2A - hex!["e09570f62a062450d4406b4eb43e7f775ff954e37606646cd590d1818189501f"].unchecked_into(), - //5Ccgs7VwJKBawMbwMENDmj2eFAxhFdGksVHdk8aTAf4w7xox - hex!["1864832dae34df30846d5cc65973f58a2d01b337d094b1284ec3466ecc90251d"].unchecked_into(), - //5EsSaZZ7niJs7hmAtp4QeK19AcAuTp7WXB7N7gRipVooerq4 - hex!["7c1d92535e6d94e21cffea6633a855a7e3c9684cd2f209e5ddbdeaf5111e395b"].unchecked_into(), - ), - ( - //5Ea11qhmGRntQ7pyEkEydbwxvfrYwGMKW6rPERU4UiSBB6rd - hex!["6ed057d2c833c45629de2f14b9f6ce6df1edbf9421b7a638e1fb4828c2bd2651"].into(), - //5CZomCZwPB78BZMZsCiy7WSpkpHhdrN8QTSyjcK3FFEZHBor - hex!["1631ff446b3534d031adfc37b7f7aed26d2a6b3938d10496aab3345c54707429"].into(), - //5CSM6vppouFHzAVPkVFWN76DPRUG7B9qwJe892ccfSfJ8M5f - hex!["108188c43a7521e1abe737b343341c2179a3a89626c7b017c09a5b10df6f1c42"].unchecked_into(), - //5GwkG4std9KcjYi3ThSC7QWfhqokmYVvWEqTU9h7iswjhLnr - hex!["d7de8a43f7ee49fa3b3aaf32fb12617ec9ff7b246a46ab14e9c9d259261117fa"].unchecked_into(), - //5CoUk3wrCGJAWbiJEcsVjYhnd2JAHvR59jBRbSw77YrBtRL1 - hex!["209f680bc501f9b59358efe3636c51fd61238a8659bac146db909aea2595284b"].unchecked_into(), - //5EcSu96wprFM7G2HfJTjYu8kMParnYGznSUNTsoEKXywEsgG - hex!["70adf80395b3f59e4cab5d9da66d5a286a0b6e138652a06f72542e46912df922"].unchecked_into(), - //5Ge3sjpD43Cuy7rNoJQmE9WctgCn6Faw89Pe7xPs3i55eHwJ - hex!["ca5f6b970b373b303f64801a0c2cadc4fc05272c6047a2560a27d0c65589ca1d"].unchecked_into(), - //5EFcjHLvB2z5vd5g63n4gABmhzP5iPsKvTwd8sjfvTehNNrk - hex!["60cae7fa5a079d9fc8061d715fbcc35ef57c3b00005694c2badce22dcc5a9f1b"].unchecked_into(), - )]; + )> = vec![ + ( + //5ERCqy118nnXDai8g4t3MjdX7ZC5PrQzQpe9vwex5cELWqbt + hex!["681af4f93073484e1acd6b27395d0d258f1a6b158c808846c8fd05ee2435056e"].into(), + //5GTS114cfQNBgpQULhMaNCPXGds6NokegCnikxDe1vqANhtn + hex!["c2463372598ebabd21ee5bc33e1d7e77f391d2df29ce2fbe6bed0d13be629a45"].into(), + //5FhGbceKeH7fuGogcBwd28ZCkAwDGYBADCTeHiYrvx2ztyRd + hex!["a097bfc6a33499ed843b711f52f523f8a7174f798a9f98620e52f4170dbe2948"] + .unchecked_into(), + //5Es7nDkJt2by5qVCCD7PZJdp76KJw1LdRCiNst5S5f4eecnz + hex!["7bde49dda82c2c9f082b807ef3ceebff96437d67b3e630c584db7a220ecafacf"] + .unchecked_into(), + //5D4e8zRjaYzFamqChGPPtu26PcKbKgUrhb7WqcNbKa2RDFUR + hex!["2c2fb730a7d9138e6d62fcf516f9ecc2d712af3f2f03ca330c9564b8c0c1bb33"] + .unchecked_into(), + //5DD3JY5ENkjcgVFbVSgUbZv7WmrnyJ8bxxu56ee6hZFiRdnh + hex!["3297a8622988cc23dd9c131e3fb8746d49e007f6e58a81d43420cd539e250e4c"] + .unchecked_into(), + //5Gpodowhud8FG9xENXR5YwTFbUAWyoEtw7sYFytFsG4z7SU6 + hex!["d2932edf775088bd088dc5a112ad867c24cc95858f77f8a1ab014de8d4f96a3f"] + .unchecked_into(), + //5GUMj8tnjL3PJZgXoiWtgLCaMVNHBNeSeTqDsvcxmaVAjKn9 + hex!["c2fb0f74591a00555a292bc4882d3158bafc4c632124cb60681f164ef81bcf72"] + .unchecked_into(), + ), + ( + //5HgDCznTkHKUjzPkQoTZGWbvbyqB7sqHDBPDKdF1FyVYM7Er + hex!["f8418f189f84814fd40cc1b2e90873e72ea789487f3b98ed42811ba76d10fc37"].into(), + //5GQTryeFwuvgmZ2tH5ZeAKZHRM9ch5WGVGo6ND9P8f9uMsNY + hex!["c002bb4af4a1bd2f33d104aef8a41878fe1ac94ba007029c4dfdefa8b698d043"].into(), + //5C7YkWSVH1zrpsE5KwW1ua1qatyphzYxiZrL24mjkxz7mUbn + hex!["022b14fbcf65a93b81f453105b9892c3fc4aa74c22c53b4abab019e1d58fbd41"] + .unchecked_into(), + //5GwFC6Tmg4fhj4PxSqHycgJxi3PDfnC9RGDsNHoRwAvXvpnZ + hex!["d77cafd3b32c8b52b0e2780a586a6e527c94f1bdec117c4e4acb0a491461ffa3"] + .unchecked_into(), + //5DSVrGURuDuh8Luzo8FYq7o2NWiUSLSN6QAVNrj9BtswWH6R + hex!["3cdb36a5a14715999faffd06c5b9e5dcdc24d4b46bc3e4df1aaad266112a7b49"] + .unchecked_into(), + //5DLEG2AupawCXGwhJtrzBRc3zAhuP8V662dDrUTzAsCiB9Ec + hex!["38134245c9919ecb20bf2eedbe943b69ba92ceb9eb5477b92b0afd3cb6ce2858"] + .unchecked_into(), + //5D83o9fDgnHxaKPkSx59hk8zYzqcgzN2mrf7cp8fiVEi7V4E + hex!["2ec917690dc1d676002e3504c530b2595490aa5a4603d9cc579b9485b8d0d854"] + .unchecked_into(), + //5DwBJquZgncRWXFxj2ydbF8LBUPPUbiq86sXWXgm8Z38m8L2 + hex!["52bae9b8dedb8058dda93ec6f57d7e5a517c4c9f002a4636fada70fed0acf376"] + .unchecked_into(), + ), + ( + //5DMHpkRpQV7NWJFfn2zQxCLiAKv7R12PWFRPHKKk5X3JkYfP + hex!["38e280b35d08db46019a210a944e4b7177665232ab679df12d6a8bbb317a2276"].into(), + //5FbJpSHmFDe5FN3DVGe1R345ZePL9nhcC9V2Cczxo7q8q6rN + hex!["9c0bc0e2469924d718ae683737f818a47c46b0612376ecca06a2ac059fe1f870"].into(), + //5E5Pm3Udzxy26KGkLE5pc8JPfQrvkYHiaXWtuEfmQsBSgep9 + hex!["58fecadc2df8182a27e999e7e1fd7c99f8ec18f2a81f9a0db38b3653613f3f4d"] + .unchecked_into(), + //5FxcystSLHtaWoy2HEgRNerj9PrUs452B6AvHVnQZm5ZQmqE + hex!["ac4d0c5e8f8486de05135c10a707f58aa29126d5eb28fdaaba00f9a505f5249d"] + .unchecked_into(), + //5E7KqVXaVGuAqiqMigpuH8oXHLVh4tmijmpJABLYANpjMkem + hex!["5a781385a0235fe8594dd101ec55ef9ba01883f8563a0cdd37b89e0303f6a578"] + .unchecked_into(), + //5H9AybjkpyZ79yN5nHuBqs6RKuZPgM7aAVVvTQsDFovgXb2A + hex!["e09570f62a062450d4406b4eb43e7f775ff954e37606646cd590d1818189501f"] + .unchecked_into(), + //5Ccgs7VwJKBawMbwMENDmj2eFAxhFdGksVHdk8aTAf4w7xox + hex!["1864832dae34df30846d5cc65973f58a2d01b337d094b1284ec3466ecc90251d"] + .unchecked_into(), + //5EsSaZZ7niJs7hmAtp4QeK19AcAuTp7WXB7N7gRipVooerq4 + hex!["7c1d92535e6d94e21cffea6633a855a7e3c9684cd2f209e5ddbdeaf5111e395b"] + .unchecked_into(), + ), + ( + //5Ea11qhmGRntQ7pyEkEydbwxvfrYwGMKW6rPERU4UiSBB6rd + hex!["6ed057d2c833c45629de2f14b9f6ce6df1edbf9421b7a638e1fb4828c2bd2651"].into(), + //5CZomCZwPB78BZMZsCiy7WSpkpHhdrN8QTSyjcK3FFEZHBor + hex!["1631ff446b3534d031adfc37b7f7aed26d2a6b3938d10496aab3345c54707429"].into(), + //5CSM6vppouFHzAVPkVFWN76DPRUG7B9qwJe892ccfSfJ8M5f + hex!["108188c43a7521e1abe737b343341c2179a3a89626c7b017c09a5b10df6f1c42"] + .unchecked_into(), + //5GwkG4std9KcjYi3ThSC7QWfhqokmYVvWEqTU9h7iswjhLnr + hex!["d7de8a43f7ee49fa3b3aaf32fb12617ec9ff7b246a46ab14e9c9d259261117fa"] + .unchecked_into(), + //5CoUk3wrCGJAWbiJEcsVjYhnd2JAHvR59jBRbSw77YrBtRL1 + hex!["209f680bc501f9b59358efe3636c51fd61238a8659bac146db909aea2595284b"] + .unchecked_into(), + //5EcSu96wprFM7G2HfJTjYu8kMParnYGznSUNTsoEKXywEsgG + hex!["70adf80395b3f59e4cab5d9da66d5a286a0b6e138652a06f72542e46912df922"] + .unchecked_into(), + //5Ge3sjpD43Cuy7rNoJQmE9WctgCn6Faw89Pe7xPs3i55eHwJ + hex!["ca5f6b970b373b303f64801a0c2cadc4fc05272c6047a2560a27d0c65589ca1d"] + .unchecked_into(), + //5EFcjHLvB2z5vd5g63n4gABmhzP5iPsKvTwd8sjfvTehNNrk + hex!["60cae7fa5a079d9fc8061d715fbcc35ef57c3b00005694c2badce22dcc5a9f1b"] + .unchecked_into(), + ), + ]; const ENDOWMENT: u128 = 1_000_000 * WND; const STASH: u128 = 100 * WND; @@ -499,14 +510,7 @@ fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> westend::Genesi minimum_validator_count: 4, stakers: initial_authorities .iter() - .map(|x| { - ( - x.0.clone(), - x.1.clone(), - STASH, - westend::StakerStatus::Validator, - ) - }) + .map(|x| (x.0.clone(), x.1.clone(), STASH, westend::StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), force_era: Forcing::ForceNone, @@ -521,9 +525,7 @@ fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> westend::Genesi im_online: Default::default(), authority_discovery: westend::AuthorityDiscoveryConfig { keys: vec![] }, vesting: westend::VestingConfig { vesting: vec![] }, - sudo: westend::SudoConfig { - key: endowed_accounts[0].clone(), - }, + sudo: westend::SudoConfig { key: endowed_accounts[0].clone() }, configuration: westend::ConfigurationConfig { config: default_parachains_host_configuration(), }, @@ -695,14 +697,7 @@ fn kusama_staging_testnet_config_genesis(wasm_binary: &[u8]) -> kusama::GenesisC minimum_validator_count: 4, stakers: initial_authorities .iter() - .map(|x| { - ( - x.0.clone(), - x.1.clone(), - STASH, - kusama::StakerStatus::Validator, - ) - }) + .map(|x| (x.0.clone(), x.1.clone(), STASH, kusama::StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), force_era: Forcing::ForceNone, @@ -711,10 +706,7 @@ fn kusama_staging_testnet_config_genesis(wasm_binary: &[u8]) -> kusama::GenesisC }, phragmen_election: Default::default(), democracy: Default::default(), - council: kusama::CouncilConfig { - members: vec![], - phantom: Default::default(), - }, + council: kusama::CouncilConfig { members: vec![], phantom: Default::default() }, technical_committee: kusama::TechnicalCommitteeConfig { members: vec![], phantom: Default::default(), @@ -727,10 +719,7 @@ fn kusama_staging_testnet_config_genesis(wasm_binary: &[u8]) -> kusama::GenesisC grandpa: Default::default(), im_online: Default::default(), authority_discovery: kusama::AuthorityDiscoveryConfig { keys: vec![] }, - claims: kusama::ClaimsConfig { - claims: vec![], - vesting: vec![], - }, + claims: kusama::ClaimsConfig { claims: vec![], vesting: vec![] }, vesting: kusama::VestingConfig { vesting: vec![] }, treasury: Default::default(), configuration: kusama::ConfigurationConfig { @@ -770,19 +759,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5FeSEpi9UYYaWwXXb3tV88qtZkmSdB3mvgj3pXkxKyYLGhcd hex!["9e6e781a76810fe93187af44c79272c290c2b9e2b8b92ee11466cd79d8023f50"].into(), //5Fh6rDpMDhM363o1Z3Y9twtaCPfizGQWCi55BSykTQjGbP7H - hex!["a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35"].unchecked_into(), + hex!["a076ef1280d768051f21d060623da3ab5b56944d681d303ed2d4bf658c5bed35"] + .unchecked_into(), //5CPd3zoV9Aaah4xWucuDivMHJ2nEEmpdi864nPTiyRZp4t87 - hex!["0e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfa"].unchecked_into(), + hex!["0e6d7d1afbcc6547b92995a394ba0daed07a2420be08220a5a1336c6731f0bfa"] + .unchecked_into(), //5F7BEa1LGFksUihyatf3dCDYneB8pWzVyavnByCsm5nBgezi - hex!["86975a37211f8704e947a365b720f7a3e2757988eaa7d0f197e83dba355ef743"].unchecked_into(), + hex!["86975a37211f8704e947a365b720f7a3e2757988eaa7d0f197e83dba355ef743"] + .unchecked_into(), //5CP6oGfwqbEfML8efqm1tCZsUgRsJztp9L8ZkEUxA16W8PPz - hex!["0e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205"].unchecked_into(), + hex!["0e07a51d3213842f8e9363ce8e444255990a225f87e80a3d651db7841e1a0205"] + .unchecked_into(), //5HQdwiDh8Qtd5dSNWajNYpwDvoyNWWA16Y43aEkCNactFc2b - hex!["ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477b"].unchecked_into(), + hex!["ec60e71fe4a567ef9fef99d4bbf37ffae70564b41aa6f94ef0317c13e0a5477b"] + .unchecked_into(), //5HbSgM72xVuscsopsdeG3sCSCYdAeM1Tay9p79N6ky6vwDGq - hex!["f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c"].unchecked_into(), + hex!["f49eae66a0ac9f610316906ec8f1a0928e20d7059d76a5ca53cbcb5a9b50dd3c"] + .unchecked_into(), //5DPSWdgw38Spu315r6LSvYCggeeieBAJtP5A1qzuzKhqmjVu - hex!["034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276"].unchecked_into(), + hex!["034f68c5661a41930c82f26a662276bf89f33467e1c850f2fb8ef687fe43d62276"] + .unchecked_into(), ), ( //5DvH8oEjQPYhzCoQVo7WDU91qmQfLZvxe9wJcrojmJKebCmG @@ -790,19 +786,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5ENZvCRzyXJJYup8bM6yEzb2kQHEb1NDpY2ZEyVGBkCfRdj3 hex!["6618289af7ae8621981ffab34591e7a6486e12745dfa3fd3b0f7e6a3994c7b5b"].into(), //5DLjSUfqZVNAADbwYLgRvHvdzXypiV1DAEaDMjcESKTcqMoM - hex!["38757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f"].unchecked_into(), + hex!["38757d0de00a0c739e7d7984ef4bc01161bd61e198b7c01b618425c16bb5bd5f"] + .unchecked_into(), //5HnDVBN9mD6mXyx8oryhDbJtezwNSj1VRXgLoYCBA6uEkiao - hex!["fcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d"].unchecked_into(), + hex!["fcd5f87a6fd5707a25122a01b4dac0a8482259df7d42a9a096606df1320df08d"] + .unchecked_into(), //5DhyXZiuB1LvqYKFgT5tRpgGsN3is2cM9QxgW7FikvakbAZP - hex!["48a910c0af90898f11bd57d37ceaea53c78994f8e1833a7ade483c9a84bde055"].unchecked_into(), + hex!["48a910c0af90898f11bd57d37ceaea53c78994f8e1833a7ade483c9a84bde055"] + .unchecked_into(), //5EPEWRecy2ApL5n18n3aHyU1956zXTRqaJpzDa9DoqiggNwF - hex!["669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816"].unchecked_into(), + hex!["669a10892119453e9feb4e3f1ee8e028916cc3240022920ad643846fbdbee816"] + .unchecked_into(), //5ES3fw5X4bndSgLNmtPfSbM2J1kLqApVB2CCLS4CBpM1UxUZ - hex!["68bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80d"].unchecked_into(), + hex!["68bf52c482630a8d1511f2edd14f34127a7d7082219cccf7fd4c6ecdb535f80d"] + .unchecked_into(), //5HeXbwb5PxtcRoopPZTp5CQun38atn2UudQ8p2AxR5BzoaXw - hex!["f6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f349"].unchecked_into(), + hex!["f6f8fe475130d21165446a02fb1dbce3a7bf36412e5d98f4f0473aed9252f349"] + .unchecked_into(), //5F7nTtN8MyJV4UsXpjg7tHSnfANXZ5KRPJmkASc1ZSH2Xoa5 - hex!["03a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e"].unchecked_into(), + hex!["03a90c2bb6d3b7000020f6152fe2e5002fa970fd1f42aafb6c8edda8dacc2ea77e"] + .unchecked_into(), ), ( //5FPMzsezo1PRxYbVpJMWK7HNbR2kUxidsAAxH4BosHa4wd6S @@ -810,19 +813,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5G6NQidFG7YiXsvV7hQTLGArir9tsYqD4JDxByhgxKvSKwRx hex!["b235f57244230589523271c27b8a490922ffd7dccc83b044feaf22273c1dc735"].into(), //5GpZhzAVg7SAtzLvaAC777pjquPEcNy1FbNUAG2nZvhmd6eY - hex!["d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a"].unchecked_into(), + hex!["d2644c1ab2c63a3ad8d40ad70d4b260969e3abfe6d7e6665f50dc9f6365c9d2a"] + .unchecked_into(), //5HAes2RQYPbYKbLBfKb88f4zoXv6pPA6Ke8CjN7dob3GpmSP - hex!["e1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1"].unchecked_into(), + hex!["e1b68fbd84333e31486c08e6153d9a1415b2e7e71b413702b7d64e9b631184a1"] + .unchecked_into(), //5HTXBf36LXmkFWJLokNUK6fPxVpkr2ToUnB1pvaagdGu4c1T - hex!["ee93e26259decb89afcf17ef2aa0fa2db2e1042fb8f56ecfb24d19eae8629878"].unchecked_into(), + hex!["ee93e26259decb89afcf17ef2aa0fa2db2e1042fb8f56ecfb24d19eae8629878"] + .unchecked_into(), //5FtAGDZYJKXkhVhAxCQrXmaP7EE2mGbBMfmKDHjfYDgq2BiU - hex!["a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037"].unchecked_into(), + hex!["a8e61ffacafaf546283dc92d14d7cc70ea0151a5dd81fdf73ff5a2951f2b6037"] + .unchecked_into(), //5CtK7JHv3h6UQZ44y54skxdwSVBRtuxwPE1FYm7UZVhg8rJV - hex!["244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e"].unchecked_into(), + hex!["244f3421b310c68646e99cdbf4963e02067601f57756b072a4b19431448c186e"] + .unchecked_into(), //5D4r6YaB6F7A7nvMRHNFNF6zrR9g39bqDJFenrcaFmTCRwfa - hex!["2c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d"].unchecked_into(), + hex!["2c57f81fd311c1ab53813c6817fe67f8947f8d39258252663b3384ab4195494d"] + .unchecked_into(), //5EPoHj8uV4fFKQHYThc6Z9fDkU7B6ih2ncVzQuDdNFb8UyhF - hex!["039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a53"].unchecked_into(), + hex!["039d065fe4f9234f0a4f13cc3ae585f2691e9c25afa469618abb6645111f607a53"] + .unchecked_into(), ), ( //5DMNx7RoX6d7JQ38NEM7DWRcW2THu92LBYZEWvBRhJeqcWgR @@ -830,19 +840,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5GGdKNDr9P47dpVnmtq3m8Tvowwf1ot1abw6tPsTYYFoKm2v hex!["ba0898c1964196474c0be08d364cdf4e9e1d47088287f5235f70b0590dfe1704"].into(), //5EjkyPCzR2SjhDZq8f7ufsw6TfkvgNRepjCRQFc4TcdXdaB1 - hex!["764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe21"].unchecked_into(), + hex!["764186bc30fd5a02477f19948dc723d6d57ab174debd4f80ed6038ec960bfe21"] + .unchecked_into(), //5DJV3zCBTJBLGNDCcdWrYxWDacSz84goGTa4pFeKVvehEBte - hex!["36be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4"].unchecked_into(), + hex!["36be9069cdb4a8a07ecd51f257875150f0a8a1be44a10d9d98dabf10a030aef4"] + .unchecked_into(), //5FHf8kpK4fPjEJeYcYon2gAPwEBubRvtwpzkUbhMWSweKPUY - hex!["8e95b9b5b4dc69790b67b566567ca8bf8cdef3a3a8bb65393c0d1d1c87cd2d2c"].unchecked_into(), + hex!["8e95b9b5b4dc69790b67b566567ca8bf8cdef3a3a8bb65393c0d1d1c87cd2d2c"] + .unchecked_into(), //5F9FsRjpecP9GonktmtFL3kjqNAMKjHVFjyjRdTPa4hbQRZA - hex!["882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b"].unchecked_into(), + hex!["882d72965e642677583b333b2d173ac94b5fd6c405c76184bb14293be748a13b"] + .unchecked_into(), //5F1FZWZSj3JyTLs8sRBxU6QWyGLSL9BMRtmSKDmVEoiKFxSP - hex!["821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b75"].unchecked_into(), + hex!["821271c99c958b9220f1771d9f5e29af969edfa865631dba31e1ab7bc0582b75"] + .unchecked_into(), //5CtgRR74VypK4h154s369abs78hDUxZSJqcbWsfXvsjcHJNA - hex!["2496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c"].unchecked_into(), + hex!["2496f28d887d84705c6dae98aee8bf90fc5ad10bb5545eca1de6b68425b70f7c"] + .unchecked_into(), //5CPx6dsr11SCJHKFkcAQ9jpparS7FwXQBrrMznRo4Hqv1PXz - hex!["0307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d58"].unchecked_into(), + hex!["0307d29bbf6a5c4061c2157b44fda33b7bb4ec52a5a0305668c74688cedf288d58"] + .unchecked_into(), ), ( //5C8AL1Zb4bVazgT3EgDxFgcow1L4SJjVu44XcLC9CrYqFN4N @@ -850,19 +867,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5FLYy3YKsAnooqE4hCudttAsoGKbVG3hYYBtVzwMjJQrevPa hex!["90cab33f0bb501727faa8319f0845faef7d31008f178b65054b6629fe531b772"].into(), //5Et3tfbVf1ByFThNAuUq5pBssdaPPskip5yob5GNyUFojXC7 - hex!["7c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813"].unchecked_into(), + hex!["7c94715e5dd8ab54221b1b6b2bfa5666f593f28a92a18e28052531de1bd80813"] + .unchecked_into(), //5EX1JBghGbQqWohTPU6msR9qZ2nYPhK9r3RTQ2oD1K8TCxaG - hex!["6c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c81"].unchecked_into(), + hex!["6c878e33b83c20324238d22240f735457b6fba544b383e70bb62a27b57380c81"] + .unchecked_into(), //5GqL8RbVAuNXpDhjQi1KrS1MyNuKhvus2AbmQwRGjpuGZmFu - hex!["d2f9d537ffa59919a4028afdb627c14c14c97a1547e13e8e82203d2049b15b1a"].unchecked_into(), + hex!["d2f9d537ffa59919a4028afdb627c14c14c97a1547e13e8e82203d2049b15b1a"] + .unchecked_into(), //5EUNaBpX9mJgcmLQHyG5Pkms6tbDiKuLbeTEJS924Js9cA1N - hex!["6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01"].unchecked_into(), + hex!["6a8570b9c6408e54bacf123cc2bb1b0f087f9c149147d0005badba63a5a4ac01"] + .unchecked_into(), //5CaZuueRVpMATZG4hkcrgDoF4WGixuz7zu83jeBdY3bgWGaG - hex!["16c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33"].unchecked_into(), + hex!["16c69ea8d595e80b6736f44be1eaeeef2ac9c04a803cc4fd944364cb0d617a33"] + .unchecked_into(), //5DABsdQCDUGuhzVGWe5xXzYQ9rtrVxRygW7RXf9Tsjsw1aGJ - hex!["306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531"].unchecked_into(), + hex!["306ac5c772fe858942f92b6e28bd82fb7dd8cdd25f9a4626c1b0eee075fcb531"] + .unchecked_into(), //5H91T5mHhoCw9JJG4NjghDdQyhC6L7XcSuBWKD3q3TAhEVvQ - hex!["02fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6"].unchecked_into(), + hex!["02fb0330356e63a35dd930bc74525edf28b3bf5eb44aab9e9e4962c8309aaba6a6"] + .unchecked_into(), ), ( //5C8XbDXdMNKJrZSrQURwVCxdNdk8AzG6xgLggbzuA399bBBF @@ -870,19 +894,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5GsyzFP8qtF8tXPSsjhjxAeU1v7D1PZofuQKN9TdCc7Dp1JM hex!["d4ffc4c05b47d1115ad200f7f86e307b20b46c50e1b72a912ec4f6f7db46b616"].into(), //5GHWB8ZDzegLcMW7Gdd1BS6WHVwDdStfkkE4G7KjPjZNJBtD - hex!["bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b"].unchecked_into(), + hex!["bab3cccdcc34401e9b3971b96a662686cf755aa869a5c4b762199ce531b12c5b"] + .unchecked_into(), //5GzDPGbUM9uH52ZEwydasTj8edokGUJ7vEpoFWp9FE1YNuFB - hex!["d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33"].unchecked_into(), + hex!["d9c056c98ca0e6b4eb7f5c58c007c1db7be0fe1f3776108f797dd4990d1ccc33"] + .unchecked_into(), //5GWZbVkJEfWZ7fRca39YAQeqri2Z7pkeHyd7rUctUHyQifLp - hex!["c4a980da30939d5bb9e4a734d12bf81259ae286aa21fa4b65405347fa40eff35"].unchecked_into(), + hex!["c4a980da30939d5bb9e4a734d12bf81259ae286aa21fa4b65405347fa40eff35"] + .unchecked_into(), //5CmLCFeSurRXXtwMmLcVo7sdJ9EqDguvJbuCYDcHkr3cpqyE - hex!["1efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c"].unchecked_into(), + hex!["1efc23c0b51ad609ab670ecf45807e31acbd8e7e5cb7c07cf49ee42992d2867c"] + .unchecked_into(), //5DnsSy8a8pfE2aFjKBDtKw7WM1V4nfE5sLzP15MNTka53GqS - hex!["4c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22"].unchecked_into(), + hex!["4c64d3f06d28adeb36a892fdaccecace150bec891f04694448a60b74fa469c22"] + .unchecked_into(), //5CZdFnyzZvKetZTeUwj5APAYskVJe4QFiTezo5dQNsrnehGd - hex!["160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a"].unchecked_into(), + hex!["160ea09c5717270e958a3da42673fa011613a9539b2e4ebcad8626bc117ca04a"] + .unchecked_into(), //5HgoR9JJkdBusxKrrs3zgd3ToppgNoGj1rDyAJp4e7eZiYyT - hex!["020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474"].unchecked_into(), + hex!["020019a8bb188f8145d02fa855e9c36e9914457d37c500e03634b5223aa5702474"] + .unchecked_into(), ), ( //5HinEonzr8MywkqedcpsmwpxKje2jqr9miEwuzyFXEBCvVXM @@ -890,19 +921,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5EHJbj6Td6ks5HDnyfN4ttTSi57osxcQsQexm7XpazdeqtV7 hex!["62145d721967bd88622d08625f0f5681463c0f1b8bcd97eb3c2c53f7660fd513"].into(), //5EeCsC58XgJ1DFaoYA1WktEpP27jvwGpKdxPMFjicpLeYu96 - hex!["720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372"].unchecked_into(), + hex!["720537e2c1c554654d73b3889c3ef4c3c2f95a65dd3f7c185ebe4afebed78372"] + .unchecked_into(), //5DnEySxbnppWEyN8cCLqvGjAorGdLRg2VmkY96dbJ1LHFK8N - hex!["4bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14"].unchecked_into(), + hex!["4bea0b37e0cce9bddd80835fa2bfd5606f5dcfb8388bbb10b10c483f0856cf14"] + .unchecked_into(), //5E1Y1FJ7dVP7qtE3wm241pTm72rTMcDT5Jd8Czv7Pwp7N3AH - hex!["560d90ca51e9c9481b8a9810060e04d0708d246714960439f804e5c6f40ca651"].unchecked_into(), + hex!["560d90ca51e9c9481b8a9810060e04d0708d246714960439f804e5c6f40ca651"] + .unchecked_into(), //5CAC278tFCHAeHYqE51FTWYxHmeLcENSS1RG77EFRTvPZMJT - hex!["042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f"].unchecked_into(), + hex!["042f07fc5268f13c026bbe199d63e6ac77a0c2a780f71cda05cee5a6f1b3f11f"] + .unchecked_into(), //5HjRTLWcQjZzN3JDvaj1UzjNSayg5ZD9ZGWMstaL7Ab2jjAa - hex!["fab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f"].unchecked_into(), + hex!["fab485e87ed1537d089df521edf983a777c57065a702d7ed2b6a2926f31da74f"] + .unchecked_into(), //5ELv74v7QcsS6FdzvG4vL2NnYDGWmRnJUSMKYwdyJD7Xcdi7 - hex!["64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f"].unchecked_into(), + hex!["64d59feddb3d00316a55906953fb3db8985797472bd2e6c7ea1ab730cc339d7f"] + .unchecked_into(), //5FaUcPt4fPz93vBhcrCJqmDkjYZ7jCbzAF56QJoCmvPaKrmx - hex!["033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685"].unchecked_into(), + hex!["033f1a6d47fe86f88934e4b83b9fae903b92b5dcf4fec97d5e3e8bf4f39df03685"] + .unchecked_into(), ), ( //5Ey3NQ3dfabaDc16NUv7wRLsFCMDFJSqZFzKVycAsWuUC6Di @@ -910,19 +948,26 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: //5HiWsuSBqt8nS9pnggexXuHageUifVPKPHDE2arTKqhTp1dV hex!["fa0388fa88f3f0cb43d583e2571fbc0edad57dff3a6fd89775451dd2c2b8ea00"].into(), //5H168nKX2Yrfo3bxj7rkcg25326Uv3CCCnKUGK6uHdKMdPt8 - hex!["da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa8349"].unchecked_into(), + hex!["da6b2df18f0f9001a6dcf1d301b92534fe9b1f3ccfa10c49449fee93adaa8349"] + .unchecked_into(), //5DrA2fZdzmNqT5j6DXNwVxPBjDV9jhkAqvjt6Us3bQHKy3cF - hex!["4ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dcc"].unchecked_into(), + hex!["4ee66173993dd0db5d628c4c9cb61a27b76611ad3c3925947f0d0011ee2c5dcc"] + .unchecked_into(), //5FNFDUGNLUtqg5LgrwYLNmBiGoP8KRxsvQpBkc7GQP6qaBUG - hex!["92156f54a114ee191415898f2da013d9db6a5362d6b36330d5fc23e27360ab66"].unchecked_into(), + hex!["92156f54a114ee191415898f2da013d9db6a5362d6b36330d5fc23e27360ab66"] + .unchecked_into(), //5Gx6YeNhynqn8qkda9QKpc9S7oDr4sBrfAu516d3sPpEt26F - hex!["d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d"].unchecked_into(), + hex!["d822d4088b20dca29a580a577a97d6f024bb24c9550bebdfd7d2d18e946a1c7d"] + .unchecked_into(), //5DhDcHqwxoes5s89AyudGMjtZXx1nEgrk5P45X88oSTR3iyx - hex!["481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c"].unchecked_into(), + hex!["481538f8c2c011a76d7d57db11c2789a5e83b0f9680dc6d26211d2f9c021ae4c"] + .unchecked_into(), //5DqAvikdpfRdk5rR35ZobZhqaC5bJXZcEuvzGtexAZP1hU3T - hex!["4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26"].unchecked_into(), + hex!["4e262811acdfe94528bfc3c65036080426a0e1301b9ada8d687a70ffcae99c26"] + .unchecked_into(), //5E41Znrr2YtZu8bZp3nvRuLVHg3jFksfQ3tXuviLku4wsao7 - hex!["025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986"].unchecked_into(), + hex!["025e84e95ed043e387ddb8668176b42f8e2773ddd84f7f58a6d9bf436a4b527986"] + .unchecked_into(), ), ]; @@ -935,29 +980,33 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: changes_trie_config: Default::default(), }, balances: rococo_runtime::BalancesConfig { - balances: endowed_accounts.iter() + balances: endowed_accounts + .iter() .map(|k: &AccountId| (k.clone(), ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect(), }, beefy: Default::default(), - indices: rococo_runtime::IndicesConfig { - indices: vec![], - }, + indices: rococo_runtime::IndicesConfig { indices: vec![] }, session: rococo_runtime::SessionConfig { - keys: initial_authorities.iter().map(|x| ( - x.0.clone(), - x.0.clone(), - rococo_session_keys( - x.2.clone(), - x.3.clone(), - x.4.clone(), - x.5.clone(), - x.6.clone(), - x.7.clone(), - x.8.clone(), - ), - )).collect::>(), + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + rococo_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), }, babe: rococo_runtime::BabeConfig { authorities: Default::default(), @@ -967,15 +1016,9 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: im_online: Default::default(), collective: Default::default(), membership: Default::default(), - authority_discovery: rococo_runtime::AuthorityDiscoveryConfig { - keys: vec![], - }, - sudo: rococo_runtime::SudoConfig { - key: endowed_accounts[0].clone(), - }, - paras: rococo_runtime::ParasConfig { - paras: vec![], - }, + authority_discovery: rococo_runtime::AuthorityDiscoveryConfig { keys: vec![] }, + sudo: rococo_runtime::SudoConfig { key: endowed_accounts[0].clone() }, + paras: rococo_runtime::ParasConfig { paras: vec![] }, hrmp: Default::default(), configuration: rococo_runtime::ConfigurationConfig { config: default_parachains_host_configuration(), @@ -1119,9 +1162,7 @@ pub fn get_authority_keys_from_seed( BeefyId, ) { let keys = get_authority_keys_from_seed_no_beefy(seed); - ( - keys.0, keys.1, keys.2, keys.3, keys.4, keys.5, keys.6, keys.7, get_from_seed::(seed) - ) + (keys.0, keys.1, keys.2, keys.3, keys.4, keys.5, keys.6, keys.7, get_from_seed::(seed)) } /// Helper function to generate stash, controller and session key from seed @@ -1194,10 +1235,7 @@ pub fn polkadot_testnet_genesis( }, indices: polkadot::IndicesConfig { indices: vec![] }, balances: polkadot::BalancesConfig { - balances: endowed_accounts - .iter() - .map(|k| (k.clone(), ENDOWMENT)) - .collect(), + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), }, session: polkadot::SessionConfig { keys: initial_authorities @@ -1223,14 +1261,7 @@ pub fn polkadot_testnet_genesis( validator_count: initial_authorities.len() as u32, stakers: initial_authorities .iter() - .map(|x| { - ( - x.0.clone(), - x.1.clone(), - STASH, - polkadot::StakerStatus::Validator, - ) - }) + .map(|x| (x.0.clone(), x.1.clone(), STASH, polkadot::StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), force_era: Forcing::NotForcing, @@ -1239,10 +1270,7 @@ pub fn polkadot_testnet_genesis( }, phragmen_election: Default::default(), democracy: polkadot::DemocracyConfig::default(), - council: polkadot::CouncilConfig { - members: vec![], - phantom: Default::default(), - }, + council: polkadot::CouncilConfig { members: vec![], phantom: Default::default() }, technical_committee: polkadot::TechnicalCommitteeConfig { members: vec![], phantom: Default::default(), @@ -1255,10 +1283,7 @@ pub fn polkadot_testnet_genesis( grandpa: Default::default(), im_online: Default::default(), authority_discovery: polkadot::AuthorityDiscoveryConfig { keys: vec![] }, - claims: polkadot::ClaimsConfig { - claims: vec![], - vesting: vec![], - }, + claims: polkadot::ClaimsConfig { claims: vec![], vesting: vec![] }, vesting: polkadot::VestingConfig { vesting: vec![] }, treasury: Default::default(), } @@ -1293,10 +1318,7 @@ pub fn kusama_testnet_genesis( }, indices: kusama::IndicesConfig { indices: vec![] }, balances: kusama::BalancesConfig { - balances: endowed_accounts - .iter() - .map(|k| (k.clone(), ENDOWMENT)) - .collect(), + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), }, session: kusama::SessionConfig { keys: initial_authorities @@ -1322,14 +1344,7 @@ pub fn kusama_testnet_genesis( validator_count: initial_authorities.len() as u32, stakers: initial_authorities .iter() - .map(|x| { - ( - x.0.clone(), - x.1.clone(), - STASH, - kusama::StakerStatus::Validator, - ) - }) + .map(|x| (x.0.clone(), x.1.clone(), STASH, kusama::StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), force_era: Forcing::NotForcing, @@ -1338,10 +1353,7 @@ pub fn kusama_testnet_genesis( }, phragmen_election: Default::default(), democracy: kusama::DemocracyConfig::default(), - council: kusama::CouncilConfig { - members: vec![], - phantom: Default::default(), - }, + council: kusama::CouncilConfig { members: vec![], phantom: Default::default() }, technical_committee: kusama::TechnicalCommitteeConfig { members: vec![], phantom: Default::default(), @@ -1354,10 +1366,7 @@ pub fn kusama_testnet_genesis( grandpa: Default::default(), im_online: Default::default(), authority_discovery: kusama::AuthorityDiscoveryConfig { keys: vec![] }, - claims: kusama::ClaimsConfig { - claims: vec![], - vesting: vec![], - }, + claims: kusama::ClaimsConfig { claims: vec![], vesting: vec![] }, vesting: kusama::VestingConfig { vesting: vec![] }, treasury: Default::default(), configuration: kusama::ConfigurationConfig { @@ -1397,10 +1406,7 @@ pub fn westend_testnet_genesis( }, indices: westend::IndicesConfig { indices: vec![] }, balances: westend::BalancesConfig { - balances: endowed_accounts - .iter() - .map(|k| (k.clone(), ENDOWMENT)) - .collect(), + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), }, session: westend::SessionConfig { keys: initial_authorities @@ -1426,14 +1432,7 @@ pub fn westend_testnet_genesis( validator_count: initial_authorities.len() as u32, stakers: initial_authorities .iter() - .map(|x| { - ( - x.0.clone(), - x.1.clone(), - STASH, - westend::StakerStatus::Validator, - ) - }) + .map(|x| (x.0.clone(), x.1.clone(), STASH, westend::StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), force_era: Forcing::NotForcing, @@ -1484,26 +1483,29 @@ pub fn rococo_testnet_genesis( changes_trie_config: Default::default(), }, beefy: Default::default(), - indices: rococo_runtime::IndicesConfig { - indices: vec![], - }, + indices: rococo_runtime::IndicesConfig { indices: vec![] }, balances: rococo_runtime::BalancesConfig { balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), }, session: rococo_runtime::SessionConfig { - keys: initial_authorities.iter().map(|x| ( - x.0.clone(), - x.0.clone(), - rococo_session_keys( - x.2.clone(), - x.3.clone(), - x.4.clone(), - x.5.clone(), - x.6.clone(), - x.7.clone(), - x.8.clone(), - ), - )).collect::>(), + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + rococo_session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + x.8.clone(), + ), + ) + }) + .collect::>(), }, babe: rococo_runtime::BabeConfig { authorities: Default::default(), @@ -1513,17 +1515,13 @@ pub fn rococo_testnet_genesis( im_online: Default::default(), collective: Default::default(), membership: Default::default(), - authority_discovery: rococo_runtime::AuthorityDiscoveryConfig { - keys: vec![], - }, + authority_discovery: rococo_runtime::AuthorityDiscoveryConfig { keys: vec![] }, sudo: rococo_runtime::SudoConfig { key: root_key.clone() }, configuration: rococo_runtime::ConfigurationConfig { config: default_parachains_host_configuration(), }, hrmp: Default::default(), - paras: rococo_runtime::ParasConfig { - paras: vec![], - }, + paras: rococo_runtime::ParasConfig { paras: vec![] }, bridge_rococo_grandpa: rococo_runtime::BridgeRococoGrandpaConfig { owner: Some(root_key.clone()), ..Default::default() @@ -1775,10 +1773,7 @@ pub fn westend_local_testnet_config() -> Result { fn rococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::GenesisConfig { rococo_testnet_genesis( wasm_binary, - vec![ - get_authority_keys_from_seed("Alice"), - get_authority_keys_from_seed("Bob"), - ], + vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], get_account_id_from_seed::("Alice"), None, ) @@ -1811,10 +1806,7 @@ pub fn rococo_local_testnet_config() -> Result { fn wococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::GenesisConfig { rococo_testnet_genesis( wasm_binary, - vec![ - get_authority_keys_from_seed("Alice"), - get_authority_keys_from_seed("Bob"), - ], + vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], get_account_id_from_seed::("Alice"), None, ) diff --git a/polkadot/node/service/src/grandpa_support.rs b/polkadot/node/service/src/grandpa_support.rs index 5ffcab34cb0..12ced6c2c05 100644 --- a/polkadot/node/service/src/grandpa_support.rs +++ b/polkadot/node/service/src/grandpa_support.rs @@ -18,8 +18,7 @@ use std::sync::Arc; -use sp_runtime::traits::Header as _; -use sp_runtime::traits::{Block as BlockT, NumberFor}; +use sp_runtime::traits::{Block as BlockT, Header as _, NumberFor}; use crate::HeaderProvider; @@ -50,7 +49,7 @@ where } if *target_header.number() == target_number { - return Ok((target_hash, target_number)); + return Ok((target_hash, target_number)) } target_hash = *target_header.parent_hash(); @@ -86,18 +85,18 @@ where // if we're past the pause period (i.e. `self.0 + self.1`) // then we no longer need to restrict any votes if *best_target.number() > self.0 + self.1 { - return None; + return None } // if we've finalized the pause block, just keep returning it // until best number increases enough to pass the condition above if *base.number() >= self.0 { - return Some((base.hash(), *base.number())); + return Some((base.hash(), *base.number())) } // otherwise find the target header at the pause block // to vote on - return walk_backwards_to_target_block(&*backend, self.0, current_target).ok(); + return walk_backwards_to_target_block(&*backend, self.0, current_target).ok() } None @@ -125,51 +124,15 @@ pub(crate) fn kusama_hard_forks() -> Vec<( use std::str::FromStr; let forks = vec![ - ( - 623, - "01e94e1e7e9cf07b3b0bf4e1717fce7448e5563901c2ef2e3b8e9ecaeba088b1", - 1492283, - ), - ( - 624, - "ddc4323c5e8966844dfaa87e0c2f74ef6b43115f17bf8e4ff38845a62d02b9a9", - 1492436, - ), - ( - 625, - "38ba115b296663e424e32d7b1655cd795719cef4fd7d579271a6d01086cf1628", - 1492586, - ), - ( - 626, - "f3172b6b8497c10fc772f5dada4eeb1f4c4919c97de9de2e1a439444d5a057ff", - 1492955, - ), - ( - 627, - "b26526aea299e9d24af29fdacd5cf4751a663d24894e3d0a37833aa14c58424a", - 1493338, - ), - ( - 628, - "3980d024327d53b8d01ef0d198a052cd058dd579508d8ed6283fe3614e0a3694", - 1493913, - ), - ( - 629, - "31f22997a786c25ee677786373368cae6fd501fd1bc4b212b8e267235c88179d", - 1495083, - ), - ( - 630, - "1c65eb250cf54b466c64f1a4003d1415a7ee275e49615450c0e0525179857eef", - 1497404, - ), - ( - 631, - "9e44116467cc9d7e224e36487bf2cf571698cae16b25f54a7430f1278331fdd8", - 1498598, - ), + (623, "01e94e1e7e9cf07b3b0bf4e1717fce7448e5563901c2ef2e3b8e9ecaeba088b1", 1492283), + (624, "ddc4323c5e8966844dfaa87e0c2f74ef6b43115f17bf8e4ff38845a62d02b9a9", 1492436), + (625, "38ba115b296663e424e32d7b1655cd795719cef4fd7d579271a6d01086cf1628", 1492586), + (626, "f3172b6b8497c10fc772f5dada4eeb1f4c4919c97de9de2e1a439444d5a057ff", 1492955), + (627, "b26526aea299e9d24af29fdacd5cf4751a663d24894e3d0a37833aa14c58424a", 1493338), + (628, "3980d024327d53b8d01ef0d198a052cd058dd579508d8ed6283fe3614e0a3694", 1493913), + (629, "31f22997a786c25ee677786373368cae6fd501fd1bc4b212b8e267235c88179d", 1495083), + (630, "1c65eb250cf54b466c64f1a4003d1415a7ee275e49615450c0e0525179857eef", 1497404), + (631, "9e44116467cc9d7e224e36487bf2cf571698cae16b25f54a7430f1278331fdd8", 1498598), ]; let authorities = vec![ @@ -253,14 +216,14 @@ pub(crate) fn kusama_hard_forks() -> Vec<( #[cfg(test)] mod tests { + use consensus_common::BlockOrigin; use grandpa::VotingRule; use polkadot_test_client::{ - TestClientBuilder, TestClientBuilderExt, DefaultTestClientBuilderExt, InitPolkadotBlockBuilder, - ClientBlockImportExt, + ClientBlockImportExt, DefaultTestClientBuilderExt, InitPolkadotBlockBuilder, + TestClientBuilder, TestClientBuilderExt, }; use sp_blockchain::HeaderBackend; use sp_runtime::{generic::BlockId, traits::Header}; - use consensus_common::BlockOrigin; use std::sync::Arc; #[test] diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs index 41bb5f620f7..e443478c13b 100644 --- a/polkadot/node/service/src/lib.rs +++ b/polkadot/node/service/src/lib.rs @@ -28,10 +28,7 @@ mod overseer; #[cfg(feature = "full-node")] pub use self::overseer::{ - OverseerGen, - OverseerGenArgs, - RealOverseerGen, - create_default_subsystems, + create_default_subsystems, OverseerGen, OverseerGenArgs, RealOverseerGen, }; #[cfg(test)] @@ -39,45 +36,43 @@ mod tests; #[cfg(feature = "full-node")] use { - tracing::info, + grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}, polkadot_network_bridge::RequestMultiplexer, + polkadot_node_core_approval_voting::Config as ApprovalVotingConfig, polkadot_node_core_av_store::Config as AvailabilityConfig, polkadot_node_core_av_store::Error as AvailabilityError, - polkadot_node_core_approval_voting::Config as ApprovalVotingConfig, polkadot_node_core_candidate_validation::Config as CandidateValidationConfig, polkadot_node_core_chain_selection::{ - self as chain_selection_subsystem, - Config as ChainSelectionConfig, + self as chain_selection_subsystem, Config as ChainSelectionConfig, }, polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig, polkadot_overseer::BlockInfo, - sp_trie::PrefixedMemoryDB, sc_client_api::ExecutorProvider, - grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}, + sp_trie::PrefixedMemoryDB, + tracing::info, }; +pub use sp_core::traits::SpawnNamed; #[cfg(feature = "full-node")] pub use { + polkadot_overseer::{Handle, Overseer, OverseerHandle}, + polkadot_primitives::v1::ParachainHost, + sc_client_api::AuxStore, + sp_authority_discovery::AuthorityDiscoveryApi, sp_blockchain::HeaderBackend, sp_consensus_babe::BabeApi, - sp_authority_discovery::AuthorityDiscoveryApi, - sc_client_api::AuxStore, - polkadot_primitives::v1::ParachainHost, - polkadot_overseer::{Overseer, Handle, OverseerHandle}, }; -pub use sp_core::traits::SpawnNamed; #[cfg(feature = "full-node")] use polkadot_subsystem::jaeger; -use std::sync::Arc; -use std::time::Duration; +use std::{sync::Arc, time::Duration}; use prometheus_endpoint::Registry; use service::RpcHandlers; +use telemetry::TelemetryWorker; #[cfg(feature = "full-node")] use telemetry::{Telemetry, TelemetryWorkerHandle}; -use telemetry::TelemetryWorker; #[cfg(feature = "rococo-native")] pub use polkadot_client::RococoExecutor; @@ -88,33 +83,28 @@ pub use polkadot_client::WestendExecutor; #[cfg(feature = "kusama-native")] pub use polkadot_client::KusamaExecutor; +pub use chain_spec::{KusamaChainSpec, PolkadotChainSpec, RococoChainSpec, WestendChainSpec}; +pub use consensus_common::{block_validation::Chain, Proposal, SelectChain}; pub use polkadot_client::{ - PolkadotExecutor, FullBackend, FullClient, AbstractClient, Client, ClientHandle, ExecuteWithClient, - RuntimeApiCollection, + AbstractClient, Client, ClientHandle, ExecuteWithClient, FullBackend, FullClient, + PolkadotExecutor, RuntimeApiCollection, }; -pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec, RococoChainSpec}; -pub use consensus_common::{Proposal, SelectChain, block_validation::Chain}; pub use polkadot_primitives::v1::{Block, BlockId, CollatorPair, Hash, Id as ParaId}; -pub use sc_client_api::{Backend, ExecutionStrategy, CallExecutor}; +pub use sc_client_api::{Backend, CallExecutor, ExecutionStrategy}; pub use sc_consensus::{BlockImport, LongestChain}; pub use sc_executor::NativeExecutionDispatch; pub use service::{ - Role, PruningMode, TransactionPoolOptions, Error as SubstrateServiceError, RuntimeGenesis, - TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor, - Configuration, ChainSpec, TaskManager, + config::{DatabaseConfig, PrometheusConfig}, + ChainSpec, Configuration, Error as SubstrateServiceError, PruningMode, Role, RuntimeGenesis, + TFullBackend, TFullCallExecutor, TFullClient, TLightBackend, TLightCallExecutor, TLightClient, + TaskManager, TransactionPoolOptions, }; -pub use service::config::{DatabaseConfig, PrometheusConfig}; -pub use sp_api::{ApiRef, Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend}; +pub use sp_api::{ApiRef, ConstructRuntimeApi, Core as CoreApi, ProvideRuntimeApi, StateBackend}; pub use sp_runtime::{ generic, traits::{ - DigestFor, - HashFor, - NumberFor, - Block as BlockT, - Header as HeaderT, - self as runtime_traits, - BlakeTwo256, + self as runtime_traits, BlakeTwo256, Block as BlockT, DigestFor, HashFor, + Header as HeaderT, NumberFor, }, }; @@ -306,7 +296,10 @@ fn jaeger_launch_collector_with_agent( type FullSelectChain = relay_chain_selection::SelectRelayChainWithFallback; #[cfg(feature = "full-node")] type FullGrandpaBlockImport = grandpa::GrandpaBlockImport< - FullBackend, Block, FullClient, FullSelectChain + FullBackend, + Block, + FullClient, + FullSelectChain, >; #[cfg(feature = "light-node")] @@ -323,7 +316,9 @@ fn new_partial( telemetry_worker_handle: Option, ) -> Result< service::PartialComponents< - FullClient, FullBackend, FullSelectChain, + FullClient, + FullBackend, + FullSelectChain, sc_consensus::DefaultImportQueue>, sc_transaction_pool::FullPool>, ( @@ -333,7 +328,9 @@ fn new_partial( ) -> polkadot_rpc::RpcExtension, ( babe::BabeBlockImport< - Block, FullClient, FullGrandpaBlockImport + Block, + FullClient, + FullGrandpaBlockImport, >, grandpa::LinkHalf, FullSelectChain>, babe::BabeLink, @@ -342,20 +339,22 @@ fn new_partial( grandpa::SharedVoterState, std::time::Duration, // slot-duration Option, - ) + ), >, - Error + Error, > - where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: +where + RuntimeApi: + ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection>, - Executor: NativeExecutionDispatch + 'static, + Executor: NativeExecutionDispatch + 'static, { set_prometheus_registry(config)?; - - let telemetry = config.telemetry_endpoints.clone() + let telemetry = config + .telemetry_endpoints + .clone() .filter(|x| !x.is_empty()) .map(move |endpoints| -> Result<_, telemetry::Error> { let (worker, mut worker_handle) = if let Some(worker_handle) = telemetry_worker_handle { @@ -377,13 +376,12 @@ fn new_partial( )?; let client = Arc::new(client); - let telemetry = telemetry - .map(|(worker, telemetry)| { - if let Some(worker) = worker { - task_manager.spawn_handle().spawn("telemetry", worker.run()); - } - telemetry - }); + let telemetry = telemetry.map(|(worker, telemetry)| { + if let Some(worker) = worker { + task_manager.spawn_handle().spawn("telemetry", worker.run()); + } + telemetry + }); jaeger_launch_collector_with_agent(task_manager.spawn_handle(), &*config, jaeger_agent)?; @@ -407,23 +405,19 @@ fn new_partial( Vec::new() }; - let (grandpa_block_import, grandpa_link) = - grandpa::block_import_with_authority_set_hard_forks( - client.clone(), - &(client.clone() as Arc<_>), - select_chain.clone(), - grandpa_hard_forks, - telemetry.as_ref().map(|x| x.handle()), - )?; + let (grandpa_block_import, grandpa_link) = grandpa::block_import_with_authority_set_hard_forks( + client.clone(), + &(client.clone() as Arc<_>), + select_chain.clone(), + grandpa_hard_forks, + telemetry.as_ref().map(|x| x.handle()), + )?; let justification_import = grandpa_block_import.clone(); let babe_config = babe::Config::get_or_compute(&*client)?; - let (block_import, babe_link) = babe::block_import( - babe_config.clone(), - grandpa_block_import, - client.clone(), - )?; + let (block_import, babe_link) = + babe::block_import(babe_config.clone(), grandpa_block_import, client.clone())?; let slot_duration = babe_link.config().slot_duration(); let import_queue = babe::import_queue( @@ -473,9 +467,9 @@ fn new_partial( let select_chain = select_chain.clone(); let chain_spec = config.chain_spec.cloned_box(); - move |deny_unsafe, subscription_executor: polkadot_rpc::SubscriptionTaskExecutor| - -> polkadot_rpc::RpcExtension - { + move |deny_unsafe, + subscription_executor: polkadot_rpc::SubscriptionTaskExecutor| + -> polkadot_rpc::RpcExtension { let deps = polkadot_rpc::FullDeps { client: client.clone(), pool: transaction_pool.clone(), @@ -512,7 +506,7 @@ fn new_partial( select_chain, import_queue, transaction_pool, - other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, telemetry) + other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, telemetry), }) } @@ -577,10 +571,11 @@ async fn active_leaves( client: &FullClient, ) -> Result, Error> where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: + RuntimeApi: + ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection>, - Executor: NativeExecutionDispatch + 'static, + Executor: NativeExecutionDispatch + 'static, { let best_block = select_chain.best_chain().await?; @@ -601,11 +596,7 @@ where let parent_hash = client.header(&BlockId::Hash(hash)).ok()??.parent_hash; - Some(BlockInfo { - hash, - parent_hash, - number, - }) + Some(BlockInfo { hash, parent_hash, number }) }) .collect::>(); @@ -636,12 +627,13 @@ pub fn new_full( program_path: Option, overseer_gen: OverseerGenerator, ) -> Result>>, Error> - where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: +where + RuntimeApi: + ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection>, - Executor: NativeExecutionDispatch + 'static, - OverseerGenerator: OverseerGen, + Executor: NativeExecutionDispatch + 'static, + OverseerGenerator: OverseerGen, { let role = config.role.clone(); let force_authoring = config.force_authoring; @@ -669,7 +661,7 @@ pub fn new_full( mut select_chain, import_queue, transaction_pool, - other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry) + other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry), } = new_partial::(&mut config, jaeger_agent, telemetry_worker_handle)?; let prometheus_registry = config.prometheus_registry().cloned(); @@ -688,11 +680,7 @@ pub fn new_full( { use polkadot_network_bridge::{peer_sets_info, IsAuthority}; - let is_authority = if role.is_authority() { - IsAuthority::Yes - } else { - IsAuthority::No - }; + let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No }; config.network.extra_sets.extend(peer_sets_info(is_authority)); } @@ -703,8 +691,8 @@ pub fn new_full( }; let warp_sync = Arc::new(grandpa::warp_proof::NetworkProvider::new( - backend.clone(), - import_setup.1.shared_authority_set().clone(), + backend.clone(), + import_setup.1.shared_authority_set().clone(), )); let (network, system_rpc_tx, network_starter) = @@ -721,7 +709,10 @@ pub fn new_full( if config.offchain_worker.enabled { let _ = service::build_offchain_workers( - &config, task_manager.spawn_handle(), client.clone(), network.clone(), + &config, + task_manager.spawn_handle(), + client.clone(), + network.clone(), ); } @@ -741,7 +732,8 @@ pub fn new_full( }; let candidate_validation_config = CandidateValidationConfig { - artifacts_cache_path: config.database + artifacts_cache_path: config + .database .path() .ok_or(Error::DatabasePathRequired)? .join("pvf-artifacts"), @@ -780,27 +772,25 @@ pub fn new_full( let overseer_client = client.clone(); let spawner = task_manager.spawn_handle(); - let active_leaves = futures::executor::block_on( - active_leaves(&select_chain, &*client) - )?; + let active_leaves = futures::executor::block_on(active_leaves(&select_chain, &*client))?; let authority_discovery_service = if role.is_authority() || is_collator.is_collator() { - use sc_network::Event; use futures::StreamExt; + use sc_network::Event; let authority_discovery_role = if role.is_authority() { - sc_authority_discovery::Role::PublishAndDiscover( - keystore_container.keystore(), - ) + sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore()) } else { // don't publish our addresses when we're only a collator sc_authority_discovery::Role::Discover }; - let dht_event_stream = network.event_stream("authority-discovery") - .filter_map(|e| async move { match e { - Event::Dht(e) => Some(e), - _ => None, - }}); + let dht_event_stream = + network.event_stream("authority-discovery").filter_map(|e| async move { + match e { + Event::Dht(e) => Some(e), + _ => None, + } + }); let (worker, service) = sc_authority_discovery::new_worker_and_service_with_config( sc_authority_discovery::WorkerConfig { publish_non_global_ips: auth_disc_publish_non_global_ips, @@ -824,58 +814,59 @@ pub fn new_full( tracing::info!("Cannot run as validator without local keystore."); } - let maybe_params = local_keystore - .and_then(move |k| authority_discovery_service.map(|a| (a, k))); + let maybe_params = + local_keystore.and_then(move |k| authority_discovery_service.map(|a| (a, k))); let overseer_handle = if let Some((authority_discovery_service, keystore)) = maybe_params { - let (overseer, overseer_handle) = overseer_gen.generate::< - service::SpawnTaskHandle, - FullClient, - >( - OverseerGenArgs { - leaves: active_leaves, - keystore, - runtime_client: overseer_client.clone(), - parachains_db, - network_service: network.clone(), - authority_discovery_service, - request_multiplexer, - registry: prometheus_registry.as_ref(), - spawner, - is_collator, - approval_voting_config, - availability_config, - candidate_validation_config, - chain_selection_config, - dispute_coordinator_config, - } - )?; + let (overseer, overseer_handle) = overseer_gen + .generate::>( + OverseerGenArgs { + leaves: active_leaves, + keystore, + runtime_client: overseer_client.clone(), + parachains_db, + network_service: network.clone(), + authority_discovery_service, + request_multiplexer, + registry: prometheus_registry.as_ref(), + spawner, + is_collator, + approval_voting_config, + availability_config, + candidate_validation_config, + chain_selection_config, + dispute_coordinator_config, + }, + )?; let handle = Handle::Connected(overseer_handle.clone()); let handle_clone = handle.clone(); - task_manager.spawn_essential_handle().spawn_blocking("overseer", Box::pin(async move { - use futures::{pin_mut, select, FutureExt}; + task_manager.spawn_essential_handle().spawn_blocking( + "overseer", + Box::pin(async move { + use futures::{pin_mut, select, FutureExt}; - let forward = polkadot_overseer::forward_events(overseer_client, handle_clone); + let forward = polkadot_overseer::forward_events(overseer_client, handle_clone); - let forward = forward.fuse(); - let overseer_fut = overseer.run().fuse(); + let forward = forward.fuse(); + let overseer_fut = overseer.run().fuse(); - pin_mut!(overseer_fut); - pin_mut!(forward); + pin_mut!(overseer_fut); + pin_mut!(forward); - select! { - _ = forward => (), - _ = overseer_fut => (), - complete => (), - } - })); + select! { + _ = forward => (), + _ = overseer_fut => (), + complete => (), + } + }), + ); // we should remove this check before we deploy parachains on polkadot // TODO: https://github.com/paritytech/polkadot/issues/3326 - let should_connect_overseer = chain_spec.is_kusama() - || chain_spec.is_westend() - || chain_spec.is_rococo() - || chain_spec.is_wococo(); + let should_connect_overseer = chain_spec.is_kusama() || + chain_spec.is_westend() || + chain_spec.is_rococo() || + chain_spec.is_wococo(); if should_connect_overseer { select_chain.connect_to_overseer(overseer_handle.clone()); @@ -900,7 +891,8 @@ pub fn new_full( ); let client_clone = client.clone(); - let overseer_handle = overseer_handle.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone(); + let overseer_handle = + overseer_handle.as_ref().ok_or(Error::AuthoritiesRequireRealOverseer)?.clone(); let slot_duration = babe_link.config().slot_duration(); let babe_config = babe::BabeParams { keystore: keystore_container.sync_keystore(), @@ -951,11 +943,8 @@ pub fn new_full( // 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_opt = if role.is_authority() { - Some(keystore_container.sync_keystore()) - } else { - None - }; + let keystore_opt = + if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None }; // We currently only run the BEEFY gadget on the Rococo and Wococo testnets. if !disable_beefy && (chain_spec.is_rococo() || chain_spec.is_wococo()) { @@ -969,9 +958,7 @@ pub fn new_full( prometheus_registry: prometheus_registry.clone(), }; - let gadget = beefy_gadget::start_beefy_gadget::<_, _, _, _>( - beefy_params - ); + let gadget = beefy_gadget::start_beefy_gadget::<_, _, _, _>(beefy_params); // Wococo's purpose is to be a testbed for BEEFY, so if it fails we'll // bring the node down with it to make sure it is noticed. @@ -1017,10 +1004,8 @@ pub fn new_full( delay, ); - builder - .add(grandpa_support::PauseAfterBlockFor(block, delay)) - .build() - } + builder.add(grandpa_support::PauseAfterBlockFor(block, delay)).build() + }, None => builder.build(), }; @@ -1034,40 +1019,33 @@ pub fn new_full( telemetry: telemetry.as_ref().map(|x| x.handle()), }; - task_manager.spawn_essential_handle().spawn_blocking( - "grandpa-voter", - grandpa::run_grandpa_voter(grandpa_config)? - ); + task_manager + .spawn_essential_handle() + .spawn_blocking("grandpa-voter", grandpa::run_grandpa_voter(grandpa_config)?); } network_starter.start_network(); - Ok(NewFull { - task_manager, - client, - overseer_handle, - network, - rpc_handlers, - backend, - }) + Ok(NewFull { task_manager, client, overseer_handle, network, rpc_handlers, backend }) } /// Builds a new service for a light client. #[cfg(feature = "light-node")] -fn new_light(mut config: Configuration) -> Result<( - TaskManager, - RpcHandlers, -), Error> - where - Runtime: 'static + Send + Sync + ConstructRuntimeApi>, - >>::RuntimeApi: +fn new_light( + mut config: Configuration, +) -> Result<(TaskManager, RpcHandlers), Error> +where + Runtime: 'static + Send + Sync + ConstructRuntimeApi>, + >>::RuntimeApi: RuntimeApiCollection>, - Dispatch: NativeExecutionDispatch + 'static, + Dispatch: NativeExecutionDispatch + 'static, { set_prometheus_registry(&mut config)?; use sc_client_api::backend::RemoteBackend; - let telemetry = config.telemetry_endpoints.clone() + let telemetry = config + .telemetry_endpoints + .clone() .filter(|x| !x.is_empty()) .map(|endpoints| -> Result<_, telemetry::Error> { let worker = TelemetryWorker::new(16)?; @@ -1082,11 +1060,10 @@ fn new_light(mut config: Configuration) -> Result<( telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), )?; - let mut telemetry = telemetry - .map(|(worker, telemetry)| { - task_manager.spawn_handle().spawn("telemetry", worker.run()); - telemetry - }); + let mut telemetry = telemetry.map(|(worker, telemetry)| { + task_manager.spawn_handle().spawn("telemetry", worker.run()); + telemetry + }); config.network.extra_sets.push(grandpa::grandpa_peers_set_config()); @@ -1140,8 +1117,8 @@ fn new_light(mut config: Configuration) -> Result<( )?; let warp_sync = Arc::new(grandpa::warp_proof::NetworkProvider::new( - backend.clone(), - grandpa_link.shared_authority_set().clone(), + backend.clone(), + grandpa_link.shared_authority_set().clone(), )); let (network, system_rpc_tx, network_starter) = @@ -1226,44 +1203,43 @@ pub fn new_chain_ops( sc_consensus::BasicQueue>, TaskManager, ), - Error -> -{ + Error, +> { config.keystore = service::config::KeystoreConfig::InMemory; #[cfg(feature = "rococo-native")] if config.chain_spec.is_rococo() || config.chain_spec.is_wococo() { - let service::PartialComponents { client, backend, import_queue, task_manager, .. } - = new_partial::(config, jaeger_agent, None)?; + let service::PartialComponents { client, backend, import_queue, task_manager, .. } = + new_partial::(config, jaeger_agent, None)?; return Ok((Arc::new(Client::Rococo(client)), backend, import_queue, task_manager)) } #[cfg(feature = "kusama-native")] if config.chain_spec.is_kusama() { - let service::PartialComponents { client, backend, import_queue, task_manager, .. } - = new_partial::(config, jaeger_agent, None)?; + let service::PartialComponents { client, backend, import_queue, task_manager, .. } = + new_partial::(config, jaeger_agent, None)?; return Ok((Arc::new(Client::Kusama(client)), backend, import_queue, task_manager)) } #[cfg(feature = "westend-native")] if config.chain_spec.is_westend() { - let service::PartialComponents { client, backend, import_queue, task_manager, .. } - = new_partial::(config, jaeger_agent, None)?; + let service::PartialComponents { client, backend, import_queue, task_manager, .. } = + new_partial::( + config, + jaeger_agent, + None, + )?; return Ok((Arc::new(Client::Westend(client)), backend, import_queue, task_manager)) } - let service::PartialComponents { client, backend, import_queue, task_manager, .. } - = new_partial::(config, jaeger_agent, None)?; + let service::PartialComponents { client, backend, import_queue, task_manager, .. } = + new_partial::(config, jaeger_agent, None)?; Ok((Arc::new(Client::Polkadot(client)), backend, import_queue, task_manager)) } - /// Build a new light node. #[cfg(feature = "light-node")] -pub fn build_light(config: Configuration) -> Result<( - TaskManager, - RpcHandlers, -), Error> { +pub fn build_light(config: Configuration) -> Result<(TaskManager, RpcHandlers), Error> { #[cfg(feature = "rococo-native")] if config.chain_spec.is_rococo() || config.chain_spec.is_wococo() { return new_light::(config) @@ -1303,7 +1279,8 @@ pub fn build_full( telemetry_worker_handle, None, overseer_gen, - ).map(|full| full.with_client(Client::Rococo)) + ) + .map(|full| full.with_client(Client::Rococo)) } #[cfg(feature = "kusama-native")] @@ -1317,7 +1294,8 @@ pub fn build_full( telemetry_worker_handle, None, overseer_gen, - ).map(|full| full.with_client(Client::Kusama)) + ) + .map(|full| full.with_client(Client::Kusama)) } #[cfg(feature = "westend-native")] @@ -1331,7 +1309,8 @@ pub fn build_full( telemetry_worker_handle, None, overseer_gen, - ).map(|full| full.with_client(Client::Westend)) + ) + .map(|full| full.with_client(Client::Westend)) } new_full::( @@ -1343,5 +1322,6 @@ pub fn build_full( telemetry_worker_handle, None, overseer_gen, - ).map(|full| full.with_client(Client::Polkadot)) + ) + .map(|full| full.with_client(Client::Polkadot)) } diff --git a/polkadot/node/service/src/overseer.rs b/polkadot/node/service/src/overseer.rs index b104481a9e8..971deb45572 100644 --- a/polkadot/node/service/src/overseer.rs +++ b/polkadot/node/service/src/overseer.rs @@ -14,55 +14,48 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use super::{ - Error, - Registry, - IsCollator, - Block, - SpawnNamed, - Hash, - AuthorityDiscoveryApi, -}; -use std::sync::Arc; +use super::{AuthorityDiscoveryApi, Block, Error, Hash, IsCollator, Registry, SpawnNamed}; use polkadot_network_bridge::RequestMultiplexer; -use polkadot_node_core_av_store::Config as AvailabilityConfig; use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig; +use polkadot_node_core_av_store::Config as AvailabilityConfig; use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig; use polkadot_node_core_chain_selection::Config as ChainSelectionConfig; use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig; use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandle}; use polkadot_primitives::v1::ParachainHost; use sc_authority_discovery::Service as AuthorityDiscoveryService; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::HeaderBackend; use sc_client_api::AuxStore; use sc_keystore::LocalKeystore; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::HeaderBackend; use sp_consensus_babe::BabeApi; +use std::sync::Arc; +pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem; +pub use polkadot_availability_bitfield_distribution::BitfieldDistribution as BitfieldDistributionSubsystem; pub use polkadot_availability_distribution::AvailabilityDistributionSubsystem; +pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem; +pub use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide}; +pub use polkadot_dispute_distribution::DisputeDistributionSubsystem; +pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem; +pub use polkadot_network_bridge::NetworkBridge as NetworkBridgeSubsystem; +pub use polkadot_node_collation_generation::CollationGenerationSubsystem; +pub use polkadot_node_core_approval_voting::ApprovalVotingSubsystem; pub use polkadot_node_core_av_store::AvailabilityStoreSubsystem; -pub use polkadot_availability_bitfield_distribution::BitfieldDistribution as BitfieldDistributionSubsystem; -pub use polkadot_node_core_bitfield_signing::BitfieldSigningSubsystem; pub use polkadot_node_core_backing::CandidateBackingSubsystem; +pub use polkadot_node_core_bitfield_signing::BitfieldSigningSubsystem; pub use polkadot_node_core_candidate_validation::CandidateValidationSubsystem; pub use polkadot_node_core_chain_api::ChainApiSubsystem; -pub use polkadot_node_collation_generation::CollationGenerationSubsystem; -pub use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide}; -pub use polkadot_network_bridge::NetworkBridge as NetworkBridgeSubsystem; +pub use polkadot_node_core_chain_selection::ChainSelectionSubsystem; +pub use polkadot_node_core_dispute_coordinator::DisputeCoordinatorSubsystem; +pub use polkadot_node_core_dispute_participation::DisputeParticipationSubsystem; pub use polkadot_node_core_provisioner::ProvisioningSubsystem as ProvisionerSubsystem; pub use polkadot_node_core_runtime_api::RuntimeApiSubsystem; pub use polkadot_statement_distribution::StatementDistribution as StatementDistributionSubsystem; -pub use polkadot_availability_recovery::AvailabilityRecoverySubsystem; -pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem; -pub use polkadot_node_core_approval_voting::ApprovalVotingSubsystem; -pub use polkadot_gossip_support::GossipSupport as GossipSupportSubsystem; -pub use polkadot_node_core_dispute_coordinator::DisputeCoordinatorSubsystem; -pub use polkadot_node_core_dispute_participation::DisputeParticipationSubsystem; -pub use polkadot_dispute_distribution::DisputeDistributionSubsystem; -pub use polkadot_node_core_chain_selection::ChainSelectionSubsystem; /// Arguments passed for overseer construction. -pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> where +pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> +where RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, @@ -103,8 +96,7 @@ pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> where /// /// A convenience for usage with malus, to avoid /// repetitive code across multiple behavior strain implementations. -pub fn create_default_subsystems<'a, Spawner, RuntimeClient> -( +pub fn create_default_subsystems<'a, Spawner, RuntimeClient>( OverseerGenArgs { keystore, runtime_client, @@ -121,37 +113,40 @@ pub fn create_default_subsystems<'a, Spawner, RuntimeClient> chain_selection_config, dispute_coordinator_config, .. - } : OverseerGenArgs<'a, Spawner, RuntimeClient> + }: OverseerGenArgs<'a, Spawner, RuntimeClient>, ) -> Result< AllSubsystems< - CandidateValidationSubsystem, - CandidateBackingSubsystem, - StatementDistributionSubsystem, - AvailabilityDistributionSubsystem, - AvailabilityRecoverySubsystem, - BitfieldSigningSubsystem, - BitfieldDistributionSubsystem, - ProvisionerSubsystem, - RuntimeApiSubsystem, - AvailabilityStoreSubsystem, - NetworkBridgeSubsystem>, AuthorityDiscoveryService>, - ChainApiSubsystem, - CollationGenerationSubsystem, - CollatorProtocolSubsystem, - ApprovalDistributionSubsystem, - ApprovalVotingSubsystem, - GossipSupportSubsystem, - DisputeCoordinatorSubsystem, - DisputeParticipationSubsystem, - DisputeDistributionSubsystem, - ChainSelectionSubsystem, ->, - Error + CandidateValidationSubsystem, + CandidateBackingSubsystem, + StatementDistributionSubsystem, + AvailabilityDistributionSubsystem, + AvailabilityRecoverySubsystem, + BitfieldSigningSubsystem, + BitfieldDistributionSubsystem, + ProvisionerSubsystem, + RuntimeApiSubsystem, + AvailabilityStoreSubsystem, + NetworkBridgeSubsystem< + Arc>, + AuthorityDiscoveryService, + >, + ChainApiSubsystem, + CollationGenerationSubsystem, + CollatorProtocolSubsystem, + ApprovalDistributionSubsystem, + ApprovalVotingSubsystem, + GossipSupportSubsystem, + DisputeCoordinatorSubsystem, + DisputeParticipationSubsystem, + DisputeDistributionSubsystem, + ChainSelectionSubsystem, + >, + Error, > where RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, - Spawner: 'static + SpawnNamed + Clone + Unpin + Spawner: 'static + SpawnNamed + Clone + Unpin, { use polkadot_node_subsystem_util::metrics::Metrics; @@ -160,16 +155,13 @@ where keystore.clone(), Metrics::register(registry)?, ), - availability_recovery: AvailabilityRecoverySubsystem::with_chunks_only( - ), + availability_recovery: AvailabilityRecoverySubsystem::with_chunks_only(), availability_store: AvailabilityStoreSubsystem::new( parachains_db.clone(), availability_config, Metrics::register(registry)?, ), - bitfield_distribution: BitfieldDistributionSubsystem::new( - Metrics::register(registry)?, - ), + bitfield_distribution: BitfieldDistributionSubsystem::new(Metrics::register(registry)?), bitfield_signing: BitfieldSigningSubsystem::new( spawner.clone(), keystore.clone(), @@ -184,13 +176,8 @@ where candidate_validation_config, Metrics::register(registry)?, ), - chain_api: ChainApiSubsystem::new( - runtime_client.clone(), - Metrics::register(registry)?, - ), - collation_generation: CollationGenerationSubsystem::new( - Metrics::register(registry)?, - ), + chain_api: ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?), + collation_generation: CollationGenerationSubsystem::new(Metrics::register(registry)?), collator_protocol: { let side = match is_collator { IsCollator::Yes(collator_pair) => ProtocolSide::Collator( @@ -204,9 +191,7 @@ where metrics: Metrics::register(registry)?, }, }; - CollatorProtocolSubsystem::new( - side, - ) + CollatorProtocolSubsystem::new(side) }, network_bridge: NetworkBridgeSubsystem::new( network_service.clone(), @@ -215,11 +200,7 @@ where Box::new(network_service.clone()), Metrics::register(registry)?, ), - provisioner: ProvisionerSubsystem::new( - spawner.clone(), - (), - Metrics::register(registry)?, - ), + provisioner: ProvisionerSubsystem::new(spawner.clone(), (), Metrics::register(registry)?), runtime_api: RuntimeApiSubsystem::new( runtime_client.clone(), Metrics::register(registry)?, @@ -229,9 +210,7 @@ where keystore.clone(), Metrics::register(registry)?, ), - approval_distribution: ApprovalDistributionSubsystem::new( - Metrics::register(registry)?, - ), + approval_distribution: ApprovalDistributionSubsystem::new(Metrics::register(registry)?), approval_voting: ApprovalVotingSubsystem::with_config( approval_voting_config, parachains_db.clone(), @@ -239,9 +218,7 @@ where Box::new(network_service.clone()), Metrics::register(registry)?, ), - gossip_support: GossipSupportSubsystem::new( - keystore.clone(), - ), + gossip_support: GossipSupportSubsystem::new(keystore.clone()), dispute_coordinator: DisputeCoordinatorSubsystem::new( parachains_db.clone(), dispute_coordinator_config, @@ -253,26 +230,26 @@ where authority_discovery_service.clone(), Metrics::register(registry)?, ), - chain_selection: ChainSelectionSubsystem::new( - chain_selection_config, - parachains_db, - ), + chain_selection: ChainSelectionSubsystem::new(chain_selection_config, parachains_db), }; Ok(all_subsystems) } - /// Trait for the `fn` generating the overseer. /// /// Default behavior is to create an unmodified overseer, as `RealOverseerGen` /// would do. pub trait OverseerGen { /// Overwrite the full generation of the overseer, including the subsystems. - fn generate<'a, Spawner, RuntimeClient>(&self, args: OverseerGenArgs<'a, Spawner, RuntimeClient>) -> Result<(Overseer>, OverseerHandle), Error> + fn generate<'a, Spawner, RuntimeClient>( + &self, + args: OverseerGenArgs<'a, Spawner, RuntimeClient>, + ) -> Result<(Overseer>, OverseerHandle), Error> where RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, - Spawner: 'static + SpawnNamed + Clone + Unpin { + Spawner: 'static + SpawnNamed + Clone + Unpin, + { let gen = RealOverseerGen; RealOverseerGen::generate::(&gen, args) } @@ -285,13 +262,14 @@ pub trait OverseerGen { pub struct RealOverseerGen; impl OverseerGen for RealOverseerGen { - fn generate<'a, Spawner, RuntimeClient>(&self, - args : OverseerGenArgs<'a, Spawner, RuntimeClient> + fn generate<'a, Spawner, RuntimeClient>( + &self, + args: OverseerGenArgs<'a, Spawner, RuntimeClient>, ) -> Result<(Overseer>, OverseerHandle), Error> where RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, - Spawner: 'static + SpawnNamed + Clone + Unpin + Spawner: 'static + SpawnNamed + Clone + Unpin, { let spawner = args.spawner.clone(); let leaves = args.leaves.clone(); @@ -300,12 +278,7 @@ impl OverseerGen for RealOverseerGen { let all_subsystems = create_default_subsystems::(args)?; - Overseer::new( - leaves, - all_subsystems, - registry, - runtime_client, - spawner, - ).map_err(|e| e.into()) + Overseer::new(leaves, all_subsystems, registry, runtime_client, spawner) + .map_err(|e| e.into()) } } diff --git a/polkadot/node/service/src/parachains_db/mod.rs b/polkadot/node/service/src/parachains_db/mod.rs index 123d154a129..17f7ae0fd0b 100644 --- a/polkadot/node/service/src/parachains_db/mod.rs +++ b/polkadot/node/service/src/parachains_db/mod.rs @@ -14,18 +14,12 @@ //! A `RocksDB` instance for storing parachain data; availability data, and approvals. #[cfg(feature = "full-node")] -use { - std::io, - std::path::PathBuf, - std::sync::Arc, - - kvdb::KeyValueDB, -}; +use {kvdb::KeyValueDB, std::io, std::path::PathBuf, std::sync::Arc}; #[cfg(feature = "full-node")] mod upgrade; -#[cfg(any(test,feature = "full-node"))] +#[cfg(any(test, feature = "full-node"))] pub(crate) mod columns { pub mod v0 { pub const NUM_COLUMNS: u32 = 3; @@ -40,7 +34,7 @@ pub(crate) mod columns { } /// Columns used by different subsystems. -#[cfg(any(test,feature = "full-node"))] +#[cfg(any(test, feature = "full-node"))] #[derive(Debug, Clone)] pub struct ColumnsConfig { /// The column used by the av-store for data. @@ -56,7 +50,7 @@ pub struct ColumnsConfig { } /// The real columns used by the parachains DB. -#[cfg(any(test,feature = "full-node"))] +#[cfg(any(test, feature = "full-node"))] pub const REAL_COLUMNS: ColumnsConfig = ColumnsConfig { col_availability_data: columns::COL_AVAILABILITY_DATA, col_availability_meta: columns::COL_AVAILABILITY_META, @@ -78,11 +72,7 @@ pub struct CacheSizes { impl Default for CacheSizes { fn default() -> Self { - CacheSizes { - availability_data: 25, - availability_meta: 1, - approval_data: 5, - } + CacheSizes { availability_data: 25, availability_meta: 1, approval_data: 5 } } } @@ -93,26 +83,26 @@ pub(crate) fn other_io_error(err: String) -> io::Error { /// Open the database on disk, creating it if it doesn't exist. #[cfg(feature = "full-node")] -pub fn open_creating( - root: PathBuf, - cache_sizes: CacheSizes, -) -> io::Result> { - use kvdb_rocksdb::{DatabaseConfig, Database}; +pub fn open_creating(root: PathBuf, cache_sizes: CacheSizes) -> io::Result> { + use kvdb_rocksdb::{Database, DatabaseConfig}; let path = root.join("parachains").join("db"); let mut db_config = DatabaseConfig::with_columns(columns::NUM_COLUMNS); - let _ = db_config.memory_budget + let _ = db_config + .memory_budget .insert(columns::COL_AVAILABILITY_DATA, cache_sizes.availability_data); - let _ = db_config.memory_budget + let _ = db_config + .memory_budget .insert(columns::COL_AVAILABILITY_META, cache_sizes.availability_meta); - let _ = db_config.memory_budget + let _ = db_config + .memory_budget .insert(columns::COL_APPROVAL_DATA, cache_sizes.approval_data); - let path_str = path.to_str().ok_or_else(|| other_io_error( - format!("Bad database path: {:?}", path), - ))?; + let path_str = path + .to_str() + .ok_or_else(|| other_io_error(format!("Bad database path: {:?}", path)))?; std::fs::create_dir_all(&path_str)?; upgrade::try_upgrade_db(&path)?; diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs index de4e09368b2..0ba84103885 100644 --- a/polkadot/node/service/src/parachains_db/upgrade.rs +++ b/polkadot/node/service/src/parachains_db/upgrade.rs @@ -13,13 +13,13 @@ //! Migration code for the parachain's DB. - #![cfg(feature = "full-node")] -use std::fs; -use std::io; -use std::path::{Path, PathBuf}; -use std::str::FromStr; +use std::{ + fs, io, + path::{Path, PathBuf}, + str::FromStr, +}; type Version = u32; @@ -36,10 +36,7 @@ pub enum Error { #[error("The version file format is incorrect")] CorruptedVersionFile, #[error("Future version (expected {current:?}, found {got:?})")] - FutureVersion { - current: Version, - got: Version, - }, + FutureVersion { current: Version, got: Version }, } impl From for io::Error { @@ -58,10 +55,7 @@ pub fn try_upgrade_db(db_path: &Path) -> Result<(), Error> { match current_version(db_path)? { 0 => migrate_from_version_0_to_1(db_path)?, CURRENT_VERSION => (), - v => return Err(Error::FutureVersion { - current: CURRENT_VERSION, - got: v, - }), + v => return Err(Error::FutureVersion { current: CURRENT_VERSION, got: v }), } } @@ -92,13 +86,13 @@ fn version_file_path(path: &Path) -> PathBuf { file_path } - /// Migration from version 0 to version 1: /// * the number of columns has changed from 3 to 5; fn migrate_from_version_0_to_1(path: &Path) -> Result<(), Error> { use kvdb_rocksdb::{Database, DatabaseConfig}; - let db_path = path.to_str() + let db_path = path + .to_str() .ok_or_else(|| super::other_io_error("Invalid database path".into()))?; let db_cfg = DatabaseConfig::with_columns(super::columns::v0::NUM_COLUMNS); let db = Database::open(&db_cfg, db_path)?; diff --git a/polkadot/node/service/src/relay_chain_selection.rs b/polkadot/node/service/src/relay_chain_selection.rs index aebd5238cc7..f499c14921e 100644 --- a/polkadot/node/service/src/relay_chain_selection.rs +++ b/polkadot/node/service/src/relay_chain_selection.rs @@ -35,16 +35,19 @@ #![cfg(feature = "full-node")] +use super::{HeaderProvider, HeaderProviderProvider}; +use consensus_common::{Error as ConsensusError, SelectChain}; +use futures::channel::oneshot; +use polkadot_node_subsystem_util::metrics::{self, prometheus}; +use polkadot_overseer::{AllMessages, Handle, OverseerHandle}; use polkadot_primitives::v1::{ - Hash, BlockNumber, Block as PolkadotBlock, Header as PolkadotHeader, + Block as PolkadotBlock, BlockNumber, Hash, Header as PolkadotHeader, +}; +use polkadot_subsystem::messages::{ + ApprovalVotingMessage, ChainSelectionMessage, DisputeCoordinatorMessage, + HighestApprovedAncestorBlock, }; -use polkadot_subsystem::messages::{ApprovalVotingMessage, HighestApprovedAncestorBlock, ChainSelectionMessage, DisputeCoordinatorMessage}; -use polkadot_node_subsystem_util::metrics::{self, prometheus}; -use futures::channel::oneshot; -use consensus_common::{Error as ConsensusError, SelectChain}; use std::sync::Arc; -use polkadot_overseer::{AllMessages, Handle, OverseerHandle}; -use super::{HeaderProvider, HeaderProviderProvider}; /// The maximum amount of unfinalized blocks we are willing to allow due to approval checking /// or disputes. @@ -106,37 +109,25 @@ impl Metrics { } /// A chain-selection implementation which provides safety for relay chains. -pub struct SelectRelayChainWithFallback< - B: sc_client_api::Backend, -> { +pub struct SelectRelayChainWithFallback> { // A fallback to use in case the overseer is disconnected. // // This is used on relay chains which have not yet enabled // parachains as well as situations where the node is offline. fallback: sc_consensus::LongestChain, - selection: SelectRelayChain< - B, - Handle, - >, + selection: SelectRelayChain, } impl Clone for SelectRelayChainWithFallback where B: sc_client_api::Backend, - SelectRelayChain< - B, - Handle, - >: Clone, + SelectRelayChain: Clone, { fn clone(&self) -> Self { - Self { - fallback: self.fallback.clone(), - selection: self.selection.clone(), - } + Self { fallback: self.fallback.clone(), selection: self.selection.clone() } } } - impl SelectRelayChainWithFallback where B: sc_client_api::Backend + 'static, @@ -146,11 +137,7 @@ where pub fn new(backend: Arc, overseer: Handle, metrics: Metrics) -> Self { SelectRelayChainWithFallback { fallback: sc_consensus::LongestChain::new(backend.clone()), - selection: SelectRelayChain::new( - backend, - overseer, - metrics, - ), + selection: SelectRelayChain::new(backend, overseer, metrics), } } } @@ -161,15 +148,11 @@ where { /// Given an overseer handle, this connects the [`SelectRelayChainWithFallback`]'s /// internal handle and its clones to the same overseer. - pub fn connect_to_overseer( - &mut self, - handle: OverseerHandle, - ) { + pub fn connect_to_overseer(&mut self, handle: OverseerHandle) { self.selection.overseer.connect_to_overseer(handle); } } - #[async_trait::async_trait] impl SelectChain for SelectRelayChainWithFallback where @@ -202,7 +185,6 @@ where } } - /// A chain-selection implementation which provides safety for relay chains /// but does not handle situations where the overseer is not yet connected. pub struct SelectRelayChain { @@ -219,24 +201,17 @@ where /// Create a new [`SelectRelayChain`] wrapping the given chain backend /// and a handle to the overseer. pub fn new(backend: Arc, overseer: OH, metrics: Metrics) -> Self { - SelectRelayChain { - backend, - overseer, - metrics, - } + SelectRelayChain { backend, overseer, metrics } } fn block_header(&self, hash: Hash) -> Result { match HeaderProvider::header(self.backend.header_provider(), hash) { Ok(Some(header)) => Ok(header), - Ok(None) => Err(ConsensusError::ChainLookup(format!( - "Missing header with hash {:?}", - hash, - ))), + Ok(None) => + Err(ConsensusError::ChainLookup(format!("Missing header with hash {:?}", hash,))), Err(e) => Err(ConsensusError::ChainLookup(format!( "Lookup failed for header with hash {:?}: {:?}", - hash, - e, + hash, e, ))), } } @@ -244,14 +219,11 @@ where fn block_number(&self, hash: Hash) -> Result { match HeaderProvider::number(self.backend.header_provider(), hash) { Ok(Some(number)) => Ok(number), - Ok(None) => Err(ConsensusError::ChainLookup(format!( - "Missing number with hash {:?}", - hash, - ))), + Ok(None) => + Err(ConsensusError::ChainLookup(format!("Missing number with hash {:?}", hash,))), Err(e) => Err(ConsensusError::ChainLookup(format!( "Lookup failed for number with hash {:?}: {:?}", - hash, - e, + hash, e, ))), } } @@ -281,7 +253,6 @@ enum Error { EmptyLeaves, } - /// Decoupling trait for the overseer handle. /// /// Required for testing purposes. @@ -297,7 +268,6 @@ impl OverseerHandleT for Handle { } } - #[async_trait::async_trait] impl SelectChain for SelectRelayChain where @@ -311,10 +281,8 @@ where self.overseer .clone() - .send_msg( - ChainSelectionMessage::Leaves(tx), - std::any::type_name::(), - ).await; + .send_msg(ChainSelectionMessage::Leaves(tx), std::any::type_name::()) + .await; rx.await .map_err(Error::OverseerDisconnected) @@ -326,13 +294,13 @@ where // The Chain Selection subsystem is supposed to treat the finalized // block as the best leaf in the case that there are no viable // leaves, so this should not happen in practice. - let best_leaf = self.leaves() + let best_leaf = self + .leaves() .await? .first() .ok_or_else(|| ConsensusError::Other(Box::new(Error::EmptyLeaves)))? .clone(); - self.block_header(best_leaf) } @@ -354,12 +322,15 @@ where let subchain_head = { let (tx, rx) = oneshot::channel(); - overseer.send_msg( - ChainSelectionMessage::BestLeafContaining(target_hash, tx), - std::any::type_name::(), - ).await; - - let best = rx.await + overseer + .send_msg( + ChainSelectionMessage::BestLeafContaining(target_hash, tx), + std::any::type_name::(), + ) + .await; + + let best = rx + .await .map_err(Error::OverseerDisconnected) .map_err(|e| ConsensusError::Other(Box::new(e)))?; @@ -385,7 +356,7 @@ where "`finality_target` max number is less than target number", ); } - return Ok(Some(target_hash)); + return Ok(Some(target_hash)) } // find the current number. let subchain_header = self.block_header(subchain_head)?; @@ -393,15 +364,17 @@ where if subchain_header.number <= max { subchain_head } else { - let (ancestor_hash, _) = crate::grandpa_support::walk_backwards_to_target_block( - self.backend.header_provider(), - max, - &subchain_header, - ).map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?; + let (ancestor_hash, _) = + crate::grandpa_support::walk_backwards_to_target_block( + self.backend.header_provider(), + max, + &subchain_header, + ) + .map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?; ancestor_hash } - } + }, }; let initial_leaf = subchain_head; @@ -409,31 +382,30 @@ where // 2. Constrain according to `ApprovedAncestor`. let (subchain_head, subchain_number, subchain_block_descriptions) = { - let (tx, rx) = oneshot::channel(); - overseer.send_msg( - ApprovalVotingMessage::ApprovedAncestor( - subchain_head, - target_number, - tx, - ), - std::any::type_name::(), - ).await; - - match rx.await + overseer + .send_msg( + ApprovalVotingMessage::ApprovedAncestor(subchain_head, target_number, tx), + std::any::type_name::(), + ) + .await; + + match rx + .await .map_err(Error::OverseerDisconnected) .map_err(|e| ConsensusError::Other(Box::new(e)))? { // No approved ancestors means target hash is maximal vote. None => (target_hash, target_number, Vec::new()), - Some(HighestApprovedAncestorBlock { - number, hash, descriptions - }) => (hash, number, descriptions), + Some(HighestApprovedAncestorBlock { number, hash, descriptions }) => + (hash, number, descriptions), } }; // Prevent sending flawed data to the dispute-coordinator. - if Some(subchain_block_descriptions.len() as _) != subchain_number.checked_sub(target_number) { + if Some(subchain_block_descriptions.len() as _) != + subchain_number.checked_sub(target_number) + { tracing::error!( LOG_TARGET, present_block_descriptions = subchain_block_descriptions.len(), @@ -441,7 +413,7 @@ where subchain_number, "Mismatch of anticipated block descriptions and block number difference.", ); - return Ok(Some(target_hash)); + return Ok(Some(target_hash)) } let lag = initial_leaf_number.saturating_sub(subchain_number); @@ -449,14 +421,18 @@ where // 3. Constrain according to disputes: let (tx, rx) = oneshot::channel(); - overseer.send_msg(DisputeCoordinatorMessage::DetermineUndisputedChain{ - base_number: target_number, - block_descriptions: subchain_block_descriptions, - tx, - }, - std::any::type_name::(), - ).await; - let (subchain_number, subchain_head) = rx.await + overseer + .send_msg( + DisputeCoordinatorMessage::DetermineUndisputedChain { + base_number: target_number, + block_descriptions: subchain_block_descriptions, + tx, + }, + std::any::type_name::(), + ) + .await; + let (subchain_number, subchain_head) = rx + .await .map_err(Error::OverseerDisconnected) .map_err(|e| ConsensusError::Other(Box::new(e)))? .unwrap_or_else(|| (subchain_number, subchain_head)); @@ -481,7 +457,8 @@ where self.backend.header_provider(), safe_target, &initial_leaf_header, - ).map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?; + ) + .map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?; Ok(Some(forced_target)) } diff --git a/polkadot/node/service/src/tests.rs b/polkadot/node/service/src/tests.rs index 84fe018de20..42f1794cd79 100644 --- a/polkadot/node/service/src/tests.rs +++ b/polkadot/node/service/src/tests.rs @@ -14,34 +14,33 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use super::relay_chain_selection::*; -use super::*; +use super::{relay_chain_selection::*, *}; use futures::channel::oneshot::Receiver; use polkadot_node_primitives::approval::{VRFOutput, VRFProof}; use polkadot_node_subsystem_test_helpers as test_helpers; use polkadot_node_subsystem_util::TimeoutExt; -use polkadot_subsystem::messages::AllMessages; -use polkadot_subsystem::messages::BlockDescription; +use polkadot_subsystem::messages::{AllMessages, BlockDescription}; use polkadot_test_client::Sr25519Keyring; -use sp_consensus_babe::digests::CompatibleDigestItem; -use sp_consensus_babe::digests::{PreDigest, SecondaryVRFPreDigest}; -use sp_consensus_babe::Transcript; -use sp_runtime::testing::*; -use sp_runtime::DigestItem; -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::iter::IntoIterator; +use sp_consensus_babe::{ + digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest}, + Transcript, +}; +use sp_runtime::{testing::*, DigestItem}; +use std::{ + collections::{BTreeMap, HashMap, HashSet}, + iter::IntoIterator, +}; use assert_matches::assert_matches; -use std::sync::Arc; -use std::time::Duration; +use std::{sync::Arc, time::Duration}; use consensus_common::SelectChain; -use futures::channel::oneshot; -use futures::prelude::*; +use futures::{channel::oneshot, prelude::*}; use polkadot_primitives::v1::{Block, BlockNumber, Hash, Header}; use polkadot_subsystem::messages::{ - ApprovalVotingMessage, ChainSelectionMessage, DisputeCoordinatorMessage, HighestApprovedAncestorBlock, + ApprovalVotingMessage, ChainSelectionMessage, DisputeCoordinatorMessage, + HighestApprovedAncestorBlock, }; use polkadot_node_subsystem_test_helpers::TestSubsystemSender; @@ -67,8 +66,14 @@ struct TestHarness { #[derive(Default)] struct HarnessConfig; -fn test_harness>(case_vars: CaseVars, test: impl FnOnce(TestHarness) -> T) { - let _ = env_logger::builder().is_test(true).filter_level(log::LevelFilter::Trace).try_init(); +fn test_harness>( + case_vars: CaseVars, + test: impl FnOnce(TestHarness) -> T, +) { + let _ = env_logger::builder() + .is_test(true) + .filter_level(log::LevelFilter::Trace) + .try_init(); let pool = sp_core::testing::TaskExecutor::new(); let (mut context, virtual_overseer) = test_helpers::make_subsystem_context(pool); @@ -111,7 +116,10 @@ async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages { msg } -async fn overseer_recv_with_timeout(overseer: &mut VirtualOverseer, timeout: Duration) -> Option { +async fn overseer_recv_with_timeout( + overseer: &mut VirtualOverseer, + timeout: Duration, +) -> Option { tracing::trace!("Waiting for message..."); overseer.recv().timeout(timeout).await } @@ -165,7 +173,7 @@ impl TestChainStorage { while let Some(block) = self.blocks_by_hash.get(&block_hash) { if minimum_block_number >= block.number { - break; + break } descriptions.push(BlockDescription { session: 1 as _, // dummy, not checked @@ -183,12 +191,12 @@ impl TestChainStorage { if &leaf != next { block_hash = *next; } else { - break; + break } } if highest_approved_ancestor.is_none() { - return None; + return None } Some(HighestApprovedAncestorBlock { @@ -199,9 +207,13 @@ impl TestChainStorage { } /// Traverse backwards from leave down to block number. - fn undisputed_chain(&self, base_blocknumber: BlockNumber, highest_approved_block_hash: Hash) -> Option { + fn undisputed_chain( + &self, + base_blocknumber: BlockNumber, + highest_approved_block_hash: Hash, + ) -> Option { if self.disputed_blocks.is_empty() { - return Some(highest_approved_block_hash); + return Some(highest_approved_block_hash) } let mut undisputed_chain = Some(highest_approved_block_hash); @@ -209,14 +221,14 @@ impl TestChainStorage { while let Some(block) = self.blocks_by_hash.get(&block_hash) { block_hash = block.hash(); if ChainBuilder::GENESIS_HASH == block_hash { - return None; + return None } let next = block.parent_hash(); if self.disputed_blocks.contains(&block_hash) { undisputed_chain = Some(*next); } if block.number() == &base_blocknumber { - return None; + return None } block_hash = *next; } @@ -256,14 +268,26 @@ impl ChainBuilder { pub fn add_block<'a>(&'a mut self, hash: Hash, parent_hash: Hash, number: u32) -> &'a mut Self { assert!(number != 0, "cannot add duplicate genesis block"); assert!(hash != Self::GENESIS_HASH, "cannot add block with genesis hash"); - assert!(parent_hash != Self::GENESIS_PARENT_HASH, "cannot add block with genesis parent hash"); + assert!( + parent_hash != Self::GENESIS_PARENT_HASH, + "cannot add block with genesis parent hash" + ); assert!(self.0.blocks_by_hash.len() < u8::MAX.into()); self.add_block_inner(hash, parent_hash, number) } - fn add_block_inner<'a>(&'a mut self, hash: Hash, parent_hash: Hash, number: u32) -> &'a mut Self { + fn add_block_inner<'a>( + &'a mut self, + hash: Hash, + parent_hash: Hash, + number: u32, + ) -> &'a mut Self { let header = ChainBuilder::make_header(parent_hash, number); - assert!(self.0.blocks_by_hash.insert(hash, header).is_none(), "block with hash {:?} already exists", hash,); + assert!( + self.0.blocks_by_hash.insert(hash, header).is_none(), + "block with hash {:?} already exists", + hash, + ); self.0.blocks_at_height.entry(number).or_insert_with(Vec::new).push(hash); self } @@ -292,7 +316,12 @@ impl ChainBuilder { block } - pub fn fast_forward(&mut self, branch_tag: u8, parent: Hash, block_number: BlockNumber) -> Hash { + pub fn fast_forward( + &mut self, + branch_tag: u8, + parent: Hash, + block_number: BlockNumber, + ) -> Hash { let hash = Hash::repeat_byte((block_number as u8 | branch_tag) as u8); let _ = self.add_block(hash, parent, block_number); hash @@ -310,16 +339,24 @@ impl ChainBuilder { let digest = { let mut digest = Digest::default(); let (vrf_output, vrf_proof) = garbage_vrf(); - digest.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF(SecondaryVRFPreDigest { - authority_index: 0, - slot: 1.into(), // slot, unused - vrf_output, - vrf_proof, - }))); + digest.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF( + SecondaryVRFPreDigest { + authority_index: 0, + slot: 1.into(), // slot, unused + vrf_output, + vrf_proof, + }, + ))); digest }; - Header { digest, extrinsics_root: Default::default(), number, state_root: Default::default(), parent_hash } + Header { + digest, + extrinsics_root: Default::default(), + number, + state_root: Default::default(), + parent_hash, + } } } @@ -353,7 +390,7 @@ async fn test_skeleton( ); if best_chain_containing_block.is_none() { - return; + return } tracing::trace!("approved ancestor response: {:?}", undisputed_chain); @@ -404,22 +441,28 @@ fn run_specialized_test_w_harness CaseVars>(case_var_provider: F) // Verify test integrity: the provided highest approved // ancestor must match the chain derived one. - let highest_approved_ancestor_w_desc = best_chain_containing_block.and_then(|best_chain_containing_block| { - let min_blocknumber = - chain.blocks_by_hash.get(&best_chain_containing_block).map(|x| x.number).unwrap_or_default(); - let highest_approved_ancestor_w_desc = - chain.highest_approved_ancestors(min_blocknumber, best_chain_containing_block); - if let (Some(highest_approved_ancestor_w_desc), Some(highest_approved_ancestor_block)) = - (&highest_approved_ancestor_w_desc, highest_approved_ancestor_block) - { - assert_eq!( + let highest_approved_ancestor_w_desc = + best_chain_containing_block.and_then(|best_chain_containing_block| { + let min_blocknumber = chain + .blocks_by_hash + .get(&best_chain_containing_block) + .map(|x| x.number) + .unwrap_or_default(); + let highest_approved_ancestor_w_desc = + chain.highest_approved_ancestors(min_blocknumber, best_chain_containing_block); + if let ( + Some(highest_approved_ancestor_w_desc), + Some(highest_approved_ancestor_block), + ) = (&highest_approved_ancestor_w_desc, highest_approved_ancestor_block) + { + assert_eq!( highest_approved_ancestor_block, highest_approved_ancestor_w_desc.hash, "TestCaseIntegrity: Provided and expected approved ancestor hash mismatch: {:?} vs {:?}", highest_approved_ancestor_block, highest_approved_ancestor_w_desc.hash, ); - } - highest_approved_ancestor_w_desc - }); + } + highest_approved_ancestor_w_desc + }); if let Some(haacwd) = &highest_approved_ancestor_w_desc { let expected = chain.undisputed_chain(haacwd.number, haacwd.hash); assert_eq!( diff --git a/polkadot/node/subsystem-test-helpers/src/lib.rs b/polkadot/node/subsystem-test-helpers/src/lib.rs index 2a7a66ac480..f3fc16e85e5 100644 --- a/polkadot/node/subsystem-test-helpers/src/lib.rs +++ b/polkadot/node/subsystem-test-helpers/src/lib.rs @@ -19,37 +19,29 @@ #![warn(missing_docs)] use polkadot_node_subsystem::{ - messages::AllMessages, - overseer, - FromOverseer, SubsystemContext, SubsystemError, SubsystemResult, - SpawnedSubsystem, OverseerSignal, + messages::AllMessages, overseer, FromOverseer, OverseerSignal, SpawnedSubsystem, + SubsystemContext, SubsystemError, SubsystemResult, }; use polkadot_node_subsystem_util::TimeoutExt; -use futures::channel::mpsc; -use futures::poll; -use futures::prelude::*; +use futures::{channel::mpsc, poll, prelude::*}; use parking_lot::Mutex; use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; -use std::convert::Infallible; -use std::pin::Pin; -use std::sync::Arc; -use std::task::{Context, Poll, Waker}; -use std::time::Duration; +use std::{ + convert::Infallible, + pin::Pin, + sync::Arc, + task::{Context, Poll, Waker}, + time::Duration, +}; /// Generally useful mock data providers for unit tests. pub mod mock; enum SinkState { - Empty { - read_waker: Option, - }, - Item { - item: T, - ready_waker: Option, - flush_waker: Option, - }, + Empty { read_waker: Option }, + Item { item: T, ready_waker: Option, flush_waker: Option }, } /// The sink half of a single-item sink that does not resolve until the item has been read. @@ -72,13 +64,10 @@ impl Sink for SingleItemSink { let mut state = self.0.lock(); match *state { SinkState::Empty { .. } => Poll::Ready(Ok(())), - SinkState::Item { - ref mut ready_waker, - .. - } => { + SinkState::Item { ref mut ready_waker, .. } => { *ready_waker = Some(cx.waker().clone()); Poll::Pending - } + }, } } @@ -86,19 +75,14 @@ impl Sink for SingleItemSink { let mut state = self.0.lock(); match *state { - SinkState::Empty { ref mut read_waker } => { + SinkState::Empty { ref mut read_waker } => if let Some(waker) = read_waker.take() { waker.wake(); - } - } + }, _ => panic!("start_send called outside of empty sink state ensured by poll_ready"), } - *state = SinkState::Item { - item, - ready_waker: None, - flush_waker: None, - }; + *state = SinkState::Item { item, ready_waker: None, flush_waker: None }; Ok(()) } @@ -107,13 +91,10 @@ impl Sink for SingleItemSink { let mut state = self.0.lock(); match *state { SinkState::Empty { .. } => Poll::Ready(Ok(())), - SinkState::Item { - ref mut flush_waker, - .. - } => { + SinkState::Item { ref mut flush_waker, .. } => { *flush_waker = Some(cx.waker().clone()); Poll::Pending - } + }, } } @@ -132,11 +113,7 @@ impl Stream for SingleItemStream { match std::mem::replace(&mut *state, SinkState::Empty { read_waker }) { SinkState::Empty { .. } => Poll::Pending, - SinkState::Item { - item, - ready_waker, - flush_waker, - } => { + SinkState::Item { item, ready_waker, flush_waker } => { if let Some(waker) = ready_waker { waker.wake(); } @@ -146,7 +123,7 @@ impl Stream for SingleItemStream { } Poll::Ready(Some(item)) - } + }, } } } @@ -169,19 +146,13 @@ pub struct TestSubsystemSender { /// Construct a sender/receiver pair. pub fn sender_receiver() -> (TestSubsystemSender, mpsc::UnboundedReceiver) { let (tx, rx) = mpsc::unbounded(); - ( - TestSubsystemSender { tx }, - rx, - ) + (TestSubsystemSender { tx }, rx) } #[async_trait::async_trait] impl overseer::SubsystemSender for TestSubsystemSender { async fn send_message(&mut self, msg: AllMessages) { - self.tx - .send(msg) - .await - .expect("test overseer no longer live"); + self.tx.send(msg).await.expect("test overseer no longer live"); } async fn send_messages(&mut self, msgs: T) @@ -190,10 +161,7 @@ impl overseer::SubsystemSender for TestSubsystemSender { T::IntoIter: Send, { let mut iter = stream::iter(msgs.into_iter().map(Ok)); - self.tx - .send_all(&mut iter) - .await - .expect("test overseer no longer live"); + self.tx.send_all(&mut iter).await.expect("test overseer no longer live"); } fn send_unbounded_message(&mut self, msg: AllMessages) { @@ -209,8 +177,7 @@ pub struct TestSubsystemContext { } #[async_trait::async_trait] -impl overseer::SubsystemContext - for TestSubsystemContext +impl overseer::SubsystemContext for TestSubsystemContext where M: std::fmt::Debug + Send + 'static, AllMessages: From, @@ -231,7 +198,9 @@ where } async fn recv(&mut self) -> SubsystemResult> { - self.rx.next().await + self.rx + .next() + .await .ok_or_else(|| SubsystemError::Context("Receiving end closed".to_owned())) } @@ -244,9 +213,11 @@ where Ok(()) } - fn spawn_blocking(&mut self, name: &'static str, s: Pin + Send>>) - -> SubsystemResult<()> - { + fn spawn_blocking( + &mut self, + name: &'static str, + s: Pin + Send>>, + ) -> SubsystemResult<()> { self.spawn.spawn_blocking(name, s); Ok(()) } @@ -272,10 +243,7 @@ impl TestSubsystemContextHandle { /// Send a message or signal to the subsystem. This resolves at the point in time where the /// subsystem has _read_ the message. pub async fn send(&mut self, from_overseer: FromOverseer) { - self.tx - .send(from_overseer) - .await - .expect("Test subsystem no longer live"); + self.tx.send(from_overseer).await.expect("Test subsystem no longer live"); } /// Receive the next message from the subsystem. @@ -302,10 +270,7 @@ pub fn make_subsystem_context( rx: overseer_rx, spawn, }, - TestSubsystemContextHandle { - tx: overseer_tx, - rx: all_messages_rx, - }, + TestSubsystemContextHandle { tx: overseer_tx, rx: all_messages_rx }, ) } @@ -365,43 +330,47 @@ where } }); - SpawnedSubsystem { - name: "forward-subsystem", - future, - } + SpawnedSubsystem { name: "forward-subsystem", future } } } #[cfg(test)] mod tests { use super::*; - use polkadot_overseer::{Overseer, Handle, HeadSupportsParachains, AllSubsystems}; use futures::executor::block_on; - use polkadot_primitives::v1::Hash; use polkadot_node_subsystem::messages::CollatorProtocolMessage; + use polkadot_overseer::{AllSubsystems, Handle, HeadSupportsParachains, Overseer}; + use polkadot_primitives::v1::Hash; struct AlwaysSupportsParachains; impl HeadSupportsParachains for AlwaysSupportsParachains { - fn head_supports_parachains(&self, _head: &Hash) -> bool { true } + fn head_supports_parachains(&self, _head: &Hash) -> bool { + true + } } #[test] fn forward_subsystem_works() { let spawner = sp_core::testing::TaskExecutor::new(); let (tx, rx) = mpsc::channel(2); - let all_subsystems = AllSubsystems::<()>::dummy().replace_collator_protocol(ForwardSubsystem(tx)); + let all_subsystems = + AllSubsystems::<()>::dummy().replace_collator_protocol(ForwardSubsystem(tx)); let (overseer, handle) = Overseer::new( Vec::new(), all_subsystems, None, AlwaysSupportsParachains, spawner.clone(), - ).unwrap(); + ) + .unwrap(); let mut handle = Handle::Connected(handle); spawner.spawn("overseer", overseer.run().then(|_| async { () }).boxed()); block_on(handle.send_msg_anon(CollatorProtocolMessage::CollateOn(Default::default()))); - assert!(matches!(block_on(rx.into_future()).0.unwrap(), CollatorProtocolMessage::CollateOn(_))); + assert!(matches!( + block_on(rx.into_future()).0.unwrap(), + CollatorProtocolMessage::CollateOn(_) + )); } } diff --git a/polkadot/node/subsystem-test-helpers/src/mock.rs b/polkadot/node/subsystem-test-helpers/src/mock.rs index 2d8671f6dc2..0883bdf98a1 100644 --- a/polkadot/node/subsystem-test-helpers/src/mock.rs +++ b/polkadot/node/subsystem-test-helpers/src/mock.rs @@ -14,17 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . - - use std::sync::Arc; use sc_keystore::LocalKeystore; use sp_application_crypto::AppKey; use sp_keyring::Sr25519Keyring; -use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; - -use polkadot_primitives::v1::{ValidatorId, AuthorityDiscoveryId}; +use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; +use polkadot_primitives::v1::{AuthorityDiscoveryId, ValidatorId}; /// Get mock keystore with `Ferdie` key. pub fn make_ferdie_keystore() -> SyncCryptoStorePtr { @@ -43,4 +40,3 @@ pub fn make_ferdie_keystore() -> SyncCryptoStorePtr { .expect("Insert key into keystore"); keystore } - diff --git a/polkadot/node/subsystem-types/src/errors.rs b/polkadot/node/subsystem-types/src/errors.rs index fffdc04ac13..4de85c6b5f9 100644 --- a/polkadot/node/subsystem-types/src/errors.rs +++ b/polkadot/node/subsystem-types/src/errors.rs @@ -16,7 +16,6 @@ //! Error types for the subsystem requests. - use crate::JaegerError; /// A description of an error causing the runtime API request to be unservable. @@ -125,7 +124,8 @@ pub enum SubsystemError { /// An additional annotation tag for the origin of `source`. origin: &'static str, /// The wrapped error. Marked as source for tracking the error chain. - #[source] source: Box + #[source] + source: Box, }, } @@ -140,7 +140,10 @@ pub enum SubsystemError { impl SubsystemError { /// Adds a `str` as `origin` to the given error `err`. - pub fn with_origin(origin: &'static str, err: E) -> Self { + pub fn with_origin( + origin: &'static str, + err: E, + ) -> Self { Self::FromOrigin { origin, source: Box::new(err) } } } diff --git a/polkadot/node/subsystem-types/src/lib.rs b/polkadot/node/subsystem-types/src/lib.rs index 7524a795cfa..dca7d56a98b 100644 --- a/polkadot/node/subsystem-types/src/lib.rs +++ b/polkadot/node/subsystem-types/src/lib.rs @@ -22,16 +22,16 @@ #![warn(missing_docs)] -use std::{sync::Arc, fmt}; +use std::{fmt, sync::Arc}; -pub use polkadot_primitives::v1::{Hash, BlockNumber}; +pub use polkadot_primitives::v1::{BlockNumber, Hash}; use smallvec::SmallVec; pub mod errors; pub mod messages; -pub use polkadot_node_jaeger as jaeger; pub use jaeger::*; +pub use polkadot_node_jaeger as jaeger; /// How many slots are stack-reserved for active leaves updates /// @@ -39,7 +39,6 @@ pub use jaeger::*; /// If there are greater than this number of slots, then we fall back to a heap vector. const ACTIVE_LEAVES_SMALLVEC_CAPACITY: usize = 8; - /// The status of an activated leaf. #[derive(Debug, Clone)] pub enum LeafStatus { @@ -118,9 +117,9 @@ impl PartialEq for ActiveLeavesUpdate { /// /// Instead, it means equality when `activated` and `deactivated` are considered as sets. fn eq(&self, other: &Self) -> bool { - self.activated.as_ref().map(|a| a.hash) == other.activated.as_ref().map(|a| a.hash) - && self.deactivated.len() == other.deactivated.len() - && self.deactivated.iter().all(|a| other.deactivated.contains(a)) + self.activated.as_ref().map(|a| a.hash) == other.activated.as_ref().map(|a| a.hash) && + self.deactivated.len() == other.deactivated.len() && + self.deactivated.iter().all(|a| other.deactivated.contains(a)) } } diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index ba4693cc191..b6cf9d0a0dd 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -22,14 +22,22 @@ //! //! Subsystems' APIs are defined separately from their implementation, leading to easier mocking. - use futures::channel::{mpsc, oneshot}; use thiserror::Error; pub use sc_network::IfDisconnected; -use polkadot_node_network_protocol::{PeerId, UnifiedReputationChange, peer_set::PeerSet, request_response::{request::IncomingRequest, v1 as req_res_v1, Requests}, v1 as protocol_v1}; -use polkadot_node_primitives::{AvailableData, BabeEpoch, BlockWeight, CandidateVotes, CollationGenerationConfig, DisputeMessage, ErasureChunk, PoV, SignedDisputeStatement, SignedFullStatement, ValidationResult, approval::{BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote}}; +use polkadot_node_network_protocol::{ + peer_set::PeerSet, + request_response::{request::IncomingRequest, v1 as req_res_v1, Requests}, + v1 as protocol_v1, PeerId, UnifiedReputationChange, +}; +use polkadot_node_primitives::{ + approval::{BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote}, + AvailableData, BabeEpoch, BlockWeight, CandidateVotes, CollationGenerationConfig, + DisputeMessage, ErasureChunk, PoV, SignedDisputeStatement, SignedFullStatement, + ValidationResult, +}; use polkadot_primitives::v1::{ AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateDescriptor, CandidateEvent, CandidateHash, CandidateIndex, CandidateReceipt, CollatorId, CommittedCandidateReceipt, @@ -222,7 +230,7 @@ pub enum DisputeCoordinatorMessage { /// - or other explicit votes on that candidate already recorded /// - or recovered availability for the candidate /// - or the imported statements are backing/approval votes, which are always accepted. - pending_confirmation: oneshot::Sender + pending_confirmation: oneshot::Sender, }, /// Fetch a list of all recent disputes the co-ordinator is aware of. /// These are disputes which have occurred any time in recent sessions, @@ -252,7 +260,7 @@ pub enum DisputeCoordinatorMessage { block_descriptions: Vec, /// A response channel - `None` to vote on base, `Some` to vote higher. tx: oneshot::Sender>, - } + }, } /// The result of `DisputeCoordinatorMessage::ImportStatements`. @@ -261,7 +269,7 @@ pub enum ImportStatementsResult { /// Import was invalid (candidate was not available) and the sending peer should get banned. InvalidImport, /// Import was valid and can be confirmed to peer. - ValidImport + ValidImport, } /// Messages received by the dispute participation subsystem. @@ -286,7 +294,6 @@ pub enum DisputeParticipationMessage { /// Messages going to the dispute distribution subsystem. #[derive(Debug)] pub enum DisputeDistributionMessage { - /// Tell dispute distribution to distribute an explicit dispute statement to /// validators. SendDispute(DisputeMessage), @@ -350,7 +357,7 @@ pub enum NetworkBridgeMessage { /// Ids of our neighbors in the new gossip topology. /// We're not necessarily connected to all of them, but we should. our_neighbors: HashSet, - } + }, } impl NetworkBridgeMessage { @@ -486,7 +493,13 @@ pub enum AvailabilityStoreMessage { /// If `ValidatorIndex` is present store corresponding chunk also. /// /// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed. - StoreAvailableData(CandidateHash, Option, u32, AvailableData, oneshot::Sender>), + StoreAvailableData( + CandidateHash, + Option, + u32, + AvailableData, + oneshot::Sender>, + ), } impl AvailabilityStoreMessage { @@ -605,11 +618,7 @@ pub enum RuntimeApiRequest { /// Get the validation code for a para, taking the given `OccupiedCoreAssumption`, which /// will inform on how the validation data should be computed if the para currently /// occupies a core. - ValidationCode( - ParaId, - OccupiedCoreAssumption, - RuntimeApiSender>, - ), + ValidationCode(ParaId, OccupiedCoreAssumption, RuntimeApiSender>), /// Get validation code by its hash, either past, current or future code can be returned, as long as state is still /// available. ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender>), @@ -621,10 +630,7 @@ pub enum RuntimeApiRequest { /// Get the session info for the given session, if stored. SessionInfo(SessionIndex, RuntimeApiSender>), /// Get all the pending inbound messages in the downward message queue for a para. - DmqContents( - ParaId, - RuntimeApiSender>>, - ), + DmqContents(ParaId, RuntimeApiSender>>), /// Get the contents of all channels addressed to the given recipient. Channels that have no /// messages in them are also included. InboundHrmpChannelsContents( @@ -764,7 +770,7 @@ pub enum ApprovalCheckResult { /// The vote was accepted and should be propagated onwards. Accepted, /// The vote was bad and should be ignored, reporting the peer who propagated it. - Bad(ApprovalCheckError) + Bad(ApprovalCheckError), } /// The error result type of [`ApprovalVotingMessage::CheckAndImportApproval`] request. @@ -789,7 +795,6 @@ pub enum ApprovalCheckError { Internal(Hash, CandidateHash), } - /// Describes a relay-chain block by the para-chain candidates /// it includes. #[derive(Clone, Debug)] @@ -830,10 +835,7 @@ pub enum ApprovalVotingMessage { /// protocol. /// /// Should not be sent unless the block hash within the indirect vote is known. - CheckAndImportApproval( - IndirectSignedApprovalVote, - oneshot::Sender, - ), + CheckAndImportApproval(IndirectSignedApprovalVote, oneshot::Sender), /// Returns the highest possible ancestor hash of the provided block hash which is /// acceptable to vote on finality for. /// The `BlockNumber` provided is the number of the block's ancestor which is the @@ -864,8 +866,7 @@ pub enum ApprovalDistributionMessage { /// Message to the Gossip Support subsystem. #[derive(Debug)] -pub enum GossipSupportMessage { -} +pub enum GossipSupportMessage {} impl From> for AvailabilityDistributionMessage { fn from(req: IncomingRequest) -> Self { diff --git a/polkadot/node/subsystem-types/src/messages/network_bridge_event.rs b/polkadot/node/subsystem-types/src/messages/network_bridge_event.rs index 173d8ac1632..2b53d0cd0be 100644 --- a/polkadot/node/subsystem-types/src/messages/network_bridge_event.rs +++ b/polkadot/node/subsystem-types/src/messages/network_bridge_event.rs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use std::convert::TryFrom; -use std::collections::HashSet; +use std::{collections::HashSet, convert::TryFrom}; -pub use sc_network::{ReputationChange, PeerId}; +pub use sc_network::{PeerId, ReputationChange}; -use polkadot_node_network_protocol::{WrongVariant, ObservedRole, OurView, View}; +use polkadot_node_network_protocol::{ObservedRole, OurView, View, WrongVariant}; use polkadot_primitives::v1::AuthorityDiscoveryId; /// Events from network. @@ -67,21 +66,23 @@ impl NetworkBridgeEvent { /// in which case the clone can be expensive and it only clones if the message type can /// be focused. pub fn focus<'a, T>(&'a self) -> Result, WrongVariant> - where T: 'a + Clone, &'a T: TryFrom<&'a M, Error = WrongVariant> + where + T: 'a + Clone, + &'a T: TryFrom<&'a M, Error = WrongVariant>, { Ok(match *self { - NetworkBridgeEvent::PeerMessage(ref peer, ref msg) - => NetworkBridgeEvent::PeerMessage(peer.clone(), <&'a T>::try_from(msg)?.clone()), - NetworkBridgeEvent::PeerConnected(ref peer, ref role, ref authority_id) - => NetworkBridgeEvent::PeerConnected(peer.clone(), role.clone(), authority_id.clone()), - NetworkBridgeEvent::PeerDisconnected(ref peer) - => NetworkBridgeEvent::PeerDisconnected(peer.clone()), - NetworkBridgeEvent::NewGossipTopology(ref peers) - => NetworkBridgeEvent::NewGossipTopology(peers.clone()), - NetworkBridgeEvent::PeerViewChange(ref peer, ref view) - => NetworkBridgeEvent::PeerViewChange(peer.clone(), view.clone()), - NetworkBridgeEvent::OurViewChange(ref view) - => NetworkBridgeEvent::OurViewChange(view.clone()), + NetworkBridgeEvent::PeerMessage(ref peer, ref msg) => + NetworkBridgeEvent::PeerMessage(peer.clone(), <&'a T>::try_from(msg)?.clone()), + NetworkBridgeEvent::PeerConnected(ref peer, ref role, ref authority_id) => + NetworkBridgeEvent::PeerConnected(peer.clone(), role.clone(), authority_id.clone()), + NetworkBridgeEvent::PeerDisconnected(ref peer) => + NetworkBridgeEvent::PeerDisconnected(peer.clone()), + NetworkBridgeEvent::NewGossipTopology(ref peers) => + NetworkBridgeEvent::NewGossipTopology(peers.clone()), + NetworkBridgeEvent::PeerViewChange(ref peer, ref view) => + NetworkBridgeEvent::PeerViewChange(peer.clone(), view.clone()), + NetworkBridgeEvent::OurViewChange(ref view) => + NetworkBridgeEvent::OurViewChange(view.clone()), }) } } diff --git a/polkadot/node/subsystem-util/src/determine_new_blocks.rs b/polkadot/node/subsystem-util/src/determine_new_blocks.rs index 9d47592d974..c282472d794 100644 --- a/polkadot/node/subsystem-util/src/determine_new_blocks.rs +++ b/polkadot/node/subsystem-util/src/determine_new_blocks.rs @@ -16,15 +16,9 @@ //! A utility for fetching all unknown blocks based on a new chain-head hash. -use polkadot_node_subsystem::{ - messages::ChainApiMessage, -}; -use polkadot_node_subsystem::{ - SubsystemSender, -}; -use polkadot_primitives::v1::{Hash, Header, BlockNumber}; -use futures::prelude::*; -use futures::channel::oneshot; +use futures::{channel::oneshot, prelude::*}; +use polkadot_node_subsystem::{messages::ChainApiMessage, SubsystemSender}; +use polkadot_primitives::v1::{BlockNumber, Hash, Header}; /// Given a new chain-head hash, this determines the hashes of all new blocks we should track /// metadata for, given this head. @@ -43,7 +37,8 @@ pub async fn determine_new_blocks( head: Hash, header: &Header, lower_bound_number: BlockNumber, -) -> Result, E> where +) -> Result, E> +where Sender: SubsystemSender, { const ANCESTRY_STEP: usize = 4; @@ -57,7 +52,7 @@ pub async fn determine_new_blocks( let before_relevant = header.number < min_block_needed; if already_known || before_relevant { - return Ok(Vec::new()); + return Ok(Vec::new()) } } @@ -66,11 +61,12 @@ pub async fn determine_new_blocks( // Early exit if the parent hash is in the DB or no further blocks // are needed. if is_known(&header.parent_hash)? || header.number == min_block_needed { - return Ok(ancestry); + return Ok(ancestry) } 'outer: loop { - let &(ref last_hash, ref last_header) = ancestry.last() + let &(ref last_hash, ref last_header) = ancestry + .last() .expect("ancestry has length 1 at initialization and is only added to; qed"); assert!( @@ -84,19 +80,22 @@ pub async fn determine_new_blocks( // This is always non-zero as determined by the loop invariant // above. - let ancestry_step = std::cmp::min( - ANCESTRY_STEP, - (last_header.number - min_block_needed) as usize, - ); + let ancestry_step = + std::cmp::min(ANCESTRY_STEP, (last_header.number - min_block_needed) as usize); let batch_hashes = if ancestry_step == 1 { vec![last_header.parent_hash] } else { - sender.send_message(ChainApiMessage::Ancestors { - hash: *last_hash, - k: ancestry_step, - response_channel: tx, - }.into()).await; + sender + .send_message( + ChainApiMessage::Ancestors { + hash: *last_hash, + k: ancestry_step, + response_channel: tx, + } + .into(), + ) + .await; // Continue past these errors. match rx.await { @@ -111,27 +110,31 @@ pub async fn determine_new_blocks( .unzip::<_, _, Vec<_>, Vec<_>>(); for (hash, batched_sender) in batch_hashes.iter().cloned().zip(batch_senders) { - sender.send_message(ChainApiMessage::BlockHeader(hash, batched_sender).into()).await; + sender + .send_message(ChainApiMessage::BlockHeader(hash, batched_sender).into()) + .await; } let mut requests = futures::stream::FuturesOrdered::new(); - batch_receivers.into_iter().map(|rx| async move { - match rx.await { - Err(_) | Ok(Err(_)) => None, - Ok(Ok(h)) => h, - } - }) + batch_receivers + .into_iter() + .map(|rx| async move { + match rx.await { + Err(_) | Ok(Err(_)) => None, + Ok(Ok(h)) => h, + } + }) .for_each(|x| requests.push(x)); - let batch_headers: Vec<_> = requests - .flat_map(|x: Option

| stream::iter(x)) - .collect() - .await; + let batch_headers: Vec<_> = + requests.flat_map(|x: Option
| stream::iter(x)).collect().await; // Any failed header fetch of the batch will yield a `None` result that will // be skipped. Any failure at this stage means we'll just ignore those blocks // as the chain DB has failed us. - if batch_headers.len() != batch_hashes.len() { break 'outer } + if batch_headers.len() != batch_hashes.len() { + break 'outer + } batch_headers }; @@ -159,11 +162,11 @@ pub async fn determine_new_blocks( #[cfg(test)] mod tests { use super::*; - use std::collections::{HashSet, HashMap}; - use sp_core::testing::TaskExecutor; - use polkadot_overseer::{AllMessages, SubsystemContext}; - use polkadot_node_subsystem_test_helpers::make_subsystem_context; use assert_matches::assert_matches; + use polkadot_node_subsystem_test_helpers::make_subsystem_context; + use polkadot_overseer::{AllMessages, SubsystemContext}; + use sp_core::testing::TaskExecutor; + use std::collections::{HashMap, HashSet}; #[derive(Default)] struct TestKnownBlocks { @@ -287,12 +290,11 @@ mod tests { head_hash, &head, lower_bound_number, - ).await.unwrap(); + ) + .await + .unwrap(); - assert_eq!( - ancestry, - expected_ancestry, - ); + assert_eq!(ancestry, expected_ancestry,); }); let aux_fut = Box::pin(async move { @@ -361,12 +363,11 @@ mod tests { head_hash, &head, lower_bound_number, - ).await.unwrap(); + ) + .await + .unwrap(); - assert_eq!( - ancestry, - expected_ancestry, - ); + assert_eq!(ancestry, expected_ancestry,); }); let aux_fut = Box::pin(async move { @@ -421,12 +422,11 @@ mod tests { head_hash, &head, lower_bound_number, - ).await.unwrap(); + ) + .await + .unwrap(); - assert_eq!( - ancestry, - expected_ancestry, - ); + assert_eq!(ancestry, expected_ancestry,); }); futures::executor::block_on(test_fut); @@ -458,12 +458,11 @@ mod tests { head_hash, &head, lower_bound_number, - ).await.unwrap(); + ) + .await + .unwrap(); - assert_eq!( - ancestry, - expected_ancestry, - ); + assert_eq!(ancestry, expected_ancestry,); }); futures::executor::block_on(test_fut); @@ -484,44 +483,26 @@ mod tests { known.insert(parent_hash); let test_fut = Box::pin(async move { - let after_finality = determine_new_blocks( - ctx.sender(), - |h| known.is_known(h), - head_hash, - &head, - 17, - ).await.unwrap(); + let after_finality = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 17) + .await + .unwrap(); - let at_finality = determine_new_blocks( - ctx.sender(), - |h| known.is_known(h), - head_hash, - &head, - 18, - ).await.unwrap(); + let at_finality = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 18) + .await + .unwrap(); - let before_finality = determine_new_blocks( - ctx.sender(), - |h| known.is_known(h), - head_hash, - &head, - 19, - ).await.unwrap(); + let before_finality = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 19) + .await + .unwrap(); - assert_eq!( - after_finality, - vec![(head_hash, head.clone())], - ); + assert_eq!(after_finality, vec![(head_hash, head.clone())],); - assert_eq!( - at_finality, - Vec::new(), - ); + assert_eq!(at_finality, Vec::new(),); - assert_eq!( - before_finality, - Vec::new(), - ); + assert_eq!(before_finality, Vec::new(),); }); futures::executor::block_on(test_fut); @@ -544,13 +525,10 @@ mod tests { .collect::>(); let test_fut = Box::pin(async move { - let ancestry = determine_new_blocks( - ctx.sender(), - |h| known.is_known(h), - head_hash, - &head, - 0, - ).await.unwrap(); + let ancestry = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 0) + .await + .unwrap(); assert_eq!(ancestry, expected_ancestry); }); @@ -585,13 +563,10 @@ mod tests { .collect::>(); let test_fut = Box::pin(async move { - let ancestry = determine_new_blocks( - ctx.sender(), - |h| known.is_known(h), - head_hash, - &head, - 0, - ).await.unwrap(); + let ancestry = + determine_new_blocks(ctx.sender(), |h| known.is_known(h), head_hash, &head, 0) + .await + .unwrap(); assert_eq!(ancestry, expected_ancestry); }); diff --git a/polkadot/node/subsystem-util/src/error_handling.rs b/polkadot/node/subsystem-util/src/error_handling.rs index 6b7ca312ff9..3660b045413 100644 --- a/polkadot/node/subsystem-util/src/error_handling.rs +++ b/polkadot/node/subsystem-util/src/error_handling.rs @@ -64,14 +64,14 @@ use thiserror::Error; /// Self(Fault::from_non_fatal(e)) /// } /// } -/// +/// /// // Make an Error from a `Fatal` one. /// impl From for Error { /// fn from(f: Fatal) -> Self { /// Self(Fault::from_fatal(f)) /// } /// } -/// +/// /// // Easy conversion from sub error types from other modules: /// impl From for Error { /// fn from(o: runtime::Error) -> Self { @@ -107,9 +107,10 @@ use thiserror::Error; /// ``` #[derive(Debug, Error)] pub enum Fault - where - E: std::fmt::Debug + std::error::Error + 'static, - F: std::fmt::Debug + std::error::Error + 'static, { +where + E: std::fmt::Debug + std::error::Error + 'static, + F: std::fmt::Debug + std::error::Error + 'static, +{ /// Error is fatal and should be escalated up. /// /// While we usually won't want to pattern match on those, a concrete descriptive enum might @@ -126,9 +127,9 @@ pub enum Fault /// `From::from` implementations. So no auto conversions by default, a simple `Result::map_err` is /// not too bad though. impl Fault - where - E: std::fmt::Debug + std::error::Error + 'static, - F: std::fmt::Debug + std::error::Error + 'static, +where + E: std::fmt::Debug + std::error::Error + 'static, + F: std::fmt::Debug + std::error::Error + 'static, { /// Build an `Fault` from compatible fatal error. pub fn from_fatal>(f: F1) -> Self { @@ -188,10 +189,10 @@ impl Fault /// } /// /// ``` -pub fn unwrap_non_fatal(result: Result<(), Fault>) -> Result, F> - where - E: std::fmt::Debug + std::error::Error + 'static, - F: std::fmt::Debug + std::error::Error + Send + Sync + 'static +pub fn unwrap_non_fatal(result: Result<(), Fault>) -> Result, F> +where + E: std::fmt::Debug + std::error::Error + 'static, + F: std::fmt::Debug + std::error::Error + Send + Sync + 'static, { match result { Ok(()) => Ok(None), diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs index 1fb1a4d124f..b8fbd9c4694 100644 --- a/polkadot/node/subsystem-util/src/lib.rs +++ b/polkadot/node/subsystem-util/src/lib.rs @@ -25,53 +25,48 @@ #![warn(missing_docs)] use polkadot_node_subsystem::{ - overseer, - errors::RuntimeApiError, + errors::{RuntimeApiError, SubsystemError}, messages::{ - AllMessages, - RuntimeApiMessage, - RuntimeApiRequest, - RuntimeApiSender, - BoundToRelayParent, + AllMessages, BoundToRelayParent, RuntimeApiMessage, RuntimeApiRequest, RuntimeApiSender, }, - ActiveLeavesUpdate, OverseerSignal, + overseer, ActiveLeavesUpdate, FromOverseer, OverseerSignal, SpawnedSubsystem, SubsystemContext, SubsystemSender, - errors::{ - SubsystemError, - }, - SubsystemContext, - SpawnedSubsystem, - FromOverseer, }; pub use overseer::{ - Subsystem, - TimeoutExt, - gen::OverseerError, - gen::Timeout, + gen::{OverseerError, Timeout}, + Subsystem, TimeoutExt, }; -pub use polkadot_node_metrics::{ - Metronome, - metrics, -}; +pub use polkadot_node_metrics::{metrics, Metronome}; -use polkadot_node_jaeger as jaeger; -use futures::{channel::{mpsc, oneshot}, prelude::*, select, stream::{Stream, SelectAll}}; +use futures::{ + channel::{mpsc, oneshot}, + prelude::*, + select, + stream::{SelectAll, Stream}, +}; use parity_scale_codec::Encode; use pin_project::pin_project; +use polkadot_node_jaeger as jaeger; use polkadot_primitives::v1::{ - CandidateEvent, CommittedCandidateReceipt, CoreState, EncodeAs, PersistedValidationData, - GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, - SessionIndex, Signed, SigningContext, ValidationCode, ValidatorId, ValidatorIndex, SessionInfo, -AuthorityDiscoveryId, GroupIndex, + AuthorityDiscoveryId, CandidateEvent, CommittedCandidateReceipt, CoreState, EncodeAs, + GroupIndex, GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, + PersistedValidationData, SessionIndex, SessionInfo, Signed, SigningContext, ValidationCode, + ValidatorId, ValidatorIndex, }; -use sp_core::{traits::SpawnNamed, Public}; use sp_application_crypto::AppKey; -use sp_keystore::{CryptoStore, SyncCryptoStorePtr, Error as KeystoreError}; +use sp_core::{traits::SpawnNamed, Public}; +use sp_keystore::{CryptoStore, Error as KeystoreError, SyncCryptoStorePtr}; use std::{ - collections::{HashMap, hash_map::Entry}, convert::TryFrom, marker::Unpin, pin::Pin, task::{Poll, Context}, - time::Duration, fmt, sync::Arc, + collections::{hash_map::Entry, HashMap}, + convert::TryFrom, + fmt, + marker::Unpin, + pin::Pin, + sync::Arc, + task::{Context, Poll}, + time::Duration, }; use thiserror::Error; @@ -80,22 +75,17 @@ pub use polkadot_node_network_protocol::MIN_GOSSIP_PEERS; pub use determine_new_blocks::determine_new_blocks; /// Error classification. -pub use error_handling::{Fault, unwrap_non_fatal}; +pub use error_handling::{unwrap_non_fatal, Fault}; /// These reexports are required so that external crates can use the `delegated_subsystem` macro properly. pub mod reexports { - pub use polkadot_overseer::gen::{ - SpawnNamed, - SpawnedSubsystem, - Subsystem, - SubsystemContext, - }; + pub use polkadot_overseer::gen::{SpawnNamed, SpawnedSubsystem, Subsystem, SubsystemContext}; } -/// Convenient and efficient runtime info access. -pub mod runtime; /// A rolling session window cache. pub mod rolling_session_window; +/// Convenient and efficient runtime info access. +pub mod runtime; mod determine_new_blocks; mod error_handling; @@ -158,7 +148,9 @@ where { let (tx, rx) = oneshot::channel(); - sender.send_message(RuntimeApiMessage::Request(parent, request_builder(tx)).into()).await; + sender + .send_message(RuntimeApiMessage::Request(parent, request_builder(tx)).into()) + .await; rx } @@ -225,39 +217,48 @@ specialize_requests! { } /// From the given set of validators, find the first key we can sign with, if any. -pub async fn signing_key(validators: &[ValidatorId], keystore: &SyncCryptoStorePtr) - -> Option -{ +pub async fn signing_key( + validators: &[ValidatorId], + keystore: &SyncCryptoStorePtr, +) -> Option { signing_key_and_index(validators, keystore).await.map(|(k, _)| k) } /// From the given set of validators, find the first key we can sign with, if any, and return it /// along with the validator index. -pub async fn signing_key_and_index(validators: &[ValidatorId], keystore: &SyncCryptoStorePtr) - -> Option<(ValidatorId, ValidatorIndex)> -{ +pub async fn signing_key_and_index( + validators: &[ValidatorId], + keystore: &SyncCryptoStorePtr, +) -> Option<(ValidatorId, ValidatorIndex)> { for (i, v) in validators.iter().enumerate() { if CryptoStore::has_keys(&**keystore, &[(v.to_raw_vec(), ValidatorId::ID)]).await { - return Some((v.clone(), ValidatorIndex(i as _))); + return Some((v.clone(), ValidatorIndex(i as _))) } } None } /// Find the validator group the given validator index belongs to. -pub fn find_validator_group(groups: &[Vec], index: ValidatorIndex) - -> Option -{ - groups.iter().enumerate().find_map(|(i, g)| if g.contains(&index) { - Some(GroupIndex(i as _)) - } else { - None +pub fn find_validator_group( + groups: &[Vec], + index: ValidatorIndex, +) -> Option { + groups.iter().enumerate().find_map(|(i, g)| { + if g.contains(&index) { + Some(GroupIndex(i as _)) + } else { + None + } }) } /// Choose a random subset of `min` elements. /// But always include `is_priority` elements. -pub fn choose_random_subset bool>(is_priority: F, mut v: Vec, min: usize) -> Vec { +pub fn choose_random_subset bool>( + is_priority: F, + mut v: Vec, + min: usize, +) -> Vec { use rand::seq::SliceRandom as _; // partition the elements into priority first @@ -266,7 +267,7 @@ pub fn choose_random_subset bool>(is_priority: F, mut v: Vec< if i >= min || v.len() <= i { v.truncate(i); - return v; + return v } let mut rng = rand::thread_rng(); @@ -300,8 +301,7 @@ impl Validator { parent: Hash, keystore: SyncCryptoStorePtr, sender: &mut impl SubsystemSender, - ) -> Result - { + ) -> Result { // Note: request_validators and request_session_index_for_child do not and cannot // run concurrently: they both have a mutable handle to the same sender. // However, each of them returns a oneshot::Receiver, and those are resolved concurrently. @@ -310,10 +310,7 @@ impl Validator { request_session_index_for_child(parent, sender).await, )?; - let signing_context = SigningContext { - session_index: session_index?, - parent_hash: parent, - }; + let signing_context = SigningContext { session_index: session_index?, parent_hash: parent }; let validators = validators?; @@ -328,15 +325,10 @@ impl Validator { signing_context: SigningContext, keystore: SyncCryptoStorePtr, ) -> Result { - let (key, index) = signing_key_and_index(validators, &keystore) - .await - .ok_or(Error::NotAValidator)?; + let (key, index) = + signing_key_and_index(validators, &keystore).await.ok_or(Error::NotAValidator)?; - Ok(Validator { - signing_context, - key, - index, - }) + Ok(Validator { signing_context, key, index }) } /// Get this validator's id. @@ -403,10 +395,7 @@ pub struct JobSender { // which `#[derive(Clone)]` requires. impl Clone for JobSender { fn clone(&self) -> Self { - Self { - sender: self.sender.clone(), - from_job: self.from_job.clone(), - } + Self { sender: self.sender.clone(), from_job: self.from_job.clone() } } } @@ -424,13 +413,13 @@ impl JobSender { /// Send multiple direct messages to other `Subsystem`s, routed based on message type. pub async fn send_messages(&mut self, msgs: T) where - T: IntoIterator + Send, T::IntoIter: Send, + T: IntoIterator + Send, + T::IntoIter: Send, M: Into, { self.sender.send_messages(msgs.into_iter().map(|m| m.into())).await } - /// Send a message onto the unbounded queue of some other `Subsystem`, routed based on message /// type. /// @@ -446,7 +435,6 @@ impl JobSender { } } - #[async_trait::async_trait] impl overseer::SubsystemSender for JobSender where @@ -458,7 +446,9 @@ where } async fn send_messages(&mut self, msgs: T) - where T: IntoIterator + Send, T::IntoIter: Send + where + T: IntoIterator + Send, + T::IntoIter: Send, { self.sender.send_messages(msgs.into_iter().map(|m| m.into())).await } @@ -547,11 +537,7 @@ where { /// Create a new Jobs manager which handles spawning appropriate jobs. pub fn new(spawner: Spawner) -> Self { - Self { - spawner, - running: HashMap::new(), - outgoing_msgs: SelectAll::new(), - } + Self { spawner, running: HashMap::new(), outgoing_msgs: SelectAll::new() } } /// Spawn a new job for this `parent_hash`, with whatever args are appropriate. @@ -562,10 +548,9 @@ where run_args: Job::RunArgs, metrics: Job::Metrics, sender: Sender, - ) - where - Job: JobTrait, - Sender: SubsystemSender, + ) where + Job: JobTrait, + Sender: SubsystemSender, { let (to_job_tx, to_job_rx) = mpsc::channel(JOB_CHANNEL_CAPACITY); let (from_job_tx, from_job_rx) = mpsc::channel(JOB_CHANNEL_CAPACITY); @@ -577,11 +562,10 @@ where run_args, metrics, to_job_rx, - JobSender { - sender, - from_job: from_job_tx, - }, - ).await { + JobSender { sender, from_job: from_job_tx }, + ) + .await + { tracing::error!( job = Job::NAME, parent_hash = %parent_hash, @@ -589,7 +573,7 @@ where "job finished with an error", ); - return Err(e); + return Err(e) } Ok(()) @@ -598,10 +582,7 @@ where self.spawner.spawn(Job::NAME, future.map(drop).boxed()); self.outgoing_msgs.push(from_job_rx); - let handle = JobHandle { - _abort_handle: AbortOnDrop(abort_handle), - to_job: to_job_tx, - }; + let handle = JobHandle { _abort_handle: AbortOnDrop(abort_handle), to_job: to_job_tx }; self.running.insert(parent_hash, handle); } @@ -672,34 +653,24 @@ impl JobSubsystem { /// Create a new `JobSubsystem`. pub fn new(spawner: Spawner, run_args: Job::RunArgs, metrics: Job::Metrics) -> Self { JobSubsystem { - params: JobSubsystemParams { - spawner, - run_args, - metrics, - }, + params: JobSubsystemParams { spawner, run_args, metrics }, _marker: std::marker::PhantomData, } } /// Run the subsystem to completion. pub async fn run(self, mut ctx: Context) - where - Spawner: SpawnNamed + Send + Clone + Unpin + 'static, - Context: SubsystemContext::ToJob, Signal=OverseerSignal>, - ::Sender: SubsystemSender, - Job: 'static + JobTrait + Send, - ::RunArgs: Clone + Sync, - ::ToJob: Sync + From<::Message>, - ::Metrics: Sync, + where + Spawner: SpawnNamed + Send + Clone + Unpin + 'static, + Context: SubsystemContext::ToJob, Signal = OverseerSignal>, + ::Sender: SubsystemSender, + Job: 'static + JobTrait + Send, + ::RunArgs: Clone + Sync, + ::ToJob: + Sync + From<::Message>, + ::Metrics: Sync, { - let JobSubsystem { - params: JobSubsystemParams { - spawner, - run_args, - metrics, - }, - .. - } = self; + let JobSubsystem { params: JobSubsystemParams { spawner, run_args, metrics }, .. } = self; let mut jobs = Jobs::::new(spawner); @@ -768,10 +739,11 @@ impl JobSubsystem { impl Subsystem for JobSubsystem where Spawner: SpawnNamed + Send + Clone + Unpin + 'static, - Context: SubsystemContext, + Context: SubsystemContext, Job: 'static + JobTrait + Send, Job::RunArgs: Clone + Sync, - ::ToJob: Sync + From<::Message>, + ::ToJob: + Sync + From<::Message>, Job::Metrics: Sync, { fn start(self, ctx: Context) -> SpawnedSubsystem { @@ -780,9 +752,6 @@ where Ok(()) }); - SpawnedSubsystem { - name: Job::NAME.strip_suffix("Job").unwrap_or(Job::NAME), - future, - } + SpawnedSubsystem { name: Job::NAME.strip_suffix("Job").unwrap_or(Job::NAME), future } } } diff --git a/polkadot/node/subsystem-util/src/rolling_session_window.rs b/polkadot/node/subsystem-util/src/rolling_session_window.rs index 944fe0c0548..1ffd79072bf 100644 --- a/polkadot/node/subsystem-util/src/rolling_session_window.rs +++ b/polkadot/node/subsystem-util/src/rolling_session_window.rs @@ -19,15 +19,14 @@ //! This is useful for consensus components which need to stay up-to-date about recent sessions but don't //! care about the state of particular blocks. -use polkadot_primitives::v1::{Hash, Header, SessionInfo, SessionIndex}; +use polkadot_primitives::v1::{Hash, Header, SessionIndex, SessionInfo}; +use futures::channel::oneshot; use polkadot_node_subsystem::{ - overseer, - messages::{RuntimeApiMessage, RuntimeApiRequest}, errors::RuntimeApiError, - SubsystemContext, + messages::{RuntimeApiMessage, RuntimeApiRequest}, + overseer, SubsystemContext, }; -use futures::channel::oneshot; /// Sessions unavailable in state to cache. #[derive(Debug)] @@ -96,11 +95,7 @@ pub struct RollingSessionWindow { impl RollingSessionWindow { /// Initialize a new session info cache with the given window size. pub fn new(window_size: SessionIndex) -> Self { - RollingSessionWindow { - earliest_session: None, - session_info: Vec::new(), - window_size, - } + RollingSessionWindow { earliest_session: None, session_info: Vec::new(), window_size } } /// Initialize a new session info cache with the given window size and @@ -110,11 +105,7 @@ impl RollingSessionWindow { earliest_session: SessionIndex, session_info: Vec, ) -> Self { - RollingSessionWindow { - earliest_session: Some(earliest_session), - session_info, - window_size, - } + RollingSessionWindow { earliest_session: Some(earliest_session), session_info, window_size } } /// Access the session info for the given session index, if stored within the window. @@ -126,7 +117,6 @@ impl RollingSessionWindow { self.session_info.get((index - earliest) as usize) } }) - } /// Access the index of the earliest session, if the window is not empty. @@ -153,7 +143,9 @@ impl RollingSessionWindow { block_hash: Hash, block_header: &Header, ) -> Result { - if self.window_size == 0 { return Ok(SessionWindowUpdate::Unchanged) } + if self.window_size == 0 { + return Ok(SessionWindowUpdate::Unchanged) + } let session_index = { let (s_tx, s_rx) = oneshot::channel(); @@ -164,18 +156,21 @@ impl RollingSessionWindow { ctx.send_message(RuntimeApiMessage::Request( if block_header.number == 0 { block_hash } else { block_header.parent_hash }, RuntimeApiRequest::SessionIndexForChild(s_tx), - )).await; + )) + .await; match s_rx.await { Ok(Ok(s)) => s, - Ok(Err(e)) => return Err(SessionsUnavailable { - kind: SessionsUnavailableKind::RuntimeApi(e), - info: None, - }), - Err(e) => return Err(SessionsUnavailable { - kind: SessionsUnavailableKind::RuntimeApiUnavailable(e), - info: None, - }), + Ok(Err(e)) => + return Err(SessionsUnavailable { + kind: SessionsUnavailableKind::RuntimeApi(e), + info: None, + }), + Err(e) => + return Err(SessionsUnavailable { + kind: SessionsUnavailableKind::RuntimeApiUnavailable(e), + info: None, + }), } }; @@ -186,16 +181,14 @@ impl RollingSessionWindow { let window_start = session_index.saturating_sub(self.window_size - 1); match load_all_sessions(ctx, block_hash, window_start, session_index).await { - Err(kind) => { - Err(SessionsUnavailable { - kind, - info: Some(SessionsUnavailableInfo { - window_start, - window_end: session_index, - block_hash, - }), - }) - }, + Err(kind) => Err(SessionsUnavailable { + kind, + info: Some(SessionsUnavailableInfo { + window_start, + window_end: session_index, + block_hash, + }), + }), Ok(s) => { let update = SessionWindowUpdate::Initialized { window_start, @@ -206,14 +199,17 @@ impl RollingSessionWindow { self.session_info = s; Ok(update) - } + }, } - } + }, Some(old_window_start) => { - let latest = self.latest_session().expect("latest always exists if earliest does; qed"); + let latest = + self.latest_session().expect("latest always exists if earliest does; qed"); // Either cached or ancient. - if session_index <= latest { return Ok(SessionWindowUpdate::Unchanged) } + if session_index <= latest { + return Ok(SessionWindowUpdate::Unchanged) + } let old_window_end = latest; @@ -222,23 +218,17 @@ impl RollingSessionWindow { // keep some of the old window, if applicable. let overlap_start = window_start.saturating_sub(old_window_start); - let fresh_start = if latest < window_start { - window_start - } else { - latest + 1 - }; + let fresh_start = if latest < window_start { window_start } else { latest + 1 }; match load_all_sessions(ctx, block_hash, fresh_start, session_index).await { - Err(kind) => { - Err(SessionsUnavailable { - kind, - info: Some(SessionsUnavailableInfo { - window_start: fresh_start, - window_end: session_index, - block_hash, - }), - }) - }, + Err(kind) => Err(SessionsUnavailable { + kind, + info: Some(SessionsUnavailableInfo { + window_start: fresh_start, + window_end: session_index, + block_hash, + }), + }), Ok(s) => { let update = SessionWindowUpdate::Advanced { prev_window_start: old_window_start, @@ -247,7 +237,8 @@ impl RollingSessionWindow { new_window_end: session_index, }; - let outdated = std::cmp::min(overlap_start as usize, self.session_info.len()); + let outdated = + std::cmp::min(overlap_start as usize, self.session_info.len()); self.session_info.drain(..outdated); self.session_info.extend(s); // we need to account for this case: @@ -257,9 +248,9 @@ impl RollingSessionWindow { self.earliest_session = Some(new_earliest); Ok(update) - } + }, } - } + }, } } } @@ -272,17 +263,16 @@ async fn load_all_sessions( ) -> Result, SessionsUnavailableKind> { let mut v = Vec::new(); for i in start..=end_inclusive { - let (tx, rx)= oneshot::channel(); + let (tx, rx) = oneshot::channel(); ctx.send_message(RuntimeApiMessage::Request( block_hash, RuntimeApiRequest::SessionInfo(i, tx), - )).await; + )) + .await; let session_info = match rx.await { Ok(Ok(Some(s))) => s, - Ok(Ok(None)) => { - return Err(SessionsUnavailableKind::Missing); - } + Ok(Ok(None)) => return Err(SessionsUnavailableKind::Missing), Ok(Err(e)) => return Err(SessionsUnavailableKind::RuntimeApi(e)), Err(canceled) => return Err(SessionsUnavailableKind::RuntimeApiUnavailable(canceled)), }; @@ -296,10 +286,10 @@ async fn load_all_sessions( #[cfg(test)] mod tests { use super::*; - use polkadot_node_subsystem_test_helpers::make_subsystem_context; + use assert_matches::assert_matches; use polkadot_node_subsystem::messages::{AllMessages, AvailabilityRecoveryMessage}; + use polkadot_node_subsystem_test_helpers::make_subsystem_context; use sp_core::testing::TaskExecutor; - use assert_matches::assert_matches; const TEST_WINDOW_SIZE: SessionIndex = 6; @@ -333,18 +323,15 @@ mod tests { }; let pool = TaskExecutor::new(); - let (mut ctx, mut handle) = make_subsystem_context::(pool.clone()); + let (mut ctx, mut handle) = + make_subsystem_context::(pool.clone()); let hash = header.hash(); let test_fut = { let header = header.clone(); Box::pin(async move { - window.cache_session_info_for_head( - &mut ctx, - hash, - &header, - ).await.unwrap(); + window.cache_session_info_for_head(&mut ctx, hash, &header).await.unwrap(); assert_eq!(window.earliest_session, Some(expected_start_session)); assert_eq!( @@ -386,12 +373,7 @@ mod tests { #[test] fn cache_session_info_first_early() { - cache_session_info_test( - 0, - 1, - RollingSessionWindow::new(TEST_WINDOW_SIZE), - 0, - ); + cache_session_info_test(0, 1, RollingSessionWindow::new(TEST_WINDOW_SIZE), 0); } #[test] @@ -402,12 +384,7 @@ mod tests { window_size: TEST_WINDOW_SIZE, }; - cache_session_info_test( - 1, - 2, - window, - 2, - ); + cache_session_info_test(1, 2, window, 2); } #[test] @@ -424,7 +401,11 @@ mod tests { fn cache_session_info_jump() { let window = RollingSessionWindow { earliest_session: Some(50), - session_info: vec![dummy_session_info(50), dummy_session_info(51), dummy_session_info(52)], + session_info: vec![ + dummy_session_info(50), + dummy_session_info(51), + dummy_session_info(52), + ], window_size: TEST_WINDOW_SIZE, }; @@ -480,10 +461,7 @@ mod tests { }; cache_session_info_test( - 0, - 2, - window, - 2, // should only make one request. + 0, 2, window, 2, // should only make one request. ); } @@ -496,12 +474,7 @@ mod tests { window_size: TEST_WINDOW_SIZE, }; - cache_session_info_test( - 0, - 3, - window, - 2, - ); + cache_session_info_test(0, 3, window, 2); } #[test] @@ -526,11 +499,7 @@ mod tests { let test_fut = { let header = header.clone(); Box::pin(async move { - let res = window.cache_session_info_for_head( - &mut ctx, - hash, - &header, - ).await; + let res = window.cache_session_info_for_head(&mut ctx, hash, &header).await; assert!(res.is_err()); }) @@ -592,17 +561,10 @@ mod tests { let test_fut = { let header = header.clone(); Box::pin(async move { - window.cache_session_info_for_head( - &mut ctx, - hash, - &header, - ).await.unwrap(); + window.cache_session_info_for_head(&mut ctx, hash, &header).await.unwrap(); assert_eq!(window.earliest_session, Some(session)); - assert_eq!( - window.session_info, - vec![dummy_session_info(session)], - ); + assert_eq!(window.session_info, vec![dummy_session_info(session)],); }) }; diff --git a/polkadot/node/subsystem-util/src/runtime/error.rs b/polkadot/node/subsystem-util/src/runtime/error.rs index 94cbe05e945..ff458434082 100644 --- a/polkadot/node/subsystem-util/src/runtime/error.rs +++ b/polkadot/node/subsystem-util/src/runtime/error.rs @@ -17,8 +17,8 @@ //! Error handling related code and Error/Result definitions. -use thiserror::Error; use futures::channel::oneshot; +use thiserror::Error; use polkadot_node_subsystem::errors::RuntimeApiError; use polkadot_primitives::v1::SessionIndex; @@ -67,7 +67,8 @@ pub enum NonFatal { pub(crate) async fn recv_runtime( r: oneshot::Receiver>, ) -> Result { - let result = r.await + let result = r + .await .map_err(Fatal::RuntimeRequestCanceled)? .map_err(NonFatal::RuntimeRequest)?; Ok(result) diff --git a/polkadot/node/subsystem-util/src/runtime/mod.rs b/polkadot/node/subsystem-util/src/runtime/mod.rs index 1dd8465afb5..e1ac19e0e8f 100644 --- a/polkadot/node/subsystem-util/src/runtime/mod.rs +++ b/polkadot/node/subsystem-util/src/runtime/mod.rs @@ -25,13 +25,14 @@ use sp_application_crypto::AppKey; use sp_core::crypto::Public; use sp_keystore::{CryptoStore, SyncCryptoStorePtr}; -use polkadot_primitives::v1::{CoreState, EncodeAs, GroupIndex, GroupRotationInfo, Hash, OccupiedCore, SessionIndex, SessionInfo, Signed, SigningContext, UncheckedSigned, ValidatorId, ValidatorIndex}; -use polkadot_node_subsystem::{SubsystemSender, SubsystemContext}; - +use polkadot_node_subsystem::{SubsystemContext, SubsystemSender}; +use polkadot_primitives::v1::{ + CoreState, EncodeAs, GroupIndex, GroupRotationInfo, Hash, OccupiedCore, SessionIndex, + SessionInfo, Signed, SigningContext, UncheckedSigned, ValidatorId, ValidatorIndex, +}; use crate::{ - request_session_index_for_child, request_session_info, - request_availability_cores, + request_availability_cores, request_session_index_for_child, request_session_info, request_validator_groups, }; @@ -39,7 +40,7 @@ use crate::{ mod error; use error::{recv_runtime, Result}; -pub use error::{Error, NonFatal, Fatal}; +pub use error::{Error, Fatal, NonFatal}; /// Configuration for construction a `RuntimeInfo`. pub struct Config { @@ -100,10 +101,7 @@ impl Default for Config { impl RuntimeInfo { /// Create a new `RuntimeInfo` for convenient runtime fetches. pub fn new(keystore: Option) -> Self { - Self::new_with_config(Config { - keystore, - ..Default::default() - }) + Self::new_with_config(Config { keystore, ..Default::default() }) } /// Create with more elaborate configuration options. @@ -128,11 +126,10 @@ impl RuntimeInfo { Some(index) => Ok(*index), None => { let index = - recv_runtime(request_session_index_for_child(parent, sender).await) - .await?; + recv_runtime(request_session_index_for_child(parent, sender).await).await?; self.session_index_cache.put(parent, index); Ok(index) - } + }, } } @@ -170,17 +167,14 @@ impl RuntimeInfo { .ok_or(NonFatal::NoSuchSession(session_index))?; let validator_info = self.get_validator_info(&session_info).await?; - let full_info = ExtendedSessionInfo { - session_info, - validator_info, - }; + let full_info = ExtendedSessionInfo { session_info, validator_info }; self.session_info_cache.put(session_index, full_info); } - Ok( - self.session_info_cache.get(&session_index) - .expect("We just put the value there. qed.") - ) + Ok(self + .session_info_cache + .get(&session_index) + .expect("We just put the value there. qed.")) } /// Convenience function for checking the signature of something signed. @@ -189,7 +183,9 @@ impl RuntimeInfo { sender: &mut Sender, parent: Hash, signed: UncheckedSigned, - ) -> Result, UncheckedSigned>> + ) -> Result< + std::result::Result, UncheckedSigned>, + > where Sender: SubsystemSender, Payload: EncodeAs + Clone, @@ -204,17 +200,11 @@ impl RuntimeInfo { /// /// /// Returns: `None` if not a validator. - async fn get_validator_info( - &self, - session_info: &SessionInfo, - ) -> Result - { + async fn get_validator_info(&self, session_info: &SessionInfo) -> Result { if let Some(our_index) = self.get_our_index(&session_info.validators).await { // Get our group index: - let our_group = session_info.validator_groups - .iter() - .enumerate() - .find_map(|(i, g)| { + let our_group = + session_info.validator_groups.iter().enumerate().find_map(|(i, g)| { g.iter().find_map(|v| { if *v == our_index { Some(GroupIndex(i as u32)) @@ -222,12 +212,8 @@ impl RuntimeInfo { None } }) - } - ); - let info = ValidatorInfo { - our_index: Some(our_index), - our_group, - }; + }); + let info = ValidatorInfo { our_index: Some(our_index), our_group }; return Ok(info) } return Ok(ValidatorInfo { our_index: None, our_group: None }) @@ -239,10 +225,8 @@ impl RuntimeInfo { async fn get_our_index(&self, validators: &[ValidatorId]) -> Option { let keystore = self.keystore.as_ref()?; for (i, v) in validators.iter().enumerate() { - if CryptoStore::has_keys(&**keystore, &[(v.to_raw_vec(), ValidatorId::ID)]) - .await - { - return Some(ValidatorIndex(i as u32)); + if CryptoStore::has_keys(&**keystore, &[(v.to_raw_vec(), ValidatorId::ID)]).await { + return Some(ValidatorIndex(i as u32)) } } None @@ -260,22 +244,22 @@ where Payload: EncodeAs + Clone, RealPayload: Encode + Clone, { - let signing_context = SigningContext { - session_index, - parent_hash: relay_parent, - }; + let signing_context = SigningContext { session_index, parent_hash: relay_parent }; - session_info.validators + session_info + .validators .get(signed.unchecked_validator_index().0 as usize) .ok_or_else(|| signed.clone()) .and_then(|v| signed.try_into_checked(&signing_context, v)) } /// Request availability cores from the runtime. -pub async fn get_availability_cores(ctx: &mut Context, relay_parent: Hash) - -> Result> - where - Context: SubsystemContext, +pub async fn get_availability_cores( + ctx: &mut Context, + relay_parent: Hash, +) -> Result> +where + Context: SubsystemContext, { recv_runtime(request_availability_cores(relay_parent, ctx.sender()).await).await } @@ -299,18 +283,20 @@ where None } }) - .collect() - ) + .collect()) } /// Get group rotation info based on the given `relay_parent`. -pub async fn get_group_rotation_info(ctx: &mut Context, relay_parent: Hash) - -> Result +pub async fn get_group_rotation_info( + ctx: &mut Context, + relay_parent: Hash, +) -> Result where Context: SubsystemContext, { // We drop `groups` here as we don't need them, because of `RuntimeInfo`. Ideally we would not // fetch them in the first place. - let (_, info) = recv_runtime(request_validator_groups(relay_parent, ctx.sender()).await).await?; + let (_, info) = + recv_runtime(request_validator_groups(relay_parent, ctx.sender()).await).await?; Ok(info) } diff --git a/polkadot/node/subsystem-util/src/tests.rs b/polkadot/node/subsystem-util/src/tests.rs index 828d47baed1..83cd18c3f2e 100644 --- a/polkadot/node/subsystem-util/src/tests.rs +++ b/polkadot/node/subsystem-util/src/tests.rs @@ -15,18 +15,25 @@ // along with Polkadot. If not, see . use super::*; +use assert_matches::assert_matches; use executor::block_on; -use thiserror::Error; +use futures::{channel::mpsc, executor, future, Future, FutureExt, SinkExt, StreamExt}; use polkadot_node_jaeger as jaeger; use polkadot_node_subsystem::{ - messages::{AllMessages, CollatorProtocolMessage}, ActiveLeavesUpdate, FromOverseer, OverseerSignal, - SpawnedSubsystem, ActivatedLeaf, LeafStatus, + messages::{AllMessages, CollatorProtocolMessage}, + ActivatedLeaf, ActiveLeavesUpdate, FromOverseer, LeafStatus, OverseerSignal, SpawnedSubsystem, }; -use assert_matches::assert_matches; -use futures::{channel::mpsc, executor, StreamExt, future, Future, FutureExt, SinkExt}; -use polkadot_primitives::v1::Hash; use polkadot_node_subsystem_test_helpers::{self as test_helpers, make_subsystem_context}; -use std::{pin::Pin, sync::{Arc, atomic::{AtomicUsize, Ordering}}, time::Duration}; +use polkadot_primitives::v1::Hash; +use std::{ + pin::Pin, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + time::Duration, +}; +use thiserror::Error; // basic usage: in a nutshell, when you want to define a subsystem, just focus on what its jobs do; // you can leave the subsystem itself to the job manager. @@ -46,7 +53,7 @@ struct FakeCollatorProtocolJob { #[derive(Debug, Error)] enum Error { #[error(transparent)] - Sending(#[from]mpsc::SendError), + Sending(#[from] mpsc::SendError), } impl JobTrait for FakeCollatorProtocolJob { @@ -72,10 +79,12 @@ impl JobTrait for FakeCollatorProtocolJob { let job = FakeCollatorProtocolJob { receiver }; if run_args { - sender.send_message(CollatorProtocolMessage::Invalid( - Default::default(), - Default::default(), - )).await; + sender + .send_message(CollatorProtocolMessage::Invalid( + Default::default(), + Default::default(), + )) + .await; } // it isn't necessary to break run_loop into its own function, @@ -92,7 +101,7 @@ impl FakeCollatorProtocolJob { match self.receiver.next().await { Some(_csm) => { unimplemented!("we'd report the collator to the peer set manager here, but that's not implemented yet"); - } + }, None => break, } } @@ -102,32 +111,21 @@ impl FakeCollatorProtocolJob { } // with the job defined, it's straightforward to get a subsystem implementation. -type FakeCollatorProtocolSubsystem = - JobSubsystem; +type FakeCollatorProtocolSubsystem = JobSubsystem; // this type lets us pretend to be the overseer type OverseerHandle = test_helpers::TestSubsystemContextHandle; -fn test_harness>( - run_args: bool, - test: impl FnOnce(OverseerHandle) -> T, -) { +fn test_harness>(run_args: bool, test: impl FnOnce(OverseerHandle) -> T) { let _ = env_logger::builder() .is_test(true) - .filter( - None, - log::LevelFilter::Trace, - ) + .filter(None, log::LevelFilter::Trace) .try_init(); let pool = sp_core::testing::TaskExecutor::new(); let (context, overseer_handle) = make_subsystem_context(pool.clone()); - let subsystem = FakeCollatorProtocolSubsystem::new( - pool, - run_args, - (), - ).run(context); + let subsystem = FakeCollatorProtocolSubsystem::new(pool, run_args, ()).run(context); let test_future = test(overseer_handle); futures::pin_mut!(subsystem, test_future); @@ -155,19 +153,14 @@ fn starting_and_stopping_job_works() { }), ))) .await; - assert_matches!( - overseer_handle.recv().await, - AllMessages::CollatorProtocol(_) - ); + assert_matches!(overseer_handle.recv().await, AllMessages::CollatorProtocol(_)); overseer_handle .send(FromOverseer::Signal(OverseerSignal::ActiveLeaves( ActiveLeavesUpdate::stop_work(relay_parent), ))) .await; - overseer_handle - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .await; + overseer_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; }); } @@ -189,20 +182,13 @@ fn sending_to_a_non_running_job_do_not_stop_the_subsystem() { // send to a non running job overseer_handle - .send(FromOverseer::Communication { - msg: Default::default(), - }) + .send(FromOverseer::Communication { msg: Default::default() }) .await; // the subsystem is still alive - assert_matches!( - overseer_handle.recv().await, - AllMessages::CollatorProtocol(_) - ); + assert_matches!(overseer_handle.recv().await, AllMessages::CollatorProtocol(_)); - overseer_handle - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .await; + overseer_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; }); } @@ -216,7 +202,6 @@ fn test_subsystem_impl_and_name_derivation() { assert_eq!(name, "FakeCollatorProtocol"); } - #[test] fn tick_tack_metronome() { let n = Arc::new(AtomicUsize::default()); @@ -226,13 +211,15 @@ fn tick_tack_metronome() { let metronome = { let n = n.clone(); let stream = Metronome::new(Duration::from_millis(137_u64)); - stream.for_each(move |_res| { - let _ = n.fetch_add(1, Ordering::Relaxed); - let mut tick = tick.clone(); - async move { - tick.send(()).await.expect("Test helper channel works. qed"); - } - }).fuse() + stream + .for_each(move |_res| { + let _ = n.fetch_add(1, Ordering::Relaxed); + let mut tick = tick.clone(); + async move { + tick.send(()).await.expect("Test helper channel works. qed"); + } + }) + .fuse() }; let f2 = async move { @@ -244,7 +231,8 @@ fn tick_tack_metronome() { assert_eq!(n.load(Ordering::Relaxed), 3_usize); block.next().await; assert_eq!(n.load(Ordering::Relaxed), 4_usize); - }.fuse(); + } + .fuse(); futures::pin_mut!(f2); futures::pin_mut!(metronome); diff --git a/polkadot/node/subsystem/src/lib.rs b/polkadot/node/subsystem/src/lib.rs index 98e76f9f949..e7ae19bcb39 100644 --- a/polkadot/node/subsystem/src/lib.rs +++ b/polkadot/node/subsystem/src/lib.rs @@ -21,15 +21,14 @@ #![deny(missing_docs)] #![deny(unused_crate_dependencies)] -pub use polkadot_node_jaeger as jaeger; pub use jaeger::*; +pub use polkadot_node_jaeger as jaeger; -pub use polkadot_overseer::{OverseerSignal, ActiveLeavesUpdate, self as overseer}; +pub use polkadot_overseer::{self as overseer, ActiveLeavesUpdate, OverseerSignal}; pub use polkadot_node_subsystem_types::{ errors::{self, *}, - ActivatedLeaf, - LeafStatus, + ActivatedLeaf, LeafStatus, }; /// Re-export of all messages type, including the wrapper type. @@ -46,29 +45,28 @@ pub type SubsystemResult = Result; // Simplify usage without having to do large scale modifications of all // subsystems at once. - /// Specialized message type originating from the overseer. pub type FromOverseer = polkadot_overseer::gen::FromOverseer; /// Specialized subsystem instance type of subsystems consuming a particular message type. -pub type SubsystemInstance = polkadot_overseer::gen::SubsystemInstance; +pub type SubsystemInstance = + polkadot_overseer::gen::SubsystemInstance; /// Sender trait for the `AllMessages` wrapper. -pub trait SubsystemSender: polkadot_overseer::gen::SubsystemSender { -} +pub trait SubsystemSender: polkadot_overseer::gen::SubsystemSender {} -impl SubsystemSender for T where T: polkadot_overseer::gen::SubsystemSender { -} +impl SubsystemSender for T where T: polkadot_overseer::gen::SubsystemSender +{} /// Spawned subsystem. pub type SpawnedSubsystem = polkadot_overseer::gen::SpawnedSubsystem; - /// Convenience trait specialization. -pub trait SubsystemContext: polkadot_overseer::gen::SubsystemContext< - Signal=OverseerSignal, - AllMessages=messages::AllMessages, - Error=SubsystemError, +pub trait SubsystemContext: + polkadot_overseer::gen::SubsystemContext< + Signal = OverseerSignal, + AllMessages = messages::AllMessages, + Error = SubsystemError, > { /// The message type the subsystem consumes. @@ -80,9 +78,9 @@ pub trait SubsystemContext: polkadot_overseer::gen::SubsystemContext< impl SubsystemContext for T where T: polkadot_overseer::gen::SubsystemContext< - Signal=OverseerSignal, - AllMessages=messages::AllMessages, - Error=SubsystemError, + Signal = OverseerSignal, + AllMessages = messages::AllMessages, + Error = SubsystemError, >, { type Message = ::Message; diff --git a/polkadot/node/test/client/src/block_builder.rs b/polkadot/node/test/client/src/block_builder.rs index a30ff4b8be0..cb938d65ca1 100644 --- a/polkadot/node/test/client/src/block_builder.rs +++ b/polkadot/node/test/client/src/block_builder.rs @@ -15,21 +15,26 @@ // along with Polkadot. If not, see . use crate::{Client, FullBackend}; -use polkadot_test_runtime::{GetLastTimestamp, UncheckedExtrinsic}; +use parity_scale_codec::{Decode, Encode}; use polkadot_primitives::v1::{Block, InherentData as ParachainsInherentData}; -use sp_runtime::{generic::BlockId, Digest, DigestItem}; +use polkadot_test_runtime::{GetLastTimestamp, UncheckedExtrinsic}; +use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sp_api::ProvideRuntimeApi; -use sp_consensus_babe::{BABE_ENGINE_ID, digests::{PreDigest, SecondaryPlainPreDigest}}; -use sc_block_builder::{BlockBuilderProvider, BlockBuilder}; +use sp_consensus_babe::{ + digests::{PreDigest, SecondaryPlainPreDigest}, + BABE_ENGINE_ID, +}; +use sp_runtime::{generic::BlockId, Digest, DigestItem}; use sp_state_machine::BasicExternalities; -use parity_scale_codec::{Encode, Decode}; /// An extension for the test client to initialize a Polkadot specific block builder. pub trait InitPolkadotBlockBuilder { /// Init a Polkadot specific block builder that works for the test runtime. /// /// This will automatically create and push the inherents for you to make the block valid for the test runtime. - fn init_polkadot_block_builder(&self) -> sc_block_builder::BlockBuilder; + fn init_polkadot_block_builder( + &self, + ) -> sc_block_builder::BlockBuilder; /// Init a Polkadot specific block builder at a specific block that works for the test runtime. /// @@ -42,9 +47,7 @@ pub trait InitPolkadotBlockBuilder { } impl InitPolkadotBlockBuilder for Client { - fn init_polkadot_block_builder( - &self, - ) -> BlockBuilder { + fn init_polkadot_block_builder(&self) -> BlockBuilder { let chain_info = self.chain_info(); self.init_polkadot_block_builder_at(&BlockId::Hash(chain_info.best_hash)) } @@ -53,17 +56,16 @@ impl InitPolkadotBlockBuilder for Client { &self, at: &BlockId, ) -> BlockBuilder { - let last_timestamp = self - .runtime_api() - .get_last_timestamp(&at) - .expect("Get last timestamp"); + let last_timestamp = + self.runtime_api().get_last_timestamp(&at).expect("Get last timestamp"); // `MinimumPeriod` is a storage parameter type that requires externalities to access the value. let minimum_period = BasicExternalities::new_empty() .execute_with(|| polkadot_test_runtime::MinimumPeriod::get()); let timestamp = if last_timestamp == 0 { - std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH) + std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) .expect("Time is always after UNIX_EPOCH; qed") .as_millis() as u64 } else { @@ -77,18 +79,15 @@ impl InitPolkadotBlockBuilder for Client { let slot = (timestamp / slot_duration).into(); let digest = Digest { - logs: vec![ - DigestItem::PreRuntime( - BABE_ENGINE_ID, - PreDigest::SecondaryPlain(SecondaryPlainPreDigest { - slot, - authority_index: 42, - }).encode() - ), - ], + logs: vec![DigestItem::PreRuntime( + BABE_ENGINE_ID, + PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot, authority_index: 42 }) + .encode(), + )], }; - let mut block_builder = self.new_block_at(at, digest, false) + let mut block_builder = self + .new_block_at(at, digest, false) .expect("Creates new block builder for test runtime"); let mut inherent_data = sp_inherents::InherentData::new(); @@ -97,7 +96,8 @@ impl InitPolkadotBlockBuilder for Client { .put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) .expect("Put timestamp inherent data"); - let parent_header = self.header(at) + let parent_header = self + .header(at) .expect("Get the parent block header") .expect("The target block header must exist"); @@ -105,7 +105,7 @@ impl InitPolkadotBlockBuilder for Client { bitfields: Vec::new(), backed_candidates: Vec::new(), disputes: Vec::new(), - parent_header: parent_header, + parent_header, }; inherent_data @@ -117,7 +117,9 @@ impl InitPolkadotBlockBuilder for Client { let inherents = block_builder.create_inherents(inherent_data).expect("Creates inherents"); - inherents.into_iter().for_each(|ext| block_builder.push(ext).expect("Pushes inherent")); + inherents + .into_iter() + .for_each(|ext| block_builder.push(ext).expect("Pushes inherent")); block_builder } @@ -132,15 +134,22 @@ pub trait BlockBuilderExt { /// the block. /// /// Returns the result of the application of the extrinsic. - fn push_polkadot_extrinsic(&mut self, ext: UncheckedExtrinsic) -> Result<(), sp_blockchain::Error>; + fn push_polkadot_extrinsic( + &mut self, + ext: UncheckedExtrinsic, + ) -> Result<(), sp_blockchain::Error>; } impl BlockBuilderExt for BlockBuilder<'_, Block, Client, FullBackend> { - fn push_polkadot_extrinsic(&mut self, ext: UncheckedExtrinsic) -> Result<(), sp_blockchain::Error> { + fn push_polkadot_extrinsic( + &mut self, + ext: UncheckedExtrinsic, + ) -> Result<(), sp_blockchain::Error> { let encoded = ext.encode(); self.push( - Decode::decode(&mut &encoded[..]) - .expect("The runtime specific extrinsic always decodes to an opaque extrinsic; qed"), + Decode::decode(&mut &encoded[..]).expect( + "The runtime specific extrinsic always decodes to an opaque extrinsic; qed", + ), ) } } diff --git a/polkadot/node/test/client/src/lib.rs b/polkadot/node/test/client/src/lib.rs index 0374395cccf..80e6a32c4c7 100644 --- a/polkadot/node/test/client/src/lib.rs +++ b/polkadot/node/test/client/src/lib.rs @@ -26,17 +26,22 @@ use sp_core::storage::Storage; use sp_runtime::BuildStorage; pub use block_builder::*; -pub use substrate_test_client::*; +pub use polkadot_test_runtime as runtime; pub use polkadot_test_service::{ - Client, construct_extrinsic, construct_transfer_extrinsic, PolkadotTestExecutor, FullBackend, + construct_extrinsic, construct_transfer_extrinsic, Client, FullBackend, PolkadotTestExecutor, }; -pub use polkadot_test_runtime as runtime; +pub use substrate_test_client::*; /// Test client executor. -pub type Executor = client::LocalCallExecutor>; +pub type Executor = client::LocalCallExecutor< + Block, + FullBackend, + sc_executor::NativeExecutor, +>; /// Test client builder for Polkadot. -pub type TestClientBuilder = substrate_test_client::TestClientBuilder; +pub type TestClientBuilder = + substrate_test_client::TestClientBuilder; /// `LongestChain` type for the test runtime/client. pub type LongestChain = sc_consensus::LongestChain; @@ -83,7 +88,7 @@ impl DefaultTestClientBuilderExt for TestClientBuilder { } #[cfg(test)] -mod tests{ +mod tests { use super::*; use sp_consensus::BlockOrigin; @@ -94,7 +99,8 @@ mod tests{ let block_builder = client.init_polkadot_block_builder(); let block = block_builder.build().expect("Finalizes the block").block; - futures::executor::block_on(client.import(BlockOrigin::Own, block)).expect("Imports the block"); + futures::executor::block_on(client.import(BlockOrigin::Own, block)) + .expect("Imports the block"); } #[test] @@ -112,6 +118,7 @@ mod tests{ let block = block_builder.build().expect("Finalizes the block").block; - futures::executor::block_on(client.import(BlockOrigin::Own, block)).expect("Imports the block"); + futures::executor::block_on(client.import(BlockOrigin::Own, block)) + .expect("Imports the block"); } } diff --git a/polkadot/node/test/polkadot-simnet/common/src/lib.rs b/polkadot/node/test/polkadot-simnet/common/src/lib.rs index 35a8c2af8ed..7b0be2151cb 100644 --- a/polkadot/node/test/polkadot-simnet/common/src/lib.rs +++ b/polkadot/node/test/polkadot-simnet/common/src/lib.rs @@ -18,23 +18,23 @@ //! Utilities for End to end runtime tests -use test_runner::{ - Node, ChainInfo, SignatureVerificationOverride, task_executor, - build_runtime, client_parts, ConfigOrChainSpec, -}; +use codec::Encode; +use democracy::{AccountVote, Conviction, Vote}; use grandpa::GrandpaBlockImport; -use sc_service::{TFullBackend, TFullClient}; -use sp_runtime::generic::Era; -use sc_consensus_babe::BabeBlockImport; +use polkadot_runtime::{ + CouncilCollective, Event, FastTrackVotingPeriod, Runtime, RuntimeApi, TechnicalCollective, +}; use polkadot_runtime_common::claims; -use sp_runtime::AccountId32; -use support::{weights::Weight, StorageValue}; -use democracy::{AccountVote, Conviction, Vote}; -use polkadot_runtime::{FastTrackVotingPeriod, Runtime, RuntimeApi, Event, TechnicalCollective, CouncilCollective}; -use std::{str::FromStr, future::Future, error::Error}; -use codec::Encode; +use sc_consensus_babe::BabeBlockImport; use sc_consensus_manual_seal::consensus::babe::SlotTimestampProvider; -use sp_runtime::app_crypto::sp_core::H256; +use sc_service::{TFullBackend, TFullClient}; +use sp_runtime::{app_crypto::sp_core::H256, generic::Era, AccountId32}; +use std::{error::Error, future::Future, str::FromStr}; +use support::{weights::Weight, StorageValue}; +use test_runner::{ + build_runtime, client_parts, task_executor, ChainInfo, ConfigOrChainSpec, Node, + SignatureVerificationOverride, +}; type BlockImport = BabeBlockImport>; type Block = polkadot_primitives::v1::Block; @@ -63,7 +63,8 @@ impl ChainInfo for PolkadotChainInfo { Self::SelectChain, >; type SignedExtras = polkadot_runtime::SignedExtra; - type InherentDataProviders = (SlotTimestampProvider, sp_consensus_babe::inherents::InherentDataProvider); + type InherentDataProviders = + (SlotTimestampProvider, sp_consensus_babe::inherents::InherentDataProvider); fn signed_extras(from: ::AccountId) -> Self::SignedExtras { ( @@ -80,23 +81,25 @@ impl ChainInfo for PolkadotChainInfo { } /// Dispatch with root origin, via pallet-democracy -pub async fn dispatch_with_root(call: impl Into<::Call>, node: &Node) - -> Result<(), Box> - where - T: ChainInfo< - Block=Block, - Executor=Executor, - Runtime=Runtime, - RuntimeApi=RuntimeApi, - SelectChain=SelectChain, - BlockImport=BlockImport< - Block, - TFullBackend, - TFullClient, - SelectChain, - >, - SignedExtras=polkadot_runtime::SignedExtra - > +pub async fn dispatch_with_root( + call: impl Into<::Call>, + node: &Node, +) -> Result<(), Box> +where + T: ChainInfo< + Block = Block, + Executor = Executor, + Runtime = Runtime, + RuntimeApi = RuntimeApi, + SelectChain = SelectChain, + BlockImport = BlockImport< + Block, + TFullBackend, + TFullClient, + SelectChain, + >, + SignedExtras = polkadot_runtime::SignedExtra, + >, { type DemocracyCall = democracy::Call; type CouncilCollectiveEvent = collective::Event; @@ -109,37 +112,47 @@ pub async fn dispatch_with_root(call: impl Into<>(); + .into_iter() + .map(|account| AccountId32::from_str(account).unwrap()) + .collect::>(); // and these - let (technical_collective, council_collective) = node.with_state(|| ( - collective::Members::::get(), - collective::Members::::get() - )); + let (technical_collective, council_collective) = node.with_state(|| { + ( + collective::Members::::get(), + collective::Members::::get(), + ) + }); // hash of the proposal in democracy let proposal_hash = { // note the call (pre-image?) of the call. - node.submit_extrinsic(DemocracyCall::note_preimage(call.into().encode()), whales[0].clone()).await?; + node.submit_extrinsic( + DemocracyCall::note_preimage(call.into().encode()), + whales[0].clone(), + ) + .await?; node.seal_blocks(1).await; // fetch proposal hash from event emitted by the runtime let events = node.events(); - events.iter() + events + .iter() .filter_map(|event| match event.event { - Event::Democracy(democracy::Event::PreimageNoted(ref proposal_hash, _, _)) - => Some(proposal_hash.clone()), - _ => None + Event::Democracy(democracy::Event::PreimageNoted(ref proposal_hash, _, _)) => + Some(proposal_hash.clone()), + _ => None, }) .next() - .ok_or_else(|| format!("democracy::Event::PreimageNoted not found in events: {:#?}", events))? + .ok_or_else(|| { + format!("democracy::Event::PreimageNoted not found in events: {:#?}", events) + })? }; // submit external_propose call through council collective { - let external_propose = DemocracyCall::external_propose_majority(proposal_hash.clone().into()); + let external_propose = + DemocracyCall::external_propose_majority(proposal_hash.clone().into()); let length = external_propose.using_encoded(|x| x.len()) as u32 + 1; let weight = Weight::MAX / 100_000_000; let proposal = CouncilCollectiveCall::propose( @@ -153,16 +166,17 @@ pub async fn dispatch_with_root(call: impl Into< - Some((index, hash.clone())), - _ => None - } + let (index, hash): (u32, H256) = events + .iter() + .filter_map(|event| match event.event { + Event::Council(CouncilCollectiveEvent::Proposed(_, index, ref hash, _)) => + Some((index, hash.clone())), + _ => None, }) .next() - .ok_or_else(|| format!("CouncilCollectiveEvent::Proposed not found in events: {:#?}", events))?; + .ok_or_else(|| { + format!("CouncilCollectiveEvent::Proposed not found in events: {:#?}", events) + })?; // vote for member in &council_collective[1..] { @@ -177,21 +191,24 @@ pub async fn dispatch_with_root(call: impl Into< true, - Event::Council(CouncilCollectiveEvent::Approved(_hash, )) if hash == _hash => true, - Event::Council(CouncilCollectiveEvent::Executed(_hash, Ok(()))) if hash == _hash => true, - _ => false, - } + .filter(|event| match event.event { + Event::Council(CouncilCollectiveEvent::Closed(_hash, _, _)) if hash == _hash => + true, + Event::Council(CouncilCollectiveEvent::Approved(_hash)) if hash == _hash => true, + Event::Council(CouncilCollectiveEvent::Executed(_hash, Ok(()))) + if hash == _hash => + true, + _ => false, }) .collect::>(); // make sure all 3 events are in state assert_eq!( - events.len(), 3, + events.len(), + 3, "CouncilCollectiveEvent::{{Closed, Approved, Executed}} not found in events: {:#?}", node.events(), ); @@ -199,7 +216,8 @@ pub async fn dispatch_with_root(call: impl Into<(call: impl Into< Some((index, hash.clone())), - _ => None - } + let (index, hash) = events + .iter() + .filter_map(|event| match event.event { + Event::TechnicalCommittee(TechnicalCollectiveEvent::Proposed( + _, + index, + ref hash, + _, + )) => Some((index, hash.clone())), + _ => None, }) .next() - .ok_or_else(|| format!("TechnicalCollectiveEvent::Proposed not found in events: {:#?}", events))?; + .ok_or_else(|| { + format!("TechnicalCollectiveEvent::Proposed not found in events: {:#?}", events) + })?; // vote for member in &technical_collective[1..] { @@ -236,35 +259,44 @@ pub async fn dispatch_with_root(call: impl Into< true, - Event::TechnicalCommittee(TechnicalCollectiveEvent::Approved(_hash)) if hash == _hash => true, - Event::TechnicalCommittee(TechnicalCollectiveEvent::Executed(_hash, Ok(()))) if hash == _hash => true, - _ => false, - } + .filter(|event| match event.event { + Event::TechnicalCommittee(TechnicalCollectiveEvent::Closed(_hash, _, _)) + if hash == _hash => + true, + Event::TechnicalCommittee(TechnicalCollectiveEvent::Approved(_hash)) + if hash == _hash => + true, + Event::TechnicalCommittee(TechnicalCollectiveEvent::Executed(_hash, Ok(()))) + if hash == _hash => + true, + _ => false, }) .collect::>(); // make sure all 3 events are in state assert_eq!( - events.len(), 3, + events.len(), + 3, "TechnicalCollectiveEvent::{{Closed, Approved, Executed}} not found in events: {:#?}", node.events(), ); } // now runtime upgrade proposal is a fast-tracked referendum we can vote for. - let ref_index = node.events() + let ref_index = node + .events() .into_iter() .filter_map(|event| match event.event { Event::Democracy(democracy::Event::Started(index, _)) => Some(index), _ => None, }) .next() - .ok_or_else(|| format!("democracy::Event::Started not found in events: {:#?}", node.events()))?; + .ok_or_else(|| { + format!("democracy::Event::Started not found in events: {:#?}", node.events()) + })?; let call = DemocracyCall::vote( ref_index, @@ -282,21 +314,24 @@ pub async fn dispatch_with_root(call: impl Into< true, - Event::Democracy(democracy::Event::PreimageUsed(_hash, _, _)) if _hash == proposal_hash => true, - Event::Democracy(democracy::Event::Executed(_index, Ok(()))) if _index == ref_index => true, - _ => false, - } + .filter(|event| match event.event { + Event::Democracy(democracy::Event::Passed(_index)) if _index == ref_index => true, + Event::Democracy(democracy::Event::PreimageUsed(_hash, _, _)) + if _hash == proposal_hash => + true, + Event::Democracy(democracy::Event::Executed(_index, Ok(()))) if _index == ref_index => + true, + _ => false, }) .collect::>(); // make sure all events were emitted assert_eq!( - events.len(), 3, + events.len(), + 3, "democracy::Event::{{Passed, PreimageUsed, Executed}} not found in events: {:#?}", node.events(), ); @@ -305,12 +340,12 @@ pub async fn dispatch_with_root(call: impl Into<(callback: F) -> Result<(), Box> - where - F: FnOnce(Node) -> Fut, - Fut: Future>>, +where + F: FnOnce(Node) -> Fut, + Fut: Future>>, { - use structopt::StructOpt; use sc_cli::{CliConfiguration, SubstrateCli}; + use structopt::StructOpt; let mut tokio_runtime = build_runtime()?; let task_executor = task_executor(tokio_runtime.handle().clone()); @@ -326,7 +361,8 @@ pub fn run(callback: F) -> Result<(), Box> sc_cli::print_node_infos::(&config); let (rpc, task_manager, client, pool, command_sink, backend) = client_parts::(ConfigOrChainSpec::Config(config))?; - let node = Node::::new(rpc, task_manager, client, pool, command_sink, backend); + let node = + Node::::new(rpc, task_manager, client, pool, command_sink, backend); // hand off node. tokio_runtime.block_on(callback(node))?; @@ -337,19 +373,22 @@ pub fn run(callback: F) -> Result<(), Box> #[cfg(test)] mod tests { use super::*; - use sp_keyring::sr25519::Keyring::Alice; - use sp_runtime::{MultiSigner, traits::IdentifyAccount}; use polkadot_service::chain_spec::polkadot_development_config; + use sp_keyring::sr25519::Keyring::Alice; + use sp_runtime::{traits::IdentifyAccount, MultiSigner}; #[test] fn test_runner() { let mut runtime = build_runtime().unwrap(); let task_executor = task_executor(runtime.handle().clone()); let (rpc, task_manager, client, pool, command_sink, backend) = - client_parts::( - ConfigOrChainSpec::ChainSpec(Box::new(polkadot_development_config().unwrap()), task_executor) - ).unwrap(); - let node = Node::::new(rpc, task_manager, client, pool, command_sink, backend); + client_parts::(ConfigOrChainSpec::ChainSpec( + Box::new(polkadot_development_config().unwrap()), + task_executor, + )) + .unwrap(); + let node = + Node::::new(rpc, task_manager, client, pool, command_sink, backend); runtime.block_on(async { // seals blocks diff --git a/polkadot/node/test/polkadot-simnet/test/src/main.rs b/polkadot/node/test/polkadot-simnet/test/src/main.rs index fccffc6b0e6..3d0771b8d65 100644 --- a/polkadot/node/test/polkadot-simnet/test/src/main.rs +++ b/polkadot/node/test/polkadot-simnet/test/src/main.rs @@ -16,40 +16,46 @@ //! Attempts to upgrade the polkadot runtime, in a Simnet environment use std::{error::Error, str::FromStr}; -use polkadot_simnet::{run, dispatch_with_root}; use polkadot_runtime::Event; -use sp_runtime::generic::BlockId; -use sc_client_api::{ExecutorProvider, CallExecutor}; -use sp_core::crypto::AccountId32; +use polkadot_simnet::{dispatch_with_root, run}; +use sc_client_api::{CallExecutor, ExecutorProvider}; use sp_blockchain::HeaderBackend; +use sp_core::crypto::AccountId32; +use sp_runtime::generic::BlockId; fn main() -> Result<(), Box> { run(|node| async { - let old_runtime_version = node.client() + let old_runtime_version = node + .client() .executor() .runtime_version(&BlockId::Hash(node.client().info().best_hash))? .spec_version; let wasm_binary = polkadot_runtime::WASM_BINARY - .ok_or("Polkadot development wasm not available")? - .to_vec(); - // upgrade runtime. - dispatch_with_root(system::Call::set_code(wasm_binary), &node).await?; + .ok_or("Polkadot development wasm not available")? + .to_vec(); + // upgrade runtime. + dispatch_with_root(system::Call::set_code(wasm_binary), &node).await?; // assert that the runtime has been updated by looking at events - let events = node.events() + let events = node + .events() .into_iter() - .filter(|event| { - match event.event { - Event::System(system::Event::CodeUpdated) => true, - _ => false, - } + .filter(|event| match event.event { + Event::System(system::Event::CodeUpdated) => true, + _ => false, }) .collect::>(); // make sure event was emitted - assert_eq!(events.len(), 1, "system::Event::CodeUpdate not found in events: {:#?}", node.events()); - let new_runtime_version = node.client() + assert_eq!( + events.len(), + 1, + "system::Event::CodeUpdate not found in events: {:#?}", + node.events() + ); + let new_runtime_version = node + .client() .executor() .runtime_version(&BlockId::Hash(node.client().info().best_hash))? .spec_version; @@ -64,20 +70,20 @@ fn main() -> Result<(), Box> { let (from, dest, balance) = ( AccountId32::from_str("15j4dg5GzsL1bw2U2AWgeyAk6QTxq43V7ZPbXdAmbVLjvDCK")?, AccountId32::from_str("1rvXMZpAj9nKLQkPFCymyH7Fg3ZyKJhJbrc7UtHbTVhJm1A")?, - 10_000_000_000_000 // 10 dots + 10_000_000_000_000, // 10 dots ); // post upgrade tests, a simple balance transfer - node.submit_extrinsic(balances::Call::transfer(dest.into(), balance), from).await?; + node.submit_extrinsic(balances::Call::transfer(dest.into(), balance), from) + .await?; node.seal_blocks(1).await; - let events = node.events() + let events = node + .events() .into_iter() - .filter(|event| { - match event.event { - Event::Balances(balances::Event::Transfer(_, _, _)) => true, - _ => false, - } + .filter(|event| match event.event { + Event::Balances(balances::Event::Transfer(_, _, _)) => true, + _ => false, }) .collect::>(); // make sure transfer went through diff --git a/polkadot/node/test/service/src/chain_spec.rs b/polkadot/node/test/service/src/chain_spec.rs index 5a54bebf1bc..855c9455075 100644 --- a/polkadot/node/test/service/src/chain_spec.rs +++ b/polkadot/node/test/service/src/chain_spec.rs @@ -16,14 +16,14 @@ //! Chain specifications for the test runtime. -use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use babe_primitives::AuthorityId as BabeId; use grandpa::AuthorityId as GrandpaId; use pallet_staking::Forcing; -use polkadot_primitives::v1::{ValidatorId, AccountId, AssignmentId, MAX_CODE_SIZE, MAX_POV_SIZE}; +use polkadot_primitives::v1::{AccountId, AssignmentId, ValidatorId, MAX_CODE_SIZE, MAX_POV_SIZE}; use polkadot_service::chain_spec::{get_account_id_from_seed, get_from_seed, Extensions}; use polkadot_test_runtime::{constants::currency::DOTS, BABE_GENESIS_EPOCH_CONFIG}; use sc_chain_spec::{ChainSpec, ChainType}; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_core::sr25519; use sp_runtime::Perbill; @@ -51,10 +51,7 @@ pub fn polkadot_local_testnet_config() -> PolkadotChainSpec { /// Local testnet genesis config (multivalidator Alice + Bob) pub fn polkadot_local_testnet_genesis() -> polkadot_test_runtime::GenesisConfig { polkadot_testnet_genesis( - vec![ - get_authority_keys_from_seed("Alice"), - get_authority_keys_from_seed("Bob"), - ], + vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], get_account_id_from_seed::("Alice"), None, ) @@ -120,10 +117,7 @@ fn polkadot_testnet_genesis( }, indices: runtime::IndicesConfig { indices: vec![] }, balances: runtime::BalancesConfig { - balances: endowed_accounts - .iter() - .map(|k| (k.clone(), ENDOWMENT)) - .collect(), + balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(), }, session: runtime::SessionConfig { keys: initial_authorities @@ -148,14 +142,7 @@ fn polkadot_testnet_genesis( validator_count: 2, stakers: initial_authorities .iter() - .map(|x| { - ( - x.0.clone(), - x.1.clone(), - STASH, - runtime::StakerStatus::Validator, - ) - }) + .map(|x| (x.0.clone(), x.1.clone(), STASH, runtime::StakerStatus::Validator)) .collect(), invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), force_era: Forcing::NotForcing, @@ -168,10 +155,7 @@ fn polkadot_testnet_genesis( }, grandpa: Default::default(), authority_discovery: runtime::AuthorityDiscoveryConfig { keys: vec![] }, - claims: runtime::ClaimsConfig { - claims: vec![], - vesting: vec![], - }, + claims: runtime::ClaimsConfig { claims: vec![], vesting: vec![] }, vesting: runtime::VestingConfig { vesting: vec![] }, sudo: runtime::SudoConfig { key: root_key }, parachains_configuration: runtime::ParachainsConfigurationConfig { diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs index bd38724b006..cad314ed761 100644 --- a/polkadot/node/test/service/src/lib.rs +++ b/polkadot/node/test/service/src/lib.rs @@ -22,20 +22,17 @@ pub mod chain_spec; pub use chain_spec::*; use futures::future::Future; +use polkadot_node_primitives::{CollationGenerationConfig, CollatorFn}; +use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage}; use polkadot_overseer::Handle; -use polkadot_primitives::v1::{ - Id as ParaId, HeadData, ValidationCode, Balance, CollatorPair, -}; +use polkadot_primitives::v1::{Balance, CollatorPair, HeadData, Id as ParaId, ValidationCode}; use polkadot_runtime_common::BlockHashCount; -use polkadot_service::{ - Error, NewFull, FullClient, ClientHandle, ExecuteWithClient, IsCollator, -}; -use polkadot_node_subsystem::messages::{CollatorProtocolMessage, CollationGenerationMessage}; +use polkadot_runtime_parachains::paras::ParaGenesisArgs; +use polkadot_service::{ClientHandle, Error, ExecuteWithClient, FullClient, IsCollator, NewFull}; use polkadot_test_runtime::{ - Runtime, SignedExtra, SignedPayload, VERSION, ParasSudoWrapperCall, SudoCall, UncheckedExtrinsic, + ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall, UncheckedExtrinsic, + VERSION, }; -use polkadot_node_primitives::{CollatorFn, CollationGenerationConfig}; -use polkadot_runtime_parachains::paras::ParaGenesisArgs; use sc_chain_spec::ChainSpec; use sc_client_api::execution_extensions::ExecutionStrategies; use sc_executor::native_executor_instance; @@ -45,16 +42,18 @@ use sc_network::{ }; use service::{ config::{DatabaseConfig, KeystoreConfig, MultiaddrWithPeerId, WasmExecutionMethod}, - RpcHandlers, TaskExecutor, TaskManager, KeepBlocks, TransactionStorageMode, + BasePath, Configuration, KeepBlocks, Role, RpcHandlers, TaskExecutor, TaskManager, + TransactionStorageMode, }; -use service::{BasePath, Configuration, Role}; use sp_arithmetic::traits::SaturatedConversion; use sp_blockchain::HeaderBackend; use sp_keyring::Sr25519Keyring; use sp_runtime::{codec::Encode, generic, traits::IdentifyAccount, MultiSigner}; use sp_state_machine::BasicExternalities; -use std::{sync::Arc, path::PathBuf}; -use substrate_test_client::{BlockchainEventsExt, RpcHandlersExt, RpcTransactionOutput, RpcTransactionError}; +use std::{path::PathBuf, sync::Arc}; +use substrate_test_client::{ + BlockchainEventsExt, RpcHandlersExt, RpcTransactionError, RpcTransactionOutput, +}; native_executor_instance!( pub PolkadotTestExecutor, @@ -74,10 +73,7 @@ pub fn new_full( config: Configuration, is_collator: IsCollator, worker_program_path: Option, -) -> Result< - NewFull>, - Error, -> { +) -> Result>, Error> { polkadot_service::new_full::( config, is_collator, @@ -115,17 +111,10 @@ pub fn node_config( ) -> Configuration { let base_path = BasePath::new_temp_dir().expect("could not create temporary directory"); let root = base_path.path(); - let role = if is_validator { - Role::Authority - } else { - Role::Full - }; + let role = if is_validator { Role::Authority } else { Role::Full }; let key_seed = key.to_seed(); let mut spec = polkadot_local_testnet_config(); - let mut storage = spec - .as_storage_builder() - .build_storage() - .expect("could not build storage"); + let mut storage = spec.as_storage_builder().build_storage().expect("could not build storage"); BasicExternalities::execute_with_storage(&mut storage, storage_update_func); spec.set_storage(storage); @@ -142,13 +131,9 @@ pub fn node_config( network_config.allow_non_globals_in_dht = true; let addr: multiaddr::Multiaddr = multiaddr::Protocol::Memory(rand::random()).into(); - network_config - .listen_addresses - .push(addr.clone()); + network_config.listen_addresses.push(addr.clone()); - network_config - .public_addresses - .push(addr); + network_config.public_addresses.push(addr); network_config.transport = TransportConfig::MemoryOnly; @@ -161,10 +146,7 @@ pub fn node_config( network: network_config, keystore: KeystoreConfig::InMemory, keystore_remote: Default::default(), - database: DatabaseConfig::RocksDb { - path: root.join("db"), - cache_size: 128, - }, + database: DatabaseConfig::RocksDb { path: root.join("db"), cache_size: 128 }, state_cache_size: 16777216, state_cache_child_ratio: None, state_pruning: Default::default(), @@ -224,19 +206,14 @@ pub fn run_validator_node( let config = node_config(storage_update_func, task_executor, key, boot_nodes, true); let multiaddr = config.network.listen_addresses[0].clone(); let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = - new_full(config, IsCollator::No, worker_program_path).expect("could not create Polkadot test service"); + new_full(config, IsCollator::No, worker_program_path) + .expect("could not create Polkadot test service"); let overseer_handle = overseer_handle.expect("test node must have an overseer handle"); let peer_id = network.local_peer_id().clone(); let addr = MultiaddrWithPeerId { multiaddr, peer_id }; - PolkadotTestNode { - task_manager, - client, - overseer_handle, - addr, - rpc_handlers, - } + PolkadotTestNode { task_manager, client, overseer_handle, addr, rpc_handlers } } /// Run a test collator node that uses the test runtime. @@ -260,27 +237,15 @@ pub fn run_collator_node( ) -> PolkadotTestNode { let config = node_config(storage_update_func, task_executor, key, boot_nodes, false); let multiaddr = config.network.listen_addresses[0].clone(); - let NewFull { - task_manager, - client, - network, - rpc_handlers, - overseer_handle, - .. - } = new_full(config, IsCollator::Yes(collator_pair), None) - .expect("could not create Polkadot test service"); + let NewFull { task_manager, client, network, rpc_handlers, overseer_handle, .. } = + new_full(config, IsCollator::Yes(collator_pair), None) + .expect("could not create Polkadot test service"); let overseer_handle = overseer_handle.expect("test node must have an overseer handle"); let peer_id = network.local_peer_id().clone(); let addr = MultiaddrWithPeerId { multiaddr, peer_id }; - PolkadotTestNode { - task_manager, - client, - overseer_handle, - addr, - rpc_handlers, - } + PolkadotTestNode { task_manager, client, overseer_handle, addr, rpc_handlers } } /// A Polkadot test node instance used for testing. @@ -325,7 +290,9 @@ impl PolkadotTestNode { }, ); - self.send_extrinsic(SudoCall::sudo(Box::new(call.into())), Sr25519Keyring::Alice).await.map(drop) + self.send_extrinsic(SudoCall::sudo(Box::new(call.into())), Sr25519Keyring::Alice) + .await + .map(drop) } /// Wait for `count` blocks to be imported in the node and then exit. This function will not return if no blocks @@ -341,11 +308,7 @@ impl PolkadotTestNode { para_id: ParaId, collator: CollatorFn, ) { - let config = CollationGenerationConfig { - key: collator_key, - collator, - para_id, - }; + let config = CollationGenerationConfig { key: collator_key, collator, para_id }; self.overseer_handle .send_msg(CollationGenerationMessage::Initialize(config), "Collator") @@ -368,10 +331,8 @@ pub fn construct_extrinsic( let current_block = client.info().best_number.saturated_into(); let genesis_block = client.hash(0).unwrap().unwrap(); let nonce = 0; - let period = BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; let tip = 0; let extra: SignedExtra = ( frame_system::CheckSpecVersion::::new(), @@ -411,12 +372,10 @@ pub fn construct_transfer_extrinsic( dest: sp_keyring::AccountKeyring, value: Balance, ) -> UncheckedExtrinsic { - let function = polkadot_test_runtime::Call::Balances( - pallet_balances::Call::transfer( - MultiSigner::from(dest.public()).into_account().into(), - value, - ), - ); + let function = polkadot_test_runtime::Call::Balances(pallet_balances::Call::transfer( + MultiSigner::from(dest.public()).into_account().into(), + value, + )); construct_extrinsic(client, function, origin) } diff --git a/polkadot/node/test/service/tests/build-blocks.rs b/polkadot/node/test/service/tests/build-blocks.rs index b563a6e46a7..74bef3277ba 100644 --- a/polkadot/node/test/service/tests/build-blocks.rs +++ b/polkadot/node/test/service/tests/build-blocks.rs @@ -25,13 +25,8 @@ async fn ensure_test_service_build_blocks(task_executor: TaskExecutor) { builder.with_colors(false); builder.init().expect("Sets up logger"); - let mut alice = run_validator_node( - task_executor.clone(), - Sr25519Keyring::Alice, - || {}, - Vec::new(), - None, - ); + let mut alice = + run_validator_node(task_executor.clone(), Sr25519Keyring::Alice, || {}, Vec::new(), None); let mut bob = run_validator_node( task_executor.clone(), Sr25519Keyring::Bob, diff --git a/polkadot/node/test/service/tests/call-function.rs b/polkadot/node/test/service/tests/call-function.rs index fa9a161923e..d913dbed478 100644 --- a/polkadot/node/test/service/tests/call-function.rs +++ b/polkadot/node/test/service/tests/call-function.rs @@ -34,11 +34,7 @@ async fn call_function_actually_work(task_executor: TaskExecutor) { assert!(object.contains_key("jsonrpc"), "key jsonrpc exists"); let result = object.get("result"); let result = result.expect("key result exists"); - assert_eq!( - result.as_str().map(|x| x.starts_with("0x")), - Some(true), - "result starts with 0x", - ); + assert_eq!(result.as_str().map(|x| x.starts_with("0x")), Some(true), "result starts with 0x",); alice.task_manager.clean_shutdown().await; } diff --git a/polkadot/parachain/src/primitives.rs b/polkadot/parachain/src/primitives.rs index 5f7f58f9bb2..85517b79159 100644 --- a/polkadot/parachain/src/primitives.rs +++ b/polkadot/parachain/src/primitives.rs @@ -19,13 +19,13 @@ use sp_std::vec::Vec; -use parity_scale_codec::{Encode, Decode, CompactAs}; +use frame_support::weights::Weight; +use parity_scale_codec::{CompactAs, Decode, Encode}; use sp_core::{RuntimeDebug, TypeId}; use sp_runtime::traits::Hash as _; -use frame_support::weights::Weight; #[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; #[cfg(feature = "std")] use sp_core::bytes; @@ -39,9 +39,11 @@ use polkadot_core_primitives::{Hash, OutboundHrmpMessage}; pub use polkadot_core_primitives::BlockNumber as RelayChainBlockNumber; /// Parachain head data included in the chain. -#[derive(PartialEq, Eq, Clone, PartialOrd, Ord, Encode, Decode, RuntimeDebug, derive_more::From)] +#[derive( + PartialEq, Eq, Clone, PartialOrd, Ord, Encode, Decode, RuntimeDebug, derive_more::From, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Default, Hash, MallocSizeOf))] -pub struct HeadData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); +pub struct HeadData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec); #[cfg(feature = "std")] impl HeadData { @@ -117,11 +119,22 @@ pub struct BlockData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec /// Unique identifier of a parachain. #[derive( - Clone, CompactAs, Copy, Decode, Default, Encode, Eq, - Hash, Ord, PartialEq, PartialOrd, RuntimeDebug, + Clone, + CompactAs, + Copy, + Decode, + Default, + Encode, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + RuntimeDebug, )] -#[cfg_attr(feature = "std", derive( - serde::Serialize, serde::Deserialize, derive_more::Display, MallocSizeOf) +#[cfg_attr( + feature = "std", + derive(serde::Serialize, serde::Deserialize, derive_more::Display, MallocSizeOf) )] pub struct Id(u32); @@ -130,11 +143,15 @@ impl TypeId for Id { } impl From for u32 { - fn from(x: Id) -> Self { x.0 } + fn from(x: Id) -> Self { + x.0 + } } impl From for Id { - fn from(x: u32) -> Self { Id(x) } + fn from(x: u32) -> Self { + Id(x) + } } impl From for Id { @@ -237,11 +254,15 @@ impl TypeId for Sibling { } impl From for u32 { - fn from(x: Sibling) -> Self { x.0.into() } + fn from(x: Sibling) -> Self { + x.0.into() + } } impl From for Sibling { - fn from(x: u32) -> Self { Sibling(x.into()) } + fn from(x: u32) -> Self { + Sibling(x.into()) + } } impl IsSystem for Sibling { @@ -282,14 +303,16 @@ impl<'a> parity_scale_codec::Input for TrailingZeroInput<'a> { /// zeroes to fill AccountId. impl AccountIdConversion for Id { fn into_account(&self) -> T { - (b"para", self).using_encoded(|b| - T::decode(&mut TrailingZeroInput(b)) - ).unwrap_or_default() + (b"para", self) + .using_encoded(|b| T::decode(&mut TrailingZeroInput(b))) + .unwrap_or_default() } fn try_from_account(x: &T) -> Option { x.using_encoded(|d| { - if &d[0..4] != b"para" { return None } + if &d[0..4] != b"para" { + return None + } let mut cursor = &d[4..]; let result = Decode::decode(&mut cursor).ok()?; if cursor.iter().all(|x| *x == 0) { diff --git a/polkadot/parachain/src/wasm_api.rs b/polkadot/parachain/src/wasm_api.rs index 99bed554147..0c20b94c5d7 100644 --- a/polkadot/parachain/src/wasm_api.rs +++ b/polkadot/parachain/src/wasm_api.rs @@ -21,9 +21,7 @@ /// Offset and length must have been provided by the validation /// function's entry point. #[cfg(not(feature = "std"))] -pub unsafe fn load_params(params: *const u8, len: usize) - -> crate::primitives::ValidationParams -{ +pub unsafe fn load_params(params: *const u8, len: usize) -> crate::primitives::ValidationParams { let mut slice = sp_std::slice::from_raw_parts(params, len); parity_scale_codec::Decode::decode(&mut slice).expect("Invalid input data") diff --git a/polkadot/parachain/test-parachains/adder/build.rs b/polkadot/parachain/test-parachains/adder/build.rs index ac1ce327cf9..1725943d37a 100644 --- a/polkadot/parachain/test-parachains/adder/build.rs +++ b/polkadot/parachain/test-parachains/adder/build.rs @@ -17,8 +17,5 @@ use substrate_wasm_builder::WasmBuilder; fn main() { - WasmBuilder::new() - .with_current_project() - .export_heap_base() - .build() + WasmBuilder::new().with_current_project().export_heap_base().build() } diff --git a/polkadot/parachain/test-parachains/adder/collator/src/cli.rs b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs index ae6e9ef9008..be7d31342a7 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/cli.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs @@ -93,17 +93,15 @@ impl SubstrateCli for Cli { fn load_spec(&self, id: &str) -> std::result::Result, String> { let id = if id.is_empty() { "rococo" } else { id }; Ok(match id { - "rococo-staging" => { - Box::new(polkadot_service::chain_spec::rococo_staging_testnet_config()?) - } - "rococo-local" => { - Box::new(polkadot_service::chain_spec::rococo_local_testnet_config()?) - } + "rococo-staging" => + Box::new(polkadot_service::chain_spec::rococo_staging_testnet_config()?), + "rococo-local" => + Box::new(polkadot_service::chain_spec::rococo_local_testnet_config()?), "rococo" => Box::new(polkadot_service::chain_spec::rococo_config()?), path => { let path = std::path::PathBuf::from(path); Box::new(polkadot_service::RococoChainSpec::from_json_file(path)?) - } + }, }) } diff --git a/polkadot/parachain/test-parachains/adder/collator/src/lib.rs b/polkadot/parachain/test-parachains/adder/collator/src/lib.rs index 80510a189d0..a7da25c30ab 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/lib.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/lib.rs @@ -16,19 +16,23 @@ //! Collator for the adder test parachain. +use futures::channel::oneshot; use futures_timer::Delay; -use polkadot_node_primitives::{Collation, CollatorFn, CollationResult, Statement, SignedFullStatement}; +use parity_scale_codec::{Decode, Encode}; +use polkadot_node_primitives::{ + Collation, CollationResult, CollatorFn, PoV, SignedFullStatement, Statement, +}; use polkadot_primitives::v1::{CollatorId, CollatorPair}; -use polkadot_node_primitives::PoV; -use parity_scale_codec::{Encode, Decode}; -use sp_core::{Pair, traits::SpawnNamed}; +use sp_core::{traits::SpawnNamed, Pair}; use std::{ collections::HashMap, - sync::{Arc, Mutex, atomic::{AtomicU32, Ordering}}, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, Mutex, + }, time::Duration, }; use test_parachain_adder::{execute, hash_state, BlockData, HeadData}; -use futures::channel::oneshot; /// The amount we add when producing a new block. /// @@ -37,11 +41,8 @@ const ADD: u64 = 2; /// Calculates the head and state for the block with the given `number`. fn calculate_head_and_state_for_number(number: u64) -> (HeadData, u64) { - let mut head = HeadData { - number: 0, - parent_hash: Default::default(), - post_state: hash_state(0), - }; + let mut head = + HeadData { number: 0, parent_hash: Default::default(), post_state: hash_state(0) }; let mut state = 0u64; @@ -89,11 +90,11 @@ impl State { add: ADD, }; - let new_head = execute(parent_head.hash(), parent_head, &block).expect("Produces valid block"); + let new_head = + execute(parent_head.hash(), parent_head, &block).expect("Produces valid block"); let new_head_arc = Arc::new(new_head.clone()); - self.head_to_state - .insert(new_head_arc.clone(), block.state.wrapping_add(ADD)); + self.head_to_state.insert(new_head_arc.clone(), block.state.wrapping_add(ADD)); self.number_to_head.insert(new_head.number, new_head_arc); (block, new_head) @@ -146,7 +147,10 @@ impl Collator { /// Create the collation function. /// /// This collation function can be plugged into the overseer to generate collations for the adder parachain. - pub fn create_collation_function(&self, spawner: impl SpawnNamed + Clone + 'static) -> CollatorFn { + pub fn create_collation_function( + &self, + spawner: impl SpawnNamed + Clone + 'static, + ) -> CollatorFn { use futures::FutureExt as _; let state = self.state.clone(); @@ -180,21 +184,29 @@ impl Collator { let (result_sender, recv) = oneshot::channel::(); let seconded_collations = seconded_collations.clone(); - spawner.spawn("adder-collator-seconded", async move { - if let Ok(res) = recv.await { - if !matches!( - res.payload(), - Statement::Seconded(s) if s.descriptor.pov_hash == compressed_pov.hash(), - ) { - log::error!("Seconded statement should match our collation: {:?}", res.payload()); - std::process::exit(-1); + spawner.spawn( + "adder-collator-seconded", + async move { + if let Ok(res) = recv.await { + if !matches!( + res.payload(), + Statement::Seconded(s) if s.descriptor.pov_hash == compressed_pov.hash(), + ) { + log::error!( + "Seconded statement should match our collation: {:?}", + res.payload() + ); + std::process::exit(-1); + } + + seconded_collations.fetch_add(1, Ordering::Relaxed); } - - seconded_collations.fetch_add(1, Ordering::Relaxed); } - }.boxed()); + .boxed(), + ); - async move { Some(CollationResult { collation, result_sender: Some(result_sender) }) }.boxed() + async move { Some(CollationResult { collation, result_sender: Some(result_sender) }) } + .boxed() }) } @@ -207,7 +219,7 @@ impl Collator { let current_block = self.state.lock().unwrap().best_block; if start_block + blocks <= current_block { - return; + return } } } @@ -222,7 +234,7 @@ impl Collator { Delay::new(Duration::from_secs(1)).await; if seconded <= seconded_collations.load(Ordering::Relaxed) { - return; + return } } } @@ -233,7 +245,7 @@ mod tests { use super::*; use futures::executor::block_on; - use polkadot_parachain::{primitives::{ValidationParams, ValidationResult}}; + use polkadot_parachain::primitives::{ValidationParams, ValidationResult}; use polkadot_primitives::v1::PersistedValidationData; #[test] @@ -243,14 +255,8 @@ mod tests { let collation_function = collator.create_collation_function(spawner); for i in 0..5 { - let parent_head = collator - .state - .lock() - .unwrap() - .number_to_head - .get(&i) - .unwrap() - .clone(); + let parent_head = + collator.state.lock().unwrap().number_to_head.get(&i).unwrap().clone(); let validation_data = PersistedValidationData { parent_head: parent_head.encode().into(), @@ -263,11 +269,7 @@ mod tests { } } - fn validate_collation( - collator: &Collator, - parent_head: HeadData, - collation: Collation, - ) { + fn validate_collation(collator: &Collator, parent_head: HeadData, collation: Collation) { use polkadot_node_core_pvf::testing::validate_candidate; let ret_buf = validate_candidate( @@ -277,7 +279,8 @@ mod tests { block_data: collation.proof_of_validity.block_data, relay_parent_number: 1, relay_parent_storage_root: Default::default(), - }.encode(), + } + .encode(), ) .unwrap(); let ret = ValidationResult::decode(&mut &ret_buf[..]).unwrap(); @@ -307,7 +310,16 @@ mod tests { } let collator = Collator::new(); - let mut second_head = collator.state.lock().unwrap().number_to_head.get(&0).cloned().unwrap().as_ref().clone(); + let mut second_head = collator + .state + .lock() + .unwrap() + .number_to_head + .get(&0) + .cloned() + .unwrap() + .as_ref() + .clone(); for _ in 1..20 { second_head = collator.state.lock().unwrap().advance(second_head.clone()).1; diff --git a/polkadot/parachain/test-parachains/adder/collator/src/main.rs b/polkadot/parachain/test-parachains/adder/collator/src/main.rs index 28f34ef5a0a..b1366abccb9 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/main.rs @@ -16,10 +16,10 @@ //! Collator for the adder test parachain. +use polkadot_cli::{Error, Result}; use polkadot_node_primitives::CollationGenerationConfig; use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage}; use polkadot_primitives::v1::Id as ParaId; -use polkadot_cli::{Error, Result}; use sc_cli::{Error as SubstrateCliError, Role, SubstrateCli}; use sp_core::hexdisplay::HexDisplay; use test_parachain_adder_collator::Collator; @@ -39,16 +39,19 @@ fn main() -> Result<()> { println!("0x{:?}", HexDisplay::from(&collator.genesis_head())); Ok::<_, Error>(()) - } + }, Some(cli::Subcommand::ExportGenesisWasm(_params)) => { let collator = Collator::new(); println!("0x{:?}", HexDisplay::from(&collator.validation_code())); Ok(()) - } + }, None => { - let runner = cli.create_runner(&cli.run.base) - .map_err(|e| SubstrateCliError::Application(Box::new(e) as Box::<(dyn 'static + Send + Sync + std::error::Error)>))?; + let runner = cli.create_runner(&cli.run.base).map_err(|e| { + SubstrateCliError::Application( + Box::new(e) as Box<(dyn 'static + Send + Sync + std::error::Error)> + ) + })?; runner.run_node_until_exit(|config| async move { let role = config.role.clone(); @@ -66,7 +69,8 @@ fn main() -> Result<()> { None, None, polkadot_service::RealOverseerGen, - ).map_err(|e| e.to_string())?; + ) + .map_err(|e| e.to_string())?; let mut overseer_handle = full_node .overseer_handle .expect("Overseer handle should be initialized for collators"); @@ -76,7 +80,8 @@ fn main() -> Result<()> { let validation_code_hex = format!("0x{:?}", HexDisplay::from(&collator.validation_code())); - let para_id = cli.run.parachain_id.map(ParaId::from).unwrap_or(DEFAULT_PARA_ID); + let para_id = + cli.run.parachain_id.map(ParaId::from).unwrap_or(DEFAULT_PARA_ID); log::info!("Running adder collator for parachain id: {}", para_id); log::info!("Genesis state: {}", genesis_head_hex); @@ -84,7 +89,8 @@ fn main() -> Result<()> { let config = CollationGenerationConfig { key: collator.collator_key(), - collator: collator.create_collation_function(full_node.task_manager.spawn_handle()), + collator: collator + .create_collation_function(full_node.task_manager.spawn_handle()), para_id, }; overseer_handle @@ -96,10 +102,10 @@ fn main() -> Result<()> { .await; Ok(full_node.task_manager) - } + }, } }) - } + }, }?; Ok(()) } diff --git a/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs index 574a9abf84d..3d9530d02ed 100644 --- a/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs +++ b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs @@ -22,9 +22,9 @@ const PUPPET_EXE: &str = env!("CARGO_BIN_EXE_adder_collator_puppet_worker"); // If this test is failing, make sure to run all tests with the `real-overseer` feature being enabled. #[substrate_test_utils::test] async fn collating_using_adder_collator(task_executor: sc_service::TaskExecutor) { - use sp_keyring::AccountKeyring::*; use futures::join; use polkadot_primitives::v1::Id as ParaId; + use sp_keyring::AccountKeyring::*; let mut builder = sc_cli::LoggerBuilder::new(""); builder.with_colors(false); @@ -35,7 +35,8 @@ async fn collating_using_adder_collator(task_executor: sc_service::TaskExecutor) // start alice let alice = polkadot_test_service::run_validator_node( task_executor.clone(), - Alice, || {}, + Alice, + || {}, vec![], Some(PUPPET_EXE.into()), ); @@ -53,11 +54,7 @@ async fn collating_using_adder_collator(task_executor: sc_service::TaskExecutor) // register parachain alice - .register_parachain( - para_id, - collator.validation_code().to_vec(), - collator.genesis_head(), - ) + .register_parachain(para_id, collator.validation_code().to_vec(), collator.genesis_head()) .await .unwrap(); @@ -70,11 +67,13 @@ async fn collating_using_adder_collator(task_executor: sc_service::TaskExecutor) collator.collator_key(), ); - charlie.register_collator( - collator.collator_key(), - para_id, - collator.create_collation_function(charlie.task_manager.spawn_handle()), - ).await; + charlie + .register_collator( + collator.collator_key(), + para_id, + collator.create_collation_function(charlie.task_manager.spawn_handle()), + ) + .await; // Wait until the parachain has 4 blocks produced. collator.wait_for_blocks(4).await; diff --git a/polkadot/parachain/test-parachains/adder/src/lib.rs b/polkadot/parachain/test-parachains/adder/src/lib.rs index 37208efbca1..096c5eac969 100644 --- a/polkadot/parachain/test-parachains/adder/src/lib.rs +++ b/polkadot/parachain/test-parachains/adder/src/lib.rs @@ -17,10 +17,12 @@ //! Basic parachain that adds a number as part of its state. #![no_std] +#![cfg_attr( + not(feature = "std"), + feature(core_intrinsics, lang_items, core_panic_info, alloc_error_handler) +)] -#![cfg_attr(not(feature = "std"), feature(core_intrinsics, lang_items, core_panic_info, alloc_error_handler))] - -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; use tiny_keccak::{Hasher as _, Keccak}; #[cfg(not(feature = "std"))] @@ -45,8 +47,10 @@ fn keccak256(input: &[u8]) -> [u8; 32] { /// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. #[cfg(feature = "std")] pub fn wasm_binary_unwrap() -> &'static [u8] { - WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ - supported with the flag disabled.") + WASM_BINARY.expect( + "Development wasm binary is not available. Testing is only \ + supported with the flag disabled.", + ) } /// Head data for this parachain. @@ -93,14 +97,10 @@ pub fn execute( assert_eq!(parent_hash, parent_head.hash()); if hash_state(block_data.state) != parent_head.post_state { - return Err(StateMismatch); + return Err(StateMismatch) } let new_state = block_data.state.wrapping_add(block_data.add); - Ok(HeadData { - number: parent_head.number + 1, - parent_hash, - post_state: hash_state(new_state), - }) + Ok(HeadData { number: parent_head.number + 1, parent_hash, post_state: hash_state(new_state) }) } diff --git a/polkadot/parachain/test-parachains/adder/src/wasm_validation.rs b/polkadot/parachain/test-parachains/adder/src/wasm_validation.rs index 4de5784adf2..240df6cb2c0 100644 --- a/polkadot/parachain/test-parachains/adder/src/wasm_validation.rs +++ b/polkadot/parachain/test-parachains/adder/src/wasm_validation.rs @@ -16,32 +16,30 @@ //! WASM validation for adder parachain. -use crate::{HeadData, BlockData}; +use crate::{BlockData, HeadData}; use core::panic; +use parachain::primitives::{HeadData as GenericHeadData, ValidationResult}; +use parity_scale_codec::{Decode, Encode}; use sp_std::vec::Vec; -use parachain::primitives::{ValidationResult, HeadData as GenericHeadData}; -use parity_scale_codec::{Encode, Decode}; #[no_mangle] pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 { let params = unsafe { parachain::load_params(params, len) }; - let parent_head = HeadData::decode(&mut ¶ms.parent_head.0[..]) - .expect("invalid parent head format."); + let parent_head = + HeadData::decode(&mut ¶ms.parent_head.0[..]).expect("invalid parent head format."); - let block_data = BlockData::decode(&mut ¶ms.block_data.0[..]) - .expect("invalid block data format."); + let block_data = + BlockData::decode(&mut ¶ms.block_data.0[..]).expect("invalid block data format."); let parent_hash = crate::keccak256(¶ms.parent_head.0[..]); let new_head = crate::execute(parent_hash, parent_head, &block_data).expect("Executes block"); - parachain::write_result( - &ValidationResult { - head_data: GenericHeadData(new_head.encode()), - new_validation_code: None, - upward_messages: sp_std::vec::Vec::new(), - horizontal_messages: sp_std::vec::Vec::new(), - processed_downward_messages: 0, - hrmp_watermark: params.relay_parent_number, - } - ) + parachain::write_result(&ValidationResult { + head_data: GenericHeadData(new_head.encode()), + new_validation_code: None, + upward_messages: sp_std::vec::Vec::new(), + horizontal_messages: sp_std::vec::Vec::new(), + processed_downward_messages: 0, + hrmp_watermark: params.relay_parent_number, + }) } diff --git a/polkadot/parachain/test-parachains/halt/build.rs b/polkadot/parachain/test-parachains/halt/build.rs index ac1ce327cf9..1725943d37a 100644 --- a/polkadot/parachain/test-parachains/halt/build.rs +++ b/polkadot/parachain/test-parachains/halt/build.rs @@ -17,8 +17,5 @@ use substrate_wasm_builder::WasmBuilder; fn main() { - WasmBuilder::new() - .with_current_project() - .export_heap_base() - .build() + WasmBuilder::new().with_current_project().export_heap_base().build() } diff --git a/polkadot/parachain/test-parachains/halt/src/lib.rs b/polkadot/parachain/test-parachains/halt/src/lib.rs index 00314033a4d..0c56cfe6393 100644 --- a/polkadot/parachain/test-parachains/halt/src/lib.rs +++ b/polkadot/parachain/test-parachains/halt/src/lib.rs @@ -17,7 +17,10 @@ //! Basic parachain that executes forever. #![no_std] -#![cfg_attr(not(feature = "std"), feature(core_intrinsics, lang_items, core_panic_info, alloc_error_handler))] +#![cfg_attr( + not(feature = "std"), + feature(core_intrinsics, lang_items, core_panic_info, alloc_error_handler) +)] // Make the WASM binary available. #[cfg(feature = "std")] @@ -26,17 +29,17 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); #[cfg(feature = "std")] /// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. pub fn wasm_binary_unwrap() -> &'static [u8] { - WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ - supported with the flag disabled.") + WASM_BINARY.expect( + "Development wasm binary is not available. Testing is only \ + supported with the flag disabled.", + ) } #[cfg(not(feature = "std"))] #[panic_handler] #[no_mangle] pub fn panic(_info: &core::panic::PanicInfo) -> ! { - unsafe { - core::intrinsics::abort() - } + unsafe { core::intrinsics::abort() } } #[cfg(not(feature = "std"))] @@ -50,6 +53,6 @@ pub fn oom(_: core::alloc::Layout) -> ! { #[cfg(not(feature = "std"))] #[no_mangle] -pub extern fn validate_block(params: *const u8, len: usize) -> u64 { +pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 { loop {} } diff --git a/polkadot/primitives/src/lib.rs b/polkadot/primitives/src/lib.rs index 82a5e7ca2e0..1c549da9427 100644 --- a/polkadot/primitives/src/lib.rs +++ b/polkadot/primitives/src/lib.rs @@ -17,7 +17,6 @@ //! Polkadot types shared between the runtime and the Node-side code. #![warn(missing_docs)] - #![cfg_attr(not(feature = "std"), no_std)] pub mod v0; diff --git a/polkadot/primitives/src/v0.rs b/polkadot/primitives/src/v0.rs index 76274c40f25..1cbeb916d48 100644 --- a/polkadot/primitives/src/v0.rs +++ b/polkadot/primitives/src/v0.rs @@ -17,28 +17,26 @@ //! Primitives which are necessary for parachain execution from a relay-chain //! perspective. -use sp_std::prelude::*; -use sp_std::cmp::Ordering; +use sp_std::{cmp::Ordering, prelude::*}; -use parity_scale_codec::{Encode, Decode}; use bitvec::vec::BitVec; -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; +use parity_scale_codec::{Decode, Encode}; #[cfg(feature = "std")] use parity_util_mem::{MallocSizeOf, MallocSizeOfOps}; +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; +use application_crypto::KeyTypeId; +use inherents::InherentIdentifier; use primitives::RuntimeDebug; use runtime_primitives::traits::{AppVerify, Block as BlockT}; -use inherents::InherentIdentifier; -use application_crypto::KeyTypeId; -pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify, IdentifyAccount}; -pub use polkadot_core_primitives::*; pub use parity_scale_codec::Compact; +pub use polkadot_core_primitives::*; +pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, IdentifyAccount, Verify}; pub use polkadot_parachain::primitives::{ - Id, LOWEST_USER_ID, UpwardMessage, HeadData, BlockData, - ValidationCode, + BlockData, HeadData, Id, UpwardMessage, ValidationCode, LOWEST_USER_ID, }; /// The key type ID for a collator key. @@ -180,9 +178,7 @@ pub struct Info { } /// An `Info` value for a standard leased parachain. -pub const PARACHAIN_INFO: Info = Info { - scheduling: Scheduling::Always, -}; +pub const PARACHAIN_INFO: Info = Info { scheduling: Scheduling::Always }; /// Auxiliary for when there's an attempt to swap two parachains/parathreads. pub trait SwapAux { @@ -200,8 +196,12 @@ pub trait SwapAux { } impl SwapAux for () { - fn ensure_can_swap(_: Id, _: Id) -> Result<(), &'static str> { Err("Swapping disabled") } - fn on_swap(_: Id, _: Id) -> Result<(), &'static str> { Err("Swapping disabled") } + fn ensure_can_swap(_: Id, _: Id) -> Result<(), &'static str> { + Err("Swapping disabled") + } + fn on_swap(_: Id, _: Id) -> Result<(), &'static str> { + Err("Swapping disabled") + } } /// Identifier for a chain, either one of a number of parachains or the relay chain. @@ -300,7 +300,7 @@ fn check_collator_signature>( pov_block_hash: &H, collator: &CollatorId, signature: &CollatorSignature, -) -> Result<(),()> { +) -> Result<(), ()> { let payload = collator_signature_payload(relay_parent, parachain_index, pov_block_hash); if signature.verify(&payload[..], collator) { Ok(()) @@ -371,10 +371,7 @@ impl, N> CandidateReceipt { commitments, }; - let omitted = OmittedValidationData { - global_validation, - local_validation, - }; + let omitted = OmittedValidationData { global_validation, local_validation }; (abridged, omitted) } @@ -390,7 +387,8 @@ impl Ord for CandidateReceipt { fn cmp(&self, other: &Self) -> Ordering { // TODO: compare signatures or something more sane // https://github.com/paritytech/polkadot/issues/222 - self.parachain_index.cmp(&other.parachain_index) + self.parachain_index + .cmp(&other.parachain_index) .then_with(|| self.head_data.cmp(&other.head_data)) } } @@ -439,7 +437,7 @@ pub struct CommitedCandidateReceipt { pub descriptor: CandidateDescriptor, /// The commitments of the candidate receipt. - pub commitments: CandidateCommitments + pub commitments: CandidateCommitments, } impl + Encode> AbridgedCandidateReceipt { @@ -480,10 +478,7 @@ impl AbridgedCandidateReceipt { commitments, } = self; - let OmittedValidationData { - global_validation, - local_validation, - } = omitted; + let OmittedValidationData { global_validation, local_validation } = omitted; CandidateReceipt { parachain_index, @@ -542,7 +537,8 @@ impl Ord for AbridgedCandidateReceipt { fn cmp(&self, other: &Self) -> Ordering { // TODO: compare signatures or something more sane // https://github.com/paritytech/polkadot/issues/222 - self.parachain_index.cmp(&other.parachain_index) + self.parachain_index + .cmp(&other.parachain_index) .then_with(|| self.head_data.cmp(&other.head_data)) } } @@ -711,10 +707,12 @@ impl parity_scale_codec::Encode for CompactStatement { } impl parity_scale_codec::Decode for CompactStatement { - fn decode(input: &mut I) -> Result { + fn decode( + input: &mut I, + ) -> Result { let maybe_magic = <[u8; 4]>::decode(input)?; if maybe_magic != BACKING_STATEMENT_MAGIC { - return Err(parity_scale_codec::Error::from("invalid magic string")); + return Err(parity_scale_codec::Error::from("invalid magic string")) } Ok(match CompactStatementInner::decode(input)? { @@ -764,14 +762,10 @@ impl ValidityAttestation { signing_context: &SigningContext, ) -> Vec { match *self { - ValidityAttestation::Implicit(_) => ( - CompactStatement::Seconded(candidate_hash), - signing_context, - ).encode(), - ValidityAttestation::Explicit(_) => ( - CompactStatement::Valid(candidate_hash), - signing_context, - ).encode(), + ValidityAttestation::Implicit(_) => + (CompactStatement::Seconded(candidate_hash), signing_context).encode(), + ValidityAttestation::Explicit(_) => + (CompactStatement::Valid(candidate_hash), signing_context).encode(), } } } @@ -906,14 +900,15 @@ pub mod fisherman { /// An `AppCrypto` type to allow submitting signed transactions using the fisherman /// application key as signer. pub struct FishermanAppCrypto; - impl frame_system::offchain::AppCrypto<::Signer, Signature> for FishermanAppCrypto { + impl frame_system::offchain::AppCrypto<::Signer, Signature> + for FishermanAppCrypto + { type RuntimeAppPublic = FishermanId; type GenericSignature = primitives::sr25519::Signature; type GenericPublic = primitives::sr25519::Public; } } - #[cfg(test)] mod tests { use super::*; @@ -932,10 +927,7 @@ mod tests { let h = Hash::default(); assert_eq!(h.as_ref().len(), 32); - let _payload = collator_signature_payload( - &Hash::repeat_byte(1), - &5u32.into(), - &Hash::repeat_byte(2), - ); + let _payload = + collator_signature_payload(&Hash::repeat_byte(1), &5u32.into(), &Hash::repeat_byte(2)); } } diff --git a/polkadot/primitives/src/v1/mod.rs b/polkadot/primitives/src/v1/mod.rs index b12d63e529d..357c0336e79 100644 --- a/polkadot/primitives/src/v1/mod.rs +++ b/polkadot/primitives/src/v1/mod.rs @@ -16,36 +16,35 @@ //! `V1` Primitives. -use sp_std::prelude::*; -use sp_std::collections::btree_map::BTreeMap; -use parity_scale_codec::{Encode, Decode}; use bitvec::vec::BitVec; +use parity_scale_codec::{Decode, Encode}; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; +use application_crypto::KeyTypeId; +use inherents::InherentIdentifier; use primitives::RuntimeDebug; use runtime_primitives::traits::{AppVerify, Header as HeaderT}; -use inherents::InherentIdentifier; use sp_arithmetic::traits::{BaseArithmetic, Saturating}; -use application_crypto::KeyTypeId; pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT}; // Export some core primitives. pub use polkadot_core_primitives::v1::{ - BlockNumber, Moment, Signature, AccountPublic, AccountId, AccountIndex, ChainId, Hash, Nonce, - Balance, Header, Block, BlockId, UncheckedExtrinsic, Remark, DownwardMessage, - InboundDownwardMessage, CandidateHash, InboundHrmpMessage, OutboundHrmpMessage, + AccountId, AccountIndex, AccountPublic, Balance, Block, BlockId, BlockNumber, CandidateHash, + ChainId, DownwardMessage, Hash, Header, InboundDownwardMessage, InboundHrmpMessage, Moment, + Nonce, OutboundHrmpMessage, Remark, Signature, UncheckedExtrinsic, }; // Export some polkadot-parachain primitives pub use polkadot_parachain::primitives::{ - Id, LOWEST_USER_ID, LOWEST_PUBLIC_ID, HrmpChannelId, UpwardMessage, HeadData, ValidationCode, ValidationCodeHash, + HeadData, HrmpChannelId, Id, UpwardMessage, ValidationCode, ValidationCodeHash, + LOWEST_PUBLIC_ID, LOWEST_USER_ID, }; // Export some basic parachain primitives from v0. pub use crate::v0::{ - CollatorId, CollatorSignature, PARACHAIN_KEY_TYPE_ID, ValidatorId, ValidatorIndex, - ValidatorSignature, SigningContext, ValidityAttestation, - CompactStatement, + CollatorId, CollatorSignature, CompactStatement, SigningContext, ValidatorId, ValidatorIndex, + ValidatorSignature, ValidityAttestation, PARACHAIN_KEY_TYPE_ID, }; #[cfg(feature = "std")] @@ -53,23 +52,23 @@ use parity_util_mem::{MallocSizeOf, MallocSizeOfOps}; // More exports from v0 for std. #[cfg(feature = "std")] -pub use crate::v0::{ValidatorPair, CollatorPair}; +pub use crate::v0::{CollatorPair, ValidatorPair}; -pub use sp_staking::SessionIndex; pub use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; pub use sp_consensus_slots::Slot; +pub use sp_staking::SessionIndex; /// Signed data. mod signed; -pub use signed::{Signed, UncheckedSigned, EncodeAs}; +pub use signed::{EncodeAs, Signed, UncheckedSigned}; /// A declarations of storage keys where an external observer can find some interesting data. pub mod well_known_keys { - use super::{Id, HrmpChannelId}; + use super::{HrmpChannelId, Id}; use hex_literal::hex; + use parity_scale_codec::Encode as _; use sp_io::hashing::twox_64; use sp_std::prelude::*; - use parity_scale_codec::Encode as _; // A note on generating these magic values below: // @@ -105,7 +104,8 @@ pub mod well_known_keys { let prefix = hex!["f5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e"]; para_id.using_encoded(|para_id: &[u8]| { - prefix.as_ref() + prefix + .as_ref() .iter() .chain(twox_64(para_id).iter()) .chain(para_id.iter()) @@ -121,7 +121,8 @@ pub mod well_known_keys { let prefix = hex!["6a0da05ca59913bc38a8630590f2627cb6604cff828a6e3f579ca6c59ace013d"]; channel.using_encoded(|channel: &[u8]| { - prefix.as_ref() + prefix + .as_ref() .iter() .chain(twox_64(channel).iter()) .chain(channel.iter()) @@ -137,7 +138,8 @@ pub mod well_known_keys { let prefix = hex!["6a0da05ca59913bc38a8630590f2627c1d3719f5b0b12c7105c073c507445948"]; para_id.using_encoded(|para_id: &[u8]| { - prefix.as_ref() + prefix + .as_ref() .iter() .chain(twox_64(para_id).iter()) .chain(para_id.iter()) @@ -153,7 +155,8 @@ pub mod well_known_keys { let prefix = hex!["6a0da05ca59913bc38a8630590f2627cf12b746dcf32e843354583c9702cc020"]; para_id.using_encoded(|para_id: &[u8]| { - prefix.as_ref() + prefix + .as_ref() .iter() .chain(twox_64(para_id).iter()) .chain(para_id.iter()) @@ -170,7 +173,8 @@ pub mod well_known_keys { let prefix = hex!["63f78c98723ddc9073523ef3beefda0c4d7fefc408aac59dbfe80a72ac8e3ce5"]; para_id.using_encoded(|para_id: &[u8]| { - prefix.as_ref() + prefix + .as_ref() .iter() .chain(twox_64(para_id).iter()) .chain(para_id.iter()) @@ -180,7 +184,6 @@ pub mod well_known_keys { } } - /// Unique identifier for the Parachains Inherent pub const PARACHAINS_INHERENT_IDENTIFIER: InherentIdentifier = *b"parachn0"; @@ -338,7 +341,10 @@ impl CandidateReceipt { } /// Computes the blake2-256 hash of the receipt. - pub fn hash(&self) -> CandidateHash where H: Encode { + pub fn hash(&self) -> CandidateHash + where + H: Encode, + { CandidateHash(BlakeTwo256::hash_of(self)) } } @@ -386,12 +392,18 @@ impl CommittedCandidateReceipt { /// /// This computes the canonical hash, not the hash of the directly encoded data. /// Thus this is a shortcut for `candidate.to_plain().hash()`. - pub fn hash(&self) -> CandidateHash where H: Encode { + pub fn hash(&self) -> CandidateHash + where + H: Encode, + { self.to_plain().hash() } /// Does this committed candidate receipt corresponds to the given [`CandidateReceipt`]? - pub fn corresponds_to(&self, receipt: &CandidateReceipt) -> bool where H: PartialEq { + pub fn corresponds_to(&self, receipt: &CandidateReceipt) -> bool + where + H: PartialEq, + { receipt.descriptor == self.descriptor && receipt.commitments_hash == self.commitments.hash() } } @@ -406,7 +418,9 @@ impl Ord for CommittedCandidateReceipt { fn cmp(&self, other: &Self) -> sp_std::cmp::Ordering { // TODO: compare signatures or something more sane // https://github.com/paritytech/polkadot/issues/222 - self.descriptor().para_id.cmp(&other.descriptor().para_id) + self.descriptor() + .para_id + .cmp(&other.descriptor().para_id) .then_with(|| self.commitments.head_data.cmp(&other.commitments.head_data)) } } @@ -475,7 +489,6 @@ impl CandidateCommitments { } } - /// A bitfield concerning availability of backed candidates. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] pub struct AvailabilityBitfield(pub BitVec); @@ -486,7 +499,6 @@ impl From> for AvailabilityBitfield { } } - /// A signed compact statement, suitable to be sent to the chain. pub type SignedStatement = Signed; @@ -519,12 +531,18 @@ impl BackedCandidate { } /// Compute this candidate's hash. - pub fn hash(&self) -> CandidateHash where H: Clone + Encode { + pub fn hash(&self) -> CandidateHash + where + H: Clone + Encode, + { self.candidate.hash() } /// Get this candidate's receipt. - pub fn receipt(&self) -> CandidateReceipt where H: Clone { + pub fn receipt(&self) -> CandidateReceipt + where + H: Clone, + { self.candidate.to_plain() } } @@ -557,7 +575,10 @@ pub fn check_candidate_backing + Clone + Encode>( let hash = backed.candidate.hash(); let mut signed = 0; - for ((val_in_group_idx, _), attestation) in backed.validator_indices.iter().enumerate() + for ((val_in_group_idx, _), attestation) in backed + .validator_indices + .iter() + .enumerate() .filter(|(_, signed)| **signed) .zip(backed.validity_votes.iter()) { @@ -644,8 +665,12 @@ impl GroupRotationInfo { /// /// `core_index` should be less than `cores`, which is capped at `u32::max()`. pub fn group_for_core(&self, core_index: CoreIndex, cores: usize) -> GroupIndex { - if self.group_rotation_frequency == 0 { return GroupIndex(core_index.0) } - if cores == 0 { return GroupIndex(0) } + if self.group_rotation_frequency == 0 { + return GroupIndex(core_index.0) + } + if cores == 0 { + return GroupIndex(0) + } let cores = sp_std::cmp::min(cores, u32::MAX as usize); let blocks_since_start = self.now.saturating_sub(self.session_start_block); @@ -662,8 +687,12 @@ impl GroupRotationInfo { /// /// `core_index` should be less than `cores`, which is capped at `u32::max()`. pub fn core_for_group(&self, group_index: GroupIndex, cores: usize) -> CoreIndex { - if self.group_rotation_frequency == 0 { return CoreIndex(group_index.0) } - if cores == 0 { return CoreIndex(0) } + if self.group_rotation_frequency == 0 { + return CoreIndex(group_index.0) + } + if cores == 0 { + return CoreIndex(0) + } let cores = sp_std::cmp::min(cores, u32::MAX as usize); let blocks_since_start = self.now.saturating_sub(self.session_start_block); @@ -694,17 +723,15 @@ impl GroupRotationInfo { /// is 10 and the rotation frequency is 5, this should return 15. pub fn next_rotation_at(&self) -> N { let cycle_once = self.now + self.group_rotation_frequency; - cycle_once - ( - cycle_once.saturating_sub(self.session_start_block) % self.group_rotation_frequency - ) + cycle_once - + (cycle_once.saturating_sub(self.session_start_block) % self.group_rotation_frequency) } /// Returns the block number of the last rotation before or including the current block. If the /// current block is 10 and the rotation frequency is 5, this should return 10. pub fn last_rotation_at(&self) -> N { - self.now - ( - self.now.saturating_sub(self.session_start_block) % self.group_rotation_frequency - ) + self.now - + (self.now.saturating_sub(self.session_start_block) % self.group_rotation_frequency) } } @@ -713,7 +740,6 @@ impl GroupRotationInfo { #[cfg_attr(feature = "std", derive(Debug, PartialEq, MallocSizeOf))] pub struct OccupiedCore { // NOTE: this has no ParaId as it can be deduced from the candidate descriptor. - /// If this core is freed by availability, this is the assignment that is next up on this /// core, if any. None if there is nothing queued for this core. pub next_up_on_available: Option, @@ -861,10 +887,7 @@ pub struct ApprovalVote(pub CandidateHash); impl ApprovalVote { /// Yields the signing payload for this approval vote. - pub fn signing_payload( - &self, - session_index: SessionIndex, - ) -> Vec { + pub fn signing_payload(&self, session_index: SessionIndex) -> Vec { const MAGIC: [u8; 4] = *b"APPR"; (MAGIC, &self.0, session_index).encode() @@ -1037,14 +1060,14 @@ pub enum ConsensusLog { /// In practice, these are issued when on-chain logic has detected an /// invalid parachain block within its own chain, due to a dispute. #[codec(index = 4)] - Revert(BlockNumber) + Revert(BlockNumber), } impl ConsensusLog { /// Attempt to convert a reference to a generic digest item into a consensus log. - pub fn from_digest_item(digest_item: &runtime_primitives::DigestItem) - -> Result, parity_scale_codec::Error> - { + pub fn from_digest_item( + digest_item: &runtime_primitives::DigestItem, + ) -> Result, parity_scale_codec::Error> { match digest_item { runtime_primitives::DigestItem::Consensus(id, encoded) if id == &POLKADOT_ENGINE_ID => Ok(Some(Self::decode(&mut &encoded[..])?)), @@ -1075,36 +1098,24 @@ pub enum DisputeStatement { impl DisputeStatement { /// Get the payload data for this type of dispute statement. pub fn payload_data(&self, candidate_hash: CandidateHash, session: SessionIndex) -> Vec { - match *self { - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) => { - ExplicitDisputeStatement { - valid: true, - candidate_hash, - session, - }.signing_payload() - }, - DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded(inclusion_parent)) => { - CompactStatement::Seconded(candidate_hash).signing_payload(&SigningContext { - session_index: session, - parent_hash: inclusion_parent, - }) - }, - DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)) => { + match *self { + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: true, candidate_hash, session }.signing_payload(), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded( + inclusion_parent, + )) => CompactStatement::Seconded(candidate_hash).signing_payload(&SigningContext { + session_index: session, + parent_hash: inclusion_parent, + }), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)) => CompactStatement::Valid(candidate_hash).signing_payload(&SigningContext { session_index: session, parent_hash: inclusion_parent, - }) - }, - DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) => { - ApprovalVote(candidate_hash).signing_payload(session) - }, - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) => { - ExplicitDisputeStatement { - valid: false, - candidate_hash, - session, - }.signing_payload() - }, + }), + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) => + ApprovalVote(candidate_hash).signing_payload(session), + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: false, candidate_hash, session }.signing_payload(), } } @@ -1118,7 +1129,7 @@ impl DisputeStatement { ) -> Result<(), ()> { let payload = self.payload_data(candidate_hash, session); - if validator_signature.verify(&payload[..] , &validator_public) { + if validator_signature.verify(&payload[..], &validator_public) { Ok(()) } else { Err(()) @@ -1246,11 +1257,8 @@ mod tests { #[test] fn group_rotation_info_calculations() { - let info = GroupRotationInfo { - session_start_block: 10u32, - now: 15, - group_rotation_frequency: 5, - }; + let info = + GroupRotationInfo { session_start_block: 10u32, now: 15, group_rotation_frequency: 5 }; assert_eq!(info.next_rotation_at(), 20); assert_eq!(info.last_rotation_at(), 15); @@ -1258,7 +1266,6 @@ mod tests { #[test] fn group_for_core_is_core_for_group() { - for cores in 1..=256 { for rotations in 0..(cores * 2) { let info = GroupRotationInfo { @@ -1273,7 +1280,6 @@ mod tests { } } } - } #[test] diff --git a/polkadot/primitives/src/v1/signed.rs b/polkadot/primitives/src/v1/signed.rs index 28d84022aac..66908216ebb 100644 --- a/polkadot/primitives/src/v1/signed.rs +++ b/polkadot/primitives/src/v1/signed.rs @@ -14,20 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; -use sp_std::prelude::Vec; -#[cfg(feature = "std")] -use sp_std::convert::TryInto; #[cfg(feature = "std")] use application_crypto::AppKey; #[cfg(feature = "std")] -use sp_keystore::{CryptoStore, SyncCryptoStorePtr, Error as KeystoreError}; +use sp_keystore::{CryptoStore, Error as KeystoreError, SyncCryptoStorePtr}; +#[cfg(feature = "std")] +use sp_std::convert::TryInto; +use sp_std::prelude::Vec; use primitives::RuntimeDebug; use runtime_primitives::traits::AppVerify; -use crate::v0::{SigningContext, ValidatorId, ValidatorSignature, ValidatorIndex}; +use crate::v0::{SigningContext, ValidatorId, ValidatorIndex, ValidatorSignature}; /// Signed data with signature already verified. /// @@ -95,7 +95,7 @@ impl, RealPayload: Encode> Signed( unchecked: UncheckedSigned, context: &SigningContext, - key: &ValidatorId + key: &ValidatorId, ) -> Result> { if unchecked.check_signature(context, key).is_ok() { Ok(Self(unchecked)) @@ -134,7 +134,10 @@ impl, RealPayload: Encode> Signed Signed where for<'a> &'a Payload: Into { + pub fn convert_payload(&self) -> Signed + where + for<'a> &'a Payload: Into, + { Signed(self.0.unchecked_convert_payload()) } } @@ -153,19 +156,14 @@ impl, RealPayload: Encode> UncheckedSigned Self { - Self { - payload, - validator_index, - signature, - real_payload: std::marker::PhantomData, - } + Self { payload, validator_index, signature, real_payload: std::marker::PhantomData } } /// Check signature and convert to `Signed` if successful. pub fn try_into_checked( self, context: &SigningContext, - key: &ValidatorId + key: &ValidatorId, ) -> Result, Self> { Signed::try_from_unchecked(self, context, key) } @@ -195,7 +193,10 @@ impl, RealPayload: Encode> UncheckedSigned UncheckedSigned where for<'a> &'a Payload: Into { + pub fn unchecked_convert_payload(&self) -> UncheckedSigned + where + for<'a> &'a Payload: Into, + { UncheckedSigned { signature: self.signature.clone(), validator_index: self.validator_index, @@ -221,15 +222,12 @@ impl, RealPayload: Encode> UncheckedSigned Result, KeystoreError> { let data = Self::payload_data(&payload, context); - let signature = CryptoStore::sign_with( - &**keystore, - ValidatorId::ID, - &key.into(), - &data, - ).await?; + let signature = + CryptoStore::sign_with(&**keystore, ValidatorId::ID, &key.into(), &data).await?; let signature = match signature { - Some(sig) => sig.try_into().map_err(|_| KeystoreError::KeyNotSupported(ValidatorId::ID))?, + Some(sig) => + sig.try_into().map_err(|_| KeystoreError::KeyNotSupported(ValidatorId::ID))?, None => return Ok(None), }; @@ -242,14 +240,23 @@ impl, RealPayload: Encode> UncheckedSigned(&self, context: &SigningContext, key: &ValidatorId) -> Result<(), ()> { + fn check_signature( + &self, + context: &SigningContext, + key: &ValidatorId, + ) -> Result<(), ()> { let data = Self::payload_data(&self.payload, context); - if self.signature.verify(data.as_slice(), key) { Ok(()) } else { Err(()) } + if self.signature.verify(data.as_slice(), key) { + Ok(()) + } else { + Err(()) + } } - } -impl From> for UncheckedSigned { +impl From> + for UncheckedSigned +{ fn from(signed: Signed) -> Self { signed.0 } diff --git a/polkadot/rpc/src/lib.rs b/polkadot/rpc/src/lib.rs index 361e1d21fea..262a698a0e3 100644 --- a/polkadot/rpc/src/lib.rs +++ b/polkadot/rpc/src/lib.rs @@ -20,20 +20,22 @@ use std::sync::Arc; -use polkadot_primitives::v0::{Block, BlockNumber, AccountId, Nonce, Balance, Hash}; +use polkadot_primitives::v0::{AccountId, Balance, Block, BlockNumber, Hash, Nonce}; +use sc_client_api::{ + light::{Fetcher, RemoteBlockchain}, + AuxStore, +}; +use sc_consensus_babe::Epoch; +use sc_finality_grandpa::FinalityProofProvider; +pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; +use sc_sync_state_rpc::{SyncStateRpcApi, SyncStateRpcHandler}; use sp_api::ProvideRuntimeApi; -use txpool_api::TransactionPool; use sp_block_builder::BlockBuilder; -use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError}; +use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; use sp_consensus::SelectChain; use sp_consensus_babe::BabeApi; use sp_keystore::SyncCryptoStorePtr; -use sc_client_api::AuxStore; -use sc_client_api::light::{Fetcher, RemoteBlockchain}; -use sc_consensus_babe::Epoch; -use sc_finality_grandpa::FinalityProofProvider; -use sc_sync_state_rpc::{SyncStateRpcApi, SyncStateRpcHandler}; -pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; +use txpool_api::TransactionPool; /// A type representing all RPC extensions. pub type RpcExtension = jsonrpc_core::IoHandler; @@ -103,9 +105,15 @@ pub struct FullDeps { } /// Instantiate all RPC extensions. -pub fn create_full(deps: FullDeps) -> RpcExtension where - C: ProvideRuntimeApi + HeaderBackend + AuxStore + - HeaderMetadata + Send + Sync + 'static, +pub fn create_full(deps: FullDeps) -> RpcExtension +where + C: ProvideRuntimeApi + + HeaderBackend + + AuxStore + + HeaderMetadata + + Send + + Sync + + 'static, C::Api: frame_rpc_system::AccountNonceApi, C::Api: pallet_mmr_rpc::MmrRuntimeApi::Hash>, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, @@ -117,27 +125,15 @@ pub fn create_full(deps: FullDeps) -> RpcExtension whe B::State: sc_client_api::StateBackend>, { use frame_rpc_system::{FullSystem, SystemApi}; - use pallet_mmr_rpc::{MmrApi, Mmr}; + use pallet_mmr_rpc::{Mmr, MmrApi}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; use sc_consensus_babe_rpc::BabeRpcHandler; use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler}; let mut io = jsonrpc_core::IoHandler::default(); - let FullDeps { - client, - pool, - select_chain, - chain_spec, - deny_unsafe, - babe, - grandpa, - beefy, - } = deps; - let BabeDeps { - keystore, - babe_config, - shared_epoch_changes, - } = babe; + let FullDeps { client, pool, select_chain, chain_spec, deny_unsafe, babe, grandpa, beefy } = + deps; + let BabeDeps { keystore, babe_config, shared_epoch_changes } = babe; let GrandpaDeps { shared_voter_state, shared_authority_set, @@ -146,45 +142,31 @@ pub fn create_full(deps: FullDeps) -> RpcExtension whe finality_provider, } = grandpa; - io.extend_with( - SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)) - ); - io.extend_with( - TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone())) - ); - io.extend_with( - MmrApi::to_delegate(Mmr::new(client.clone())) - ); - io.extend_with( - sc_consensus_babe_rpc::BabeApi::to_delegate( - BabeRpcHandler::new( - client.clone(), - shared_epoch_changes.clone(), - keystore, - babe_config, - select_chain, - deny_unsafe, - ) - ) - ); - io.extend_with( - GrandpaApi::to_delegate(GrandpaRpcHandler::new( - shared_authority_set.clone(), - shared_voter_state, - justification_stream, - subscription_executor, - finality_provider, - )) - ); - io.extend_with( - SyncStateRpcApi::to_delegate(SyncStateRpcHandler::new( - chain_spec, - client, - shared_authority_set, - shared_epoch_changes, - deny_unsafe, - )) - ); + io.extend_with(SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe))); + io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone()))); + io.extend_with(MmrApi::to_delegate(Mmr::new(client.clone()))); + io.extend_with(sc_consensus_babe_rpc::BabeApi::to_delegate(BabeRpcHandler::new( + client.clone(), + shared_epoch_changes.clone(), + keystore, + babe_config, + select_chain, + deny_unsafe, + ))); + io.extend_with(GrandpaApi::to_delegate(GrandpaRpcHandler::new( + shared_authority_set.clone(), + shared_voter_state, + justification_stream, + subscription_executor, + finality_provider, + ))); + io.extend_with(SyncStateRpcApi::to_delegate(SyncStateRpcHandler::new( + chain_spec, + client, + shared_authority_set, + shared_epoch_changes, + deny_unsafe, + ))); io.extend_with(beefy_gadget_rpc::BeefyApi::to_delegate( beefy_gadget_rpc::BeefyRpcHandler::new( @@ -198,26 +180,24 @@ pub fn create_full(deps: FullDeps) -> RpcExtension whe /// Instantiate all RPC extensions for light node. pub fn create_light(deps: LightDeps) -> RpcExtension - where - C: ProvideRuntimeApi, - C: HeaderBackend, - C: Send + Sync + 'static, - C::Api: frame_rpc_system::AccountNonceApi, - C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - P: TransactionPool + Sync + Send + 'static, - F: Fetcher + 'static, +where + C: ProvideRuntimeApi, + C: HeaderBackend, + C: Send + Sync + 'static, + C::Api: frame_rpc_system::AccountNonceApi, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + P: TransactionPool + Sync + Send + 'static, + F: Fetcher + 'static, { use frame_rpc_system::{LightSystem, SystemApi}; - let LightDeps { + let LightDeps { client, pool, remote_blockchain, fetcher } = deps; + let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with(SystemApi::::to_delegate(LightSystem::new( client, - pool, remote_blockchain, fetcher, - } = deps; - let mut io = jsonrpc_core::IoHandler::default(); - io.extend_with( - SystemApi::::to_delegate(LightSystem::new(client, remote_blockchain, fetcher, pool)) - ); + pool, + ))); io } diff --git a/polkadot/runtime/common/slot_range_helper/src/lib.rs b/polkadot/runtime/common/slot_range_helper/src/lib.rs index 4ebf1e2e282..2adb8ecaea9 100644 --- a/polkadot/runtime/common/slot_range_helper/src/lib.rs +++ b/polkadot/runtime/common/slot_range_helper/src/lib.rs @@ -18,11 +18,11 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub use sp_std::{result, ops::Add, convert::TryInto}; -pub use sp_runtime::traits::CheckedSub; -pub use parity_scale_codec::{Encode, Decode}; -pub use paste; pub use enumn::N; +pub use parity_scale_codec::{Decode, Encode}; +pub use paste; +pub use sp_runtime::traits::CheckedSub; +pub use sp_std::{convert::TryInto, ops::Add, result}; /// This macro generates a `SlotRange` enum of arbitrary length for use in the Slot Auction /// mechanism on Polkadot. diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index e577faa165f..9ff037deb37 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -18,22 +18,26 @@ //! auctioning mechanism and for reserving balance as part of the "payment". Unreserving the balance //! happens elsewhere. -use sp_std::{prelude::*, mem::swap}; -use sp_runtime::traits::{CheckedSub, Zero, One, Saturating}; +use crate::{ + slot_range::SlotRange, + traits::{AuctionStatus, Auctioneer, LeaseError, Leaser, Registrar}, +}; use frame_support::{ - ensure, dispatch::DispatchResult, - traits::{Randomness, Currency, ReservableCurrency, Get}, - weights::{Weight}, + dispatch::DispatchResult, + ensure, + traits::{Currency, Get, Randomness, ReservableCurrency}, + weights::Weight, }; -use primitives::v1::Id as ParaId; -use crate::slot_range::SlotRange; -use crate::traits::{Leaser, LeaseError, Auctioneer, Registrar, AuctionStatus}; -use parity_scale_codec::Decode; pub use pallet::*; +use parity_scale_codec::Decode; +use primitives::v1::Id as ParaId; +use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; +use sp_std::{mem::swap, prelude::*}; type CurrencyOf = <::Leaser as Leaser>::Currency; -type BalanceOf = - <<::Leaser as Leaser>::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <<::Leaser as Leaser>::Currency as Currency< + ::AccountId, +>>::Balance; pub trait WeightInfo { fn new_auction() -> Weight; @@ -44,10 +48,18 @@ pub trait WeightInfo { pub struct TestWeightInfo; impl WeightInfo for TestWeightInfo { - fn new_auction() -> Weight { 0 } - fn bid() -> Weight { 0 } - fn cancel_auction() -> Weight { 0 } - fn on_initialize() -> Weight { 0 } + fn new_auction() -> Weight { + 0 + } + fn bid() -> Weight { + 0 + } + fn cancel_auction() -> Weight { + 0 + } + fn on_initialize() -> Weight { + 0 + } } /// An auction index. We count auctions in this type. @@ -55,17 +67,18 @@ pub type AuctionIndex = u32; type LeasePeriodOf = <::Leaser as Leaser>::LeasePeriod; // Winning data type. This encodes the top bidders of each range together with their bid. -type WinningData = - [Option<(::AccountId, ParaId, BalanceOf)>; SlotRange::SLOT_RANGE_COUNT]; +type WinningData = [Option<(::AccountId, ParaId, BalanceOf)>; + SlotRange::SLOT_RANGE_COUNT]; // Winners data type. This encodes each of the final winners of a parachain auction, the parachain // index assigned to them, their winning bid and the range that they won. -type WinnersData = Vec<(::AccountId, ParaId, BalanceOf, SlotRange)>; +type WinnersData = + Vec<(::AccountId, ParaId, BalanceOf, SlotRange)>; #[frame_support::pallet] pub mod pallet { - use frame_support::{pallet_prelude::*, traits::EnsureOrigin, weights::DispatchClass}; - use frame_system::{pallet_prelude::*, ensure_signed, ensure_root}; use super::*; + use frame_support::{pallet_prelude::*, traits::EnsureOrigin, weights::DispatchClass}; + use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -78,10 +91,10 @@ pub mod pallet { type Event: From> + IsType<::Event>; /// The type representing the leasing system. - type Leaser: Leaser; + type Leaser: Leaser; /// The parachain registrar type. - type Registrar: Registrar; + type Registrar: Registrar; /// The number of blocks over which an auction may be retroactively ended. #[pallet::constant] @@ -171,7 +184,8 @@ pub mod pallet { /// (sub-)ranges. #[pallet::storage] #[pallet::getter(fn reserved_amounts)] - pub type ReservedAmounts = StorageMap<_, Twox64Concat, (T::AccountId, ParaId), BalanceOf>; + pub type ReservedAmounts = + StorageMap<_, Twox64Concat, (T::AccountId, ParaId), BalanceOf>; /// The winning bids for each of the 10 ranges at each sample in the final Ending Period of /// the current auction. The map's key is the 0-based index into the Sample Size. The @@ -207,9 +221,10 @@ pub mod pallet { weight = weight.saturating_add(T::DbWeight::get().reads(1)); if !Winning::::contains_key(&offset) { weight = weight.saturating_add(T::DbWeight::get().writes(1)); - let winning_data = offset.checked_sub(&One::one()) - .and_then(Winning::::get) - .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + let winning_data = offset + .checked_sub(&One::one()) + .and_then(Winning::::get) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); Winning::::insert(offset, winning_data); } } @@ -218,10 +233,7 @@ pub mod pallet { if let Some((winning_ranges, auction_lease_period_index)) = Self::check_auction_end(n) { // Auction is ended now. We have the winning ranges and the lease period index which // acts as the offset. Handle it. - Self::manage_auction_end( - auction_lease_period_index, - winning_ranges, - ); + Self::manage_auction_end(auction_lease_period_index, winning_ranges); weight = weight.saturating_add(T::WeightInfo::on_initialize()); } @@ -269,7 +281,7 @@ pub mod pallet { #[pallet::compact] auction_index: AuctionIndex, #[pallet::compact] first_slot: LeasePeriodOf, #[pallet::compact] last_slot: LeasePeriodOf, - #[pallet::compact] amount: BalanceOf + #[pallet::compact] amount: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; Self::handle_bid(who, para, auction_index, first_slot, last_slot, amount)?; @@ -368,10 +380,16 @@ impl Pallet { ) -> DispatchResult { let maybe_auction = AuctionInfo::::get(); ensure!(maybe_auction.is_none(), Error::::AuctionInProgress); - ensure!(lease_period_index >= T::Leaser::lease_period_index(), Error::::LeasePeriodInPast); + ensure!( + lease_period_index >= T::Leaser::lease_period_index(), + Error::::LeasePeriodInPast + ); // Bump the counter. - let n = AuctionCounter::::mutate(|n| { *n += 1; *n }); + let n = AuctionCounter::::mutate(|n| { + *n += 1; + *n + }); // Set the information. let ending = frame_system::Pallet::::block_number().saturating_add(duration); @@ -416,7 +434,10 @@ impl Pallet { }; // We also make sure that the bid is not for any existing leases the para already has. - ensure!(!T::Leaser::already_leased(para, first_slot, last_slot), Error::::AlreadyLeasedOut); + ensure!( + !T::Leaser::already_leased(para, first_slot, last_slot), + Error::::AlreadyLeasedOut + ); // Our range. let range = SlotRange::new_bounded(first_lease_period, first_slot, last_slot)?; @@ -461,9 +482,11 @@ impl Pallet { let mut outgoing_winner = Some((bidder.clone(), para, amount)); swap(&mut current_winning[range_index], &mut outgoing_winner); if let Some((who, para, _amount)) = outgoing_winner { - if auction_status.is_starting() && current_winning.iter() - .filter_map(Option::as_ref) - .all(|&(ref other, other_para, _)| other != &who || other_para != para) + if auction_status.is_starting() && + current_winning + .iter() + .filter_map(Option::as_ref) + .all(|&(ref other, other_para, _)| other != &who || other_para != para) { // Previous bidder is no longer winning any ranges: unreserve their funds. if let Some(amount) = ReservedAmounts::::take(&(who.clone(), para)) { @@ -477,7 +500,9 @@ impl Pallet { // Update the range winner. Winning::::insert(offset, ¤t_winning); - Self::deposit_event(Event::::BidAccepted(bidder, para, amount, first_slot, last_slot)); + Self::deposit_event(Event::::BidAccepted( + bidder, para, amount, first_slot, last_slot, + )); } Ok(()) } @@ -500,13 +525,17 @@ impl Pallet { if late_end <= known_since { // Our random seed was known only after the auction ended. Good to use. - let raw_offset_block_number = ::decode(&mut raw_offset.as_ref()) - .expect("secure hashes should always be bigger than the block number; qed"); - let offset = (raw_offset_block_number % ending_period) / T::SampleLength::get().max(One::one()); + let raw_offset_block_number = ::decode( + &mut raw_offset.as_ref(), + ) + .expect("secure hashes should always be bigger than the block number; qed"); + let offset = (raw_offset_block_number % ending_period) / + T::SampleLength::get().max(One::one()); let auction_counter = AuctionCounter::::get(); Self::deposit_event(Event::::WinningOffset(auction_counter, offset)); - let res = Winning::::get(offset).unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); + let res = Winning::::get(offset) + .unwrap_or([Self::EMPTY; SlotRange::SLOT_RANGE_COUNT]); // This `remove_all` statement should remove at most `EndingPeriod` / `SampleLength` items, // which should be bounded and sensibly configured in the runtime. Winning::::remove_all(None); @@ -547,14 +576,14 @@ impl Pallet { Err(LeaseError::ReserveFailed) | Err(LeaseError::AlreadyEnded) => { // Should never happen since we just unreserved this amount (and our offset is from the // present period). But if it does, there's not much we can do. - } + }, Err(LeaseError::AlreadyLeased) => { // The leaser attempted to get a second lease on the same para ID, possibly griefing us. Let's // keep the amount reserved and let governance sort it out. if CurrencyOf::::reserve(&leaser, amount).is_ok() { Self::deposit_event(Event::::ReserveConfiscated(para, leaser, amount)); } - } + }, Ok(()) => {}, // Nothing to report. } } @@ -566,14 +595,13 @@ impl Pallet { /// /// This is a simple dynamic programming algorithm designed by Al, the original code is at: /// `https://github.com/w3f/consensus/blob/master/NPoS/auctiondynamicthing.py` - fn calculate_winners( - mut winning: WinningData - ) -> WinnersData { + fn calculate_winners(mut winning: WinningData) -> WinnersData { let winning_ranges = { - let mut best_winners_ending_at: - [(Vec, BalanceOf); SlotRange::LEASE_PERIODS_PER_SLOT] = Default::default(); + let mut best_winners_ending_at: [(Vec, BalanceOf); + SlotRange::LEASE_PERIODS_PER_SLOT] = Default::default(); let best_bid = |range: SlotRange| { - winning[range as u8 as usize].as_ref() + winning[range as u8 as usize] + .as_ref() .map(|(_, _, amount)| *amount * (range.len() as u32).into()) }; for i in 0..SlotRange::LEASE_PERIODS_PER_SLOT { @@ -601,13 +629,20 @@ impl Pallet { best_winners_ending_at[SlotRange::LEASE_PERIODS_PER_SLOT - 1].0.clone() }; - winning_ranges.into_iter().map(|range| { - let mut final_winner = Default::default(); - swap(&mut final_winner, winning[range as u8 as usize].as_mut() - .expect("none values are filtered out in previous logic; qed")); - let (bidder, para, amount) = final_winner; - (bidder, para, amount, range) - }).collect::>() + winning_ranges + .into_iter() + .map(|range| { + let mut final_winner = Default::default(); + swap( + &mut final_winner, + winning[range as u8 as usize] + .as_mut() + .expect("none values are filtered out in previous logic; qed"), + ); + let (bidder, para, amount) = final_winner; + (bidder, para, amount, range) + }) + .collect::>() } } @@ -615,18 +650,19 @@ impl Pallet { #[cfg(test)] mod tests { use super::*; - use std::{collections::BTreeMap, cell::RefCell}; - use sp_core::H256; - use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; + use crate::{auctions, mock::TestRegistrar}; use frame_support::{ - parameter_types, ord_parameter_types, assert_ok, assert_noop, assert_storage_noop, - traits::{OnInitialize, OnFinalize}, + assert_noop, assert_ok, assert_storage_noop, dispatch::DispatchError::BadOrigin, + ord_parameter_types, parameter_types, + traits::{OnFinalize, OnInitialize}, }; - use frame_system::{EnsureSignedBy, EnsureOneOf, EnsureRoot}; + use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy}; use pallet_balances; - use crate::{auctions, mock::TestRegistrar}; use primitives::v1::{BlockNumber, Header, Id as ParaId}; + use sp_core::H256; + use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; + use std::{cell::RefCell, collections::BTreeMap}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -734,12 +770,17 @@ mod tests { fn deposit_held( para: ParaId, - leaser: &Self::AccountId + leaser: &Self::AccountId, ) -> >::Balance { - leases().iter() - .filter_map(|((id, _period), data)| - if id == ¶ && &data.leaser == leaser { Some(data.amount) } else { None } - ) + leases() + .iter() + .filter_map(|((id, _period), data)| { + if id == ¶ && &data.leaser == leaser { + Some(data.amount) + } else { + None + } + }) .max() .unwrap_or_default() } @@ -755,25 +796,19 @@ mod tests { fn already_leased( para_id: ParaId, first_period: Self::LeasePeriod, - last_period: Self::LeasePeriod + last_period: Self::LeasePeriod, ) -> bool { leases().into_iter().any(|((para, period), _data)| { - para == para_id && - first_period <= period && - period <= last_period + para == para_id && first_period <= period && period <= last_period }) } } - ord_parameter_types!{ + ord_parameter_types! { pub const Six: u64 = 6; } - type RootOrSix = EnsureOneOf< - u64, - EnsureRoot, - EnsureSignedBy, - >; + type RootOrSix = EnsureOneOf, EnsureSignedBy>; thread_local! { pub static LAST_RANDOM: RefCell> = RefCell::new(None); @@ -794,7 +829,7 @@ mod tests { } } - parameter_types!{ + parameter_types! { pub static EndingPeriod: BlockNumber = 3; pub static SampleLength: BlockNumber = 1; } @@ -814,16 +849,38 @@ mod tests { // our desired mock up. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig::{ + pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], - }.assimilate_storage(&mut t).unwrap(); + } + .assimilate_storage(&mut t) + .unwrap(); let mut ext: sp_io::TestExternalities = t.into(); ext.execute_with(|| { // Register para 0, 1, 2, and 3 for tests - assert_ok!(TestRegistrar::::register(1, 0.into(), Default::default(), Default::default())); - assert_ok!(TestRegistrar::::register(1, 1.into(), Default::default(), Default::default())); - assert_ok!(TestRegistrar::::register(1, 2.into(), Default::default(), Default::default())); - assert_ok!(TestRegistrar::::register(1, 3.into(), Default::default(), Default::default())); + assert_ok!(TestRegistrar::::register( + 1, + 0.into(), + Default::default(), + Default::default() + )); + assert_ok!(TestRegistrar::::register( + 1, + 1.into(), + Default::default(), + Default::default() + )); + assert_ok!(TestRegistrar::::register( + 1, + 2.into(), + Default::default(), + Default::default() + )); + assert_ok!(TestRegistrar::::register( + 1, + 3.into(), + Default::default(), + Default::default() + )); }); ext } @@ -845,13 +902,19 @@ mod tests { new_test_ext().execute_with(|| { assert_eq!(AuctionCounter::::get(), 0); assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::NotStarted); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); run_to_block(10); assert_eq!(AuctionCounter::::get(), 0); assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::NotStarted); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); }); } @@ -864,7 +927,10 @@ mod tests { assert_ok!(Auctions::new_auction(Origin::signed(6), 5, 1)); assert_eq!(AuctionCounter::::get(), 1); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); }); } @@ -892,9 +958,9 @@ mod tests { assert_ok!(Auctions::bid(Origin::signed(1), 0.into(), 1, 1, 4, 5)); - assert_storage_noop!( - {assert_ok!(Auctions::bid(Origin::signed(2), 0.into(), 1, 1, 4, 1));} - ); + assert_storage_noop!({ + assert_ok!(Auctions::bid(Origin::signed(2), 0.into(), 1, 1, 4, 1)); + }); }); } @@ -925,31 +991,58 @@ mod tests { assert_ok!(Auctions::new_auction(Origin::signed(6), 5, 1)); assert_eq!(AuctionCounter::::get(), 1); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(2); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(3); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(4); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(5); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(6); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(0, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); run_to_block(7); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(1, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); run_to_block(8); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(2, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); run_to_block(9); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::NotStarted); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); }); } @@ -963,12 +1056,15 @@ mod tests { assert_eq!(Balances::free_balance(1), 9); run_to_block(9); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), - ]); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), + ] + ); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); }); } @@ -981,11 +1077,17 @@ mod tests { assert_ok!(Auctions::bid(Origin::signed(1), 0.into(), 1, 1, 4, 1)); assert_eq!(Balances::reserved_balance(1), 1); assert_eq!(Balances::free_balance(1), 9); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(8); // Auction has not yet ended. assert_eq!(leases(), vec![]); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(2, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); // This will prevent the auction's winner from being decided in the next block, since the random // seed was known before the final bids were made. set_last_random(H256::zero(), 8); @@ -993,7 +1095,10 @@ mod tests { // no randomness available yet. run_to_block(9); // Auction has now ended... But auction winner still not yet decided, so no leases yet. - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::VrfDelay(0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(0) + ); assert_eq!(leases(), vec![]); // Random seed now updated to a value known at block 9, when the auction ended. This means @@ -1001,13 +1106,19 @@ mod tests { set_last_random(H256::zero(), 9); run_to_block(10); // Auction ended and winner selected - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::NotStarted); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), - ]); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 1 }), + ] + ); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); }); } @@ -1020,9 +1131,7 @@ mod tests { assert_ok!(Auctions::bid(Origin::signed(1), 0.into(), 1, 4, 4, 5)); run_to_block(9); - assert_eq!(leases(), vec![ - ((0.into(), 4), LeaseData { leaser: 1, amount: 5 }), - ]); + assert_eq!(leases(), vec![((0.into(), 4), LeaseData { leaser: 1, amount: 5 }),]); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); }); } @@ -1038,12 +1147,15 @@ mod tests { assert_ok!(Auctions::bid(Origin::signed(1), 1.into(), 1, 1, 4, 2)); run_to_block(9); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 2), LeaseData { leaser: 2, amount: 4 }), - ((0.into(), 3), LeaseData { leaser: 2, amount: 4 }), - ((0.into(), 4), LeaseData { leaser: 3, amount: 2 }), - ]); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 2), LeaseData { leaser: 2, amount: 4 }), + ((0.into(), 3), LeaseData { leaser: 2, amount: 4 }), + ((0.into(), 4), LeaseData { leaser: 3, amount: 2 }), + ] + ); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); assert_eq!(TestLeaser::deposit_held(1.into(), &1), 0); assert_eq!(TestLeaser::deposit_held(0.into(), &2), 4); @@ -1075,12 +1187,15 @@ mod tests { // End the auction. run_to_block(9); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 4), LeaseData { leaser: 1, amount: 4 }), - ((1.into(), 2), LeaseData { leaser: 2, amount: 2 }), - ((1.into(), 3), LeaseData { leaser: 3, amount: 3 }), - ]); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 4), LeaseData { leaser: 1, amount: 4 }), + ((1.into(), 2), LeaseData { leaser: 2, amount: 2 }), + ((1.into(), 3), LeaseData { leaser: 3, amount: 3 }), + ] + ); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 4); assert_eq!(TestLeaser::deposit_held(1.into(), &2), 2); assert_eq!(TestLeaser::deposit_held(1.into(), &3), 3); @@ -1096,9 +1211,7 @@ mod tests { assert_eq!(Balances::reserved_balance(1), 5); run_to_block(10); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), - ]); + assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); assert_ok!(Auctions::new_auction(Origin::signed(6), 5, 2)); @@ -1107,10 +1220,13 @@ mod tests { assert_eq!(Balances::reserved_balance(1), 1); run_to_block(20); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), - ((0.into(), 2), LeaseData { leaser: 1, amount: 6 }), - ]); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), + ((0.into(), 2), LeaseData { leaser: 1, amount: 6 }), + ] + ); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 6); }); } @@ -1124,9 +1240,7 @@ mod tests { assert_eq!(Balances::reserved_balance(1), 5); run_to_block(10); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), - ]); + assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); assert_ok!(Auctions::new_auction(Origin::signed(6), 5, 2)); @@ -1135,10 +1249,13 @@ mod tests { assert_eq!(Balances::reserved_balance(1), 6); run_to_block(20); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), - ((1.into(), 2), LeaseData { leaser: 1, amount: 6 }), - ]); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 1, amount: 5 }), + ((1.into(), 2), LeaseData { leaser: 1, amount: 6 }), + ] + ); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5); assert_eq!(TestLeaser::deposit_held(1.into(), &1), 6); }); @@ -1161,12 +1278,15 @@ mod tests { } run_to_block(9); - assert_eq!(leases(), vec![ - ((0.into(), 1), LeaseData { leaser: 5, amount: 5 }), - ((0.into(), 2), LeaseData { leaser: 5, amount: 5 }), - ((0.into(), 3), LeaseData { leaser: 5, amount: 5 }), - ((0.into(), 4), LeaseData { leaser: 5, amount: 5 }), - ]); + assert_eq!( + leases(), + vec![ + ((0.into(), 1), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 2), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 3), LeaseData { leaser: 5, amount: 5 }), + ((0.into(), 4), LeaseData { leaser: 5, amount: 5 }), + ] + ); }); } @@ -1190,7 +1310,12 @@ mod tests { } run_to_block(5); - assert_eq!(leases(), (1..=4).map(|i| ((0.into(), i), LeaseData { leaser: 2, amount: 2 })).collect::>()); + assert_eq!( + leases(), + (1..=4) + .map(|i| ((0.into(), i), LeaseData { leaser: 2, amount: 2 })) + .collect::>() + ); }); } @@ -1199,9 +1324,7 @@ mod tests { let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; winning[SlotRange::ThreeThree as u8 as usize] = Some((1, 0.into(), 1)); - let winners = vec![ - (1, 0.into(), 1, SlotRange::ThreeThree) - ]; + let winners = vec![(1, 0.into(), 1, SlotRange::ThreeThree)]; assert_eq!(Auctions::calculate_winners(winning), winners); } @@ -1211,9 +1334,7 @@ mod tests { let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; winning[0] = Some((1, 0.into(), 1)); - let winners = vec![ - (1, 0.into(), 1, SlotRange::ZeroZero) - ]; + let winners = vec![(1, 0.into(), 1, SlotRange::ZeroZero)]; assert_eq!(Auctions::calculate_winners(winning), winners); } @@ -1244,9 +1365,7 @@ mod tests { assert_eq!(Auctions::calculate_winners(winning.clone()), winners); winning[SlotRange::ZeroThree as u8 as usize] = Some((1, 100.into(), 100)); - let winners = vec![ - (1, 100.into(), 100, SlotRange::ZeroThree), - ]; + let winners = vec![(1, 100.into(), 100, SlotRange::ZeroThree)]; assert_eq!(Auctions::calculate_winners(winning.clone()), winners); } @@ -1287,26 +1406,41 @@ mod tests { assert_ok!(Auctions::bid(Origin::signed(1), para_1, 1, 1, 4, 10)); assert_ok!(Auctions::bid(Origin::signed(2), para_2, 1, 3, 4, 20)); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 10)); winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 20)); assert_eq!(Auctions::winning(0), Some(winning)); run_to_block(9); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(10); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(0, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); assert_eq!(Auctions::winning(0), Some(winning)); run_to_block(11); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(1, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); assert_eq!(Auctions::winning(1), Some(winning)); assert_ok!(Auctions::bid(Origin::signed(3), para_3, 1, 3, 4, 30)); run_to_block(12); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(2, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 30)); assert_eq!(Auctions::winning(2), Some(winning)); }); @@ -1317,8 +1451,16 @@ mod tests { new_test_ext().execute_with(|| { run_to_block(1); assert_ok!(Auctions::new_auction(Origin::signed(6), 5, 1)); - assert_noop!(Auctions::bid(Origin::signed(1), 1337.into(), 1, 1, 4, 1), Error::::ParaNotRegistered); - assert_ok!(TestRegistrar::::register(1, 1337.into(), Default::default(), Default::default())); + assert_noop!( + Auctions::bid(Origin::signed(1), 1337.into(), 1, 1, 4, 1), + Error::::ParaNotRegistered + ); + assert_ok!(TestRegistrar::::register( + 1, + 1337.into(), + Default::default(), + Default::default() + )); assert_ok!(Auctions::bid(Origin::signed(1), 1337.into(), 1, 1, 4, 1)); }); } @@ -1333,10 +1475,13 @@ mod tests { assert_eq!(Balances::free_balance(1), 9); run_to_block(9); - assert_eq!(leases(), vec![ - ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), - ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), - ]); + assert_eq!( + leases(), + vec![ + ((0.into(), 2), LeaseData { leaser: 1, amount: 1 }), + ((0.into(), 3), LeaseData { leaser: 1, amount: 1 }), + ] + ); assert_eq!(TestLeaser::deposit_held(0.into(), &1), 1); // Para 1 just won an auction above and won some lease periods. @@ -1376,17 +1521,26 @@ mod tests { assert_ok!(Auctions::bid(Origin::signed(1), para_1, 1, 11, 14, 10)); assert_ok!(Auctions::bid(Origin::signed(2), para_2, 1, 13, 14, 20)); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; winning[SlotRange::ZeroThree as u8 as usize] = Some((1, para_1, 10)); winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 20)); assert_eq!(Auctions::winning(0), Some(winning)); run_to_block(9); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(10); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(0, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); assert_eq!(Auctions::winning(0), Some(winning)); // New bids update the current winning @@ -1395,7 +1549,10 @@ mod tests { assert_eq!(Auctions::winning(0), Some(winning)); run_to_block(20); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(1, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); assert_eq!(Auctions::winning(1), Some(winning)); run_to_block(25); // Overbid mid sample @@ -1404,17 +1561,26 @@ mod tests { assert_eq!(Auctions::winning(1), Some(winning)); run_to_block(30); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(2, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); assert_eq!(Auctions::winning(2), Some(winning)); set_last_random(H256::from([254; 32]), 40); run_to_block(40); // Auction ended and winner selected - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::NotStarted); - assert_eq!(leases(), vec![ - ((3.into(), 13), LeaseData { leaser: 3, amount: 30 }), - ((3.into(), 14), LeaseData { leaser: 3, amount: 30 }), - ]); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); + assert_eq!( + leases(), + vec![ + ((3.into(), 13), LeaseData { leaser: 3, amount: 30 }), + ((3.into(), 14), LeaseData { leaser: 3, amount: 30 }), + ] + ); }); } @@ -1425,44 +1591,80 @@ mod tests { SampleLength::set(10); set_last_random(Default::default(), 0); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::NotStarted); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); run_to_block(1); assert_ok!(Auctions::new_auction(Origin::signed(6), 9, 11)); run_to_block(9); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::StartingPeriod); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::StartingPeriod + ); run_to_block(10); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(0, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 0) + ); run_to_block(11); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(0, 1)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 1) + ); run_to_block(19); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(0, 9)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(0, 9) + ); run_to_block(20); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(1, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 0) + ); run_to_block(25); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(1, 5)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(1, 5) + ); run_to_block(30); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(2, 0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 0) + ); run_to_block(39); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::EndingPeriod(2, 9)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::EndingPeriod(2, 9) + ); run_to_block(40); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::VrfDelay(0)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(0) + ); run_to_block(44); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::VrfDelay(4)); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::VrfDelay(4) + ); set_last_random(Default::default(), 45); run_to_block(45); - assert_eq!(Auctions::auction_status(System::block_number()), AuctionStatus::::NotStarted); + assert_eq!( + Auctions::auction_status(System::block_number()), + AuctionStatus::::NotStarted + ); }); } @@ -1488,12 +1690,12 @@ mod tests { #[cfg(feature = "runtime-benchmarks")] mod benchmarking { - use super::{*, Pallet as Auctions}; - use frame_system::RawOrigin; + use super::{Pallet as Auctions, *}; use frame_support::traits::{EnsureOrigin, OnInitialize}; + use frame_system::RawOrigin; use sp_runtime::{traits::Bounded, SaturatedConversion}; - use frame_benchmarking::{benchmarks, whitelisted_caller, account, impl_benchmark_test_suite}; + use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; fn assert_last_event(generic_event: ::Event) { let events = frame_system::Pallet::::events(); @@ -1507,7 +1709,7 @@ mod benchmarking { let auction_index = AuctionCounter::::get(); let minimum_balance = CurrencyOf::::minimum_balance(); - for n in 1 ..= SlotRange::SLOT_RANGE_COUNT as u32 { + for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { let owner = account("owner", n, 0); let worst_validation_code = T::Registrar::worst_validation_code(); let worst_head_data = T::Registrar::worst_head_data(); @@ -1518,12 +1720,13 @@ mod benchmarking { ParaId::from(n), worst_head_data, worst_validation_code - ).is_ok()); + ) + .is_ok()); } T::Registrar::execute_pending_transitions(); - for n in 1 ..= SlotRange::SLOT_RANGE_COUNT as u32 { + for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 { let bidder = account("bidder", n, 0); CurrencyOf::::make_free_balance_be(&bidder, BalanceOf::::max_value()); @@ -1534,10 +1737,11 @@ mod benchmarking { RawOrigin::Signed(bidder).into(), ParaId::from(n), auction_index, - lease_period_index + start.into(), // First Slot - lease_period_index + end.into(), // Last slot + lease_period_index + start.into(), // First Slot + lease_period_index + end.into(), // Last slot minimum_balance.saturating_mul(n.into()), // Amount - ).is_ok()); + ) + .is_ok()); } } diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index 686006f7646..0c146eabf8b 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -16,24 +16,31 @@ //! Pallet to process claims from Ethereum addresses. -use sp_std::{prelude::*, fmt::Debug}; -use sp_io::{hashing::keccak_256, crypto::secp256k1_ecdsa_recover}; -use frame_support::{ensure, traits::{Currency, Get, VestingSchedule, IsSubType}, weights::Weight}; -use parity_scale_codec::{Encode, Decode}; +use frame_support::{ + ensure, + traits::{Currency, Get, IsSubType, VestingSchedule}, + weights::Weight, +}; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use primitives::v1::ValidityError; #[cfg(feature = "std")] -use serde::{self, Serialize, Deserialize, Serializer, Deserializer}; +use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; +use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256}; #[cfg(feature = "std")] use sp_runtime::traits::Zero; use sp_runtime::{ - traits::{CheckedSub, SignedExtension, DispatchInfoOf}, RuntimeDebug, + traits::{CheckedSub, DispatchInfoOf, SignedExtension}, transaction_validity::{ - TransactionValidity, ValidTransaction, InvalidTransaction, TransactionValidityError, + InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, + RuntimeDebug, }; -use primitives::v1::ValidityError; -pub use pallet::*; +use sp_std::{fmt::Debug, prelude::*}; -type CurrencyOf = <::VestingSchedule as VestingSchedule<::AccountId>>::Currency; +type CurrencyOf = <::VestingSchedule as VestingSchedule< + ::AccountId, +>>::Currency; type BalanceOf = as Currency<::AccountId>>::Balance; pub trait WeightInfo { @@ -46,11 +53,21 @@ pub trait WeightInfo { pub struct TestWeightInfo; impl WeightInfo for TestWeightInfo { - fn claim() -> Weight { 0 } - fn mint_claim() -> Weight { 0 } - fn claim_attest() -> Weight { 0 } - fn attest() -> Weight { 0 } - fn move_claim() -> Weight { 0 } + fn claim() -> Weight { + 0 + } + fn mint_claim() -> Weight { + 0 + } + fn claim_attest() -> Weight { + 0 + } + fn attest() -> Weight { + 0 + } + fn move_claim() -> Weight { + 0 + } } /// The kind of statement an account needs to make for a claim to be valid. @@ -93,7 +110,10 @@ pub struct EthereumAddress([u8; 20]); #[cfg(feature = "std")] impl Serialize for EthereumAddress { - fn serialize(&self, serializer: S) -> Result where S: Serializer { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { let hex: String = rustc_hex::ToHex::to_hex(&self.0[..]); serializer.serialize_str(&format!("0x{}", hex)) } @@ -101,12 +121,17 @@ impl Serialize for EthereumAddress { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for EthereumAddress { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { let base_string = String::deserialize(deserializer)?; let offset = if base_string.starts_with("0x") { 2 } else { 0 }; let s = &base_string[offset..]; if s.len() != 40 { - Err(serde::de::Error::custom("Bad length of Ethereum address (should be 42 including '0x')"))?; + Err(serde::de::Error::custom( + "Bad length of Ethereum address (should be 42 including '0x')", + ))?; } let raw: Vec = rustc_hex::FromHex::from_hex(s) .map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?; @@ -133,9 +158,9 @@ impl sp_std::fmt::Debug for EcdsaSignature { #[frame_support::pallet] pub mod pallet { + use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use super::*; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -146,7 +171,7 @@ pub mod pallet { pub trait Config: frame_system::Config { /// The overarching event type. type Event: From> + IsType<::Event>; - type VestingSchedule: VestingSchedule; + type VestingSchedule: VestingSchedule; #[pallet::constant] type Prefix: Get<&'static [u8]>; type MoveClaimOrigin: EnsureOrigin; @@ -192,11 +217,8 @@ pub mod pallet { /// The block number is when the vesting should start. #[pallet::storage] #[pallet::getter(fn vesting)] - pub(super) type Vesting = StorageMap< - _, - Identity, EthereumAddress, - (BalanceOf, BalanceOf, T::BlockNumber), - >; + pub(super) type Vesting = + StorageMap<_, Identity, EthereumAddress, (BalanceOf, BalanceOf, T::BlockNumber)>; /// The statement kind that must be signed, if any. #[pallet::storage] @@ -208,17 +230,15 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { - pub claims: Vec<(EthereumAddress, BalanceOf, Option, Option)>, + pub claims: + Vec<(EthereumAddress, BalanceOf, Option, Option)>, pub vesting: Vec<(EthereumAddress, (BalanceOf, BalanceOf, T::BlockNumber))>, } #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { - GenesisConfig { - claims: Default::default(), - vesting: Default::default(), - } + GenesisConfig { claims: Default::default(), vesting: Default::default() } } } @@ -226,23 +246,32 @@ pub mod pallet { impl GenesisBuild for GenesisConfig { fn build(&self) { // build `Claims` - self.claims.iter().map(|(a, b, _, _)| (a.clone(), b.clone())).for_each(|(a, b)| { - Claims::::insert(a, b); - }); + self.claims + .iter() + .map(|(a, b, _, _)| (a.clone(), b.clone())) + .for_each(|(a, b)| { + Claims::::insert(a, b); + }); // build `Total` Total::::put( - self.claims.iter().fold(Zero::zero(), |acc: BalanceOf, &(_, b, _, _)| acc + b), + self.claims + .iter() + .fold(Zero::zero(), |acc: BalanceOf, &(_, b, _, _)| acc + b), ); // build `Vesting` - self.vesting.iter().for_each(|(k, v)| { Vesting::::insert(k, v); }); + self.vesting.iter().for_each(|(k, v)| { + Vesting::::insert(k, v); + }); // build `Signing` - self.claims.iter() + self.claims + .iter() .filter_map(|(a, _, _, s)| Some((a.clone(), s.clone()?))) .for_each(|(a, s)| { Signing::::insert(a, s); }); // build `Preclaims` - self.claims.iter() + self.claims + .iter() .filter_map(|(a, _, i, _)| Some((i.clone()?, a.clone()))) .for_each(|(i, a)| { Preclaims::::insert(i, a); @@ -283,7 +312,7 @@ pub mod pallet { pub fn claim( origin: OriginFor, dest: T::AccountId, - ethereum_signature: EcdsaSignature + ethereum_signature: EcdsaSignature, ) -> DispatchResult { ensure_none(origin)?; @@ -422,9 +451,13 @@ pub mod pallet { Claims::::take(&old).map(|c| Claims::::insert(&new, c)); Vesting::::take(&old).map(|c| Vesting::::insert(&new, c)); Signing::::take(&old).map(|c| Signing::::insert(&new, c)); - maybe_preclaim.map(|preclaim| Preclaims::::mutate(&preclaim, |maybe_o| - if maybe_o.as_ref().map_or(false, |o| o == &old) { *maybe_o = Some(new) } - )); + maybe_preclaim.map(|preclaim| { + Preclaims::::mutate(&preclaim, |maybe_o| { + if maybe_o.as_ref().map_or(false, |o| o == &old) { + *maybe_o = Some(new) + } + }) + }); Ok(Pays::No.into()) } } @@ -443,19 +476,23 @@ pub mod pallet { Call::claim(account, ethereum_signature) => { let data = account.using_encoded(to_ascii_hex); (Self::eth_recover(ðereum_signature, &data, &[][..]), None) - } + }, // // The weight of this logic is included in the `claim_attest` dispatchable. // Call::claim_attest(account, ethereum_signature, statement) => { let data = account.using_encoded(to_ascii_hex); - (Self::eth_recover(ðereum_signature, &data, &statement), Some(statement.as_slice())) - } + ( + Self::eth_recover(ðereum_signature, &data, &statement), + Some(statement.as_slice()), + ) + }, _ => return Err(InvalidTransaction::Call.into()), }; - let signer = maybe_signer - .ok_or(InvalidTransaction::Custom(ValidityError::InvalidEthereumSignature.into()))?; + let signer = maybe_signer.ok_or(InvalidTransaction::Custom( + ValidityError::InvalidEthereumSignature.into(), + ))?; let e = InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()); ensure!(>::contains_key(&signer), e); @@ -511,13 +548,13 @@ impl Pallet { fn eth_recover(s: &EcdsaSignature, what: &[u8], extra: &[u8]) -> Option { let msg = keccak_256(&Self::ethereum_signable_message(what, extra)); let mut res = EthereumAddress::default(); - res.0.copy_from_slice(&keccak_256(&secp256k1_ecdsa_recover(&s.0, &msg).ok()?[..])[12..]); + res.0 + .copy_from_slice(&keccak_256(&secp256k1_ecdsa_recover(&s.0, &msg).ok()?[..])[12..]); Some(res) } fn process_claim(signer: EthereumAddress, dest: T::AccountId) -> sp_runtime::DispatchResult { - let balance_due = >::get(&signer) - .ok_or(Error::::SignerHasNoClaim)?; + let balance_due = >::get(&signer).ok_or(Error::::SignerHasNoClaim)?; let new_total = Self::total().checked_sub(&balance_due).ok_or(Error::::PotUnderflow)?; @@ -552,11 +589,13 @@ impl Pallet { /// Validate `attest` calls prior to execution. Needed to avoid a DoS attack since they are /// otherwise free to place on chain. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct PrevalidateAttests(sp_std::marker::PhantomData) where +pub struct PrevalidateAttests(sp_std::marker::PhantomData) +where ::Call: IsSubType>; -impl Debug for PrevalidateAttests where - ::Call: IsSubType> +impl Debug for PrevalidateAttests +where + ::Call: IsSubType>, { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { @@ -569,8 +608,9 @@ impl Debug for PrevalidateAttests where } } -impl PrevalidateAttests where - ::Call: IsSubType> +impl PrevalidateAttests +where + ::Call: IsSubType>, { /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { @@ -578,8 +618,9 @@ impl PrevalidateAttests where } } -impl SignedExtension for PrevalidateAttests where - ::Call: IsSubType> +impl SignedExtension for PrevalidateAttests +where + ::Call: IsSubType>, { type AccountId = T::AccountId; type Call = ::Call; @@ -627,8 +668,15 @@ mod secp_utils { res.0.copy_from_slice(&keccak_256(&public(secret).serialize()[1..65])[12..]); res } - pub fn sig(secret: &libsecp256k1::SecretKey, what: &[u8], extra: &[u8]) -> EcdsaSignature { - let msg = keccak_256(&>::ethereum_signable_message(&to_ascii_hex(what)[..], extra)); + pub fn sig( + secret: &libsecp256k1::SecretKey, + what: &[u8], + extra: &[u8], + ) -> EcdsaSignature { + let msg = keccak_256(&>::ethereum_signable_message( + &to_ascii_hex(what)[..], + extra, + )); let (sig, recovery_id) = libsecp256k1::sign(&libsecp256k1::Message::parse(&msg), secret); let mut r = [0u8; 65]; r[0..64].copy_from_slice(&sig.serialize()[..]); @@ -639,27 +687,29 @@ mod secp_utils { #[cfg(test)] mod tests { - use hex_literal::hex; use super::*; + use hex_literal::hex; use secp_utils::*; - use sp_core::H256; use parity_scale_codec::Encode; + use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup, Identity}, - transaction_validity::TransactionLongevity, - testing::Header, - }; + use crate::claims; + use claims::Call as ClaimsCall; use frame_support::{ - assert_ok, assert_err, assert_noop, parameter_types, - ord_parameter_types, weights::{Pays, GetDispatchInfo}, traits::{ExistenceRequirement, GenesisBuild}, + assert_err, assert_noop, assert_ok, dispatch::DispatchError::BadOrigin, + ord_parameter_types, parameter_types, + traits::{ExistenceRequirement, GenesisBuild}, + weights::{GetDispatchInfo, Pays}, }; use pallet_balances; - use crate::claims; - use claims::Call as ClaimsCall; + use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, Identity, IdentityLookup}, + transaction_validity::TransactionLongevity, + }; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -734,7 +784,7 @@ mod tests { type WeightInfo = (); } - parameter_types!{ + parameter_types! { pub Prefix: &'static [u8] = b"Pay RUSTs to the TEST account:"; } ord_parameter_types! { @@ -770,8 +820,10 @@ mod tests { pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. - pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); - claims::GenesisConfig::{ + pallet_balances::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + claims::GenesisConfig:: { claims: vec![ (eth(&alice()), 100, None, None), (eth(&dave()), 200, None, Some(StatementKind::Regular)), @@ -779,7 +831,9 @@ mod tests { (eth(&frank()), 400, Some(43), None), ], vesting: vec![(eth(&alice()), (50, 10, 1))], - }.assimilate_storage(&mut t).unwrap(); + } + .assimilate_storage(&mut t) + .unwrap(); t.into() } @@ -813,7 +867,11 @@ mod tests { fn claiming_works() { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); - assert_ok!(Claims::claim(Origin::none(), 42, sig::(&alice(), &42u64.encode(), &[][..]))); + assert_ok!(Claims::claim( + Origin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); assert_eq!(Balances::free_balance(&42), 100); assert_eq!(Vesting::vesting_balance(&42), Some(50)); assert_eq!(Claims::total(), total_claims() - 100); @@ -824,10 +882,20 @@ mod tests { fn basic_claim_moving_works() { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); - assert_noop!(Claims::move_claim(Origin::signed(1), eth(&alice()), eth(&bob()), None), BadOrigin); + assert_noop!( + Claims::move_claim(Origin::signed(1), eth(&alice()), eth(&bob()), None), + BadOrigin + ); assert_ok!(Claims::move_claim(Origin::signed(6), eth(&alice()), eth(&bob()), None)); - assert_noop!(Claims::claim(Origin::none(), 42, sig::(&alice(), &42u64.encode(), &[][..])), Error::::SignerHasNoClaim); - assert_ok!(Claims::claim(Origin::none(), 42, sig::(&bob(), &42u64.encode(), &[][..]))); + assert_noop!( + Claims::claim(Origin::none(), 42, sig::(&alice(), &42u64.encode(), &[][..])), + Error::::SignerHasNoClaim + ); + assert_ok!(Claims::claim( + Origin::none(), + 42, + sig::(&bob(), &42u64.encode(), &[][..]) + )); assert_eq!(Balances::free_balance(&42), 100); assert_eq!(Vesting::vesting_balance(&42), Some(50)); assert_eq!(Claims::total(), total_claims() - 100); @@ -839,7 +907,12 @@ mod tests { new_test_ext().execute_with(|| { assert_ok!(Claims::move_claim(Origin::signed(6), eth(&dave()), eth(&bob()), None)); let s = sig::(&bob(), &42u64.encode(), StatementKind::Regular.to_text()); - assert_ok!(Claims::claim_attest(Origin::none(), 42, s, StatementKind::Regular.to_text().to_vec())); + assert_ok!(Claims::claim_attest( + Origin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec() + )); assert_eq!(Balances::free_balance(&42), 200); }); } @@ -856,7 +929,11 @@ mod tests { #[test] fn claiming_does_not_bypass_signing() { new_test_ext().execute_with(|| { - assert_ok!(Claims::claim(Origin::none(), 42, sig::(&alice(), &42u64.encode(), &[][..]))); + assert_ok!(Claims::claim( + Origin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); assert_noop!( Claims::claim(Origin::none(), 42, sig::(&dave(), &42u64.encode(), &[][..])), Error::::InvalidStatement, @@ -865,7 +942,11 @@ mod tests { Claims::claim(Origin::none(), 42, sig::(&eve(), &42u64.encode(), &[][..])), Error::::InvalidStatement, ); - assert_ok!(Claims::claim(Origin::none(), 42, sig::(&frank(), &42u64.encode(), &[][..]))); + assert_ok!(Claims::claim( + Origin::none(), + 42, + sig::(&frank(), &42u64.encode(), &[][..]) + )); }); } @@ -874,21 +955,41 @@ mod tests { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); let s = sig::(&dave(), &42u64.encode(), StatementKind::Saft.to_text()); - let r = Claims::claim_attest(Origin::none(), 42, s.clone(), StatementKind::Saft.to_text().to_vec()); + let r = Claims::claim_attest( + Origin::none(), + 42, + s.clone(), + StatementKind::Saft.to_text().to_vec(), + ); assert_noop!(r, Error::::InvalidStatement); - let r = Claims::claim_attest(Origin::none(), 42, s, StatementKind::Regular.to_text().to_vec()); + let r = Claims::claim_attest( + Origin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec(), + ); assert_noop!(r, Error::::SignerHasNoClaim); // ^^^ we use ecdsa_recover, so an invalid signature just results in a random signer id // being recovered, which realistically will never have a claim. let s = sig::(&dave(), &42u64.encode(), StatementKind::Regular.to_text()); - assert_ok!(Claims::claim_attest(Origin::none(), 42, s, StatementKind::Regular.to_text().to_vec())); + assert_ok!(Claims::claim_attest( + Origin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec() + )); assert_eq!(Balances::free_balance(&42), 200); assert_eq!(Claims::total(), total_claims() - 200); let s = sig::(&dave(), &42u64.encode(), StatementKind::Regular.to_text()); - let r = Claims::claim_attest(Origin::none(), 42, s, StatementKind::Regular.to_text().to_vec()); + let r = Claims::claim_attest( + Origin::none(), + 42, + s, + StatementKind::Regular.to_text().to_vec(), + ); assert_noop!(r, Error::::SignerHasNoClaim); }); } @@ -897,8 +998,14 @@ mod tests { fn attesting_works() { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); - assert_noop!(Claims::attest(Origin::signed(69), StatementKind::Saft.to_text().to_vec()), Error::::SenderHasNoClaim); - assert_noop!(Claims::attest(Origin::signed(42), StatementKind::Regular.to_text().to_vec()), Error::::InvalidStatement); + assert_noop!( + Claims::attest(Origin::signed(69), StatementKind::Saft.to_text().to_vec()), + Error::::SenderHasNoClaim + ); + assert_noop!( + Claims::attest(Origin::signed(42), StatementKind::Regular.to_text().to_vec()), + Error::::InvalidStatement + ); assert_ok!(Claims::attest(Origin::signed(42), StatementKind::Saft.to_text().to_vec())); assert_eq!(Balances::free_balance(&42), 300); assert_eq!(Claims::total(), total_claims() - 300); @@ -910,7 +1017,11 @@ mod tests { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); // Alice's claim is 100 - assert_ok!(Claims::claim(Origin::none(), 42, sig::(&alice(), &42u64.encode(), &[][..]))); + assert_ok!(Claims::claim( + Origin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); assert_eq!(Balances::free_balance(&42), 100); // Eve's claim is 300 through Account 42 assert_ok!(Claims::attest(Origin::signed(42), StatementKind::Saft.to_text().to_vec())); @@ -970,7 +1081,11 @@ mod tests { ); assert_ok!(Claims::mint_claim(Origin::root(), eth(&bob()), 200, None, None)); assert_eq!(Claims::total(), total_claims() + 200); - assert_ok!(Claims::claim(Origin::none(), 69, sig::(&bob(), &69u64.encode(), &[][..]))); + assert_ok!(Claims::claim( + Origin::none(), + 69, + sig::(&bob(), &69u64.encode(), &[][..]) + )); assert_eq!(Balances::free_balance(&69), 200); assert_eq!(Vesting::vesting_balance(&69), None); assert_eq!(Claims::total(), total_claims()); @@ -989,14 +1104,29 @@ mod tests { Claims::claim(Origin::none(), 69, sig::(&bob(), &69u64.encode(), &[][..])), Error::::SignerHasNoClaim, ); - assert_ok!(Claims::mint_claim(Origin::root(), eth(&bob()), 200, Some((50, 10, 1)), None)); - assert_ok!(Claims::claim(Origin::none(), 69, sig::(&bob(), &69u64.encode(), &[][..]))); + assert_ok!(Claims::mint_claim( + Origin::root(), + eth(&bob()), + 200, + Some((50, 10, 1)), + None + )); + assert_ok!(Claims::claim( + Origin::none(), + 69, + sig::(&bob(), &69u64.encode(), &[][..]) + )); assert_eq!(Balances::free_balance(&69), 200); assert_eq!(Vesting::vesting_balance(&69), Some(50)); // Make sure we can not transfer the vested balance. assert_err!( - >::transfer(&69, &80, 180, ExistenceRequirement::AllowDeath), + >::transfer( + &69, + &80, + 180, + ExistenceRequirement::AllowDeath + ), pallet_balances::Error::::LiquidityRestrictions, ); }); @@ -1006,29 +1136,43 @@ mod tests { fn add_claim_with_statement_works() { new_test_ext().execute_with(|| { assert_noop!( - Claims::mint_claim(Origin::signed(42), eth(&bob()), 200, None, Some(StatementKind::Regular)), + Claims::mint_claim( + Origin::signed(42), + eth(&bob()), + 200, + None, + Some(StatementKind::Regular) + ), sp_runtime::traits::BadOrigin, ); assert_eq!(Balances::free_balance(42), 0); let signature = sig::(&bob(), &69u64.encode(), StatementKind::Regular.to_text()); assert_noop!( Claims::claim_attest( - Origin::none(), 69, signature.clone(), StatementKind::Regular.to_text().to_vec() + Origin::none(), + 69, + signature.clone(), + StatementKind::Regular.to_text().to_vec() ), Error::::SignerHasNoClaim ); - assert_ok!(Claims::mint_claim(Origin::root(), eth(&bob()), 200, None, Some(StatementKind::Regular))); + assert_ok!(Claims::mint_claim( + Origin::root(), + eth(&bob()), + 200, + None, + Some(StatementKind::Regular) + )); assert_noop!( - Claims::claim_attest( - Origin::none(), 69, signature.clone(), vec![], - ), + Claims::claim_attest(Origin::none(), 69, signature.clone(), vec![],), Error::::SignerHasNoClaim ); - assert_ok!( - Claims::claim_attest( - Origin::none(), 69, signature.clone(), StatementKind::Regular.to_text().to_vec() - ) - ); + assert_ok!(Claims::claim_attest( + Origin::none(), + 69, + signature.clone(), + StatementKind::Regular.to_text().to_vec() + )); assert_eq!(Balances::free_balance(&69), 200); }); } @@ -1038,7 +1182,11 @@ mod tests { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); assert_err!( - Claims::claim(Origin::signed(42), 42, sig::(&alice(), &42u64.encode(), &[][..])), + Claims::claim( + Origin::signed(42), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + ), sp_runtime::traits::BadOrigin, ); }); @@ -1048,7 +1196,11 @@ mod tests { fn double_claiming_doesnt_work() { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(42), 0); - assert_ok!(Claims::claim(Origin::none(), 42, sig::(&alice(), &42u64.encode(), &[][..]))); + assert_ok!(Claims::claim( + Origin::none(), + 42, + sig::(&alice(), &42u64.encode(), &[][..]) + )); assert_noop!( Claims::claim(Origin::none(), 42, sig::(&alice(), &42u64.encode(), &[][..])), Error::::SignerHasNoClaim @@ -1060,10 +1212,21 @@ mod tests { fn claiming_while_vested_doesnt_work() { new_test_ext().execute_with(|| { // A user is already vested - assert_ok!(::VestingSchedule::add_vesting_schedule(&69, total_claims(), 100, 10)); + assert_ok!(::VestingSchedule::add_vesting_schedule( + &69, + total_claims(), + 100, + 10 + )); CurrencyOf::::make_free_balance_be(&69, total_claims()); assert_eq!(Balances::free_balance(69), total_claims()); - assert_ok!(Claims::mint_claim(Origin::root(), eth(&bob()), 200, Some((50, 10, 1)), None)); + assert_ok!(Claims::mint_claim( + Origin::root(), + eth(&bob()), + 200, + Some((50, 10, 1)), + None + )); // New total assert_eq!(Claims::total(), total_claims() + 200); @@ -1116,7 +1279,10 @@ mod tests { new_test_ext().execute_with(|| { assert_eq!( - >::validate_unsigned(source, &ClaimsCall::claim(1, sig::(&alice(), &1u64.encode(), &[][..]))), + >::validate_unsigned( + source, + &ClaimsCall::claim(1, sig::(&alice(), &1u64.encode(), &[][..])) + ), Ok(ValidTransaction { priority: 100, requires: vec![], @@ -1126,11 +1292,17 @@ mod tests { }) ); assert_eq!( - >::validate_unsigned(source, &ClaimsCall::claim(0, EcdsaSignature([0; 65]))), + >::validate_unsigned( + source, + &ClaimsCall::claim(0, EcdsaSignature([0; 65])) + ), InvalidTransaction::Custom(ValidityError::InvalidEthereumSignature.into()).into(), ); assert_eq!( - >::validate_unsigned(source, &ClaimsCall::claim(1, sig::(&bob(), &1u64.encode(), &[][..]))), + >::validate_unsigned( + source, + &ClaimsCall::claim(1, sig::(&bob(), &1u64.encode(), &[][..])) + ), InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()).into(), ); let s = sig::(&dave(), &1u64.encode(), StatementKind::Regular.to_text()); @@ -1148,8 +1320,11 @@ mod tests { assert_eq!( >::validate_unsigned( source, - &ClaimsCall::claim_attest(1, EcdsaSignature([0; 65]), - StatementKind::Regular.to_text().to_vec()) + &ClaimsCall::claim_attest( + 1, + EcdsaSignature([0; 65]), + StatementKind::Regular.to_text().to_vec() + ) ), InvalidTransaction::Custom(ValidityError::InvalidEthereumSignature.into()).into(), ); @@ -1181,12 +1356,11 @@ mod tests { #[cfg(feature = "runtime-benchmarks")] mod benchmarking { use super::*; - use secp_utils::*; - use frame_system::RawOrigin; - use frame_benchmarking::{benchmarks, account}; - use sp_runtime::DispatchResult; - use sp_runtime::traits::ValidateUnsigned; use crate::claims::Call; + use frame_benchmarking::{account, benchmarks}; + use frame_system::RawOrigin; + use secp_utils::*; + use sp_runtime::{traits::ValidateUnsigned, DispatchResult}; const SEED: u32 = 0; @@ -1197,7 +1371,13 @@ mod benchmarking { let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&input.encode())).unwrap(); let eth_address = eth(&secret_key); let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); - super::Pallet::::mint_claim(RawOrigin::Root.into(), eth_address, VALUE.into(), vesting, None)?; + super::Pallet::::mint_claim( + RawOrigin::Root.into(), + eth_address, + VALUE.into(), + vesting, + None, + )?; Ok(()) } @@ -1210,7 +1390,7 @@ mod benchmarking { eth_address, VALUE.into(), vesting, - Some(Default::default()) + Some(Default::default()), )?; Ok(()) } diff --git a/polkadot/runtime/common/src/crowdloan.rs b/polkadot/runtime/common/src/crowdloan.rs index 8215b9ac293..7ceff18e246 100644 --- a/polkadot/runtime/common/src/crowdloan.rs +++ b/polkadot/runtime/common/src/crowdloan.rs @@ -49,33 +49,35 @@ //! the parachain remains active. Users can withdraw their funds once the slot is completed and funds are //! returned to the crowdloan account. +use crate::{ + slot_range::SlotRange, + traits::{Auctioneer, Registrar}, +}; use frame_support::{ - ensure, Identity, PalletId, - storage::{child, ChildTriePrefixIterator}, - traits::{ - Currency, ReservableCurrency, Get, ExistenceRequirement::AllowDeath - }, + ensure, pallet_prelude::Weight, + storage::{child, ChildTriePrefixIterator}, + traits::{Currency, ExistenceRequirement::AllowDeath, Get, ReservableCurrency}, + Identity, PalletId, }; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use primitives::v1::Id as ParaId; use sp_runtime::{ - RuntimeDebug, MultiSignature, MultiSigner, traits::{ - AccountIdConversion, Hash, Saturating, Zero, One, CheckedAdd, Verify, IdentifyAccount, + AccountIdConversion, CheckedAdd, Hash, IdentifyAccount, One, Saturating, Verify, Zero, }, + MultiSignature, MultiSigner, RuntimeDebug, }; -use crate::traits::{Registrar, Auctioneer}; -use crate::slot_range::SlotRange; -use parity_scale_codec::{Encode, Decode}; use sp_std::vec::Vec; -use primitives::v1::Id as ParaId; -pub use pallet::*; type CurrencyOf = <::Auctioneer as Auctioneer>::Currency; type LeasePeriodOf = <::Auctioneer as Auctioneer>::LeasePeriod; type BalanceOf = as Currency<::AccountId>>::Balance; #[allow(dead_code)] -type NegativeImbalanceOf = as Currency<::AccountId>>::NegativeImbalance; +type NegativeImbalanceOf = + as Currency<::AccountId>>::NegativeImbalance; type TrieIndex = u32; @@ -83,25 +85,43 @@ pub trait WeightInfo { fn create() -> Weight; fn contribute() -> Weight; fn withdraw() -> Weight; - fn refund(k: u32, ) -> Weight; + fn refund(k: u32) -> Weight; fn dissolve() -> Weight; fn edit() -> Weight; fn add_memo() -> Weight; - fn on_initialize(n: u32, ) -> Weight; + fn on_initialize(n: u32) -> Weight; fn poke() -> Weight; } pub struct TestWeightInfo; impl WeightInfo for TestWeightInfo { - fn create() -> Weight { 0 } - fn contribute() -> Weight { 0 } - fn withdraw() -> Weight { 0 } - fn refund(_k: u32, ) -> Weight { 0 } - fn dissolve() -> Weight { 0 } - fn edit() -> Weight { 0 } - fn add_memo() -> Weight { 0 } - fn on_initialize(_n: u32, ) -> Weight { 0 } - fn poke() -> Weight { 0 } + fn create() -> Weight { + 0 + } + fn contribute() -> Weight { + 0 + } + fn withdraw() -> Weight { + 0 + } + fn refund(_k: u32) -> Weight { + 0 + } + fn dissolve() -> Weight { + 0 + } + fn edit() -> Weight { + 0 + } + fn add_memo() -> Weight { + 0 + } + fn on_initialize(_n: u32) -> Weight { + 0 + } + fn poke() -> Weight { + 0 + } } #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug)] @@ -148,9 +168,9 @@ pub struct FundInfo { #[frame_support::pallet] pub mod pallet { - use frame_support::pallet_prelude::*; - use frame_system::{pallet_prelude::*, ensure_signed, ensure_root}; use super::*; + use frame_support::pallet_prelude::*; + use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -178,13 +198,13 @@ pub mod pallet { /// The parachain registrar type. We just use this to ensure that only the manager of a para is able to /// start a crowdloan for its slot. - type Registrar: Registrar; + type Registrar: Registrar; /// The type representing the auctioning system. type Auctioneer: Auctioneer< - AccountId=Self::AccountId, - BlockNumber=Self::BlockNumber, - LeasePeriod=Self::BlockNumber, + AccountId = Self::AccountId, + BlockNumber = Self::BlockNumber, + LeasePeriod = Self::BlockNumber, >; /// The maximum length for the memo attached to a crowdloan contribution. @@ -199,7 +219,8 @@ pub mod pallet { #[pallet::getter(fn funds)] pub(super) type Funds = StorageMap< _, - Twox64Concat, ParaId, + Twox64Concat, + ParaId, FundInfo, T::BlockNumber, LeasePeriodOf>, >; @@ -305,7 +326,9 @@ pub mod pallet { } let new_raise = NewRaise::::take(); let new_raise_len = new_raise.len() as u32; - for (fund, para_id) in new_raise.into_iter().filter_map(|i| Self::funds(i).map(|f| (f, i))) { + for (fund, para_id) in + new_raise.into_iter().filter_map(|i| Self::funds(i).map(|f| (f, i))) + { // Care needs to be taken by the crowdloan creator that this function will succeed given // the crowdloaning configuration. We do some checks ahead of time in crowdloan `create`. let result = T::Auctioneer::place_bid( @@ -349,9 +372,13 @@ pub mod pallet { .ok_or(Error::::FirstPeriodTooFarInFuture)?; ensure!(last_period <= last_period_limit, Error::::LastPeriodTooFarInFuture); ensure!(end > >::block_number(), Error::::CannotEndInPast); - let last_possible_win_date = (first_period.saturating_add(One::one())).saturating_mul(T::Auctioneer::lease_period()); + let last_possible_win_date = (first_period.saturating_add(One::one())) + .saturating_mul(T::Auctioneer::lease_period()); ensure!(end <= last_possible_win_date, Error::::EndTooFarInFuture); - ensure!(first_period >= T::Auctioneer::lease_period_index(), Error::::FirstPeriodInPast); + ensure!( + first_period >= T::Auctioneer::lease_period_index(), + Error::::FirstPeriodInPast + ); // There should not be an existing fund. ensure!(!Funds::::contains_key(index), Error::::FundNotEnded); @@ -367,18 +394,21 @@ pub mod pallet { CurrencyOf::::reserve(&depositor, deposit)?; - Funds::::insert(index, FundInfo { - depositor, - verifier, - deposit, - raised: Zero::zero(), - end, - cap, - last_contribution: LastContribution::Never, - first_period, - last_period, - trie_index, - }); + Funds::::insert( + index, + FundInfo { + depositor, + verifier, + deposit, + raised: Zero::zero(), + end, + cap, + last_contribution: LastContribution::Never, + first_period, + last_period, + trie_index, + }, + ); NextTrieIndex::::put(new_trie_index); // Add a lock to the para so that the configuration cannot be changed. @@ -401,7 +431,7 @@ pub mod pallet { ensure!(value >= T::MinContribution::get(), Error::::ContributionTooSmall); let mut fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - fund.raised = fund.raised.checked_add(&value).ok_or(Error::::Overflow)?; + fund.raised = fund.raised.checked_add(&value).ok_or(Error::::Overflow)?; ensure!(fund.raised <= fund.cap, Error::::CapExceeded); // Make sure crowdloan has not ended @@ -414,7 +444,10 @@ pub mod pallet { // Make sure crowdloan has not already won. let fund_account = Self::fund_account_id(index); - ensure!(!T::Auctioneer::has_won_an_auction(index, &fund_account), Error::::BidOrLeaseActive); + ensure!( + !T::Auctioneer::has_won_an_auction(index, &fund_account), + Error::::BidOrLeaseActive + ); // We disallow any crowdloan contributions during the VRF Period, so that people do not sneak their // contributions into the auction when it would not impact the outcome. @@ -425,7 +458,9 @@ pub mod pallet { if let Some(ref verifier) = fund.verifier { let signature = signature.ok_or(Error::::InvalidSignature)?; let payload = (index, &who, old_balance, value); - let valid = payload.using_encoded(|encoded| signature.verify(encoded, &verifier.clone().into_account())); + let valid = payload.using_encoded(|encoded| { + signature.verify(encoded, &verifier.clone().into_account()) + }); ensure!(valid, Error::::InvalidSignature); } @@ -439,11 +474,11 @@ pub mod pallet { // In ending period; must ensure that we are in NewRaise. LastContribution::Ending(n) if n == now => { // do nothing - already in NewRaise - } + }, _ => { NewRaise::::append(index); fund.last_contribution = LastContribution::Ending(now); - } + }, } } else { let endings_count = Self::endings_count(); @@ -452,13 +487,13 @@ pub mod pallet { // Not in ending period and no auctions have ended ending since our // previous bid which was also not in an ending period. // `NewRaise` will contain our ID still: Do nothing. - } + }, _ => { // Not in ending period; but an auction has been ending since our previous // bid, or we never had one to begin with. Add bid. NewRaise::::append(index); fund.last_contribution = LastContribution::PreEnding(endings_count); - } + }, } } @@ -538,7 +573,7 @@ pub mod pallet { if refund_count >= T::RemoveKeysLimit::get() { // Not everyone was able to be refunded this time around. all_refunded = false; - break; + break } CurrencyOf::::transfer(&fund_account, &who, balance, AllowDeath)?; Self::contribution_kill(fund.trie_index, &who); @@ -602,18 +637,21 @@ pub mod pallet { let fund = Self::funds(index).ok_or(Error::::InvalidParaId)?; - Funds::::insert(index, FundInfo { - depositor: fund.depositor, - verifier, - deposit: fund.deposit, - raised: fund.raised, - end, - cap, - last_contribution: fund.last_contribution, - first_period, - last_period, - trie_index: fund.trie_index, - }); + Funds::::insert( + index, + FundInfo { + depositor: fund.depositor, + verifier, + deposit: fund.deposit, + raised: fund.raised, + end, + cap, + last_contribution: fund.last_contribution, + first_period, + last_period, + trie_index: fund.trie_index, + }, + ); Self::deposit_event(Event::::Edited(index)); Ok(()) @@ -669,15 +707,19 @@ impl Pallet { child::ChildInfo::new_default(T::Hashing::hash(&buf[..]).as_ref()) } - pub fn contribution_put(index: TrieIndex, who: &T::AccountId, balance: &BalanceOf, memo: &[u8]) { + pub fn contribution_put( + index: TrieIndex, + who: &T::AccountId, + balance: &BalanceOf, + memo: &[u8], + ) { who.using_encoded(|b| child::put(&Self::id_from_index(index), b, &(balance, memo))); } pub fn contribution_get(index: TrieIndex, who: &T::AccountId) -> (BalanceOf, Vec) { - who.using_encoded(|b| child::get_or_default::<(BalanceOf, Vec)>( - &Self::id_from_index(index), - b, - )) + who.using_encoded(|b| { + child::get_or_default::<(BalanceOf, Vec)>(&Self::id_from_index(index), b) + }) } pub fn contribution_kill(index: TrieIndex, who: &T::AccountId) { @@ -689,9 +731,12 @@ impl Pallet { } pub fn contribution_iterator( - index: TrieIndex + index: TrieIndex, ) -> ChildTriePrefixIterator<(T::AccountId, (BalanceOf, Vec))> { - ChildTriePrefixIterator::<_>::with_prefix_over_key::(&Self::id_from_index(index), &[]) + ChildTriePrefixIterator::<_>::with_prefix_over_key::( + &Self::id_from_index(index), + &[], + ) } /// This function checks all conditions which would qualify a crowdloan has ended. @@ -701,40 +746,39 @@ impl Pallet { fn ensure_crowdloan_ended( now: T::BlockNumber, fund_account: &T::AccountId, - fund: &FundInfo, T::BlockNumber, LeasePeriodOf> + fund: &FundInfo, T::BlockNumber, LeasePeriodOf>, ) -> sp_runtime::DispatchResult { - // `fund.end` can represent the end of a failed crowdloan or the beginning of retirement - // If the current lease period is past the first period they are trying to bid for, then - // it is already too late to win the bid. - let current_lease_period = T::Auctioneer::lease_period_index(); - ensure!(now >= fund.end || current_lease_period > fund.first_period, Error::::FundNotEnded); - // free balance must greater than or equal amount raised, otherwise funds are being used - // and a bid or lease must be active. - ensure!(CurrencyOf::::free_balance(&fund_account) >= fund.raised, Error::::BidOrLeaseActive); - - Ok(()) + // `fund.end` can represent the end of a failed crowdloan or the beginning of retirement + // If the current lease period is past the first period they are trying to bid for, then + // it is already too late to win the bid. + let current_lease_period = T::Auctioneer::lease_period_index(); + ensure!( + now >= fund.end || current_lease_period > fund.first_period, + Error::::FundNotEnded + ); + // free balance must greater than or equal amount raised, otherwise funds are being used + // and a bid or lease must be active. + ensure!( + CurrencyOf::::free_balance(&fund_account) >= fund.raised, + Error::::BidOrLeaseActive + ); + + Ok(()) } } impl crate::traits::OnSwap for Pallet { fn on_swap(one: ParaId, other: ParaId) { - Funds::::mutate(one, |x| - Funds::::mutate(other, |y| - sp_std::mem::swap(x, y) - ) - ) + Funds::::mutate(one, |x| Funds::::mutate(other, |y| sp_std::mem::swap(x, y))) } } #[cfg(any(feature = "runtime-benchmarks", test))] mod crypto { use sp_core::ed25519; - use sp_io::crypto::{ed25519_sign, ed25519_generate}; - use sp_std::{ - vec::Vec, - convert::TryFrom, - }; - use sp_runtime::{MultiSigner, MultiSignature}; + use sp_io::crypto::{ed25519_generate, ed25519_sign}; + use sp_runtime::{MultiSignature, MultiSigner}; + use sp_std::{convert::TryFrom, vec::Vec}; pub fn create_ed25519_pubkey(seed: Vec) -> MultiSigner { ed25519_generate(0.into(), Some(seed)).into() @@ -751,24 +795,26 @@ mod crypto { mod tests { use super::*; - use std::{cell::RefCell, sync::Arc, collections::BTreeMap}; use frame_support::{ - assert_ok, assert_noop, parameter_types, - traits::{OnInitialize, OnFinalize}, + assert_noop, assert_ok, parameter_types, + traits::{OnFinalize, OnInitialize}, }; - use sp_core::H256; use primitives::v1::Id as ParaId; + use sp_core::H256; + use std::{cell::RefCell, collections::BTreeMap, sync::Arc}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. - use sp_runtime::{ - testing::Header, traits::{BlakeTwo256, IdentityLookup}, DispatchResult, - }; use crate::{ - mock::TestRegistrar, - traits::{OnSwap, AuctionStatus}, crowdloan, + mock::TestRegistrar, + traits::{AuctionStatus, OnSwap}, + }; + use sp_keystore::{testing::KeyStore, KeystoreExt}; + use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + DispatchResult, }; - use sp_keystore::{KeystoreExt, testing::KeyStore}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -840,7 +886,7 @@ mod tests { para: ParaId, first_period: u64, last_period: u64, - amount: u64 + amount: u64, } thread_local! { static AUCTION: RefCell> = RefCell::new(None); @@ -875,7 +921,8 @@ mod tests { let account_id = Crowdloan::fund_account_id(para); if winner { let free_balance = Balances::free_balance(&account_id); - Balances::reserve(&account_id, free_balance).expect("should be able to reserve free balance"); + Balances::reserve(&account_id, free_balance) + .expect("should be able to reserve free balance"); } else { let reserved_balance = Balances::reserved_balance(&account_id); Balances::unreserve(&account_id, reserved_balance); @@ -915,10 +962,10 @@ mod tests { let after_end = after_early_end - ending_period; // Optional VRF delay if after_end < vrf_delay() { - return AuctionStatus::VrfDelay(after_end); + return AuctionStatus::VrfDelay(after_end) } else { // VRF delay is done, so we just end the auction - return AuctionStatus::NotStarted; + return AuctionStatus::NotStarted } } } @@ -928,10 +975,19 @@ mod tests { para: ParaId, first_period: u64, last_period: u64, - amount: u64 + amount: u64, ) -> DispatchResult { let height = System::block_number(); - BIDS_PLACED.with(|p| p.borrow_mut().push(BidPlaced { height, bidder, para, first_period, last_period, amount })); + BIDS_PLACED.with(|p| { + p.borrow_mut().push(BidPlaced { + height, + bidder, + para, + first_period, + last_period, + amount, + }) + }); Ok(()) } @@ -974,9 +1030,11 @@ mod tests { // our desired mockup. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig::{ + pallet_balances::GenesisConfig:: { balances: vec![(1, 1000), (2, 2000), (3, 3000), (4, 4000)], - }.assimilate_storage(&mut t).unwrap(); + } + .assimilate_storage(&mut t) + .unwrap(); let keystore = KeyStore::new(); let mut t: sp_io::TestExternalities = t.into(); t.register_extension(KeystoreExt(Arc::new(keystore))); @@ -986,9 +1044,16 @@ mod tests { fn new_para() -> ParaId { for i in 0.. { let para: ParaId = i.into(); - if TestRegistrar::::is_registered(para) { continue } - assert_ok!(TestRegistrar::::register(1, para, Default::default(), Default::default())); - return para; + if TestRegistrar::::is_registered(para) { + continue + } + assert_ok!(TestRegistrar::::register( + 1, + para, + Default::default(), + Default::default() + )); + return para } unreachable!() } @@ -1023,7 +1088,14 @@ mod tests { assert_eq!(bids(), vec![]); assert_ok!(TestAuctioneer::place_bid(1, 2.into(), 0, 3, 6)); - let b = BidPlaced { height: 0, bidder: 1, para: 2.into(), first_period: 0, last_period: 3, amount: 6 }; + let b = BidPlaced { + height: 0, + bidder: 1, + para: 2.into(), + first_period: 0, + last_period: 3, + amount: 6, + }; assert_eq!(bids(), vec![b]); assert_eq!(TestAuctioneer::auction_status(4), AuctionStatus::::StartingPeriod); assert_eq!(TestAuctioneer::auction_status(5), AuctionStatus::::EndingPeriod(0, 0)); @@ -1069,7 +1141,15 @@ mod tests { let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); let para = new_para(); // Now try to create a crowdloan campaign - assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 4, 9, Some(pubkey.clone()))); + assert_ok!(Crowdloan::create( + Origin::signed(1), + para, + 1000, + 1, + 4, + 9, + Some(pubkey.clone()) + )); // This is what the initial `fund_info` should look like let fund_info = FundInfo { depositor: 1, @@ -1110,13 +1190,24 @@ mod tests { assert_noop!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 9, 9, None), e); // Cannot create a crowdloan without some deposit funds - assert_ok!(TestRegistrar::::register(1337, ParaId::from(1234), Default::default(), Default::default())); + assert_ok!(TestRegistrar::::register( + 1337, + ParaId::from(1234), + Default::default(), + Default::default() + )); let e = BalancesError::::InsufficientBalance; - assert_noop!(Crowdloan::create(Origin::signed(1337), ParaId::from(1234), 1000, 1, 3, 9, None), e); + assert_noop!( + Crowdloan::create(Origin::signed(1337), ParaId::from(1234), 1000, 1, 3, 9, None), + e + ); // Cannot create a crowdloan with nonsense end date // This crowdloan would end in lease period 2, but is bidding for some slot that starts in lease period 1. - assert_noop!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 4, 41, None), Error::::EndTooFarInFuture); + assert_noop!( + Crowdloan::create(Origin::signed(1), para, 1000, 1, 4, 41, None), + Error::::EndTooFarInFuture + ); }); } @@ -1156,30 +1247,59 @@ mod tests { let para = new_para(); let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec()); // Set up a crowdloan - assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 4, 9, Some(pubkey.clone()))); + assert_ok!(Crowdloan::create( + Origin::signed(1), + para, + 1000, + 1, + 4, + 9, + Some(pubkey.clone()) + )); // No contributions yet assert_eq!(Crowdloan::contribution_get(u32::from(para), &1).0, 0); // Missing signature - assert_noop!(Crowdloan::contribute(Origin::signed(1), para, 49, None), Error::::InvalidSignature); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para, 49, None), + Error::::InvalidSignature + ); let payload = (0u32, 1u64, 0u64, 49u64); - let valid_signature = crypto::create_ed25519_signature(&payload.encode(), pubkey.clone()); + let valid_signature = + crypto::create_ed25519_signature(&payload.encode(), pubkey.clone()); let invalid_signature = MultiSignature::default(); // Invalid signature - assert_noop!(Crowdloan::contribute(Origin::signed(1), para, 49, Some(invalid_signature)), Error::::InvalidSignature); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para, 49, Some(invalid_signature)), + Error::::InvalidSignature + ); // Valid signature wrong parameter - assert_noop!(Crowdloan::contribute(Origin::signed(1), para, 50, Some(valid_signature.clone())), Error::::InvalidSignature); - assert_noop!(Crowdloan::contribute(Origin::signed(2), para, 49, Some(valid_signature.clone())), Error::::InvalidSignature); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para, 50, Some(valid_signature.clone())), + Error::::InvalidSignature + ); + assert_noop!( + Crowdloan::contribute(Origin::signed(2), para, 49, Some(valid_signature.clone())), + Error::::InvalidSignature + ); // Valid signature - assert_ok!(Crowdloan::contribute(Origin::signed(1), para, 49, Some(valid_signature.clone()))); + assert_ok!(Crowdloan::contribute( + Origin::signed(1), + para, + 49, + Some(valid_signature.clone()) + )); // Reuse valid signature - assert_noop!(Crowdloan::contribute(Origin::signed(1), para, 49, Some(valid_signature)), Error::::InvalidSignature); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para, 49, Some(valid_signature)), + Error::::InvalidSignature + ); let payload_2 = (0u32, 1u64, 49u64, 10u64); let valid_signature_2 = crypto::create_ed25519_signature(&payload_2.encode(), pubkey); @@ -1202,22 +1322,34 @@ mod tests { let para = new_para(); // Cannot contribute to non-existing fund - assert_noop!(Crowdloan::contribute(Origin::signed(1), para, 49, None), Error::::InvalidParaId); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para, 49, None), + Error::::InvalidParaId + ); // Cannot contribute below minimum contribution - assert_noop!(Crowdloan::contribute(Origin::signed(1), para, 9, None), Error::::ContributionTooSmall); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para, 9, None), + Error::::ContributionTooSmall + ); // Set up a crowdloan assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, 1, 4, 9, None)); assert_ok!(Crowdloan::contribute(Origin::signed(1), para, 101, None)); // Cannot contribute past the limit - assert_noop!(Crowdloan::contribute(Origin::signed(2), para, 900, None), Error::::CapExceeded); + assert_noop!( + Crowdloan::contribute(Origin::signed(2), para, 900, None), + Error::::CapExceeded + ); // Move past end date run_to_block(10); // Cannot contribute to ended fund - assert_noop!(Crowdloan::contribute(Origin::signed(1), para, 49, None), Error::::ContributionPeriodOver); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para, 49, None), + Error::::ContributionPeriodOver + ); // If a crowdloan has already won, it should not allow contributions. let para_2 = new_para(); @@ -1225,7 +1357,10 @@ mod tests { // Emulate a win by leasing out and putting a deposit. Slots pallet would normally do this. let crowdloan_account = Crowdloan::fund_account_id(para_2); set_winner(para_2, crowdloan_account, true); - assert_noop!(Crowdloan::contribute(Origin::signed(1), para_2, 49, None), Error::::BidOrLeaseActive); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para_2, 49, None), + Error::::BidOrLeaseActive + ); // Move past lease period 1, should not be allowed to have further contributions with a crowdloan // that has starting period 1. @@ -1233,7 +1368,10 @@ mod tests { assert_ok!(Crowdloan::create(Origin::signed(1), para_3, 1000, 1, 4, 40, None)); run_to_block(40); assert_eq!(TestAuctioneer::lease_period_index(), 2); - assert_noop!(Crowdloan::contribute(Origin::signed(1), para_3, 49, None), Error::::ContributionPeriodOver); + assert_noop!( + Crowdloan::contribute(Origin::signed(1), para_3, 49, None), + Error::::ContributionPeriodOver + ); }); } @@ -1249,7 +1387,15 @@ mod tests { assert_ok!(TestAuctioneer::new_auction(5, 0)); // Set up a crowdloan - assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, first_period, last_period, 20, None)); + assert_ok!(Crowdloan::create( + Origin::signed(1), + para, + 1000, + first_period, + last_period, + 20, + None + )); run_to_block(8); // Can def contribute when auction is running. @@ -1259,7 +1405,10 @@ mod tests { run_to_block(10); // Can't contribute when auction is in the VRF delay period. assert!(TestAuctioneer::auction_status(System::block_number()).is_vrf()); - assert_noop!(Crowdloan::contribute(Origin::signed(2), para, 250, None), Error::::VrfDelayInProgress); + assert_noop!( + Crowdloan::contribute(Origin::signed(2), para, 250, None), + Error::::VrfDelayInProgress + ); run_to_block(15); // Its fine to contribute when no auction is running. @@ -1278,7 +1427,15 @@ mod tests { assert_ok!(TestAuctioneer::new_auction(5, 0)); // Set up a crowdloan - assert_ok!(Crowdloan::create(Origin::signed(1), para, 1000, first_period, last_period, 9, None)); + assert_ok!(Crowdloan::create( + Origin::signed(1), + para, + 1000, + first_period, + last_period, + 9, + None + )); let bidder = Crowdloan::fund_account_id(para); // Fund crowdloan @@ -1292,11 +1449,14 @@ mod tests { assert_ok!(Crowdloan::contribute(Origin::signed(2), para, 250, None)); run_to_block(10); - assert_eq!(bids(), vec![ - BidPlaced { height: 5, amount: 250, bidder, para, first_period, last_period }, - BidPlaced { height: 6, amount: 450, bidder, para, first_period, last_period }, - BidPlaced { height: 9, amount: 700, bidder, para, first_period, last_period }, - ]); + assert_eq!( + bids(), + vec![ + BidPlaced { height: 5, amount: 250, bidder, para, first_period, last_period }, + BidPlaced { height: 6, amount: 450, bidder, para, first_period, last_period }, + BidPlaced { height: 9, amount: 700, bidder, para, first_period, last_period }, + ] + ); // Endings count incremented assert_eq!(Crowdloan::endings_count(), 1); @@ -1405,9 +1565,14 @@ mod tests { // Set up a crowdloan ending on 9 assert_ok!(Crowdloan::create(Origin::signed(1), para, 100000, 1, 1, 9, None)); // Make more contributions than our limit - for i in 1 ..= RemoveKeysLimit::get() * 2 { + for i in 1..=RemoveKeysLimit::get() * 2 { Balances::make_free_balance_be(&i.into(), (1000 * i).into()); - assert_ok!(Crowdloan::contribute(Origin::signed(i.into()), para, (i * 100).into(), None)); + assert_ok!(Crowdloan::contribute( + Origin::signed(i.into()), + para, + (i * 100).into(), + None + )); } assert_eq!(Balances::free_balance(account_id), 21000); @@ -1427,7 +1592,7 @@ mod tests { // Funds are returned assert_eq!(Balances::free_balance(account_id), 0); // 1 deposit for the crowdloan which hasn't dissolved yet. - for i in 1 ..= RemoveKeysLimit::get() * 2 { + for i in 1..=RemoveKeysLimit::get() * 2 { assert_eq!(Balances::free_balance(&i.into()), i as u64 * 1000); } }); @@ -1469,16 +1634,25 @@ mod tests { assert_ok!(Crowdloan::contribute(Origin::signed(3), para, 50, None)); // Can't dissolve before it ends - assert_noop!(Crowdloan::dissolve(Origin::signed(1), para), Error::::NotReadyToDissolve); + assert_noop!( + Crowdloan::dissolve(Origin::signed(1), para), + Error::::NotReadyToDissolve + ); run_to_block(10); set_winner(para, 1, true); // Can't dissolve when it won. - assert_noop!(Crowdloan::dissolve(Origin::signed(1), para), Error::::NotReadyToDissolve); + assert_noop!( + Crowdloan::dissolve(Origin::signed(1), para), + Error::::NotReadyToDissolve + ); set_winner(para, 1, false); // Can't dissolve while it still has user funds - assert_noop!(Crowdloan::dissolve(Origin::signed(1), para), Error::::NotReadyToDissolve); + assert_noop!( + Crowdloan::dissolve(Origin::signed(1), para), + Error::::NotReadyToDissolve + ); // All funds are refunded assert_ok!(Crowdloan::refund(Origin::signed(2), para)); @@ -1508,7 +1682,10 @@ mod tests { assert_ok!(Balances::reserve(&account_id, 150)); run_to_block(19); - assert_noop!(Crowdloan::withdraw(Origin::signed(2), 2, para), Error::::BidOrLeaseActive); + assert_noop!( + Crowdloan::withdraw(Origin::signed(2), 2, para), + Error::::BidOrLeaseActive + ); run_to_block(20); // simulate the unreserving of para's funds, now that the lease expired. this actually @@ -1566,7 +1743,6 @@ mod tests { Crowdloan::create(Origin::signed(1), para_1, 1000, 1, 1, 9, None), Error::::FundNotEnded, ); - }); } @@ -1648,16 +1824,13 @@ mod tests { #[cfg(feature = "runtime-benchmarks")] mod benchmarking { - use super::{*, Pallet as Crowdloan}; + use super::{Pallet as Crowdloan, *}; + use frame_support::{assert_ok, traits::OnInitialize}; use frame_system::RawOrigin; - use frame_support::{ - assert_ok, - traits::OnInitialize, - }; use sp_runtime::traits::{Bounded, CheckedSub}; use sp_std::prelude::*; - use frame_benchmarking::{benchmarks, whitelisted_caller, account, impl_benchmark_test_suite}; + use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; fn assert_last_event(generic_event: ::Event) { let events = frame_system::Pallet::::events(); @@ -1671,7 +1844,8 @@ mod benchmarking { let cap = BalanceOf::::max_value(); let lease_period_index = T::Auctioneer::lease_period_index(); let first_period = lease_period_index; - let last_period = lease_period_index + ((SlotRange::LEASE_PERIODS_PER_SLOT as u32) - 1).into(); + let last_period = + lease_period_index + ((SlotRange::LEASE_PERIODS_PER_SLOT as u32) - 1).into(); let para_id = id.into(); let caller = account("fund_creator", id, 0); @@ -1706,7 +1880,12 @@ mod benchmarking { let payload = (index, &who, BalanceOf::::default(), value); let sig = crypto::create_ed25519_signature(&payload.encode(), pubkey); - assert_ok!(Crowdloan::::contribute(RawOrigin::Signed(who.clone()).into(), index, value, Some(sig))); + assert_ok!(Crowdloan::::contribute( + RawOrigin::Signed(who.clone()).into(), + index, + value, + Some(sig) + )); } benchmarks! { diff --git a/polkadot/runtime/common/src/elections.rs b/polkadot/runtime/common/src/elections.rs index 35d60e4a583..b85d8013f4f 100644 --- a/polkadot/runtime/common/src/elections.rs +++ b/polkadot/runtime/common/src/elections.rs @@ -16,12 +16,12 @@ //! Code for elections. +use super::{BlockExecutionWeight, BlockLength, BlockWeights}; use frame_support::{ parameter_types, weights::{DispatchClass, Weight}, }; use sp_runtime::Perbill; -use super::{BlockExecutionWeight, BlockLength, BlockWeights}; parameter_types! { /// A limit for off-chain phragmen unsigned solution submission. diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 655b6b3401a..28990a0929c 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -16,8 +16,8 @@ //! Auxiliary `struct`/`enum`s for polkadot runtime. -use frame_support::traits::{OnUnbalanced, Imbalance, Currency}; use crate::NegativeImbalance; +use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; /// Logic for the author to get a portion of fees. pub struct ToAuthor(sp_std::marker::PhantomData); @@ -31,8 +31,14 @@ where fn on_nonzero_unbalanced(amount: NegativeImbalance) { let numeric_amount = amount.peek(); let author = >::author(); - >::resolve_creating(&>::author(), amount); - >::deposit_event(pallet_balances::Event::Deposit(author, numeric_amount)); + >::resolve_creating( + &>::author(), + amount, + ); + >::deposit_event(pallet_balances::Event::Deposit( + author, + numeric_amount, + )); } } @@ -45,7 +51,7 @@ where ::AccountId: Into, ::Event: From>, { - fn on_unbalanceds(mut fees_then_tips: impl Iterator>) { + fn on_unbalanceds(mut fees_then_tips: impl Iterator>) { if let Some(fees) = fees_then_tips.next() { // for fees, 80% to treasury, 20% to author let mut split = fees.ration(80, 20); @@ -60,20 +66,18 @@ where } } - #[cfg(test)] mod tests { use super::*; + use frame_support::{parameter_types, traits::FindAuthor, weights::DispatchClass, PalletId}; use frame_system::limits; - use frame_support::{parameter_types, PalletId, weights::DispatchClass}; - use frame_support::traits::FindAuthor; + use primitives::v1::AccountId; use sp_core::H256; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, Perbill, }; - use primitives::v1::AccountId; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -169,7 +173,8 @@ mod tests { pub struct OneAuthor; impl FindAuthor for OneAuthor { fn find_author<'a, I>(_: I) -> Option - where I: 'a, + where + I: 'a, { Some(Default::default()) } @@ -184,7 +189,9 @@ mod tests { pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. - pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); + pallet_balances::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); t.into() } diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index 003e49c0ad1..809526f71c7 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -16,33 +16,28 @@ //! Mocking utilities for testing with real pallets. -use sp_std::sync::Arc; -use sp_io::TestExternalities; -use sp_core::{H256, crypto::KeyTypeId}; -use sp_runtime::{ - traits::{ - BlakeTwo256, IdentityLookup, One, - }, +use crate::{ + auctions, crowdloan, paras_registrar, + slot_range::SlotRange, + slots, + traits::{AuctionStatus, Auctioneer, Registrar as RegistrarT}, }; -use sp_keystore::{KeystoreExt, testing::KeyStore}; -use primitives::v1::{BlockNumber, Header, Id as ParaId, ValidationCode, HeadData, LOWEST_PUBLIC_ID}; use frame_support::{ - parameter_types, assert_ok, assert_noop, PalletId, - traits::{Currency, OnInitialize, OnFinalize, KeyOwnerProofSystem, GenesisBuild}, -}; -use frame_system::EnsureRoot; -use runtime_parachains::{ - ParaLifecycle, Origin as ParaOrigin, - paras, configuration, shared, + assert_noop, assert_ok, parameter_types, + traits::{Currency, GenesisBuild, KeyOwnerProofSystem, OnFinalize, OnInitialize}, + PalletId, }; use frame_support_test::TestRandomness; -use crate::{ - auctions, crowdloan, slots, paras_registrar, - slot_range::SlotRange, - traits::{ - Registrar as RegistrarT, Auctioneer, AuctionStatus, - }, +use frame_system::EnsureRoot; +use primitives::v1::{ + BlockNumber, HeadData, Header, Id as ParaId, ValidationCode, LOWEST_PUBLIC_ID, }; +use runtime_parachains::{configuration, paras, shared, Origin as ParaOrigin, ParaLifecycle}; +use sp_core::{crypto::KeyTypeId, H256}; +use sp_io::TestExternalities; +use sp_keystore::{testing::KeyStore, KeystoreExt}; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup, One}; +use sp_std::sync::Arc; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -75,8 +70,7 @@ frame_support::construct_runtime!( } ); -use crate::crowdloan::Error as CrowdloanError; -use crate::auctions::Error as AuctionsError; +use crate::{auctions::Error as AuctionsError, crowdloan::Error as CrowdloanError}; parameter_types! { pub const BlockHashCount: u32 = 250; @@ -121,8 +115,10 @@ impl pallet_babe::Config for Test { type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = pallet_babe::ExternalTrigger; type KeyOwnerProofSystem = (); - type KeyOwnerProof = - >::Proof; + type KeyOwnerProof = >::Proof; type KeyOwnerIdentification = TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisBuild::::assimilate_storage( &configuration::GenesisConfig { - config: configuration::HostConfiguration { - max_code_size: 2 * 1024 * 1024, // 2 MB - max_head_data_size: 1 * 1024 * 1024, // 1 MB - ..Default::default() - } + config: configuration::HostConfiguration { + max_code_size: 2 * 1024 * 1024, // 2 MB + max_head_data_size: 1 * 1024 * 1024, // 1 MB + ..Default::default() }, - &mut t - ).unwrap(); + }, + &mut t, + ) + .unwrap(); let keystore = KeyStore::new(); let mut ext: sp_io::TestExternalities = t.into(); ext.register_extension(KeystoreExt(Arc::new(keystore))); @@ -255,9 +252,7 @@ const BLOCKS_PER_SESSION: u32 = 10; fn maybe_new_session(n: u32) { if n % BLOCKS_PER_SESSION == 0 { - shared::Pallet::::set_session_index( - shared::Pallet::::session_index() + 1 - ); + shared::Pallet::::set_session_index(shared::Pallet::::session_index() + 1); Paras::test_on_new_session(); } } @@ -343,10 +338,10 @@ fn basic_end_to_end_works() { assert_ok!(Crowdloan::create( Origin::signed(2), ParaId::from(para_2), - 1_000, // Cap + 1_000, // Cap lease_period_index_start + 2, // First Slot lease_period_index_start + 3, // Last Slot - 200, // Block End + 200, // Block End None, )); let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(para_2)); @@ -361,10 +356,10 @@ fn basic_end_to_end_works() { assert_ok!(Auctions::bid( Origin::signed(10), ParaId::from(para_1), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 0, // First Slot lease_period_index_start + 1, // Last slot - 910, // Amount + 910, // Amount )); // User 2 will be a contribute to crowdloan for parachain 2 @@ -378,10 +373,7 @@ fn basic_end_to_end_works() { crowdloan::Event::::HandleBidResult(ParaId::from(para_2), Ok(())).into(), ); run_to_block(110); - assert_eq!( - last_event(), - auctions::Event::::AuctionClosed(1).into(), - ); + assert_eq!(last_event(), auctions::Event::::AuctionClosed(1).into(),); // Paras should have won slots assert_eq!( @@ -392,19 +384,33 @@ fn basic_end_to_end_works() { assert_eq!( slots::Leases::::get(ParaId::from(para_2)), // -- 1 --- 2 --- 3 --- 4 --- 5 ---------------- 6 --------------------------- 7 ---------------- - vec![None, None, None, None, None, Some((crowdloan_account, 920)), Some((crowdloan_account, 920))], + vec![ + None, + None, + None, + None, + None, + Some((crowdloan_account, 920)), + Some((crowdloan_account, 920)) + ], ); // Should not be able to contribute to a winning crowdloan Balances::make_free_balance_be(&3, 1_000_000_000); - assert_noop!(Crowdloan::contribute(Origin::signed(3), ParaId::from(2001), 10, None), CrowdloanError::::BidOrLeaseActive); + assert_noop!( + Crowdloan::contribute(Origin::signed(3), ParaId::from(2001), 10, None), + CrowdloanError::::BidOrLeaseActive + ); // New leases will start on block 400 let lease_start_block = 400; run_to_block(lease_start_block); // First slot, Para 1 should be transitioning to Parachain - assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::UpgradingParathread)); + assert_eq!( + Paras::lifecycle(ParaId::from(para_1)), + Some(ParaLifecycle::UpgradingParathread) + ); assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread)); // Two sessions later, it has upgraded @@ -419,8 +425,14 @@ fn basic_end_to_end_works() { // Third slot, Para 2 should be upgrading, and Para 1 is downgrading run_to_block(lease_start_block + 200); - assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::DowngradingParachain)); - assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::UpgradingParathread)); + assert_eq!( + Paras::lifecycle(ParaId::from(para_1)), + Some(ParaLifecycle::DowngradingParachain) + ); + assert_eq!( + Paras::lifecycle(ParaId::from(para_2)), + Some(ParaLifecycle::UpgradingParathread) + ); // Two sessions later, they have transitioned run_to_block(lease_start_block + 220); @@ -435,7 +447,10 @@ fn basic_end_to_end_works() { // Fifth slot, Para 2 is downgrading run_to_block(lease_start_block + 400); assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread)); - assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::DowngradingParachain)); + assert_eq!( + Paras::lifecycle(ParaId::from(para_2)), + Some(ParaLifecycle::DowngradingParachain) + ); // Two sessions later, Para 2 is downgraded run_to_block(lease_start_block + 420); @@ -463,12 +478,10 @@ fn basic_errors_fail() { validation_code.clone(), )); assert_ok!(Registrar::reserve(Origin::signed(2))); - assert_noop!(Registrar::register( - Origin::signed(2), - para_id, - genesis_head, - validation_code, - ), paras_registrar::Error::::NotOwner); + assert_noop!( + Registrar::register(Origin::signed(2), para_id, genesis_head, validation_code,), + paras_registrar::Error::::NotOwner + ); // Start an auction let duration = 99u32; @@ -476,15 +489,18 @@ fn basic_errors_fail() { assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start)); // Cannot create a crowdloan if you do not own the para - assert_noop!(Crowdloan::create( - Origin::signed(2), - para_id, - 1_000, // Cap - lease_period_index_start + 2, // First Slot - lease_period_index_start + 3, // Last Slot - 200, // Block End - None, - ), crowdloan::Error::::InvalidOrigin); + assert_noop!( + Crowdloan::create( + Origin::signed(2), + para_id, + 1_000, // Cap + lease_period_index_start + 2, // First Slot + lease_period_index_start + 3, // Last Slot + 200, // Block End + None, + ), + crowdloan::Error::::InvalidOrigin + ); }); } @@ -497,7 +513,7 @@ fn competing_slots() { let para_id = LOWEST_PUBLIC_ID; // Create n paras and owners - for n in 1 ..= max_bids { + for n in 1..=max_bids { Balances::make_free_balance_be(&n, 1_000_000_000); let genesis_head = Registrar::worst_head_data(); let validation_code = Registrar::worst_validation_code(); @@ -518,22 +534,22 @@ fn competing_slots() { // Paras should be onboarded run_to_block(20); // session 2 - for n in 1 ..= max_bids { + for n in 1..=max_bids { // Increment block number run_to_block(System::block_number() + 10); Balances::make_free_balance_be(&(n * 10), n * 1_000); let (start, end) = match n { - 1 => (0, 0), - 2 => (0, 1), - 3 => (0, 2), - 4 => (0, 3), - 5 => (1, 1), - 6 => (1, 2), - 7 => (1, 3), - 8 => (2, 2), - 9 => (2, 3), + 1 => (0, 0), + 2 => (0, 1), + 3 => (0, 2), + 4 => (0, 3), + 5 => (1, 1), + 6 => (1, 2), + 7 => (1, 3), + 8 => (2, 2), + 9 => (2, 3), 10 => (3, 3), _ => panic!("test not meant for this"), }; @@ -542,10 +558,10 @@ fn competing_slots() { assert_ok!(Auctions::bid( Origin::signed(n * 10), para_id + n - 1, - 1, // Auction Index + 1, // Auction Index lease_period_index_start + start, // First Slot - lease_period_index_start + end, // Last slot - n * 900, // Amount + lease_period_index_start + end, // Last slot + n * 900, // Amount )); } @@ -582,7 +598,7 @@ fn competing_bids() { let start_para = LOWEST_PUBLIC_ID - 1; // Create 3 paras and owners - for n in 1 ..= 3 { + for n in 1..=3 { Balances::make_free_balance_be(&n, 1_000_000_000); let genesis_head = Registrar::worst_head_data(); let validation_code = Registrar::worst_validation_code(); @@ -604,20 +620,20 @@ fn competing_bids() { let lease_period_index_start = 4u32; assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start)); - for n in 1 ..= 3 { + for n in 1..=3 { // Create a crowdloan for each para assert_ok!(Crowdloan::create( Origin::signed(n), ParaId::from(start_para + n), - 100_000, // Cap + 100_000, // Cap lease_period_index_start + 2, // First Slot lease_period_index_start + 3, // Last Slot - 200, // Block End, + 200, // Block End, None, )); } - for n in 1 ..= 9 { + for n in 1..=9 { // Increment block number run_to_block(starting_block + n * 10); @@ -630,10 +646,10 @@ fn competing_bids() { assert_ok!(Auctions::bid( Origin::signed(n * 10), ParaId::from(para), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 0, // First Slot lease_period_index_start + 1, // Last slot - n * 900, // Amount + n * 900, // Amount )); } else { // User 20 will be a contribute to crowdloan for parachain 2 @@ -654,7 +670,15 @@ fn competing_bids() { assert_eq!( slots::Leases::::get(ParaId::from(2000)), // -- 1 --- 2 --- 3 --- 4 --- 5 ------------- 6 ------------------------ 7 ------------- - vec![None, None, None, None, None, Some((crowdloan_2, 1812)), Some((crowdloan_2, 1812))], + vec![ + None, + None, + None, + None, + None, + Some((crowdloan_2, 1812)), + Some((crowdloan_2, 1812)) + ], ); assert_eq!( slots::Leases::::get(ParaId::from(2002)), @@ -669,7 +693,7 @@ fn basic_swap_works() { // This test will test a swap between a parachain and parathread works successfully. new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&1, 1_000_000_000); Balances::make_free_balance_be(&2, 1_000_000_000); // First register 2 parathreads with different data @@ -706,17 +730,17 @@ fn basic_swap_works() { assert_ok!(Crowdloan::create( Origin::signed(1), ParaId::from(2000), - 1_000_000, // Cap + 1_000_000, // Cap lease_period_index_start + 0, // First Slot lease_period_index_start + 3, // Last Slot - 200, // Block End + 200, // Block End None, )); let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000)); // Bunch of contributions let mut total = 0; - for i in 10 .. 20 { + for i in 10..20 { Balances::make_free_balance_be(&i, 1_000_000_000); assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None)); total += 900 - i; @@ -750,8 +774,16 @@ fn basic_swap_works() { assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread)); // Initiate a swap - assert_ok!(Registrar::swap(para_origin(2000).into(), ParaId::from(2000), ParaId::from(2001))); - assert_ok!(Registrar::swap(para_origin(2001).into(), ParaId::from(2001), ParaId::from(2000))); + assert_ok!(Registrar::swap( + para_origin(2000).into(), + ParaId::from(2000), + ParaId::from(2001) + )); + assert_ok!(Registrar::swap( + para_origin(2001).into(), + ParaId::from(2001), + ParaId::from(2000) + )); assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::DowngradingParachain)); assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::UpgradingParathread)); @@ -774,15 +806,21 @@ fn basic_swap_works() { assert!(!Slots::lease(ParaId::from(2001)).is_empty()); // Cant dissolve - assert_noop!(Crowdloan::dissolve(Origin::signed(1), ParaId::from(2000)), CrowdloanError::::InvalidParaId); - assert_noop!(Crowdloan::dissolve(Origin::signed(2), ParaId::from(2001)), CrowdloanError::::NotReadyToDissolve); + assert_noop!( + Crowdloan::dissolve(Origin::signed(1), ParaId::from(2000)), + CrowdloanError::::InvalidParaId + ); + assert_noop!( + Crowdloan::dissolve(Origin::signed(2), ParaId::from(2001)), + CrowdloanError::::NotReadyToDissolve + ); // Go way in the future when the para is offboarded run_to_block(lease_start_block + 1000); // Withdraw of contributions works assert_eq!(Balances::free_balance(&crowdloan_account), total); - for i in 10 .. 20 { + for i in 10..20 { assert_ok!(Crowdloan::withdraw(Origin::signed(i), i, ParaId::from(2001))); } assert_eq!(Balances::free_balance(&crowdloan_account), 0); @@ -802,7 +840,7 @@ fn basic_swap_works() { fn crowdloan_ending_period_bid() { new_test_ext().execute_with(|| { assert!(System::block_number().is_one()); // So events are emitted - // User 1 and 2 will own paras + // User 1 and 2 will own paras Balances::make_free_balance_be(&1, 1_000_000_000); Balances::make_free_balance_be(&2, 1_000_000_000); // First register 2 parathreads @@ -839,17 +877,17 @@ fn crowdloan_ending_period_bid() { assert_ok!(Crowdloan::create( Origin::signed(1), ParaId::from(2000), - 1_000_000, // Cap + 1_000_000, // Cap lease_period_index_start + 0, // First Slot lease_period_index_start + 3, // Last Slot - 200, // Block End + 200, // Block End None, )); let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000)); // Bunch of contributions let mut total = 0; - for i in 10 .. 20 { + for i in 10..20 { Balances::make_free_balance_be(&i, 1_000_000_000); assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None)); total += 900 - i; @@ -862,10 +900,10 @@ fn crowdloan_ending_period_bid() { assert_ok!(Auctions::bid( Origin::signed(2), ParaId::from(2001), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 0, // First Slot lease_period_index_start + 1, // Last slot - 900, // Amount + 900, // Amount )); // Go to beginning of ending period @@ -874,7 +912,8 @@ fn crowdloan_ending_period_bid() { assert_eq!(Auctions::auction_status(100), AuctionStatus::::EndingPeriod(0, 0)); let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; winning[SlotRange::ZeroOne as u8 as usize] = Some((2, ParaId::from(2001), 900)); - winning[SlotRange::ZeroThree as u8 as usize] = Some((crowdloan_account, ParaId::from(2000), total)); + winning[SlotRange::ZeroThree as u8 as usize] = + Some((crowdloan_account, ParaId::from(2000), total)); assert_eq!(Auctions::winning(0), Some(winning)); @@ -887,7 +926,8 @@ fn crowdloan_ending_period_bid() { run_to_block(102); let mut winning = [None; SlotRange::SLOT_RANGE_COUNT]; winning[SlotRange::ZeroOne as u8 as usize] = Some((2, ParaId::from(2001), 900)); - winning[SlotRange::ZeroThree as u8 as usize] = Some((crowdloan_account, ParaId::from(2000), total + 900)); + winning[SlotRange::ZeroThree as u8 as usize] = + Some((crowdloan_account, ParaId::from(2000), total + 900)); assert_eq!(Auctions::winning(2), Some(winning)); }) } @@ -904,14 +944,17 @@ fn auction_bid_requires_registered_para() { // Can't bid with non-registered paras Balances::make_free_balance_be(&1, 1_000_000_000); - assert_noop!(Auctions::bid( - Origin::signed(1), - ParaId::from(2000), - 1, // Auction Index - lease_period_index_start + 0, // First Slot - lease_period_index_start + 1, // Last slot - 900, // Amount - ), AuctionsError::::ParaNotRegistered); + assert_noop!( + Auctions::bid( + Origin::signed(1), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + 900, // Amount + ), + AuctionsError::::ParaNotRegistered + ); // Now we register the para assert_ok!(Registrar::reserve(Origin::signed(1))); @@ -923,14 +966,17 @@ fn auction_bid_requires_registered_para() { )); // Still can't bid until it is fully onboarded - assert_noop!(Auctions::bid( - Origin::signed(1), - ParaId::from(2000), - 1, // Auction Index - lease_period_index_start + 0, // First Slot - lease_period_index_start + 1, // Last slot - 900, // Amount - ), AuctionsError::::ParaNotRegistered); + assert_noop!( + Auctions::bid( + Origin::signed(1), + ParaId::from(2000), + 1, // Auction Index + lease_period_index_start + 0, // First Slot + lease_period_index_start + 1, // Last slot + 900, // Amount + ), + AuctionsError::::ParaNotRegistered + ); // Onboarded on Session 2 run_to_session(2); @@ -940,10 +986,10 @@ fn auction_bid_requires_registered_para() { assert_ok!(Auctions::bid( Origin::signed(1), ParaId::from(2000), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 0, // First Slot lease_period_index_start + 1, // Last slot - 900, // Amount + 900, // Amount )); }); } @@ -986,29 +1032,29 @@ fn gap_bids_work() { assert_ok!(Auctions::bid( Origin::signed(10), ParaId::from(2000), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 0, // First Slot lease_period_index_start + 0, // Last slot - 100, // Amount + 100, // Amount )); // Slot 4 for 400 from 10 assert_ok!(Auctions::bid( Origin::signed(10), ParaId::from(2000), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 3, // First Slot lease_period_index_start + 3, // Last slot - 400, // Amount + 400, // Amount )); // A bid for another para is counted separately. assert_ok!(Auctions::bid( Origin::signed(10), ParaId::from(2001), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 1, // First Slot lease_period_index_start + 1, // Last slot - 555, // Amount + 555, // Amount )); assert_eq!(Balances::reserved_balance(&10), 400 + 555); @@ -1016,19 +1062,19 @@ fn gap_bids_work() { assert_ok!(Auctions::bid( Origin::signed(20), ParaId::from(2000), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 1, // First Slot lease_period_index_start + 1, // Last slot - 800, // Amount + 800, // Amount )); // Slot 3 for 200 from 20 assert_ok!(Auctions::bid( Origin::signed(20), ParaId::from(2000), - 1, // Auction Index + 1, // Auction Index lease_period_index_start + 2, // First Slot lease_period_index_start + 2, // Last slot - 200, // Amount + 200, // Amount )); // Finish the auction @@ -1038,7 +1084,15 @@ fn gap_bids_work() { assert_eq!( slots::Leases::::get(ParaId::from(2000)), // -- 1 --- 2 --- 3 ---------- 4 -------------- 5 -------------- 6 -------------- 7 ------- - vec![None, None, None, Some((10, 100)), Some((20, 800)), Some((20, 200)), Some((10, 400))], + vec![ + None, + None, + None, + Some((10, 100)), + Some((20, 800)), + Some((20, 200)), + Some((10, 400)) + ], ); // Appropriate amount is reserved (largest of the values) assert_eq!(Balances::reserved_balance(&10), 400); @@ -1125,17 +1179,17 @@ fn cant_bid_on_existing_lease_periods() { assert_ok!(Crowdloan::create( Origin::signed(1), ParaId::from(2000), - 1_000_000, // Cap + 1_000_000, // Cap lease_period_index_start + 0, // First Slot lease_period_index_start + 1, // Last Slot - 400, // Long block end + 400, // Long block end None, )); let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000)); // Bunch of contributions let mut total = 0; - for i in 10 .. 20 { + for i in 10..20 { Balances::make_free_balance_be(&i, 1_000_000_000); assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None)); total += 900 - i; @@ -1150,7 +1204,13 @@ fn cant_bid_on_existing_lease_periods() { assert_eq!( slots::Leases::::get(ParaId::from(2000)), // -- 1 --- 2 --- 3 ------------- 4 ------------------------ 5 ------------- - vec![None, None, None, Some((crowdloan_account, 8855)), Some((crowdloan_account, 8855))], + vec![ + None, + None, + None, + Some((crowdloan_account, 8855)), + Some((crowdloan_account, 8855)) + ], ); // Let's start another auction for the same range @@ -1175,7 +1235,8 @@ fn cant_bid_on_existing_lease_periods() { lease_period_index_start + 0, lease_period_index_start + 1, 100, - ), AuctionsError::::AlreadyLeasedOut, + ), + AuctionsError::::AlreadyLeasedOut, ); assert_noop!( @@ -1186,7 +1247,8 @@ fn cant_bid_on_existing_lease_periods() { lease_period_index_start + 1, lease_period_index_start + 2, 100, - ), AuctionsError::::AlreadyLeasedOut, + ), + AuctionsError::::AlreadyLeasedOut, ); assert_noop!( @@ -1197,7 +1259,8 @@ fn cant_bid_on_existing_lease_periods() { lease_period_index_start - 1, lease_period_index_start + 0, 100, - ), AuctionsError::::AlreadyLeasedOut, + ), + AuctionsError::::AlreadyLeasedOut, ); assert_noop!( @@ -1208,7 +1271,8 @@ fn cant_bid_on_existing_lease_periods() { lease_period_index_start + 0, lease_period_index_start + 0, 100, - ), AuctionsError::::AlreadyLeasedOut, + ), + AuctionsError::::AlreadyLeasedOut, ); assert_noop!( @@ -1219,7 +1283,8 @@ fn cant_bid_on_existing_lease_periods() { lease_period_index_start + 1, lease_period_index_start + 1, 100, - ), AuctionsError::::AlreadyLeasedOut, + ), + AuctionsError::::AlreadyLeasedOut, ); assert_noop!( @@ -1230,19 +1295,18 @@ fn cant_bid_on_existing_lease_periods() { lease_period_index_start - 1, lease_period_index_start + 5, 100, - ), AuctionsError::::AlreadyLeasedOut, + ), + AuctionsError::::AlreadyLeasedOut, ); // Will work when not overlapping - assert_ok!( - Auctions::bid( - Origin::signed(crowdloan_account), - ParaId::from(2000), - 2, - lease_period_index_start + 2, - lease_period_index_start + 3, - 100, - ) - ); + assert_ok!(Auctions::bid( + Origin::signed(crowdloan_account), + ParaId::from(2000), + 2, + lease_period_index_start + 2, + lease_period_index_start + 3, + 100, + )); }); } diff --git a/polkadot/runtime/common/src/lib.rs b/polkadot/runtime/common/src/lib.rs index 06047593c22..a2ce71c558e 100644 --- a/polkadot/runtime/common/src/lib.rs +++ b/polkadot/runtime/common/src/lib.rs @@ -18,47 +18,52 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub mod claims; -pub mod slots; pub mod auctions; +pub mod claims; pub mod crowdloan; -pub mod purchase; +pub mod elections; pub mod impls; -pub mod paras_sudo_wrapper; pub mod paras_registrar; +pub mod paras_sudo_wrapper; +pub mod purchase; pub mod slot_range; +pub mod slots; pub mod traits; pub mod xcm_sender; -pub mod elections; -#[cfg(test)] -mod mock; #[cfg(test)] mod integration_tests; +#[cfg(test)] +mod mock; -use primitives::v1::{AssignmentId, BlockNumber, ValidatorId}; -use sp_runtime::{Perquintill, Perbill, FixedPointNumber}; -use frame_system::limits; +pub use frame_support::weights::constants::{ + BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, +}; use frame_support::{ - parameter_types, traits::{Currency, OneSessionHandler}, - weights::{Weight, constants::WEIGHT_PER_SECOND, DispatchClass}, + parameter_types, + traits::{Currency, OneSessionHandler}, + weights::{constants::WEIGHT_PER_SECOND, DispatchClass, Weight}, }; -use pallet_transaction_payment::{TargetedFeeAdjustment, Multiplier}; +use frame_system::limits; +use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; +use primitives::v1::{AssignmentId, BlockNumber, ValidatorId}; +use sp_runtime::{FixedPointNumber, Perbill, Perquintill}; use static_assertions::const_assert; -pub use frame_support::weights::constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; +pub use elections::{OffchainSolutionLengthLimit, OffchainSolutionWeightLimit}; +pub use pallet_balances::Call as BalancesCall; #[cfg(feature = "std")] pub use pallet_staking::StakerStatus; +pub use pallet_timestamp::Call as TimestampCall; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -pub use pallet_timestamp::Call as TimestampCall; -pub use pallet_balances::Call as BalancesCall; -pub use elections::{OffchainSolutionLengthLimit, OffchainSolutionWeightLimit}; /// Implementations of some helper traits passed into runtime modules as associated types. pub use impls::ToAuthor; -pub type NegativeImbalance = as Currency<::AccountId>>::NegativeImbalance; +pub type NegativeImbalance = as Currency< + ::AccountId, +>>::NegativeImbalance; /// We assume that an on-initialize consumes 1% of the weight on average, hence a single extrinsic /// will not be allowed to consume more than `AvailableBlockRatio - 1%`. @@ -110,12 +115,8 @@ parameter_types! { /// Parameterized slow adjusting fee updated based on /// https://w3f-research.readthedocs.io/en/latest/polkadot/Token%20Economics.html#-2.-slow-adjusting-mechanism -pub type SlowAdjustingFeeUpdate = TargetedFeeAdjustment< - R, - TargetBlockFullness, - AdjustmentVariable, - MinimumMultiplier ->; +pub type SlowAdjustingFeeUpdate = + TargetedFeeAdjustment; /// The type used for currency conversion. /// @@ -130,25 +131,26 @@ impl sp_runtime::BoundToRuntimeAppPublic for ParachainSessionKeyPlaceholder OneSessionHandler for ParachainSessionKeyPlaceholder +impl OneSessionHandler + for ParachainSessionKeyPlaceholder { type Key = ValidatorId; - fn on_genesis_session<'a, I: 'a>(_validators: I) where + fn on_genesis_session<'a, I: 'a>(_validators: I) + where I: Iterator, - T::AccountId: 'a + T::AccountId: 'a, { - } - fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I) where + fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I) + where I: Iterator, - T::AccountId: 'a + T::AccountId: 'a, { - } - fn on_disabled(_: usize) { } + fn on_disabled(_: usize) {} } /// A placeholder since there is currently no provided session key handler for parachain validator @@ -158,25 +160,26 @@ impl sp_runtime::BoundToRuntimeAppPublic for AssignmentSessionKeyPlaceholder< type Public = AssignmentId; } -impl OneSessionHandler for AssignmentSessionKeyPlaceholder +impl OneSessionHandler + for AssignmentSessionKeyPlaceholder { type Key = AssignmentId; - fn on_genesis_session<'a, I: 'a>(_validators: I) where + fn on_genesis_session<'a, I: 'a>(_validators: I) + where I: Iterator, - T::AccountId: 'a + T::AccountId: 'a, { - } - fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I) where + fn on_new_session<'a, I: 'a>(_changed: bool, _v: I, _q: I) + where I: Iterator, - T::AccountId: 'a + T::AccountId: 'a, { - } - fn on_disabled(_: usize) { } + fn on_disabled(_: usize) {} } #[cfg(test)] @@ -186,7 +189,7 @@ mod multiplier_tests { use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup, Convert, One}, + traits::{BlakeTwo256, Convert, IdentityLookup, One}, Perbill, }; @@ -238,9 +241,14 @@ mod multiplier_tests { type OnSetCode = (); } - fn run_with_system_weight(w: Weight, mut assertions: F) where F: FnMut() -> () { - let mut t: sp_io::TestExternalities = - frame_system::GenesisConfig::default().build_storage::().unwrap().into(); + fn run_with_system_weight(w: Weight, mut assertions: F) + where + F: FnMut() -> (), + { + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap() + .into(); t.execute_with(|| { System::set_block_consumed_resources(w, 0); assertions() @@ -266,9 +274,9 @@ mod multiplier_tests { // assume the multiplier is initially set to its minimum. We update it with values twice the //target (target is 25%, thus 50%) and we see at which point it reaches 1. let mut multiplier = MinimumMultiplier::get(); - let block_weight = TargetBlockFullness::get() - * BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap() - * 2; + let block_weight = TargetBlockFullness::get() * + BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap() * + 2; let mut blocks = 0; while multiplier <= Multiplier::one() { run_with_system_weight(block_weight, || { diff --git a/polkadot/runtime/common/src/mock.rs b/polkadot/runtime/common/src/mock.rs index 5e62681bd72..523f0c76668 100644 --- a/polkadot/runtime/common/src/mock.rs +++ b/polkadot/runtime/common/src/mock.rs @@ -16,12 +16,12 @@ //! Mocking utilities for testing. -use std::{cell::RefCell, collections::HashMap}; -use parity_scale_codec::{Encode, Decode}; -use sp_runtime::traits::SaturatedConversion; -use frame_support::dispatch::{DispatchError, DispatchResult}; -use primitives::v1::{HeadData, ValidationCode, Id as ParaId}; use crate::traits::Registrar; +use frame_support::dispatch::{DispatchError, DispatchResult}; +use parity_scale_codec::{Decode, Encode}; +use primitives::v1::{HeadData, Id as ParaId, ValidationCode}; +use sp_runtime::traits::SaturatedConversion; +use std::{cell::RefCell, collections::HashMap}; thread_local! { static OPERATIONS: RefCell> = RefCell::new(Vec::new()); @@ -130,9 +130,13 @@ impl Registrar for TestRegistrar { }, } })?; - OPERATIONS.with(|x| x.borrow_mut().push( - (id, frame_system::Pallet::::block_number().saturated_into(), true) - )); + OPERATIONS.with(|x| { + x.borrow_mut().push(( + id, + frame_system::Pallet::::block_number().saturated_into(), + true, + )) + }); Ok(()) } fn make_parathread(id: ParaId) -> DispatchResult { @@ -149,16 +153,21 @@ impl Registrar for TestRegistrar { PARATHREADS.with(|x| { let mut parathreads = x.borrow_mut(); match parathreads.binary_search(&id) { - Ok(_) => Err(DispatchError::Other("already parathread, so cannot `make_parathread`")), + Ok(_) => + Err(DispatchError::Other("already parathread, so cannot `make_parathread`")), Err(i) => { parathreads.insert(i, id); Ok(()) }, } })?; - OPERATIONS.with(|x| x.borrow_mut().push( - (id, frame_system::Pallet::::block_number().saturated_into(), false) - )); + OPERATIONS.with(|x| { + x.borrow_mut().push(( + id, + frame_system::Pallet::::block_number().saturated_into(), + false, + )) + }); Ok(()) } @@ -179,7 +188,8 @@ impl Registrar for TestRegistrar { impl TestRegistrar { pub fn operations() -> Vec<(ParaId, T::BlockNumber, bool)> { - OPERATIONS.with(|x| x.borrow().iter().map(|(p, b, c)| (*p, (*b).into(), *c)).collect::>()) + OPERATIONS + .with(|x| x.borrow().iter().map(|(p, b, c)| (*p, (*b).into(), *c)).collect::>()) } #[allow(dead_code)] diff --git a/polkadot/runtime/common/src/paras_registrar.rs b/polkadot/runtime/common/src/paras_registrar.rs index 02cb2a0fe8a..6a922818fe6 100644 --- a/polkadot/runtime/common/src/paras_registrar.rs +++ b/polkadot/runtime/common/src/paras_registrar.rs @@ -17,31 +17,28 @@ //! Pallet to handle parathread/parachain registration and related fund management. //! In essence this is a simple wrapper around `paras`. -use sp_std::{prelude::*, result}; use frame_support::{ - ensure, dispatch::DispatchResult, - traits::{Get, Currency, ReservableCurrency}, + ensure, pallet_prelude::Weight, + traits::{Currency, Get, ReservableCurrency}, }; use frame_system::{self, ensure_root, ensure_signed}; -use primitives::v1::{ - Id as ParaId, ValidationCode, HeadData, LOWEST_PUBLIC_ID, -}; +use primitives::v1::{HeadData, Id as ParaId, ValidationCode, LOWEST_PUBLIC_ID}; use runtime_parachains::{ - paras::{ - self, - ParaGenesisArgs, - }, - configuration, - ensure_parachain, + configuration, ensure_parachain, + paras::{self, ParaGenesisArgs}, Origin, ParaLifecycle, }; +use sp_std::{prelude::*, result}; -use crate::traits::{Registrar, OnSwap}; -use parity_scale_codec::{Encode, Decode}; -use sp_runtime::{RuntimeDebug, traits::{Saturating, CheckedSub}}; +use crate::traits::{OnSwap, Registrar}; pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; +use sp_runtime::{ + traits::{CheckedSub, Saturating}, + RuntimeDebug, +}; #[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug)] pub struct ParaInfo { @@ -66,18 +63,28 @@ pub trait WeightInfo { pub struct TestWeightInfo; impl WeightInfo for TestWeightInfo { - fn reserve() -> Weight { 0 } - fn register() -> Weight { 0 } - fn force_register() -> Weight { 0 } - fn deregister() -> Weight { 0 } - fn swap() -> Weight { 0 } + fn reserve() -> Weight { + 0 + } + fn register() -> Weight { + 0 + } + fn force_register() -> Weight { + 0 + } + fn deregister() -> Weight { + 0 + } + fn swap() -> Weight { + 0 + } } #[frame_support::pallet] pub mod pallet { + use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use super::*; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -161,7 +168,8 @@ pub mod pallet { /// The given account ID is responsible for registering the code and initial head data, but may only do /// so if it isn't yet registered. (After that, it's up to governance to do so.) #[pallet::storage] - pub type Paras = StorageMap<_, Twox64Concat, ParaId, ParaInfo>>; + pub type Paras = + StorageMap<_, Twox64Concat, ParaId, ParaInfo>>; /// The next free `ParaId`. #[pallet::storage] @@ -363,8 +371,12 @@ impl Registrar for Pallet { // Upgrade a registered parathread into a parachain. fn make_parachain(id: ParaId) -> DispatchResult { // Para backend should think this is a parathread... - ensure!(paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parathread), Error::::NotParathread); - runtime_parachains::schedule_parathread_upgrade::(id).map_err(|_| Error::::CannotUpgrade)?; + ensure!( + paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parathread), + Error::::NotParathread + ); + runtime_parachains::schedule_parathread_upgrade::(id) + .map_err(|_| Error::::CannotUpgrade)?; // Once a para has upgraded to a parachain, it can no longer be managed by the owner. // Intentionally, the flag stays with the para even after downgrade. Self::apply_lock(id); @@ -374,8 +386,12 @@ impl Registrar for Pallet { // Downgrade a registered para into a parathread. fn make_parathread(id: ParaId) -> DispatchResult { // Para backend should think this is a parachain... - ensure!(paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parachain), Error::::NotParachain); - runtime_parachains::schedule_parachain_downgrade::(id).map_err(|_| Error::::CannotDowngrade)?; + ensure!( + paras::Pallet::::lifecycle(id) == Some(ParaLifecycle::Parachain), + Error::::NotParachain + ); + runtime_parachains::schedule_parachain_downgrade::(id) + .map_err(|_| Error::::CannotDowngrade)?; Ok(()) } @@ -397,9 +413,7 @@ impl Registrar for Pallet { #[cfg(any(feature = "runtime-benchmarks", test))] fn execute_pending_transitions() { use runtime_parachains::shared; - shared::Pallet::::set_session_index( - shared::Pallet::::scheduled_session() - ); + shared::Pallet::::set_session_index(shared::Pallet::::scheduled_session()); paras::Pallet::::test_on_new_session(); } } @@ -407,23 +421,28 @@ impl Registrar for Pallet { impl Pallet { /// Ensure the origin is one of Root, the `para` owner, or the `para` itself. /// If the origin is the `para` owner, the `para` must be unlocked. - fn ensure_root_para_or_owner(origin: ::Origin, id: ParaId) -> DispatchResult { - ensure_signed(origin.clone()).map_err(|e| e.into()) - .and_then(|who| -> DispatchResult { - let para_info = Paras::::get(id).ok_or(Error::::NotRegistered)?; - ensure!(!para_info.locked, Error::::ParaLocked); - ensure!(para_info.manager == who, Error::::NotOwner); - Ok(()) - }) - .or_else(|_| -> DispatchResult { - // Else check if para origin... - let caller_id = ensure_parachain(::Origin::from(origin.clone()))?; - ensure!(caller_id == id, Error::::NotOwner); - Ok(()) - }).or_else(|_| -> DispatchResult { - // Check if root... - ensure_root(origin.clone()).map_err(|e| e.into()) - }) + fn ensure_root_para_or_owner( + origin: ::Origin, + id: ParaId, + ) -> DispatchResult { + ensure_signed(origin.clone()) + .map_err(|e| e.into()) + .and_then(|who| -> DispatchResult { + let para_info = Paras::::get(id).ok_or(Error::::NotRegistered)?; + ensure!(!para_info.locked, Error::::ParaLocked); + ensure!(para_info.manager == who, Error::::NotOwner); + Ok(()) + }) + .or_else(|_| -> DispatchResult { + // Else check if para origin... + let caller_id = ensure_parachain(::Origin::from(origin.clone()))?; + ensure!(caller_id == id, Error::::NotOwner); + Ok(()) + }) + .or_else(|_| -> DispatchResult { + // Check if root... + ensure_root(origin.clone()).map_err(|e| e.into()) + }) } fn do_reserve( @@ -436,11 +455,7 @@ impl Pallet { let deposit = deposit_override.unwrap_or_else(T::ParaDeposit::get); ::Currency::reserve(&who, deposit)?; - let info = ParaInfo { - manager: who.clone(), - deposit, - locked: false, - }; + let info = ParaInfo { manager: who.clone(), deposit, locked: false }; Paras::::insert(id, info); Self::deposit_event(Event::::Reserved(id, who)); @@ -466,11 +481,8 @@ impl Pallet { Default::default() }; ensure!(paras::Pallet::::lifecycle(id).is_none(), Error::::AlreadyRegistered); - let (genesis, deposit) = Self::validate_onboarding_data( - genesis_head, - validation_code, - false - )?; + let (genesis, deposit) = + Self::validate_onboarding_data(genesis_head, validation_code, false)?; let deposit = deposit_override.unwrap_or(deposit); if let Some(additional) = deposit.checked_sub(&deposited) { @@ -478,11 +490,7 @@ impl Pallet { } else if let Some(rebate) = deposited.checked_sub(&deposit) { ::Currency::unreserve(&who, rebate); }; - let info = ParaInfo { - manager: who.clone(), - deposit, - locked: false, - }; + let info = ParaInfo { manager: who.clone(), deposit, locked: false }; Paras::::insert(id, info); // We check above that para has no lifecycle, so this should not fail. @@ -497,9 +505,10 @@ impl Pallet { match paras::Pallet::::lifecycle(id) { // Para must be a parathread, or not exist at all. Some(ParaLifecycle::Parathread) | None => {}, - _ => return Err(Error::::NotParathread.into()) + _ => return Err(Error::::NotParathread.into()), } - runtime_parachains::schedule_para_cleanup::(id).map_err(|_| Error::::CannotDeregister)?; + runtime_parachains::schedule_para_cleanup::(id) + .map_err(|_| Error::::CannotDeregister)?; if let Some(info) = Paras::::take(&id) { ::Currency::unreserve(&info.manager, info.deposit); @@ -520,45 +529,40 @@ impl Pallet { ) -> Result<(ParaGenesisArgs, BalanceOf), sp_runtime::DispatchError> { let config = configuration::Pallet::::config(); ensure!(validation_code.0.len() <= config.max_code_size as usize, Error::::CodeTooLarge); - ensure!(genesis_head.0.len() <= config.max_head_data_size as usize, Error::::HeadDataTooLarge); + ensure!( + genesis_head.0.len() <= config.max_head_data_size as usize, + Error::::HeadDataTooLarge + ); let per_byte_fee = T::DataDepositPerByte::get(); let deposit = T::ParaDeposit::get() - .saturating_add( - per_byte_fee.saturating_mul((genesis_head.0.len() as u32).into()) - ).saturating_add( - per_byte_fee.saturating_mul((validation_code.0.len() as u32).into()) - ); + .saturating_add(per_byte_fee.saturating_mul((genesis_head.0.len() as u32).into())) + .saturating_add(per_byte_fee.saturating_mul((validation_code.0.len() as u32).into())); - Ok((ParaGenesisArgs { - genesis_head, - validation_code, - parachain, - }, deposit)) + Ok((ParaGenesisArgs { genesis_head, validation_code, parachain }, deposit)) } } #[cfg(test)] mod tests { use super::*; - use sp_io::TestExternalities; - use sp_core::H256; - use sp_runtime::{ - traits::{ - BlakeTwo256, IdentityLookup, - }, Perbill, - }; - use primitives::v1::{Balance, BlockNumber, Header}; - use frame_system::limits; + use crate::{paras_registrar, traits::Registrar as RegistrarTrait}; use frame_support::{ - traits::{OnInitialize, OnFinalize, GenesisBuild}, - assert_ok, assert_noop, parameter_types, + assert_noop, assert_ok, error::BadOrigin, + parameter_types, + traits::{GenesisBuild, OnFinalize, OnInitialize}, }; - use runtime_parachains::{configuration, shared}; + use frame_system::limits; use pallet_balances::Error as BalancesError; - use crate::traits::Registrar as RegistrarTrait; - use crate::paras_registrar; + use primitives::v1::{Balance, BlockNumber, Header}; + use runtime_parachains::{configuration, shared}; + use sp_core::H256; + use sp_io::TestExternalities; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + Perbill, + }; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -636,7 +640,7 @@ mod tests { type Event = Event; } - impl configuration::Config for Test { } + impl configuration::Config for Test {} parameter_types! { pub const ParaDeposit: Balance = 10; @@ -661,17 +665,18 @@ mod tests { GenesisBuild::::assimilate_storage( &configuration::GenesisConfig { config: configuration::HostConfiguration { - max_code_size: 2 * 1024 * 1024, // 2 MB + max_code_size: 2 * 1024 * 1024, // 2 MB max_head_data_size: 1 * 1024 * 1024, // 1 MB ..Default::default() - } + }, }, - &mut t - ).unwrap(); + &mut t, + ) + .unwrap(); - pallet_balances::GenesisConfig:: { - balances: vec![(1, 10_000_000), (2, 10_000_000)], - }.assimilate_storage(&mut t).unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 10_000_000), (2, 10_000_000)] } + .assimilate_storage(&mut t) + .unwrap(); t.into() } @@ -691,7 +696,7 @@ mod tests { // Session change every 3 blocks. if (b + 1) % BLOCKS_PER_SESSION == 0 { shared::Pallet::::set_session_index( - shared::Pallet::::session_index() + 1 + shared::Pallet::::session_index() + 1, ); Parachains::test_on_new_session(); } @@ -765,10 +770,7 @@ mod tests { assert!(Parachains::is_parathread(para_id)); assert!(!Parachains::is_parachain(para_id)); // Deregister it - assert_ok!(Registrar::deregister( - Origin::root(), - para_id, - )); + assert_ok!(Registrar::deregister(Origin::root(), para_id,)); run_to_session(8); // It is nothing assert!(!Parachains::is_parathread(para_id)); @@ -794,7 +796,8 @@ mod tests { assert!(Parachains::is_parathread(para_id)); assert_eq!( Balances::reserved_balance(&1), - ::ParaDeposit::get() + 64 * ::DataDepositPerByte::get() + ::ParaDeposit::get() + + 64 * ::DataDepositPerByte::get() ); }); } @@ -804,22 +807,28 @@ mod tests { new_test_ext().execute_with(|| { let para_id = LOWEST_PUBLIC_ID; - assert_noop!(Registrar::register( - Origin::signed(1), - para_id, - test_genesis_head(max_head_size() as usize), - test_validation_code(max_code_size() as usize), - ), Error::::NotReserved); + assert_noop!( + Registrar::register( + Origin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotReserved + ); // Successfully register para assert_ok!(Registrar::reserve(Origin::signed(1))); - assert_noop!(Registrar::register( - Origin::signed(2), - para_id, - test_genesis_head(max_head_size() as usize), - test_validation_code(max_code_size() as usize), - ), Error::::NotOwner); + assert_noop!( + Registrar::register( + Origin::signed(2), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotOwner + ); assert_ok!(Registrar::register( Origin::signed(1), @@ -833,32 +842,44 @@ mod tests { assert_ok!(Registrar::deregister(Origin::root(), para_id)); // Can't do it again - assert_noop!(Registrar::register( - Origin::signed(1), - para_id, - test_genesis_head(max_head_size() as usize), - test_validation_code(max_code_size() as usize), - ), Error::::NotReserved); + assert_noop!( + Registrar::register( + Origin::signed(1), + para_id, + test_genesis_head(max_head_size() as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::NotReserved + ); // Head Size Check assert_ok!(Registrar::reserve(Origin::signed(2))); - assert_noop!(Registrar::register( - Origin::signed(2), - para_id + 1, - test_genesis_head((max_head_size() + 1) as usize), - test_validation_code(max_code_size() as usize), - ), Error::::HeadDataTooLarge); + assert_noop!( + Registrar::register( + Origin::signed(2), + para_id + 1, + test_genesis_head((max_head_size() + 1) as usize), + test_validation_code(max_code_size() as usize), + ), + Error::::HeadDataTooLarge + ); // Code Size Check - assert_noop!(Registrar::register( - Origin::signed(2), - para_id + 1, - test_genesis_head(max_head_size() as usize), - test_validation_code((max_code_size() + 1) as usize), - ), Error::::CodeTooLarge); + assert_noop!( + Registrar::register( + Origin::signed(2), + para_id + 1, + test_genesis_head(max_head_size() as usize), + test_validation_code((max_code_size() + 1) as usize), + ), + Error::::CodeTooLarge + ); // Needs enough funds for deposit - assert_noop!(Registrar::reserve(Origin::signed(1337)), BalancesError::::InsufficientBalance); + assert_noop!( + Registrar::reserve(Origin::signed(1337)), + BalancesError::::InsufficientBalance + ); }); } @@ -877,10 +898,7 @@ mod tests { )); run_to_session(2); assert!(Parachains::is_parathread(para_id)); - assert_ok!(Registrar::deregister( - Origin::root(), - para_id, - )); + assert_ok!(Registrar::deregister(Origin::root(), para_id,)); run_to_session(4); assert!(paras::Pallet::::lifecycle(para_id).is_none()); assert_eq!(Balances::reserved_balance(&1), 0); @@ -903,17 +921,14 @@ mod tests { run_to_session(2); assert!(Parachains::is_parathread(para_id)); // Owner check - assert_noop!(Registrar::deregister( - Origin::signed(2), - para_id, - ), BadOrigin); + assert_noop!(Registrar::deregister(Origin::signed(2), para_id,), BadOrigin); assert_ok!(Registrar::make_parachain(para_id)); run_to_session(4); // Cant directly deregister parachain - assert_noop!(Registrar::deregister( - Origin::root(), - para_id, - ), Error::::NotParathread); + assert_noop!( + Registrar::deregister(Origin::root(), para_id,), + Error::::NotParathread + ); }); } @@ -951,22 +966,17 @@ mod tests { assert!(Parachains::is_parathread(para_2)); // Both paras initiate a swap - assert_ok!(Registrar::swap( - para_origin(para_1), - para_1, - para_2, - )); - assert_ok!(Registrar::swap( - para_origin(para_2), - para_2, - para_1, - )); + assert_ok!(Registrar::swap(para_origin(para_1), para_1, para_2,)); + assert_ok!(Registrar::swap(para_origin(para_2), para_2, para_1,)); run_to_session(6); // Deregister a parathread that was originally a parachain assert_eq!(Parachains::lifecycle(para_1), Some(ParaLifecycle::Parathread)); - assert_ok!(Registrar::deregister(runtime_parachains::Origin::Parachain(para_1).into(), para_1)); + assert_ok!(Registrar::deregister( + runtime_parachains::Origin::Parachain(para_1).into(), + para_1 + )); run_to_block(21); @@ -1010,14 +1020,14 @@ mod tests { #[cfg(feature = "runtime-benchmarks")] mod benchmarking { - use super::{*, Pallet as Registrar}; - use frame_system::RawOrigin; + use super::{Pallet as Registrar, *}; + use crate::traits::Registrar as RegistrarT; use frame_support::assert_ok; - use sp_runtime::traits::Bounded; - use crate::traits::{Registrar as RegistrarT}; + use frame_system::RawOrigin; use runtime_parachains::{paras, shared, Origin as ParaOrigin}; + use sp_runtime::traits::Bounded; - use frame_benchmarking::{account, benchmarks, whitelisted_caller, impl_benchmark_test_suite}; + use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; fn assert_last_event(generic_event: ::Event) { let events = frame_system::Pallet::::events(); @@ -1034,8 +1044,13 @@ mod benchmarking { let caller: T::AccountId = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); assert_ok!(Registrar::::reserve(RawOrigin::Signed(caller.clone()).into())); - assert_ok!(Registrar::::register(RawOrigin::Signed(caller).into(), para, genesis_head, validation_code)); - return para; + assert_ok!(Registrar::::register( + RawOrigin::Signed(caller).into(), + para, + genesis_head, + validation_code + )); + return para } fn para_origin(id: u32) -> ParaOrigin { @@ -1044,9 +1059,7 @@ mod benchmarking { // This function moves forward to the next scheduled session for parachain lifecycle upgrades. fn next_scheduled_session() { - shared::Pallet::::set_session_index( - shared::Pallet::::scheduled_session() - ); + shared::Pallet::::set_session_index(shared::Pallet::::scheduled_session()); paras::Pallet::::test_on_new_session(); } diff --git a/polkadot/runtime/common/src/paras_sudo_wrapper.rs b/polkadot/runtime/common/src/paras_sudo_wrapper.rs index 8bef0afb2a8..cb9f7220e7c 100644 --- a/polkadot/runtime/common/src/paras_sudo_wrapper.rs +++ b/polkadot/runtime/common/src/paras_sudo_wrapper.rs @@ -18,14 +18,14 @@ use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; +pub use pallet::*; +use parity_scale_codec::Encode; +use primitives::v1::Id as ParaId; use runtime_parachains::{ - configuration, dmp, ump, hrmp, - ParaLifecycle, + configuration, dmp, hrmp, paras::{self, ParaGenesisArgs}, + ump, ParaLifecycle, }; -use primitives::v1::Id as ParaId; -use parity_scale_codec::Encode; -pub use pallet::*; #[frame_support::pallet] pub mod pallet { @@ -38,8 +38,9 @@ pub mod pallet { #[pallet::config] #[pallet::disable_frame_system_supertrait_check] pub trait Config: - configuration::Config + paras::Config + dmp::Config + ump::Config + hrmp::Config {} - + configuration::Config + paras::Config + dmp::Config + ump::Config + hrmp::Config + { + } #[pallet::error] pub enum Error { @@ -84,13 +85,17 @@ pub mod pallet { #[pallet::weight((1_000, DispatchClass::Operational))] pub fn sudo_schedule_para_cleanup(origin: OriginFor, id: ParaId) -> DispatchResult { ensure_root(origin)?; - runtime_parachains::schedule_para_cleanup::(id).map_err(|_| Error::::CouldntCleanup)?; + runtime_parachains::schedule_para_cleanup::(id) + .map_err(|_| Error::::CouldntCleanup)?; Ok(()) } /// Upgrade a parathread to a parachain #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn sudo_schedule_parathread_upgrade(origin: OriginFor, id: ParaId) -> DispatchResult { + pub fn sudo_schedule_parathread_upgrade( + origin: OriginFor, + id: ParaId, + ) -> DispatchResult { ensure_root(origin)?; // Para backend should think this is a parathread... ensure!( @@ -104,7 +109,10 @@ pub mod pallet { /// Downgrade a parachain to a parathread #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn sudo_schedule_parachain_downgrade(origin: OriginFor, id: ParaId) -> DispatchResult { + pub fn sudo_schedule_parachain_downgrade( + origin: OriginFor, + id: ParaId, + ) -> DispatchResult { ensure_root(origin)?; // Para backend should think this is a parachain... ensure!( @@ -129,11 +137,11 @@ pub mod pallet { ensure_root(origin)?; ensure!(>::is_valid_para(id), Error::::ParaDoesntExist); let config = >::config(); - >::queue_downward_message(&config, id, xcm.encode()) - .map_err(|e| match e { - dmp::QueueDownwardMessageError::ExceedsMaxMessageSize => - Error::::ExceedsMaxMessageSize.into(), - }) + >::queue_downward_message(&config, id, xcm.encode()).map_err(|e| match e + { + dmp::QueueDownwardMessageError::ExceedsMaxMessageSize => + Error::::ExceedsMaxMessageSize.into(), + }) } /// Forcefully establish a channel from the sender to the recipient. diff --git a/polkadot/runtime/common/src/purchase.rs b/polkadot/runtime/common/src/purchase.rs index fb50622b20f..0b4a1303b13 100644 --- a/polkadot/runtime/common/src/purchase.rs +++ b/polkadot/runtime/common/src/purchase.rs @@ -16,19 +16,22 @@ //! Pallet to process purchase of DOTs. -use parity_scale_codec::{Encode, Decode}; -use sp_runtime::{Permill, RuntimeDebug, DispatchResult, DispatchError, AnySignature}; -use sp_runtime::traits::{Zero, CheckedAdd, Verify, Saturating}; -use frame_support::pallet_prelude::*; -use frame_support::traits::{ - EnsureOrigin, Currency, ExistenceRequirement, VestingSchedule, Get +use frame_support::{ + pallet_prelude::*, + traits::{Currency, EnsureOrigin, ExistenceRequirement, Get, VestingSchedule}, }; use frame_system::pallet_prelude::*; +pub use pallet::*; +use parity_scale_codec::{Decode, Encode}; use sp_core::sr25519; +use sp_runtime::{ + traits::{CheckedAdd, Saturating, Verify, Zero}, + AnySignature, DispatchError, DispatchResult, Permill, RuntimeDebug, +}; use sp_std::prelude::*; -pub use pallet::*; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; /// The kind of a statement an account needs to make for a claim to be valid. #[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, RuntimeDebug)] @@ -99,7 +102,11 @@ pub mod pallet { type Currency: Currency; /// Vesting Pallet - type VestingSchedule: VestingSchedule; + type VestingSchedule: VestingSchedule< + Self::AccountId, + Moment = Self::BlockNumber, + Currency = Self::Currency, + >; /// The origin allowed to set account status. type ValidityOrigin: EnsureOrigin; @@ -166,12 +173,8 @@ pub mod pallet { // A map of all participants in the DOT purchase process. #[pallet::storage] - pub(super) type Accounts = StorageMap< - _, - Blake2_128Concat, T::AccountId, - AccountStatus>, - ValueQuery, - >; + pub(super) type Accounts = + StorageMap<_, Blake2_128Concat, T::AccountId, AccountStatus>, ValueQuery>; // The account that will be used to payout participants of the DOT purchase process. #[pallet::storage] @@ -199,13 +202,16 @@ pub mod pallet { pub fn create_account( origin: OriginFor, who: T::AccountId, - signature: Vec + signature: Vec, ) -> DispatchResult { T::ValidityOrigin::ensure_origin(origin)?; // Account is already being tracked by the pallet. ensure!(!Accounts::::contains_key(&who), Error::::ExistingAccount); // Account should not have a vesting schedule. - ensure!(T::VestingSchedule::vesting_balance(&who).is_none(), Error::::VestingScheduleExists); + ensure!( + T::VestingSchedule::vesting_balance(&who).is_none(), + Error::::VestingScheduleExists + ); // Verify the signature provided is valid for the statement. Self::verify_signature(&who, &signature)?; @@ -233,15 +239,21 @@ pub mod pallet { pub fn update_validity_status( origin: OriginFor, who: T::AccountId, - validity: AccountValidity + validity: AccountValidity, ) -> DispatchResult { T::ValidityOrigin::ensure_origin(origin)?; ensure!(Accounts::::contains_key(&who), Error::::InvalidAccount); - Accounts::::try_mutate(&who, |status: &mut AccountStatus>| -> DispatchResult { - ensure!(status.validity != AccountValidity::Completed, Error::::AlreadyCompleted); - status.validity = validity; - Ok(()) - })?; + Accounts::::try_mutate( + &who, + |status: &mut AccountStatus>| -> DispatchResult { + ensure!( + status.validity != AccountValidity::Completed, + Error::::AlreadyCompleted + ); + status.validity = validity; + Ok(()) + }, + )?; Self::deposit_event(Event::::ValidityUpdated(who, validity)); Ok(()) } @@ -261,16 +273,19 @@ pub mod pallet { ) -> DispatchResult { T::ValidityOrigin::ensure_origin(origin)?; - Accounts::::try_mutate(&who, |status: &mut AccountStatus>| -> DispatchResult { - // Account has a valid status (not Invalid, Pending, or Completed)... - ensure!(status.validity.is_valid(), Error::::InvalidAccount); - - free_balance.checked_add(&locked_balance).ok_or(Error::::Overflow)?; - status.free_balance = free_balance; - status.locked_balance = locked_balance; - status.vat = vat; - Ok(()) - })?; + Accounts::::try_mutate( + &who, + |status: &mut AccountStatus>| -> DispatchResult { + // Account has a valid status (not Invalid, Pending, or Completed)... + ensure!(status.validity.is_valid(), Error::::InvalidAccount); + + free_balance.checked_add(&locked_balance).ok_or(Error::::Overflow)?; + status.free_balance = free_balance; + status.locked_balance = locked_balance; + status.vat = vat; + Ok(()) + }, + )?; Self::deposit_event(Event::::BalanceUpdated(who, free_balance, locked_balance)); Ok(()) } @@ -287,44 +302,59 @@ pub mod pallet { ensure!(payment_account == PaymentAccount::::get(), DispatchError::BadOrigin); // Account should not have a vesting schedule. - ensure!(T::VestingSchedule::vesting_balance(&who).is_none(), Error::::VestingScheduleExists); - - Accounts::::try_mutate(&who, |status: &mut AccountStatus>| -> DispatchResult { - // Account has a valid status (not Invalid, Pending, or Completed)... - ensure!(status.validity.is_valid(), Error::::InvalidAccount); - - // Transfer funds from the payment account into the purchasing user. - let total_balance = status.free_balance - .checked_add(&status.locked_balance) - .ok_or(Error::::Overflow)?; - T::Currency::transfer(&payment_account, &who, total_balance, ExistenceRequirement::AllowDeath)?; - - if !status.locked_balance.is_zero() { - let unlock_block = UnlockBlock::::get(); - // We allow some configurable portion of the purchased locked DOTs to be unlocked for basic usage. - let unlocked = (T::UnlockedProportion::get() * status.locked_balance).min(T::MaxUnlocked::get()); - let locked = status.locked_balance.saturating_sub(unlocked); - // We checked that this account has no existing vesting schedule. So this function should - // never fail, however if it does, not much we can do about it at this point. - let _ = T::VestingSchedule::add_vesting_schedule( - // Apply vesting schedule to this user - &who, - // For this much amount - locked, - // Unlocking the full amount after one block - locked, - // When everything unlocks - unlock_block - ); - } + ensure!( + T::VestingSchedule::vesting_balance(&who).is_none(), + Error::::VestingScheduleExists + ); - // Setting the user account to `Completed` ends the purchase process for this user. - status.validity = AccountValidity::Completed; - Self::deposit_event( - Event::::PaymentComplete(who.clone(), status.free_balance, status.locked_balance) - ); - Ok(()) - })?; + Accounts::::try_mutate( + &who, + |status: &mut AccountStatus>| -> DispatchResult { + // Account has a valid status (not Invalid, Pending, or Completed)... + ensure!(status.validity.is_valid(), Error::::InvalidAccount); + + // Transfer funds from the payment account into the purchasing user. + let total_balance = status + .free_balance + .checked_add(&status.locked_balance) + .ok_or(Error::::Overflow)?; + T::Currency::transfer( + &payment_account, + &who, + total_balance, + ExistenceRequirement::AllowDeath, + )?; + + if !status.locked_balance.is_zero() { + let unlock_block = UnlockBlock::::get(); + // We allow some configurable portion of the purchased locked DOTs to be unlocked for basic usage. + let unlocked = (T::UnlockedProportion::get() * status.locked_balance) + .min(T::MaxUnlocked::get()); + let locked = status.locked_balance.saturating_sub(unlocked); + // We checked that this account has no existing vesting schedule. So this function should + // never fail, however if it does, not much we can do about it at this point. + let _ = T::VestingSchedule::add_vesting_schedule( + // Apply vesting schedule to this user + &who, + // For this much amount + locked, + // Unlocking the full amount after one block + locked, + // When everything unlocks + unlock_block, + ); + } + + // Setting the user account to `Completed` ends the purchase process for this user. + status.validity = AccountValidity::Completed; + Self::deposit_event(Event::::PaymentComplete( + who.clone(), + status.free_balance, + status.locked_balance, + )); + Ok(()) + }, + )?; Ok(()) } @@ -348,7 +378,10 @@ pub mod pallet { #[pallet::weight(T::DbWeight::get().writes(1))] pub fn set_statement(origin: OriginFor, statement: Vec) -> DispatchResult { T::ConfigurationOrigin::ensure_origin(origin)?; - ensure!((statement.len() as u32) < T::MaxStatementLength::get(), Error::::InvalidStatement); + ensure!( + (statement.len() as u32) < T::MaxStatementLength::get(), + Error::::InvalidStatement + ); // Possibly this is worse than having the caller account be the payment account? Statement::::set(statement); Self::deposit_event(Event::::StatementUpdated); @@ -359,9 +392,15 @@ pub mod pallet { /// /// Origin must match the `ConfigurationOrigin` #[pallet::weight(T::DbWeight::get().writes(1))] - pub fn set_unlock_block(origin: OriginFor, unlock_block: T::BlockNumber) -> DispatchResult { + pub fn set_unlock_block( + origin: OriginFor, + unlock_block: T::BlockNumber, + ) -> DispatchResult { T::ConfigurationOrigin::ensure_origin(origin)?; - ensure!(unlock_block > frame_system::Pallet::::block_number(), Error::::InvalidUnlockBlock); + ensure!( + unlock_block > frame_system::Pallet::::block_number(), + Error::::InvalidUnlockBlock + ); // Possibly this is worse than having the caller account be the payment account? UnlockBlock::::set(unlock_block); Self::deposit_event(Event::::UnlockBlockUpdated(unlock_block)); @@ -392,7 +431,8 @@ impl Pallet { // This function converts a 32 byte AccountId to its byte-array equivalent form. fn account_to_bytes(account: &AccountId) -> Result<[u8; 32], DispatchError> - where AccountId: Encode, +where + AccountId: Encode, { let account_vec = account.encode(); ensure!(account_vec.len() == 32, "AccountId must be 32 bytes."); @@ -404,7 +444,8 @@ fn account_to_bytes(account: &AccountId) -> Result<[u8; 32], Dispatch /// WARNING: Executing this function will clear all storage used by this pallet. /// Be sure this is what you want... pub fn remove_pallet() -> frame_support::weights::Weight - where T: frame_system::Config +where + T: frame_system::Config, { use frame_support::migration::remove_storage_prefix; remove_storage_prefix(b"Purchase", b"Accounts", b""); @@ -419,21 +460,20 @@ pub fn remove_pallet() -> frame_support::weights::Weight mod tests { use super::*; - use sp_core::{H256, Pair, Public, crypto::AccountId32, ed25519}; + use sp_core::{crypto::AccountId32, ed25519, Pair, Public, H256}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use sp_runtime::{ - MultiSignature, - traits::{BlakeTwo256, IdentityLookup, Identity, Verify, IdentifyAccount, Dispatchable}, - testing::Header - }; + use crate::purchase; use frame_support::{ - assert_ok, assert_noop, parameter_types, - ord_parameter_types, dispatch::DispatchError::BadOrigin, + assert_noop, assert_ok, dispatch::DispatchError::BadOrigin, ord_parameter_types, + parameter_types, traits::Currency, }; - use frame_support::traits::Currency; use pallet_balances::Error as BalancesError; - use crate::purchase; + use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, Dispatchable, IdentifyAccount, Identity, IdentityLookup, Verify}, + MultiSignature, + }; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -547,7 +587,8 @@ mod tests { let unlock_block = 100; Purchase::set_statement(Origin::signed(configuration_origin()), statement).unwrap(); Purchase::set_unlock_block(Origin::signed(configuration_origin()), unlock_block).unwrap(); - Purchase::set_payment_account(Origin::signed(configuration_origin()), payment_account()).unwrap(); + Purchase::set_payment_account(Origin::signed(configuration_origin()), payment_account()) + .unwrap(); Balances::make_free_balance_be(&payment_account(), 100_000); } @@ -561,8 +602,9 @@ mod tests { } /// Helper function to generate an account ID from seed - fn get_account_id_from_seed(seed: &str) -> AccountId where - AccountPublic: From<::Public> + fn get_account_id_from_seed(seed: &str) -> AccountId + where + AccountPublic: From<::Public>, { AccountPublic::from(get_from_seed::(seed)).into_account() } @@ -622,7 +664,10 @@ mod tests { Error::::InvalidStatement, ); // Just right... - assert_ok!(Purchase::set_statement(Origin::signed(configuration_origin()), statement.clone())); + assert_ok!(Purchase::set_statement( + Origin::signed(configuration_origin()), + statement.clone() + )); assert_eq!(Statement::::get(), statement); }); } @@ -640,11 +685,17 @@ mod tests { let bad_unlock_block = 50; System::set_block_number(bad_unlock_block); assert_noop!( - Purchase::set_unlock_block(Origin::signed(configuration_origin()), bad_unlock_block), + Purchase::set_unlock_block( + Origin::signed(configuration_origin()), + bad_unlock_block + ), Error::::InvalidUnlockBlock, ); // Just right... - assert_ok!(Purchase::set_unlock_block(Origin::signed(configuration_origin()), unlock_block)); + assert_ok!(Purchase::set_unlock_block( + Origin::signed(configuration_origin()), + unlock_block + )); assert_eq!(UnlockBlock::::get(), unlock_block); }); } @@ -659,7 +710,10 @@ mod tests { BadOrigin, ); // Just right... - assert_ok!(Purchase::set_payment_account(Origin::signed(configuration_origin()), payment_account.clone())); + assert_ok!(Purchase::set_payment_account( + Origin::signed(configuration_origin()), + payment_account.clone() + )); assert_eq!(PaymentAccount::::get(), payment_account); }); } @@ -672,8 +726,14 @@ mod tests { assert_ok!(Purchase::verify_signature(&bob(), &bob_signature())); // Mixing and matching fails - assert_noop!(Purchase::verify_signature(&alice(), &bob_signature()), Error::::InvalidSignature); - assert_noop!(Purchase::verify_signature(&bob(), &alice_signature()), Error::::InvalidSignature); + assert_noop!( + Purchase::verify_signature(&alice(), &bob_signature()), + Error::::InvalidSignature + ); + assert_noop!( + Purchase::verify_signature(&bob(), &alice_signature()), + Error::::InvalidSignature + ); }); } @@ -704,13 +764,21 @@ mod tests { new_test_ext().execute_with(|| { // Wrong Origin assert_noop!( - Purchase::create_account(Origin::signed(alice()), alice(), alice_signature().to_vec()), + Purchase::create_account( + Origin::signed(alice()), + alice(), + alice_signature().to_vec() + ), BadOrigin, ); // Wrong Account/Signature assert_noop!( - Purchase::create_account(Origin::signed(validity_origin()), alice(), bob_signature().to_vec()), + Purchase::create_account( + Origin::signed(validity_origin()), + alice(), + bob_signature().to_vec() + ), Error::::InvalidSignature, ); @@ -722,16 +790,26 @@ mod tests { 50 )); assert_noop!( - Purchase::create_account(Origin::signed(validity_origin()), alice(), alice_signature().to_vec()), + Purchase::create_account( + Origin::signed(validity_origin()), + alice(), + alice_signature().to_vec() + ), Error::::VestingScheduleExists, ); // Duplicate Purchasing Account - assert_ok!( - Purchase::create_account(Origin::signed(validity_origin()), bob(), bob_signature().to_vec()) - ); + assert_ok!(Purchase::create_account( + Origin::signed(validity_origin()), + bob(), + bob_signature().to_vec() + )); assert_noop!( - Purchase::create_account(Origin::signed(validity_origin()), bob(), bob_signature().to_vec()), + Purchase::create_account( + Origin::signed(validity_origin()), + bob(), + bob_signature().to_vec() + ), Error::::ExistingAccount, ); }); @@ -791,17 +869,23 @@ mod tests { fn update_validity_status_handles_basic_errors() { new_test_ext().execute_with(|| { // Wrong Origin - assert_noop!(Purchase::update_validity_status( - Origin::signed(alice()), - alice(), - AccountValidity::Pending, - ), BadOrigin); + assert_noop!( + Purchase::update_validity_status( + Origin::signed(alice()), + alice(), + AccountValidity::Pending, + ), + BadOrigin + ); // Inactive Account - assert_noop!(Purchase::update_validity_status( - Origin::signed(validity_origin()), - alice(), - AccountValidity::Pending, - ), Error::::InvalidAccount); + assert_noop!( + Purchase::update_validity_status( + Origin::signed(validity_origin()), + alice(), + AccountValidity::Pending, + ), + Error::::InvalidAccount + ); // Already Completed assert_ok!(Purchase::create_account( Origin::signed(validity_origin()), @@ -813,11 +897,14 @@ mod tests { alice(), AccountValidity::Completed, )); - assert_noop!(Purchase::update_validity_status( - Origin::signed(validity_origin()), - alice(), - AccountValidity::Pending, - ), Error::::AlreadyCompleted); + assert_noop!( + Purchase::update_validity_status( + Origin::signed(validity_origin()), + alice(), + AccountValidity::Pending, + ), + Error::::AlreadyCompleted + ); }); } @@ -828,8 +915,8 @@ mod tests { assert_ok!(Purchase::create_account( Origin::signed(validity_origin()), alice(), - alice_signature().to_vec()) - ); + alice_signature().to_vec() + )); // And approved for basic contribution assert_ok!(Purchase::update_validity_status( Origin::signed(validity_origin()), @@ -879,29 +966,32 @@ mod tests { fn update_balance_handles_basic_errors() { new_test_ext().execute_with(|| { // Wrong Origin - assert_noop!(Purchase::update_balance( - Origin::signed(alice()), - alice(), - 50, - 50, - Permill::zero(), - ), BadOrigin); + assert_noop!( + Purchase::update_balance(Origin::signed(alice()), alice(), 50, 50, Permill::zero(),), + BadOrigin + ); // Inactive Account - assert_noop!(Purchase::update_balance( - Origin::signed(validity_origin()), - alice(), - 50, - 50, - Permill::zero(), - ), Error::::InvalidAccount); + assert_noop!( + Purchase::update_balance( + Origin::signed(validity_origin()), + alice(), + 50, + 50, + Permill::zero(), + ), + Error::::InvalidAccount + ); // Overflow - assert_noop!(Purchase::update_balance( - Origin::signed(validity_origin()), - alice(), - u64::MAX, - u64::MAX, - Permill::zero(), - ), Error::::InvalidAccount); + assert_noop!( + Purchase::update_balance( + Origin::signed(validity_origin()), + alice(), + u64::MAX, + u64::MAX, + Permill::zero(), + ), + Error::::InvalidAccount + ); }); } @@ -912,13 +1002,13 @@ mod tests { assert_ok!(Purchase::create_account( Origin::signed(validity_origin()), alice(), - alice_signature().to_vec()) - ); + alice_signature().to_vec() + )); assert_ok!(Purchase::create_account( Origin::signed(validity_origin()), bob(), - bob_signature().to_vec()) - ); + bob_signature().to_vec() + )); // Alice is approved for basic contribution assert_ok!(Purchase::update_validity_status( Origin::signed(validity_origin()), @@ -947,14 +1037,8 @@ mod tests { Permill::zero(), )); // Now we call payout for Alice and Bob. - assert_ok!(Purchase::payout( - Origin::signed(payment_account()), - alice(), - )); - assert_ok!(Purchase::payout( - Origin::signed(payment_account()), - bob(), - )); + assert_ok!(Purchase::payout(Origin::signed(payment_account()), alice(),)); + assert_ok!(Purchase::payout(Origin::signed(payment_account()), bob(),)); // Payment is made. assert_eq!(::Currency::free_balance(&payment_account()), 99_650); assert_eq!(::Currency::free_balance(&alice()), 100); @@ -1003,33 +1087,30 @@ mod tests { fn payout_handles_basic_errors() { new_test_ext().execute_with(|| { // Wrong Origin - assert_noop!(Purchase::payout( - Origin::signed(alice()), - alice(), - ), BadOrigin); + assert_noop!(Purchase::payout(Origin::signed(alice()), alice(),), BadOrigin); // Account with Existing Vesting Schedule - assert_ok!(::VestingSchedule::add_vesting_schedule( - &bob(), 100, 1, 50, - )); - assert_noop!(Purchase::payout( - Origin::signed(payment_account()), - bob(), - ), Error::::VestingScheduleExists); + assert_ok!( + ::VestingSchedule::add_vesting_schedule(&bob(), 100, 1, 50,) + ); + assert_noop!( + Purchase::payout(Origin::signed(payment_account()), bob(),), + Error::::VestingScheduleExists + ); // Invalid Account (never created) - assert_noop!(Purchase::payout( - Origin::signed(payment_account()), - alice(), - ), Error::::InvalidAccount); + assert_noop!( + Purchase::payout(Origin::signed(payment_account()), alice(),), + Error::::InvalidAccount + ); // Invalid Account (created, but not valid) assert_ok!(Purchase::create_account( Origin::signed(validity_origin()), alice(), - alice_signature().to_vec()) + alice_signature().to_vec() + )); + assert_noop!( + Purchase::payout(Origin::signed(payment_account()), alice(),), + Error::::InvalidAccount ); - assert_noop!(Purchase::payout( - Origin::signed(payment_account()), - alice(), - ), Error::::InvalidAccount); // Not enough funds in payment account assert_ok!(Purchase::update_validity_status( Origin::signed(validity_origin()), @@ -1043,10 +1124,10 @@ mod tests { 100_000, Permill::zero(), )); - assert_noop!(Purchase::payout( - Origin::signed(payment_account()), - alice(), - ), BalancesError::::InsufficientBalance); + assert_noop!( + Purchase::payout(Origin::signed(payment_account()), alice(),), + BalancesError::::InsufficientBalance + ); }); } diff --git a/polkadot/runtime/common/src/slot_range.rs b/polkadot/runtime/common/src/slot_range.rs index ea09d1f0838..d5bc38b3f63 100644 --- a/polkadot/runtime/common/src/slot_range.rs +++ b/polkadot/runtime/common/src/slot_range.rs @@ -17,7 +17,16 @@ //! The `SlotRange` struct which succinctly handles the 36 values that //! represent all sub ranges between 0 and 7 inclusive. -slot_range_helper::generate_slot_range!(Zero(0), One(1), Two(2), Three(3), Four(4), Five(5), Six(6), Seven(7)); +slot_range_helper::generate_slot_range!( + Zero(0), + One(1), + Two(2), + Three(3), + Four(4), + Five(5), + Six(6), + Seven(7) +); // Will generate: // pub enum SlotRange { diff --git a/polkadot/runtime/common/src/slots.rs b/polkadot/runtime/common/src/slots.rs index 96909b75d7e..658f5d20c49 100644 --- a/polkadot/runtime/common/src/slots.rs +++ b/polkadot/runtime/common/src/slots.rs @@ -209,9 +209,7 @@ pub mod pallet { // We can try to onboard it. Some(Some(_lease_info)) => T::Registrar::make_parachain(para)?, // Otherwise, it does not have a lease. - Some(None) | None => { - return Err(Error::::ParaNotOnboarding.into()); - } + Some(None) | None => return Err(Error::::ParaNotOnboarding.into()), }; Ok(()) } @@ -232,7 +230,7 @@ impl Pallet { let mut parachains = Vec::new(); for (para, mut lease_periods) in Leases::::iter() { if lease_periods.is_empty() { - continue; + continue } // ^^ should never be empty since we would have deleted the entry otherwise. @@ -307,16 +305,15 @@ impl Pallet { let mut tracker = sp_std::collections::btree_map::BTreeMap::new(); Leases::::get(para).into_iter().for_each(|lease| match lease { Some((who, amount)) => match tracker.get(&who) { - Some(prev_amount) => { + Some(prev_amount) => if amount > *prev_amount { tracker.insert(who, amount); - } - } + }, None => { tracker.insert(who, amount); - } + }, }, - None => {} + None => {}, }); tracker.into_iter().collect() @@ -375,7 +372,7 @@ impl Leaser for Pallet { // attempt. // // We bail, not giving any lease and leave it for governance to sort out. - return Err(LeaseError::AlreadyLeased); + return Err(LeaseError::AlreadyLeased) } } else if d.len() == i { // Doesn't exist. This is usual. @@ -423,13 +420,12 @@ impl Leaser for Pallet { Leases::::get(para) .into_iter() .map(|lease| match lease { - Some((who, amount)) => { + Some((who, amount)) => if &who == leaser { amount } else { Zero::zero() - } - } + }, None => Zero::zero(), }) .max() @@ -471,7 +467,7 @@ impl Leaser for Pallet { for slot in offset..=offset + period_count { if let Some(Some(_)) = leases.get(slot) { // If there exists any lease period, we exit early and return true. - return true; + return true } } diff --git a/polkadot/runtime/common/src/traits.rs b/polkadot/runtime/common/src/traits.rs index 1c42902dcb4..eb5e0eda517 100644 --- a/polkadot/runtime/common/src/traits.rs +++ b/polkadot/runtime/common/src/traits.rs @@ -16,12 +16,12 @@ //! Traits used across pallets for Polkadot. -use sp_std::vec::*; -use primitives::v1::{HeadData, ValidationCode, Id as ParaId}; use frame_support::{ dispatch::DispatchResult, traits::{Currency, ReservableCurrency}, }; +use primitives::v1::{HeadData, Id as ParaId, ValidationCode}; +use sp_std::vec::*; /// Parachain registration API. pub trait Registrar { @@ -128,7 +128,10 @@ pub trait Leaser { /// Return the amount of balance currently held in reserve on `leaser`'s account for leasing `para`. This won't /// go down outside of a lease period. - fn deposit_held(para: ParaId, leaser: &Self::AccountId) -> >::Balance; + fn deposit_held( + para: ParaId, + leaser: &Self::AccountId, + ) -> >::Balance; /// The lease period. This is constant, but can't be a `const` due to it being a runtime configurable quantity. fn lease_period() -> Self::LeasePeriod; @@ -141,7 +144,7 @@ pub trait Leaser { fn already_leased( para_id: ParaId, first_period: Self::LeasePeriod, - last_period: Self::LeasePeriod + last_period: Self::LeasePeriod, ) -> bool; } @@ -204,7 +207,10 @@ pub trait Auctioneer { /// This can only happen when there isn't already an auction in progress. Accepts the `duration` /// of this auction and the `lease_period_index` of the initial lease period of the four that /// are to be auctioned. - fn new_auction(duration: Self::BlockNumber, lease_period_index: Self::LeasePeriod) -> DispatchResult; + fn new_auction( + duration: Self::BlockNumber, + lease_period_index: Self::LeasePeriod, + ) -> DispatchResult; /// Given the current block number, return the current auction status. fn auction_status(now: Self::BlockNumber) -> AuctionStatus; diff --git a/polkadot/runtime/common/src/xcm_sender.rs b/polkadot/runtime/common/src/xcm_sender.rs index eb301a53ea3..151c649a8c4 100644 --- a/polkadot/runtime/common/src/xcm_sender.rs +++ b/polkadot/runtime/common/src/xcm_sender.rs @@ -17,9 +17,12 @@ //! XCM sender for relay chain. use parity_scale_codec::Encode; -use sp_std::marker::PhantomData; -use xcm::opaque::{VersionedXcm, v0::{SendXcm, MultiLocation, Junction, Xcm, Result, Error}}; use runtime_parachains::{configuration, dmp}; +use sp_std::marker::PhantomData; +use xcm::opaque::{ + v0::{Error, Junction, MultiLocation, Result, SendXcm, Xcm}, + VersionedXcm, +}; /// XCM sender for relay chain. It only sends downward message. pub struct ChildParachainRouter(PhantomData); @@ -34,9 +37,10 @@ impl SendXcm for ChildParachainRouter &config, id.into(), VersionedXcm::from(msg).encode(), - ).map_err(Into::::into)?; + ) + .map_err(Into::::into)?; Ok(()) - } + }, d => Err(Error::CannotReachDestination(d, msg)), } } diff --git a/polkadot/runtime/kusama/src/constants.rs b/polkadot/runtime/kusama/src/constants.rs index 0ccbdee37eb..fa653df2a39 100644 --- a/polkadot/runtime/kusama/src/constants.rs +++ b/polkadot/runtime/kusama/src/constants.rs @@ -30,7 +30,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::v0::{Moment, BlockNumber}; + use primitives::v0::{BlockNumber, Moment}; pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = 1 * HOURS; @@ -47,13 +47,13 @@ pub mod time { /// Fee-related. pub mod fee { - pub use sp_runtime::Perbill; - use primitives::v0::Balance; - use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ - WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }; + use primitives::v0::Balance; + use runtime_common::ExtrinsicBaseWeight; use smallvec::smallvec; + pub use sp_runtime::Perbill; /// The block saturation level. Fees will be updates based on this value. pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); @@ -87,10 +87,12 @@ pub mod fee { #[cfg(test)] mod tests { + use super::{ + currency::{CENTS, MILLICENTS}, + fee::WeightToFee, + }; use frame_support::weights::WeightToFeePolynomial; - use runtime_common::{MAXIMUM_BLOCK_WEIGHT, ExtrinsicBaseWeight}; - use super::fee::WeightToFee; - use super::currency::{CENTS, MILLICENTS}; + use runtime_common::{ExtrinsicBaseWeight, MAXIMUM_BLOCK_WEIGHT}; #[test] // This function tests that the fee for `MAXIMUM_BLOCK_WEIGHT` of weight is correct diff --git a/polkadot/runtime/kusama/src/tests.rs b/polkadot/runtime/kusama/src/tests.rs index c6423ae9ebf..82f84db78a3 100644 --- a/polkadot/runtime/kusama/src/tests.rs +++ b/polkadot/runtime/kusama/src/tests.rs @@ -17,12 +17,11 @@ //! Tests for the Kusama Runtime Configuration use crate::*; -use frame_support::weights::WeightToFeePolynomial; -use sp_runtime::FixedPointNumber; -use frame_support::weights::GetDispatchInfo; -use parity_scale_codec::Encode; +use frame_support::weights::{GetDispatchInfo, WeightToFeePolynomial}; use pallet_transaction_payment::Multiplier; +use parity_scale_codec::Encode; use separator::Separatable; +use sp_runtime::FixedPointNumber; #[test] fn remove_keys_weight_is_sensible() { @@ -40,16 +39,18 @@ fn sample_size_is_sensible() { let max_weight: Weight = RocksDbWeight::get().reads_writes(samples.into(), samples.into()); // Max sample cleanup should be no more than half the total block weight. assert!(max_weight * 2 < BlockWeights::get().max_block); - assert!(::WeightInfo::on_initialize() * 2 < BlockWeights::get().max_block); + assert!( + ::WeightInfo::on_initialize() * 2 < + BlockWeights::get().max_block + ); } #[test] fn payout_weight_portion() { use pallet_staking::WeightInfo; - let payout_weight = - ::WeightInfo::payout_stakers_alive_staked( - MaxNominatorRewardedPerValidator::get(), - ) as f64; + let payout_weight = ::WeightInfo::payout_stakers_alive_staked( + MaxNominatorRewardedPerValidator::get(), + ) as f64; let block_weight = BlockWeights::get().max_block as f64; println!( @@ -78,7 +79,10 @@ fn block_cost() { #[ignore] fn transfer_cost_min_multiplier() { let min_multiplier = runtime_common::MinimumMultiplier::get(); - let call = >::transfer_keep_alive(Default::default(), Default::default()); + let call = >::transfer_keep_alive( + Default::default(), + Default::default(), + ); let info = call.get_dispatch_info(); // convert to outer call. let call = Call::Balances(call); @@ -133,37 +137,34 @@ fn nominator_limit() { #[test] fn compute_inflation_should_give_sensible_results() { - assert_eq!(pallet_staking_reward_fn::compute_inflation( - Perquintill::from_percent(75), - Perquintill::from_percent(75), - Perquintill::from_percent(5), - ), Perquintill::one()); - assert_eq!(pallet_staking_reward_fn::compute_inflation( - Perquintill::from_percent(50), - Perquintill::from_percent(75), - Perquintill::from_percent(5), - ), Perquintill::from_rational(2u64, 3u64)); - assert_eq!(pallet_staking_reward_fn::compute_inflation( - Perquintill::from_percent(80), - Perquintill::from_percent(75), - Perquintill::from_percent(5), - ), Perquintill::from_rational(1u64, 2u64)); + assert_eq!( + pallet_staking_reward_fn::compute_inflation( + Perquintill::from_percent(75), + Perquintill::from_percent(75), + Perquintill::from_percent(5), + ), + Perquintill::one() + ); + assert_eq!( + pallet_staking_reward_fn::compute_inflation( + Perquintill::from_percent(50), + Perquintill::from_percent(75), + Perquintill::from_percent(5), + ), + Perquintill::from_rational(2u64, 3u64) + ); + assert_eq!( + pallet_staking_reward_fn::compute_inflation( + Perquintill::from_percent(80), + Perquintill::from_percent(75), + Perquintill::from_percent(5), + ), + Perquintill::from_rational(1u64, 2u64) + ); } #[test] fn era_payout_should_give_sensible_results() { - assert_eq!(era_payout( - 75, - 100, - Perquintill::from_percent(10), - Perquintill::one(), - 0, - ), (10, 0)); - assert_eq!(era_payout( - 80, - 100, - Perquintill::from_percent(10), - Perquintill::one(), - 0, - ), (6, 4)); + assert_eq!(era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), (10, 0)); + assert_eq!(era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), (6, 4)); } diff --git a/polkadot/runtime/kusama/src/weights/frame_system.rs b/polkadot/runtime/kusama/src/weights/frame_system.rs index ec892350aad..3b4f27c8d9f 100644 --- a/polkadot/runtime/kusama/src/weights/frame_system.rs +++ b/polkadot/runtime/kusama/src/weights/frame_system.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,36 +42,35 @@ use sp_std::marker::PhantomData; /// Weight functions for `frame_system`. pub struct WeightInfo(PhantomData); impl frame_system::WeightInfo for WeightInfo { - fn remark(_b: u32, ) -> Weight { + fn remark(_b: u32) -> Weight { (1_234_000 as Weight) } - fn remark_with_event(b: u32, ) -> Weight { + fn remark_with_event(b: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((1_000 as Weight).saturating_mul(b as Weight)) } fn set_heap_pages() -> Weight { - (1_670_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (1_670_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_changes_trie_config() -> Weight { (9_897_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn set_storage(i: u32, ) -> Weight { + fn set_storage(i: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((529_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) } - fn kill_storage(i: u32, ) -> Weight { + fn kill_storage(i: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((381_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) } - fn kill_prefix(p: u32, ) -> Weight { + fn kill_prefix(p: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((788_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/mod.rs b/polkadot/runtime/kusama/src/weights/mod.rs index a83b57bfcdf..ebe810d6290 100644 --- a/polkadot/runtime/kusama/src/weights/mod.rs +++ b/polkadot/runtime/kusama/src/weights/mod.rs @@ -20,8 +20,8 @@ pub mod pallet_balances; pub mod pallet_bounties; pub mod pallet_collective; pub mod pallet_democracy; -pub mod pallet_elections_phragmen; pub mod pallet_election_provider_multi_phase; +pub mod pallet_elections_phragmen; pub mod pallet_gilt; pub mod pallet_identity; pub mod pallet_im_online; diff --git a/polkadot/runtime/kusama/src/weights/pallet_balances.rs b/polkadot/runtime/kusama/src/weights/pallet_balances.rs index edc3b81e681..74001c45381 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_balances.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_balances.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/kusama/src/weights/pallet_bounties.rs b/polkadot/runtime/kusama/src/weights/pallet_bounties.rs index ee5cf0212ea..ae945a0676d 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_bounties.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_bounties.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_bounties`. pub struct WeightInfo(PhantomData); impl pallet_bounties::WeightInfo for WeightInfo { - fn propose_bounty(d: u32, ) -> Weight { + fn propose_bounty(d: u32) -> Weight { (43_276_000 as Weight) // Standard Error: 0 .saturating_add((1_000 as Weight).saturating_mul(d as Weight)) @@ -95,7 +94,7 @@ impl pallet_bounties::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn spend_funds(b: u32, ) -> Weight { + fn spend_funds(b: u32) -> Weight { (0 as Weight) // Standard Error: 14_000 .saturating_add((60_142_000 as Weight).saturating_mul(b as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_collective.rs b/polkadot/runtime/kusama/src/weights/pallet_collective.rs index 9a59fb34bb0..3f50e94419e 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_collective.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_collective.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_collective`. pub struct WeightInfo(PhantomData); impl pallet_collective::WeightInfo for WeightInfo { - fn set_members(m: u32, n: u32, p: u32, ) -> Weight { + fn set_members(m: u32, n: u32, p: u32) -> Weight { (0 as Weight) // Standard Error: 4_000 .saturating_add((14_115_000 as Weight).saturating_mul(m as Weight)) @@ -56,7 +55,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) } - fn execute(b: u32, m: u32, ) -> Weight { + fn execute(b: u32, m: u32) -> Weight { (23_670_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) @@ -64,7 +63,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add((83_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn propose_execute(b: u32, m: u32, ) -> Weight { + fn propose_execute(b: u32, m: u32) -> Weight { (28_523_000 as Weight) // Standard Error: 0 .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) @@ -72,7 +71,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add((163_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) } - fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + fn propose_proposed(b: u32, m: u32, p: u32) -> Weight { (44_252_000 as Weight) // Standard Error: 0 .saturating_add((4_000 as Weight).saturating_mul(b as Weight)) @@ -83,14 +82,14 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn vote(m: u32, ) -> Weight { + fn vote(m: u32) -> Weight { (32_883_000 as Weight) // Standard Error: 0 .saturating_add((214_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + fn close_early_disapproved(m: u32, p: u32) -> Weight { (42_090_000 as Weight) // Standard Error: 0 .saturating_add((166_000 as Weight).saturating_mul(m as Weight)) @@ -99,7 +98,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + fn close_early_approved(b: u32, m: u32, p: u32) -> Weight { (62_491_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) @@ -110,7 +109,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn close_disapproved(m: u32, p: u32, ) -> Weight { + fn close_disapproved(m: u32, p: u32) -> Weight { (46_976_000 as Weight) // Standard Error: 0 .saturating_add((168_000 as Weight).saturating_mul(m as Weight)) @@ -119,7 +118,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + fn close_approved(b: u32, m: u32, p: u32) -> Weight { (66_976_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) @@ -130,7 +129,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn disapprove_proposal(p: u32, ) -> Weight { + fn disapprove_proposal(p: u32) -> Weight { (26_129_000 as Weight) // Standard Error: 0 .saturating_add((379_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_democracy.rs b/polkadot/runtime/kusama/src/weights/pallet_democracy.rs index b3263b2c3ab..f6a4991a3fb 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_democracy.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_democracy.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -48,21 +47,21 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn second(s: u32, ) -> Weight { + fn second(s: u32) -> Weight { (39_011_000 as Weight) // Standard Error: 0 .saturating_add((157_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn vote_new(r: u32, ) -> Weight { + fn vote_new(r: u32) -> Weight { (43_998_000 as Weight) // Standard Error: 0 .saturating_add((211_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn vote_existing(r: u32, ) -> Weight { + fn vote_existing(r: u32) -> Weight { (44_219_000 as Weight) // Standard Error: 0 .saturating_add((206_000 as Weight).saturating_mul(r as Weight)) @@ -74,14 +73,14 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn blacklist(p: u32, ) -> Weight { + fn blacklist(p: u32) -> Weight { (77_299_000 as Weight) // Standard Error: 4_000 .saturating_add((541_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } - fn external_propose(v: u32, ) -> Weight { + fn external_propose(v: u32) -> Weight { (13_334_000 as Weight) // Standard Error: 0 .saturating_add((80_000 as Weight).saturating_mul(v as Weight)) @@ -89,26 +88,24 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn external_propose_majority() -> Weight { - (2_650_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_650_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn external_propose_default() -> Weight { - (2_667_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_667_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn fast_track() -> Weight { (27_908_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn veto_external(v: u32, ) -> Weight { + fn veto_external(v: u32) -> Weight { (28_446_000 as Weight) // Standard Error: 0 .saturating_add((134_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn cancel_proposal(p: u32, ) -> Weight { + fn cancel_proposal(p: u32) -> Weight { (51_004_000 as Weight) // Standard Error: 0 .saturating_add((512_000 as Weight).saturating_mul(p as Weight)) @@ -116,24 +113,23 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn cancel_referendum() -> Weight { - (17_377_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (17_377_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel_queued(r: u32, ) -> Weight { + fn cancel_queued(r: u32) -> Weight { (33_882_000 as Weight) // Standard Error: 15_000 .saturating_add((6_070_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn on_initialize_base(r: u32, ) -> Weight { + fn on_initialize_base(r: u32) -> Weight { (7_295_000 as Weight) // Standard Error: 4_000 .saturating_add((5_093_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) } - fn delegate(r: u32, ) -> Weight { + fn delegate(r: u32) -> Weight { (54_128_000 as Weight) // Standard Error: 5_000 .saturating_add((7_209_000 as Weight).saturating_mul(r as Weight)) @@ -142,7 +138,7 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) } - fn undelegate(r: u32, ) -> Weight { + fn undelegate(r: u32) -> Weight { (23_613_000 as Weight) // Standard Error: 4_000 .saturating_add((7_196_000 as Weight).saturating_mul(r as Weight)) @@ -152,52 +148,51 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) } fn clear_public_proposals() -> Weight { - (2_607_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_607_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn note_preimage(b: u32, ) -> Weight { + fn note_preimage(b: u32) -> Weight { (42_847_000 as Weight) // Standard Error: 0 .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn note_imminent_preimage(b: u32, ) -> Weight { + fn note_imminent_preimage(b: u32) -> Weight { (27_699_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn reap_preimage(b: u32, ) -> Weight { + fn reap_preimage(b: u32) -> Weight { (38_171_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn unlock_remove(r: u32, ) -> Weight { + fn unlock_remove(r: u32) -> Weight { (37_418_000 as Weight) // Standard Error: 0 .saturating_add((55_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn unlock_set(r: u32, ) -> Weight { + fn unlock_set(r: u32) -> Weight { (35_077_000 as Weight) // Standard Error: 0 .saturating_add((197_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn remove_vote(r: u32, ) -> Weight { + fn remove_vote(r: u32) -> Weight { (19_476_000 as Weight) // Standard Error: 0 .saturating_add((183_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn remove_other_vote(r: u32, ) -> Weight { + fn remove_other_vote(r: u32) -> Weight { (19_518_000 as Weight) // Standard Error: 0 .saturating_add((186_000 as Weight).saturating_mul(r as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_election_provider_multi_phase.rs b/polkadot/runtime/kusama/src/weights/pallet_election_provider_multi_phase.rs index b6de878cf7c..54f42a7f0a3 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_election_provider_multi_phase.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_election_provider_multi_phase.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -44,8 +43,7 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_election_provider_multi_phase::WeightInfo for WeightInfo { fn on_initialize_nothing() -> Weight { - (22_984_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) + (22_984_000 as Weight).saturating_add(T::DbWeight::get().reads(8 as Weight)) } fn on_initialize_open_signed() -> Weight { (83_667_000 as Weight) @@ -62,19 +60,19 @@ impl pallet_election_provider_multi_phase::WeightInfo f .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn elect_queued(_v: u32, _t: u32, _a: u32, _d: u32, ) -> Weight { + fn elect_queued(_v: u32, _t: u32, _a: u32, _d: u32) -> Weight { (8_641_847_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } - fn submit(c: u32, ) -> Weight { + fn submit(c: u32) -> Weight { (84_430_000 as Weight) // Standard Error: 146_000 .saturating_add((2_758_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn submit_unsigned(v: u32, t: u32, a: u32, d: u32, ) -> Weight { + fn submit_unsigned(v: u32, t: u32, a: u32, d: u32) -> Weight { (0 as Weight) // Standard Error: 13_000 .saturating_add((4_805_000 as Weight).saturating_mul(v as Weight)) @@ -87,7 +85,7 @@ impl pallet_election_provider_multi_phase::WeightInfo f .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn feasibility_check(v: u32, t: u32, a: u32, d: u32, ) -> Weight { + fn feasibility_check(v: u32, t: u32, a: u32, d: u32) -> Weight { (0 as Weight) // Standard Error: 8_000 .saturating_add((4_729_000 as Weight).saturating_mul(v as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_elections_phragmen.rs b/polkadot/runtime/kusama/src/weights/pallet_elections_phragmen.rs index 7d732d080c0..444b3e3c920 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_elections_phragmen.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_elections_phragmen.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,19 +42,19 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_elections_phragmen`. pub struct WeightInfo(PhantomData); impl pallet_elections_phragmen::WeightInfo for WeightInfo { - fn vote_equal(v: u32, ) -> Weight { + fn vote_equal(v: u32) -> Weight { (54_923_000 as Weight) .saturating_add((324_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vote_more(v: u32, ) -> Weight { + fn vote_more(v: u32) -> Weight { (83_389_000 as Weight) .saturating_add((341_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vote_less(v: u32, ) -> Weight { + fn vote_less(v: u32) -> Weight { (78_865_000 as Weight) .saturating_add((343_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) @@ -66,13 +65,13 @@ impl pallet_elections_phragmen::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn submit_candidacy(c: u32, ) -> Weight { + fn submit_candidacy(c: u32) -> Weight { (68_455_000 as Weight) .saturating_add((370_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn renounce_candidacy_candidate(c: u32, ) -> Weight { + fn renounce_candidacy_candidate(c: u32) -> Weight { (54_009_000 as Weight) .saturating_add((200_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) @@ -94,17 +93,16 @@ impl pallet_elections_phragmen::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().writes(5 as Weight)) } fn remove_member_wrong_refund() -> Weight { - (8_551_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (8_551_000 as Weight).saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { + fn clean_defunct_voters(v: u32, _d: u32) -> Weight { (0 as Weight) .saturating_add((151_754_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(v as Weight))) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(v as Weight))) } - fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { + fn election_phragmen(c: u32, v: u32, e: u32) -> Weight { (0 as Weight) .saturating_add((134_602_000 as Weight).saturating_mul(c as Weight)) .saturating_add((111_037_000 as Weight).saturating_mul(v as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_gilt.rs b/polkadot/runtime/kusama/src/weights/pallet_gilt.rs index 28813c9a5c9..160a78b982a 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_gilt.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_gilt.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_gilt`. pub struct WeightInfo(PhantomData); impl pallet_gilt::WeightInfo for WeightInfo { - fn place_bid(l: u32, ) -> Weight { + fn place_bid(l: u32) -> Weight { (57_179_000 as Weight) // Standard Error: 0 .saturating_add((195_000 as Weight).saturating_mul(l as Weight)) @@ -55,7 +54,7 @@ impl pallet_gilt::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn retract_bid(l: u32, ) -> Weight { + fn retract_bid(l: u32) -> Weight { (57_082_000 as Weight) // Standard Error: 0 .saturating_add((166_000 as Weight).saturating_mul(l as Weight)) @@ -73,10 +72,9 @@ impl pallet_gilt::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn pursue_target_noop() -> Weight { - (3_347_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (3_347_000 as Weight).saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn pursue_target_per_item(b: u32, ) -> Weight { + fn pursue_target_per_item(b: u32) -> Weight { (56_853_000 as Weight) // Standard Error: 1_000 .saturating_add((10_238_000 as Weight).saturating_mul(b as Weight)) @@ -84,7 +82,7 @@ impl pallet_gilt::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight))) } - fn pursue_target_per_queue(q: u32, ) -> Weight { + fn pursue_target_per_queue(q: u32) -> Weight { (23_272_000 as Weight) // Standard Error: 5_000 .saturating_add((16_821_000 as Weight).saturating_mul(q as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_identity.rs b/polkadot/runtime/kusama/src/weights/pallet_identity.rs index 87f881c36d8..676361ee81b 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_identity.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_identity.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,14 +42,14 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_identity`. pub struct WeightInfo(PhantomData); impl pallet_identity::WeightInfo for WeightInfo { - fn add_registrar(r: u32, ) -> Weight { + fn add_registrar(r: u32) -> Weight { (21_339_000 as Weight) // Standard Error: 2_000 .saturating_add((236_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_identity(r: u32, x: u32, ) -> Weight { + fn set_identity(r: u32, x: u32) -> Weight { (50_839_000 as Weight) // Standard Error: 14_000 .saturating_add((223_000 as Weight).saturating_mul(r as Weight)) @@ -59,7 +58,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_subs_new(s: u32, ) -> Weight { + fn set_subs_new(s: u32) -> Weight { (40_807_000 as Weight) // Standard Error: 1_000 .saturating_add((6_374_000 as Weight).saturating_mul(s as Weight)) @@ -68,7 +67,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn set_subs_old(p: u32, ) -> Weight { + fn set_subs_old(p: u32) -> Weight { (40_924_000 as Weight) // Standard Error: 0 .saturating_add((2_059_000 as Weight).saturating_mul(p as Weight)) @@ -76,7 +75,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) } - fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight { + fn clear_identity(r: u32, s: u32, x: u32) -> Weight { (51_123_000 as Weight) // Standard Error: 7_000 .saturating_add((110_000 as Weight).saturating_mul(r as Weight)) @@ -88,7 +87,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn request_judgement(r: u32, x: u32, ) -> Weight { + fn request_judgement(r: u32, x: u32) -> Weight { (53_230_000 as Weight) // Standard Error: 5_000 .saturating_add((223_000 as Weight).saturating_mul(r as Weight)) @@ -97,7 +96,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel_request(r: u32, x: u32, ) -> Weight { + fn cancel_request(r: u32, x: u32) -> Weight { (48_425_000 as Weight) // Standard Error: 6_000 .saturating_add((161_000 as Weight).saturating_mul(r as Weight)) @@ -106,28 +105,28 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_fee(r: u32, ) -> Weight { + fn set_fee(r: u32) -> Weight { (8_028_000 as Weight) // Standard Error: 0 .saturating_add((202_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_account_id(r: u32, ) -> Weight { + fn set_account_id(r: u32) -> Weight { (8_682_000 as Weight) // Standard Error: 1_000 .saturating_add((203_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_fields(r: u32, ) -> Weight { + fn set_fields(r: u32) -> Weight { (8_010_000 as Weight) // Standard Error: 0 .saturating_add((203_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn provide_judgement(r: u32, x: u32, ) -> Weight { + fn provide_judgement(r: u32, x: u32) -> Weight { (34_291_000 as Weight) // Standard Error: 5_000 .saturating_add((203_000 as Weight).saturating_mul(r as Weight)) @@ -136,7 +135,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight { + fn kill_identity(r: u32, s: u32, x: u32) -> Weight { (62_644_000 as Weight) // Standard Error: 6_000 .saturating_add((111_000 as Weight).saturating_mul(r as Weight)) @@ -148,28 +147,28 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn add_sub(s: u32, ) -> Weight { + fn add_sub(s: u32) -> Weight { (54_234_000 as Weight) // Standard Error: 0 .saturating_add((154_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn rename_sub(s: u32, ) -> Weight { + fn rename_sub(s: u32) -> Weight { (16_622_000 as Weight) // Standard Error: 0 .saturating_add((21_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_sub(s: u32, ) -> Weight { + fn remove_sub(s: u32) -> Weight { (55_325_000 as Weight) // Standard Error: 0 .saturating_add((138_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn quit_sub(s: u32, ) -> Weight { + fn quit_sub(s: u32) -> Weight { (34_002_000 as Weight) // Standard Error: 0 .saturating_add((138_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_im_online.rs b/polkadot/runtime/kusama/src/weights/pallet_im_online.rs index 7112c0b36ff..df006e93135 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_im_online.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_im_online.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_im_online`. pub struct WeightInfo(PhantomData); impl pallet_im_online::WeightInfo for WeightInfo { - fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight { + fn validate_unsigned_and_then_heartbeat(k: u32, e: u32) -> Weight { (86_872_000 as Weight) // Standard Error: 0 .saturating_add((158_000 as Weight).saturating_mul(k as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_indices.rs b/polkadot/runtime/kusama/src/weights/pallet_indices.rs index fb6ef191cad..3449f65b454 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_indices.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_indices.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/kusama/src/weights/pallet_membership.rs b/polkadot/runtime/kusama/src/weights/pallet_membership.rs index 0f5083e6e87..ed0e08098d1 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_membership.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_membership.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,50 +42,49 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_membership`. pub struct WeightInfo(PhantomData); impl pallet_membership::WeightInfo for WeightInfo { - fn add_member(m: u32, ) -> Weight { + fn add_member(m: u32) -> Weight { (23_736_000 as Weight) // Standard Error: 3_000 .saturating_add((166_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn remove_member(m: u32, ) -> Weight { + fn remove_member(m: u32) -> Weight { (28_609_000 as Weight) // Standard Error: 0 .saturating_add((137_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn swap_member(m: u32, ) -> Weight { + fn swap_member(m: u32) -> Weight { (28_935_000 as Weight) // Standard Error: 0 .saturating_add((150_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn reset_member(m: u32, ) -> Weight { + fn reset_member(m: u32) -> Weight { (29_621_000 as Weight) // Standard Error: 0 .saturating_add((304_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn change_key(m: u32, ) -> Weight { + fn change_key(m: u32) -> Weight { (30_393_000 as Weight) // Standard Error: 0 .saturating_add((145_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn set_prime(m: u32, ) -> Weight { + fn set_prime(m: u32) -> Weight { (7_534_000 as Weight) // Standard Error: 0 .saturating_add((79_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn clear_prime(_m: u32, ) -> Weight { - (2_755_000 as Weight) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) + fn clear_prime(_m: u32) -> Weight { + (2_755_000 as Weight).saturating_add(T::DbWeight::get().writes(2 as Weight)) } } diff --git a/polkadot/runtime/kusama/src/weights/pallet_multisig.rs b/polkadot/runtime/kusama/src/weights/pallet_multisig.rs index 0779f8a189d..fc049c3acdc 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_multisig.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_multisig.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,10 +42,10 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_multisig`. pub struct WeightInfo(PhantomData); impl pallet_multisig::WeightInfo for WeightInfo { - fn as_multi_threshold_1(_z: u32, ) -> Weight { + fn as_multi_threshold_1(_z: u32) -> Weight { (12_153_000 as Weight) } - fn as_multi_create(s: u32, z: u32, ) -> Weight { + fn as_multi_create(s: u32, z: u32) -> Weight { (50_455_000 as Weight) // Standard Error: 0 .saturating_add((103_000 as Weight).saturating_mul(s as Weight)) @@ -55,7 +54,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn as_multi_create_store(s: u32, z: u32, ) -> Weight { + fn as_multi_create_store(s: u32, z: u32) -> Weight { (56_117_000 as Weight) // Standard Error: 0 .saturating_add((106_000 as Weight).saturating_mul(s as Weight)) @@ -64,7 +63,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn as_multi_approve(s: u32, z: u32, ) -> Weight { + fn as_multi_approve(s: u32, z: u32) -> Weight { (29_486_000 as Weight) // Standard Error: 0 .saturating_add((103_000 as Weight).saturating_mul(s as Weight)) @@ -73,7 +72,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn as_multi_approve_store(s: u32, z: u32, ) -> Weight { + fn as_multi_approve_store(s: u32, z: u32) -> Weight { (53_516_000 as Weight) // Standard Error: 0 .saturating_add((118_000 as Weight).saturating_mul(s as Weight)) @@ -82,7 +81,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn as_multi_complete(s: u32, z: u32, ) -> Weight { + fn as_multi_complete(s: u32, z: u32) -> Weight { (70_795_000 as Weight) // Standard Error: 0 .saturating_add((205_000 as Weight).saturating_mul(s as Weight)) @@ -91,28 +90,28 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn approve_as_multi_create(s: u32, ) -> Weight { + fn approve_as_multi_create(s: u32) -> Weight { (50_128_000 as Weight) // Standard Error: 0 .saturating_add((104_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn approve_as_multi_approve(s: u32, ) -> Weight { + fn approve_as_multi_approve(s: u32) -> Weight { (28_902_000 as Weight) // Standard Error: 0 .saturating_add((105_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn approve_as_multi_complete(s: u32, ) -> Weight { + fn approve_as_multi_complete(s: u32) -> Weight { (112_716_000 as Weight) // Standard Error: 0 .saturating_add((210_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn cancel_as_multi(s: u32, ) -> Weight { + fn cancel_as_multi(s: u32) -> Weight { (84_205_000 as Weight) // Standard Error: 0 .saturating_add((101_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_proxy.rs b/polkadot/runtime/kusama/src/weights/pallet_proxy.rs index 5f551494e1a..40db10a6379 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_proxy.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_proxy.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,13 +42,13 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_proxy`. pub struct WeightInfo(PhantomData); impl pallet_proxy::WeightInfo for WeightInfo { - fn proxy(p: u32, ) -> Weight { + fn proxy(p: u32) -> Weight { (24_892_000 as Weight) // Standard Error: 0 .saturating_add((122_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn proxy_announced(a: u32, p: u32, ) -> Weight { + fn proxy_announced(a: u32, p: u32) -> Weight { (55_405_000 as Weight) // Standard Error: 1_000 .saturating_add((563_000 as Weight).saturating_mul(a as Weight)) @@ -58,21 +57,21 @@ impl pallet_proxy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn remove_announcement(a: u32, _p: u32, ) -> Weight { + fn remove_announcement(a: u32, _p: u32) -> Weight { (37_762_000 as Weight) // Standard Error: 1_000 .saturating_add((554_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn reject_announcement(a: u32, _p: u32, ) -> Weight { + fn reject_announcement(a: u32, _p: u32) -> Weight { (37_826_000 as Weight) // Standard Error: 1_000 .saturating_add((554_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn announce(a: u32, p: u32, ) -> Weight { + fn announce(a: u32, p: u32) -> Weight { (51_131_000 as Weight) // Standard Error: 1_000 .saturating_add((562_000 as Weight).saturating_mul(a as Weight)) @@ -81,35 +80,35 @@ impl pallet_proxy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn add_proxy(p: u32, ) -> Weight { + fn add_proxy(p: u32) -> Weight { (36_114_000 as Weight) // Standard Error: 1_000 .saturating_add((223_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_proxy(p: u32, ) -> Weight { + fn remove_proxy(p: u32) -> Weight { (35_456_000 as Weight) // Standard Error: 2_000 .saturating_add((246_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_proxies(p: u32, ) -> Weight { + fn remove_proxies(p: u32) -> Weight { (33_748_000 as Weight) // Standard Error: 1_000 .saturating_add((136_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn anonymous(p: u32, ) -> Weight { + fn anonymous(p: u32) -> Weight { (48_409_000 as Weight) // Standard Error: 1_000 .saturating_add((31_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn kill_anonymous(p: u32, ) -> Weight { + fn kill_anonymous(p: u32) -> Weight { (35_515_000 as Weight) // Standard Error: 1_000 .saturating_add((134_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_scheduler.rs b/polkadot/runtime/kusama/src/weights/pallet_scheduler.rs index fe7b45604b7..e68d1c90927 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_scheduler.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_scheduler.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,28 +42,28 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_scheduler`. pub struct WeightInfo(PhantomData); impl pallet_scheduler::WeightInfo for WeightInfo { - fn schedule(s: u32, ) -> Weight { + fn schedule(s: u32) -> Weight { (28_202_000 as Weight) // Standard Error: 0 .saturating_add((42_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel(s: u32, ) -> Weight { + fn cancel(s: u32) -> Weight { (27_640_000 as Weight) // Standard Error: 14_000 .saturating_add((5_699_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn schedule_named(s: u32, ) -> Weight { + fn schedule_named(s: u32) -> Weight { (34_298_000 as Weight) // Standard Error: 1_000 .saturating_add((56_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn cancel_named(s: u32, ) -> Weight { + fn cancel_named(s: u32) -> Weight { (29_004_000 as Weight) // Standard Error: 15_000 .saturating_add((5_720_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_session.rs b/polkadot/runtime/kusama/src/weights/pallet_session.rs index 1ebe0adeac8..23a29acbbdf 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_session.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_session.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/kusama/src/weights/pallet_staking.rs b/polkadot/runtime/kusama/src/weights/pallet_staking.rs index af87a6f6b04..2df8f525cc5 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_staking.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_staking.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -58,14 +57,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn withdraw_unbonded_update(s: u32, ) -> Weight { + fn withdraw_unbonded_update(s: u32) -> Weight { (49_532_000 as Weight) // Standard Error: 0 .saturating_add((29_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn withdraw_unbonded_kill(s: u32, ) -> Weight { + fn withdraw_unbonded_kill(s: u32) -> Weight { (81_722_000 as Weight) // Standard Error: 1_000 .saturating_add((2_331_000 as Weight).saturating_mul(s as Weight)) @@ -78,7 +77,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn kick(k: u32, ) -> Weight { + fn kick(k: u32) -> Weight { (10_120_000 as Weight) // Standard Error: 6_000 .saturating_add((18_142_000 as Weight).saturating_mul(k as Weight)) @@ -86,7 +85,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(k as Weight))) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } - fn nominate(n: u32, ) -> Weight { + fn nominate(n: u32) -> Weight { (37_716_000 as Weight) // Standard Error: 6_000 .saturating_add((5_240_000 as Weight).saturating_mul(n as Weight)) @@ -95,8 +94,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn chill() -> Weight { - (16_594_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) + (16_594_000 as Weight).saturating_add(T::DbWeight::get().reads(3 as Weight)) } fn set_payee() -> Weight { (11_260_000 as Weight) @@ -109,28 +107,24 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn set_validator_count() -> Weight { - (2_123_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_123_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_no_eras() -> Weight { - (2_458_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_458_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_new_era() -> Weight { - (2_428_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_428_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_new_era_always() -> Weight { - (2_435_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_435_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_invulnerables(v: u32, ) -> Weight { + fn set_invulnerables(v: u32) -> Weight { (2_524_000 as Weight) // Standard Error: 0 .saturating_add((23_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn force_unstake(s: u32, ) -> Weight { + fn force_unstake(s: u32) -> Weight { (57_861_000 as Weight) // Standard Error: 1_000 .saturating_add((2_315_000 as Weight).saturating_mul(s as Weight)) @@ -138,14 +132,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(6 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn cancel_deferred_slash(s: u32, ) -> Weight { + fn cancel_deferred_slash(s: u32) -> Weight { (3_460_645_000 as Weight) // Standard Error: 221_000 .saturating_add((19_673_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn payout_stakers_dead_controller(n: u32, ) -> Weight { + fn payout_stakers_dead_controller(n: u32) -> Weight { (108_055_000 as Weight) // Standard Error: 15_000 .saturating_add((47_913_000 as Weight).saturating_mul(n as Weight)) @@ -154,7 +148,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(n as Weight))) } - fn payout_stakers_alive_staked(n: u32, ) -> Weight { + fn payout_stakers_alive_staked(n: u32) -> Weight { (122_624_000 as Weight) // Standard Error: 22_000 .saturating_add((60_815_000 as Weight).saturating_mul(n as Weight)) @@ -163,14 +157,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(n as Weight))) } - fn rebond(l: u32, ) -> Weight { + fn rebond(l: u32) -> Weight { (46_725_000 as Weight) // Standard Error: 1_000 .saturating_add((62_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn set_history_depth(e: u32, ) -> Weight { + fn set_history_depth(e: u32) -> Weight { (0 as Weight) // Standard Error: 68_000 .saturating_add((32_190_000 as Weight).saturating_mul(e as Weight)) @@ -178,7 +172,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((7 as Weight).saturating_mul(e as Weight))) } - fn reap_stash(s: u32, ) -> Weight { + fn reap_stash(s: u32) -> Weight { (68_887_000 as Weight) // Standard Error: 0 .saturating_add((2_318_000 as Weight).saturating_mul(s as Weight)) @@ -186,7 +180,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(8 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn new_era(v: u32, n: u32, ) -> Weight { + fn new_era(v: u32, n: u32) -> Weight { (0 as Weight) // Standard Error: 734_000 .saturating_add((296_342_000 as Weight).saturating_mul(v as Weight)) @@ -198,7 +192,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(v as Weight))) } - fn get_npos_voters(v: u32, n: u32, s: u32, ) -> Weight { + fn get_npos_voters(v: u32, n: u32, s: u32) -> Weight { (0 as Weight) // Standard Error: 92_000 .saturating_add((24_187_000 as Weight).saturating_mul(v as Weight)) @@ -211,7 +205,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(s as Weight))) } - fn get_npos_targets(v: u32, ) -> Weight { + fn get_npos_targets(v: u32) -> Weight { (0 as Weight) // Standard Error: 27_000 .saturating_add((10_233_000 as Weight).saturating_mul(v as Weight)) @@ -219,8 +213,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(v as Weight))) } fn set_staking_limits() -> Weight { - (5_708_000 as Weight) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) + (5_708_000 as Weight).saturating_add(T::DbWeight::get().writes(5 as Weight)) } fn chill_other() -> Weight { (39_559_000 as Weight) diff --git a/polkadot/runtime/kusama/src/weights/pallet_timestamp.rs b/polkadot/runtime/kusama/src/weights/pallet_timestamp.rs index 62c648462aa..e13e8de5767 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_timestamp.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_timestamp.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/kusama/src/weights/pallet_tips.rs b/polkadot/runtime/kusama/src/weights/pallet_tips.rs index 13e0f4b9f4e..361829d2ec5 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_tips.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_tips.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_tips`. pub struct WeightInfo(PhantomData); impl pallet_tips::WeightInfo for WeightInfo { - fn report_awesome(r: u32, ) -> Weight { + fn report_awesome(r: u32) -> Weight { (49_516_000 as Weight) // Standard Error: 0 .saturating_add((1_000 as Weight).saturating_mul(r as Weight)) @@ -55,7 +54,7 @@ impl pallet_tips::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn tip_new(r: u32, t: u32, ) -> Weight { + fn tip_new(r: u32, t: u32) -> Weight { (30_538_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) @@ -64,21 +63,21 @@ impl pallet_tips::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn tip(t: u32, ) -> Weight { + fn tip(t: u32) -> Weight { (18_895_000 as Weight) // Standard Error: 0 .saturating_add((558_000 as Weight).saturating_mul(t as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn close_tip(t: u32, ) -> Weight { + fn close_tip(t: u32) -> Weight { (82_263_000 as Weight) // Standard Error: 0 .saturating_add((290_000 as Weight).saturating_mul(t as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn slash_tip(t: u32, ) -> Weight { + fn slash_tip(t: u32) -> Weight { (24_307_000 as Weight) // Standard Error: 0 .saturating_add((7_000 as Weight).saturating_mul(t as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_treasury.rs b/polkadot/runtime/kusama/src/weights/pallet_treasury.rs index 2f8423a055a..04512bd4724 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_treasury.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_treasury.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -53,14 +52,14 @@ impl pallet_treasury::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn approve_proposal(p: u32, ) -> Weight { + fn approve_proposal(p: u32) -> Weight { (12_321_000 as Weight) // Standard Error: 0 .saturating_add((34_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn on_initialize_proposals(p: u32, ) -> Weight { + fn on_initialize_proposals(p: u32) -> Weight { (76_361_000 as Weight) // Standard Error: 17_000 .saturating_add((60_132_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_utility.rs b/polkadot/runtime/kusama/src/weights/pallet_utility.rs index ce79e4f0a24..b7fe894b072 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_utility.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_utility.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_utility`. pub struct WeightInfo(PhantomData); impl pallet_utility::WeightInfo for WeightInfo { - fn batch(c: u32, ) -> Weight { + fn batch(c: u32) -> Weight { (15_334_000 as Weight) // Standard Error: 0 .saturating_add((2_478_000 as Weight).saturating_mul(c as Weight)) @@ -51,7 +50,7 @@ impl pallet_utility::WeightInfo for WeightInfo { fn as_derivative() -> Weight { (5_220_000 as Weight) } - fn batch_all(c: u32, ) -> Weight { + fn batch_all(c: u32) -> Weight { (16_791_000 as Weight) // Standard Error: 0 .saturating_add((3_292_000 as Weight).saturating_mul(c as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/pallet_vesting.rs b/polkadot/runtime/kusama/src/weights/pallet_vesting.rs index af97d0b84b3..f98b5148fd0 100644 --- a/polkadot/runtime/kusama/src/weights/pallet_vesting.rs +++ b/polkadot/runtime/kusama/src/weights/pallet_vesting.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,42 +42,42 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_vesting`. pub struct WeightInfo(PhantomData); impl pallet_vesting::WeightInfo for WeightInfo { - fn vest_locked(l: u32, ) -> Weight { + fn vest_locked(l: u32) -> Weight { (42_136_000 as Weight) // Standard Error: 16_000 .saturating_add((235_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn vest_unlocked(l: u32, ) -> Weight { + fn vest_unlocked(l: u32) -> Weight { (45_276_000 as Weight) // Standard Error: 10_000 .saturating_add((189_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vest_other_locked(l: u32, ) -> Weight { + fn vest_other_locked(l: u32) -> Weight { (42_030_000 as Weight) // Standard Error: 18_000 .saturating_add((243_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vest_other_unlocked(l: u32, ) -> Weight { + fn vest_other_unlocked(l: u32) -> Weight { (45_211_000 as Weight) // Standard Error: 10_000 .saturating_add((191_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn vested_transfer(l: u32, ) -> Weight { + fn vested_transfer(l: u32) -> Weight { (100_375_000 as Weight) // Standard Error: 13_000 .saturating_add((136_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn force_vested_transfer(l: u32, ) -> Weight { + fn force_vested_transfer(l: u32) -> Weight { (100_907_000 as Weight) // Standard Error: 12_000 .saturating_add((101_000 as Weight).saturating_mul(l as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs b/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs index 100719bcb10..6e81685ad71 100644 --- a/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs +++ b/polkadot/runtime/kusama/src/weights/runtime_common_auctions.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_claims.rs b/polkadot/runtime/kusama/src/weights/runtime_common_claims.rs index 2e54af89de4..9b2ea68299d 100644 --- a/polkadot/runtime/kusama/src/weights/runtime_common_claims.rs +++ b/polkadot/runtime/kusama/src/weights/runtime_common_claims.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs index a04eda47ab9..11bd36458ee 100644 --- a/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs +++ b/polkadot/runtime/kusama/src/weights/runtime_common_crowdloan.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -58,7 +57,7 @@ impl runtime_common::crowdloan::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn refund(k: u32, ) -> Weight { + fn refund(k: u32) -> Weight { (0 as Weight) // Standard Error: 21_000 .saturating_add((45_890_000 as Weight).saturating_mul(k as Weight)) @@ -87,7 +86,7 @@ impl runtime_common::crowdloan::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn on_initialize(n: u32, ) -> Weight { + fn on_initialize(n: u32) -> Weight { (0 as Weight) // Standard Error: 19_000 .saturating_add((110_004_000 as Weight).saturating_mul(n as Weight)) diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/kusama/src/weights/runtime_common_paras_registrar.rs index f0edfc18916..3ed1b730dcd 100644 --- a/polkadot/runtime/kusama/src/weights/runtime_common_paras_registrar.rs +++ b/polkadot/runtime/kusama/src/weights/runtime_common_paras_registrar.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/kusama/src/weights/runtime_common_slots.rs b/polkadot/runtime/kusama/src/weights/runtime_common_slots.rs index 591ddf724ac..07101259d10 100644 --- a/polkadot/runtime/kusama/src/weights/runtime_common_slots.rs +++ b/polkadot/runtime/kusama/src/weights/runtime_common_slots.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/kusama/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -48,7 +47,7 @@ impl runtime_common::slots::WeightInfo for WeightInfo Weight { + fn manage_lease_period_start(c: u32, t: u32) -> Weight { (0 as Weight) // Standard Error: 17_000 .saturating_add((16_401_000 as Weight).saturating_mul(c as Weight)) diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs index 609e287bc9a..4521fd590d2 100644 --- a/polkadot/runtime/parachains/src/configuration.rs +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -18,13 +18,13 @@ //! //! Configuration can change only at session boundaries and is buffered until then. -use sp_std::prelude::*; -use primitives::v1::{Balance, SessionIndex, MAX_CODE_SIZE, MAX_POV_SIZE}; -use parity_scale_codec::{Encode, Decode}; -use frame_system::pallet_prelude::*; +use crate::shared; use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; +use parity_scale_codec::{Decode, Encode}; +use primitives::v1::{Balance, SessionIndex, MAX_CODE_SIZE, MAX_POV_SIZE}; use sp_runtime::traits::Zero; -use crate::shared; +use sp_std::prelude::*; pub use pallet::*; @@ -38,7 +38,6 @@ pub struct HostConfiguration { // A parachain requested this struct can only depend on the subset of this struct. Specifically, // only a first few fields can be depended upon. These fields cannot be changed without // corresponding migration of the parachains. - /** * The parameters that are required for the parachains. */ @@ -244,8 +243,7 @@ impl HostConfiguration { if self.max_code_size > MAX_CODE_SIZE { panic!( "`max_code_size` ({}) is bigger than allowed by the client ({})", - self.max_code_size, - MAX_CODE_SIZE, + self.max_code_size, MAX_CODE_SIZE, ) } @@ -275,32 +273,23 @@ pub mod pallet { /// The active configuration for the current session. #[pallet::storage] #[pallet::getter(fn config)] - pub(crate) type ActiveConfig = StorageValue< - _, - HostConfiguration, - ValueQuery - >; + pub(crate) type ActiveConfig = + StorageValue<_, HostConfiguration, ValueQuery>; /// Pending configuration (if any) for the next session. #[pallet::storage] - pub(crate) type PendingConfig = StorageMap< - _, - Twox64Concat, - SessionIndex, - HostConfiguration - >; + pub(crate) type PendingConfig = + StorageMap<_, Twox64Concat, SessionIndex, HostConfiguration>; #[pallet::genesis_config] pub struct GenesisConfig { - pub config: HostConfiguration + pub config: HostConfiguration, } #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { - GenesisConfig { - config: Default::default() - } + GenesisConfig { config: Default::default() } } } @@ -316,7 +305,10 @@ pub mod pallet { impl Pallet { /// Set the validation upgrade frequency. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_validation_upgrade_frequency(origin: OriginFor, new: T::BlockNumber) -> DispatchResult { + pub fn set_validation_upgrade_frequency( + origin: OriginFor, + new: T::BlockNumber, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.validation_upgrade_frequency, new) != new @@ -326,7 +318,10 @@ pub mod pallet { /// Set the validation upgrade delay. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_validation_upgrade_delay(origin: OriginFor, new: T::BlockNumber) -> DispatchResult { + pub fn set_validation_upgrade_delay( + origin: OriginFor, + new: T::BlockNumber, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.validation_upgrade_delay, new) != new @@ -336,7 +331,10 @@ pub mod pallet { /// Set the acceptance period for an included candidate. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_code_retention_period(origin: OriginFor, new: T::BlockNumber) -> DispatchResult { + pub fn set_code_retention_period( + origin: OriginFor, + new: T::BlockNumber, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.code_retention_period, new) != new @@ -396,10 +394,12 @@ pub mod pallet { Ok(()) } - /// Set the parachain validator-group rotation frequency #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_group_rotation_frequency(origin: OriginFor, new: T::BlockNumber) -> DispatchResult { + pub fn set_group_rotation_frequency( + origin: OriginFor, + new: T::BlockNumber, + ) -> DispatchResult { ensure_root(origin)?; ensure!(!new.is_zero(), Error::::InvalidNewValue); @@ -412,7 +412,10 @@ pub mod pallet { /// Set the availability period for parachains. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_chain_availability_period(origin: OriginFor, new: T::BlockNumber) -> DispatchResult { + pub fn set_chain_availability_period( + origin: OriginFor, + new: T::BlockNumber, + ) -> DispatchResult { ensure_root(origin)?; ensure!(!new.is_zero(), Error::::InvalidNewValue); @@ -425,7 +428,10 @@ pub mod pallet { /// Set the availability period for parathreads. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_thread_availability_period(origin: OriginFor, new: T::BlockNumber) -> DispatchResult { + pub fn set_thread_availability_period( + origin: OriginFor, + new: T::BlockNumber, + ) -> DispatchResult { ensure_root(origin)?; ensure!(!new.is_zero(), Error::::InvalidNewValue); @@ -448,7 +454,10 @@ pub mod pallet { /// Set the maximum number of validators to assign to any core. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_max_validators_per_core(origin: OriginFor, new: Option) -> DispatchResult { + pub fn set_max_validators_per_core( + origin: OriginFor, + new: Option, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.max_validators_per_core, new) != new @@ -484,7 +493,8 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { - sp_std::mem::replace(&mut config.dispute_post_conclusion_acceptance_period, new) != new + sp_std::mem::replace(&mut config.dispute_post_conclusion_acceptance_period, new) != + new }); Ok(()) } @@ -501,9 +511,10 @@ pub mod pallet { /// Set the dispute conclusion by time out period. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_dispute_conclusion_by_time_out_period(origin: OriginFor, new: T::BlockNumber) - -> DispatchResult - { + pub fn set_dispute_conclusion_by_time_out_period( + origin: OriginFor, + new: T::BlockNumber, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.dispute_conclusion_by_time_out_period, new) != new @@ -617,7 +628,10 @@ pub mod pallet { /// Sets the maximum number of messages that a candidate can contain. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_max_upward_message_num_per_candidate(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_max_upward_message_num_per_candidate( + origin: OriginFor, + new: u32, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.max_upward_message_num_per_candidate, new) != new @@ -678,7 +692,10 @@ pub mod pallet { /// Sets the maximum number of inbound HRMP channels a parachain is allowed to accept. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_hrmp_max_parachain_inbound_channels(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_hrmp_max_parachain_inbound_channels( + origin: OriginFor, + new: u32, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.hrmp_max_parachain_inbound_channels, new) != new @@ -688,7 +705,10 @@ pub mod pallet { /// Sets the maximum number of inbound HRMP channels a parathread is allowed to accept. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_hrmp_max_parathread_inbound_channels(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_hrmp_max_parathread_inbound_channels( + origin: OriginFor, + new: u32, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.hrmp_max_parathread_inbound_channels, new) != new @@ -708,7 +728,10 @@ pub mod pallet { /// Sets the maximum number of outbound HRMP channels a parachain is allowed to open. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_hrmp_max_parachain_outbound_channels(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_hrmp_max_parachain_outbound_channels( + origin: OriginFor, + new: u32, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.hrmp_max_parachain_outbound_channels, new) != new @@ -718,7 +741,10 @@ pub mod pallet { /// Sets the maximum number of outbound HRMP channels a parathread is allowed to open. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_hrmp_max_parathread_outbound_channels(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_hrmp_max_parathread_outbound_channels( + origin: OriginFor, + new: u32, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.hrmp_max_parathread_outbound_channels, new) != new @@ -728,7 +754,10 @@ pub mod pallet { /// Sets the maximum number of outbound HRMP messages can be sent by a candidate. #[pallet::weight((1_000, DispatchClass::Operational))] - pub fn set_hrmp_max_message_num_per_candidate(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_hrmp_max_message_num_per_candidate( + origin: OriginFor, + new: u32, + ) -> DispatchResult { ensure_root(origin)?; Self::update_config_member(|config| { sp_std::mem::replace(&mut config.hrmp_max_message_num_per_candidate, new) != new @@ -745,12 +774,10 @@ impl Pallet { } /// Called by the initializer to finalize the configuration module. - pub(crate) fn initializer_finalize() { } + pub(crate) fn initializer_finalize() {} /// Called by the initializer to note that a new session has started. - pub(crate) fn initializer_on_new_session( - session_index: &SessionIndex, - ) { + pub(crate) fn initializer_on_new_session(session_index: &SessionIndex) { if let Some(pending) = ::PendingConfig::take(session_index) { ::ActiveConfig::set(pending); } @@ -773,9 +800,7 @@ impl Pallet { // duplicated code (making this function to show up in the top of heaviest functions) only for // the sake of essentially avoiding an indirect call. Doesn't worth it. #[inline(never)] - fn update_config_member( - updater: impl FnOnce(&mut HostConfiguration) -> bool, - ) { + fn update_config_member(updater: impl FnOnce(&mut HostConfiguration) -> bool) { let scheduled_session = Self::scheduled_session(); let pending = ::PendingConfig::get(scheduled_session); let mut prev = pending.unwrap_or_else(Self::config); @@ -867,138 +892,172 @@ mod tests { assert!(::PendingConfig::get(shared::SESSION_DELAY).is_none()); Configuration::set_validation_upgrade_frequency( - Origin::root(), new_config.validation_upgrade_frequency, - ).unwrap(); + Origin::root(), + new_config.validation_upgrade_frequency, + ) + .unwrap(); Configuration::set_validation_upgrade_delay( - Origin::root(), new_config.validation_upgrade_delay, - ).unwrap(); + Origin::root(), + new_config.validation_upgrade_delay, + ) + .unwrap(); Configuration::set_code_retention_period( - Origin::root(), new_config.code_retention_period, - ).unwrap(); - Configuration::set_max_code_size( - Origin::root(), new_config.max_code_size, - ).unwrap(); - Configuration::set_max_pov_size( - Origin::root(), new_config.max_pov_size, - ).unwrap(); - Configuration::set_max_head_data_size( - Origin::root(), new_config.max_head_data_size, - ).unwrap(); - Configuration::set_parathread_cores( - Origin::root(), new_config.parathread_cores, - ).unwrap(); - Configuration::set_parathread_retries( - Origin::root(), new_config.parathread_retries, - ).unwrap(); + Origin::root(), + new_config.code_retention_period, + ) + .unwrap(); + Configuration::set_max_code_size(Origin::root(), new_config.max_code_size).unwrap(); + Configuration::set_max_pov_size(Origin::root(), new_config.max_pov_size).unwrap(); + Configuration::set_max_head_data_size(Origin::root(), new_config.max_head_data_size) + .unwrap(); + Configuration::set_parathread_cores(Origin::root(), new_config.parathread_cores) + .unwrap(); + Configuration::set_parathread_retries(Origin::root(), new_config.parathread_retries) + .unwrap(); Configuration::set_group_rotation_frequency( - Origin::root(), new_config.group_rotation_frequency, - ).unwrap(); + Origin::root(), + new_config.group_rotation_frequency, + ) + .unwrap(); Configuration::set_chain_availability_period( - Origin::root(), new_config.chain_availability_period, - ).unwrap(); + Origin::root(), + new_config.chain_availability_period, + ) + .unwrap(); Configuration::set_thread_availability_period( - Origin::root(), new_config.thread_availability_period, - ).unwrap(); + Origin::root(), + new_config.thread_availability_period, + ) + .unwrap(); Configuration::set_scheduling_lookahead( - Origin::root(), new_config.scheduling_lookahead, - ).unwrap(); + Origin::root(), + new_config.scheduling_lookahead, + ) + .unwrap(); Configuration::set_max_validators_per_core( - Origin::root(), new_config.max_validators_per_core, - ).unwrap(); - Configuration::set_max_validators( - Origin::root(), new_config.max_validators, - ).unwrap(); - Configuration::set_dispute_period( - Origin::root(), new_config.dispute_period, - ).unwrap(); + Origin::root(), + new_config.max_validators_per_core, + ) + .unwrap(); + Configuration::set_max_validators(Origin::root(), new_config.max_validators).unwrap(); + Configuration::set_dispute_period(Origin::root(), new_config.dispute_period).unwrap(); Configuration::set_dispute_post_conclusion_acceptance_period( - Origin::root(), new_config.dispute_post_conclusion_acceptance_period, - ).unwrap(); + Origin::root(), + new_config.dispute_post_conclusion_acceptance_period, + ) + .unwrap(); Configuration::set_dispute_max_spam_slots( - Origin::root(), new_config.dispute_max_spam_slots, - ).unwrap(); + Origin::root(), + new_config.dispute_max_spam_slots, + ) + .unwrap(); Configuration::set_dispute_conclusion_by_time_out_period( - Origin::root(), new_config.dispute_conclusion_by_time_out_period, - ).unwrap(); - Configuration::set_no_show_slots( - Origin::root(), new_config.no_show_slots, - ).unwrap(); - Configuration::set_n_delay_tranches( - Origin::root(), new_config.n_delay_tranches, - ).unwrap(); + Origin::root(), + new_config.dispute_conclusion_by_time_out_period, + ) + .unwrap(); + Configuration::set_no_show_slots(Origin::root(), new_config.no_show_slots).unwrap(); + Configuration::set_n_delay_tranches(Origin::root(), new_config.n_delay_tranches) + .unwrap(); Configuration::set_zeroth_delay_tranche_width( - Origin::root(), new_config.zeroth_delay_tranche_width, - ).unwrap(); - Configuration::set_needed_approvals( - Origin::root(), new_config.needed_approvals, - ).unwrap(); + Origin::root(), + new_config.zeroth_delay_tranche_width, + ) + .unwrap(); + Configuration::set_needed_approvals(Origin::root(), new_config.needed_approvals) + .unwrap(); Configuration::set_relay_vrf_modulo_samples( - Origin::root(), new_config.relay_vrf_modulo_samples, - ).unwrap(); + Origin::root(), + new_config.relay_vrf_modulo_samples, + ) + .unwrap(); Configuration::set_max_upward_queue_count( - Origin::root(), new_config.max_upward_queue_count, - ).unwrap(); + Origin::root(), + new_config.max_upward_queue_count, + ) + .unwrap(); Configuration::set_max_upward_queue_size( - Origin::root(), new_config.max_upward_queue_size, - ).unwrap(); + Origin::root(), + new_config.max_upward_queue_size, + ) + .unwrap(); Configuration::set_max_downward_message_size( - Origin::root(), new_config.max_downward_message_size, - ).unwrap(); + Origin::root(), + new_config.max_downward_message_size, + ) + .unwrap(); Configuration::set_ump_service_total_weight( - Origin::root(), new_config.ump_service_total_weight, - ).unwrap(); + Origin::root(), + new_config.ump_service_total_weight, + ) + .unwrap(); Configuration::set_max_upward_message_size( - Origin::root(), new_config.max_upward_message_size, - ).unwrap(); + Origin::root(), + new_config.max_upward_message_size, + ) + .unwrap(); Configuration::set_max_upward_message_num_per_candidate( - Origin::root(), new_config.max_upward_message_num_per_candidate, - ).unwrap(); + Origin::root(), + new_config.max_upward_message_num_per_candidate, + ) + .unwrap(); Configuration::set_hrmp_open_request_ttl( Origin::root(), new_config.hrmp_open_request_ttl, - ).unwrap(); - Configuration::set_hrmp_sender_deposit( - Origin::root(), - new_config.hrmp_sender_deposit, - ).unwrap(); + ) + .unwrap(); + Configuration::set_hrmp_sender_deposit(Origin::root(), new_config.hrmp_sender_deposit) + .unwrap(); Configuration::set_hrmp_recipient_deposit( Origin::root(), new_config.hrmp_recipient_deposit, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_channel_max_capacity( Origin::root(), new_config.hrmp_channel_max_capacity, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_channel_max_total_size( Origin::root(), new_config.hrmp_channel_max_total_size, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_max_parachain_inbound_channels( Origin::root(), new_config.hrmp_max_parachain_inbound_channels, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_max_parathread_inbound_channels( Origin::root(), new_config.hrmp_max_parathread_inbound_channels, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_channel_max_message_size( Origin::root(), new_config.hrmp_channel_max_message_size, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_max_parachain_outbound_channels( Origin::root(), new_config.hrmp_max_parachain_outbound_channels, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_max_parathread_outbound_channels( Origin::root(), new_config.hrmp_max_parathread_outbound_channels, - ).unwrap(); + ) + .unwrap(); Configuration::set_hrmp_max_message_num_per_candidate( Origin::root(), new_config.hrmp_max_message_num_per_candidate, - ).unwrap(); + ) + .unwrap(); - assert_eq!(::PendingConfig::get(shared::SESSION_DELAY), Some(new_config)); + assert_eq!( + ::PendingConfig::get(shared::SESSION_DELAY), + Some(new_config) + ); }) } @@ -1012,7 +1071,8 @@ mod tests { #[test] fn setting_config_to_same_as_current_is_noop() { new_test_ext(Default::default()).execute_with(|| { - Configuration::set_validation_upgrade_delay(Origin::root(), Default::default()).unwrap(); + Configuration::set_validation_upgrade_delay(Origin::root(), Default::default()) + .unwrap(); assert!(::PendingConfig::get(shared::SESSION_DELAY).is_none()) }); } diff --git a/polkadot/runtime/parachains/src/disputes.rs b/polkadot/runtime/parachains/src/disputes.rs index ea813d67336..a685910514b 100644 --- a/polkadot/runtime/parachains/src/disputes.rs +++ b/polkadot/runtime/parachains/src/disputes.rs @@ -16,8 +16,14 @@ //! Runtime component for handling disputes of parachain candidates. -use sp_std::prelude::*; -use sp_std::collections::btree_set::BTreeSet; +use crate::{ + configuration::{self, HostConfiguration}, + initializer::SessionChangeNotification, + session_info, +}; +use bitvec::{bitvec, order::Lsb0 as BitOrderLsb0}; +use frame_support::{ensure, traits::Get, weights::Weight}; +use parity_scale_codec::{Decode, Encode}; use primitives::v1::{ byzantine_threshold, supermajority_threshold, ApprovalVote, CandidateHash, CompactStatement, ConsensusLog, DisputeState, DisputeStatement, DisputeStatementSet, ExplicitDisputeStatement, @@ -25,17 +31,10 @@ use primitives::v1::{ ValidDisputeStatementKind, ValidatorId, ValidatorIndex, ValidatorSignature, }; use sp_runtime::{ - traits::{One, Zero, Saturating, AppVerify}, + traits::{AppVerify, One, Saturating, Zero}, DispatchError, RuntimeDebug, SaturatedConversion, }; -use frame_support::{ensure, traits::Get, weights::Weight}; -use parity_scale_codec::{Encode, Decode}; -use bitvec::{bitvec, order::Lsb0 as BitOrderLsb0}; -use crate::{ - configuration::{self, HostConfiguration}, - initializer::SessionChangeNotification, - session_info, -}; +use sp_std::{collections::btree_set::BTreeSet, prelude::*}; /// Whether the dispute is local or remote. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] @@ -54,40 +53,46 @@ pub enum DisputeResult { /// Reward hooks for disputes. pub trait RewardValidators { // Give each validator a reward, likely small, for participating in the dispute. - fn reward_dispute_statement(session: SessionIndex, validators: impl IntoIterator); + fn reward_dispute_statement( + session: SessionIndex, + validators: impl IntoIterator, + ); } impl RewardValidators for () { - fn reward_dispute_statement(_: SessionIndex, _: impl IntoIterator) { } + fn reward_dispute_statement(_: SessionIndex, _: impl IntoIterator) {} } /// Punishment hooks for disputes. pub trait PunishValidators { /// Punish a series of validators who were for an invalid parablock. This is expected to be a major /// punishment. - fn punish_for_invalid(session: SessionIndex, validators: impl IntoIterator); + fn punish_for_invalid( + session: SessionIndex, + validators: impl IntoIterator, + ); /// Punish a series of validators who were against a valid parablock. This is expected to be a minor /// punishment. - fn punish_against_valid(session: SessionIndex, validators: impl IntoIterator); + fn punish_against_valid( + session: SessionIndex, + validators: impl IntoIterator, + ); /// Punish a series of validators who were part of a dispute which never concluded. This is expected /// to be a minor punishment. - fn punish_inconclusive(session: SessionIndex, validators: impl IntoIterator); + fn punish_inconclusive( + session: SessionIndex, + validators: impl IntoIterator, + ); } impl PunishValidators for () { - fn punish_for_invalid(_: SessionIndex, _: impl IntoIterator) { + fn punish_for_invalid(_: SessionIndex, _: impl IntoIterator) {} - } - - fn punish_against_valid(_: SessionIndex, _: impl IntoIterator) { + fn punish_against_valid(_: SessionIndex, _: impl IntoIterator) {} - } - - fn punish_inconclusive(_: SessionIndex, _: impl IntoIterator) { - - } + fn punish_inconclusive(_: SessionIndex, _: impl IntoIterator) {} } /// Hook into disputes handling. @@ -151,7 +156,6 @@ impl DisputesHandler for () { _candidate_hash: CandidateHash, _included_in: BlockNumber, ) { - } fn could_be_invalid(_session: SessionIndex, _candidate_hash: CandidateHash) -> bool { @@ -162,13 +166,9 @@ impl DisputesHandler for () { 0 } - fn initializer_finalize() { - - } - - fn initializer_on_new_session(_notification: &SessionChangeNotification) { + fn initializer_finalize() {} - } + fn initializer_on_new_session(_notification: &SessionChangeNotification) {} } impl DisputesHandler for pallet::Pallet { @@ -214,15 +214,11 @@ impl DisputesHandler for pallet::Pallet { pub use pallet::*; #[frame_support::pallet] pub mod pallet { - use frame_support::pallet_prelude::*; use super::*; + use frame_support::pallet_prelude::*; #[pallet::config] - pub trait Config: - frame_system::Config + - configuration::Config + - session_info::Config - { + pub trait Config: frame_system::Config + configuration::Config + session_info::Config { type Event: From> + IsType<::Event>; type RewardValidators: RewardValidators; type PunishValidators: PunishValidators; @@ -240,8 +236,10 @@ pub mod pallet { #[pallet::storage] pub(super) type Disputes = StorageDoubleMap< _, - Twox64Concat, SessionIndex, - Blake2_128Concat, CandidateHash, + Twox64Concat, + SessionIndex, + Blake2_128Concat, + CandidateHash, DisputeState, >; @@ -250,8 +248,10 @@ pub mod pallet { #[pallet::storage] pub(super) type Included = StorageDoubleMap< _, - Twox64Concat, SessionIndex, - Blake2_128Concat, CandidateHash, + Twox64Concat, + SessionIndex, + Blake2_128Concat, + CandidateHash, T::BlockNumber, >; @@ -269,7 +269,7 @@ pub mod pallet { /// It can only be set back to `None` by governance intervention. #[pallet::storage] #[pallet::getter(fn last_valid_block)] - pub(super) type Frozen = StorageValue<_, Option, ValueQuery>; + pub(super) type Frozen = StorageValue<_, Option, ValueQuery>; #[pallet::event] #[pallet::generate_deposit(pub fn deposit_event)] @@ -316,9 +316,7 @@ bitflags::bitflags! { } impl DisputeStateFlags { - fn from_state( - state: &DisputeState, - ) -> Self { + fn from_state(state: &DisputeState) -> Self { let n = state.validators_for.len(); let byzantine_threshold = byzantine_threshold(n); @@ -390,24 +388,14 @@ struct DisputeStateImporter { } impl DisputeStateImporter { - fn new( - state: DisputeState, - now: BlockNumber, - ) -> Self { + fn new(state: DisputeState, now: BlockNumber) -> Self { let pre_flags = DisputeStateFlags::from_state(&state); let new_participants = bitvec::bitvec![BitOrderLsb0, u8; 0; state.validators_for.len()]; - DisputeStateImporter { - state, - now, - new_participants, - pre_flags, - } + DisputeStateImporter { state, now, new_participants, pre_flags } } - fn import(&mut self, validator: ValidatorIndex, valid: bool) - -> Result<(), VoteImportError> - { + fn import(&mut self, validator: ValidatorIndex, valid: bool) -> Result<(), VoteImportError> { let (bits, other_bits) = if valid { (&mut self.state.validators_for, &mut self.state.validators_against) } else { @@ -418,12 +406,12 @@ impl DisputeStateImporter { match bits.get(validator.0 as usize).map(|b| *b) { None => return Err(VoteImportError::ValidatorIndexOutOfBounds), Some(true) => return Err(VoteImportError::DuplicateStatement), - Some(false) => {} + Some(false) => {}, } // inefficient, and just for extra sanity. if validator.0 as usize >= self.new_participants.len() { - return Err(VoteImportError::ValidatorIndexOutOfBounds); + return Err(VoteImportError::ValidatorIndexOutOfBounds) } bits.set(validator.0 as usize, true); @@ -448,10 +436,11 @@ impl DisputeStateImporter { let spam_slot_changes: Vec<_> = match pre_post_contains(DisputeStateFlags::CONFIRMED) { (false, false) => { // increment spam slots for all new participants. - self.new_participants.iter_ones() + self.new_participants + .iter_ones() .map(|i| (ValidatorIndex(i as _), SpamSlotChange::Inc)) .collect() - } + }, (false, true) => { let prev_participants = { // all participants @@ -464,43 +453,46 @@ impl DisputeStateImporter { a }; - prev_participants.iter_ones() + prev_participants + .iter_ones() .map(|i| (ValidatorIndex(i as _), SpamSlotChange::Dec)) .collect() - } + }, (true, true) | (true, false) => { // nothing to do. (true, false) is also impossible. Vec::new() - } + }, }; // 2. Check for fresh FOR supermajority. Only if not already concluded. - let slash_against = if let (false, true) = pre_post_contains(DisputeStateFlags::FOR_SUPERMAJORITY) { - if self.state.concluded_at.is_none() { - self.state.concluded_at = Some(self.now.clone()); - } + let slash_against = + if let (false, true) = pre_post_contains(DisputeStateFlags::FOR_SUPERMAJORITY) { + if self.state.concluded_at.is_none() { + self.state.concluded_at = Some(self.now.clone()); + } - // provide AGAINST voters to slash. - self.state.validators_against.iter_ones() - .map(|i| ValidatorIndex(i as _)) - .collect() - } else { - Vec::new() - }; + // provide AGAINST voters to slash. + self.state + .validators_against + .iter_ones() + .map(|i| ValidatorIndex(i as _)) + .collect() + } else { + Vec::new() + }; // 3. Check for fresh AGAINST supermajority. - let slash_for = if let (false, true) = pre_post_contains(DisputeStateFlags::AGAINST_SUPERMAJORITY) { - if self.state.concluded_at.is_none() { - self.state.concluded_at = Some(self.now.clone()); - } + let slash_for = + if let (false, true) = pre_post_contains(DisputeStateFlags::AGAINST_SUPERMAJORITY) { + if self.state.concluded_at.is_none() { + self.state.concluded_at = Some(self.now.clone()); + } - // provide FOR voters to slash. - self.state.validators_for.iter_ones() - .map(|i| ValidatorIndex(i as _)) - .collect() - } else { - Vec::new() - }; + // provide FOR voters to slash. + self.state.validators_for.iter_ones().map(|i| ValidatorIndex(i as _)).collect() + } else { + Vec::new() + }; ImportSummary { state: self.state, @@ -524,9 +516,10 @@ enum StatementSetFilter { } impl StatementSetFilter { - fn filter_statement_set(self, mut statement_set: DisputeStatementSet) - -> Option - { + fn filter_statement_set( + self, + mut statement_set: DisputeStatementSet, + ) -> Option { match self { StatementSetFilter::RemoveAll => None, StatementSetFilter::RemoveIndices(mut indices) => { @@ -544,7 +537,7 @@ impl StatementSetFilter { } else { Some(statement_set) } - } + }, } } @@ -564,8 +557,8 @@ impl Pallet { for (session_index, candidate_hash, mut dispute) in >::iter() { weight += T::DbWeight::get().reads_writes(1, 0); - if dispute.concluded_at.is_none() - && dispute.start + config.dispute_conclusion_by_time_out_period < now + if dispute.concluded_at.is_none() && + dispute.start + config.dispute_conclusion_by_time_out_period < now { Self::deposit_event(Event::DisputeTimedOut(candidate_hash)); @@ -576,7 +569,7 @@ impl Pallet { // Local disputes don't count towards spam. weight += T::DbWeight::get().reads_writes(1, 1); - continue; + continue } // mildly punish all validators involved. they've failed to make @@ -612,10 +605,12 @@ impl Pallet { } /// Called by the initializer to finalize the disputes module. - pub(crate) fn initializer_finalize() { } + pub(crate) fn initializer_finalize() {} /// Called by the initializer to note a new session in the disputes module. - pub(crate) fn initializer_on_new_session(notification: &SessionChangeNotification) { + pub(crate) fn initializer_on_new_session( + notification: &SessionChangeNotification, + ) { let config = >::config(); if notification.session_index <= config.dispute_period + 1 { @@ -626,9 +621,9 @@ impl Pallet { LastPrunedSession::::mutate(|last_pruned| { let to_prune = if let Some(last_pruned) = last_pruned { - *last_pruned + 1 ..= pruning_target + *last_pruned + 1..=pruning_target } else { - pruning_target ..= pruning_target + pruning_target..=pruning_target }; for to_prune in to_prune { @@ -653,16 +648,15 @@ impl Pallet { /// This functions modifies the state when failing. It is expected to be called in inherent, /// and to fail the extrinsic on error. As invalid inherents are not allowed, the dirty state /// is not commited. - pub(crate) fn provide_multi_dispute_data(statement_sets: MultiDisputeStatementSet) - -> Result, DispatchError> - { + pub(crate) fn provide_multi_dispute_data( + statement_sets: MultiDisputeStatementSet, + ) -> Result, DispatchError> { let config = >::config(); // Deduplicate. { - let mut targets: Vec<_> = statement_sets.iter() - .map(|set| (set.candidate_hash.0, set.session)) - .collect(); + let mut targets: Vec<_> = + statement_sets.iter().map(|set| (set.candidate_hash.0, set.session)).collect(); targets.sort(); @@ -697,11 +691,13 @@ impl Pallet { }) }; - *statement_sets = dedup_iter.filter_map(|set| { - let filter = Self::filter_dispute_data(&config, &set); + *statement_sets = dedup_iter + .filter_map(|set| { + let filter = Self::filter_dispute_data(&config, &set); - filter.filter_statement_set(set) - }).collect(); + filter.filter_statement_set(set) + }) + .collect(); } // Given a statement set, this produces a filter to be applied to the statement set. @@ -709,9 +705,10 @@ impl Pallet { // // Votes which are duplicate or already known by the chain are filtered out. // The entire set is removed if the dispute is ancient or concluded. - fn filter_dispute_data(config: &HostConfiguration, set: &DisputeStatementSet) - -> StatementSetFilter - { + fn filter_dispute_data( + config: &HostConfiguration, + set: &DisputeStatementSet, + ) -> StatementSetFilter { let mut filter = StatementSetFilter::RemoveIndices(Vec::new()); // Dispute statement sets on any dispute which concluded @@ -731,7 +728,7 @@ impl Pallet { let dispute_state = { if let Some(dispute_state) = >::get(&set.session, &set.candidate_hash) { if dispute_state.concluded_at.as_ref().map_or(false, |c| c < &oldest_accepted) { - return StatementSetFilter::RemoveAll; + return StatementSetFilter::RemoveAll } dispute_state @@ -748,16 +745,13 @@ impl Pallet { // Check and import all votes. let summary = { let mut importer = DisputeStateImporter::new(dispute_state, now); - for (i, (statement, validator_index, signature)) - in set.statements.iter().enumerate() - { - let validator_public = match session_info - .validators.get(validator_index.0 as usize) + for (i, (statement, validator_index, signature)) in set.statements.iter().enumerate() { + let validator_public = match session_info.validators.get(validator_index.0 as usize) { None => { filter.remove_index(i); continue - } + }, Some(v) => v, }; @@ -795,21 +789,25 @@ impl Pallet { // Apply spam slot changes. Bail early if too many occupied. let is_local = >::contains_key(&set.session, &set.candidate_hash); if !is_local { - let mut spam_slots: Vec = SpamSlots::::get(&set.session) - .unwrap_or_else(|| vec![0; n_validators]); + let mut spam_slots: Vec = + SpamSlots::::get(&set.session).unwrap_or_else(|| vec![0; n_validators]); for (validator_index, spam_slot_change) in summary.spam_slot_changes { - let spam_slot = spam_slots.get_mut(validator_index.0 as usize) + let spam_slot = spam_slots + .get_mut(validator_index.0 as usize) .expect("index is in-bounds, as checked above; qed"); if let SpamSlotChange::Inc = spam_slot_change { if *spam_slot >= config.dispute_max_spam_slots { // Find the vote by this validator and filter it out. - let first_index_in_set = set.statements + let first_index_in_set = set + .statements .iter() .position(|(_, v_i, _)| &validator_index == v_i) - .expect("spam slots are only incremented when a new statement \ - from a validator is included; qed"); + .expect( + "spam slots are only incremented when a new statement \ + from a validator is included; qed", + ); // Note that there may be many votes by the validator in the statement // set. There are not supposed to be, but the purpose of this function @@ -854,9 +852,10 @@ impl Pallet { /// /// Fails if the dispute data is invalid. Returns a boolean indicating whether the /// dispute is fresh. - fn provide_dispute_data(config: &HostConfiguration, set: DisputeStatementSet) - -> Result - { + fn provide_dispute_data( + config: &HostConfiguration, + set: DisputeStatementSet, + ) -> Result { // Dispute statement sets on any dispute which concluded // before this point are to be rejected. let now = >::block_number(); @@ -887,7 +886,7 @@ impl Pallet { validators_against: bitvec![BitOrderLsb0, u8; 0; n_validators], start: now, concluded_at: None, - } + }, ) } }; @@ -896,7 +895,9 @@ impl Pallet { let summary = { let mut importer = DisputeStateImporter::new(dispute_state, now); for (statement, validator_index, signature) in &set.statements { - let validator_public = session_info.validators.get(validator_index.0 as usize) + let validator_public = session_info + .validators + .get(validator_index.0 as usize) .ok_or(Error::::ValidatorIndexOutOfBounds)?; // Check signature before importing. @@ -906,7 +907,8 @@ impl Pallet { set.session, statement, signature, - ).map_err(|()| Error::::InvalidSignature)?; + ) + .map_err(|()| Error::::InvalidSignature)?; let valid = statement.indicates_validity(); @@ -919,11 +921,12 @@ impl Pallet { // Apply spam slot changes. Bail early if too many occupied. let is_local = >::contains_key(&set.session, &set.candidate_hash); if !is_local { - let mut spam_slots: Vec = SpamSlots::::get(&set.session) - .unwrap_or_else(|| vec![0; n_validators]); + let mut spam_slots: Vec = + SpamSlots::::get(&set.session).unwrap_or_else(|| vec![0; n_validators]); for (validator_index, spam_slot_change) in summary.spam_slot_changes { - let spam_slot = spam_slots.get_mut(validator_index.0 as usize) + let spam_slot = spam_slots + .get_mut(validator_index.0 as usize) .expect("index is in-bounds, as checked above; qed"); match spam_slot_change { @@ -934,10 +937,10 @@ impl Pallet { ); *spam_slot += 1; - } + }, SpamSlotChange::Dec => { *spam_slot = spam_slot.saturating_sub(1); - } + }, } } @@ -980,16 +983,10 @@ impl Pallet { // Slash participants on a losing side. { // a valid candidate, according to 2/3. Punish those on the 'against' side. - T::PunishValidators::punish_against_valid( - set.session, - summary.slash_against, - ); + T::PunishValidators::punish_against_valid(set.session, summary.slash_against); // an invalid candidate, according to 2/3. Punish those on the 'for' side. - T::PunishValidators::punish_for_invalid( - set.session, - summary.slash_for, - ); + T::PunishValidators::punish_for_invalid(set.session, summary.slash_for); } >::insert(&set.session, &set.candidate_hash, &summary.state); @@ -1009,8 +1006,14 @@ impl Pallet { >::iter().collect() } - pub(crate) fn note_included(session: SessionIndex, candidate_hash: CandidateHash, included_in: T::BlockNumber) { - if included_in.is_zero() { return } + pub(crate) fn note_included( + session: SessionIndex, + candidate_hash: CandidateHash, + included_in: T::BlockNumber, + ) { + if included_in.is_zero() { + return + } let revert_to = included_in - One::one(); @@ -1089,38 +1092,25 @@ fn check_signature( validator_signature: &ValidatorSignature, ) -> Result<(), ()> { let payload = match *statement { - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) => { - ExplicitDisputeStatement { - valid: true, - candidate_hash, - session, - }.signing_payload() - }, - DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded(inclusion_parent)) => { + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: true, candidate_hash, session }.signing_payload(), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded(inclusion_parent)) => CompactStatement::Seconded(candidate_hash).signing_payload(&SigningContext { session_index: session, parent_hash: inclusion_parent, - }) - }, - DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)) => { + }), + DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid(inclusion_parent)) => CompactStatement::Valid(candidate_hash).signing_payload(&SigningContext { session_index: session, parent_hash: inclusion_parent, - }) - }, - DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) => { - ApprovalVote(candidate_hash).signing_payload(session) - }, - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) => { - ExplicitDisputeStatement { - valid: false, - candidate_hash, - session, - }.signing_payload() - }, + }), + DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking) => + ApprovalVote(candidate_hash).signing_payload(session), + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit) => + ExplicitDisputeStatement { valid: false, candidate_hash, session }.signing_payload(), }; - if validator_signature.verify(&payload[..] , &validator_public) { + if validator_signature.verify(&payload[..], &validator_public) { Ok(()) } else { Err(()) @@ -1130,18 +1120,26 @@ fn check_signature( #[cfg(test)] mod tests { use super::*; - use frame_system::InitKind; - use frame_support::{assert_ok, assert_err, assert_noop, traits::{OnInitialize, OnFinalize}}; use crate::mock::{ - new_test_ext, Test, System, AllPallets, Initializer, AccountId, MockGenesisConfig, - REWARD_VALIDATORS, PUNISH_VALIDATORS_FOR, PUNISH_VALIDATORS_AGAINST, - PUNISH_VALIDATORS_INCONCLUSIVE, + new_test_ext, AccountId, AllPallets, Initializer, MockGenesisConfig, System, Test, + PUNISH_VALIDATORS_AGAINST, PUNISH_VALIDATORS_FOR, PUNISH_VALIDATORS_INCONCLUSIVE, + REWARD_VALIDATORS, + }; + use frame_support::{ + assert_err, assert_noop, assert_ok, + traits::{OnFinalize, OnInitialize}, }; - use sp_core::{Pair, crypto::CryptoType}; + use frame_system::InitKind; use primitives::v1::BlockNumber; + use sp_core::{crypto::CryptoType, Pair}; // All arguments for `initializer::on_new_session` - type NewSession<'a> = (bool, SessionIndex, Vec<(&'a AccountId, ValidatorId)>, Option>); + type NewSession<'a> = ( + bool, + SessionIndex, + Vec<(&'a AccountId, ValidatorId)>, + Option>, + ); // Run to specific block, while calling disputes pallet hooks manually, because disputes is not // integrated in initializer yet. @@ -1220,23 +1218,14 @@ mod tests { VoteImportError::ValidatorIndexOutOfBounds, ); - assert_err!( - importer.import(ValidatorIndex(0), true), - VoteImportError::DuplicateStatement, - ); + assert_err!(importer.import(ValidatorIndex(0), true), VoteImportError::DuplicateStatement,); assert_ok!(importer.import(ValidatorIndex(0), false)); assert_ok!(importer.import(ValidatorIndex(2), true)); - assert_err!( - importer.import(ValidatorIndex(2), true), - VoteImportError::DuplicateStatement, - ); + assert_err!(importer.import(ValidatorIndex(2), true), VoteImportError::DuplicateStatement,); assert_ok!(importer.import(ValidatorIndex(2), false)); - assert_err!( - importer.import(ValidatorIndex(2), false), - VoteImportError::DuplicateStatement, - ); + assert_err!(importer.import(ValidatorIndex(2), false), VoteImportError::DuplicateStatement,); let summary = importer.finish(); assert_eq!(summary.new_flags, DisputeStateFlags::default()); @@ -1249,10 +1238,7 @@ mod tests { concluded_at: None, }, ); - assert_eq!( - summary.spam_slot_changes, - vec![(ValidatorIndex(2), SpamSlotChange::Inc)], - ); + assert_eq!(summary.spam_slot_changes, vec![(ValidatorIndex(2), SpamSlotChange::Inc)],); assert!(summary.slash_for.is_empty()); assert!(summary.slash_against.is_empty()); assert_eq!(summary.new_participants, bitvec![BitOrderLsb0, u8; 0, 0, 1, 0, 0, 0, 0, 0]); @@ -1385,11 +1371,11 @@ mod tests { configuration: crate::configuration::GenesisConfig { config: HostConfiguration { dispute_conclusion_by_time_out_period, - .. Default::default() + ..Default::default() }, - .. Default::default() + ..Default::default() }, - .. Default::default() + ..Default::default() }; new_test_ext(mock_genesis_config).execute_with(|| { @@ -1403,41 +1389,45 @@ mod tests { // NOTE: v2 index will be 2 // NOTE: v3 index will be 1 - run_to_block( - start, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())], - Some(vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())]), - )) - } - ); + run_to_block(start, |b| { + // a new session at each block + Some(( + true, + b, + vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ]), + )) + }); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); // v0 votes for 3 - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: start - 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - v0.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: start - 1, - }.signing_payload() - ) - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: start - 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: start - 1, + } + .signing_payload(), + ), + )], + }]; assert_ok!( Pallet::::provide_multi_dispute_data(stmts), @@ -1466,13 +1456,10 @@ mod tests { let mock_genesis_config = MockGenesisConfig { configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - dispute_period, - .. Default::default() - }, - .. Default::default() + config: HostConfiguration { dispute_period, ..Default::default() }, + ..Default::default() }, - .. Default::default() + ..Default::default() }; new_test_ext(mock_genesis_config).execute_with(|| { @@ -1487,18 +1474,10 @@ mod tests { Pallet::::note_included(5, candidate_hash.clone(), 5); Pallet::::note_included(6, candidate_hash.clone(), 5); - run_to_block( - 7, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } - ); + run_to_block(7, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); // current session is 7, // we keep for dispute_period + 1 session and we remove in on_finalize @@ -1553,49 +1532,32 @@ mod tests { let v0 = ::Pair::generate().0; let v1 = ::Pair::generate().0; - run_to_block( - 3, - |b| { - // a new session at each block - if b == 1 { - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } else { - Some(( - true, - b, - vec![(&1, v1.public())], - Some(vec![(&1, v1.public())]), - )) - } + run_to_block(3, |b| { + // a new session at each block + if b == 1 { + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + } else { + Some((true, b, vec![(&1, v1.public())], Some(vec![(&1, v1.public())]))) } - ); - + }); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - v0.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: 1, - }.signing_payload() - ), - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: 1, + } + .signing_payload(), + ), + )], + }]; assert_ok!( Pallet::::provide_multi_dispute_data(stmts), @@ -1603,25 +1565,22 @@ mod tests { ); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 2, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - v0.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: 2, - }.signing_payload() - ), - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 2, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: 2, + } + .signing_payload(), + ), + )], + }]; assert_noop!( Pallet::::provide_multi_dispute_data(stmts), @@ -1635,41 +1594,30 @@ mod tests { new_test_ext(Default::default()).execute_with(|| { let v0 = ::Pair::generate().0; - run_to_block( - 6, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } - ); + run_to_block(6, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); // v0 votes for 3 - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 3, - statements: vec![ - ( - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), - ValidatorIndex(0), - v0.sign( - &ExplicitDisputeStatement { - valid: false, - candidate_hash: candidate_hash.clone(), - session: 3, - }.signing_payload() - ) - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 3, + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { + valid: false, + candidate_hash: candidate_hash.clone(), + session: 3, + } + .signing_payload(), + ), + )], + }]; assert!(Pallet::::provide_multi_dispute_data(stmts).is_ok()); Pallet::::note_included(3, candidate_hash.clone(), 3); @@ -1682,43 +1630,32 @@ mod tests { new_test_ext(Default::default()).execute_with(|| { let v0 = ::Pair::generate().0; - run_to_block( - 6, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } - ); + run_to_block(6, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); Pallet::::note_included(3, candidate_hash.clone(), 3); // v0 votes for 3 - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 3, - statements: vec![ - ( - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), - ValidatorIndex(0), - v0.sign( - &ExplicitDisputeStatement { - valid: false, - candidate_hash: candidate_hash.clone(), - session: 3, - }.signing_payload() - ) - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 3, + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { + valid: false, + candidate_hash: candidate_hash.clone(), + session: 3, + } + .signing_payload(), + ), + )], + }]; assert!(Pallet::::provide_multi_dispute_data(stmts).is_ok()); assert_eq!(Frozen::::get(), Some(2)); @@ -1745,41 +1682,45 @@ mod tests { // NOTE: v2 index will be 2 // NOTE: v3 index will be 1 - run_to_block( - 6, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())], - Some(vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())]), - )) - } - ); + run_to_block(6, |b| { + // a new session at each block + Some(( + true, + b, + vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ]), + )) + }); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); // v0 votes for 3 - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 3, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - v0.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: 3, - }.signing_payload() - ) - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 3, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: 3, + } + .signing_payload(), + ), + )], + }]; assert_ok!( Pallet::::provide_multi_dispute_data(stmts), @@ -1792,36 +1733,34 @@ mod tests { DisputeStatementSet { candidate_hash: candidate_hash.clone(), session: 4, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(3), - v1.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: 4, - }.signing_payload() - ) + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(3), + v1.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: 4, + } + .signing_payload(), ), - ], + )], }, DisputeStatementSet { candidate_hash: candidate_hash.clone(), session: 3, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(3), - v1.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: 3, - }.signing_payload() - ), + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(3), + v1.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: 3, + } + .signing_payload(), ), - ], + )], }, ]; @@ -1837,36 +1776,34 @@ mod tests { DisputeStatementSet { candidate_hash: candidate_hash.clone(), session: 3, - statements: vec![ - ( - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), - ValidatorIndex(1), - v3.sign( - &ExplicitDisputeStatement { - valid: false, - candidate_hash: candidate_hash.clone(), - session: 3, - }.signing_payload() - ), + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v3.sign( + &ExplicitDisputeStatement { + valid: false, + candidate_hash: candidate_hash.clone(), + session: 3, + } + .signing_payload(), ), - ], + )], }, DisputeStatementSet { candidate_hash: candidate_hash.clone(), session: 5, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(1), - v3.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: 5, - }.signing_payload() - ), + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(1), + v3.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: 5, + } + .signing_payload(), ), - ], + )], }, ]; assert_ok!( @@ -1882,36 +1819,34 @@ mod tests { DisputeStatementSet { candidate_hash: candidate_hash.clone(), session: 3, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(2), - v2.sign( - &ExplicitDisputeStatement { - valid: true, - candidate_hash: candidate_hash.clone(), - session: 3, - }.signing_payload() - ) + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(2), + v2.sign( + &ExplicitDisputeStatement { + valid: true, + candidate_hash: candidate_hash.clone(), + session: 3, + } + .signing_payload(), ), - ], + )], }, DisputeStatementSet { candidate_hash: candidate_hash.clone(), session: 5, - statements: vec![ - ( - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), - ValidatorIndex(2), - v2.sign( - &ExplicitDisputeStatement { - valid: false, - candidate_hash: candidate_hash.clone(), - session: 5, - }.signing_payload() - ), + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(2), + v2.sign( + &ExplicitDisputeStatement { + valid: false, + candidate_hash: candidate_hash.clone(), + session: 5, + } + .signing_payload(), ), - ], + )], }, ]; assert_ok!(Pallet::::provide_multi_dispute_data(stmts), vec![]); @@ -1920,25 +1855,22 @@ mod tests { assert_eq!(SpamSlots::::get(5), Some(vec![0, 0, 0, 0])); // v0 votes for 5 - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 5, - statements: vec![ - ( - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), - ValidatorIndex(0), - v0.sign( - &ExplicitDisputeStatement { - valid: false, - candidate_hash: candidate_hash.clone(), - session: 5, - }.signing_payload() - ), - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 5, + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + v0.sign( + &ExplicitDisputeStatement { + valid: false, + candidate_hash: candidate_hash.clone(), + session: 5, + } + .signing_payload(), + ), + )], + }]; assert_ok!(Pallet::::provide_multi_dispute_data(stmts), vec![]); assert_eq!(SpamSlots::::get(3), Some(vec![0, 0, 0, 0])); @@ -1946,30 +1878,24 @@ mod tests { assert_eq!(SpamSlots::::get(5), Some(vec![0, 0, 0, 0])); // v1 votes for 5 - let stmts = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 5, - statements: vec![ - ( - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), - ValidatorIndex(3), - v1.sign( - &ExplicitDisputeStatement { - valid: false, - candidate_hash: candidate_hash.clone(), - session: 5, - }.signing_payload() - ) - ), - ], - }, - ]; + let stmts = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 5, + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(3), + v1.sign( + &ExplicitDisputeStatement { + valid: false, + candidate_hash: candidate_hash.clone(), + session: 5, + } + .signing_payload(), + ), + )], + }]; - assert_ok!( - Pallet::::provide_multi_dispute_data(stmts), - vec![], - ); + assert_ok!(Pallet::::provide_multi_dispute_data(stmts), vec![],); assert_eq!(SpamSlots::::get(3), Some(vec![0, 0, 0, 0])); assert_eq!(SpamSlots::::get(4), Some(vec![0, 0, 0, 1])); assert_eq!(SpamSlots::::get(5), Some(vec![0, 0, 0, 0])); @@ -2187,18 +2113,18 @@ mod tests { let wrong_inclusion_parent = sp_core::H256::repeat_byte(4); let statement_1 = DisputeStatement::Valid(ValidDisputeStatementKind::Explicit); - let statement_2 = DisputeStatement::Valid( - ValidDisputeStatementKind::BackingSeconded(inclusion_parent.clone()) - ); + let statement_2 = DisputeStatement::Valid(ValidDisputeStatementKind::BackingSeconded( + inclusion_parent.clone(), + )); let wrong_statement_2 = DisputeStatement::Valid( - ValidDisputeStatementKind::BackingSeconded(wrong_inclusion_parent.clone()) - ); - let statement_3 = DisputeStatement::Valid( - ValidDisputeStatementKind::BackingValid(inclusion_parent.clone()) - ); - let wrong_statement_3 = DisputeStatement::Valid( - ValidDisputeStatementKind::BackingValid(wrong_inclusion_parent.clone()) + ValidDisputeStatementKind::BackingSeconded(wrong_inclusion_parent.clone()), ); + let statement_3 = DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + inclusion_parent.clone(), + )); + let wrong_statement_3 = DisputeStatement::Valid(ValidDisputeStatementKind::BackingValid( + wrong_inclusion_parent.clone(), + )); let statement_4 = DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking); let statement_5 = DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit); @@ -2207,79 +2133,368 @@ mod tests { valid: true, candidate_hash: candidate_hash.clone(), session, - }.signing_payload() - ); - let signed_2 = validator_id.sign( - &CompactStatement::Seconded(candidate_hash.clone()) - .signing_payload(&SigningContext { - session_index: session, - parent_hash: inclusion_parent.clone() - }) - ); - let signed_3 = validator_id.sign( - &CompactStatement::Valid(candidate_hash.clone()) - .signing_payload(&SigningContext { - session_index: session, - parent_hash: inclusion_parent.clone() - }) - ); - let signed_4 = validator_id.sign( - &ApprovalVote(candidate_hash.clone()).signing_payload(session) + } + .signing_payload(), ); + let signed_2 = + validator_id.sign(&CompactStatement::Seconded(candidate_hash.clone()).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent.clone() }, + )); + let signed_3 = + validator_id.sign(&CompactStatement::Valid(candidate_hash.clone()).signing_payload( + &SigningContext { session_index: session, parent_hash: inclusion_parent.clone() }, + )); + let signed_4 = + validator_id.sign(&ApprovalVote(candidate_hash.clone()).signing_payload(session)); let signed_5 = validator_id.sign( &ExplicitDisputeStatement { valid: false, candidate_hash: candidate_hash.clone(), session, - }.signing_payload() + } + .signing_payload(), ); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_1, &signed_1).is_ok()); - assert!(check_signature(&wrong_validator_id.public(), candidate_hash, session, &statement_1, &signed_1).is_err()); - assert!(check_signature(&validator_id.public(), wrong_candidate_hash, session, &statement_1, &signed_1).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, wrong_session, &statement_1, &signed_1).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_2, &signed_1).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_3, &signed_1).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_4, &signed_1).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_5, &signed_1).is_err()); - - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_2, &signed_2).is_ok()); - assert!(check_signature(&wrong_validator_id.public(), candidate_hash, session, &statement_2, &signed_2).is_err()); - assert!(check_signature(&validator_id.public(), wrong_candidate_hash, session, &statement_2, &signed_2).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, wrong_session, &statement_2, &signed_2).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &wrong_statement_2, &signed_2).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_1, &signed_2).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_3, &signed_2).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_4, &signed_2).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_5, &signed_2).is_err()); - - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_3, &signed_3).is_ok()); - assert!(check_signature(&wrong_validator_id.public(), candidate_hash, session, &statement_3, &signed_3).is_err()); - assert!(check_signature(&validator_id.public(), wrong_candidate_hash, session, &statement_3, &signed_3).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, wrong_session, &statement_3, &signed_3).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &wrong_statement_3, &signed_3).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_1, &signed_3).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_2, &signed_3).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_4, &signed_3).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_5, &signed_3).is_err()); - - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_4, &signed_4).is_ok()); - assert!(check_signature(&wrong_validator_id.public(), candidate_hash, session, &statement_4, &signed_4).is_err()); - assert!(check_signature(&validator_id.public(), wrong_candidate_hash, session, &statement_4, &signed_4).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, wrong_session, &statement_4, &signed_4).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_1, &signed_4).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_2, &signed_4).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_3, &signed_4).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_5, &signed_4).is_err()); - - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_5, &signed_5).is_ok()); - assert!(check_signature(&wrong_validator_id.public(), candidate_hash, session, &statement_5, &signed_5).is_err()); - assert!(check_signature(&validator_id.public(), wrong_candidate_hash, session, &statement_5, &signed_5).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, wrong_session, &statement_5, &signed_5).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_1, &signed_5).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_2, &signed_5).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_3, &signed_5).is_err()); - assert!(check_signature(&validator_id.public(), candidate_hash, session, &statement_4, &signed_5).is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_1 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_1, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_1, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_1 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_1 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_2 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &wrong_statement_2, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_2 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_2 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_3 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &wrong_statement_3, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_3 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_3 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_4 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_4, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_4, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_4 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_4 + ) + .is_err()); + + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_5 + ) + .is_ok()); + assert!(check_signature( + &wrong_validator_id.public(), + candidate_hash, + session, + &statement_5, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + wrong_candidate_hash, + session, + &statement_5, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + wrong_session, + &statement_5, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_1, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_2, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_3, + &signed_5 + ) + .is_err()); + assert!(check_signature( + &validator_id.public(), + candidate_hash, + session, + &statement_4, + &signed_5 + ) + .is_err()); } #[test] @@ -2287,18 +2502,10 @@ mod tests { new_test_ext(Default::default()).execute_with(|| { let v0 = ::Pair::generate().0; - run_to_block( - 3, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } - ); + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); @@ -2306,53 +2513,48 @@ mod tests { valid: true, candidate_hash: candidate_hash.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let sig_a = v0.sign(&payload); let sig_b = v0.sign(&payload); let sig_c = v0.sign(&payload); - let mut statements = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_a.clone(), - ), - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_b, - ), - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_c, - ), - ] - } - ]; + let mut statements = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 1, + statements: vec![ + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a.clone(), + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_b, + ), + ( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_c, + ), + ], + }]; Pallet::::filter_multi_dispute_data(&mut statements); assert_eq!( statements, - vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_a, - ), - ] - } - ] + vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a, + ),] + }] ) }) } @@ -2363,13 +2565,10 @@ mod tests { let mock_genesis_config = MockGenesisConfig { configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - dispute_max_spam_slots, - .. Default::default() - }, - .. Default::default() + config: HostConfiguration { dispute_max_spam_slots, ..Default::default() }, + ..Default::default() }, - .. Default::default() + ..Default::default() }; new_test_ext(mock_genesis_config).execute_with(|| { @@ -2378,18 +2577,25 @@ mod tests { let v2 = ::Pair::generate().0; let v3 = ::Pair::generate().0; - run_to_block( - 3, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())], - Some(vec![(&0, v0.public()), (&1, v1.public()), (&2, v2.public()), (&3, v3.public())]), - )) - } - ); + run_to_block(3, |b| { + // a new session at each block + Some(( + true, + b, + vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ], + Some(vec![ + (&0, v0.public()), + (&1, v1.public()), + (&2, v2.public()), + (&3, v3.public()), + ]), + )) + }); let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); let candidate_hash_b = CandidateHash(sp_core::H256::repeat_byte(2)); @@ -2399,19 +2605,22 @@ mod tests { valid: true, candidate_hash: candidate_hash_a.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let payload_b = ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_b.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let payload_c = ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_c.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let sig_0a = v0.sign(&payload_a); let sig_0b = v0.sign(&payload_b); @@ -2423,13 +2632,11 @@ mod tests { DisputeStatementSet { candidate_hash: candidate_hash_a.clone(), session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_0a.clone(), - ), - ] + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_0a.clone(), + )], }, DisputeStatementSet { candidate_hash: candidate_hash_b.clone(), @@ -2445,18 +2652,16 @@ mod tests { ValidatorIndex(3), sig_1b.clone(), ), - ] + ], }, DisputeStatementSet { candidate_hash: candidate_hash_c.clone(), session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_0c.clone(), - ), - ] + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_0c.clone(), + )], }, ]; @@ -2472,18 +2677,10 @@ mod tests { new_test_ext(Default::default()).execute_with(|| { let v0 = ::Pair::generate().0; - run_to_block( - 3, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } - ); + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); let candidate_hash = CandidateHash(sp_core::H256::repeat_byte(1)); @@ -2491,23 +2688,20 @@ mod tests { valid: true, candidate_hash: candidate_hash.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let sig_a = v0.sign(&payload); - let mut statements = vec![ - DisputeStatementSet { - candidate_hash: candidate_hash.clone(), - session: 100, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_a, - ), - ] - } - ]; + let mut statements = vec![DisputeStatementSet { + candidate_hash: candidate_hash.clone(), + session: 100, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a, + )], + }]; Pallet::::filter_multi_dispute_data(&mut statements); @@ -2523,28 +2717,20 @@ mod tests { configuration: crate::configuration::GenesisConfig { config: HostConfiguration { dispute_post_conclusion_acceptance_period, - .. Default::default() + ..Default::default() }, - .. Default::default() + ..Default::default() }, - .. Default::default() + ..Default::default() }; new_test_ext(mock_genesis_config).execute_with(|| { let v0 = ::Pair::generate().0; - run_to_block( - 3, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } - ); + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); let candidate_hash_b = CandidateHash(sp_core::H256::repeat_byte(2)); @@ -2575,13 +2761,15 @@ mod tests { valid: true, candidate_hash: candidate_hash_a.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let payload_b = ExplicitDisputeStatement { valid: true, candidate_hash: candidate_hash_b.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let sig_a = v0.sign(&payload_a); let sig_b = v0.sign(&payload_b); @@ -2590,24 +2778,20 @@ mod tests { DisputeStatementSet { candidate_hash: candidate_hash_a.clone(), session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_a, - ), - ] + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a, + )], }, DisputeStatementSet { candidate_hash: candidate_hash_b.clone(), session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_b.clone(), - ), - ] + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_b.clone(), + )], }, ]; @@ -2615,19 +2799,15 @@ mod tests { assert_eq!( statements, - vec![ - DisputeStatementSet { - candidate_hash: candidate_hash_b.clone(), - session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_b, - ), - ] - } - ] + vec![DisputeStatementSet { + candidate_hash: candidate_hash_b.clone(), + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_b, + ),] + }] ); }) } @@ -2637,18 +2817,10 @@ mod tests { new_test_ext(Default::default()).execute_with(|| { let v0 = ::Pair::generate().0; - run_to_block( - 3, - |b| { - // a new session at each block - Some(( - true, - b, - vec![(&0, v0.public())], - Some(vec![(&0, v0.public())]), - )) - } - ); + run_to_block(3, |b| { + // a new session at each block + Some((true, b, vec![(&0, v0.public())], Some(vec![(&0, v0.public())]))) + }); let candidate_hash_a = CandidateHash(sp_core::H256::repeat_byte(1)); @@ -2656,7 +2828,8 @@ mod tests { valid: true, candidate_hash: candidate_hash_a.clone(), session: 1, - }.signing_payload(); + } + .signing_payload(); let sig_a = v0.sign(&payload); let sig_b = v0.sign(&payload); @@ -2665,24 +2838,20 @@ mod tests { DisputeStatementSet { candidate_hash: candidate_hash_a.clone(), session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_a.clone(), - ), - ] + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a.clone(), + )], }, DisputeStatementSet { candidate_hash: candidate_hash_a.clone(), session: 1, - statements: vec![ - ( - DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_b.clone(), - ), - ] + statements: vec![( + DisputeStatement::Invalid(InvalidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_b.clone(), + )], }, ]; @@ -2690,19 +2859,15 @@ mod tests { assert_eq!( statements, - vec![ - DisputeStatementSet { - candidate_hash: candidate_hash_a.clone(), - session: 1, - statements: vec![ - ( - DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), - ValidatorIndex(0), - sig_a, - ), - ] - } - ] + vec![DisputeStatementSet { + candidate_hash: candidate_hash_a.clone(), + session: 1, + statements: vec![( + DisputeStatement::Valid(ValidDisputeStatementKind::Explicit), + ValidatorIndex(0), + sig_a, + ),] + }] ); }) } diff --git a/polkadot/runtime/parachains/src/dmp.rs b/polkadot/runtime/parachains/src/dmp.rs index 6d48cb3c85c..7982424800e 100644 --- a/polkadot/runtime/parachains/src/dmp.rs +++ b/polkadot/runtime/parachains/src/dmp.rs @@ -19,9 +19,9 @@ use crate::{ initializer, }; use frame_support::pallet_prelude::*; -use sp_std::{fmt, prelude::*}; +use primitives::v1::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage}; use sp_runtime::traits::{BlakeTwo256, Hash as HashT, SaturatedConversion}; -use primitives::v1::{Id as ParaId, DownwardMessage, InboundDownwardMessage, Hash}; +use sp_std::{fmt, prelude::*}; use xcm::v0::Error as XcmError; pub use pallet::*; @@ -47,24 +47,16 @@ pub enum ProcessedDownwardMessagesAcceptanceErr { /// If there are pending messages then `processed_downward_messages` should be at least 1, AdvancementRule, /// `processed_downward_messages` should not be greater than the number of pending messages. - Underflow { - processed_downward_messages: u32, - dmq_length: u32, - }, + Underflow { processed_downward_messages: u32, dmq_length: u32 }, } impl fmt::Debug for ProcessedDownwardMessagesAcceptanceErr { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use ProcessedDownwardMessagesAcceptanceErr::*; match *self { - AdvancementRule => write!( - fmt, - "DMQ is not empty, but processed_downward_messages is 0", - ), - Underflow { - processed_downward_messages, - dmq_length, - } => write!( + AdvancementRule => + write!(fmt, "DMQ is not empty, but processed_downward_messages is 0",), + Underflow { processed_downward_messages, dmq_length } => write!( fmt, "processed_downward_messages = {}, but dmq_length is only {}", processed_downward_messages, dmq_length, @@ -91,7 +83,7 @@ pub mod pallet { Twox64Concat, ParaId, Vec>, - ValueQuery + ValueQuery, >; /// A mapping that stores the downward message queue MQC head for each para. @@ -102,13 +94,8 @@ pub mod pallet { /// - `B`: is the relay-chain block number in which a message was appended. /// - `H(M)`: is the hash of the message being appended. #[pallet::storage] - pub(crate) type DownwardMessageQueueHeads = StorageMap< - _, - Twox64Concat, - ParaId, - Hash, - ValueQuery, - >; + pub(crate) type DownwardMessageQueueHeads = + StorageMap<_, Twox64Concat, ParaId, Hash, ValueQuery>; #[pallet::call] impl Pallet {} @@ -161,13 +148,11 @@ impl Pallet { ) -> Result<(), QueueDownwardMessageError> { let serialized_len = msg.len() as u32; if serialized_len > config.max_downward_message_size { - return Err(QueueDownwardMessageError::ExceedsMaxMessageSize); + return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) } - let inbound = InboundDownwardMessage { - msg, - sent_at: >::block_number(), - }; + let inbound = + InboundDownwardMessage { msg, sent_at: >::block_number() }; // obtain the new link in the MQC and update the head. ::DownwardMessageQueueHeads::mutate(para, |head| { @@ -191,13 +176,13 @@ impl Pallet { let dmq_length = Self::dmq_length(para); if dmq_length > 0 && processed_downward_messages == 0 { - return Err(ProcessedDownwardMessagesAcceptanceErr::AdvancementRule); + return Err(ProcessedDownwardMessagesAcceptanceErr::AdvancementRule) } if dmq_length < processed_downward_messages { return Err(ProcessedDownwardMessagesAcceptanceErr::Underflow { processed_downward_messages, dmq_length, - }); + }) } Ok(()) @@ -245,10 +230,10 @@ impl Pallet { #[cfg(test)] mod tests { use super::*; + use crate::mock::{new_test_ext, Configuration, Dmp, MockGenesisConfig, Paras, System}; use hex_literal::hex; - use primitives::v1::BlockNumber; use parity_scale_codec::Encode; - use crate::mock::{Configuration, new_test_ext, System, Dmp, MockGenesisConfig, Paras}; + use primitives::v1::BlockNumber; pub(crate) fn run_to_block(to: BlockNumber, new_session: Option>) { while System::block_number() < to { @@ -413,8 +398,8 @@ mod tests { #[test] fn verify_dmq_mqc_head_is_externally_accessible() { - use primitives::v1::well_known_keys; use hex_literal::hex; + use primitives::v1::well_known_keys; let a = ParaId::from(2020); @@ -427,7 +412,10 @@ mod tests { let head = sp_io::storage::get(&well_known_keys::dmq_mqc_head(a)); assert_eq!( head, - Some(hex!["434f8579a2297dfea851bf6be33093c83a78b655a53ae141a7894494c0010589"].to_vec()) + Some( + hex!["434f8579a2297dfea851bf6be33093c83a78b655a53ae141a7894494c0010589"] + .to_vec() + ) ); }); } diff --git a/polkadot/runtime/parachains/src/hrmp.rs b/polkadot/runtime/parachains/src/hrmp.rs index 6a684b7e9a9..906c9d77d39 100644 --- a/polkadot/runtime/parachains/src/hrmp.rs +++ b/polkadot/runtime/parachains/src/hrmp.rs @@ -15,22 +15,20 @@ // along with Polkadot. If not, see . use crate::{ - ensure_parachain, configuration::{self, HostConfiguration}, - initializer, paras, dmp, + dmp, ensure_parachain, initializer, paras, }; -use parity_scale_codec::{Decode, Encode}; -use frame_support::pallet_prelude::*; -use frame_support::traits::ReservableCurrency; +use frame_support::{pallet_prelude::*, traits::ReservableCurrency}; use frame_system::pallet_prelude::*; +use parity_scale_codec::{Decode, Encode}; use primitives::v1::{ Balance, Hash, HrmpChannelId, Id as ParaId, InboundHrmpMessage, OutboundHrmpMessage, SessionIndex, }; -use sp_runtime::traits::{UniqueSaturatedInto, AccountIdConversion, BlakeTwo256, Hash as HashT}; +use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash as HashT, UniqueSaturatedInto}; use sp_std::{ - mem, fmt, collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + fmt, mem, prelude::*, }; @@ -63,7 +61,6 @@ pub struct HrmpChannel { // A parachain requested this struct can only depend on the subset of this struct. Specifically, // only a first few fields can be depended upon (See `AbridgedHrmpChannel`). These fields cannot // be changed without corresponding migration of parachains. - /// The maximum number of messages that can be pending in the channel at once. pub max_capacity: u32, /// The maximum total size of the messages that can be pending in the channel at once. @@ -93,48 +90,20 @@ pub struct HrmpChannel { /// An error returned by [`check_hrmp_watermark`] that indicates an acceptance criteria check /// didn't pass. pub enum HrmpWatermarkAcceptanceErr { - AdvancementRule { - new_watermark: BlockNumber, - last_watermark: BlockNumber, - }, - AheadRelayParent { - new_watermark: BlockNumber, - relay_chain_parent_number: BlockNumber, - }, - LandsOnBlockWithNoMessages { - new_watermark: BlockNumber, - }, + AdvancementRule { new_watermark: BlockNumber, last_watermark: BlockNumber }, + AheadRelayParent { new_watermark: BlockNumber, relay_chain_parent_number: BlockNumber }, + LandsOnBlockWithNoMessages { new_watermark: BlockNumber }, } /// An error returned by [`check_outbound_hrmp`] that indicates an acceptance criteria check /// didn't pass. pub enum OutboundHrmpAcceptanceErr { - MoreMessagesThanPermitted { - sent: u32, - permitted: u32, - }, - NotSorted { - idx: u32, - }, - NoSuchChannel { - idx: u32, - channel_id: HrmpChannelId, - }, - MaxMessageSizeExceeded { - idx: u32, - msg_size: u32, - max_size: u32, - }, - TotalSizeExceeded { - idx: u32, - total_size: u32, - limit: u32, - }, - CapacityExceeded { - idx: u32, - count: u32, - limit: u32, - }, + MoreMessagesThanPermitted { sent: u32, permitted: u32 }, + NotSorted { idx: u32 }, + NoSuchChannel { idx: u32, channel_id: HrmpChannelId }, + MaxMessageSizeExceeded { idx: u32, msg_size: u32, max_size: u32 }, + TotalSizeExceeded { idx: u32, total_size: u32, limit: u32 }, + CapacityExceeded { idx: u32, count: u32, limit: u32 }, } impl fmt::Debug for HrmpWatermarkAcceptanceErr @@ -144,18 +113,12 @@ where fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use HrmpWatermarkAcceptanceErr::*; match self { - AdvancementRule { - new_watermark, - last_watermark, - } => write!( + AdvancementRule { new_watermark, last_watermark } => write!( fmt, "the HRMP watermark is not advanced relative to the last watermark ({:?} > {:?})", new_watermark, last_watermark, ), - AheadRelayParent { - new_watermark, - relay_chain_parent_number, - } => write!( + AheadRelayParent { new_watermark, relay_chain_parent_number } => write!( fmt, "the HRMP watermark is ahead the relay-parent ({:?} > {:?})", new_watermark, relay_chain_parent_number @@ -178,30 +141,19 @@ impl fmt::Debug for OutboundHrmpAcceptanceErr { "more HRMP messages than permitted by config ({} > {})", sent, permitted, ), - NotSorted { idx } => write!( - fmt, - "the HRMP messages are not sorted (first unsorted is at index {})", - idx, - ), + NotSorted { idx } => + write!(fmt, "the HRMP messages are not sorted (first unsorted is at index {})", idx,), NoSuchChannel { idx, channel_id } => write!( fmt, "the HRMP message at index {} is sent to a non existent channel {:?}->{:?}", idx, channel_id.sender, channel_id.recipient, ), - MaxMessageSizeExceeded { - idx, - msg_size, - max_size, - } => write!( + MaxMessageSizeExceeded { idx, msg_size, max_size } => write!( fmt, "the HRMP message at index {} exceeds the negotiated channel maximum message size ({} > {})", idx, msg_size, max_size, ), - TotalSizeExceeded { - idx, - total_size, - limit, - } => write!( + TotalSizeExceeded { idx, total_size, limit } => write!( fmt, "sending the HRMP message at index {} would exceed the neogitiated channel total size ({} > {})", idx, total_size, limit, @@ -219,13 +171,14 @@ impl fmt::Debug for OutboundHrmpAcceptanceErr { pub mod pallet { use super::*; - #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); #[pallet::config] - pub trait Config: frame_system::Config + configuration::Config + paras::Config + dmp::Config { + pub trait Config: + frame_system::Config + configuration::Config + paras::Config + dmp::Config + { /// The outer event type. type Event: From> + IsType<::Event>; @@ -294,39 +247,26 @@ pub mod pallet { /// Invariant: /// - There are no channels that exists in list but not in the set and vice versa. #[pallet::storage] - pub type HrmpOpenChannelRequests = StorageMap< - _, - Twox64Concat, - HrmpChannelId, - HrmpOpenChannelRequest - >; + pub type HrmpOpenChannelRequests = + StorageMap<_, Twox64Concat, HrmpChannelId, HrmpOpenChannelRequest>; #[pallet::storage] - pub type HrmpOpenChannelRequestsList = StorageValue<_, Vec, ValueQuery>; + pub type HrmpOpenChannelRequestsList = + StorageValue<_, Vec, ValueQuery>; /// This mapping tracks how many open channel requests are initiated by a given sender para. /// Invariant: `HrmpOpenChannelRequests` should contain the same number of items that has `(X, _)` /// as the number of `HrmpOpenChannelRequestCount` for `X`. #[pallet::storage] - pub type HrmpOpenChannelRequestCount = StorageMap< - _, - Twox64Concat, - ParaId, - u32, - ValueQuery - >; + pub type HrmpOpenChannelRequestCount = + StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>; /// This mapping tracks how many open channel requests were accepted by a given recipient para. /// Invariant: `HrmpOpenChannelRequests` should contain the same number of items `(_, X)` with /// `confirmed` set to true, as the number of `HrmpAcceptedChannelRequestCount` for `X`. #[pallet::storage] - pub type HrmpAcceptedChannelRequestCount = StorageMap< - _, - Twox64Concat, - ParaId, - u32, - ValueQuery - >; + pub type HrmpAcceptedChannelRequestCount = + StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>; /// A set of pending HRMP close channel requests that are going to be closed during the session change. /// Used for checking if a given channel is registered for closure. @@ -339,7 +279,8 @@ pub mod pallet { pub type HrmpCloseChannelRequests = StorageMap<_, Twox64Concat, HrmpChannelId, ()>; #[pallet::storage] - pub type HrmpCloseChannelRequestsList = StorageValue<_, Vec, ValueQuery>; + pub type HrmpCloseChannelRequestsList = + StorageValue<_, Vec, ValueQuery>; /// The HRMP watermark associated with each para. /// Invariant: @@ -367,24 +308,14 @@ pub mod pallet { /// - there should be no other dangling channels in `HrmpChannels`. /// - the vectors are sorted. #[pallet::storage] - pub type HrmpIngressChannelsIndex = StorageMap< - _, - Twox64Concat, - ParaId, - Vec, - ValueQuery - >; + pub type HrmpIngressChannelsIndex = + StorageMap<_, Twox64Concat, ParaId, Vec, ValueQuery>; // NOTE that this field is used by parachains via merkle storage proofs, therefore changing // the format will require migration of parachains. #[pallet::storage] - pub type HrmpEgressChannelsIndex = StorageMap< - _, - Twox64Concat, - ParaId, - Vec, - ValueQuery - >; + pub type HrmpEgressChannelsIndex = + StorageMap<_, Twox64Concat, ParaId, Vec, ValueQuery>; /// Storage for the messages for each channel. /// Invariant: cannot be non-empty if the corresponding channel in `HrmpChannels` is `None`. @@ -394,7 +325,7 @@ pub mod pallet { Twox64Concat, HrmpChannelId, Vec>, - ValueQuery + ValueQuery, >; /// Maintains a mapping that can be used to answer the question: @@ -405,13 +336,8 @@ pub mod pallet { /// - The outer vector is sorted ascending by block number and cannot store two items with the same /// block number. #[pallet::storage] - pub type HrmpChannelDigests = StorageMap< - _, - Twox64Concat, - ParaId, - Vec<(T::BlockNumber, Vec)>, - ValueQuery - >; + pub type HrmpChannelDigests = + StorageMap<_, Twox64Concat, ParaId, Vec<(T::BlockNumber, Vec)>, ValueQuery>; /// Preopen the given HRMP channels. /// @@ -432,9 +358,7 @@ pub mod pallet { #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { - GenesisConfig { - preopen_hrmp_channels: Default::default(), - } + GenesisConfig { preopen_hrmp_channels: Default::default() } } } @@ -469,13 +393,13 @@ pub mod pallet { origin, recipient, proposed_max_capacity, - proposed_max_message_size + proposed_max_message_size, )?; Self::deposit_event(Event::OpenChannelRequested( origin, recipient, proposed_max_capacity, - proposed_max_message_size + proposed_max_message_size, )); Ok(()) } @@ -496,7 +420,10 @@ pub mod pallet { /// /// The closure can only happen on a session change. #[pallet::weight(0)] - pub fn hrmp_close_channel(origin: OriginFor, channel_id: HrmpChannelId) -> DispatchResult { + pub fn hrmp_close_channel( + origin: OriginFor, + channel_id: HrmpChannelId, + ) -> DispatchResult { let origin = ensure_parachain(::Origin::from(origin))?; Self::close_channel(origin, channel_id.clone())?; Self::deposit_event(Event::ChannelClosed(origin, channel_id)); @@ -544,7 +471,9 @@ pub mod pallet { fn initialize_storage(preopen_hrmp_channels: &[(ParaId, ParaId, u32, u32)]) { let host_config = configuration::Pallet::::config(); for &(sender, recipient, max_capacity, max_message_size) in preopen_hrmp_channels { - if let Err(err) = preopen_hrmp_channel::(sender, recipient, max_capacity, max_message_size) { + if let Err(err) = + preopen_hrmp_channel::(sender, recipient, max_capacity, max_message_size) + { panic!("failed to initialize the genesis storage: {:?}", err); } } @@ -556,14 +485,9 @@ fn preopen_hrmp_channel( sender: ParaId, recipient: ParaId, max_capacity: u32, - max_message_size: u32 + max_message_size: u32, ) -> DispatchResult { - >::init_open_channel( - sender, - recipient, - max_capacity, - max_message_size, - )?; + >::init_open_channel(sender, recipient, max_capacity, max_message_size)?; >::accept_open_channel(recipient, sender)?; Ok(()) } @@ -603,16 +527,10 @@ impl Pallet { let ingress = ::HrmpIngressChannelsIndex::take(outgoing_para) .into_iter() - .map(|sender| HrmpChannelId { - sender, - recipient: outgoing_para.clone(), - }); + .map(|sender| HrmpChannelId { sender, recipient: outgoing_para.clone() }); let egress = ::HrmpEgressChannelsIndex::take(outgoing_para) .into_iter() - .map(|recipient| HrmpChannelId { - sender: outgoing_para.clone(), - recipient, - }); + .map(|recipient| HrmpChannelId { sender: outgoing_para.clone(), recipient }); let mut to_close = ingress.chain(egress).collect::>(); to_close.sort(); to_close.dedup(); @@ -629,7 +547,7 @@ impl Pallet { fn process_hrmp_open_channel_requests(config: &HostConfiguration) { let mut open_req_channels = ::HrmpOpenChannelRequestsList::get(); if open_req_channels.is_empty() { - return; + return } // iterate the vector starting from the end making our way to the beginning. This way we @@ -638,7 +556,7 @@ impl Pallet { loop { // bail if we've iterated over all items. if idx == 0 { - break; + break } idx -= 1; @@ -648,8 +566,8 @@ impl Pallet { ); if request.confirmed { - if >::is_valid_para(channel_id.sender) - && >::is_valid_para(channel_id.recipient) + if >::is_valid_para(channel_id.sender) && + >::is_valid_para(channel_id.recipient) { ::HrmpChannels::insert( &channel_id, @@ -745,11 +663,8 @@ impl Pallet { /// This function is idempotent, meaning that after the first application it should have no /// effect (i.e. it won't return the deposits twice). fn close_hrmp_channel(channel_id: &HrmpChannelId) { - if let Some(HrmpChannel { - sender_deposit, - recipient_deposit, - .. - }) = ::HrmpChannels::take(channel_id) + if let Some(HrmpChannel { sender_deposit, recipient_deposit, .. }) = + ::HrmpChannels::take(channel_id) { T::Currency::unreserve( &channel_id.sender.into_account(), @@ -793,14 +708,14 @@ impl Pallet { return Err(HrmpWatermarkAcceptanceErr::AdvancementRule { new_watermark: new_hrmp_watermark, last_watermark, - }); + }) } } if new_hrmp_watermark > relay_chain_parent_number { return Err(HrmpWatermarkAcceptanceErr::AheadRelayParent { new_watermark: new_hrmp_watermark, relay_chain_parent_number, - }); + }) } // Second, check where the watermark CAN land. It's one of the following: @@ -817,7 +732,7 @@ impl Pallet { { return Err(HrmpWatermarkAcceptanceErr::LandsOnBlockWithNoMessages { new_watermark: new_hrmp_watermark, - }); + }) } Ok(()) } @@ -832,36 +747,28 @@ impl Pallet { return Err(OutboundHrmpAcceptanceErr::MoreMessagesThanPermitted { sent: out_hrmp_msgs.len() as u32, permitted: config.hrmp_max_message_num_per_candidate, - }); + }) } let mut last_recipient = None::; - for (idx, out_msg) in out_hrmp_msgs - .iter() - .enumerate() - .map(|(idx, out_msg)| (idx as u32, out_msg)) + for (idx, out_msg) in + out_hrmp_msgs.iter().enumerate().map(|(idx, out_msg)| (idx as u32, out_msg)) { match last_recipient { // the messages must be sorted in ascending order and there must be no two messages sent // to the same recipient. Thus we can check that every recipient is strictly greater than // the previous one. - Some(last_recipient) if out_msg.recipient <= last_recipient => { - return Err(OutboundHrmpAcceptanceErr::NotSorted { idx }); - } + Some(last_recipient) if out_msg.recipient <= last_recipient => + return Err(OutboundHrmpAcceptanceErr::NotSorted { idx }), _ => last_recipient = Some(out_msg.recipient), } - let channel_id = HrmpChannelId { - sender, - recipient: out_msg.recipient, - }; + let channel_id = HrmpChannelId { sender, recipient: out_msg.recipient }; let channel = match ::HrmpChannels::get(&channel_id) { Some(channel) => channel, - None => { - return Err(OutboundHrmpAcceptanceErr::NoSuchChannel { channel_id, idx }); - } + None => return Err(OutboundHrmpAcceptanceErr::NoSuchChannel { channel_id, idx }), }; let msg_size = out_msg.data.len() as u32; @@ -870,7 +777,7 @@ impl Pallet { idx, msg_size, max_size: channel.max_message_size, - }); + }) } let new_total_size = channel.total_size + out_msg.data.len() as u32; @@ -879,7 +786,7 @@ impl Pallet { idx, total_size: new_total_size, limit: channel.max_total_size, - }); + }) } let new_msg_count = channel.msg_count + 1; @@ -888,7 +795,7 @@ impl Pallet { idx, count: new_msg_count, limit: channel.max_capacity, - }); + }) } } @@ -916,9 +823,8 @@ impl Pallet { weight += T::DbWeight::get().reads_writes(1, 1); // having all senders we can trivially find out the channels which we need to prune. - let channels_to_prune = senders - .into_iter() - .map(|sender| HrmpChannelId { sender, recipient }); + let channels_to_prune = + senders.into_iter().map(|sender| HrmpChannelId { sender, recipient }); for channel_id in channels_to_prune { // prune each channel up to the new watermark keeping track how many messages we removed // and what is the total byte size of them. @@ -968,24 +874,18 @@ impl Pallet { let now = >::block_number(); for out_msg in out_hrmp_msgs { - let channel_id = HrmpChannelId { - sender, - recipient: out_msg.recipient, - }; + let channel_id = HrmpChannelId { sender, recipient: out_msg.recipient }; let mut channel = match ::HrmpChannels::get(&channel_id) { Some(channel) => channel, None => { // apparently, that since acceptance of this candidate the recipient was // offboarded and the channel no longer exists. - continue; - } + continue + }, }; - let inbound = InboundHrmpMessage { - sent_at: now, - data: out_msg.data, - }; + let inbound = InboundHrmpMessage { sent_at: now, data: out_msg.data }; // book keeping channel.msg_count += 1; @@ -1052,27 +952,18 @@ impl Pallet { ); let config = >::config(); - ensure!( - proposed_max_capacity > 0, - Error::::OpenHrmpChannelZeroCapacity, - ); + ensure!(proposed_max_capacity > 0, Error::::OpenHrmpChannelZeroCapacity,); ensure!( proposed_max_capacity <= config.hrmp_channel_max_capacity, Error::::OpenHrmpChannelCapacityExceedsLimit, ); - ensure!( - proposed_max_message_size > 0, - Error::::OpenHrmpChannelZeroMessageSize, - ); + ensure!(proposed_max_message_size > 0, Error::::OpenHrmpChannelZeroMessageSize,); ensure!( proposed_max_message_size <= config.hrmp_channel_max_message_size, Error::::OpenHrmpChannelMessageSizeExceedsLimit, ); - let channel_id = HrmpChannelId { - sender: origin, - recipient, - }; + let channel_id = HrmpChannelId { sender: origin, recipient }; ensure!( ::HrmpOpenChannelRequests::get(&channel_id).is_none(), Error::::OpenHrmpChannelAlreadyExists, @@ -1115,8 +1006,8 @@ impl Pallet { ::HrmpOpenChannelRequestsList::append(channel_id); let notification_bytes = { - use xcm::opaque::{v0::Xcm, VersionedXcm}; use parity_scale_codec::Encode as _; + use xcm::opaque::{v0::Xcm, VersionedXcm}; VersionedXcm::from(Xcm::HrmpNewChannelOpenRequest { sender: u32::from(origin), @@ -1141,16 +1032,10 @@ impl Pallet { /// Basically the same as [`hrmp_accept_open_channel`](Pallet::hrmp_accept_open_channel) but /// intendend for calling directly from other pallets rather than dispatched. pub fn accept_open_channel(origin: ParaId, sender: ParaId) -> DispatchResult { - let channel_id = HrmpChannelId { - sender, - recipient: origin, - }; + let channel_id = HrmpChannelId { sender, recipient: origin }; let mut channel_req = ::HrmpOpenChannelRequests::get(&channel_id) .ok_or(Error::::AcceptHrmpChannelDoesntExist)?; - ensure!( - !channel_req.confirmed, - Error::::AcceptHrmpChannelAlreadyConfirmed, - ); + ensure!(!channel_req.confirmed, Error::::AcceptHrmpChannelAlreadyConfirmed,); // check if by accepting this open channel request, this parachain would exceed the // number of inbound channels. @@ -1183,10 +1068,7 @@ impl Pallet { use parity_scale_codec::Encode as _; use xcm::opaque::{v0::Xcm, VersionedXcm}; - VersionedXcm::from(Xcm::HrmpChannelAccepted { - recipient: u32::from(origin), - }) - .encode() + VersionedXcm::from(Xcm::HrmpChannelAccepted { recipient: u32::from(origin) }).encode() }; if let Err(dmp::QueueDownwardMessageError::ExceedsMaxMessageSize) = >::queue_downward_message(&config, sender, notification_bytes) @@ -1233,11 +1115,8 @@ impl Pallet { }) .encode() }; - let opposite_party = if origin == channel_id.sender { - channel_id.recipient - } else { - channel_id.sender - }; + let opposite_party = + if origin == channel_id.sender { channel_id.recipient } else { channel_id.sender }; if let Err(dmp::QueueDownwardMessageError::ExceedsMaxMessageSize) = >::queue_downward_message(&config, opposite_party, notification_bytes) { @@ -1292,15 +1171,14 @@ impl Pallet { mod tests { use super::*; use crate::mock::{ - new_test_ext, Test, Configuration, Paras, ParasShared, Hrmp, System, MockGenesisConfig, - Event as MockEvent, + new_test_ext, Configuration, Event as MockEvent, Hrmp, MockGenesisConfig, Paras, + ParasShared, System, Test, }; use frame_support::{assert_noop, assert_ok, traits::Currency as _}; use primitives::v1::BlockNumber; use std::collections::{BTreeMap, HashSet}; fn run_to_block(to: BlockNumber, new_session: Option>) { - let config = Configuration::config(); while System::block_number() < to { let b = System::block_number(); @@ -1500,9 +1378,7 @@ mod tests { // An entry in `HrmpChannels` indicates that the channel is open. Only open channels can // have contents. for (non_empty_channel, contents) in ::HrmpChannelContents::iter() { - assert!(::HrmpChannels::contains_key( - &non_empty_channel - )); + assert!(::HrmpChannels::contains_key(&non_empty_channel)); // pedantic check: there should be no empty vectors in storage, those should be modeled // by a removed kv pair. @@ -1544,10 +1420,7 @@ mod tests { let channel_set_ground_truth = ::HrmpChannels::iter() .map(|(k, _)| (k.sender, k.recipient)) .collect::>(); - assert_eq!( - channel_set_derived_from_ingress, - channel_set_derived_from_egress - ); + assert_eq!(channel_set_derived_from_ingress, channel_set_derived_from_egress); assert_eq!(channel_set_derived_from_egress, channel_set_ground_truth); ::HrmpIngressChannelsIndex::iter() @@ -1583,22 +1456,13 @@ mod tests { fn assert_contains_only_onboarded(iter: impl Iterator, cause: &str) { for para in iter { - assert!( - Paras::is_valid_para(para), - "{}: {} para is offboarded", - cause, - para - ); + assert!(Paras::is_valid_para(para), "{}: {} para is offboarded", cause, para); } } } fn assert_is_sorted(slice: &[T], id: &str) { - assert!( - slice.windows(2).all(|xs| xs[0] <= xs[1]), - "{} supposed to be sorted", - id - ); + assert!(slice.windows(2).all(|xs| xs[0] <= xs[1]), "{} supposed to be sorted", id); } #[test] @@ -1623,15 +1487,13 @@ mod tests { run_to_block(5, Some(vec![4, 5])); Hrmp::hrmp_init_open_channel(para_a_origin.into(), para_b, 2, 8).unwrap(); assert_storage_consistency_exhaustive(); - assert!(System::events().iter().any(|record| - record.event == MockEvent::Hrmp(Event::OpenChannelRequested(para_a, para_b, 2, 8)) - )); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::OpenChannelRequested(para_a, para_b, 2, 8)))); Hrmp::hrmp_accept_open_channel(para_b_origin.into(), para_a).unwrap(); assert_storage_consistency_exhaustive(); - assert!(System::events().iter().any(|record| - record.event == MockEvent::Hrmp(Event::OpenChannelAccepted(para_a, para_b)) - )); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::OpenChannelAccepted(para_a, para_b)))); // Advance to a block 6, but without session change. That means that the channel has // not been created yet. @@ -1664,10 +1526,7 @@ mod tests { // Close the channel. The effect is not immediate, but rather deferred to the next // session change. - let channel_id = HrmpChannelId { - sender: para_a, - recipient: para_b, - }; + let channel_id = HrmpChannelId { sender: para_a, recipient: para_b }; Hrmp::hrmp_close_channel(para_b_origin.into(), channel_id.clone()).unwrap(); assert!(channel_exists(para_a, para_b)); assert_storage_consistency_exhaustive(); @@ -1676,9 +1535,8 @@ mod tests { run_to_block(8, Some(vec![8])); assert!(!channel_exists(para_a, para_b)); assert_storage_consistency_exhaustive(); - assert!(System::events().iter().any(|record| - record.event == MockEvent::Hrmp(Event::ChannelClosed(para_b, channel_id.clone())) - )); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::ChannelClosed(para_b, channel_id.clone())))); }); } @@ -1732,27 +1590,31 @@ mod tests { register_parachain(para_a); register_parachain(para_b); - run_to_block(2, Some(vec![1,2])); + run_to_block(2, Some(vec![1, 2])); Hrmp::init_open_channel(para_a, para_b, 2, 20).unwrap(); Hrmp::accept_open_channel(para_b, para_a).unwrap(); run_to_block(3, Some(vec![3])); - let _ = Hrmp::queue_outbound_hrmp(para_a, vec![OutboundHrmpMessage { - recipient: para_b, - data: vec![1, 2, 3], - }]); + let _ = Hrmp::queue_outbound_hrmp( + para_a, + vec![OutboundHrmpMessage { recipient: para_b, data: vec![1, 2, 3] }], + ); run_to_block(4, None); - let _ = Hrmp::queue_outbound_hrmp(para_a, vec![OutboundHrmpMessage { - recipient: para_b, - data: vec![4, 5, 6], - }]); + let _ = Hrmp::queue_outbound_hrmp( + para_a, + vec![OutboundHrmpMessage { recipient: para_b, data: vec![4, 5, 6] }], + ); assert_eq!( Hrmp::hrmp_mqc_heads(para_b), - vec![ - (para_a, hex_literal::hex!["a964fd3b4f3d3ce92a0e25e576b87590d92bb5cb7031909c7f29050e1f04a375"].into()), - ], + vec![( + para_a, + hex_literal::hex![ + "a964fd3b4f3d3ce92a0e25e576b87590d92bb5cb7031909c7f29050e1f04a375" + ] + .into() + ),], ); }); } @@ -1803,10 +1665,7 @@ mod tests { run_to_block(6, Some(vec![6])); assert!(Paras::is_valid_para(para_a)); - let msgs = vec![OutboundHrmpMessage { - recipient: para_b, - data: b"knock".to_vec(), - }]; + let msgs = vec![OutboundHrmpMessage { recipient: para_b, data: b"knock".to_vec() }]; let config = Configuration::config(); assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok()); let _ = Hrmp::queue_outbound_hrmp(para_a, msgs.clone()); @@ -1817,13 +1676,7 @@ mod tests { assert_eq!( contents, vec![ - ( - para_a, - vec![InboundHrmpMessage { - sent_at: 6, - data: b"knock".to_vec(), - }] - ), + (para_a, vec![InboundHrmpMessage { sent_at: 6, data: b"knock".to_vec() }]), (para_c, vec![]) ] .into_iter() @@ -1891,29 +1744,19 @@ mod tests { ); let raw_ingress_index = - sp_io::storage::get( - &well_known_keys::hrmp_ingress_channel_index(para_b), - ) - .expect("the ingress index must be present for para_b"); + sp_io::storage::get(&well_known_keys::hrmp_ingress_channel_index(para_b)) + .expect("the ingress index must be present for para_b"); let ingress_index = >::decode(&mut &raw_ingress_index[..]) .expect("ingress indexx should be decodable as a list of para ids"); - assert_eq!( - ingress_index, - vec![para_a], - ); + assert_eq!(ingress_index, vec![para_a],); // Now, verify that we can access and decode the egress index. let raw_egress_index = - sp_io::storage::get( - &well_known_keys::hrmp_egress_channel_index(para_a) - ) - .expect("the egress index must be present for para_a"); + sp_io::storage::get(&well_known_keys::hrmp_egress_channel_index(para_a)) + .expect("the egress index must be present for para_a"); let egress_index = >::decode(&mut &raw_egress_index[..]) .expect("egress index should be decodable as a list of para ids"); - assert_eq!( - egress_index, - vec![para_b], - ); + assert_eq!(egress_index, vec![para_b],); }); } @@ -1962,34 +1805,16 @@ mod tests { run_to_block(5, Some(vec![4, 5])); Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); Hrmp::accept_open_channel(para_b, para_a).unwrap(); - assert_eq!( - ::Currency::free_balance(¶_a.into_account()), - 80 - ); - assert_eq!( - ::Currency::free_balance(¶_b.into_account()), - 95 - ); + assert_eq!(::Currency::free_balance(¶_a.into_account()), 80); + assert_eq!(::Currency::free_balance(¶_b.into_account()), 95); run_to_block(8, Some(vec![8])); // Now, we close the channel and wait until the next session. - Hrmp::close_channel( - para_b, - HrmpChannelId { - sender: para_a, - recipient: para_b, - }, - ) - .unwrap(); + Hrmp::close_channel(para_b, HrmpChannelId { sender: para_a, recipient: para_b }) + .unwrap(); run_to_block(10, Some(vec![10])); - assert_eq!( - ::Currency::free_balance(¶_a.into_account()), - 100 - ); - assert_eq!( - ::Currency::free_balance(¶_b.into_account()), - 110 - ); + assert_eq!(::Currency::free_balance(¶_a.into_account()), 100); + assert_eq!(::Currency::free_balance(¶_b.into_account()), 110); }); } @@ -2009,28 +1834,16 @@ mod tests { register_parachain_with_balance(para_b, 110); run_to_block(5, Some(vec![4, 5])); Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); - assert_eq!( - ::Currency::free_balance(¶_a.into_account()), - 80 - ); - assert_eq!( - ::Currency::free_balance(¶_b.into_account()), - 110 - ); + assert_eq!(::Currency::free_balance(¶_a.into_account()), 80); + assert_eq!(::Currency::free_balance(¶_b.into_account()), 110); // Request age is 1 out of 2 run_to_block(10, Some(vec![10])); - assert_eq!( - ::Currency::free_balance(¶_a.into_account()), - 80 - ); + assert_eq!(::Currency::free_balance(¶_a.into_account()), 80); // Request age is 2 out of 2. The request should expire. run_to_block(20, Some(vec![20])); - assert_eq!( - ::Currency::free_balance(¶_a.into_account()), - 100 - ); + assert_eq!(::Currency::free_balance(¶_a.into_account()), 100); }); } @@ -2049,14 +1862,8 @@ mod tests { run_to_block(5, Some(vec![4, 5])); Hrmp::init_open_channel(para_a, para_b, 2, 8).unwrap(); Hrmp::accept_open_channel(para_b, para_a).unwrap(); - assert_eq!( - ::Currency::free_balance(¶_a.into_account()), - 80 - ); - assert_eq!( - ::Currency::free_balance(¶_b.into_account()), - 95 - ); + assert_eq!(::Currency::free_balance(¶_a.into_account()), 80); + assert_eq!(::Currency::free_balance(¶_b.into_account()), 95); run_to_block(8, Some(vec![8])); assert!(channel_exists(para_a, para_b)); @@ -2069,14 +1876,8 @@ mod tests { assert!(!channel_exists(para_a, para_b)); assert_storage_consistency_exhaustive(); - assert_eq!( - ::Currency::free_balance(¶_a.into_account()), - 100 - ); - assert_eq!( - ::Currency::free_balance(¶_b.into_account()), - 110 - ); + assert_eq!(::Currency::free_balance(¶_a.into_account()), 100); + assert_eq!(::Currency::free_balance(¶_b.into_account()), 110); }); } } diff --git a/polkadot/runtime/parachains/src/inclusion.rs b/polkadot/runtime/parachains/src/inclusion.rs index 279ef7a1673..e271e5f415d 100644 --- a/polkadot/runtime/parachains/src/inclusion.rs +++ b/polkadot/runtime/parachains/src/inclusion.rs @@ -20,19 +20,21 @@ //! It is responsible for carrying candidates from being backable to being backed, and then from backed //! to included. -use sp_std::prelude::*; +use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; +use frame_support::pallet_prelude::*; +use parity_scale_codec::{Decode, Encode}; use primitives::v1::{ - CandidateCommitments, CandidateDescriptor, ValidatorIndex, Id as ParaId, - AvailabilityBitfield as AvailabilityBitfield, UncheckedSignedAvailabilityBitfields, SigningContext, - BackedCandidate, CoreIndex, GroupIndex, CommittedCandidateReceipt, - CandidateReceipt, HeadData, CandidateHash, + AvailabilityBitfield, BackedCandidate, CandidateCommitments, CandidateDescriptor, + CandidateHash, CandidateReceipt, CommittedCandidateReceipt, CoreIndex, GroupIndex, HeadData, + Id as ParaId, SigningContext, UncheckedSignedAvailabilityBitfields, ValidatorIndex, }; -use frame_support::pallet_prelude::*; -use parity_scale_codec::{Encode, Decode}; -use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; -use sp_runtime::{DispatchError, traits::{One, Saturating}}; +use sp_runtime::{ + traits::{One, Saturating}, + DispatchError, +}; +use sp_std::prelude::*; -use crate::{configuration, disputes, paras, dmp, ump, hrmp, shared, scheduler::CoreAssignment}; +use crate::{configuration, disputes, dmp, hrmp, paras, scheduler::CoreAssignment, shared, ump}; pub use pallet::*; @@ -45,7 +47,7 @@ pub use pallet::*; #[cfg_attr(test, derive(Debug))] pub struct AvailabilityBitfieldRecord { bitfield: AvailabilityBitfield, // one bit per core. - submitted_at: N, // for accounting, as meaning of bits may change over time. + submitted_at: N, // for accounting, as meaning of bits may change over time. } /// A backed candidate pending availability. @@ -82,7 +84,7 @@ impl CandidatePendingAvailability { } /// Get the core index. - pub(crate) fn core_occupied(&self)-> CoreIndex { + pub(crate) fn core_occupied(&self) -> CoreIndex { self.core.clone() } @@ -100,11 +102,11 @@ impl CandidatePendingAvailability { /// A hook for applying validator rewards pub trait RewardValidators { // Reward the validators with the given indices for issuing backing statements. - fn reward_backing(validators: impl IntoIterator); + fn reward_backing(validators: impl IntoIterator); // Reward the validators with the given indices for issuing availability bitfields. // Validators are sent to this hook when they have contributed to the availability // of a candidate by setting a bit in their bitfield. - fn reward_bitfields(validators: impl IntoIterator); + fn reward_bitfields(validators: impl IntoIterator); } #[frame_support::pallet] @@ -196,54 +198,43 @@ pub mod pallet { /// The latest bitfield for each validator, referred to by their index in the validator set. #[pallet::storage] - pub(crate) type AvailabilityBitfields = StorageMap< - _, - Twox64Concat, - ValidatorIndex, - AvailabilityBitfieldRecord - >; + pub(crate) type AvailabilityBitfields = + StorageMap<_, Twox64Concat, ValidatorIndex, AvailabilityBitfieldRecord>; /// Candidates pending availability by `ParaId`. #[pallet::storage] - pub(crate) type PendingAvailability = StorageMap< - _, - Twox64Concat, - ParaId, - CandidatePendingAvailability - >; + pub(crate) type PendingAvailability = + StorageMap<_, Twox64Concat, ParaId, CandidatePendingAvailability>; /// The commitments of candidates pending availability, by `ParaId`. #[pallet::storage] - pub(crate) type PendingAvailabilityCommitments = StorageMap< - _, - Twox64Concat, - ParaId, - CandidateCommitments - >; + pub(crate) type PendingAvailabilityCommitments = + StorageMap<_, Twox64Concat, ParaId, CandidateCommitments>; #[pallet::call] impl Pallet {} - } const LOG_TARGET: &str = "runtime::inclusion"; impl Pallet { /// Block initialization logic, called by initializer. - pub(crate) fn initializer_initialize(_now: T::BlockNumber) -> Weight { 0 } + pub(crate) fn initializer_initialize(_now: T::BlockNumber) -> Weight { + 0 + } /// Block finalization logic, called by initializer. - pub(crate) fn initializer_finalize() { } + pub(crate) fn initializer_finalize() {} /// Handle an incoming session change. pub(crate) fn initializer_on_new_session( - _notification: &crate::initializer::SessionChangeNotification + _notification: &crate::initializer::SessionChangeNotification, ) { // unlike most drain methods, drained elements are not cleared on `Drop` of the iterator // and require consumption. - for _ in >::drain() { } - for _ in >::drain() { } - for _ in >::drain() { } + for _ in >::drain() {} + for _ in >::drain() {} + for _ in >::drain() {} } /// Process a set of incoming bitfields. Return a `vec` of cores freed by candidates @@ -267,10 +258,12 @@ impl Pallet { // 3. each bitfield has exactly `expected_bits` // 4. signature is valid. let signed_bitfields = { - let occupied_bitmask: BitVec = assigned_paras_record.iter() - .map(|p| p.as_ref() - .map_or(false, |(_id, pending_availability)| pending_availability.is_some()) - ) + let occupied_bitmask: BitVec = assigned_paras_record + .iter() + .map(|p| { + p.as_ref() + .map_or(false, |(_id, pending_availability)| pending_availability.is_some()) + }) .collect(); let mut last_index = None; @@ -289,7 +282,8 @@ impl Pallet { ); ensure!( - last_index.map_or(true, |last| last < unchecked_bitfield.unchecked_validator_index()), + last_index + .map_or(true, |last| last < unchecked_bitfield.unchecked_validator_index()), Error::::BitfieldDuplicateOrUnordered, ); @@ -299,19 +293,20 @@ impl Pallet { ); ensure!( - occupied_bitmask.clone() & unchecked_bitfield.unchecked_payload().0.clone() == unchecked_bitfield.unchecked_payload().0, + occupied_bitmask.clone() & unchecked_bitfield.unchecked_payload().0.clone() == + unchecked_bitfield.unchecked_payload().0, Error::::UnoccupiedBitInBitfield, ); - let validator_public = &validators[unchecked_bitfield.unchecked_validator_index().0 as usize]; + let validator_public = + &validators[unchecked_bitfield.unchecked_validator_index().0 as usize]; last_index = Some(unchecked_bitfield.unchecked_validator_index()); signed_bitfields.push( - unchecked_bitfield.try_into_checked( - &signing_context, - validator_public, - ).map_err(|_| Error::::InvalidBitfieldSignature)? + unchecked_bitfield + .try_into_checked(&signing_context, validator_public) + .map_err(|_| Error::::InvalidBitfieldSignature)?, ); } signed_bitfields @@ -319,8 +314,8 @@ impl Pallet { let now = >::block_number(); for signed_bitfield in signed_bitfields { - for (bit_idx, _) - in signed_bitfield.payload().0.iter().enumerate().filter(|(_, is_av)| **is_av) + for (bit_idx, _) in + signed_bitfield.payload().0.iter().enumerate().filter(|(_, is_av)| **is_av) { let (_, pending_availability) = assigned_paras_record[bit_idx] .as_mut() @@ -329,7 +324,8 @@ impl Pallet { // defensive check - this is constructed by loading the availability bitfield record, // which is always `Some` if the core is occupied - that's why we're here. let val_idx = signed_bitfield.validator_index().0 as usize; - if let Some(mut bit) = pending_availability.as_mut() + if let Some(mut bit) = pending_availability + .as_mut() .and_then(|r| r.availability_votes.get_mut(val_idx)) { *bit = true; @@ -350,7 +346,8 @@ impl Pallet { let threshold = availability_threshold(validators.len()); let mut freed_cores = Vec::with_capacity(expected_bits); - for (para_id, pending_availability) in assigned_paras_record.into_iter() + for (para_id, pending_availability) in assigned_paras_record + .into_iter() .filter_map(|x| x) .filter_map(|(id, p)| p.map(|p| (id, p))) { @@ -364,8 +361,8 @@ impl Pallet { "Inclusion::process_bitfields: PendingAvailability and PendingAvailabilityCommitments are out of sync, did someone mess with the storage?", ); - continue; - } + continue + }, }; let receipt = CommittedCandidateReceipt { @@ -404,7 +401,7 @@ impl Pallet { ensure!(candidates.len() <= scheduled.len(), Error::::UnscheduledCandidate); if scheduled.is_empty() { - return Ok(Vec::new()); + return Ok(Vec::new()) } let validators = shared::Pallet::::active_validator_keys(); @@ -432,10 +429,8 @@ impl Pallet { Ok(()) }; - let signing_context = SigningContext { - parent_hash, - session_index: shared::Pallet::::session_index(), - }; + let signing_context = + SigningContext { parent_hash, session_index: shared::Pallet::::session_index() }; // We combine an outer loop over candidates with an inner loop over the scheduled, // where each iteration of the outer loop picks up at the position @@ -447,8 +442,7 @@ impl Pallet { // // In the meantime, we do certain sanity checks on the candidates and on the scheduled // list. - 'a: - for (candidate_idx, candidate) in candidates.iter().enumerate() { + 'a: for (candidate_idx, candidate) in candidates.iter().enumerate() { let para_id = candidate.descriptor().para_id; let mut backers = bitvec::bitvec![BitOrderLsb0, u8; 0; validators.len()]; @@ -464,24 +458,22 @@ impl Pallet { let validation_code_hash = >::validation_code_hash_at(para_id, now, None) - // A candidate for a parachain without current validation code is not scheduled. - .ok_or_else(|| Error::::UnscheduledCandidate)?; + // A candidate for a parachain without current validation code is not scheduled. + .ok_or_else(|| Error::::UnscheduledCandidate)?; ensure!( candidate.descriptor().validation_code_hash == validation_code_hash, Error::::InvalidValidationCodeHash, ); - if let Err(err) = check_cx - .check_validation_outputs( - para_id, - &candidate.candidate.commitments.head_data, - &candidate.candidate.commitments.new_validation_code, - candidate.candidate.commitments.processed_downward_messages, - &candidate.candidate.commitments.upward_messages, - T::BlockNumber::from(candidate.candidate.commitments.hrmp_watermark), - &candidate.candidate.commitments.horizontal_messages, - ) - { + if let Err(err) = check_cx.check_validation_outputs( + para_id, + &candidate.candidate.commitments.head_data, + &candidate.candidate.commitments.new_validation_code, + candidate.candidate.commitments.processed_downward_messages, + &candidate.candidate.commitments.upward_messages, + T::BlockNumber::from(candidate.candidate.commitments.hrmp_watermark), + &candidate.candidate.commitments.horizontal_messages, + ) { log::debug!( target: LOG_TARGET, "Validation outputs checking during inclusion of a candidate {} for parachain `{}` failed: {:?}", @@ -516,8 +508,8 @@ impl Pallet { // We don't want to error out here because it will // brick the relay-chain. So we return early without // doing anything. - return Ok(Vec::new()); - } + return Ok(Vec::new()) + }, }; let expected = persisted_validation_data.hash(); @@ -530,7 +522,7 @@ impl Pallet { ensure!( >::get(¶_id).is_none() && - >::get(¶_id).is_none(), + >::get(¶_id).is_none(), Error::::CandidateScheduledBeforeParaFree, ); @@ -542,47 +534,54 @@ impl Pallet { // check the signatures in the backing and that it is a majority. { - let maybe_amount_validated - = primitives::v1::check_candidate_backing( - &candidate, - &signing_context, - group_vals.len(), - |idx| group_vals.get(idx) + let maybe_amount_validated = primitives::v1::check_candidate_backing( + &candidate, + &signing_context, + group_vals.len(), + |idx| { + group_vals + .get(idx) .and_then(|i| validators.get(i.0 as usize)) - .map(|v| v.clone()), - ); + .map(|v| v.clone()) + }, + ); match maybe_amount_validated { Ok(amount_validated) => ensure!( amount_validated * 2 > group_vals.len(), Error::::InsufficientBacking, ), - Err(()) => { Err(Error::::InvalidBacking)?; } + Err(()) => { + Err(Error::::InvalidBacking)?; + }, } for (bit_idx, _) in candidate - .validator_indices.iter() - .enumerate().filter(|(_, signed)| **signed) + .validator_indices + .iter() + .enumerate() + .filter(|(_, signed)| **signed) { - let val_idx = group_vals.get(bit_idx) - .expect("this query done above; qed"); + let val_idx = + group_vals.get(bit_idx).expect("this query done above; qed"); backers.set(val_idx.0 as _, true); } } - core_indices_and_backers.push((assignment.core, backers, assignment.group_idx)); - continue 'a; + core_indices_and_backers.push(( + assignment.core, + backers, + assignment.group_idx, + )); + continue 'a } } // end of loop reached means that the candidate didn't appear in the non-traversed // section of the `scheduled` slice. either it was not scheduled or didn't appear in // `candidates` in the correct order. - ensure!( - false, - Error::::UnscheduledCandidate, - ); + ensure!(false, Error::::UnscheduledCandidate,); } // check remainder of scheduled cores, if any. @@ -594,13 +593,16 @@ impl Pallet { }; // one more sweep for actually writing to storage. - let core_indices = core_indices_and_backers.iter().map(|&(ref c, _, _)| c.clone()).collect(); - for (candidate, (core, backers, group)) in candidates.into_iter().zip(core_indices_and_backers) { + let core_indices = + core_indices_and_backers.iter().map(|&(ref c, _, _)| c.clone()).collect(); + for (candidate, (core, backers, group)) in + candidates.into_iter().zip(core_indices_and_backers) + { let para_id = candidate.descriptor().para_id; // initialize all availability votes to 0. - let availability_votes: BitVec - = bitvec::bitvec![BitOrderLsb0, u8; 0; validators.len()]; + let availability_votes: BitVec = + bitvec::bitvec![BitOrderLsb0, u8; 0; validators.len()]; Self::deposit_event(Event::::CandidateBacked( candidate.candidate.to_plain(), @@ -611,21 +613,22 @@ impl Pallet { let candidate_hash = candidate.candidate.hash(); - let (descriptor, commitments) = ( - candidate.candidate.descriptor, - candidate.candidate.commitments, + let (descriptor, commitments) = + (candidate.candidate.descriptor, candidate.candidate.commitments); + + >::insert( + ¶_id, + CandidatePendingAvailability { + core, + hash: candidate_hash, + descriptor, + availability_votes, + relay_parent_number, + backers, + backed_in_number: check_cx.now, + backing_group: group, + }, ); - - >::insert(¶_id, CandidatePendingAvailability { - core, - hash: candidate_hash, - descriptor, - availability_votes, - relay_parent_number, - backers, - backed_in_number: check_cx.now, - backing_group: group, - }); >::insert(¶_id, commitments); } @@ -676,14 +679,20 @@ impl Pallet { let commitments = receipt.commitments; let config = >::config(); - T::RewardValidators::reward_backing(backers.iter().enumerate() - .filter(|(_, backed)| **backed) - .map(|(i, _)| ValidatorIndex(i as _)) + T::RewardValidators::reward_backing( + backers + .iter() + .enumerate() + .filter(|(_, backed)| **backed) + .map(|(i, _)| ValidatorIndex(i as _)), ); - T::RewardValidators::reward_bitfields(availability_votes.iter().enumerate() - .filter(|(_, voted)| **voted) - .map(|(i, _)| ValidatorIndex(i as _)) + T::RewardValidators::reward_bitfields( + availability_votes + .iter() + .enumerate() + .filter(|(_, voted)| **voted) + .map(|(i, _)| ValidatorIndex(i as _)), ); // initial weight is config read. @@ -714,15 +723,19 @@ impl Pallet { commitments.horizontal_messages, ); - Self::deposit_event( - Event::::CandidateIncluded(plain, commitments.head_data.clone(), core_index, backing_group) - ); + Self::deposit_event(Event::::CandidateIncluded( + plain, + commitments.head_data.clone(), + core_index, + backing_group, + )); - weight + >::note_new_head( - receipt.descriptor.para_id, - commitments.head_data, - relay_parent_number, - ) + weight + + >::note_new_head( + receipt.descriptor.para_id, + commitments.head_data, + relay_parent_number, + ) } /// Cleans up all paras pending availability that the predicate returns true for. @@ -731,7 +744,9 @@ impl Pallet { /// since (i.e. the block number the candidate was backed at in this fork of the relay chain). /// /// Returns a vector of cleaned-up core IDs. - pub(crate) fn collect_pending(pred: impl Fn(CoreIndex, T::BlockNumber) -> bool) -> Vec { + pub(crate) fn collect_pending( + pred: impl Fn(CoreIndex, T::BlockNumber) -> bool, + ) -> Vec { let mut cleaned_up_ids = Vec::new(); let mut cleaned_up_cores = Vec::new(); @@ -797,10 +812,8 @@ impl Pallet { let commitments = >::take(¶); if let (Some(pending), Some(commitments)) = (pending, commitments) { - let candidate = CommittedCandidateReceipt { - descriptor: pending.descriptor, - commitments, - }; + let candidate = + CommittedCandidateReceipt { descriptor: pending.descriptor, commitments }; Self::enact_candidate( pending.relay_parent_number, @@ -814,9 +827,9 @@ impl Pallet { } /// Returns the `CommittedCandidateReceipt` pending availability for the para provided, if any. - pub(crate) fn candidate_pending_availability(para: ParaId) - -> Option> - { + pub(crate) fn candidate_pending_availability( + para: ParaId, + ) -> Option> { >::get(¶) .map(|p| p.descriptor) .and_then(|d| >::get(¶).map(move |c| (d, c))) @@ -825,9 +838,9 @@ impl Pallet { /// Returns the metadata around the candidate pending availability for the /// para provided, if any. - pub(crate) fn pending_availability(para: ParaId) - -> Option> - { + pub(crate) fn pending_availability( + para: ParaId, + ) -> Option> { >::get(¶) } } @@ -875,11 +888,7 @@ struct CandidateCheckContext { impl CandidateCheckContext { fn new(now: T::BlockNumber, relay_parent_number: T::BlockNumber) -> Self { - Self { - config: >::config(), - now, - relay_parent_number, - } + Self { config: >::config(), now, relay_parent_number } } /// Check the given outputs after candidate validation on whether it passes the acceptance @@ -903,14 +912,11 @@ impl CandidateCheckContext { if let Some(new_validation_code) = new_validation_code { let valid_upgrade_attempt = >::last_code_upgrade(para_id, true) .map_or(true, |last| { - last <= self.relay_parent_number - && self.relay_parent_number.saturating_sub(last) - >= self.config.validation_upgrade_frequency + last <= self.relay_parent_number && + self.relay_parent_number.saturating_sub(last) >= + self.config.validation_upgrade_frequency }); - ensure!( - valid_upgrade_attempt, - AcceptanceCheckErr::PrematureCodeUpgrade, - ); + ensure!(valid_upgrade_attempt, AcceptanceCheckErr::PrematureCodeUpgrade,); ensure!( new_validation_code.0.len() <= self.config.max_code_size as _, AcceptanceCheckErr::NewCodeTooLarge, @@ -918,16 +924,9 @@ impl CandidateCheckContext { } // check if the candidate passes the messaging acceptance criteria - >::check_processed_downward_messages( - para_id, - processed_downward_messages, - )?; + >::check_processed_downward_messages(para_id, processed_downward_messages)?; >::check_upward_messages(&self.config, para_id, upward_messages)?; - >::check_hrmp_watermark( - para_id, - self.relay_parent_number, - hrmp_watermark, - )?; + >::check_hrmp_watermark(para_id, self.relay_parent_number, hrmp_watermark)?; >::check_outbound_hrmp(&self.config, para_id, horizontal_messages)?; Ok(()) @@ -938,25 +937,29 @@ impl CandidateCheckContext { mod tests { use super::*; - use std::sync::Arc; - use futures::executor::block_on; - use primitives::{v0::PARACHAIN_KEY_TYPE_ID, v1::UncheckedSignedAvailabilityBitfield}; - use primitives::v1::{BlockNumber, Hash}; - use primitives::v1::{ - SignedAvailabilityBitfield, CompactStatement as Statement, ValidityAttestation, CollatorId, - CandidateCommitments, SignedStatement, CandidateDescriptor, ValidationCode, ValidatorId, + use crate::{ + configuration::HostConfiguration, + initializer::SessionChangeNotification, + mock::{ + new_test_ext, Configuration, MockGenesisConfig, ParaInclusion, Paras, ParasShared, + System, Test, + }, + paras::ParaGenesisArgs, + scheduler::AssignmentKind, }; - use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; + use futures::executor::block_on; use keyring::Sr25519Keyring; - use sc_keystore::LocalKeystore; - use crate::mock::{ - new_test_ext, Configuration, Paras, System, ParaInclusion, - MockGenesisConfig, Test, ParasShared, + use primitives::{ + v0::PARACHAIN_KEY_TYPE_ID, + v1::{ + BlockNumber, CandidateCommitments, CandidateDescriptor, CollatorId, + CompactStatement as Statement, Hash, SignedAvailabilityBitfield, SignedStatement, + UncheckedSignedAvailabilityBitfield, ValidationCode, ValidatorId, ValidityAttestation, + }, }; - use crate::initializer::SessionChangeNotification; - use crate::configuration::HostConfiguration; - use crate::paras::ParaGenesisArgs; - use crate::scheduler::AssignmentKind; + use sc_keystore::LocalKeystore; + use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; + use std::sync::Arc; fn default_config() -> HostConfiguration { let mut config = HostConfiguration::default(); @@ -968,11 +971,19 @@ mod tests { fn genesis_config(paras: Vec<(ParaId, bool)>) -> MockGenesisConfig { MockGenesisConfig { paras: paras::GenesisConfig { - paras: paras.into_iter().map(|(id, is_chain)| (id, ParaGenesisArgs { - genesis_head: Vec::new().into(), - validation_code: Vec::new().into(), - parachain: is_chain, - })).collect(), + paras: paras + .into_iter() + .map(|(id, is_chain)| { + ( + id, + ParaGenesisArgs { + genesis_head: Vec::new().into(), + validation_code: Vec::new().into(), + parachain: is_chain, + }, + ) + }) + .collect(), ..Default::default() }, configuration: configuration::GenesisConfig { @@ -1039,28 +1050,30 @@ mod tests { signing_context, *val_idx, &key.public().into(), - ).await.unwrap().unwrap().signature().clone(); + ) + .await + .unwrap() + .unwrap() + .signature() + .clone(); validity_votes.push(ValidityAttestation::Explicit(signature).into()); } - let backed = BackedCandidate { - candidate, - validity_votes, - validator_indices, - }; + let backed = BackedCandidate { candidate, validity_votes, validator_indices }; let should_pass = match kind { BackingKind::Unanimous | BackingKind::Threshold => true, BackingKind::Lacking => false, }; - let successfully_backed = primitives::v1::check_candidate_backing( - &backed, - signing_context, - group.len(), - |i| Some(validators[group[i].0 as usize].public().into()), - ).ok().unwrap_or(0) * 2 > group.len(); + let successfully_backed = + primitives::v1::check_candidate_backing(&backed, signing_context, group.len(), |i| { + Some(validators[group[i].0 as usize].public().into()) + }) + .ok() + .unwrap_or(0) * 2 > + group.len(); if should_pass { assert!(successfully_backed); @@ -1138,16 +1151,17 @@ mod tests { validator_index: ValidatorIndex, bitfield: AvailabilityBitfield, signing_context: &SigningContext, - ) - -> SignedAvailabilityBitfield - { + ) -> SignedAvailabilityBitfield { SignedAvailabilityBitfield::sign( &keystore, bitfield, &signing_context, validator_index, &key.public().into(), - ).await.unwrap().unwrap() + ) + .await + .unwrap() + .unwrap() } #[derive(Default)] @@ -1185,12 +1199,11 @@ mod tests { fn make_vdata_hash(para_id: ParaId) -> Option { let relay_parent_number = >::block_number() - 1; - let persisted_validation_data - = crate::util::make_persisted_validation_data::( - para_id, - relay_parent_number, - Default::default(), - )?; + let persisted_validation_data = crate::util::make_persisted_validation_data::( + para_id, + relay_parent_number, + Default::default(), + )?; Some(persisted_validation_data.hash()) } @@ -1203,28 +1216,37 @@ mod tests { let paras = vec![(chain_a, true), (chain_b, true), (thread_a, false)]; new_test_ext(genesis_config(paras)).execute_with(|| { let default_candidate = TestCandidateBuilder::default().build(); - >::insert(chain_a, CandidatePendingAvailability { - core: CoreIndex::from(0), - hash: default_candidate.hash(), - descriptor: default_candidate.descriptor.clone(), - availability_votes: default_availability_votes(), - relay_parent_number: 0, - backed_in_number: 0, - backers: default_backing_bitfield(), - backing_group: GroupIndex::from(0), - }); - PendingAvailabilityCommitments::::insert(chain_a, default_candidate.commitments.clone()); + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor.clone(), + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); + PendingAvailabilityCommitments::::insert( + chain_a, + default_candidate.commitments.clone(), + ); - >::insert(&chain_b, CandidatePendingAvailability { - core: CoreIndex::from(1), - hash: default_candidate.hash(), - descriptor: default_candidate.descriptor, - availability_votes: default_availability_votes(), - relay_parent_number: 0, - backed_in_number: 0, - backers: default_backing_bitfield(), - backing_group: GroupIndex::from(1), - }); + >::insert( + &chain_b, + CandidatePendingAvailability { + core: CoreIndex::from(1), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(1), + }, + ); PendingAvailabilityCommitments::::insert(chain_b, default_candidate.commitments); run_to_block(5, |_| None); @@ -1259,7 +1281,12 @@ mod tests { ]; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); for validator in validators.iter() { - SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap(); + SyncCryptoStore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); } let validator_public = validator_pubkeys(&validators); @@ -1267,10 +1294,8 @@ mod tests { shared::Pallet::::set_active_validators_ascending(validator_public.clone()); shared::Pallet::::set_session_index(5); - let signing_context = SigningContext { - parent_hash: System::parent_hash(), - session_index: 5, - }; + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; let core_lookup = |core| match core { core if core == CoreIndex::from(0) => Some(chain_a), @@ -1296,7 +1321,8 @@ mod tests { expected_bits(), vec![signed.into()], &core_lookup, - ).is_err()); + ) + .is_err()); } // wrong number of bits: other way around. @@ -1314,26 +1340,28 @@ mod tests { expected_bits() + 1, vec![signed.into()], &core_lookup, - ).is_err()); + ) + .is_err()); } // duplicate. { let bare_bitfield = default_bitfield(); - let signed: UncheckedSignedAvailabilityBitfield = - block_on(sign_bitfield( - &keystore, - &validators[0], - ValidatorIndex(0), - bare_bitfield, - &signing_context, - )).into(); + let signed: UncheckedSignedAvailabilityBitfield = block_on(sign_bitfield( + &keystore, + &validators[0], + ValidatorIndex(0), + bare_bitfield, + &signing_context, + )) + .into(); assert!(ParaInclusion::process_bitfields( expected_bits(), vec![signed.clone(), signed], &core_lookup, - ).is_err()); + ) + .is_err()); } // out of order. @@ -1345,7 +1373,8 @@ mod tests { ValidatorIndex(0), bare_bitfield.clone(), &signing_context, - )).into(); + )) + .into(); let signed_1 = block_on(sign_bitfield( &keystore, @@ -1353,13 +1382,15 @@ mod tests { ValidatorIndex(1), bare_bitfield, &signing_context, - )).into(); + )) + .into(); assert!(ParaInclusion::process_bitfields( expected_bits(), vec![signed_1, signed_0], &core_lookup, - ).is_err()); + ) + .is_err()); } // non-pending bit set. @@ -1378,7 +1409,8 @@ mod tests { expected_bits(), vec![signed.into()], &core_lookup, - ).is_err()); + ) + .is_err()); } // empty bitfield signed: always OK, but kind of useless. @@ -1396,7 +1428,8 @@ mod tests { expected_bits(), vec![signed.into()], &core_lookup, - ).is_ok()); + ) + .is_ok()); } // bitfield signed with pending bit signed. @@ -1406,17 +1439,23 @@ mod tests { assert_eq!(core_lookup(CoreIndex::from(0)), Some(chain_a)); let default_candidate = TestCandidateBuilder::default().build(); - >::insert(chain_a, CandidatePendingAvailability { - core: CoreIndex::from(0), - hash: default_candidate.hash(), - descriptor: default_candidate.descriptor, - availability_votes: default_availability_votes(), - relay_parent_number: 0, - backed_in_number: 0, - backers: default_backing_bitfield(), - backing_group: GroupIndex::from(0), - }); - PendingAvailabilityCommitments::::insert(chain_a, default_candidate.commitments); + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); + PendingAvailabilityCommitments::::insert( + chain_a, + default_candidate.commitments, + ); *bare_bitfield.0.get_mut(0).unwrap() = true; let signed = block_on(sign_bitfield( @@ -1431,7 +1470,8 @@ mod tests { expected_bits(), vec![signed.into()], &core_lookup, - ).is_ok()); + ) + .is_ok()); >::remove(chain_a); PendingAvailabilityCommitments::::remove(chain_a); @@ -1444,16 +1484,19 @@ mod tests { assert_eq!(core_lookup(CoreIndex::from(0)), Some(chain_a)); let default_candidate = TestCandidateBuilder::default().build(); - >::insert(chain_a, CandidatePendingAvailability { - core: CoreIndex::from(0), - hash: default_candidate.hash(), - descriptor: default_candidate.descriptor, - availability_votes: default_availability_votes(), - relay_parent_number: 0, - backed_in_number: 0, - backers: default_backing_bitfield(), - backing_group: GroupIndex::from(0), - }); + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: default_candidate.hash(), + descriptor: default_candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); *bare_bitfield.0.get_mut(0).unwrap() = true; let signed = block_on(sign_bitfield( @@ -1493,7 +1536,12 @@ mod tests { ]; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); for validator in validators.iter() { - SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap(); + SyncCryptoStore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); } let validator_public = validator_pubkeys(&validators); @@ -1501,10 +1549,8 @@ mod tests { shared::Pallet::::set_active_validators_ascending(validator_public.clone()); shared::Pallet::::set_session_index(5); - let signing_context = SigningContext { - parent_hash: System::parent_hash(), - session_index: 5, - }; + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; let core_lookup = |core| match core { core if core == CoreIndex::from(0) => Some(chain_a), @@ -1517,36 +1563,44 @@ mod tests { para_id: chain_a, head_data: vec![1, 2, 3, 4].into(), ..Default::default() - }.build(); + } + .build(); - >::insert(chain_a, CandidatePendingAvailability { - core: CoreIndex::from(0), - hash: candidate_a.hash(), - descriptor: candidate_a.descriptor, - availability_votes: default_availability_votes(), - relay_parent_number: 0, - backed_in_number: 0, - backers: backing_bitfield(&[3, 4]), - backing_group: GroupIndex::from(0), - }); + >::insert( + chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate_a.hash(), + descriptor: candidate_a.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: backing_bitfield(&[3, 4]), + backing_group: GroupIndex::from(0), + }, + ); PendingAvailabilityCommitments::::insert(chain_a, candidate_a.commitments); let candidate_b = TestCandidateBuilder { para_id: chain_b, head_data: vec![5, 6, 7, 8].into(), ..Default::default() - }.build(); + } + .build(); - >::insert(chain_b, CandidatePendingAvailability { - core: CoreIndex::from(1), - hash: candidate_b.hash(), - descriptor: candidate_b.descriptor, - availability_votes: default_availability_votes(), - relay_parent_number: 0, - backed_in_number: 0, - backers: backing_bitfield(&[0, 2]), - backing_group: GroupIndex::from(1), - }); + >::insert( + chain_b, + CandidatePendingAvailability { + core: CoreIndex::from(1), + hash: candidate_b.hash(), + descriptor: candidate_b.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 0, + backed_in_number: 0, + backers: backing_bitfield(&[0, 2]), + backing_group: GroupIndex::from(1), + }, + ); PendingAvailabilityCommitments::::insert(chain_b, candidate_b.commitments); // this bitfield signals that a and b are available. @@ -1571,49 +1625,54 @@ mod tests { // 4 of 5 first value >= 2/3 assert_eq!(threshold, 4); - let signed_bitfields = validators.iter().enumerate().filter_map(|(i, key)| { - let to_sign = if i < 3 { - a_and_b_available.clone() - } else if i < 4 { - a_available.clone() - } else { - // sign nothing. - return None - }; - - Some(block_on(sign_bitfield( - &keystore, - key, - ValidatorIndex(i as _), - to_sign, - &signing_context, - )).into()) - }).collect(); + let signed_bitfields = validators + .iter() + .enumerate() + .filter_map(|(i, key)| { + let to_sign = if i < 3 { + a_and_b_available.clone() + } else if i < 4 { + a_available.clone() + } else { + // sign nothing. + return None + }; + + Some( + block_on(sign_bitfield( + &keystore, + key, + ValidatorIndex(i as _), + to_sign, + &signing_context, + )) + .into(), + ) + }) + .collect(); assert!(ParaInclusion::process_bitfields( expected_bits(), signed_bitfields, &core_lookup, - ).is_ok()); + ) + .is_ok()); // chain A had 4 signing off, which is >= threshold. // chain B has 3 signing off, which is < threshold. assert!(>::get(&chain_a).is_none()); assert!(>::get(&chain_a).is_none()); assert!(>::get(&chain_b).is_some()); - assert_eq!( - >::get(&chain_b).unwrap().availability_votes, - { - // check that votes from first 3 were tracked. + assert_eq!(>::get(&chain_b).unwrap().availability_votes, { + // check that votes from first 3 were tracked. - let mut votes = default_availability_votes(); - *votes.get_mut(0).unwrap() = true; - *votes.get_mut(1).unwrap() = true; - *votes.get_mut(2).unwrap() = true; + let mut votes = default_availability_votes(); + *votes.get_mut(0).unwrap() = true; + *votes.get_mut(1).unwrap() = true; + *votes.get_mut(2).unwrap() = true; - votes - }, - ); + votes + },); // and check that chain head was enacted. assert_eq!(Paras::para_head(&chain_a), Some(vec![1, 2, 3, 4].into())); @@ -1658,7 +1717,12 @@ mod tests { ]; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); for validator in validators.iter() { - SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap(); + SyncCryptoStore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); } let validator_public = validator_pubkeys(&validators); @@ -1668,17 +1732,18 @@ mod tests { run_to_block(5, |_| None); - let signing_context = SigningContext { - parent_hash: System::parent_hash(), - session_index: 5, - }; + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; - let group_validators = |group_index: GroupIndex| match group_index { - group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), - group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), - group_index if group_index == GroupIndex::from(2) => Some(vec![4]), - _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), - }.map(|m| m.into_iter().map(ValidatorIndex).collect::>()); + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), + group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), + group_index if group_index == GroupIndex::from(2) => Some(vec![4]), + _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), + } + .map(|m| m.into_iter().map(ValidatorIndex).collect::>()) + }; let thread_collator: CollatorId = Sr25519Keyring::Two.public().into(); @@ -1712,11 +1777,9 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -1747,7 +1810,8 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); let mut candidate_b = TestCandidateBuilder { para_id: chain_b, relay_parent: System::parent_hash(), @@ -1755,17 +1819,12 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_b).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate_a, - ); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); - collator_sign_candidate( - Sr25519Keyring::Two, - &mut candidate_b, - ); + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_b); let backed_a = block_on(back_candidate( candidate_a, @@ -1806,11 +1865,9 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -1843,11 +1900,9 @@ mod tests { pov_hash: Hash::repeat_byte(1), persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), ..Default::default() - }.build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -1878,13 +1933,11 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); assert!(CollatorId::from(Sr25519Keyring::One.public()) != thread_collator); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -1919,13 +1972,11 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); assert_eq!(CollatorId::from(Sr25519Keyring::Two.public()), thread_collator); - collator_sign_candidate( - Sr25519Keyring::Two, - &mut candidate, - ); + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate); // change the candidate after signing. candidate.descriptor.pov_hash = Hash::repeat_byte(2); @@ -1959,12 +2010,10 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -1976,16 +2025,19 @@ mod tests { )); let candidate = TestCandidateBuilder::default().build(); - >::insert(&chain_a, CandidatePendingAvailability { - core: CoreIndex::from(0), - hash: candidate.hash(), - descriptor: candidate.descriptor, - availability_votes: default_availability_votes(), - relay_parent_number: 3, - backed_in_number: 4, - backers: default_backing_bitfield(), - backing_group: GroupIndex::from(0), - }); + >::insert( + &chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate.hash(), + descriptor: candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 3, + backed_in_number: 4, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); >::insert(&chain_a, candidate.commitments); assert_eq!( @@ -2011,15 +2063,16 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); // this is not supposed to happen - >::insert(&chain_a, candidate.commitments.clone()); + >::insert( + &chain_a, + candidate.commitments.clone(), + ); let backed = block_on(back_candidate( candidate, @@ -2053,12 +2106,10 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -2069,11 +2120,7 @@ mod tests { BackingKind::Threshold, )); - Paras::schedule_code_upgrade( - chain_a, - vec![1, 2, 3, 4].into(), - 10, - ); + Paras::schedule_code_upgrade(chain_a, vec![1, 2, 3, 4].into(), 10); assert_eq!(Paras::last_code_upgrade(chain_a, true), Some(10)); @@ -2097,12 +2144,10 @@ mod tests { persisted_validation_data_hash: [42u8; 32].into(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); + } + .build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -2134,12 +2179,10 @@ mod tests { hrmp_watermark: RELAY_PARENT_NUM, validation_code: ValidationCode(vec![1]), ..Default::default() - }.build(); + } + .build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate, - ); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate); let backed = block_on(back_candidate( candidate, @@ -2182,7 +2225,12 @@ mod tests { ]; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); for validator in validators.iter() { - SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap(); + SyncCryptoStore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); } let validator_public = validator_pubkeys(&validators); @@ -2192,17 +2240,18 @@ mod tests { run_to_block(5, |_| None); - let signing_context = SigningContext { - parent_hash: System::parent_hash(), - session_index: 5, - }; + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; - let group_validators = |group_index: GroupIndex| match group_index { - group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), - group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), - group_index if group_index == GroupIndex::from(2) => Some(vec![4]), - _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), - }.map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()); + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), + group_index if group_index == GroupIndex::from(1) => Some(vec![2, 3]), + group_index if group_index == GroupIndex::from(2) => Some(vec![4]), + _ => panic!("Group index out of bounds for 2 parachains and 1 parathread core"), + } + .map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()) + }; let thread_collator: CollatorId = Sr25519Keyring::Two.public().into(); @@ -2234,11 +2283,9 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate_a, - ); + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); let mut candidate_b = TestCandidateBuilder { para_id: chain_b, @@ -2247,11 +2294,9 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(chain_b).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate_b, - ); + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_b); let mut candidate_c = TestCandidateBuilder { para_id: thread_a, @@ -2260,11 +2305,9 @@ mod tests { persisted_validation_data_hash: make_vdata_hash(thread_a).unwrap(), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); - collator_sign_candidate( - Sr25519Keyring::Two, - &mut candidate_c, - ); + } + .build(); + collator_sign_candidate(Sr25519Keyring::Two, &mut candidate_c); let backed_a = block_on(back_candidate( candidate_a.clone(), @@ -2302,9 +2345,13 @@ mod tests { thread_a_assignment.clone(), ], &group_validators, - ).expect("candidates scheduled, in order, and backed"); + ) + .expect("candidates scheduled, in order, and backed"); - assert_eq!(occupied_cores, vec![CoreIndex::from(0), CoreIndex::from(1), CoreIndex::from(2)]); + assert_eq!( + occupied_cores, + vec![CoreIndex::from(0), CoreIndex::from(1), CoreIndex::from(2)] + ); assert_eq!( >::get(&chain_a), @@ -2379,7 +2426,12 @@ mod tests { ]; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); for validator in validators.iter() { - SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap(); + SyncCryptoStore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); } let validator_public = validator_pubkeys(&validators); @@ -2389,15 +2441,16 @@ mod tests { run_to_block(5, |_| None); - let signing_context = SigningContext { - parent_hash: System::parent_hash(), - session_index: 5, - }; + let signing_context = + SigningContext { parent_hash: System::parent_hash(), session_index: 5 }; - let group_validators = |group_index: GroupIndex| match group_index { - group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1, 2, 3, 4]), - _ => panic!("Group index out of bounds for 1 parachain"), - }.map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()); + let group_validators = |group_index: GroupIndex| { + match group_index { + group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1, 2, 3, 4]), + _ => panic!("Group index out of bounds for 1 parachain"), + } + .map(|vs| vs.into_iter().map(ValidatorIndex).collect::>()) + }; let chain_a_assignment = CoreAssignment { core: CoreIndex::from(0), @@ -2414,11 +2467,9 @@ mod tests { new_validation_code: Some(vec![1, 2, 3].into()), hrmp_watermark: RELAY_PARENT_NUM, ..Default::default() - }.build(); - collator_sign_candidate( - Sr25519Keyring::One, - &mut candidate_a, - ); + } + .build(); + collator_sign_candidate(Sr25519Keyring::One, &mut candidate_a); let backed_a = block_on(back_candidate( candidate_a.clone(), @@ -2432,11 +2483,10 @@ mod tests { let occupied_cores = ParaInclusion::process_candidates( Default::default(), vec![backed_a], - vec![ - chain_a_assignment.clone(), - ], + vec![chain_a_assignment.clone()], &group_validators, - ).expect("candidates scheduled, in order, and backed"); + ) + .expect("candidates scheduled, in order, and backed"); assert_eq!(occupied_cores, vec![CoreIndex::from(0)]); @@ -2476,7 +2526,12 @@ mod tests { ]; let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory()); for validator in validators.iter() { - SyncCryptoStore::sr25519_generate_new(&*keystore, PARACHAIN_KEY_TYPE_ID, Some(&validator.to_seed())).unwrap(); + SyncCryptoStore::sr25519_generate_new( + &*keystore, + PARACHAIN_KEY_TYPE_ID, + Some(&validator.to_seed()), + ) + .unwrap(); } let validator_public = validator_pubkeys(&validators); @@ -2484,11 +2539,8 @@ mod tests { shared::Pallet::::set_active_validators_ascending(validator_public.clone()); shared::Pallet::::set_session_index(5); - let validators_new = vec![ - Sr25519Keyring::Alice, - Sr25519Keyring::Bob, - Sr25519Keyring::Charlie, - ]; + let validators_new = + vec![Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie]; let validator_public_new = validator_pubkeys(&validators_new); @@ -2496,51 +2548,48 @@ mod tests { >::insert( &ValidatorIndex(0), - AvailabilityBitfieldRecord { - bitfield: default_bitfield(), - submitted_at: 9, - }, + AvailabilityBitfieldRecord { bitfield: default_bitfield(), submitted_at: 9 }, ); >::insert( &ValidatorIndex(1), - AvailabilityBitfieldRecord { - bitfield: default_bitfield(), - submitted_at: 9, - }, + AvailabilityBitfieldRecord { bitfield: default_bitfield(), submitted_at: 9 }, ); >::insert( &ValidatorIndex(4), - AvailabilityBitfieldRecord { - bitfield: default_bitfield(), - submitted_at: 9, - }, + AvailabilityBitfieldRecord { bitfield: default_bitfield(), submitted_at: 9 }, ); let candidate = TestCandidateBuilder::default().build(); - >::insert(&chain_a, CandidatePendingAvailability { - core: CoreIndex::from(0), - hash: candidate.hash(), - descriptor: candidate.descriptor.clone(), - availability_votes: default_availability_votes(), - relay_parent_number: 5, - backed_in_number: 6, - backers: default_backing_bitfield(), - backing_group: GroupIndex::from(0), - }); + >::insert( + &chain_a, + CandidatePendingAvailability { + core: CoreIndex::from(0), + hash: candidate.hash(), + descriptor: candidate.descriptor.clone(), + availability_votes: default_availability_votes(), + relay_parent_number: 5, + backed_in_number: 6, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(0), + }, + ); >::insert(&chain_a, candidate.commitments.clone()); - >::insert(&chain_b, CandidatePendingAvailability { - core: CoreIndex::from(1), - hash: candidate.hash(), - descriptor: candidate.descriptor, - availability_votes: default_availability_votes(), - relay_parent_number: 6, - backed_in_number: 7, - backers: default_backing_bitfield(), - backing_group: GroupIndex::from(1), - }); + >::insert( + &chain_b, + CandidatePendingAvailability { + core: CoreIndex::from(1), + hash: candidate.hash(), + descriptor: candidate.descriptor, + availability_votes: default_availability_votes(), + relay_parent_number: 6, + backed_in_number: 7, + backers: default_backing_bitfield(), + backing_group: GroupIndex::from(1), + }, + ); >::insert(&chain_b, candidate.commitments); run_to_block(11, |_| None); diff --git a/polkadot/runtime/parachains/src/initializer.rs b/polkadot/runtime/parachains/src/initializer.rs index 2db82ab1673..dc47ccc7986 100644 --- a/polkadot/runtime/parachains/src/initializer.rs +++ b/polkadot/runtime/parachains/src/initializer.rs @@ -19,15 +19,15 @@ //! //! This module can throw fatal errors if session-change notifications are received after initialization. -use sp_std::prelude::*; -use primitives::v1::{ValidatorId, SessionIndex, ConsensusLog, BlockNumber}; -use frame_support::traits::{Randomness, OneSessionHandler}; -use parity_scale_codec::{Encode, Decode}; use crate::{ configuration::{self, HostConfiguration}, disputes::DisputesHandler, - shared, paras, scheduler, inclusion, session_info, dmp, ump, hrmp, + dmp, hrmp, inclusion, paras, scheduler, session_info, shared, ump, }; +use frame_support::traits::{OneSessionHandler, Randomness}; +use parity_scale_codec::{Decode, Encode}; +use primitives::v1::{BlockNumber, ConsensusLog, SessionIndex, ValidatorId}; +use sp_std::prelude::*; pub use pallet::*; @@ -70,9 +70,9 @@ struct BufferedSessionChange { #[frame_support::pallet] pub mod pallet { + use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use super::*; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -97,7 +97,6 @@ pub mod pallet { type ForceOrigin: EnsureOrigin<::Origin>; } - /// Whether the parachains modules have been initialized within this block. /// /// Semantically a `bool`, but this guarantees it should never hit the trie, @@ -117,7 +116,8 @@ pub mod pallet { /// However this is a `Vec` regardless to handle various edge cases that may occur at runtime /// upgrade boundaries or if governance intervenes. #[pallet::storage] - pub(super) type BufferedSessionChanges = StorageValue<_, Vec, ValueQuery>; + pub(super) type BufferedSessionChanges = + StorageValue<_, Vec, ValueQuery>; #[pallet::hooks] impl Hooks> for Pallet { @@ -165,11 +165,8 @@ pub mod pallet { // next block will observe the next session. // // Note that we only apply the last session as all others lasted less than a block (weirdly). - if let Some(BufferedSessionChange { - session_index, - validators, - queued, - }) = BufferedSessionChanges::::take().pop() + if let Some(BufferedSessionChange { session_index, validators, queued }) = + BufferedSessionChanges::::take().pop() { Self::apply_new_session(session_index, validators, queued); } @@ -250,8 +247,8 @@ impl Pallet { session_index: SessionIndex, validators: I, queued: Option, - ) - where I: Iterator + ) where + I: Iterator, { let validators: Vec<_> = validators.map(|(_, v)| v).collect(); let queued: Vec<_> = if let Some(queued) = queued { @@ -264,13 +261,10 @@ impl Pallet { // Genesis session should be immediately enacted. Self::apply_new_session(0, validators, queued); } else { - BufferedSessionChanges::::mutate(|v| v.push(BufferedSessionChange { - validators, - queued, - session_index, - })); + BufferedSessionChanges::::mutate(|v| { + v.push(BufferedSessionChange { validators, queued, session_index }) + }); } - } // Allow to trigger on_new_session in tests, this is needed as long as pallet_session is not @@ -281,8 +275,8 @@ impl Pallet { session_index: SessionIndex, validators: I, queued: Option, - ) - where I: Iterator + ) where + I: Iterator, { Self::on_new_session(changed, session_index, validators, queued) } @@ -296,29 +290,31 @@ impl OneSessionHandler for Pal type Key = ValidatorId; fn on_genesis_session<'a, I: 'a>(validators: I) - where I: Iterator + where + I: Iterator, { >::on_new_session(false, 0, validators, None); } fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued: I) - where I: Iterator + where + I: Iterator, { let session_index = >::current_index(); >::on_new_session(changed, session_index, validators, Some(queued)); } - fn on_disabled(_i: usize) { } + fn on_disabled(_i: usize) {} } #[cfg(test)] mod tests { use super::*; - use primitives::v1::{Id as ParaId}; use crate::mock::{ - new_test_ext, - Initializer, System, Dmp, Paras, Configuration, SessionInfo, MockGenesisConfig, + new_test_ext, Configuration, Dmp, Initializer, MockGenesisConfig, Paras, SessionInfo, + System, }; + use primitives::v1::Id as ParaId; use frame_support::{ assert_ok, @@ -409,26 +405,24 @@ mod tests { validation_code: Default::default(), }; - new_test_ext( - MockGenesisConfig { - configuration: crate::configuration::GenesisConfig { - config: crate::configuration::HostConfiguration { - max_downward_message_size: 1024, - ..Default::default() - }, - }, - paras: crate::paras::GenesisConfig { - paras: vec![ - (a, mock_genesis.clone()), - (b, mock_genesis.clone()), - (c, mock_genesis.clone()), - ], + new_test_ext(MockGenesisConfig { + configuration: crate::configuration::GenesisConfig { + config: crate::configuration::HostConfiguration { + max_downward_message_size: 1024, ..Default::default() }, + }, + paras: crate::paras::GenesisConfig { + paras: vec![ + (a, mock_genesis.clone()), + (b, mock_genesis.clone()), + (c, mock_genesis.clone()), + ], ..Default::default() - } - ).execute_with(|| { - + }, + ..Default::default() + }) + .execute_with(|| { // enqueue downward messages to A, B and C. assert_ok!(Dmp::queue_downward_message(&Configuration::config(), a, vec![1, 2, 3])); assert_ok!(Dmp::queue_downward_message(&Configuration::config(), b, vec![4, 5, 6])); diff --git a/polkadot/runtime/parachains/src/lib.rs b/polkadot/runtime/parachains/src/lib.rs index e4341405886..1ea90bb84e6 100644 --- a/polkadot/runtime/parachains/src/lib.rs +++ b/polkadot/runtime/parachains/src/lib.rs @@ -24,18 +24,18 @@ pub mod configuration; pub mod disputes; -pub mod shared; +pub mod dmp; +pub mod hrmp; pub mod inclusion; pub mod initializer; +pub mod origin; pub mod paras; pub mod paras_inherent; +pub mod reward_points; pub mod scheduler; pub mod session_info; -pub mod origin; -pub mod dmp; +pub mod shared; pub mod ump; -pub mod hrmp; -pub mod reward_points; pub mod runtime_api_impl; @@ -44,9 +44,9 @@ mod util; #[cfg(test)] mod mock; -pub use origin::{Origin, ensure_parachain}; -use primitives::v1::Id as ParaId; +pub use origin::{ensure_parachain, Origin}; pub use paras::ParaLifecycle; +use primitives::v1::Id as ParaId; /// Schedule a para to be initialized at the start of the next session with the given genesis data. pub fn schedule_para_initialize( diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index e10dd308b28..db51cc33026 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -16,23 +16,19 @@ //! Mocks for all the traits. -use sp_io::TestExternalities; -use sp_core::H256; -use sp_runtime::traits::{ - BlakeTwo256, IdentityLookup, -}; -use primitives::v1::{ - AuthorityDiscoveryId, Balance, BlockNumber, Header, ValidatorIndex, SessionIndex, +use crate::{ + configuration, disputes, dmp, hrmp, inclusion, initializer, paras, scheduler, session_info, + shared, ump, }; -use frame_support::parameter_types; -use frame_support::traits::GenesisBuild; +use frame_support::{parameter_types, traits::GenesisBuild}; use frame_support_test::TestRandomness; -use std::cell::RefCell; -use std::collections::HashMap; -use crate::{ - inclusion, scheduler, dmp, ump, hrmp, session_info, paras, configuration, - initializer, shared, disputes, +use primitives::v1::{ + AuthorityDiscoveryId, Balance, BlockNumber, Header, SessionIndex, ValidatorIndex, }; +use sp_core::H256; +use sp_io::TestExternalities; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; +use std::{cell::RefCell, collections::HashMap}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -114,16 +110,16 @@ impl crate::initializer::Config for Test { type ForceOrigin = frame_system::EnsureRoot; } -impl crate::configuration::Config for Test { } +impl crate::configuration::Config for Test {} -impl crate::shared::Config for Test { } +impl crate::shared::Config for Test {} impl crate::paras::Config for Test { type Origin = Origin; type Event = Event; } -impl crate::dmp::Config for Test { } +impl crate::dmp::Config for Test {} parameter_types! { pub const FirstMessageFactorPercent: u64 = 100; @@ -157,7 +153,7 @@ thread_local! { impl crate::disputes::RewardValidators for Test { fn reward_dispute_statement( session: SessionIndex, - validators: impl IntoIterator + validators: impl IntoIterator, ) { REWARD_VALIDATORS.with(|r| r.borrow_mut().push((session, validators.into_iter().collect()))) } @@ -166,7 +162,7 @@ impl crate::disputes::RewardValidators for Test { impl crate::disputes::PunishValidators for Test { fn punish_for_invalid( session: SessionIndex, - validators: impl IntoIterator, + validators: impl IntoIterator, ) { PUNISH_VALIDATORS_FOR .with(|r| r.borrow_mut().push((session, validators.into_iter().collect()))) @@ -174,7 +170,7 @@ impl crate::disputes::PunishValidators for Test { fn punish_against_valid( session: SessionIndex, - validators: impl IntoIterator, + validators: impl IntoIterator, ) { PUNISH_VALIDATORS_AGAINST .with(|r| r.borrow_mut().push((session, validators.into_iter().collect()))) @@ -182,14 +178,14 @@ impl crate::disputes::PunishValidators for Test { fn punish_inconclusive( session: SessionIndex, - validators: impl IntoIterator, + validators: impl IntoIterator, ) { PUNISH_VALIDATORS_INCONCLUSIVE .with(|r| r.borrow_mut().push((session, validators.into_iter().collect()))) } } -impl crate::scheduler::Config for Test { } +impl crate::scheduler::Config for Test {} impl crate::inclusion::Config for Test { type Event = Event; @@ -197,9 +193,9 @@ impl crate::inclusion::Config for Test { type RewardValidators = TestRewardValidators; } -impl crate::paras_inherent::Config for Test { } +impl crate::paras_inherent::Config for Test {} -impl crate::session_info::Config for Test { } +impl crate::session_info::Config for Test {} thread_local! { pub static DISCOVERY_AUTHORITIES: RefCell> = RefCell::new(Vec::new()); diff --git a/polkadot/runtime/parachains/src/origin.rs b/polkadot/runtime/parachains/src/origin.rs index 6a16c3cfedf..ba4ad549c78 100644 --- a/polkadot/runtime/parachains/src/origin.rs +++ b/polkadot/runtime/parachains/src/origin.rs @@ -16,16 +16,17 @@ //! Declaration of the parachain specific origin and a pallet that hosts it. -use sp_std::result; -use sp_runtime::traits::BadOrigin; use primitives::v1::Id as ParaId; +use sp_runtime::traits::BadOrigin; +use sp_std::result; pub use pallet::*; /// Ensure that the origin `o` represents a parachain. /// Returns `Ok` with the parachain ID that effected the extrinsic or an `Err` otherwise. pub fn ensure_parachain(o: OuterOrigin) -> result::Result - where OuterOrigin: Into> +where + OuterOrigin: Into>, { match o.into() { Ok(Origin::Parachain(id)) => Ok(id), @@ -41,8 +42,8 @@ pub fn ensure_parachain(o: OuterOrigin) -> result::Result bool { - matches!(self, + matches!( + self, ParaLifecycle::Parachain | - ParaLifecycle::DowngradingParachain | - ParaLifecycle::OffboardingParachain + ParaLifecycle::DowngradingParachain | + ParaLifecycle::OffboardingParachain ) } @@ -134,10 +134,11 @@ impl ParaLifecycle { /// This also includes transitioning states, so you may want to combine /// this check with `is_stable` if you specifically want `Paralifecycle::Parathread`. pub fn is_parathread(&self) -> bool { - matches!(self, + matches!( + self, ParaLifecycle::Parathread | - ParaLifecycle::UpgradingParathread | - ParaLifecycle::OffboardingParathread + ParaLifecycle::UpgradingParathread | + ParaLifecycle::OffboardingParathread ) } @@ -196,8 +197,8 @@ impl ParaPastCodeMeta { // The earliest stored code replacement needs to be special-cased, since we need to check // against the pruning state to see if this replacement represents the correct code, or // is simply after a replacement that actually represents the correct code, but has been pruned. - let was_pruned = replaced_after_pos == 0 - && self.last_pruned.map_or(false, |t| t >= para_at); + let was_pruned = + replaced_after_pos == 0 && self.last_pruned.map_or(false, |t| t >= para_at); if was_pruned { None @@ -210,10 +211,12 @@ impl ParaPastCodeMeta { // we don't know the code necessary anymore. Compare against `last_pruned` to determine. self.last_pruned.as_ref().map_or( Some(UseCodeAt::Current), // nothing pruned, use current - |earliest_activation| if ¶_at < earliest_activation { - None - } else { - Some(UseCodeAt::Current) + |earliest_activation| { + if ¶_at < earliest_activation { + None + } else { + Some(UseCodeAt::Current) + } }, ) } @@ -235,7 +238,7 @@ impl ParaPastCodeMeta { // // returns an iterator of block numbers at which code was replaced, where the replaced // code should be now pruned, in ascending order. - fn prune_up_to(&'_ mut self, max: N) -> impl Iterator + '_ { + fn prune_up_to(&'_ mut self, max: N) -> impl Iterator + '_ { let to_prune = self.upgrade_times.iter().take_while(|t| t.activated_at <= max).count(); let drained = if to_prune == 0 { // no-op prune. @@ -271,11 +274,7 @@ pub mod pallet { pub struct Pallet(_); #[pallet::config] - pub trait Config: - frame_system::Config + - configuration::Config + - shared::Config - { + pub trait Config: frame_system::Config + configuration::Config + shared::Config { /// The outer origin type. type Origin: From + From<::Origin> @@ -331,32 +330,24 @@ pub mod pallet { /// /// Corresponding code can be retrieved with [`CodeByHash`]. #[pallet::storage] - pub(super) type CurrentCodeHash = StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>; + pub(super) type CurrentCodeHash = + StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>; /// Actual past code hash, indicated by the para id as well as the block number at which it /// became outdated. /// /// Corresponding code can be retrieved with [`CodeByHash`]. #[pallet::storage] - pub(super) type PastCodeHash = StorageMap< - _, - Twox64Concat, - (ParaId, T::BlockNumber), - ValidationCodeHash - >; + pub(super) type PastCodeHash = + StorageMap<_, Twox64Concat, (ParaId, T::BlockNumber), ValidationCodeHash>; /// Past code of parachains. The parachains themselves may not be registered anymore, /// but we also keep their code on-chain for the same amount of time as outdated code /// to keep it available for secondary checkers. #[pallet::storage] #[pallet::getter(fn past_code_meta)] - pub(super) type PastCodeMeta = StorageMap< - _, - Twox64Concat, - ParaId, - ParaPastCodeMeta, - ValueQuery - >; + pub(super) type PastCodeMeta = + StorageMap<_, Twox64Concat, ParaId, ParaPastCodeMeta, ValueQuery>; /// Which paras have past code that needs pruning and the relay-chain block at which the code was replaced. /// Note that this is the actual height of the included block, not the expected height at which the @@ -365,33 +356,39 @@ pub mod pallet { /// from the time at which the parachain perceives a code upgrade as having occurred. /// Multiple entries for a single para are permitted. Ordered ascending by block number. #[pallet::storage] - pub(super) type PastCodePruning = StorageValue<_, Vec<(ParaId, T::BlockNumber)>, ValueQuery>; + pub(super) type PastCodePruning = + StorageValue<_, Vec<(ParaId, T::BlockNumber)>, ValueQuery>; /// The block number at which the planned code change is expected for a para. /// The change will be applied after the first parablock for this ID included which executes /// in the context of a relay chain block with a number >= `expected_at`. #[pallet::storage] #[pallet::getter(fn future_code_upgrade_at)] - pub(super) type FutureCodeUpgrades = StorageMap<_, Twox64Concat, ParaId, T::BlockNumber>; + pub(super) type FutureCodeUpgrades = + StorageMap<_, Twox64Concat, ParaId, T::BlockNumber>; /// The actual future code hash of a para. /// /// Corresponding code can be retrieved with [`CodeByHash`]. #[pallet::storage] - pub(super) type FutureCodeHash = StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>; + pub(super) type FutureCodeHash = + StorageMap<_, Twox64Concat, ParaId, ValidationCodeHash>; /// The actions to perform during the start of a specific session index. #[pallet::storage] #[pallet::getter(fn actions_queue)] - pub(super) type ActionsQueue = StorageMap<_, Twox64Concat, SessionIndex, Vec, ValueQuery>; + pub(super) type ActionsQueue = + StorageMap<_, Twox64Concat, SessionIndex, Vec, ValueQuery>; /// Upcoming paras instantiation arguments. #[pallet::storage] - pub(super) type UpcomingParasGenesis = StorageMap<_, Twox64Concat, ParaId, ParaGenesisArgs>; + pub(super) type UpcomingParasGenesis = + StorageMap<_, Twox64Concat, ParaId, ParaGenesisArgs>; /// The number of reference on the validation code in [`CodeByHash`] storage. #[pallet::storage] - pub(super) type CodeByHashRefs = StorageMap<_, Identity, ValidationCodeHash, u32, ValueQuery>; + pub(super) type CodeByHashRefs = + StorageMap<_, Identity, ValidationCodeHash, u32, ValueQuery>; /// Validation code stored by its hash. /// @@ -399,7 +396,8 @@ pub mod pallet { /// [`PastCodeHash`]. #[pallet::storage] #[pallet::getter(fn code_by_hash)] - pub(super) type CodeByHash = StorageMap<_, Identity, ValidationCodeHash, ValidationCode>; + pub(super) type CodeByHash = + StorageMap<_, Identity, ValidationCodeHash, ValidationCode>; #[pallet::genesis_config] pub struct GenesisConfig { @@ -409,16 +407,15 @@ pub mod pallet { #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { - GenesisConfig { - paras: Default::default(), - } + GenesisConfig { paras: Default::default() } } } #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - let mut parachains: Vec<_> = self.paras + let mut parachains: Vec<_> = self + .paras .iter() .filter(|(_, args)| args.parachain) .map(|&(ref id, _)| id) @@ -451,7 +448,11 @@ pub mod pallet { impl Pallet { /// Set the storage for the parachain validation code immediately. #[pallet::weight(0)] - pub fn force_set_current_code(origin: OriginFor, para: ParaId, new_code: ValidationCode) -> DispatchResult { + pub fn force_set_current_code( + origin: OriginFor, + para: ParaId, + new_code: ValidationCode, + ) -> DispatchResult { ensure_root(origin)?; let prior_code_hash = ::CurrentCodeHash::get(¶).unwrap_or_default(); let new_code_hash = new_code.hash(); @@ -466,7 +467,11 @@ pub mod pallet { /// Set the storage for the current parachain head data immediately. #[pallet::weight(0)] - pub fn force_set_current_head(origin: OriginFor, para: ParaId, new_head: HeadData) -> DispatchResult { + pub fn force_set_current_head( + origin: OriginFor, + para: ParaId, + new_head: HeadData, + ) -> DispatchResult { ensure_root(origin)?; ::Heads::insert(¶, new_head); Self::deposit_event(Event::CurrentHeadUpdated(para)); @@ -479,7 +484,7 @@ pub mod pallet { origin: OriginFor, para: ParaId, new_code: ValidationCode, - expected_at: T::BlockNumber + expected_at: T::BlockNumber, ) -> DispatchResult { ensure_root(origin)?; Self::schedule_code_upgrade(para, new_code, expected_at); @@ -489,7 +494,11 @@ pub mod pallet { /// Note a new block head for para within the context of the current block. #[pallet::weight(0)] - pub fn force_note_new_head(origin: OriginFor, para: ParaId, new_head: HeadData) -> DispatchResult { + pub fn force_note_new_head( + origin: OriginFor, + para: ParaId, + new_head: HeadData, + ) -> DispatchResult { ensure_root(origin)?; let now = frame_system::Pallet::::block_number(); Self::note_new_head(para, new_head, now); @@ -522,12 +531,14 @@ impl Pallet { } /// Called by the initializer to finalize the configuration pallet. - pub(crate) fn initializer_finalize() { } + pub(crate) fn initializer_finalize() {} /// Called by the initializer to note that a new session has started. /// /// Returns the list of outgoing paras from the actions queue. - pub(crate) fn initializer_on_new_session(notification: &SessionChangeNotification) -> Vec { + pub(crate) fn initializer_on_new_session( + notification: &SessionChangeNotification, + ) -> Vec { let outgoing_paras = Self::apply_actions_queue(notification.session_index); outgoing_paras } @@ -564,7 +575,8 @@ impl Pallet { for para in actions { let lifecycle = ParaLifecycles::::get(¶); match lifecycle { - None | Some(ParaLifecycle::Parathread) | Some(ParaLifecycle::Parachain) => { /* Nothing to do... */ }, + None | Some(ParaLifecycle::Parathread) | Some(ParaLifecycle::Parachain) => { /* Nothing to do... */ + }, // Onboard a new parathread or parachain. Some(ParaLifecycle::Onboarding) => { if let Some(genesis_data) = ::UpcomingParasGenesis::take(¶) { @@ -598,7 +610,8 @@ impl Pallet { ParaLifecycles::::insert(¶, ParaLifecycle::Parathread); }, // Offboard a parathread or parachain from the system - Some(ParaLifecycle::OffboardingParachain) | Some(ParaLifecycle::OffboardingParathread) => { + Some(ParaLifecycle::OffboardingParachain) | + Some(ParaLifecycle::OffboardingParathread) => { if let Ok(i) = parachains.binary_search(¶) { parachains.remove(i); } @@ -648,8 +661,8 @@ impl Pallet { // Schedule pruning for this past-code to be removed as soon as it // exits the slashing window. ::PastCodePruning::mutate(|pruning| { - let insert_idx = pruning.binary_search_by_key(&at, |&(_, b)| b) - .unwrap_or_else(|idx| idx); + let insert_idx = + pruning.binary_search_by_key(&at, |&(_, b)| b).unwrap_or_else(|idx| idx); pruning.insert(insert_idx, (id, now)); }); @@ -663,19 +676,18 @@ impl Pallet { let code_retention_period = config.code_retention_period; if now <= code_retention_period { let weight = T::DbWeight::get().reads_writes(1, 0); - return weight; + return weight } // The height of any changes we no longer should keep around. let pruning_height = now - (code_retention_period + One::one()); - let pruning_tasks_done = - ::PastCodePruning::mutate(|pruning_tasks: &mut Vec<(_, T::BlockNumber)>| { + let pruning_tasks_done = ::PastCodePruning::mutate( + |pruning_tasks: &mut Vec<(_, T::BlockNumber)>| { let (pruning_tasks_done, pruning_tasks_to_do) = { // find all past code that has just exited the pruning window. - let up_to_idx = pruning_tasks.iter() - .take_while(|&(_, at)| at <= &pruning_height) - .count(); + let up_to_idx = + pruning_tasks.iter().take_while(|&(_, at)| at <= &pruning_height).count(); (up_to_idx, pruning_tasks.drain(..up_to_idx)) }; @@ -707,7 +719,8 @@ impl Pallet { } pruning_tasks_done as u64 - }); + }, + ); // 1 read for the meta for each pruning task, 1 read for the config // 2 writes: updating the meta and pruning the code @@ -751,9 +764,7 @@ impl Pallet { let lifecycle = ParaLifecycles::::get(&id); match lifecycle { // If para is not registered, nothing to do! - None => { - return Ok(()) - }, + None => return Ok(()), Some(ParaLifecycle::Parathread) => { ParaLifecycles::::insert(&id, ParaLifecycle::OffboardingParathread); }, @@ -864,12 +875,7 @@ impl Pallet { // `now` is only used for registering pruning as part of `fn note_past_code` let now = >::block_number(); - let weight = Self::note_past_code( - id, - expected_at, - now, - prior_code_hash, - ); + let weight = Self::note_past_code(id, expected_at, now, prior_code_hash); // add 1 to writes due to heads update. weight + T::DbWeight::get().reads_writes(3, 1 + 3) @@ -897,7 +903,7 @@ impl Pallet { assume_intermediate: Option, ) -> Option { if assume_intermediate.as_ref().map_or(false, |i| &at <= i) { - return None; + return None } let planned_upgrade = ::FutureCodeUpgrades::get(&id); @@ -912,7 +918,8 @@ impl Pallet { match Self::past_code_meta(&id).code_at(at) { None => None, Some(UseCodeAt::Current) => CurrentCodeHash::::get(&id), - Some(UseCodeAt::ReplacedAt(replaced)) => ::PastCodeHash::get(&(id, replaced)), + Some(UseCodeAt::ReplacedAt(replaced)) => + ::PastCodeHash::get(&(id, replaced)), } } } @@ -960,7 +967,7 @@ impl Pallet { pub(crate) fn last_code_upgrade(id: ParaId, include_future: bool) -> Option { if include_future { if let Some(at) = Self::future_code_upgrade_at(id) { - return Some(at); + return Some(at) } } @@ -1013,11 +1020,13 @@ impl Pallet { #[cfg(test)] mod tests { use super::*; - use primitives::v1::BlockNumber; use frame_support::assert_ok; + use primitives::v1::BlockNumber; - use crate::mock::{new_test_ext, Paras, ParasShared, System, MockGenesisConfig}; - use crate::configuration::HostConfiguration; + use crate::{ + configuration::HostConfiguration, + mock::{new_test_ext, MockGenesisConfig, Paras, ParasShared, System}, + }; fn run_to_block(to: BlockNumber, new_session: Option>) { while System::block_number() < to { @@ -1045,7 +1054,10 @@ mod tests { } } - fn upgrade_at(expected_at: BlockNumber, activated_at: BlockNumber) -> ReplacementTimes { + fn upgrade_at( + expected_at: BlockNumber, + activated_at: BlockNumber, + ) -> ReplacementTimes { ReplacementTimes { expected_at, activated_at } } @@ -1103,7 +1115,6 @@ mod tests { assert_eq!(past_code.code_at(24), Some(UseCodeAt::ReplacedAt(20))); assert_eq!(past_code.code_at(25), Some(UseCodeAt::ReplacedAt(30))); assert_eq!(past_code.code_at(30), Some(UseCodeAt::Current)); - } #[test] @@ -1118,66 +1129,80 @@ mod tests { assert_eq!(old, past_code); assert_eq!(past_code.prune_up_to(10).collect::>(), vec![10]); - assert_eq!(past_code, ParaPastCodeMeta { - upgrade_times: vec![upgrade_at(20, 25), upgrade_at(30, 35)], - last_pruned: Some(10), - }); + assert_eq!( + past_code, + ParaPastCodeMeta { + upgrade_times: vec![upgrade_at(20, 25), upgrade_at(30, 35)], + last_pruned: Some(10), + } + ); assert!(past_code.prune_up_to(21).collect::>().is_empty()); assert_eq!(past_code.prune_up_to(26).collect::>(), vec![20]); - assert_eq!(past_code, ParaPastCodeMeta { - upgrade_times: vec![upgrade_at(30, 35)], - last_pruned: Some(25), - }); + assert_eq!( + past_code, + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(30, 35)], last_pruned: Some(25) } + ); past_code.note_replacement(40, 42); past_code.note_replacement(50, 53); past_code.note_replacement(60, 66); - assert_eq!(past_code, ParaPastCodeMeta { - upgrade_times: vec![upgrade_at(30, 35), upgrade_at(40, 42), upgrade_at(50, 53), upgrade_at(60, 66)], - last_pruned: Some(25), - }); + assert_eq!( + past_code, + ParaPastCodeMeta { + upgrade_times: vec![ + upgrade_at(30, 35), + upgrade_at(40, 42), + upgrade_at(50, 53), + upgrade_at(60, 66) + ], + last_pruned: Some(25), + } + ); assert_eq!(past_code.prune_up_to(60).collect::>(), vec![30, 40, 50]); - assert_eq!(past_code, ParaPastCodeMeta { - upgrade_times: vec![upgrade_at(60, 66)], - last_pruned: Some(53), - }); + assert_eq!( + past_code, + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(60, 66)], last_pruned: Some(53) } + ); assert_eq!(past_code.most_recent_change(), Some(60)); assert_eq!(past_code.prune_up_to(66).collect::>(), vec![60]); - assert_eq!(past_code, ParaPastCodeMeta { - upgrade_times: Vec::new(), - last_pruned: Some(66), - }); + assert_eq!( + past_code, + ParaPastCodeMeta { upgrade_times: Vec::new(), last_pruned: Some(66) } + ); } #[test] fn para_past_code_pruning_in_initialize() { let code_retention_period = 10; let paras = vec![ - (0u32.into(), ParaGenesisArgs { - parachain: true, - genesis_head: Default::default(), - validation_code: Default::default(), - }), - (1u32.into(), ParaGenesisArgs { - parachain: false, - genesis_head: Default::default(), - validation_code: Default::default(), - }), + ( + 0u32.into(), + ParaGenesisArgs { + parachain: true, + genesis_head: Default::default(), + validation_code: Default::default(), + }, + ), + ( + 1u32.into(), + ParaGenesisArgs { + parachain: false, + genesis_head: Default::default(), + validation_code: Default::default(), + }, + ), ]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - code_retention_period, - ..Default::default() - }, + config: HostConfiguration { code_retention_period, ..Default::default() }, ..Default::default() }, ..Default::default() @@ -1200,11 +1225,17 @@ mod tests { } let pruned_at: BlockNumber = included_block + code_retention_period + 1; - assert_eq!(::PastCodeHash::get(&(id, at_block)), Some(validation_code.hash())); + assert_eq!( + ::PastCodeHash::get(&(id, at_block)), + Some(validation_code.hash()) + ); check_code_is_stored(&validation_code); run_to_block(pruned_at - 1, None); - assert_eq!(::PastCodeHash::get(&(id, at_block)), Some(validation_code.hash())); + assert_eq!( + ::PastCodeHash::get(&(id, at_block)), + Some(validation_code.hash()) + ); assert_eq!(Paras::past_code_meta(&id).most_recent_change(), Some(at_block)); check_code_is_stored(&validation_code); @@ -1218,21 +1249,19 @@ mod tests { #[test] fn note_new_head_sets_head() { let code_retention_period = 10; - let paras = vec![ - (0u32.into(), ParaGenesisArgs { + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { parachain: true, genesis_head: Default::default(), validation_code: Default::default(), - }), - ]; + }, + )]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - code_retention_period, - ..Default::default() - }, + config: HostConfiguration { code_retention_period, ..Default::default() }, ..Default::default() }, ..Default::default() @@ -1253,25 +1282,28 @@ mod tests { fn note_past_code_sets_up_pruning_correctly() { let code_retention_period = 10; let paras = vec![ - (0u32.into(), ParaGenesisArgs { - parachain: true, - genesis_head: Default::default(), - validation_code: Default::default(), - }), - (1u32.into(), ParaGenesisArgs { - parachain: false, - genesis_head: Default::default(), - validation_code: Default::default(), - }), + ( + 0u32.into(), + ParaGenesisArgs { + parachain: true, + genesis_head: Default::default(), + validation_code: Default::default(), + }, + ), + ( + 1u32.into(), + ParaGenesisArgs { + parachain: false, + genesis_head: Default::default(), + validation_code: Default::default(), + }, + ), ]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - code_retention_period, - ..Default::default() - }, + config: HostConfiguration { code_retention_period, ..Default::default() }, ..Default::default() }, ..Default::default() @@ -1287,17 +1319,11 @@ mod tests { assert_eq!(::PastCodePruning::get(), vec![(id_a, 12), (id_b, 23)]); assert_eq!( Paras::past_code_meta(&id_a), - ParaPastCodeMeta { - upgrade_times: vec![upgrade_at(10, 12)], - last_pruned: None, - } + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(10, 12)], last_pruned: None } ); assert_eq!( Paras::past_code_meta(&id_b), - ParaPastCodeMeta { - upgrade_times: vec![upgrade_at(20, 23)], - last_pruned: None, - } + ParaPastCodeMeta { upgrade_times: vec![upgrade_at(20, 23)], last_pruned: None } ); }); } @@ -1308,13 +1334,14 @@ mod tests { let validation_upgrade_delay = 5; let original_code = ValidationCode(vec![1, 2, 3]); - let paras = vec![ - (0u32.into(), ParaGenesisArgs { + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { parachain: true, genesis_head: Default::default(), validation_code: original_code.clone(), - }), - ]; + }, + )]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, @@ -1376,10 +1403,7 @@ mod tests { { Paras::note_new_head(para_id, Default::default(), expected_at); - assert_eq!( - Paras::past_code_meta(¶_id).most_recent_change(), - Some(expected_at), - ); + assert_eq!(Paras::past_code_meta(¶_id).most_recent_change(), Some(expected_at),); assert_eq!( ::PastCodeHash::get(&(para_id, expected_at)), Some(original_code.hash()), @@ -1399,13 +1423,14 @@ mod tests { let validation_upgrade_delay = 5; let original_code = ValidationCode(vec![1, 2, 3]); - let paras = vec![ - (0u32.into(), ParaGenesisArgs { + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { parachain: true, genesis_head: Default::default(), validation_code: original_code.clone(), - }), - ]; + }, + )]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, @@ -1448,10 +1473,7 @@ mod tests { { Paras::note_new_head(para_id, Default::default(), expected_at + 4); - assert_eq!( - Paras::past_code_meta(¶_id).most_recent_change(), - Some(expected_at), - ); + assert_eq!(Paras::past_code_meta(¶_id).most_recent_change(), Some(expected_at),); // Some hypothetical block which would have triggered the code change // should still use the old code. @@ -1489,21 +1511,19 @@ mod tests { fn submit_code_change_when_not_allowed_is_err() { let code_retention_period = 10; - let paras = vec![ - (0u32.into(), ParaGenesisArgs { + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { parachain: true, genesis_head: Default::default(), validation_code: vec![1, 2, 3].into(), - }), - ]; + }, + )]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - code_retention_period, - ..Default::default() - }, + config: HostConfiguration { code_retention_period, ..Default::default() }, ..Default::default() }, ..Default::default() @@ -1533,21 +1553,19 @@ mod tests { let code_retention_period = 10; let original_code = ValidationCode(vec![1, 2, 3]); - let paras = vec![ - (0u32.into(), ParaGenesisArgs { + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { parachain: true, genesis_head: Default::default(), validation_code: original_code.clone(), - }), - ]; + }, + )]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - code_retention_period, - ..Default::default() - }, + config: HostConfiguration { code_retention_period, ..Default::default() }, ..Default::default() }, ..Default::default() @@ -1600,12 +1618,15 @@ mod tests { } // run to block #4, with a 2 session changes at the end of the block 2 & 3. - run_to_block(4, Some(vec![3,4])); + run_to_block(4, Some(vec![3, 4])); // cleaning up the parachain should place the current parachain code // into the past code buffer & schedule cleanup. assert_eq!(Paras::past_code_meta(¶_id).most_recent_change(), Some(3)); - assert_eq!(::PastCodeHash::get(&(para_id, 3)), Some(original_code.hash())); + assert_eq!( + ::PastCodeHash::get(&(para_id, 3)), + Some(original_code.hash()) + ); assert_eq!(::PastCodePruning::get(), vec![(para_id, 3)]); check_code_is_stored(&original_code); @@ -1688,9 +1709,8 @@ mod tests { assert_eq!(::ParaLifecycles::get(&b), Some(ParaLifecycle::Onboarding)); assert_eq!(::ParaLifecycles::get(&c), Some(ParaLifecycle::Onboarding)); - // Two sessions pass, so action queue is triggered - run_to_block(4, Some(vec![3,4])); + run_to_block(4, Some(vec![3, 4])); assert_eq!(Paras::parachains(), vec![c, b]); assert_eq!(::ActionsQueue::get(Paras::scheduled_session()), Vec::new()); @@ -1710,21 +1730,19 @@ mod tests { fn code_hash_at_with_intermediate() { let code_retention_period = 10; - let paras = vec![ - (0u32.into(), ParaGenesisArgs { + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { parachain: true, genesis_head: Default::default(), validation_code: vec![1, 2, 3].into(), - }), - ]; + }, + )]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - code_retention_period, - ..Default::default() - }, + config: HostConfiguration { code_retention_period, ..Default::default() }, ..Default::default() }, ..Default::default() @@ -1762,21 +1780,19 @@ mod tests { fn code_hash_at_returns_up_to_end_of_code_retention_period() { let code_retention_period = 10; - let paras = vec![ - (0u32.into(), ParaGenesisArgs { + let paras = vec![( + 0u32.into(), + ParaGenesisArgs { parachain: true, genesis_head: Default::default(), validation_code: vec![1, 2, 3].into(), - }), - ]; + }, + )]; let genesis_config = MockGenesisConfig { paras: GenesisConfig { paras, ..Default::default() }, configuration: crate::configuration::GenesisConfig { - config: HostConfiguration { - code_retention_period, - ..Default::default() - }, + config: HostConfiguration { code_retention_period, ..Default::default() }, ..Default::default() }, ..Default::default() @@ -1791,10 +1807,7 @@ mod tests { run_to_block(10, None); Paras::note_new_head(para_id, Default::default(), 7); - assert_eq!( - Paras::past_code_meta(¶_id).upgrade_times, - vec![upgrade_at(2, 10)], - ); + assert_eq!(Paras::past_code_meta(¶_id).upgrade_times, vec![upgrade_at(2, 10)],); assert_eq!(fetch_validation_code_at(para_id, 2, None), Some(old_code.clone())); assert_eq!(fetch_validation_code_at(para_id, 3, None), Some(old_code.clone())); @@ -1814,10 +1827,7 @@ mod tests { assert_eq!( Paras::past_code_meta(¶_id), - ParaPastCodeMeta { - upgrade_times: Vec::new(), - last_pruned: Some(10), - }, + ParaPastCodeMeta { upgrade_times: Vec::new(), last_pruned: Some(10) }, ); assert_eq!(fetch_validation_code_at(para_id, 2, None), None); // pruned :( diff --git a/polkadot/runtime/parachains/src/paras_inherent.rs b/polkadot/runtime/parachains/src/paras_inherent.rs index d679035c4b4..fba7107e7f6 100644 --- a/polkadot/runtime/parachains/src/paras_inherent.rs +++ b/polkadot/runtime/parachains/src/paras_inherent.rs @@ -21,26 +21,26 @@ //! as it has no initialization logic and its finalization logic depends only on the details of //! this module. -use sp_std::prelude::*; -use sp_runtime::traits::Header as HeaderT; -use primitives::v1::{ - BackedCandidate, PARACHAINS_INHERENT_IDENTIFIER, InherentData as ParachainsInherentData, +use crate::{ + disputes::DisputesHandler, + inclusion, + scheduler::{self, FreedReason}, + shared, ump, }; use frame_support::{ - decl_error, decl_module, decl_storage, ensure, + decl_error, decl_module, decl_storage, dispatch::DispatchResultWithPostInfo, - weights::{DispatchClass, Weight}, + ensure, + inherent::{InherentData, InherentIdentifier, MakeFatalError, ProvideInherent}, traits::Get, - inherent::{InherentIdentifier, InherentData, MakeFatalError, ProvideInherent}, + weights::{DispatchClass, Weight}, }; use frame_system::ensure_none; -use crate::{ - disputes::DisputesHandler, - inclusion, - scheduler::{self, FreedReason}, - shared, - ump, +use primitives::v1::{ + BackedCandidate, InherentData as ParachainsInherentData, PARACHAINS_INHERENT_IDENTIFIER, }; +use sp_runtime::traits::Header as HeaderT; +use sp_std::prelude::*; const LOG_TARGET: &str = "runtime::inclusion-inherent"; // In the future, we should benchmark these consts; these are all untested assumptions for now. @@ -249,7 +249,7 @@ fn limit_backed_candidates( return false } - code_upgrades +=1; + code_upgrades += 1; } true @@ -258,7 +258,9 @@ fn limit_backed_candidates( // the weight of the paras inherent is already included in the current block weight, // so our operation is simple: if the block is currently overloaded, make this intrinsic smaller - if frame_system::Pallet::::block_weight().total() > ::BlockWeights::get().max_block { + if frame_system::Pallet::::block_weight().total() > + ::BlockWeights::get().max_block + { Vec::new() } else { backed_candidates @@ -271,47 +273,41 @@ impl ProvideInherent for Module { const INHERENT_IDENTIFIER: InherentIdentifier = PARACHAINS_INHERENT_IDENTIFIER; fn create_inherent(data: &InherentData) -> Option { - let mut inherent_data: ParachainsInherentData - = match data.get_data(&Self::INHERENT_IDENTIFIER) - { - Ok(Some(d)) => d, - Ok(None) => return None, - Err(_) => { - log::warn!( - target: LOG_TARGET, - "ParachainsInherentData failed to decode", - ); - - return None; - } - }; + let mut inherent_data: ParachainsInherentData = + match data.get_data(&Self::INHERENT_IDENTIFIER) { + Ok(Some(d)) => d, + Ok(None) => return None, + Err(_) => { + log::warn!(target: LOG_TARGET, "ParachainsInherentData failed to decode",); + + return None + }, + }; // filter out any unneeded dispute statements T::DisputesHandler::filter_multi_dispute_data(&mut inherent_data.disputes); // Sanity check: session changes can invalidate an inherent, and we _really_ don't want that to happen. // See github.com/paritytech/polkadot/issues/1327 - let inherent_data = match Self::enter( - frame_system::RawOrigin::None.into(), - inherent_data.clone(), - ) { - Ok(_) => inherent_data, - Err(err) => { - log::warn!( - target: LOG_TARGET, - "dropping signed_bitfields and backed_candidates because they produced \ + let inherent_data = + match Self::enter(frame_system::RawOrigin::None.into(), inherent_data.clone()) { + Ok(_) => inherent_data, + Err(err) => { + log::warn!( + target: LOG_TARGET, + "dropping signed_bitfields and backed_candidates because they produced \ an invalid paras inherent: {:?}", - err, - ); - - ParachainsInherentData { - bitfields: Vec::new(), - backed_candidates: Vec::new(), - disputes: Vec::new(), - parent_header: inherent_data.parent_header, - } - } - }; + err, + ); + + ParachainsInherentData { + bitfields: Vec::new(), + backed_candidates: Vec::new(), + disputes: Vec::new(), + parent_header: inherent_data.parent_header, + } + }, + }; Some(Call::enter(inherent_data)) } @@ -325,9 +321,7 @@ impl ProvideInherent for Module { mod tests { use super::*; - use crate::mock::{ - new_test_ext, System, MockGenesisConfig, Test - }; + use crate::mock::{new_test_ext, MockGenesisConfig, System, Test}; mod limit_backed_candidates { use super::*; @@ -345,7 +339,8 @@ mod tests { fn does_not_truncate_on_exactly_full_block() { new_test_ext(MockGenesisConfig::default()).execute_with(|| { let backed_candidates = vec![BackedCandidate::default()]; - let max_block_weight = ::BlockWeights::get().max_block; + let max_block_weight = + ::BlockWeights::get().max_block; // if the consumed resources are precisely equal to the max block weight, we do not truncate. System::set_block_consumed_resources(max_block_weight, 0); assert_eq!(limit_backed_candidates::(backed_candidates).len(), 1); @@ -356,7 +351,8 @@ mod tests { fn truncates_on_over_full_block() { new_test_ext(MockGenesisConfig::default()).execute_with(|| { let backed_candidates = vec![BackedCandidate::default()]; - let max_block_weight = ::BlockWeights::get().max_block; + let max_block_weight = + ::BlockWeights::get().max_block; // if the consumed resources are precisely equal to the max block weight, we do not truncate. System::set_block_consumed_resources(max_block_weight + 1, 0); assert_eq!(limit_backed_candidates::(backed_candidates).len(), 0); @@ -367,7 +363,8 @@ mod tests { fn all_backed_candidates_get_truncated() { new_test_ext(MockGenesisConfig::default()).execute_with(|| { let backed_candidates = vec![BackedCandidate::default(); 10]; - let max_block_weight = ::BlockWeights::get().max_block; + let max_block_weight = + ::BlockWeights::get().max_block; // if the consumed resources are precisely equal to the max block weight, we do not truncate. System::set_block_consumed_resources(max_block_weight + 1, 0); assert_eq!(limit_backed_candidates::(backed_candidates).len(), 0); @@ -388,9 +385,7 @@ mod tests { mod paras_inherent_weight { use super::*; - use crate::mock::{ - new_test_ext, System, MockGenesisConfig, Test - }; + use crate::mock::{new_test_ext, MockGenesisConfig, System, Test}; use primitives::v1::Header; use frame_support::traits::UnfilteredDispatchable; @@ -425,7 +420,8 @@ mod tests { (backed_candidates.len() as Weight * BACKED_CANDIDATE_WEIGHT); // we've used half the block weight; there's plenty of margin - let max_block_weight = ::BlockWeights::get().max_block; + let max_block_weight = + ::BlockWeights::get().max_block; let used_block_weight = max_block_weight / 2; System::set_block_consumed_resources(used_block_weight, 0); @@ -436,7 +432,9 @@ mod tests { disputes: Vec::new(), parent_header: default_header(), }) - .dispatch_bypass_filter(None.into()).unwrap_err().post_info; + .dispatch_bypass_filter(None.into()) + .unwrap_err() + .post_info; // we don't directly check the block's weight post-call. Instead, we check that the // call has returned the appropriate post-dispatch weight for refund, and trust @@ -470,7 +468,8 @@ mod tests { let expected_weight = MINIMAL_INCLUSION_INHERENT_WEIGHT; // oops, looks like this mandatory call pushed the block weight over the limit - let max_block_weight = ::BlockWeights::get().max_block; + let max_block_weight = + ::BlockWeights::get().max_block; let used_block_weight = max_block_weight + 1; System::set_block_consumed_resources(used_block_weight, 0); @@ -481,15 +480,13 @@ mod tests { disputes: Vec::new(), parent_header: header, }) - .dispatch_bypass_filter(None.into()).unwrap(); + .dispatch_bypass_filter(None.into()) + .unwrap(); // we don't directly check the block's weight post-call. Instead, we check that the // call has returned the appropriate post-dispatch weight for refund, and trust // Substrate to do the right thing with that information. - assert_eq!( - post_info.actual_weight.unwrap(), - expected_weight, - ); + assert_eq!(post_info.actual_weight.unwrap(), expected_weight,); }); } } diff --git a/polkadot/runtime/parachains/src/reward_points.rs b/polkadot/runtime/parachains/src/reward_points.rs index ff86132b8e4..1f593e6490b 100644 --- a/polkadot/runtime/parachains/src/reward_points.rs +++ b/polkadot/runtime/parachains/src/reward_points.rs @@ -21,9 +21,9 @@ //! which doesn't currently mention availability bitfields. As such, we don't reward them //! for the time being, although we will build schemes to do so in the future. -use primitives::v1::ValidatorIndex; -use pallet_staking::SessionInterface; use crate::shared; +use pallet_staking::SessionInterface; +use primitives::v1::ValidatorIndex; /// The amount of era points given by backing a candidate that is included. pub const BACKING_POINTS: u32 = 20; @@ -31,21 +31,27 @@ pub const BACKING_POINTS: u32 = 20; /// Rewards validators for participating in parachains with era points in pallet-staking. pub struct RewardValidatorsWithEraPoints(sp_std::marker::PhantomData); -fn validators_to_reward(validators: &'_ [T], indirect_indices: I) -> impl IntoIterator where +fn validators_to_reward( + validators: &'_ [T], + indirect_indices: I, +) -> impl IntoIterator +where C: shared::Config, - I: IntoIterator + I: IntoIterator, { let validator_indirection = >::active_validator_indices(); - indirect_indices.into_iter() + indirect_indices + .into_iter() .filter_map(move |i| validator_indirection.get(i.0 as usize).map(|v| v.clone())) .filter_map(move |i| validators.get(i.0 as usize)) } impl crate::inclusion::RewardValidators for RewardValidatorsWithEraPoints - where C: pallet_staking::Config + shared::Config, +where + C: pallet_staking::Config + shared::Config, { - fn reward_backing(indirect_indices: impl IntoIterator) { + fn reward_backing(indirect_indices: impl IntoIterator) { // Fetch the validators from the _session_ because sessions are offset from eras // and we are rewarding for behavior in current session. let validators = C::SessionInterface::validators(); @@ -57,16 +63,18 @@ impl crate::inclusion::RewardValidators for RewardValidatorsWithEraPoints >::reward_by_ids(rewards); } - fn reward_bitfields(_validators: impl IntoIterator) { } + fn reward_bitfields(_validators: impl IntoIterator) {} } #[cfg(test)] mod tests { use super::*; - use primitives::v1::ValidatorId; - use crate::configuration::HostConfiguration; - use crate::mock::{new_test_ext, MockGenesisConfig, ParasShared, Test}; + use crate::{ + configuration::HostConfiguration, + mock::{new_test_ext, MockGenesisConfig, ParasShared, Test}, + }; use keyring::Sr25519Keyring; + use primitives::v1::ValidatorId; #[test] fn rewards_based_on_indirection() { @@ -88,12 +96,8 @@ mod tests { let pubkeys = validator_pubkeys(&validators); - let shuffled_pubkeys = ParasShared::initializer_on_new_session( - 1, - [1; 32], - &config, - pubkeys, - ); + let shuffled_pubkeys = + ParasShared::initializer_on_new_session(1, [1; 32], &config, pubkeys); assert_eq!( shuffled_pubkeys, @@ -121,7 +125,10 @@ mod tests { validators_to_reward::( &validators, vec![ValidatorIndex(0), ValidatorIndex(1), ValidatorIndex(2)], - ).into_iter().copied().collect::>(), + ) + .into_iter() + .copied() + .collect::>(), vec![Sr25519Keyring::Ferdie, Sr25519Keyring::Bob, Sr25519Keyring::Charlie], ); }) diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs index f019aa36374..3dd0be08488 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs @@ -17,9 +17,9 @@ //! Runtimes implementing the v1 runtime API are recommended to forward directly to these //! functions. -use sp_std::prelude::*; -use sp_std::collections::btree_map::BTreeMap; -use sp_runtime::traits::One; +use crate::{ + configuration, dmp, hrmp, inclusion, initializer, paras, scheduler, session_info, shared, +}; use primitives::v1::{ AuthorityDiscoveryId, CandidateEvent, CommittedCandidateReceipt, CoreIndex, CoreOccupied, CoreState, GroupIndex, GroupRotationInfo, Id as ParaId, InboundDownwardMessage, @@ -27,8 +27,8 @@ use primitives::v1::{ ScheduledCore, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, }; -use crate::{initializer, inclusion, scheduler, configuration, paras, session_info, dmp, hrmp, shared}; - +use sp_runtime::traits::One; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; /// Implementation for the `validators` function of the runtime API. pub fn validators() -> Vec { @@ -36,10 +36,8 @@ pub fn validators() -> Vec { } /// Implementation for the `validator_groups` function of the runtime API. -pub fn validator_groups() -> ( - Vec>, - GroupRotationInfo, -) { +pub fn validator_groups( +) -> (Vec>, GroupRotationInfo) { let now = >::block_number() + One::one(); let groups = >::validator_groups(); @@ -80,10 +78,13 @@ pub fn availability_cores() -> Vec>::group_assigned_to_core(core_index, backed_in_number) { + let group_responsible_for = + |backed_in_number, core_index| match >::group_assigned_to_core( + core_index, + backed_in_number, + ) { Some(g) => g, - None => { + None => { log::warn!( target: "runtime::polkadot-api::v1", "Could not determine the group responsible for core extracted \ @@ -91,23 +92,24 @@ pub fn availability_cores() -> Vec = cores.into_iter().enumerate().map(|(i, core)| match core { - Some(occupied) => { - CoreState::Occupied(match occupied { + }, + }; + + let mut core_states: Vec<_> = cores + .into_iter() + .enumerate() + .map(|(i, core)| match core { + Some(occupied) => CoreState::Occupied(match occupied { CoreOccupied::Parachain => { let para_id = parachains[i]; - let pending_availability = > - ::pending_availability(para_id) - .expect("Occupied core always has pending availability; qed"); + let pending_availability = + >::pending_availability(para_id) + .expect("Occupied core always has pending availability; qed"); let backed_in_number = pending_availability.backed_in_number().clone(); OccupiedCore { next_up_on_available: >::next_up_on_available( - CoreIndex(i as u32) + CoreIndex(i as u32), ), occupied_since: backed_in_number, time_out_at: time_out_at( @@ -115,7 +117,7 @@ pub fn availability_cores() -> Vec>::next_up_on_time_out( - CoreIndex(i as u32) + CoreIndex(i as u32), ), availability: pending_availability.availability_votes().clone(), group_responsible: group_responsible_for( @@ -125,17 +127,17 @@ pub fn availability_cores() -> Vec { let para_id = p.claim.0; - let pending_availability = > - ::pending_availability(para_id) - .expect("Occupied core always has pending availability; qed"); + let pending_availability = + >::pending_availability(para_id) + .expect("Occupied core always has pending availability; qed"); let backed_in_number = pending_availability.backed_in_number().clone(); OccupiedCore { next_up_on_available: >::next_up_on_available( - CoreIndex(i as u32) + CoreIndex(i as u32), ), occupied_since: backed_in_number, time_out_at: time_out_at( @@ -143,7 +145,7 @@ pub fn availability_cores() -> Vec>::next_up_on_time_out( - CoreIndex(i as u32) + CoreIndex(i as u32), ), availability: pending_availability.availability_votes().clone(), group_responsible: group_responsible_for( @@ -153,11 +155,11 @@ pub fn availability_cores() -> Vec CoreState::Free, - }).collect(); + }, + }), + None => CoreState::Free, + }) + .collect(); // This will overwrite only `Free` cores if the scheduler module is working as intended. for scheduled in >::scheduled() { @@ -174,7 +176,8 @@ fn with_assumption( para_id: ParaId, assumption: OccupiedCoreAssumption, build: F, -) -> Option where +) -> Option +where Config: inclusion::Config, F: FnOnce() -> Option, { @@ -182,17 +185,15 @@ fn with_assumption( OccupiedCoreAssumption::Included => { >::force_enact(para_id); build() - } - OccupiedCoreAssumption::TimedOut => { - build() - } + }, + OccupiedCoreAssumption::TimedOut => build(), OccupiedCoreAssumption::Free => { if >::pending_availability(para_id).is_some() { None } else { build() } - } + }, } } @@ -237,7 +238,8 @@ pub fn session_index_for_child() -> SessionIndex { /// Implementation for the `AuthorityDiscoveryApi::authorities()` function of the runtime API. /// It is a heavy call, but currently only used for authority discovery, so it is fine. /// Gets next, current and some historical authority ids using `session_info` module. -pub fn relevant_authority_ids() -> Vec { +pub fn relevant_authority_ids( +) -> Vec { let current_session_index = session_index_for_child::(); let earliest_stored_session = >::earliest_stored_session(); @@ -267,17 +269,13 @@ pub fn validation_code( para_id: ParaId, assumption: OccupiedCoreAssumption, ) -> Option { - with_assumption::( - para_id, - assumption, - || >::current_code(¶_id), - ) + with_assumption::(para_id, assumption, || >::current_code(¶_id)) } /// Implementation for the `candidate_pending_availability` function of the runtime API. -pub fn candidate_pending_availability(para_id: ParaId) - -> Option> -{ +pub fn candidate_pending_availability( + para_id: ParaId, +) -> Option> { >::candidate_pending_availability(para_id) } @@ -291,17 +289,17 @@ where { use inclusion::Event as RawEvent; - >::events().into_iter() + >::events() + .into_iter() .filter_map(|record| extract_event(record.event)) .map(|event| match event { - RawEvent::::CandidateBacked(c, h, core, group) - => CandidateEvent::CandidateBacked(c, h, core, group), - RawEvent::::CandidateIncluded(c, h, core, group) - => CandidateEvent::CandidateIncluded(c, h, core, group), - RawEvent::::CandidateTimedOut(c, h, core) - => CandidateEvent::CandidateTimedOut(c, h, core), - RawEvent::::__Ignore(_, _) - => unreachable!("__Ignore cannot be used"), + RawEvent::::CandidateBacked(c, h, core, group) => + CandidateEvent::CandidateBacked(c, h, core, group), + RawEvent::::CandidateIncluded(c, h, core, group) => + CandidateEvent::CandidateIncluded(c, h, core, group), + RawEvent::::CandidateTimedOut(c, h, core) => + CandidateEvent::CandidateTimedOut(c, h, core), + RawEvent::::__Ignore(_, _) => unreachable!("__Ignore cannot be used"), }) .collect() } diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs index 1ac5359c054..ef06fb79beb 100644 --- a/polkadot/runtime/parachains/src/scheduler.rs +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -35,16 +35,15 @@ //! number of groups as availability cores. Validator groups will be assigned to different availability cores //! over time. -use sp_std::prelude::*; -use sp_std::convert::TryInto; +use frame_support::pallet_prelude::*; use primitives::v1::{ - Id as ParaId, ValidatorIndex, CoreOccupied, CoreIndex, CollatorId, - GroupIndex, ParathreadClaim, ParathreadEntry, GroupRotationInfo, ScheduledCore, + CollatorId, CoreIndex, CoreOccupied, GroupIndex, GroupRotationInfo, Id as ParaId, + ParathreadClaim, ParathreadEntry, ScheduledCore, ValidatorIndex, }; -use frame_support::pallet_prelude::*; use sp_runtime::traits::{One, Saturating}; +use sp_std::{convert::TryInto, prelude::*}; -use crate::{configuration, paras, initializer::SessionChangeNotification}; +use crate::{configuration, initializer::SessionChangeNotification, paras}; pub use pallet::*; @@ -73,10 +72,7 @@ impl ParathreadClaimQueue { let core_offset = self.next_core_offset; self.next_core_offset = (self.next_core_offset + 1) % n_parathread_cores; - self.queue.push(QueuedParathread { - claim: entry, - core_offset, - }) + self.queue.push(QueuedParathread { claim: entry, core_offset }) } /// Take next queued entry with given core offset, if any. @@ -100,7 +96,6 @@ pub enum FreedReason { TimedOut, } - /// The assignment type. #[derive(Clone, Encode, Decode)] #[cfg_attr(feature = "std", derive(PartialEq, Debug))] @@ -138,17 +133,15 @@ impl CoreAssignment { pub fn to_core_occupied(&self) -> CoreOccupied { match self.kind { AssignmentKind::Parachain => CoreOccupied::Parachain, - AssignmentKind::Parathread(ref collator, retries) => CoreOccupied::Parathread( - ParathreadEntry { + AssignmentKind::Parathread(ref collator, retries) => + CoreOccupied::Parathread(ParathreadEntry { claim: ParathreadClaim(self.para_id, collator.clone()), retries, - } - ), + }), } } } - #[frame_support::pallet] pub mod pallet { use super::*; @@ -214,8 +207,8 @@ pub mod pallet { /// for the upcoming block. #[pallet::storage] #[pallet::getter(fn scheduled)] - pub(crate) type Scheduled = StorageValue<_, Vec, ValueQuery>; // sorted ascending by CoreIndex. - + pub(crate) type Scheduled = StorageValue<_, Vec, ValueQuery>; + // sorted ascending by CoreIndex. } impl Pallet { @@ -225,15 +218,13 @@ impl Pallet { } /// Called by the initializer to finalize the scheduler module. - pub(crate) fn initializer_finalize() { } + pub(crate) fn initializer_finalize() {} /// Called by the initializer to note that a new session has started. - pub(crate) fn initializer_on_new_session(notification: &SessionChangeNotification) { - let &SessionChangeNotification { - ref validators, - ref new_config, - .. - } = notification; + pub(crate) fn initializer_on_new_session( + notification: &SessionChangeNotification, + ) { + let &SessionChangeNotification { ref validators, ref new_config, .. } = notification; let config = new_config; let mut thread_queue = ParathreadQueue::::get(); @@ -241,7 +232,7 @@ impl Pallet { let n_cores = core::cmp::max( n_parachains + config.parathread_cores, match config.max_validators_per_core { - Some(x) if x != 0 => { validators.len() as u32 / x }, + Some(x) if x != 0 => validators.len() as u32 / x, _ => 0, }, ); @@ -276,14 +267,20 @@ impl Pallet { for i in 0..n_larger_groups { let offset = (group_base_size + 1) * i; groups.push( - (0..group_base_size + 1).map(|j| offset + j).map(|j| ValidatorIndex(j as _)).collect() + (0..group_base_size + 1) + .map(|j| offset + j) + .map(|j| ValidatorIndex(j as _)) + .collect(), ); } for i in 0..(n_cores as usize - n_larger_groups) { let offset = (n_larger_groups * (group_base_size + 1)) + (i * group_base_size); groups.push( - (0..group_base_size).map(|j| offset + j).map(|j| ValidatorIndex(j as _)).collect() + (0..group_base_size) + .map(|j| offset + j) + .map(|j| ValidatorIndex(j as _)) + .collect(), ); } @@ -295,18 +292,15 @@ impl Pallet { ParathreadClaimIndex::::mutate(|claim_index| { // wipe all parathread metadata if no parathread cores are configured. if config.parathread_cores == 0 { - thread_queue = ParathreadClaimQueue { - queue: Vec::new(), - next_core_offset: 0, - }; + thread_queue = ParathreadClaimQueue { queue: Vec::new(), next_core_offset: 0 }; claim_index.clear(); - return; + return } // prune out all entries beyond retry or that no longer correspond to live parathread. thread_queue.queue.retain(|queued| { - let will_keep = queued.claim.retries <= config.parathread_retries - && >::is_parathread(queued.claim.claim.0); + let will_keep = queued.claim.retries <= config.parathread_retries && + >::is_parathread(queued.claim.claim.0); if !will_keep { let claim_para = queued.claim.claim.0; @@ -342,27 +336,32 @@ impl Pallet { /// Fails if the claim does not correspond to any live parathread. #[allow(unused)] pub fn add_parathread_claim(claim: ParathreadClaim) { - if !>::is_parathread(claim.0) { return } + if !>::is_parathread(claim.0) { + return + } let config = >::config(); let queue_max_size = config.parathread_cores * config.scheduling_lookahead; ParathreadQueue::::mutate(|queue| { - if queue.queue.len() >= queue_max_size as usize { return } + if queue.queue.len() >= queue_max_size as usize { + return + } let para_id = claim.0; - let competes_with_another = ParathreadClaimIndex::::mutate(|index| { - match index.binary_search(¶_id) { + let competes_with_another = + ParathreadClaimIndex::::mutate(|index| match index.binary_search(¶_id) { Ok(_) => true, Err(i) => { index.insert(i, para_id); false - } - } - }); + }, + }); - if competes_with_another { return } + if competes_with_another { + return + } let entry = ParathreadEntry { claim, retries: 0 }; queue.enqueue_entry(entry, config.parathread_cores); @@ -394,16 +393,16 @@ impl Pallet { index.remove(i); } }) - } + }, FreedReason::TimedOut => { // If a parathread candidate times out, it's not the collator's fault, // so we don't increment retries. ParathreadQueue::::mutate(|queue| { queue.enqueue_entry(entry, config.parathread_cores); }) - } + }, } - } + }, } } } @@ -412,7 +411,9 @@ impl Pallet { let mut scheduled = Scheduled::::get(); let mut parathread_queue = ParathreadQueue::::get(); - if ValidatorGroups::::get().is_empty() { return } + if ValidatorGroups::::get().is_empty() { + return + } { let mut prev_scheduled_in_order = scheduled.iter().enumerate().peekable(); @@ -425,10 +426,10 @@ impl Pallet { for (core_index, _core) in cores.iter().enumerate().filter(|(_, ref c)| c.is_none()) { let schedule_and_insert_at = { // advance the iterator until just before the core index we are looking at now. - while prev_scheduled_in_order.peek().map_or( - false, - |(_, assign)| (assign.core.0 as usize) < core_index, - ) { + while prev_scheduled_in_order + .peek() + .map_or(false, |(_, assign)| (assign.core.0 as usize) < core_index) + { let _ = prev_scheduled_in_order.next(); } @@ -440,10 +441,12 @@ impl Pallet { // insertion position. prev_scheduled_in_order.peek().map_or( Some(scheduled.len()), - |(idx_in_scheduled, assign)| if (assign.core.0 as usize) == core_index { - None - } else { - Some(*idx_in_scheduled) + |(idx_in_scheduled, assign)| { + if (assign.core.0 as usize) == core_index { + None + } else { + Some(*idx_in_scheduled) + } }, ) }; @@ -461,9 +464,10 @@ impl Pallet { kind: AssignmentKind::Parachain, para_id: parachains[core_index], core: core.clone(), - group_idx: Self::group_assigned_to_core(core, now) - .expect("core is not out of bounds and we are guaranteed \ - to be after the most recent session start; qed"), + group_idx: Self::group_assigned_to_core(core, now).expect( + "core is not out of bounds and we are guaranteed \ + to be after the most recent session start; qed", + ), }) } else { // parathread core offset, rel. to beginning. @@ -473,9 +477,10 @@ impl Pallet { kind: AssignmentKind::Parathread(entry.claim.1, entry.retries), para_id: entry.claim.0, core: core.clone(), - group_idx: Self::group_assigned_to_core(core, now) - .expect("core is not out of bounds and we are guaranteed \ - to be after the most recent session start; qed"), + group_idx: Self::group_assigned_to_core(core, now).expect( + "core is not out of bounds and we are guaranteed \ + to be after the most recent session start; qed", + ), }) }; @@ -490,7 +495,9 @@ impl Pallet { // while inserting, we have to account for the amount of insertions already done. // // This is O(n) as well, capped at n operations, where n is the number of cores. - for (num_insertions_before, (insert_at, to_insert)) in scheduled_updates.into_iter().enumerate() { + for (num_insertions_before, (insert_at, to_insert)) in + scheduled_updates.into_iter().enumerate() + { let insert_at = num_insertions_before + insert_at; scheduled.insert(insert_at, to_insert); } @@ -511,7 +518,9 @@ impl Pallet { /// Complexity: O(n) in the number of scheduled cores, which is capped at the number of total cores. /// This is efficient in the case that most scheduled cores are occupied. pub(crate) fn occupied(now_occupied: &[CoreIndex]) { - if now_occupied.is_empty() { return } + if now_occupied.is_empty() { + return + } let mut availability_cores = AvailabilityCores::::get(); Scheduled::::mutate(|scheduled| { @@ -520,16 +529,17 @@ impl Pallet { let mut occupied_iter = now_occupied.iter().cloned().peekable(); scheduled.retain(|assignment| { - let retain = occupied_iter.peek().map_or(true, |occupied_idx| { - occupied_idx != &assignment.core - }); + let retain = occupied_iter + .peek() + .map_or(true, |occupied_idx| occupied_idx != &assignment.core); if !retain { // remove this entry - it's now occupied. and begin inspecting the next extry // of the occupied iterator. let _ = occupied_iter.next(); - availability_cores[assignment.core.0 as usize] = Some(assignment.to_core_occupied()); + availability_cores[assignment.core.0 as usize] = + Some(assignment.to_core_occupied()); } retain @@ -548,7 +558,7 @@ impl Pallet { Some(CoreOccupied::Parachain) => { let parachains = >::parachains(); Some(parachains[core_index.0 as usize]) - } + }, Some(CoreOccupied::Parathread(ref entry)) => Some(entry.claim.0), } } @@ -560,28 +570,35 @@ impl Pallet { /// Get the group assigned to a specific core by index at the current block number. Result undefined if the core index is unknown /// or the block number is less than the session start index. - pub(crate) fn group_assigned_to_core(core: CoreIndex, at: T::BlockNumber) -> Option { + pub(crate) fn group_assigned_to_core( + core: CoreIndex, + at: T::BlockNumber, + ) -> Option { let config = >::config(); let session_start_block = >::get(); - if at < session_start_block { return None } + if at < session_start_block { + return None + } let validator_groups = ValidatorGroups::::get(); - if core.0 as usize >= validator_groups.len() { return None } + if core.0 as usize >= validator_groups.len() { + return None + } let rotations_since_session_start: T::BlockNumber = (at - session_start_block) / config.group_rotation_frequency.into(); - let rotations_since_session_start - = match >::try_into(rotations_since_session_start) - { - Ok(i) => i, - Err(_) => 0, // can only happen if rotations occur only once every u32::max(), - // so functionally no difference in behavior. - }; + let rotations_since_session_start = + match >::try_into(rotations_since_session_start) { + Ok(i) => i, + Err(_) => 0, // can only happen if rotations occur only once every u32::max(), + // so functionally no difference in behavior. + }; - let group_idx = (core.0 as usize + rotations_since_session_start as usize) % validator_groups.len(); + let group_idx = + (core.0 as usize + rotations_since_session_start as usize) % validator_groups.len(); Some(GroupIndex(group_idx as u32)) } @@ -595,18 +612,18 @@ impl Pallet { /// This really should not be a box, but is working around a compiler limitation filed here: /// https://github.com/rust-lang/rust/issues/73226 /// which prevents us from testing the code if using `impl Trait`. - pub(crate) fn availability_timeout_predicate() -> Option bool>> { + pub(crate) fn availability_timeout_predicate( + ) -> Option bool>> { let now = >::block_number(); let config = >::config(); let session_start = >::get(); let blocks_since_session_start = now.saturating_sub(session_start); - let blocks_since_last_rotation = blocks_since_session_start % config.group_rotation_frequency; + let blocks_since_last_rotation = + blocks_since_session_start % config.group_rotation_frequency; - let absolute_cutoff = sp_std::cmp::max( - config.chain_availability_period, - config.thread_availability_period, - ); + let absolute_cutoff = + sp_std::cmp::max(config.chain_availability_period, config.thread_availability_period); let availability_cores = AvailabilityCores::::get(); @@ -615,7 +632,7 @@ impl Pallet { } else { Some(Box::new(move |core_index: CoreIndex, pending_since| { match availability_cores.get(core_index.0 as usize) { - None => true, // out-of-bounds, doesn't really matter what is returned. + None => true, // out-of-bounds, doesn't really matter what is returned. Some(None) => true, // core not occupied, still doesn't really matter. Some(Some(CoreOccupied::Parachain)) => { if blocks_since_last_rotation >= config.chain_availability_period { @@ -623,14 +640,14 @@ impl Pallet { } else { now.saturating_sub(pending_since) >= config.chain_availability_period } - } + }, Some(Some(CoreOccupied::Parathread(_))) => { if blocks_since_last_rotation >= config.thread_availability_period { false // no pruning except recently after rotation. } else { now.saturating_sub(pending_since) >= config.thread_availability_period } - } + }, } })) } @@ -639,14 +656,10 @@ impl Pallet { /// Returns a helper for determining group rotation. pub(crate) fn group_rotation_info(now: T::BlockNumber) -> GroupRotationInfo { let session_start_block = Self::session_start_block(); - let group_rotation_frequency = >::config() - .group_rotation_frequency; + let group_rotation_frequency = + >::config().group_rotation_frequency; - GroupRotationInfo { - session_start_block, - now, - group_rotation_frequency, - } + GroupRotationInfo { session_start_block, now, group_rotation_frequency } } /// Return the next thing that will be scheduled on this core assuming it is currently @@ -658,10 +671,7 @@ impl Pallet { pub(crate) fn next_up_on_available(core: CoreIndex) -> Option { let parachains = >::parachains(); if (core.0 as usize) < parachains.len() { - Some(ScheduledCore { - para_id: parachains[core.0 as usize], - collator: None, - }) + Some(ScheduledCore { para_id: parachains[core.0 as usize], collator: None }) } else { let queue = ParathreadQueue::::get(); let core_offset = (core.0 as usize - parachains.len()) as u32; @@ -682,16 +692,14 @@ impl Pallet { pub(crate) fn next_up_on_time_out(core: CoreIndex) -> Option { let parachains = >::parachains(); if (core.0 as usize) < parachains.len() { - Some(ScheduledCore { - para_id: parachains[core.0 as usize], - collator: None, - }) + Some(ScheduledCore { para_id: parachains[core.0 as usize], collator: None }) } else { let queue = ParathreadQueue::::get(); // This is the next scheduled para on this core. let core_offset = (core.0 as usize - parachains.len()) as u32; - queue.get_next_on_core(core_offset) + queue + .get_next_on_core(core_offset) .map(|entry| ScheduledCore { para_id: entry.claim.0, collator: Some(entry.claim.1.clone()), @@ -702,12 +710,10 @@ impl Pallet { let cores = AvailabilityCores::::get(); cores.get(core.0 as usize).and_then(|c| c.as_ref()).and_then(|o| { match o { - CoreOccupied::Parathread(entry) => { - Some(ScheduledCore { - para_id: entry.claim.0, - collator: Some(entry.claim.1.clone()), - }) - } + CoreOccupied::Parathread(entry) => Some(ScheduledCore { + para_id: entry.claim.0, + collator: Some(entry.claim.1.clone()), + }), CoreOccupied::Parachain => None, // defensive; not possible. } }) @@ -717,12 +723,13 @@ impl Pallet { // Free all scheduled cores and return parathread claims to queue, with retries incremented. pub(crate) fn clear() { - let config = >::config(); ParathreadQueue::::mutate(|queue| { for core_assignment in Scheduled::::take() { if let AssignmentKind::Parathread(collator, retries) = core_assignment.kind { - if !>::is_parathread(core_assignment.para_id) { continue } + if !>::is_parathread(core_assignment.para_id) { + continue + } let entry = ParathreadEntry { claim: ParathreadClaim(core_assignment.para_id, collator), @@ -738,26 +745,33 @@ impl Pallet { } } - #[cfg(test)] mod tests { use super::*; - use primitives::v1::{BlockNumber, ValidatorId, CollatorId, SessionIndex}; use frame_support::assert_ok; use keyring::Sr25519Keyring; - - use crate::mock::{new_test_ext, Configuration, Paras, ParasShared, System, Scheduler, MockGenesisConfig, Test}; - use crate::initializer::SessionChangeNotification; - use crate::configuration::HostConfiguration; - use crate::paras::ParaGenesisArgs; + use primitives::v1::{BlockNumber, CollatorId, SessionIndex, ValidatorId}; + + use crate::{ + configuration::HostConfiguration, + initializer::SessionChangeNotification, + mock::{ + new_test_ext, Configuration, MockGenesisConfig, Paras, ParasShared, Scheduler, System, + Test, + }, + paras::ParaGenesisArgs, + }; fn schedule_blank_para(id: ParaId, is_chain: bool) { - assert_ok!(Paras::schedule_para_initialize(id, ParaGenesisArgs { - genesis_head: Vec::new().into(), - validation_code: Vec::new().into(), - parachain: is_chain, - })); + assert_ok!(Paras::schedule_para_initialize( + id, + ParaGenesisArgs { + genesis_head: Vec::new().into(), + validation_code: Vec::new().into(), + parachain: is_chain, + } + )); } fn run_to_block( @@ -774,7 +788,8 @@ mod tests { let mut notification_with_session_index = notification; // We will make every session change trigger an action queue. Normally this may require 2 or more session changes. if notification_with_session_index.session_index == SessionIndex::default() { - notification_with_session_index.session_index = ParasShared::scheduled_session(); + notification_with_session_index.session_index = + ParasShared::scheduled_session(); } Paras::initializer_on_new_session(¬ification_with_session_index); Scheduler::initializer_on_new_session(¬ification_with_session_index); @@ -850,13 +865,16 @@ mod tests { let queue = ParathreadQueue::::get(); assert_eq!(queue.next_core_offset, 1); assert_eq!(queue.queue.len(), 1); - assert_eq!(queue.queue[0], QueuedParathread { - claim: ParathreadEntry { - claim: ParathreadClaim(thread_id, collator.clone()), - retries: 0, - }, - core_offset: 0, - }); + assert_eq!( + queue.queue[0], + QueuedParathread { + claim: ParathreadEntry { + claim: ParathreadClaim(thread_id, collator.clone()), + retries: 0, + }, + core_offset: 0, + } + ); } // due to the index, completing claims are not allowed. @@ -866,13 +884,16 @@ mod tests { let queue = ParathreadQueue::::get(); assert_eq!(queue.next_core_offset, 1); assert_eq!(queue.queue.len(), 1); - assert_eq!(queue.queue[0], QueuedParathread { - claim: ParathreadEntry { - claim: ParathreadClaim(thread_id, collator.clone()), - retries: 0, - }, - core_offset: 0, - }); + assert_eq!( + queue.queue[0], + QueuedParathread { + claim: ParathreadEntry { + claim: ParathreadClaim(thread_id, collator.clone()), + retries: 0, + }, + core_offset: 0, + } + ); } // claims on non-live parathreads have no effect. @@ -882,13 +903,16 @@ mod tests { let queue = ParathreadQueue::::get(); assert_eq!(queue.next_core_offset, 1); assert_eq!(queue.queue.len(), 1); - assert_eq!(queue.queue[0], QueuedParathread { - claim: ParathreadEntry { - claim: ParathreadClaim(thread_id, collator.clone()), - retries: 0, - }, - core_offset: 0, - }); + assert_eq!( + queue.queue[0], + QueuedParathread { + claim: ParathreadEntry { + claim: ParathreadClaim(thread_id, collator.clone()), + retries: 0, + }, + core_offset: 0, + } + ); } }) } @@ -901,10 +925,7 @@ mod tests { config }; let genesis_config = MockGenesisConfig { - configuration: crate::configuration::GenesisConfig { - config, - ..Default::default() - }, + configuration: crate::configuration::GenesisConfig { config, ..Default::default() }, ..Default::default() }; @@ -958,44 +979,53 @@ mod tests { let mut queue = ParathreadClaimQueue::default(); // Will be pruned: too many retries. - queue.enqueue_entry(ParathreadEntry { - claim: ParathreadClaim(thread_a, collator.clone()), - retries: max_parathread_retries + 1, - }, 4); + queue.enqueue_entry( + ParathreadEntry { + claim: ParathreadClaim(thread_a, collator.clone()), + retries: max_parathread_retries + 1, + }, + 4, + ); // Will not be pruned. - queue.enqueue_entry(ParathreadEntry { - claim: ParathreadClaim(thread_b, collator.clone()), - retries: max_parathread_retries, - }, 4); + queue.enqueue_entry( + ParathreadEntry { + claim: ParathreadClaim(thread_b, collator.clone()), + retries: max_parathread_retries, + }, + 4, + ); // Will not be pruned. - queue.enqueue_entry(ParathreadEntry { - claim: ParathreadClaim(thread_c, collator.clone()), - retries: 0, - }, 4); + queue.enqueue_entry( + ParathreadEntry { + claim: ParathreadClaim(thread_c, collator.clone()), + retries: 0, + }, + 4, + ); // Will be pruned: not a live parathread. - queue.enqueue_entry(ParathreadEntry { - claim: ParathreadClaim(thread_d, collator.clone()), - retries: 0, - }, 4); + queue.enqueue_entry( + ParathreadEntry { + claim: ParathreadClaim(thread_d, collator.clone()), + retries: 0, + }, + 4, + ); queue }); ParathreadClaimIndex::::put(vec![thread_a, thread_b, thread_c, thread_d]); - run_to_block( - 10, - |b| match b { - 10 => Some(SessionChangeNotification { - new_config: Configuration::config(), - ..Default::default() - }), - _ => None, - } - ); + run_to_block(10, |b| match b { + 10 => Some(SessionChangeNotification { + new_config: Configuration::config(), + ..Default::default() + }), + _ => None, + }); assert_eq!(Configuration::config(), default_config()); let queue = ParathreadQueue::::get(); @@ -1043,7 +1073,6 @@ mod tests { schedule_blank_para(chain_a, true); schedule_blank_para(chain_b, true); - run_to_block(1, |number| match number { 1 => Some(SessionChangeNotification { new_config: default_config(), @@ -1103,7 +1132,6 @@ mod tests { schedule_blank_para(chain_b, true); schedule_blank_para(chain_c, false); - run_to_block(1, |number| match number { 1 => Some(SessionChangeNotification { new_config: config.clone(), @@ -1183,19 +1211,25 @@ mod tests { let scheduled = Scheduler::scheduled(); assert_eq!(scheduled.len(), 2); - assert_eq!(scheduled[0], CoreAssignment { - core: CoreIndex(0), - para_id: chain_a, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(0), - }); + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(0), + para_id: chain_a, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(0), + } + ); - assert_eq!(scheduled[1], CoreAssignment { - core: CoreIndex(1), - para_id: chain_b, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(1), - }); + assert_eq!( + scheduled[1], + CoreAssignment { + core: CoreIndex(1), + para_id: chain_b, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(1), + } + ); } // add a couple of parathread claims. @@ -1208,33 +1242,45 @@ mod tests { let scheduled = Scheduler::scheduled(); assert_eq!(scheduled.len(), 4); - assert_eq!(scheduled[0], CoreAssignment { - core: CoreIndex(0), - para_id: chain_a, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(0), - }); + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(0), + para_id: chain_a, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(0), + } + ); - assert_eq!(scheduled[1], CoreAssignment { - core: CoreIndex(1), - para_id: chain_b, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(1), - }); + assert_eq!( + scheduled[1], + CoreAssignment { + core: CoreIndex(1), + para_id: chain_b, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(1), + } + ); - assert_eq!(scheduled[2], CoreAssignment{ - core: CoreIndex(2), - para_id: thread_a, - kind: AssignmentKind::Parathread(collator.clone(), 0), - group_idx: GroupIndex(2), - }); + assert_eq!( + scheduled[2], + CoreAssignment { + core: CoreIndex(2), + para_id: thread_a, + kind: AssignmentKind::Parathread(collator.clone(), 0), + group_idx: GroupIndex(2), + } + ); - assert_eq!(scheduled[3], CoreAssignment{ - core: CoreIndex(3), - para_id: thread_c, - kind: AssignmentKind::Parathread(collator.clone(), 0), - group_idx: GroupIndex(3), - }); + assert_eq!( + scheduled[3], + CoreAssignment { + core: CoreIndex(3), + para_id: thread_c, + kind: AssignmentKind::Parathread(collator.clone(), 0), + group_idx: GroupIndex(3), + } + ); } }); } @@ -1328,12 +1374,15 @@ mod tests { // cores 0 and 1 are occupied by parachains. cores 2 and 3 are occupied by parathread // claims. core 4 was free. assert_eq!(scheduled.len(), 1); - assert_eq!(scheduled[0], CoreAssignment { - core: CoreIndex(4), - para_id: thread_b, - kind: AssignmentKind::Parathread(collator.clone(), 0), - group_idx: GroupIndex(4), - }); + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(4), + para_id: thread_b, + kind: AssignmentKind::Parathread(collator.clone(), 0), + group_idx: GroupIndex(4), + } + ); } // now note that cores 0, 2, and 3 were freed. @@ -1343,7 +1392,7 @@ mod tests { (CoreIndex(2), FreedReason::Concluded), (CoreIndex(3), FreedReason::TimedOut), // should go back on queue. ], - 3 + 3, ); { @@ -1351,30 +1400,42 @@ mod tests { // 1 thing scheduled before, + 3 cores freed. assert_eq!(scheduled.len(), 4); - assert_eq!(scheduled[0], CoreAssignment { - core: CoreIndex(0), - para_id: chain_a, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(0), - }); - assert_eq!(scheduled[1], CoreAssignment { - core: CoreIndex(2), - para_id: thread_d, - kind: AssignmentKind::Parathread(collator.clone(), 0), - group_idx: GroupIndex(2), - }); - assert_eq!(scheduled[2], CoreAssignment { - core: CoreIndex(3), - para_id: thread_e, - kind: AssignmentKind::Parathread(collator.clone(), 0), - group_idx: GroupIndex(3), - }); - assert_eq!(scheduled[3], CoreAssignment { - core: CoreIndex(4), - para_id: thread_b, - kind: AssignmentKind::Parathread(collator.clone(), 0), - group_idx: GroupIndex(4), - }); + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(0), + para_id: chain_a, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(0), + } + ); + assert_eq!( + scheduled[1], + CoreAssignment { + core: CoreIndex(2), + para_id: thread_d, + kind: AssignmentKind::Parathread(collator.clone(), 0), + group_idx: GroupIndex(2), + } + ); + assert_eq!( + scheduled[2], + CoreAssignment { + core: CoreIndex(3), + para_id: thread_e, + kind: AssignmentKind::Parathread(collator.clone(), 0), + group_idx: GroupIndex(3), + } + ); + assert_eq!( + scheduled[3], + CoreAssignment { + core: CoreIndex(4), + para_id: thread_b, + kind: AssignmentKind::Parathread(collator.clone(), 0), + group_idx: GroupIndex(4), + } + ); // the prior claim on thread A concluded, but the claim on thread C was marked as // timed out. @@ -1386,13 +1447,16 @@ mod tests { // Although C was descheduled, the core `4` was occupied so C goes back on the queue. assert_eq!(parathread_queue.queue.len(), 1); - assert_eq!(parathread_queue.queue[0], QueuedParathread { - claim: ParathreadEntry { - claim: ParathreadClaim(thread_c, collator.clone()), - retries: 0, // retries not incremented by timeout - validators' fault. - }, - core_offset: 2, // reassigned to next core. thread_e claim was on offset 1. - }); + assert_eq!( + parathread_queue.queue[0], + QueuedParathread { + claim: ParathreadEntry { + claim: ParathreadClaim(thread_c, collator.clone()), + retries: 0, // retries not incremented by timeout - validators' fault. + }, + core_offset: 2, // reassigned to next core. thread_e claim was on offset 1. + } + ); } }); } @@ -1467,18 +1531,24 @@ mod tests { let scheduled = Scheduler::scheduled(); assert_eq!(scheduled.len(), 2); - assert_eq!(scheduled[0], CoreAssignment { - core: CoreIndex(0), - para_id: chain_a, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(0), - }); - assert_eq!(scheduled[1], CoreAssignment { - core: CoreIndex(2), - para_id: chain_c, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(2), - }); + assert_eq!( + scheduled[0], + CoreAssignment { + core: CoreIndex(0), + para_id: chain_a, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(0), + } + ); + assert_eq!( + scheduled[1], + CoreAssignment { + core: CoreIndex(2), + para_id: chain_c, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(2), + } + ); // The freed cores should be `None` in `AvailabilityCores`. let cores = AvailabilityCores::::get(); @@ -1545,8 +1615,14 @@ mod tests { let assert_groups_rotated = |rotations: u32| { let scheduled = Scheduler::scheduled(); assert_eq!(scheduled.len(), 2); - assert_eq!(scheduled[0].group_idx, GroupIndex((0u32 + rotations) % parathread_cores)); - assert_eq!(scheduled[1].group_idx, GroupIndex((1u32 + rotations) % parathread_cores)); + assert_eq!( + scheduled[0].group_idx, + GroupIndex((0u32 + rotations) % parathread_cores) + ); + assert_eq!( + scheduled[1].group_idx, + GroupIndex((1u32 + rotations) % parathread_cores) + ); }; assert_groups_rotated(0); @@ -1639,8 +1715,8 @@ mod tests { let collator = CollatorId::from(Sr25519Keyring::Alice.public()); assert!( - chain_availability_period < thread_availability_period - && thread_availability_period < group_rotation_frequency + chain_availability_period < thread_availability_period && + thread_availability_period < group_rotation_frequency ); let chain_a = ParaId::from(1); @@ -1791,10 +1867,7 @@ mod tests { assert_eq!( Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), - ScheduledCore { - para_id: thread_b, - collator: Some(collator.clone()), - } + ScheduledCore { para_id: thread_b, collator: Some(collator.clone()) } ); } }); @@ -1858,10 +1931,7 @@ mod tests { assert!(queue.get_next_on_core(0).is_none()); assert_eq!( Scheduler::next_up_on_time_out(CoreIndex(0)).unwrap(), - ScheduledCore { - para_id: thread_a, - collator: Some(collator.clone()), - } + ScheduledCore { para_id: thread_a, collator: Some(collator.clone()) } ); Scheduler::add_parathread_claim(thread_claim_b); @@ -1875,10 +1945,7 @@ mod tests { // Now that there is an earlier next-up, we use that. assert_eq!( Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), - ScheduledCore { - para_id: thread_b, - collator: Some(collator.clone()), - } + ScheduledCore { para_id: thread_b, collator: Some(collator.clone()) } ); } }); @@ -1932,10 +1999,7 @@ mod tests { // Now that there is an earlier next-up, we use that. assert_eq!( Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), - ScheduledCore { - para_id: chain_a, - collator: None, - } + ScheduledCore { para_id: chain_a, collator: None } ); } }); @@ -1989,10 +2053,7 @@ mod tests { // Now that there is an earlier next-up, we use that. assert_eq!( Scheduler::next_up_on_available(CoreIndex(0)).unwrap(), - ScheduledCore { - para_id: chain_a, - collator: None, - } + ScheduledCore { para_id: chain_a, collator: None } ); } }); @@ -2017,7 +2078,6 @@ mod tests { schedule_blank_para(chain_a, true); schedule_blank_para(chain_b, true); - run_to_block(1, |number| match number { 1 => Some(SessionChangeNotification { new_config: default_config(), @@ -2066,14 +2126,12 @@ mod tests { assert_eq!( Scheduler::scheduled(), - vec![ - CoreAssignment { - core: CoreIndex(0), - para_id: chain_a, - kind: AssignmentKind::Parachain, - group_idx: GroupIndex(0), - } - ], + vec![CoreAssignment { + core: CoreIndex(0), + para_id: chain_a, + kind: AssignmentKind::Parachain, + group_idx: GroupIndex(0), + }], ); }); } @@ -2136,5 +2194,4 @@ mod tests { assert_eq!(Scheduler::scheduled().len(), 1); }); } - } diff --git a/polkadot/runtime/parachains/src/session_info.rs b/polkadot/runtime/parachains/src/session_info.rs index c09b573c739..35c7b11a01a 100644 --- a/polkadot/runtime/parachains/src/session_info.rs +++ b/polkadot/runtime/parachains/src/session_info.rs @@ -19,11 +19,9 @@ //! //! See https://w3f.github.io/parachain-implementers-guide/runtime/session_info.html. +use crate::{configuration, paras, scheduler, shared, util::take_active_subset}; +use frame_support::{pallet_prelude::*, traits::OneSessionHandler}; use primitives::v1::{AssignmentId, AuthorityDiscoveryId, SessionIndex, SessionInfo}; -use frame_support::pallet_prelude::*; -use frame_support::traits::OneSessionHandler; -use crate::{configuration, paras, scheduler, shared}; -use crate::util::take_active_subset; use sp_std::vec::Vec; pub use pallet::*; @@ -51,7 +49,8 @@ pub mod pallet { /// Note that this API is private due to it being prone to 'off-by-one' at session boundaries. /// When in doubt, use `Sessions` API instead. #[pallet::storage] - pub(super) type AssignmentKeysUnsafe = StorageValue<_, Vec, ValueQuery>; + pub(super) type AssignmentKeysUnsafe = + StorageValue<_, Vec, ValueQuery>; /// The earliest session for which previous session info is stored. #[pallet::storage] @@ -82,7 +81,7 @@ impl AuthorityDiscoveryConfig for T { impl Pallet { /// Handle an incoming session change. pub(crate) fn initializer_on_new_session( - notification: &crate::initializer::SessionChangeNotification + notification: &crate::initializer::SessionChangeNotification, ) { let config = >::config(); @@ -104,7 +103,8 @@ impl Pallet { let new_session_index = notification.session_index; let old_earliest_stored_session = EarliestStoredSession::::get(); let new_earliest_stored_session = new_session_index.saturating_sub(dispute_period); - let new_earliest_stored_session = core::cmp::max(new_earliest_stored_session, old_earliest_stored_session); + let new_earliest_stored_session = + core::cmp::max(new_earliest_stored_session, old_earliest_stored_session); // remove all entries from `Sessions` from the previous value up to the new value // avoid a potentially heavy loop when introduced on a live chain if old_earliest_stored_session != 0 || Sessions::::get(0).is_some() { @@ -150,33 +150,35 @@ impl OneSessionHandler for Pal type Key = AssignmentId; fn on_genesis_session<'a, I: 'a>(_validators: I) - where I: Iterator + where + I: Iterator, { - } fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, _queued: I) - where I: Iterator + where + I: Iterator, { let assignment_keys: Vec<_> = validators.map(|(_, v)| v).collect(); AssignmentKeysUnsafe::::set(assignment_keys); } - fn on_disabled(_i: usize) { } + fn on_disabled(_i: usize) {} } - #[cfg(test)] mod tests { use super::*; - use crate::mock::{ - new_test_ext, Configuration, SessionInfo, System, MockGenesisConfig, - Origin, ParasShared, Test + use crate::{ + configuration::HostConfiguration, + initializer::SessionChangeNotification, + mock::{ + new_test_ext, Configuration, MockGenesisConfig, Origin, ParasShared, SessionInfo, + System, Test, + }, }; - use crate::initializer::SessionChangeNotification; - use crate::configuration::HostConfiguration; - use primitives::v1::{BlockNumber, ValidatorId, ValidatorIndex}; use keyring::Sr25519Keyring; + use primitives::v1::{BlockNumber, ValidatorId, ValidatorIndex}; fn run_to_block( to: BlockNumber, @@ -190,9 +192,7 @@ mod tests { Configuration::initializer_finalize(); if let Some(notification) = new_session(b + 1) { - Configuration::initializer_on_new_session( - ¬ification.session_index, - ); + Configuration::initializer_on_new_session(¬ification.session_index); ParasShared::initializer_on_new_session( notification.session_index, notification.random_seed, @@ -234,20 +234,14 @@ mod tests { fn session_changes(n: BlockNumber) -> Option> { if n % 10 == 0 { - Some(SessionChangeNotification { - session_index: n / 10, - ..Default::default() - }) + Some(SessionChangeNotification { session_index: n / 10, ..Default::default() }) } else { None } } fn new_session_every_block(n: BlockNumber) -> Option> { - Some(SessionChangeNotification{ - session_index: n, - ..Default::default() - }) + Some(SessionChangeNotification { session_index: n, ..Default::default() }) } #[test] @@ -333,20 +327,17 @@ mod tests { let active_set = vec![ValidatorIndex(4), ValidatorIndex(0), ValidatorIndex(2)]; - let unscrambled_validators: Vec - = unscrambled.iter().map(|v| v.public().into()).collect(); - let unscrambled_discovery: Vec - = unscrambled.iter().map(|v| v.public().into()).collect(); - let unscrambled_assignment: Vec - = unscrambled.iter().map(|v| v.public().into()).collect(); + let unscrambled_validators: Vec = + unscrambled.iter().map(|v| v.public().into()).collect(); + let unscrambled_discovery: Vec = + unscrambled.iter().map(|v| v.public().into()).collect(); + let unscrambled_assignment: Vec = + unscrambled.iter().map(|v| v.public().into()).collect(); let validators = take_active_subset(&active_set, &unscrambled_validators); new_test_ext(genesis_config()).execute_with(|| { - ParasShared::set_active_validators_with_indices( - active_set.clone(), - validators.clone(), - ); + ParasShared::set_active_validators_with_indices(active_set.clone(), validators.clone()); assert_eq!(ParasShared::active_validator_indices(), active_set); diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index 1efc3e89ada..1cf4c55cd69 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -19,11 +19,11 @@ //! To avoid cyclic dependencies, it is important that this pallet is not //! dependent on any of the other pallets. -use primitives::v1::{SessionIndex, ValidatorId, ValidatorIndex}; use frame_support::pallet_prelude::*; +use primitives::v1::{SessionIndex, ValidatorId, ValidatorIndex}; use sp_std::vec::Vec; -use rand::{SeedableRng, seq::SliceRandom}; +use rand::{seq::SliceRandom, SeedableRng}; use rand_chacha::ChaCha20Rng; use crate::configuration::HostConfiguration; @@ -55,7 +55,8 @@ pub mod pallet { /// Indices are into the broader validator set. #[pallet::storage] #[pallet::getter(fn active_validator_indices)] - pub(super) type ActiveValidatorIndices = StorageValue<_, Vec, ValueQuery>; + pub(super) type ActiveValidatorIndices = + StorageValue<_, Vec, ValueQuery>; /// The parachain attestation keys of the validators actively participating in parachain consensus. /// This should be the same length as `ActiveValidatorIndices`. @@ -74,7 +75,7 @@ impl Pallet { } /// Called by the initializer to finalize the configuration pallet. - pub(crate) fn initializer_finalize() { } + pub(crate) fn initializer_finalize() {} /// Called by the initializer to note that a new session has started. /// @@ -99,10 +100,8 @@ impl Pallet { shuffled_indices.truncate(max as usize); } - let active_validator_keys = crate::util::take_active_subset( - &shuffled_indices, - &all_validators, - ); + let active_validator_keys = + crate::util::take_active_subset(&shuffled_indices, &all_validators); ActiveValidatorIndices::::set(shuffled_indices); ActiveValidatorKeys::::set(active_validator_keys.clone()); @@ -124,7 +123,7 @@ impl Pallet { #[cfg(test)] pub(crate) fn set_active_validators_ascending(active: Vec) { ActiveValidatorIndices::::set( - (0..active.len()).map(|i| ValidatorIndex(i as _)).collect() + (0..active.len()).map(|i| ValidatorIndex(i as _)).collect(), ); ActiveValidatorKeys::::set(active); } @@ -143,8 +142,10 @@ impl Pallet { #[cfg(test)] mod tests { use super::*; - use crate::configuration::HostConfiguration; - use crate::mock::{new_test_ext, MockGenesisConfig, ParasShared}; + use crate::{ + configuration::HostConfiguration, + mock::{new_test_ext, MockGenesisConfig, ParasShared}, + }; use keyring::Sr25519Keyring; fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec { @@ -167,12 +168,7 @@ mod tests { let pubkeys = validator_pubkeys(&validators); new_test_ext(MockGenesisConfig::default()).execute_with(|| { - let validators = ParasShared::initializer_on_new_session( - 1, - [1; 32], - &config, - pubkeys, - ); + let validators = ParasShared::initializer_on_new_session(1, [1; 32], &config, pubkeys); assert_eq!( validators, @@ -185,10 +181,7 @@ mod tests { ]) ); - assert_eq!( - ParasShared::active_validator_keys(), - validators, - ); + assert_eq!(ParasShared::active_validator_keys(), validators,); assert_eq!( ParasShared::active_validator_indices(), @@ -219,32 +212,18 @@ mod tests { let pubkeys = validator_pubkeys(&validators); new_test_ext(MockGenesisConfig::default()).execute_with(|| { - let validators = ParasShared::initializer_on_new_session( - 1, - [1; 32], - &config, - pubkeys, - ); + let validators = ParasShared::initializer_on_new_session(1, [1; 32], &config, pubkeys); assert_eq!( validators, - validator_pubkeys(&[ - Sr25519Keyring::Ferdie, - Sr25519Keyring::Bob, - ]) + validator_pubkeys(&[Sr25519Keyring::Ferdie, Sr25519Keyring::Bob,]) ); - assert_eq!( - ParasShared::active_validator_keys(), - validators, - ); + assert_eq!(ParasShared::active_validator_keys(), validators,); assert_eq!( ParasShared::active_validator_indices(), - vec![ - ValidatorIndex(4), - ValidatorIndex(1), - ] + vec![ValidatorIndex(4), ValidatorIndex(1),] ); }); } diff --git a/polkadot/runtime/parachains/src/ump.rs b/polkadot/runtime/parachains/src/ump.rs index c0a8af36f8a..c64123537b0 100644 --- a/polkadot/runtime/parachains/src/ump.rs +++ b/polkadot/runtime/parachains/src/ump.rs @@ -18,10 +18,15 @@ use crate::{ configuration::{self, HostConfiguration}, initializer, }; -use sp_std::{prelude::*, fmt, marker::PhantomData, convert::TryFrom}; -use sp_std::collections::{btree_map::BTreeMap, vec_deque::VecDeque}; use frame_support::pallet_prelude::*; use primitives::v1::{Id as ParaId, UpwardMessage}; +use sp_std::{ + collections::{btree_map::BTreeMap, vec_deque::VecDeque}, + convert::TryFrom, + fmt, + marker::PhantomData, + prelude::*, +}; use xcm::v0::Outcome; pub use pallet::*; @@ -46,13 +51,21 @@ pub trait UmpSink { /// it did not begin processing a message since it would otherwise exceed `max_weight`. /// /// See the trait docs for more details. - fn process_upward_message(origin: ParaId, msg: &[u8], max_weight: Weight) -> Result; + fn process_upward_message( + origin: ParaId, + msg: &[u8], + max_weight: Weight, + ) -> Result; } /// An implementation of a sink that just swallows the message without consuming any weight. Returns /// `Some(0)` indicating that no messages existed for it to process. impl UmpSink for () { - fn process_upward_message(_: ParaId, _: &[u8], _: Weight) -> Result { + fn process_upward_message( + _: ParaId, + _: &[u8], + _: Weight, + ) -> Result { Ok(0) } } @@ -66,13 +79,19 @@ pub type MessageId = [u8; 32]; pub struct XcmSink(PhantomData<(XcmExecutor, Config)>); impl, C: Config> UmpSink for XcmSink { - fn process_upward_message(origin: ParaId, data: &[u8], max_weight: Weight) -> Result { - use xcm::VersionedXcm; - use xcm::v0::{Xcm, Junction, MultiLocation, Error as XcmError}; + fn process_upward_message( + origin: ParaId, + data: &[u8], + max_weight: Weight, + ) -> Result { + use xcm::{ + v0::{Error as XcmError, Junction, MultiLocation, Xcm}, + VersionedXcm, + }; let id = sp_io::hashing::blake2_256(&data[..]); - let maybe_msg = VersionedXcm::::decode(&mut &data[..]) - .map(Xcm::::try_from); + let maybe_msg = + VersionedXcm::::decode(&mut &data[..]).map(Xcm::::try_from); match maybe_msg { Err(_) => { Pallet::::deposit_event(Event::InvalidFormat(id)); @@ -92,9 +111,9 @@ impl, C: Config> UmpSink for XcmSink::deposit_event(Event::ExecutedUpward(id, outcome)); Ok(weight_used) - } + }, } - } + }, } } } @@ -102,23 +121,10 @@ impl, C: Config> UmpSink for XcmSink {})", sent, permitted, ), - AcceptanceCheckErr::MessageSize { - idx, - msg_size, - max_size, - } => write!( + AcceptanceCheckErr::MessageSize { idx, msg_size, max_size } => write!( fmt, "upward message idx {} larger than permitted by config ({} > {})", idx, msg_size, max_size, @@ -204,13 +206,8 @@ pub mod pallet { /// /// The messages are processed in FIFO order. #[pallet::storage] - pub type RelayDispatchQueues = StorageMap< - _, - Twox64Concat, - ParaId, - VecDeque, - ValueQuery - >; + pub type RelayDispatchQueues = + StorageMap<_, Twox64Concat, ParaId, VecDeque, ValueQuery>; /// Size of the dispatch queues. Caches sizes of the queues in `RelayDispatchQueue`. /// @@ -226,13 +223,8 @@ pub mod pallet { // NOTE that this field is used by parachains via merkle storage proofs, therefore changing // the format will require migration of parachains. #[pallet::storage] - pub type RelayDispatchQueueSize = StorageMap< - _, - Twox64Concat, - ParaId, - (u32, u32), - ValueQuery - >; + pub type RelayDispatchQueueSize = + StorageMap<_, Twox64Concat, ParaId, (u32, u32), ValueQuery>; /// The ordered list of `ParaId`s that have a `RelayDispatchQueue` entry. /// @@ -311,7 +303,7 @@ impl Pallet { return Err(AcceptanceCheckErr::MoreMessagesThanPermitted { sent: upward_messages.len() as u32, permitted: config.max_upward_message_num_per_candidate, - }); + }) } let (mut para_queue_count, mut para_queue_size) = @@ -324,7 +316,7 @@ impl Pallet { idx: idx as u32, msg_size, max_size: config.max_upward_message_size, - }); + }) } para_queue_count += 1; para_queue_size += msg_size; @@ -336,13 +328,13 @@ impl Pallet { return Err(AcceptanceCheckErr::CapacityExceeded { count: para_queue_count, limit: config.max_upward_queue_count, - }); + }) } if para_queue_size > config.max_upward_queue_size { return Err(AcceptanceCheckErr::TotalSizeExceeded { total_size: para_queue_size, limit: config.max_upward_queue_size, - }); + }) } Ok(()) @@ -364,10 +356,13 @@ impl Pallet { v.extend(upward_messages.into_iter()) }); - ::RelayDispatchQueueSize::mutate(¶, |(ref mut cnt, ref mut size)| { - *cnt += extra_count; - *size += extra_size; - }); + ::RelayDispatchQueueSize::mutate( + ¶, + |(ref mut cnt, ref mut size)| { + *cnt += extra_count; + *size += extra_size; + }, + ); ::NeedsDispatch::mutate(|v| { if let Err(i) = v.binary_search(¶) { @@ -398,7 +393,7 @@ impl Pallet { // preferred weight for the dispatching stage. // // if so - bail. - break; + break } let max_weight = if weight_used == 0 { // we increase the amount of weight that we're allowed to use on the first message to try to prevent @@ -411,7 +406,11 @@ impl Pallet { // dequeue the next message from the queue of the dispatchee let (upward_message, became_empty) = queue_cache.dequeue::(dispatchee); if let Some(upward_message) = upward_message { - match T::UmpSink::process_upward_message(dispatchee, &upward_message[..], max_weight) { + match T::UmpSink::process_upward_message( + dispatchee, + &upward_message[..], + max_weight, + ) { Ok(used) => weight_used += used, Err((id, required)) => { // we process messages in order and don't drop them if we run out of weight, so need to break @@ -478,11 +477,7 @@ impl QueueCache { let cache_entry = self.0.entry(para).or_insert_with(|| { let queue = as Store>::RelayDispatchQueues::get(¶); let (count, total_size) = as Store>::RelayDispatchQueueSize::get(¶); - QueueCacheEntry { - queue, - count, - total_size, - } + QueueCacheEntry { queue, count, total_size } }); let upward_message = cache_entry.queue.pop_front(); if let Some(ref msg) = upward_message { @@ -499,15 +494,7 @@ impl QueueCache { // NOTE we use an explicit method here instead of Drop impl because it has unwanted semantics // within runtime. It is dangerous to use because of double-panics and flushing on a panic // is not necessary as well. - for ( - para, - QueueCacheEntry { - queue, - count, - total_size, - }, - ) in self.0 - { + for (para, QueueCacheEntry { queue, count, total_size }) in self.0 { if queue.is_empty() { // remove the entries altogether. as Store>::RelayDispatchQueues::remove(¶); @@ -551,15 +538,12 @@ impl NeedsDispatchCursor { // let's select 0 as the starting index as a safe bet. debug_assert!(false); 0 - } + }, }, None => 0, }; - Self { - needs_dispatch, - index: initial_index, - } + Self { needs_dispatch, index: initial_index } } /// Returns the item the cursor points to. @@ -570,7 +554,7 @@ impl NeedsDispatchCursor { /// Moves the cursor to the next item. fn advance(&mut self) { if self.needs_dispatch.is_empty() { - return; + return } self.index = (self.index + 1) % self.needs_dispatch.len(); } @@ -578,7 +562,7 @@ impl NeedsDispatchCursor { /// Removes the item under the cursor. fn remove(&mut self) { if self.needs_dispatch.is_empty() { - return; + return } let _ = self.needs_dispatch.remove(self.index); @@ -615,10 +599,9 @@ pub(crate) mod mock_sink { //! 2. All messages expected by the probe must be received by the time of dropping it. Unreceived //! messages will lead to a panic while dropping a probe. - use super::{UmpSink, UpwardMessage, ParaId, MessageId}; - use std::cell::RefCell; - use std::collections::vec_deque::VecDeque; + use super::{MessageId, ParaId, UmpSink, UpwardMessage}; use frame_support::weights::Weight; + use std::{cell::RefCell, collections::vec_deque::VecDeque}; #[derive(Debug)] struct UmpExpectation { @@ -634,25 +617,30 @@ pub(crate) mod mock_sink { pub struct MockUmpSink; impl UmpSink for MockUmpSink { - fn process_upward_message(actual_origin: ParaId, actual_msg: &[u8], _max_weight: Weight) -> Result { - Ok(HOOK.with(|opt_hook| opt_hook.borrow_mut().as_mut().map(|hook| { - let UmpExpectation { - expected_origin, - expected_msg, - mock_weight, - } = match hook.pop_front() { - Some(expectation) => expectation, - None => { - panic!( + fn process_upward_message( + actual_origin: ParaId, + actual_msg: &[u8], + _max_weight: Weight, + ) -> Result { + Ok(HOOK + .with(|opt_hook| { + opt_hook.borrow_mut().as_mut().map(|hook| { + let UmpExpectation { expected_origin, expected_msg, mock_weight } = + match hook.pop_front() { + Some(expectation) => expectation, + None => { + panic!( "The probe is active but didn't expect the message:\n\n\t{:?}.", actual_msg, ); - } - }; - assert_eq!(expected_origin, actual_origin); - assert_eq!(expected_msg, &actual_msg[..]); - mock_weight - })).unwrap_or(0)) + }, + }; + assert_eq!(expected_origin, actual_origin); + assert_eq!(expected_msg, &actual_msg[..]); + mock_weight + }) + }) + .unwrap_or(0)) } } @@ -684,15 +672,11 @@ pub(crate) mod mock_sink { mock_weight: Weight, ) { HOOK.with(|opt_hook| { - opt_hook - .borrow_mut() - .as_mut() - .unwrap() - .push_back(UmpExpectation { - expected_origin, - expected_msg, - mock_weight, - }) + opt_hook.borrow_mut().as_mut().unwrap().push_back(UmpExpectation { + expected_origin, + expected_msg, + mock_weight, + }) }); } } @@ -727,9 +711,8 @@ pub(crate) mod mock_sink { #[cfg(test)] mod tests { - use super::*; - use super::mock_sink::Probe; - use crate::mock::{Configuration, Ump, new_test_ext, MockGenesisConfig}; + use super::{mock_sink::Probe, *}; + use crate::mock::{new_test_ext, Configuration, MockGenesisConfig, Ump}; use std::collections::HashSet; struct GenesisConfigBuilder { @@ -761,8 +744,7 @@ mod tests { config.max_upward_message_num_per_candidate = self.max_upward_message_num_per_candidate; config.max_upward_queue_count = self.max_upward_queue_count; config.max_upward_queue_size = self.max_upward_queue_size; - config.ump_service_total_weight = - self.ump_service_total_weight; + config.ump_service_total_weight = self.ump_service_total_weight; genesis } } @@ -811,9 +793,8 @@ mod tests { let queue_sizes_set = ::RelayDispatchQueueSize::iter() .map(|(k, _)| k) .collect::>(); - let needs_dispatch_set = ::NeedsDispatch::get() - .into_iter() - .collect::>(); + let needs_dispatch_set = + ::NeedsDispatch::get().into_iter().collect::>(); assert_eq!(queue_contents_set, queue_sizes_set); assert_eq!(queue_contents_set, needs_dispatch_set); @@ -823,11 +804,7 @@ mod tests { } // `NeedsDispatch` is always sorted. - assert!( - ::NeedsDispatch::get() - .windows(2) - .all(|xs| xs[0] <= xs[1]) - ); + assert!(::NeedsDispatch::get().windows(2).all(|xs| xs[0] <= xs[1])); } #[test] @@ -872,11 +849,7 @@ mod tests { let q_msg = b"we are Q".to_vec(); new_test_ext( - GenesisConfigBuilder { - ump_service_total_weight: 500, - ..Default::default() - } - .build(), + GenesisConfigBuilder { ump_service_total_weight: 500, ..Default::default() }.build(), ) .execute_with(|| { queue_upward_msg(q, q_msg.clone()); @@ -946,11 +919,7 @@ mod tests { let b_msg_1 = vec![4, 5, 6]; new_test_ext( - GenesisConfigBuilder { - ump_service_total_weight: 900, - ..Default::default() - } - .build(), + GenesisConfigBuilder { ump_service_total_weight: 900, ..Default::default() }.build(), ) .execute_with(|| { // We want to test here an edge case, where we remove the queue with the highest @@ -982,8 +951,8 @@ mod tests { // Make sure that the relay dispatch queue size storage entry is accessible via well known // keys and is decodable into a (u32, u32). - use primitives::v1::well_known_keys; use parity_scale_codec::Decode as _; + use primitives::v1::well_known_keys; let a = ParaId::from(228); let msg = vec![1, 2, 3]; @@ -991,9 +960,11 @@ mod tests { new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { queue_upward_msg(a, msg); - let raw_queue_size = sp_io::storage::get(&well_known_keys::relay_dispatch_queue_size(a)) - .expect("enqueing a message should create the dispatch queue\ - and it should be accessible via the well known keys"); + let raw_queue_size = + sp_io::storage::get(&well_known_keys::relay_dispatch_queue_size(a)).expect( + "enqueing a message should create the dispatch queue\ + and it should be accessible via the well known keys", + ); let (cnt, size) = <(u32, u32)>::decode(&mut &raw_queue_size[..]) .expect("the dispatch queue size should be decodable into (u32, u32)"); diff --git a/polkadot/runtime/parachains/src/util.rs b/polkadot/runtime/parachains/src/util.rs index 1f867235d73..4f9d1e588ba 100644 --- a/polkadot/runtime/parachains/src/util.rs +++ b/polkadot/runtime/parachains/src/util.rs @@ -20,7 +20,7 @@ use primitives::v1::{Id as ParaId, PersistedValidationData, ValidatorIndex}; use sp_std::vec::Vec; -use crate::{configuration, paras, hrmp}; +use crate::{configuration, hrmp, paras}; /// Make the persisted validation data for a particular parachain, a specified relay-parent and it's /// storage root. @@ -43,7 +43,8 @@ pub fn make_persisted_validation_data( /// Take the active subset of a set containing all validators. pub fn take_active_subset(active_validators: &[ValidatorIndex], set: &[T]) -> Vec { - let subset: Vec<_> = active_validators.iter() + let subset: Vec<_> = active_validators + .iter() .filter_map(|i| set.get(i.0 as usize)) .cloned() .collect(); diff --git a/polkadot/runtime/polkadot/src/constants.rs b/polkadot/runtime/polkadot/src/constants.rs index 27604630772..cd3a6927d23 100644 --- a/polkadot/runtime/polkadot/src/constants.rs +++ b/polkadot/runtime/polkadot/src/constants.rs @@ -19,8 +19,8 @@ pub mod currency { use primitives::v0::Balance; pub const UNITS: Balance = 10_000_000_000; - pub const DOLLARS: Balance = UNITS; // 10_000_000_000 - pub const CENTS: Balance = DOLLARS / 100; // 100_000_000 + pub const DOLLARS: Balance = UNITS; // 10_000_000_000 + pub const CENTS: Balance = DOLLARS / 100; // 100_000_000 pub const MILLICENTS: Balance = CENTS / 1_000; // 100_000 pub const fn deposit(items: u32, bytes: u32) -> Balance { @@ -30,7 +30,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::v0::{Moment, BlockNumber}; + use primitives::v0::{BlockNumber, Moment}; pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = 4 * HOURS; @@ -46,13 +46,13 @@ pub mod time { /// Fee-related. pub mod fee { - pub use sp_runtime::Perbill; - use primitives::v0::Balance; - use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ - WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }; + use primitives::v0::Balance; + use runtime_common::ExtrinsicBaseWeight; use smallvec::smallvec; + pub use sp_runtime::Perbill; /// The block saturation level. Fees will be updates based on this value. pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); @@ -86,10 +86,12 @@ pub mod fee { #[cfg(test)] mod tests { + use super::{ + currency::{CENTS, DOLLARS, MILLICENTS}, + fee::WeightToFee, + }; use frame_support::weights::WeightToFeePolynomial; - use runtime_common::{MAXIMUM_BLOCK_WEIGHT, ExtrinsicBaseWeight}; - use super::fee::WeightToFee; - use super::currency::{CENTS, DOLLARS, MILLICENTS}; + use runtime_common::{ExtrinsicBaseWeight, MAXIMUM_BLOCK_WEIGHT}; #[test] // This function tests that the fee for `MAXIMUM_BLOCK_WEIGHT` of weight is correct diff --git a/polkadot/runtime/polkadot/src/weights/frame_system.rs b/polkadot/runtime/polkadot/src/weights/frame_system.rs index 8798291667d..b53e3769c55 100644 --- a/polkadot/runtime/polkadot/src/weights/frame_system.rs +++ b/polkadot/runtime/polkadot/src/weights/frame_system.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,36 +42,35 @@ use sp_std::marker::PhantomData; /// Weight functions for `frame_system`. pub struct WeightInfo(PhantomData); impl frame_system::WeightInfo for WeightInfo { - fn remark(_b: u32, ) -> Weight { + fn remark(_b: u32) -> Weight { (990_000 as Weight) } - fn remark_with_event(b: u32, ) -> Weight { + fn remark_with_event(b: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((1_000 as Weight).saturating_mul(b as Weight)) } fn set_heap_pages() -> Weight { - (1_353_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (1_353_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_changes_trie_config() -> Weight { (9_064_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn set_storage(i: u32, ) -> Weight { + fn set_storage(i: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((546_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) } - fn kill_storage(i: u32, ) -> Weight { + fn kill_storage(i: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((402_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) } - fn kill_prefix(p: u32, ) -> Weight { + fn kill_prefix(p: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((790_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/mod.rs b/polkadot/runtime/polkadot/src/weights/mod.rs index 6f72ddc2d70..b71177e5d5f 100644 --- a/polkadot/runtime/polkadot/src/weights/mod.rs +++ b/polkadot/runtime/polkadot/src/weights/mod.rs @@ -17,10 +17,11 @@ pub mod frame_system; pub mod pallet_balances; +pub mod pallet_bounties; pub mod pallet_collective; pub mod pallet_democracy; -pub mod pallet_elections_phragmen; pub mod pallet_election_provider_multi_phase; +pub mod pallet_elections_phragmen; pub mod pallet_identity; pub mod pallet_im_online; pub mod pallet_indices; @@ -31,9 +32,8 @@ pub mod pallet_scheduler; pub mod pallet_session; pub mod pallet_staking; pub mod pallet_timestamp; +pub mod pallet_tips; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_vesting; -pub mod pallet_bounties; -pub mod pallet_tips; pub mod runtime_common_claims; diff --git a/polkadot/runtime/polkadot/src/weights/pallet_balances.rs b/polkadot/runtime/polkadot/src/weights/pallet_balances.rs index 52555a0ddad..1fd1ac72f6d 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_balances.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_balances.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/polkadot/src/weights/pallet_bounties.rs b/polkadot/runtime/polkadot/src/weights/pallet_bounties.rs index dcb3b21d49f..58195515cdd 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_bounties.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_bounties.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_bounties`. pub struct WeightInfo(PhantomData); impl pallet_bounties::WeightInfo for WeightInfo { - fn propose_bounty(d: u32, ) -> Weight { + fn propose_bounty(d: u32) -> Weight { (41_618_000 as Weight) // Standard Error: 0 .saturating_add((1_000 as Weight).saturating_mul(d as Weight)) @@ -95,7 +94,7 @@ impl pallet_bounties::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn spend_funds(b: u32, ) -> Weight { + fn spend_funds(b: u32) -> Weight { (0 as Weight) // Standard Error: 14_000 .saturating_add((58_304_000 as Weight).saturating_mul(b as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_collective.rs b/polkadot/runtime/polkadot/src/weights/pallet_collective.rs index ec3c568d25e..adbce61c299 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_collective.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_collective.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_collective`. pub struct WeightInfo(PhantomData); impl pallet_collective::WeightInfo for WeightInfo { - fn set_members(m: u32, n: u32, p: u32, ) -> Weight { + fn set_members(m: u32, n: u32, p: u32) -> Weight { (0 as Weight) // Standard Error: 4_000 .saturating_add((14_051_000 as Weight).saturating_mul(m as Weight)) @@ -56,7 +55,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) } - fn execute(b: u32, m: u32, ) -> Weight { + fn execute(b: u32, m: u32) -> Weight { (20_424_000 as Weight) // Standard Error: 0 .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) @@ -64,7 +63,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add((82_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn propose_execute(b: u32, m: u32, ) -> Weight { + fn propose_execute(b: u32, m: u32) -> Weight { (24_961_000 as Weight) // Standard Error: 0 .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) @@ -72,7 +71,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add((160_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) } - fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + fn propose_proposed(b: u32, m: u32, p: u32) -> Weight { (41_826_000 as Weight) // Standard Error: 0 .saturating_add((4_000 as Weight).saturating_mul(b as Weight)) @@ -83,14 +82,14 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn vote(m: u32, ) -> Weight { + fn vote(m: u32) -> Weight { (31_640_000 as Weight) // Standard Error: 0 .saturating_add((216_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + fn close_early_disapproved(m: u32, p: u32) -> Weight { (40_355_000 as Weight) // Standard Error: 0 .saturating_add((165_000 as Weight).saturating_mul(m as Weight)) @@ -99,7 +98,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + fn close_early_approved(b: u32, m: u32, p: u32) -> Weight { (55_837_000 as Weight) // Standard Error: 0 .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) @@ -110,7 +109,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn close_disapproved(m: u32, p: u32, ) -> Weight { + fn close_disapproved(m: u32, p: u32) -> Weight { (44_700_000 as Weight) // Standard Error: 0 .saturating_add((169_000 as Weight).saturating_mul(m as Weight)) @@ -119,7 +118,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + fn close_approved(b: u32, m: u32, p: u32) -> Weight { (60_051_000 as Weight) // Standard Error: 0 .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) @@ -130,7 +129,7 @@ impl pallet_collective::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn disapprove_proposal(p: u32, ) -> Weight { + fn disapprove_proposal(p: u32) -> Weight { (24_750_000 as Weight) // Standard Error: 0 .saturating_add((380_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_democracy.rs b/polkadot/runtime/polkadot/src/weights/pallet_democracy.rs index 1fa65a03fdf..868ff527ec1 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_democracy.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_democracy.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -48,21 +47,21 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn second(s: u32, ) -> Weight { + fn second(s: u32) -> Weight { (37_688_000 as Weight) // Standard Error: 0 .saturating_add((154_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn vote_new(r: u32, ) -> Weight { + fn vote_new(r: u32) -> Weight { (43_654_000 as Weight) // Standard Error: 0 .saturating_add((208_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn vote_existing(r: u32, ) -> Weight { + fn vote_existing(r: u32) -> Weight { (43_543_000 as Weight) // Standard Error: 0 .saturating_add((207_000 as Weight).saturating_mul(r as Weight)) @@ -74,14 +73,14 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn blacklist(p: u32, ) -> Weight { + fn blacklist(p: u32) -> Weight { (74_916_000 as Weight) // Standard Error: 4_000 .saturating_add((536_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } - fn external_propose(v: u32, ) -> Weight { + fn external_propose(v: u32) -> Weight { (12_632_000 as Weight) // Standard Error: 0 .saturating_add((79_000 as Weight).saturating_mul(v as Weight)) @@ -89,26 +88,24 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn external_propose_majority() -> Weight { - (2_396_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_396_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn external_propose_default() -> Weight { - (2_450_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_450_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn fast_track() -> Weight { (25_867_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn veto_external(v: u32, ) -> Weight { + fn veto_external(v: u32) -> Weight { (26_789_000 as Weight) // Standard Error: 0 .saturating_add((133_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn cancel_proposal(p: u32, ) -> Weight { + fn cancel_proposal(p: u32) -> Weight { (49_939_000 as Weight) // Standard Error: 0 .saturating_add((511_000 as Weight).saturating_mul(p as Weight)) @@ -116,24 +113,23 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn cancel_referendum() -> Weight { - (15_902_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (15_902_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel_queued(r: u32, ) -> Weight { + fn cancel_queued(r: u32) -> Weight { (27_621_000 as Weight) // Standard Error: 1_000 .saturating_add((2_163_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn on_initialize_base(r: u32, ) -> Weight { + fn on_initialize_base(r: u32) -> Weight { (7_728_000 as Weight) // Standard Error: 4_000 .saturating_add((5_099_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) } - fn delegate(r: u32, ) -> Weight { + fn delegate(r: u32) -> Weight { (53_667_000 as Weight) // Standard Error: 4_000 .saturating_add((7_194_000 as Weight).saturating_mul(r as Weight)) @@ -142,7 +138,7 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) } - fn undelegate(r: u32, ) -> Weight { + fn undelegate(r: u32) -> Weight { (23_077_000 as Weight) // Standard Error: 5_000 .saturating_add((7_164_000 as Weight).saturating_mul(r as Weight)) @@ -152,52 +148,51 @@ impl pallet_democracy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) } fn clear_public_proposals() -> Weight { - (2_195_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_195_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn note_preimage(b: u32, ) -> Weight { + fn note_preimage(b: u32) -> Weight { (41_252_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn note_imminent_preimage(b: u32, ) -> Weight { + fn note_imminent_preimage(b: u32) -> Weight { (26_149_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn reap_preimage(b: u32, ) -> Weight { + fn reap_preimage(b: u32) -> Weight { (36_669_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(b as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn unlock_remove(r: u32, ) -> Weight { + fn unlock_remove(r: u32) -> Weight { (37_226_000 as Weight) // Standard Error: 0 .saturating_add((53_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn unlock_set(r: u32, ) -> Weight { + fn unlock_set(r: u32) -> Weight { (34_663_000 as Weight) // Standard Error: 0 .saturating_add((199_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn remove_vote(r: u32, ) -> Weight { + fn remove_vote(r: u32) -> Weight { (19_247_000 as Weight) // Standard Error: 0 .saturating_add((182_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn remove_other_vote(r: u32, ) -> Weight { + fn remove_other_vote(r: u32) -> Weight { (19_335_000 as Weight) // Standard Error: 0 .saturating_add((184_000 as Weight).saturating_mul(r as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_election_provider_multi_phase.rs b/polkadot/runtime/polkadot/src/weights/pallet_election_provider_multi_phase.rs index a8686e373cb..bb45af18831 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_election_provider_multi_phase.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_election_provider_multi_phase.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -44,8 +43,7 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_election_provider_multi_phase::WeightInfo for WeightInfo { fn on_initialize_nothing() -> Weight { - (23_244_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) + (23_244_000 as Weight).saturating_add(T::DbWeight::get().reads(8 as Weight)) } fn on_initialize_open_signed() -> Weight { (82_453_000 as Weight) @@ -62,12 +60,12 @@ impl pallet_election_provider_multi_phase::WeightInfo f .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn elect_queued(_v: u32, _t: u32, _a: u32, _d: u32, ) -> Weight { + fn elect_queued(_v: u32, _t: u32, _a: u32, _d: u32) -> Weight { (5_408_539_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } - fn submit_unsigned(v: u32, t: u32, a: u32, d: u32, ) -> Weight { + fn submit_unsigned(v: u32, t: u32, a: u32, d: u32) -> Weight { (0 as Weight) // Standard Error: 15_000 .saturating_add((3_352_000 as Weight).saturating_mul(v as Weight)) @@ -80,7 +78,7 @@ impl pallet_election_provider_multi_phase::WeightInfo f .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn feasibility_check(v: u32, t: u32, a: u32, d: u32, ) -> Weight { + fn feasibility_check(v: u32, t: u32, a: u32, d: u32) -> Weight { (0 as Weight) // Standard Error: 10_000 .saturating_add((3_365_000 as Weight).saturating_mul(v as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_elections_phragmen.rs b/polkadot/runtime/polkadot/src/weights/pallet_elections_phragmen.rs index 5f57059aee9..dae7697d90e 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_elections_phragmen.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_elections_phragmen.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,21 +42,21 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_elections_phragmen`. pub struct WeightInfo(PhantomData); impl pallet_elections_phragmen::WeightInfo for WeightInfo { - fn vote_equal(v: u32, ) -> Weight { + fn vote_equal(v: u32) -> Weight { (40_509_000 as Weight) // Standard Error: 3_000 .saturating_add((254_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vote_more(v: u32, ) -> Weight { + fn vote_more(v: u32) -> Weight { (63_177_000 as Weight) // Standard Error: 5_000 .saturating_add((246_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vote_less(v: u32, ) -> Weight { + fn vote_less(v: u32) -> Weight { (62_878_000 as Weight) // Standard Error: 5_000 .saturating_add((269_000 as Weight).saturating_mul(v as Weight)) @@ -69,14 +68,14 @@ impl pallet_elections_phragmen::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn submit_candidacy(c: u32, ) -> Weight { + fn submit_candidacy(c: u32) -> Weight { (51_250_000 as Weight) // Standard Error: 0 .saturating_add((272_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn renounce_candidacy_candidate(c: u32, ) -> Weight { + fn renounce_candidacy_candidate(c: u32) -> Weight { (42_742_000 as Weight) // Standard Error: 0 .saturating_add((156_000 as Weight).saturating_mul(c as Weight)) @@ -99,10 +98,9 @@ impl pallet_elections_phragmen::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().writes(5 as Weight)) } fn remove_member_wrong_refund() -> Weight { - (6_347_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) + (6_347_000 as Weight).saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { + fn clean_defunct_voters(v: u32, _d: u32) -> Weight { (0 as Weight) // Standard Error: 43_000 .saturating_add((107_372_000 as Weight).saturating_mul(v as Weight)) @@ -110,7 +108,7 @@ impl pallet_elections_phragmen::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(v as Weight))) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(v as Weight))) } - fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { + fn election_phragmen(c: u32, v: u32, e: u32) -> Weight { (0 as Weight) // Standard Error: 2_739_000 .saturating_add((126_782_000 as Weight).saturating_mul(c as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_identity.rs b/polkadot/runtime/polkadot/src/weights/pallet_identity.rs index 9ad4d20cef0..82b97505cf8 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_identity.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_identity.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,14 +42,14 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_identity`. pub struct WeightInfo(PhantomData); impl pallet_identity::WeightInfo for WeightInfo { - fn add_registrar(r: u32, ) -> Weight { + fn add_registrar(r: u32) -> Weight { (20_345_000 as Weight) // Standard Error: 2_000 .saturating_add((233_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_identity(r: u32, x: u32, ) -> Weight { + fn set_identity(r: u32, x: u32) -> Weight { (50_253_000 as Weight) // Standard Error: 14_000 .saturating_add((196_000 as Weight).saturating_mul(r as Weight)) @@ -59,7 +58,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_subs_new(s: u32, ) -> Weight { + fn set_subs_new(s: u32) -> Weight { (39_222_000 as Weight) // Standard Error: 1_000 .saturating_add((6_369_000 as Weight).saturating_mul(s as Weight)) @@ -68,7 +67,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn set_subs_old(p: u32, ) -> Weight { + fn set_subs_old(p: u32) -> Weight { (39_661_000 as Weight) // Standard Error: 0 .saturating_add((2_102_000 as Weight).saturating_mul(p as Weight)) @@ -76,7 +75,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) } - fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight { + fn clear_identity(r: u32, s: u32, x: u32) -> Weight { (48_967_000 as Weight) // Standard Error: 7_000 .saturating_add((135_000 as Weight).saturating_mul(r as Weight)) @@ -88,7 +87,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn request_judgement(r: u32, x: u32, ) -> Weight { + fn request_judgement(r: u32, x: u32) -> Weight { (52_197_000 as Weight) // Standard Error: 4_000 .saturating_add((218_000 as Weight).saturating_mul(r as Weight)) @@ -97,7 +96,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel_request(r: u32, x: u32, ) -> Weight { + fn cancel_request(r: u32, x: u32) -> Weight { (48_022_000 as Weight) // Standard Error: 6_000 .saturating_add((141_000 as Weight).saturating_mul(r as Weight)) @@ -106,28 +105,28 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_fee(r: u32, ) -> Weight { + fn set_fee(r: u32) -> Weight { (7_590_000 as Weight) // Standard Error: 1_000 .saturating_add((203_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_account_id(r: u32, ) -> Weight { + fn set_account_id(r: u32) -> Weight { (8_422_000 as Weight) // Standard Error: 1_000 .saturating_add((210_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_fields(r: u32, ) -> Weight { + fn set_fields(r: u32) -> Weight { (7_561_000 as Weight) // Standard Error: 0 .saturating_add((207_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn provide_judgement(r: u32, x: u32, ) -> Weight { + fn provide_judgement(r: u32, x: u32) -> Weight { (33_330_000 as Weight) // Standard Error: 4_000 .saturating_add((196_000 as Weight).saturating_mul(r as Weight)) @@ -136,7 +135,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight { + fn kill_identity(r: u32, s: u32, x: u32) -> Weight { (61_538_000 as Weight) // Standard Error: 4_000 .saturating_add((106_000 as Weight).saturating_mul(r as Weight)) @@ -148,28 +147,28 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn add_sub(s: u32, ) -> Weight { + fn add_sub(s: u32) -> Weight { (52_704_000 as Weight) // Standard Error: 0 .saturating_add((156_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn rename_sub(s: u32, ) -> Weight { + fn rename_sub(s: u32) -> Weight { (16_279_000 as Weight) // Standard Error: 0 .saturating_add((22_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_sub(s: u32, ) -> Weight { + fn remove_sub(s: u32) -> Weight { (53_681_000 as Weight) // Standard Error: 0 .saturating_add((138_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn quit_sub(s: u32, ) -> Weight { + fn quit_sub(s: u32) -> Weight { (32_963_000 as Weight) // Standard Error: 0 .saturating_add((136_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_im_online.rs b/polkadot/runtime/polkadot/src/weights/pallet_im_online.rs index d5c73b82a0f..1d20ae82fd8 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_im_online.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_im_online.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_im_online`. pub struct WeightInfo(PhantomData); impl pallet_im_online::WeightInfo for WeightInfo { - fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight { + fn validate_unsigned_and_then_heartbeat(k: u32, e: u32) -> Weight { (88_006_000 as Weight) // Standard Error: 0 .saturating_add((157_000 as Weight).saturating_mul(k as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_indices.rs b/polkadot/runtime/polkadot/src/weights/pallet_indices.rs index cf976bfb7d6..531b2e7505d 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_indices.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_indices.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/polkadot/src/weights/pallet_membership.rs b/polkadot/runtime/polkadot/src/weights/pallet_membership.rs index 1c46690f6ab..ae0e961f25b 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_membership.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_membership.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,50 +42,49 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_membership`. pub struct WeightInfo(PhantomData); impl pallet_membership::WeightInfo for WeightInfo { - fn add_member(m: u32, ) -> Weight { + fn add_member(m: u32) -> Weight { (22_415_000 as Weight) // Standard Error: 3_000 .saturating_add((169_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn remove_member(m: u32, ) -> Weight { + fn remove_member(m: u32) -> Weight { (27_436_000 as Weight) // Standard Error: 0 .saturating_add((135_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn swap_member(m: u32, ) -> Weight { + fn swap_member(m: u32) -> Weight { (27_577_000 as Weight) // Standard Error: 0 .saturating_add((149_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn reset_member(m: u32, ) -> Weight { + fn reset_member(m: u32) -> Weight { (28_417_000 as Weight) // Standard Error: 0 .saturating_add((305_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn change_key(m: u32, ) -> Weight { + fn change_key(m: u32) -> Weight { (29_217_000 as Weight) // Standard Error: 0 .saturating_add((145_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn set_prime(m: u32, ) -> Weight { + fn set_prime(m: u32) -> Weight { (7_017_000 as Weight) // Standard Error: 0 .saturating_add((80_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn clear_prime(_m: u32, ) -> Weight { - (2_742_000 as Weight) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) + fn clear_prime(_m: u32) -> Weight { + (2_742_000 as Weight).saturating_add(T::DbWeight::get().writes(2 as Weight)) } } diff --git a/polkadot/runtime/polkadot/src/weights/pallet_multisig.rs b/polkadot/runtime/polkadot/src/weights/pallet_multisig.rs index 8db5643e1e5..4348dd722df 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_multisig.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_multisig.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,10 +42,10 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_multisig`. pub struct WeightInfo(PhantomData); impl pallet_multisig::WeightInfo for WeightInfo { - fn as_multi_threshold_1(_z: u32, ) -> Weight { + fn as_multi_threshold_1(_z: u32) -> Weight { (10_355_000 as Weight) } - fn as_multi_create(s: u32, z: u32, ) -> Weight { + fn as_multi_create(s: u32, z: u32) -> Weight { (48_627_000 as Weight) // Standard Error: 0 .saturating_add((106_000 as Weight).saturating_mul(s as Weight)) @@ -55,7 +54,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn as_multi_create_store(s: u32, z: u32, ) -> Weight { + fn as_multi_create_store(s: u32, z: u32) -> Weight { (54_885_000 as Weight) // Standard Error: 0 .saturating_add((108_000 as Weight).saturating_mul(s as Weight)) @@ -64,7 +63,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn as_multi_approve(s: u32, z: u32, ) -> Weight { + fn as_multi_approve(s: u32, z: u32) -> Weight { (28_368_000 as Weight) // Standard Error: 0 .saturating_add((103_000 as Weight).saturating_mul(s as Weight)) @@ -73,7 +72,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn as_multi_approve_store(s: u32, z: u32, ) -> Weight { + fn as_multi_approve_store(s: u32, z: u32) -> Weight { (52_085_000 as Weight) // Standard Error: 0 .saturating_add((116_000 as Weight).saturating_mul(s as Weight)) @@ -82,7 +81,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn as_multi_complete(s: u32, z: u32, ) -> Weight { + fn as_multi_complete(s: u32, z: u32) -> Weight { (66_094_000 as Weight) // Standard Error: 0 .saturating_add((206_000 as Weight).saturating_mul(s as Weight)) @@ -91,28 +90,28 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn approve_as_multi_create(s: u32, ) -> Weight { + fn approve_as_multi_create(s: u32) -> Weight { (48_354_000 as Weight) // Standard Error: 0 .saturating_add((105_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn approve_as_multi_approve(s: u32, ) -> Weight { + fn approve_as_multi_approve(s: u32) -> Weight { (27_780_000 as Weight) // Standard Error: 0 .saturating_add((103_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn approve_as_multi_complete(s: u32, ) -> Weight { + fn approve_as_multi_complete(s: u32) -> Weight { (108_496_000 as Weight) // Standard Error: 0 .saturating_add((211_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn cancel_as_multi(s: u32, ) -> Weight { + fn cancel_as_multi(s: u32) -> Weight { (81_062_000 as Weight) // Standard Error: 0 .saturating_add((103_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_proxy.rs b/polkadot/runtime/polkadot/src/weights/pallet_proxy.rs index a4ced828fd8..6f840032bd9 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_proxy.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_proxy.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,13 +42,13 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_proxy`. pub struct WeightInfo(PhantomData); impl pallet_proxy::WeightInfo for WeightInfo { - fn proxy(p: u32, ) -> Weight { + fn proxy(p: u32) -> Weight { (21_368_000 as Weight) // Standard Error: 0 .saturating_add((123_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn proxy_announced(a: u32, p: u32, ) -> Weight { + fn proxy_announced(a: u32, p: u32) -> Weight { (51_019_000 as Weight) // Standard Error: 1_000 .saturating_add((562_000 as Weight).saturating_mul(a as Weight)) @@ -58,21 +57,21 @@ impl pallet_proxy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn remove_announcement(a: u32, _p: u32, ) -> Weight { + fn remove_announcement(a: u32, _p: u32) -> Weight { (36_491_000 as Weight) // Standard Error: 1_000 .saturating_add((556_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn reject_announcement(a: u32, _p: u32, ) -> Weight { + fn reject_announcement(a: u32, _p: u32) -> Weight { (36_142_000 as Weight) // Standard Error: 1_000 .saturating_add((564_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn announce(a: u32, p: u32, ) -> Weight { + fn announce(a: u32, p: u32) -> Weight { (48_515_000 as Weight) // Standard Error: 2_000 .saturating_add((562_000 as Weight).saturating_mul(a as Weight)) @@ -81,35 +80,35 @@ impl pallet_proxy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn add_proxy(p: u32, ) -> Weight { + fn add_proxy(p: u32) -> Weight { (34_650_000 as Weight) // Standard Error: 1_000 .saturating_add((212_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_proxy(p: u32, ) -> Weight { + fn remove_proxy(p: u32) -> Weight { (34_378_000 as Weight) // Standard Error: 2_000 .saturating_add((240_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_proxies(p: u32, ) -> Weight { + fn remove_proxies(p: u32) -> Weight { (32_543_000 as Weight) // Standard Error: 1_000 .saturating_add((134_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn anonymous(p: u32, ) -> Weight { + fn anonymous(p: u32) -> Weight { (46_410_000 as Weight) // Standard Error: 1_000 .saturating_add((32_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn kill_anonymous(p: u32, ) -> Weight { + fn kill_anonymous(p: u32) -> Weight { (34_483_000 as Weight) // Standard Error: 1_000 .saturating_add((133_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_scheduler.rs b/polkadot/runtime/polkadot/src/weights/pallet_scheduler.rs index 9484e8db00a..12b30c34df5 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_scheduler.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_scheduler.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,28 +42,28 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_scheduler`. pub struct WeightInfo(PhantomData); impl pallet_scheduler::WeightInfo for WeightInfo { - fn schedule(s: u32, ) -> Weight { + fn schedule(s: u32) -> Weight { (23_340_000 as Weight) // Standard Error: 0 .saturating_add((39_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel(s: u32, ) -> Weight { + fn cancel(s: u32) -> Weight { (22_347_000 as Weight) // Standard Error: 4_000 .saturating_add((1_864_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn schedule_named(s: u32, ) -> Weight { + fn schedule_named(s: u32) -> Weight { (29_626_000 as Weight) // Standard Error: 1_000 .saturating_add((58_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn cancel_named(s: u32, ) -> Weight { + fn cancel_named(s: u32) -> Weight { (25_024_000 as Weight) // Standard Error: 4_000 .saturating_add((1_882_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_session.rs b/polkadot/runtime/polkadot/src/weights/pallet_session.rs index c7548a0afca..83eca6bf5e9 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_session.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_session.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/polkadot/src/weights/pallet_staking.rs b/polkadot/runtime/polkadot/src/weights/pallet_staking.rs index d56a945f09a..81b65921bbf 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_staking.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_staking.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -58,14 +57,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn withdraw_unbonded_update(s: u32, ) -> Weight { + fn withdraw_unbonded_update(s: u32) -> Weight { (49_182_000 as Weight) // Standard Error: 0 .saturating_add((31_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn withdraw_unbonded_kill(s: u32, ) -> Weight { + fn withdraw_unbonded_kill(s: u32) -> Weight { (81_006_000 as Weight) // Standard Error: 1_000 .saturating_add((2_333_000 as Weight).saturating_mul(s as Weight)) @@ -78,7 +77,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn kick(k: u32, ) -> Weight { + fn kick(k: u32) -> Weight { (10_487_000 as Weight) // Standard Error: 7_000 .saturating_add((16_334_000 as Weight).saturating_mul(k as Weight)) @@ -86,7 +85,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(k as Weight))) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } - fn nominate(n: u32, ) -> Weight { + fn nominate(n: u32) -> Weight { (38_083_000 as Weight) // Standard Error: 10_000 .saturating_add((5_185_000 as Weight).saturating_mul(n as Weight)) @@ -95,8 +94,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn chill() -> Weight { - (16_783_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) + (16_783_000 as Weight).saturating_add(T::DbWeight::get().reads(3 as Weight)) } fn set_payee() -> Weight { (11_391_000 as Weight) @@ -109,28 +107,24 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn set_validator_count() -> Weight { - (1_879_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (1_879_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_no_eras() -> Weight { - (2_139_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_139_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_new_era() -> Weight { - (2_096_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_096_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_new_era_always() -> Weight { - (2_089_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_089_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_invulnerables(v: u32, ) -> Weight { + fn set_invulnerables(v: u32) -> Weight { (2_143_000 as Weight) // Standard Error: 0 .saturating_add((23_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn force_unstake(s: u32, ) -> Weight { + fn force_unstake(s: u32) -> Weight { (58_264_000 as Weight) // Standard Error: 1_000 .saturating_add((2_309_000 as Weight).saturating_mul(s as Weight)) @@ -138,14 +132,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(6 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn cancel_deferred_slash(s: u32, ) -> Weight { + fn cancel_deferred_slash(s: u32) -> Weight { (3_444_385_000 as Weight) // Standard Error: 224_000 .saturating_add((19_743_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn payout_stakers_dead_controller(n: u32, ) -> Weight { + fn payout_stakers_dead_controller(n: u32) -> Weight { (106_496_000 as Weight) // Standard Error: 13_000 .saturating_add((46_186_000 as Weight).saturating_mul(n as Weight)) @@ -154,7 +148,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(n as Weight))) } - fn payout_stakers_alive_staked(n: u32, ) -> Weight { + fn payout_stakers_alive_staked(n: u32) -> Weight { (131_706_000 as Weight) // Standard Error: 20_000 .saturating_add((60_519_000 as Weight).saturating_mul(n as Weight)) @@ -163,14 +157,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(n as Weight))) } - fn rebond(l: u32, ) -> Weight { + fn rebond(l: u32) -> Weight { (46_089_000 as Weight) // Standard Error: 1_000 .saturating_add((64_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn set_history_depth(e: u32, ) -> Weight { + fn set_history_depth(e: u32) -> Weight { (0 as Weight) // Standard Error: 67_000 .saturating_add((32_486_000 as Weight).saturating_mul(e as Weight)) @@ -178,7 +172,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((7 as Weight).saturating_mul(e as Weight))) } - fn reap_stash(s: u32, ) -> Weight { + fn reap_stash(s: u32) -> Weight { (69_019_000 as Weight) // Standard Error: 0 .saturating_add((2_317_000 as Weight).saturating_mul(s as Weight)) @@ -186,7 +180,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(8 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn new_era(v: u32, n: u32, ) -> Weight { + fn new_era(v: u32, n: u32) -> Weight { (0 as Weight) // Standard Error: 666_000 .saturating_add((306_698_000 as Weight).saturating_mul(v as Weight)) @@ -198,7 +192,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(v as Weight))) } - fn get_npos_voters(v: u32, n: u32, s: u32, ) -> Weight { + fn get_npos_voters(v: u32, n: u32, s: u32) -> Weight { (0 as Weight) // Standard Error: 97_000 .saturating_add((25_109_000 as Weight).saturating_mul(v as Weight)) @@ -211,7 +205,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(s as Weight))) } - fn get_npos_targets(v: u32, ) -> Weight { + fn get_npos_targets(v: u32) -> Weight { (0 as Weight) // Standard Error: 31_000 .saturating_add((10_220_000 as Weight).saturating_mul(v as Weight)) @@ -219,8 +213,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(v as Weight))) } fn set_staking_limits() -> Weight { - (5_584_000 as Weight) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) + (5_584_000 as Weight).saturating_add(T::DbWeight::get().writes(5 as Weight)) } fn chill_other() -> Weight { (39_524_000 as Weight) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_timestamp.rs b/polkadot/runtime/polkadot/src/weights/pallet_timestamp.rs index 6c56445db35..6c5e910899c 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_timestamp.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_timestamp.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/polkadot/src/weights/pallet_tips.rs b/polkadot/runtime/polkadot/src/weights/pallet_tips.rs index 0dcd11b2bea..4b998ef16d2 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_tips.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_tips.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_tips`. pub struct WeightInfo(PhantomData); impl pallet_tips::WeightInfo for WeightInfo { - fn report_awesome(r: u32, ) -> Weight { + fn report_awesome(r: u32) -> Weight { (46_460_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) @@ -55,7 +54,7 @@ impl pallet_tips::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn tip_new(r: u32, t: u32, ) -> Weight { + fn tip_new(r: u32, t: u32) -> Weight { (27_685_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) @@ -64,21 +63,21 @@ impl pallet_tips::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn tip(t: u32, ) -> Weight { + fn tip(t: u32) -> Weight { (18_081_000 as Weight) // Standard Error: 0 .saturating_add((565_000 as Weight).saturating_mul(t as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn close_tip(t: u32, ) -> Weight { + fn close_tip(t: u32) -> Weight { (77_929_000 as Weight) // Standard Error: 0 .saturating_add((299_000 as Weight).saturating_mul(t as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn slash_tip(t: u32, ) -> Weight { + fn slash_tip(t: u32) -> Weight { (22_710_000 as Weight) // Standard Error: 0 .saturating_add((7_000 as Weight).saturating_mul(t as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_treasury.rs b/polkadot/runtime/polkadot/src/weights/pallet_treasury.rs index ceb9ba9a444..c59ceea70aa 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_treasury.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_treasury.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -53,14 +52,14 @@ impl pallet_treasury::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn approve_proposal(p: u32, ) -> Weight { + fn approve_proposal(p: u32) -> Weight { (11_245_000 as Weight) // Standard Error: 0 .saturating_add((32_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn on_initialize_proposals(p: u32, ) -> Weight { + fn on_initialize_proposals(p: u32) -> Weight { (40_847_000 as Weight) // Standard Error: 15_000 .saturating_add((56_748_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_utility.rs b/polkadot/runtime/polkadot/src/weights/pallet_utility.rs index 2257a086b75..947ed1bcb46 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_utility.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_utility.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_utility`. pub struct WeightInfo(PhantomData); impl pallet_utility::WeightInfo for WeightInfo { - fn batch(c: u32, ) -> Weight { + fn batch(c: u32) -> Weight { (13_489_000 as Weight) // Standard Error: 0 .saturating_add((605_000 as Weight).saturating_mul(c as Weight)) @@ -51,7 +50,7 @@ impl pallet_utility::WeightInfo for WeightInfo { fn as_derivative() -> Weight { (3_230_000 as Weight) } - fn batch_all(c: u32, ) -> Weight { + fn batch_all(c: u32) -> Weight { (13_266_000 as Weight) // Standard Error: 0 .saturating_add((1_014_000 as Weight).saturating_mul(c as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/pallet_vesting.rs b/polkadot/runtime/polkadot/src/weights/pallet_vesting.rs index 93a6e646502..4de01dc16ca 100644 --- a/polkadot/runtime/polkadot/src/weights/pallet_vesting.rs +++ b/polkadot/runtime/polkadot/src/weights/pallet_vesting.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,42 +42,42 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_vesting`. pub struct WeightInfo(PhantomData); impl pallet_vesting::WeightInfo for WeightInfo { - fn vest_locked(l: u32, ) -> Weight { + fn vest_locked(l: u32) -> Weight { (41_282_000 as Weight) // Standard Error: 14_000 .saturating_add((225_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn vest_unlocked(l: u32, ) -> Weight { + fn vest_unlocked(l: u32) -> Weight { (44_048_000 as Weight) // Standard Error: 10_000 .saturating_add((192_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vest_other_locked(l: u32, ) -> Weight { + fn vest_other_locked(l: u32) -> Weight { (40_722_000 as Weight) // Standard Error: 17_000 .saturating_add((242_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vest_other_unlocked(l: u32, ) -> Weight { + fn vest_other_unlocked(l: u32) -> Weight { (43_752_000 as Weight) // Standard Error: 14_000 .saturating_add((215_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn vested_transfer(l: u32, ) -> Weight { + fn vested_transfer(l: u32) -> Weight { (97_642_000 as Weight) // Standard Error: 13_000 .saturating_add((133_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn force_vested_transfer(l: u32, ) -> Weight { + fn force_vested_transfer(l: u32) -> Weight { (97_119_000 as Weight) // Standard Error: 13_000 .saturating_add((124_000 as Weight).saturating_mul(l as Weight)) diff --git a/polkadot/runtime/polkadot/src/weights/runtime_common_claims.rs b/polkadot/runtime/polkadot/src/weights/runtime_common_claims.rs index a64d81e75d7..1086ebdee55 100644 --- a/polkadot/runtime/polkadot/src/weights/runtime_common_claims.rs +++ b/polkadot/runtime/polkadot/src/weights/runtime_common_claims.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/polkadot/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/rococo/src/bridge_messages.rs b/polkadot/runtime/rococo/src/bridge_messages.rs index f61620666a5..0eef3705684 100644 --- a/polkadot/runtime/rococo/src/bridge_messages.rs +++ b/polkadot/runtime/rococo/src/bridge_messages.rs @@ -23,17 +23,25 @@ use bp_messages::{ target_chain::{ProvedMessages, SourceHeaderChain}, InboundLaneData, LaneId, Message, MessageNonce, }; -use bp_rococo::{EXTRA_STORAGE_PROOF_SIZE, MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, max_extrinsic_size, max_extrinsic_weight}; -use bp_runtime::{ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID, ChainId}; +use bp_rococo::{ + max_extrinsic_size, max_extrinsic_weight, EXTRA_STORAGE_PROOF_SIZE, + MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, +}; +use bp_runtime::{ChainId, ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID}; use bridge_runtime_common::messages::{ - BridgedChainWithMessages, ChainWithMessages, MessageBridge, MessageTransaction, ThisChainWithMessages, - source as messages_source, target as messages_target, + source as messages_source, target as messages_target, BridgedChainWithMessages, + ChainWithMessages, MessageBridge, MessageTransaction, ThisChainWithMessages, +}; +use frame_support::{ + traits::Get, + weights::{Weight, WeightToFeePolynomial}, + RuntimeDebug, }; -use frame_support::{traits::Get, weights::{Weight, WeightToFeePolynomial}, RuntimeDebug}; use sp_std::{convert::TryFrom, marker::PhantomData, ops::RangeInclusive}; /// Maximal number of pending outbound messages. -const MAXIMAL_PENDING_MESSAGES_AT_OUTBOUND_LANE: MessageNonce = bp_rococo::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE; +const MAXIMAL_PENDING_MESSAGES_AT_OUTBOUND_LANE: MessageNonce = + bp_rococo::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE; /// Maximal weight of single message delivery confirmation transaction on Rococo/Wococo chain. /// /// This value is a result of `pallet_bridge_messages::Pallet::receive_messages_delivery_proof` weight formula @@ -64,16 +72,20 @@ const PAY_INBOUND_DISPATCH_FEE_WEIGHT: Weight = 600_000_000; const TX_EXTRA_BYTES: u32 = 130; /// Rococo chain as it is seen at Rococo. -pub type RococoAtRococo = RococoLikeChain; +pub type RococoAtRococo = + RococoLikeChain; /// Rococo chain as it is seen at Wococo. -pub type RococoAtWococo = RococoLikeChain; +pub type RococoAtWococo = + RococoLikeChain; /// Wococo chain as it is seen at Wococo. -pub type WococoAtWococo = RococoLikeChain; +pub type WococoAtWococo = + RococoLikeChain; /// Wococo chain as it is seen at Rococo. -pub type WococoAtRococo = RococoLikeChain; +pub type WococoAtRococo = + RococoLikeChain; /// Rococo/Wococo chain from message lane point of view. #[derive(RuntimeDebug, Clone, Copy)] @@ -121,7 +133,9 @@ impl ThisChainWithMessages for RococoLikeChain { fn transaction_payment(transaction: MessageTransaction) -> crate::Balance { // current fee multiplier is used here bridge_runtime_common::messages::transaction_payment( - crate::BlockWeights::get().get(frame_support::weights::DispatchClass::Normal).base_extrinsic, + crate::BlockWeights::get() + .get(frame_support::weights::DispatchClass::Normal) + .base_extrinsic, crate::TransactionByteFee::get(), pallet_transaction_payment::Pallet::::next_fee_multiplier(), |weight| crate::constants::fee::WeightToFee::calc(&weight), @@ -137,7 +151,8 @@ impl BridgedChainWithMessages for RococoLikeChain { fn message_weight_limits(_message_payload: &[u8]) -> RangeInclusive { // we don't want to relay too large messages + keep reserve for future upgrades - let upper_limit = messages_target::maximal_incoming_message_dispatch_weight(max_extrinsic_weight()); + let upper_limit = + messages_target::maximal_incoming_message_dispatch_weight(max_extrinsic_weight()); // we're charging for payload bytes in `With(Wococo | Rococo)MessageBridge::transaction_payment` function // @@ -175,7 +190,9 @@ impl BridgedChainWithMessages for RococoLikeChain { fn transaction_payment(transaction: MessageTransaction) -> crate::Balance { // current fee multiplier is used here bridge_runtime_common::messages::transaction_payment( - crate::BlockWeights::get().get(frame_support::weights::DispatchClass::Normal).base_extrinsic, + crate::BlockWeights::get() + .get(frame_support::weights::DispatchClass::Normal) + .base_extrinsic, crate::TransactionByteFee::get(), pallet_transaction_payment::Pallet::::next_fee_multiplier(), |weight| crate::constants::fee::WeightToFee::calc(&weight), @@ -233,7 +250,7 @@ pub struct GetDeliveryConfirmationTransactionFee; impl Get for GetDeliveryConfirmationTransactionFee { fn get() -> crate::Balance { ::transaction_payment( - RococoAtRococo::estimate_delivery_confirmation_transaction() + RococoAtRococo::estimate_delivery_confirmation_transaction(), ) } } @@ -255,24 +272,28 @@ mod at_rococo { type BridgedChain = WococoAtRococo; type BridgedMessagesInstance = crate::AtWococoWithRococoMessagesInstance; - fn bridged_balance_to_this_balance(bridged_balance: bp_wococo::Balance) -> bp_rococo::Balance { + fn bridged_balance_to_this_balance( + bridged_balance: bp_wococo::Balance, + ) -> bp_rococo::Balance { bridged_balance } } /// Message payload for Rococo -> Wococo messages as it is seen at the Rococo. - pub type ToWococoMessagePayload = messages_source::FromThisChainMessagePayload; + pub type ToWococoMessagePayload = + messages_source::FromThisChainMessagePayload; /// Message verifier for Rococo -> Wococo messages at Rococo. - pub type ToWococoMessageVerifier = messages_source::FromThisChainMessageVerifier; + pub type ToWococoMessageVerifier = + messages_source::FromThisChainMessageVerifier; /// Message payload for Wococo -> Rococo messages as it is seen at Rococo. - pub type FromWococoMessagePayload = messages_target::FromBridgedChainMessagePayload< - AtRococoWithWococoMessageBridge - >; + pub type FromWococoMessagePayload = + messages_target::FromBridgedChainMessagePayload; /// Encoded Rococo Call as it comes from Wococo. - pub type FromWococoEncodedCall = messages_target::FromBridgedChainEncodedMessageCall; + pub type FromWococoEncodedCall = + messages_target::FromBridgedChainEncodedMessageCall; /// Call-dispatch based message dispatch for Wococo -> Rococo messages. pub type FromWococoMessageDispatch = messages_target::FromBridgedChainMessageDispatch< @@ -300,24 +321,28 @@ mod at_wococo { type BridgedChain = RococoAtWococo; type BridgedMessagesInstance = crate::AtRococoWithWococoMessagesInstance; - fn bridged_balance_to_this_balance(bridged_balance: bp_rococo::Balance) -> bp_wococo::Balance { + fn bridged_balance_to_this_balance( + bridged_balance: bp_rococo::Balance, + ) -> bp_wococo::Balance { bridged_balance } } /// Message payload for Wococo -> Rococo messages as it is seen at the Wococo. - pub type ToRococoMessagePayload = messages_source::FromThisChainMessagePayload; + pub type ToRococoMessagePayload = + messages_source::FromThisChainMessagePayload; /// Message verifier for Wococo -> Rococo messages at Wococo. - pub type ToRococoMessageVerifier = messages_source::FromThisChainMessageVerifier; + pub type ToRococoMessageVerifier = + messages_source::FromThisChainMessageVerifier; /// Message payload for Rococo -> Wococo messages as it is seen at Wococo. - pub type FromRococoMessagePayload = messages_target::FromBridgedChainMessagePayload< - AtWococoWithRococoMessageBridge, - >; + pub type FromRococoMessagePayload = + messages_target::FromBridgedChainMessagePayload; /// Encoded Wococo Call as it comes from Rococo. - pub type FromRococoEncodedCall = messages_target::FromBridgedChainEncodedMessageCall; + pub type FromRococoEncodedCall = + messages_target::FromBridgedChainEncodedMessageCall; /// Call-dispatch based message dispatch for Rococo -> Wococo messages. pub type FromRococoMessageDispatch = messages_target::FromBridgedChainMessageDispatch< @@ -330,9 +355,9 @@ mod at_wococo { #[cfg(test)] mod tests { + use super::*; use bridge_runtime_common::messages; use parity_scale_codec::Encode; - use super::*; #[test] fn ensure_rococo_messages_weights_are_correct() { @@ -361,15 +386,18 @@ mod tests { bp_rococo::max_extrinsic_size(), bp_rococo::max_extrinsic_weight(), max_incoming_message_proof_size, - messages::target::maximal_incoming_message_dispatch_weight(bp_rococo::max_extrinsic_weight()), + messages::target::maximal_incoming_message_dispatch_weight( + bp_rococo::max_extrinsic_weight(), + ), ); - let max_incoming_inbound_lane_data_proof_size = bp_messages::InboundLaneData::<()>::encoded_size_hint( - bp_rococo::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, - bp_rococo::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE as _, - bp_rococo::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE as _, - ) - .unwrap_or(u32::MAX); + let max_incoming_inbound_lane_data_proof_size = + bp_messages::InboundLaneData::<()>::encoded_size_hint( + bp_rococo::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, + bp_rococo::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE as _, + bp_rococo::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE as _, + ) + .unwrap_or(u32::MAX); pallet_bridge_messages::ensure_able_to_receive_confirmation::( bp_rococo::max_extrinsic_size(), bp_rococo::max_extrinsic_weight(), @@ -392,14 +420,19 @@ mod tests { frame_system::CheckSpecVersion::new(), frame_system::CheckTxVersion::new(), frame_system::CheckGenesis::new(), - frame_system::CheckMortality::from(sp_runtime::generic::Era::mortal(u64::MAX, u64::MAX)), + frame_system::CheckMortality::from(sp_runtime::generic::Era::mortal( + u64::MAX, + u64::MAX, + )), frame_system::CheckNonce::from(primitives::v1::Nonce::MAX), frame_system::CheckWeight::new(), - pallet_transaction_payment::ChargeTransactionPayment::from(primitives::v1::Balance::MAX), + pallet_transaction_payment::ChargeTransactionPayment::from( + primitives::v1::Balance::MAX, + ), ); - let extra_bytes_in_transaction = crate::Address::default().encoded_size() - + crate::Signature::default().encoded_size() - + signed_extra.encoded_size(); + let extra_bytes_in_transaction = crate::Address::default().encoded_size() + + crate::Signature::default().encoded_size() + + signed_extra.encoded_size(); assert!( TX_EXTRA_BYTES as usize >= extra_bytes_in_transaction, "Hardcoded number of extra bytes in Rococo transaction {} is lower than actual value: {}", diff --git a/polkadot/runtime/rococo/src/constants.rs b/polkadot/runtime/rococo/src/constants.rs index b4949544fe6..cb69e2d867e 100644 --- a/polkadot/runtime/rococo/src/constants.rs +++ b/polkadot/runtime/rococo/src/constants.rs @@ -30,7 +30,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::v0::{Moment, BlockNumber}; + use primitives::v0::{BlockNumber, Moment}; pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; frame_support::parameter_types! { @@ -48,13 +48,13 @@ pub mod time { /// Fee-related. pub mod fee { - pub use sp_runtime::Perbill; - use primitives::v0::Balance; - use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ - WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }; + use primitives::v0::Balance; + use runtime_common::ExtrinsicBaseWeight; use smallvec::smallvec; + pub use sp_runtime::Perbill; /// The block saturation level. Fees will be updates based on this value. pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); @@ -88,10 +88,12 @@ pub mod fee { #[cfg(test)] mod tests { - use frame_support::weights::{WeightToFeePolynomial, DispatchClass}; + use super::{ + currency::{CENTS, DOLLARS, MILLICENTS}, + fee::WeightToFee, + }; + use frame_support::weights::{DispatchClass, WeightToFeePolynomial}; use runtime_common::BlockWeights; - use super::fee::WeightToFee; - use super::currency::{CENTS, DOLLARS, MILLICENTS}; #[test] // This function tests that the fee for `MaximumBlockWeight` of weight is correct diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 683865f31c2..b45ef057775 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -20,87 +20,78 @@ // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] -use pallet_transaction_payment::CurrencyAdapter; -use sp_std::prelude::*; -use sp_std::collections::btree_map::BTreeMap; -use parity_scale_codec::{Encode, Decode, MaxEncodedLen}; -use primitives::v1::{ - AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, - GroupRotationInfo, CoreState, Id, ValidationCode, ValidationCodeHash, CandidateEvent, - ValidatorId, ValidatorIndex, CommittedCandidateReceipt, OccupiedCoreAssumption, - PersistedValidationData, InboundDownwardMessage, InboundHrmpMessage, - SessionInfo as SessionInfoData, -}; -use runtime_common::{ - SlowAdjustingFeeUpdate, impls::ToAuthor, BlockHashCount, BlockWeights, BlockLength, RocksDbWeight, -}; -use runtime_parachains::{ - self, - runtime_api_impl::v1 as runtime_api_impl, -}; +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::{crypto::AuthorityId as BeefyId, mmr::MmrLeafVersion}; use frame_support::{ - PalletId, construct_runtime, parameter_types, + construct_runtime, parameter_types, traits::{All, Filter, IsInVec, KeyOwnerProofSystem, OnRuntimeUpgrade, Randomness}, weights::Weight, + PalletId, +}; +use frame_system::EnsureRoot; +use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use pallet_mmr_primitives as mmr; +use pallet_session::historical as session_historical; +use pallet_transaction_payment::{CurrencyAdapter, FeeDetails, RuntimeDispatchInfo}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use primitives::v1::{ + AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt, + CoreState, GroupRotationInfo, Hash, Id, InboundDownwardMessage, InboundHrmpMessage, Moment, + Nonce, OccupiedCoreAssumption, PersistedValidationData, SessionInfo as SessionInfoData, + Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, +}; +use runtime_common::{ + auctions, crowdloan, impls::ToAuthor, paras_registrar, paras_sudo_wrapper, slots, xcm_sender, + BlockHashCount, BlockLength, BlockWeights, RocksDbWeight, SlowAdjustingFeeUpdate, }; +use runtime_parachains::{self, runtime_api_impl::v1 as runtime_api_impl}; +use sp_core::{OpaqueMetadata, RuntimeDebug}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - ApplyExtrinsicResult, KeyTypeId, Perbill, - transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority}, traits::{ - self, Keccak256, BlakeTwo256, Block as BlockT, OpaqueKeys, AccountIdLookup, - Extrinsic as ExtrinsicT, SaturatedConversion, Verify, + self, AccountIdLookup, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, Keccak256, + OpaqueKeys, SaturatedConversion, Verify, }, + transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, KeyTypeId, Perbill, }; -use pallet_im_online::sr25519::AuthorityId as ImOnlineId; -use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use sp_staking::SessionIndex; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; -use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives}; -use sp_core::{OpaqueMetadata, RuntimeDebug}; -use sp_staking::SessionIndex; -use pallet_session::historical as session_historical; -use beefy_primitives::crypto::AuthorityId as BeefyId; -use beefy_primitives::mmr::MmrLeafVersion; -use pallet_mmr_primitives as mmr; -use frame_system::EnsureRoot; -use runtime_common::{paras_sudo_wrapper, paras_registrar, xcm_sender, auctions, crowdloan, slots}; - -use runtime_parachains::origin as parachains_origin; -use runtime_parachains::configuration as parachains_configuration; -use runtime_parachains::shared as parachains_shared; -use runtime_parachains::inclusion as parachains_inclusion; -use runtime_parachains::paras_inherent as parachains_paras_inherent; -use runtime_parachains::initializer as parachains_initializer; -use runtime_parachains::session_info as parachains_session_info; -use runtime_parachains::paras as parachains_paras; -use runtime_parachains::dmp as parachains_dmp; -use runtime_parachains::ump as parachains_ump; -use runtime_parachains::hrmp as parachains_hrmp; -use runtime_parachains::scheduler as parachains_scheduler; - -use bridge_runtime_common::messages::{MessageBridge, source::estimate_message_dispatch_and_delivery_fee}; + +use runtime_parachains::{ + configuration as parachains_configuration, dmp as parachains_dmp, hrmp as parachains_hrmp, + inclusion as parachains_inclusion, initializer as parachains_initializer, + origin as parachains_origin, paras as parachains_paras, + paras_inherent as parachains_paras_inherent, scheduler as parachains_scheduler, + session_info as parachains_session_info, shared as parachains_shared, ump as parachains_ump, +}; + +use bridge_runtime_common::messages::{ + source::estimate_message_dispatch_and_delivery_fee, MessageBridge, +}; pub use pallet_balances::Call as BalancesCall; use polkadot_parachain::primitives::Id as ParaId; -use xcm::v0::{Xcm, MultiLocation, NetworkId, BodyId}; -use xcm_executor::XcmExecutor; +use constants::{currency::*, fee::*, time::*}; +use frame_support::traits::InstanceFilter; +use xcm::v0::{BodyId, MultiLocation, NetworkId, Xcm}; use xcm_builder::{ - AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, - CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative, SignedAccountId32AsNative, - ChildSystemParachainAsSuperuser, LocationInverter, IsConcrete, FixedWeightBounds, - BackingToPlurality, SignedToAccountId32, UsingComponents, + AccountId32Aliases, BackingToPlurality, ChildParachainAsNative, ChildParachainConvertsVia, + ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, + IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, UsingComponents, }; -use constants::{time::*, currency::*, fee::*}; -use frame_support::traits::InstanceFilter; +use xcm_executor::XcmExecutor; +mod bridge_messages; /// Constant values used within the runtime. pub mod constants; -mod bridge_messages; mod validator_manager; // Make the WASM binary available. @@ -125,16 +116,13 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration = babe_primitives::BabeEpochConfiguration { c: PRIMARY_PROBABILITY, - allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots + allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots, }; /// Native version. #[cfg(any(feature = "std", test))] pub fn native_version() -> NativeVersion { - NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } /// The address format for describing accounts. @@ -163,9 +151,9 @@ pub struct MigratePalletVersionToStorageVersion; impl OnRuntimeUpgrade for MigratePalletVersionToStorageVersion { fn on_runtime_upgrade() -> frame_support::weights::Weight { - frame_support::migrations::migrate_from_pallet_version_to_storage_version::( - &RocksDbWeight::get() - ) + frame_support::migrations::migrate_from_pallet_version_to_storage_version::< + AllPalletsWithSystem, + >(&RocksDbWeight::get()) } } @@ -323,7 +311,8 @@ parameter_types! { /// Submits a transaction with the node's public and signature type. Adheres to the signed extension /// format of the chain. -impl frame_system::offchain::CreateSignedTransaction for Runtime where +impl frame_system::offchain::CreateSignedTransaction for Runtime +where Call: From, { fn create_transaction>( @@ -334,10 +323,8 @@ impl frame_system::offchain::CreateSignedTransaction for R ) -> Option<(Call, ::SignaturePayload)> { use sp_runtime::traits::StaticLookup; // take the biggest period possible. - let period = BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; + 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::() @@ -349,17 +336,20 @@ impl frame_system::offchain::CreateSignedTransaction for R frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), frame_system::CheckGenesis::::new(), - frame_system::CheckMortality::::from(generic::Era::mortal(period, current_block)), + frame_system::CheckMortality::::from(generic::Era::mortal( + period, + current_block, + )), 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 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 (call, extra, _) = raw_payload.deconstruct(); let address = ::Lookup::unlookup(account); Some((call, (address, signature, extra))) @@ -374,7 +364,9 @@ impl frame_system::offchain::SigningTypes for Runtime { /// Special `FullIdentificationOf` implementation that is returning for every input `Some(Default::default())`. pub struct FullIdentificationOf; impl sp_runtime::traits::Convert> for FullIdentificationOf { - fn convert(_: AccountId) -> Option<()> { Some(Default::default()) } + fn convert(_: AccountId) -> Option<()> { + Some(Default::default()) + } } impl pallet_session::historical::Config for Runtime { @@ -418,7 +410,8 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); } -impl frame_system::offchain::SendTransactionTypes for Runtime where +impl frame_system::offchain::SendTransactionTypes for Runtime +where Call: From, { type OverarchingCall = Call; @@ -466,7 +459,9 @@ parameter_types! { /// Special `ValidatorIdOf` implementation that is just returning the input as result. pub struct ValidatorIdOf; impl sp_runtime::traits::Convert> for ValidatorIdOf { - fn convert(a: AccountId) -> Option { Some(a) } + fn convert(a: AccountId) -> Option { + Some(a) + } } impl pallet_session::Config for Runtime { @@ -542,8 +537,11 @@ impl pallet_grandpa::Config for Runtime { GrandpaId, )>>::IdentificationTuple; - type HandleEquivocation = - pallet_grandpa::EquivocationHandler; + type HandleEquivocation = pallet_grandpa::EquivocationHandler< + Self::KeyOwnerIdentification, + Offences, + ReportLongevity, + >; type WeightInfo = (); } @@ -568,8 +566,8 @@ impl parachains_shared::Config for Runtime {} /// Special `RewardValidators` that does nothing ;) pub struct RewardValidators; impl runtime_parachains::inclusion::RewardValidators for RewardValidators { - fn reward_backing(_: impl IntoIterator) {} - fn reward_bitfields(_: impl IntoIterator) {} + fn reward_backing(_: impl IntoIterator) {} + fn reward_bitfields(_: impl IntoIterator) {} } impl parachains_inclusion::Config for Runtime { @@ -590,24 +588,21 @@ parameter_types! { pub CheckAccount: AccountId = XcmPallet::check_account(); } -pub type SovereignAccountOf = ( - ChildParachainConvertsVia, - AccountId32Aliases, -); - -pub type LocalAssetTransactor = - XcmCurrencyAdapter< - // Use this currency: - Balances, - // Use this currency when it is a fungible asset matching the given location or name: - IsConcrete, - // We can convert the MultiLocations with our converter above: - SovereignAccountOf, - // Our chain's account ID type (we can't get away without mentioning it explicitly): - AccountId, - // It's a native asset so we keep track of the teleports to maintain total issuance. - CheckAccount, - >; +pub type SovereignAccountOf = + (ChildParachainConvertsVia, AccountId32Aliases); + +pub type LocalAssetTransactor = XcmCurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // We can convert the MultiLocations with our converter above: + SovereignAccountOf, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // It's a native asset so we keep track of the teleports to maintain total issuance. + CheckAccount, +>; type LocalOriginConverter = ( SovereignSignedViaLocation, @@ -627,7 +622,12 @@ pub type XcmRouter = ( xcm_sender::ChildParachainRouter, ); -use xcm::v0::{MultiAsset, MultiAsset::AllConcreteFungible, MultiLocation::{Null, X1}, Junction::Parachain}; +use xcm::v0::{ + Junction::Parachain, + MultiAsset, + MultiAsset::AllConcreteFungible, + MultiLocation::{Null, X1}, +}; parameter_types! { pub const RococoForTick: (MultiAsset, MultiLocation) = (AllConcreteFungible { id: Null }, X1(Parachain(100))); @@ -655,11 +655,11 @@ parameter_types! { ]; } -use xcm_builder::{TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom}; +use xcm_builder::{AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, TakeWeightCredit}; pub type Barrier = ( TakeWeightCredit, AllowTopLevelPaidExecutionFrom>, - AllowUnpaidExecutionFrom>, // <- Trusted parachains get free execution + AllowUnpaidExecutionFrom>, // <- Trusted parachains get free execution ); pub struct XcmConfig; @@ -692,11 +692,15 @@ pub type LocalOriginToLocation = ( ); pub struct OnlyWithdrawTeleportForAccounts; -impl frame_support::traits::Contains<(MultiLocation, Xcm)> for OnlyWithdrawTeleportForAccounts { +impl frame_support::traits::Contains<(MultiLocation, Xcm)> + for OnlyWithdrawTeleportForAccounts +{ fn contains((ref origin, ref msg): &(MultiLocation, Xcm)) -> bool { use xcm::v0::{ - Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset}, - MultiAsset::{All, ConcreteFungible}, Junction::{AccountId32, Plurality}, + Junction::{AccountId32, Plurality}, + MultiAsset::{All, ConcreteFungible}, + Order::{BuyExecution, DepositAsset, InitiateTeleport}, + Xcm::WithdrawAsset, }; match origin { // Root and collective are allowed to execute anything. @@ -731,7 +735,7 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm)> for OnlyWithdra ) ) ) - } + }, // Nobody else is allowed to execute anything. _ => false, } @@ -821,9 +825,7 @@ impl pallet_beefy_mmr::ParachainHeadsProvider for ParasProvider { fn parachain_heads() -> Vec<(u32, Vec)> { Paras::parachains() .into_iter() - .filter_map(|id| { - Paras::para_head(&id).map(|head| (id.into(), head.0)) - }) + .filter_map(|id| Paras::para_head(&id).map(|head| (id.into(), head.0))) .collect() } } @@ -942,12 +944,13 @@ impl pallet_bridge_messages::Config for Runt type TargetHeaderChain = crate::bridge_messages::RococoAtWococo; type LaneMessageVerifier = crate::bridge_messages::ToRococoMessageVerifier; - type MessageDeliveryAndDispatchPayment = pallet_bridge_messages::instant_payments::InstantCurrencyPayments< - Runtime, - pallet_balances::Pallet, - crate::bridge_messages::GetDeliveryConfirmationTransactionFee, - RootAccountForPayments, - >; + type MessageDeliveryAndDispatchPayment = + pallet_bridge_messages::instant_payments::InstantCurrencyPayments< + Runtime, + pallet_balances::Pallet, + crate::bridge_messages::GetDeliveryConfirmationTransactionFee, + RootAccountForPayments, + >; type OnDeliveryConfirmed = (); type SourceHeaderChain = crate::bridge_messages::RococoAtWococo; @@ -976,12 +979,13 @@ impl pallet_bridge_messages::Config for Runt type TargetHeaderChain = crate::bridge_messages::WococoAtRococo; type LaneMessageVerifier = crate::bridge_messages::ToWococoMessageVerifier; - type MessageDeliveryAndDispatchPayment = pallet_bridge_messages::instant_payments::InstantCurrencyPayments< - Runtime, - pallet_balances::Pallet, - crate::bridge_messages::GetDeliveryConfirmationTransactionFee, - RootAccountForPayments, - >; + type MessageDeliveryAndDispatchPayment = + pallet_bridge_messages::instant_payments::InstantCurrencyPayments< + Runtime, + pallet_balances::Pallet, + crate::bridge_messages::GetDeliveryConfirmationTransactionFee, + RootAccountForPayments, + >; type OnDeliveryConfirmed = (); type SourceHeaderChain = crate::bridge_messages::WococoAtRococo; @@ -991,7 +995,9 @@ impl pallet_bridge_messages::Config for Runt impl Randomness for ParentHashRandomness { fn random(subject: &[u8]) -> (Hash, BlockNumber) { ( - (System::parent_hash(), subject).using_encoded(sp_io::hashing::blake2_256).into(), + (System::parent_hash(), subject) + .using_encoded(sp_io::hashing::blake2_256) + .into(), System::block_number(), ) } @@ -1074,19 +1080,24 @@ parameter_types! { } /// The type used to represent the kinds of proxying allowed. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen)] +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, MaxEncodedLen, +)] pub enum ProxyType { Any, CancelProxy, } -impl Default for ProxyType { fn default() -> Self { Self::Any } } +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} impl InstanceFilter for ProxyType { fn filter(&self, c: &Call) -> bool { match self { ProxyType::Any => true, - ProxyType::CancelProxy => matches!(c, - Call::Proxy(pallet_proxy::Call::reject_announcement(..)) - ) + ProxyType::CancelProxy => + matches!(c, Call::Proxy(pallet_proxy::Call::reject_announcement(..))), } } fn is_superset(&self, o: &Self) -> bool { diff --git a/polkadot/runtime/rococo/src/validator_manager.rs b/polkadot/runtime/rococo/src/validator_manager.rs index 194dcbe3580..a5fd2bb0a92 100644 --- a/polkadot/runtime/rococo/src/validator_manager.rs +++ b/polkadot/runtime/rococo/src/validator_manager.rs @@ -16,10 +16,7 @@ //! A pallet for managing validators on Rococo. -use frame_support::{ - decl_event, decl_error, decl_module, decl_storage, - traits::EnsureOrigin, -}; +use frame_support::{decl_error, decl_event, decl_module, decl_storage, traits::EnsureOrigin}; use sp_staking::SessionIndex; use sp_std::vec::Vec; @@ -99,7 +96,7 @@ impl Module {} impl pallet_session::SessionManager for Module { fn new_session(new_index: SessionIndex) -> Option> { if new_index <= 1 { - return None; + return None } let mut validators = Session::::validators(); @@ -125,9 +122,7 @@ impl pallet_session::SessionManager for Module { } impl pallet_session::historical::SessionManager for Module { - fn new_session( - new_index: SessionIndex, - ) -> Option> { + fn new_session(new_index: SessionIndex) -> Option> { >::new_session(new_index) .map(|r| r.into_iter().map(|v| (v, Default::default())).collect()) } diff --git a/polkadot/runtime/test-runtime/src/constants.rs b/polkadot/runtime/test-runtime/src/constants.rs index 0cfdfacdec6..3554363e900 100644 --- a/polkadot/runtime/test-runtime/src/constants.rs +++ b/polkadot/runtime/test-runtime/src/constants.rs @@ -26,7 +26,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::v0::{Moment, BlockNumber}; + use primitives::v0::{BlockNumber, Moment}; // Testnet pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; @@ -44,13 +44,13 @@ pub mod time { /// Fee-related. pub mod fee { - pub use sp_runtime::Perbill; - use primitives::v0::Balance; - use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ - WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }; + use primitives::v0::Balance; + use runtime_common::ExtrinsicBaseWeight; use smallvec::smallvec; + pub use sp_runtime::Perbill; /// The block saturation level. Fees will be updates based on this value. pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index b5721d1f5d4..de61fe47409 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -21,70 +21,65 @@ #![recursion_limit = "256"] use pallet_transaction_payment::CurrencyAdapter; -use sp_std::prelude::*; -use sp_std::collections::btree_map::BTreeMap; use parity_scale_codec::Encode; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; + +use polkadot_runtime_parachains::{ + configuration as parachains_configuration, disputes as parachains_disputes, + dmp as parachains_dmp, hrmp as parachains_hrmp, inclusion as parachains_inclusion, + initializer as parachains_initializer, paras as parachains_paras, + paras_inherent as parachains_paras_inherent, runtime_api_impl::v1 as runtime_impl, + scheduler as parachains_scheduler, session_info as parachains_session_info, + shared as parachains_shared, ump as parachains_ump, +}; -use polkadot_runtime_parachains::configuration as parachains_configuration; -use polkadot_runtime_parachains::shared as parachains_shared; -use polkadot_runtime_parachains::inclusion as parachains_inclusion; -use polkadot_runtime_parachains::paras_inherent as parachains_paras_inherent; -use polkadot_runtime_parachains::initializer as parachains_initializer; -use polkadot_runtime_parachains::session_info as parachains_session_info; -use polkadot_runtime_parachains::paras as parachains_paras; -use polkadot_runtime_parachains::dmp as parachains_dmp; -use polkadot_runtime_parachains::ump as parachains_ump; -use polkadot_runtime_parachains::hrmp as parachains_hrmp; -use polkadot_runtime_parachains::scheduler as parachains_scheduler; -use polkadot_runtime_parachains::disputes as parachains_disputes; -use polkadot_runtime_parachains::runtime_api_impl::v1 as runtime_impl; - +use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; +use beefy_primitives::crypto::AuthorityId as BeefyId; +use frame_support::{construct_runtime, parameter_types, traits::KeyOwnerProofSystem}; +use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; +use pallet_mmr_primitives as mmr; +use pallet_session::historical as session_historical; +use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; +use polkadot_runtime_parachains::reward_points::RewardValidatorsWithEraPoints; use primitives::v1::{ AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt, - CoreState, GroupRotationInfo, Hash as HashT, Id as ParaId, Moment, Nonce, OccupiedCoreAssumption, - PersistedValidationData, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, - InboundDownwardMessage, InboundHrmpMessage, SessionInfo as SessionInfoData, + CoreState, GroupRotationInfo, Hash as HashT, Id as ParaId, InboundDownwardMessage, + InboundHrmpMessage, Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, + SessionInfo as SessionInfoData, Signature, ValidationCode, ValidationCodeHash, ValidatorId, + ValidatorIndex, }; use runtime_common::{ - claims, SlowAdjustingFeeUpdate, paras_sudo_wrapper, - BlockHashCount, BlockWeights, BlockLength, + claims, paras_sudo_wrapper, BlockHashCount, BlockLength, BlockWeights, SlowAdjustingFeeUpdate, }; +use sp_core::OpaqueMetadata; use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - ApplyExtrinsicResult, Perbill, KeyTypeId, - transaction_validity::{TransactionValidity, TransactionSource}, + create_runtime_str, curve::PiecewiseLinear, + generic, impl_opaque_keys, traits::{ - BlakeTwo256, Block as BlockT, StaticLookup, OpaqueKeys, ConvertInto, - Extrinsic as ExtrinsicT, SaturatedConversion, Verify, + BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, OpaqueKeys, + SaturatedConversion, StaticLookup, Verify, }, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, KeyTypeId, Perbill, }; -use sp_version::RuntimeVersion; -use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives}; +use sp_staking::SessionIndex; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; -use sp_core::OpaqueMetadata; -use sp_staking::SessionIndex; -use frame_support::{parameter_types, construct_runtime, traits::KeyOwnerProofSystem}; -use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; -use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; -use pallet_session::historical as session_historical; -use polkadot_runtime_parachains::reward_points::RewardValidatorsWithEraPoints; -use beefy_primitives::crypto::AuthorityId as BeefyId; -use pallet_mmr_primitives as mmr; +use sp_version::RuntimeVersion; +pub use pallet_balances::Call as BalancesCall; #[cfg(feature = "std")] pub use pallet_staking::StakerStatus; -#[cfg(any(feature = "std", test))] -pub use sp_runtime::BuildStorage; +pub use pallet_sudo::Call as SudoCall; pub use pallet_timestamp::Call as TimestampCall; -pub use pallet_balances::Call as BalancesCall; pub use paras_sudo_wrapper::Call as ParasSudoWrapperCall; -pub use pallet_sudo::Call as SudoCall; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; /// Constant values used within the runtime. pub mod constants; -use constants::{time::*, currency::*, fee::*}; +use constants::{currency::*, fee::*, time::*}; // Make the WASM binary available. #[cfg(feature = "std")] @@ -105,16 +100,13 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { pub const BABE_GENESIS_EPOCH_CONFIG: babe_primitives::BabeEpochConfiguration = babe_primitives::BabeEpochConfiguration { c: PRIMARY_PROBABILITY, - allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots + allowed_slots: babe_primitives::AllowedSlots::PrimaryAndSecondaryVRFSlots, }; /// Native version. #[cfg(any(feature = "std", test))] pub fn native_version() -> NativeVersion { - NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } sp_api::decl_runtime_apis! { @@ -155,7 +147,8 @@ impl frame_system::Config for Runtime { type OnSetCode = (); } -impl frame_system::offchain::SendTransactionTypes for Runtime where +impl frame_system::offchain::SendTransactionTypes for Runtime +where Call: From, { type OverarchingCall = Call; @@ -339,7 +332,8 @@ impl pallet_staking::Config for Runtime { type EraPayout = pallet_staking::ConvertCurve; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type NextNewSession = Session; - type ElectionProvider = frame_election_provider_support::onchain::OnChainSequentialPhragmen; + type ElectionProvider = + frame_election_provider_support::onchain::OnChainSequentialPhragmen; type GenesisElectionProvider = frame_election_provider_support::onchain::OnChainSequentialPhragmen; type WeightInfo = (); @@ -364,7 +358,8 @@ impl pallet_grandpa::Config for Runtime { type WeightInfo = (); } -impl frame_system::offchain::CreateSignedTransaction for Runtime where +impl frame_system::offchain::CreateSignedTransaction for Runtime +where Call: From, { fn create_transaction>( @@ -373,30 +368,29 @@ impl frame_system::offchain::CreateSignedTransaction for R account: AccountId, nonce: ::Index, ) -> Option<(Call, ::SignaturePayload)> { - 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::() - .saturating_sub(1); + 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::().saturating_sub(1); let tip = 0; let extra: SignedExtra = ( frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), frame_system::CheckGenesis::::new(), - frame_system::CheckMortality::::from(generic::Era::mortal(period, current_block)), + frame_system::CheckMortality::::from(generic::Era::mortal( + period, + current_block, + )), 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 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 (call, extra, _) = raw_payload.deconstruct(); let address = Indices::unlookup(account); Some((call, (address, signature, extra))) @@ -571,12 +565,18 @@ pub type SignedExtra = ( frame_system::CheckMortality, frame_system::CheckNonce, frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment::, + pallet_transaction_payment::ChargeTransactionPayment, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive, Runtime, AllPallets>; +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPallets, +>; /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; diff --git a/polkadot/runtime/westend/src/constants.rs b/polkadot/runtime/westend/src/constants.rs index ff74d8977bd..77bdd954c03 100644 --- a/polkadot/runtime/westend/src/constants.rs +++ b/polkadot/runtime/westend/src/constants.rs @@ -30,7 +30,7 @@ pub mod currency { /// Time and blocks. pub mod time { - use primitives::v0::{Moment, BlockNumber}; + use primitives::v0::{BlockNumber, Moment}; pub const MILLISECS_PER_BLOCK: Moment = 6000; pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = 1 * HOURS; @@ -46,13 +46,13 @@ pub mod time { /// Fee-related. pub mod fee { - pub use sp_runtime::Perbill; - use primitives::v0::Balance; - use runtime_common::ExtrinsicBaseWeight; use frame_support::weights::{ - WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, + WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }; + use primitives::v0::Balance; + use runtime_common::ExtrinsicBaseWeight; use smallvec::smallvec; + pub use sp_runtime::Perbill; /// The block saturation level. Fees will be updates based on this value. pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); @@ -86,10 +86,12 @@ pub mod fee { #[cfg(test)] mod tests { + use super::{ + currency::{CENTS, MILLICENTS}, + fee::WeightToFee, + }; use frame_support::weights::WeightToFeePolynomial; - use runtime_common::{MAXIMUM_BLOCK_WEIGHT, ExtrinsicBaseWeight}; - use super::fee::WeightToFee; - use super::currency::{CENTS, MILLICENTS}; + use runtime_common::{ExtrinsicBaseWeight, MAXIMUM_BLOCK_WEIGHT}; #[test] // This function tests that the fee for `MAXIMUM_BLOCK_WEIGHT` of weight is correct diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index 0f763d21ab0..7603e02f251 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -34,6 +34,8 @@ fn sample_size_is_sensible() { let max_weight: Weight = RocksDbWeight::get().reads_writes(samples.into(), samples.into()); // Max sample cleanup should be no more than half the total block weight. assert!(max_weight * 2 < BlockWeights::get().max_block); - assert!(::WeightInfo::on_initialize() * 2 < BlockWeights::get().max_block); + assert!( + ::WeightInfo::on_initialize() * 2 < + BlockWeights::get().max_block + ); } - diff --git a/polkadot/runtime/westend/src/weights/frame_system.rs b/polkadot/runtime/westend/src/weights/frame_system.rs index abaa2028134..87e46f90bda 100644 --- a/polkadot/runtime/westend/src/weights/frame_system.rs +++ b/polkadot/runtime/westend/src/weights/frame_system.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,36 +42,35 @@ use sp_std::marker::PhantomData; /// Weight functions for `frame_system`. pub struct WeightInfo(PhantomData); impl frame_system::WeightInfo for WeightInfo { - fn remark(_b: u32, ) -> Weight { + fn remark(_b: u32) -> Weight { (1_238_000 as Weight) } - fn remark_with_event(b: u32, ) -> Weight { + fn remark_with_event(b: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((1_000 as Weight).saturating_mul(b as Weight)) } fn set_heap_pages() -> Weight { - (1_689_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (1_689_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn set_changes_trie_config() -> Weight { (9_679_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn set_storage(i: u32, ) -> Weight { + fn set_storage(i: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((532_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) } - fn kill_storage(i: u32, ) -> Weight { + fn kill_storage(i: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((380_000 as Weight).saturating_mul(i as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) } - fn kill_prefix(p: u32, ) -> Weight { + fn kill_prefix(p: u32) -> Weight { (0 as Weight) // Standard Error: 0 .saturating_add((789_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_balances.rs b/polkadot/runtime/westend/src/weights/pallet_balances.rs index 4e9f870706b..5009fc87204 100644 --- a/polkadot/runtime/westend/src/weights/pallet_balances.rs +++ b/polkadot/runtime/westend/src/weights/pallet_balances.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/westend/src/weights/pallet_election_provider_multi_phase.rs b/polkadot/runtime/westend/src/weights/pallet_election_provider_multi_phase.rs index faf166cf65b..6f6c7f4be34 100644 --- a/polkadot/runtime/westend/src/weights/pallet_election_provider_multi_phase.rs +++ b/polkadot/runtime/westend/src/weights/pallet_election_provider_multi_phase.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -44,8 +43,7 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_election_provider_multi_phase::WeightInfo for WeightInfo { fn on_initialize_nothing() -> Weight { - (23_792_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) + (23_792_000 as Weight).saturating_add(T::DbWeight::get().reads(8 as Weight)) } fn on_initialize_open_signed() -> Weight { (86_272_000 as Weight) @@ -62,12 +60,12 @@ impl pallet_election_provider_multi_phase::WeightInfo f .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn elect_queued(_v: u32, _t: u32, _a: u32, _d: u32, ) -> Weight { + fn elect_queued(_v: u32, _t: u32, _a: u32, _d: u32) -> Weight { (5_511_380_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } - fn submit_unsigned(v: u32, t: u32, a: u32, d: u32, ) -> Weight { + fn submit_unsigned(v: u32, t: u32, a: u32, d: u32) -> Weight { (0 as Weight) // Standard Error: 12_000 .saturating_add((3_399_000 as Weight).saturating_mul(v as Weight)) @@ -80,7 +78,7 @@ impl pallet_election_provider_multi_phase::WeightInfo f .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn feasibility_check(v: u32, t: u32, a: u32, d: u32, ) -> Weight { + fn feasibility_check(v: u32, t: u32, a: u32, d: u32) -> Weight { (0 as Weight) // Standard Error: 7_000 .saturating_add((3_426_000 as Weight).saturating_mul(v as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs index dac367578ab..6ed8d329ed6 100644 --- a/polkadot/runtime/westend/src/weights/pallet_identity.rs +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,14 +42,14 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_identity`. pub struct WeightInfo(PhantomData); impl pallet_identity::WeightInfo for WeightInfo { - fn add_registrar(r: u32, ) -> Weight { + fn add_registrar(r: u32) -> Weight { (20_852_000 as Weight) // Standard Error: 2_000 .saturating_add((249_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_identity(r: u32, x: u32, ) -> Weight { + fn set_identity(r: u32, x: u32) -> Weight { (50_867_000 as Weight) // Standard Error: 14_000 .saturating_add((216_000 as Weight).saturating_mul(r as Weight)) @@ -59,7 +58,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_subs_new(s: u32, ) -> Weight { + fn set_subs_new(s: u32) -> Weight { (39_701_000 as Weight) // Standard Error: 1_000 .saturating_add((6_376_000 as Weight).saturating_mul(s as Weight)) @@ -68,7 +67,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn set_subs_old(p: u32, ) -> Weight { + fn set_subs_old(p: u32) -> Weight { (40_181_000 as Weight) // Standard Error: 0 .saturating_add((2_045_000 as Weight).saturating_mul(p as Weight)) @@ -76,7 +75,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) } - fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight { + fn clear_identity(r: u32, s: u32, x: u32) -> Weight { (48_884_000 as Weight) // Standard Error: 6_000 .saturating_add((140_000 as Weight).saturating_mul(r as Weight)) @@ -88,7 +87,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn request_judgement(r: u32, x: u32, ) -> Weight { + fn request_judgement(r: u32, x: u32) -> Weight { (52_661_000 as Weight) // Standard Error: 5_000 .saturating_add((250_000 as Weight).saturating_mul(r as Weight)) @@ -97,7 +96,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel_request(r: u32, x: u32, ) -> Weight { + fn cancel_request(r: u32, x: u32) -> Weight { (48_072_000 as Weight) // Standard Error: 7_000 .saturating_add((173_000 as Weight).saturating_mul(r as Weight)) @@ -106,28 +105,28 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_fee(r: u32, ) -> Weight { + fn set_fee(r: u32) -> Weight { (7_817_000 as Weight) // Standard Error: 1_000 .saturating_add((220_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_account_id(r: u32, ) -> Weight { + fn set_account_id(r: u32) -> Weight { (8_397_000 as Weight) // Standard Error: 1_000 .saturating_add((223_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_fields(r: u32, ) -> Weight { + fn set_fields(r: u32) -> Weight { (7_854_000 as Weight) // Standard Error: 1_000 .saturating_add((216_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn provide_judgement(r: u32, x: u32, ) -> Weight { + fn provide_judgement(r: u32, x: u32) -> Weight { (33_563_000 as Weight) // Standard Error: 5_000 .saturating_add((232_000 as Weight).saturating_mul(r as Weight)) @@ -136,7 +135,7 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn kill_identity(r: u32, s: u32, _x: u32, ) -> Weight { + fn kill_identity(r: u32, s: u32, _x: u32) -> Weight { (49_152_000 as Weight) // Standard Error: 3_000 .saturating_add((72_000 as Weight).saturating_mul(r as Weight)) @@ -146,28 +145,28 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn add_sub(s: u32, ) -> Weight { + fn add_sub(s: u32) -> Weight { (53_373_000 as Weight) // Standard Error: 0 .saturating_add((162_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn rename_sub(s: u32, ) -> Weight { + fn rename_sub(s: u32) -> Weight { (16_191_000 as Weight) // Standard Error: 0 .saturating_add((19_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_sub(s: u32, ) -> Weight { + fn remove_sub(s: u32) -> Weight { (54_328_000 as Weight) // Standard Error: 0 .saturating_add((143_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn quit_sub(s: u32, ) -> Weight { + fn quit_sub(s: u32) -> Weight { (32_901_000 as Weight) // Standard Error: 0 .saturating_add((145_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_im_online.rs b/polkadot/runtime/westend/src/weights/pallet_im_online.rs index 72ebf13d83d..8026b8673dc 100644 --- a/polkadot/runtime/westend/src/weights/pallet_im_online.rs +++ b/polkadot/runtime/westend/src/weights/pallet_im_online.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_im_online`. pub struct WeightInfo(PhantomData); impl pallet_im_online::WeightInfo for WeightInfo { - fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight { + fn validate_unsigned_and_then_heartbeat(k: u32, e: u32) -> Weight { (88_980_000 as Weight) // Standard Error: 0 .saturating_add((167_000 as Weight).saturating_mul(k as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_indices.rs b/polkadot/runtime/westend/src/weights/pallet_indices.rs index ae663707e70..aefc7f897aa 100644 --- a/polkadot/runtime/westend/src/weights/pallet_indices.rs +++ b/polkadot/runtime/westend/src/weights/pallet_indices.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/westend/src/weights/pallet_multisig.rs b/polkadot/runtime/westend/src/weights/pallet_multisig.rs index 7ffaafee207..5233df27976 100644 --- a/polkadot/runtime/westend/src/weights/pallet_multisig.rs +++ b/polkadot/runtime/westend/src/weights/pallet_multisig.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,10 +42,10 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_multisig`. pub struct WeightInfo(PhantomData); impl pallet_multisig::WeightInfo for WeightInfo { - fn as_multi_threshold_1(_z: u32, ) -> Weight { + fn as_multi_threshold_1(_z: u32) -> Weight { (12_189_000 as Weight) } - fn as_multi_create(s: u32, z: u32, ) -> Weight { + fn as_multi_create(s: u32, z: u32) -> Weight { (50_768_000 as Weight) // Standard Error: 0 .saturating_add((106_000 as Weight).saturating_mul(s as Weight)) @@ -55,7 +54,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn as_multi_create_store(s: u32, z: u32, ) -> Weight { + fn as_multi_create_store(s: u32, z: u32) -> Weight { (56_293_000 as Weight) // Standard Error: 0 .saturating_add((110_000 as Weight).saturating_mul(s as Weight)) @@ -64,7 +63,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn as_multi_approve(s: u32, z: u32, ) -> Weight { + fn as_multi_approve(s: u32, z: u32) -> Weight { (29_281_000 as Weight) // Standard Error: 0 .saturating_add((105_000 as Weight).saturating_mul(s as Weight)) @@ -73,7 +72,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn as_multi_approve_store(s: u32, z: u32, ) -> Weight { + fn as_multi_approve_store(s: u32, z: u32) -> Weight { (53_770_000 as Weight) // Standard Error: 0 .saturating_add((122_000 as Weight).saturating_mul(s as Weight)) @@ -82,7 +81,7 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn as_multi_complete(s: u32, z: u32, ) -> Weight { + fn as_multi_complete(s: u32, z: u32) -> Weight { (70_625_000 as Weight) // Standard Error: 0 .saturating_add((212_000 as Weight).saturating_mul(s as Weight)) @@ -91,28 +90,28 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn approve_as_multi_create(s: u32, ) -> Weight { + fn approve_as_multi_create(s: u32) -> Weight { (49_662_000 as Weight) // Standard Error: 0 .saturating_add((107_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn approve_as_multi_approve(s: u32, ) -> Weight { + fn approve_as_multi_approve(s: u32) -> Weight { (28_469_000 as Weight) // Standard Error: 0 .saturating_add((107_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn approve_as_multi_complete(s: u32, ) -> Weight { + fn approve_as_multi_complete(s: u32) -> Weight { (121_389_000 as Weight) // Standard Error: 0 .saturating_add((212_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn cancel_as_multi(s: u32, ) -> Weight { + fn cancel_as_multi(s: u32) -> Weight { (86_993_000 as Weight) // Standard Error: 0 .saturating_add((102_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_proxy.rs b/polkadot/runtime/westend/src/weights/pallet_proxy.rs index 6b47b4ee19c..c863341d35c 100644 --- a/polkadot/runtime/westend/src/weights/pallet_proxy.rs +++ b/polkadot/runtime/westend/src/weights/pallet_proxy.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,13 +42,13 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_proxy`. pub struct WeightInfo(PhantomData); impl pallet_proxy::WeightInfo for WeightInfo { - fn proxy(p: u32, ) -> Weight { + fn proxy(p: u32) -> Weight { (24_786_000 as Weight) // Standard Error: 1_000 .saturating_add((133_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } - fn proxy_announced(a: u32, p: u32, ) -> Weight { + fn proxy_announced(a: u32, p: u32) -> Weight { (55_730_000 as Weight) // Standard Error: 1_000 .saturating_add((558_000 as Weight).saturating_mul(a as Weight)) @@ -58,21 +57,21 @@ impl pallet_proxy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn remove_announcement(a: u32, _p: u32, ) -> Weight { + fn remove_announcement(a: u32, _p: u32) -> Weight { (37_947_000 as Weight) // Standard Error: 1_000 .saturating_add((560_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn reject_announcement(a: u32, _p: u32, ) -> Weight { + fn reject_announcement(a: u32, _p: u32) -> Weight { (37_904_000 as Weight) // Standard Error: 1_000 .saturating_add((562_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn announce(a: u32, p: u32, ) -> Weight { + fn announce(a: u32, p: u32) -> Weight { (51_562_000 as Weight) // Standard Error: 2_000 .saturating_add((550_000 as Weight).saturating_mul(a as Weight)) @@ -81,35 +80,35 @@ impl pallet_proxy::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn add_proxy(p: u32, ) -> Weight { + fn add_proxy(p: u32) -> Weight { (36_284_000 as Weight) // Standard Error: 1_000 .saturating_add((223_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_proxy(p: u32, ) -> Weight { + fn remove_proxy(p: u32) -> Weight { (35_792_000 as Weight) // Standard Error: 2_000 .saturating_add((249_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn remove_proxies(p: u32, ) -> Weight { + fn remove_proxies(p: u32) -> Weight { (34_091_000 as Weight) // Standard Error: 1_000 .saturating_add((136_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn anonymous(p: u32, ) -> Weight { + fn anonymous(p: u32) -> Weight { (48_824_000 as Weight) // Standard Error: 1_000 .saturating_add((31_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn kill_anonymous(p: u32, ) -> Weight { + fn kill_anonymous(p: u32) -> Weight { (35_989_000 as Weight) // Standard Error: 0 .saturating_add((134_000 as Weight).saturating_mul(p as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_scheduler.rs b/polkadot/runtime/westend/src/weights/pallet_scheduler.rs index 6443c081771..779bb007400 100644 --- a/polkadot/runtime/westend/src/weights/pallet_scheduler.rs +++ b/polkadot/runtime/westend/src/weights/pallet_scheduler.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,28 +42,28 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_scheduler`. pub struct WeightInfo(PhantomData); impl pallet_scheduler::WeightInfo for WeightInfo { - fn schedule(s: u32, ) -> Weight { + fn schedule(s: u32) -> Weight { (28_493_000 as Weight) // Standard Error: 0 .saturating_add((39_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn cancel(s: u32, ) -> Weight { + fn cancel(s: u32) -> Weight { (27_793_000 as Weight) // Standard Error: 14_000 .saturating_add((6_333_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn schedule_named(s: u32, ) -> Weight { + fn schedule_named(s: u32) -> Weight { (34_482_000 as Weight) // Standard Error: 1_000 .saturating_add((56_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn cancel_named(s: u32, ) -> Weight { + fn cancel_named(s: u32) -> Weight { (29_087_000 as Weight) // Standard Error: 14_000 .saturating_add((6_341_000 as Weight).saturating_mul(s as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_session.rs b/polkadot/runtime/westend/src/weights/pallet_session.rs index e506eebf803..ed8c5c429d8 100644 --- a/polkadot/runtime/westend/src/weights/pallet_session.rs +++ b/polkadot/runtime/westend/src/weights/pallet_session.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/westend/src/weights/pallet_staking.rs b/polkadot/runtime/westend/src/weights/pallet_staking.rs index 8b57d67a0ef..45b2f6646c3 100644 --- a/polkadot/runtime/westend/src/weights/pallet_staking.rs +++ b/polkadot/runtime/westend/src/weights/pallet_staking.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -58,14 +57,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn withdraw_unbonded_update(s: u32, ) -> Weight { + fn withdraw_unbonded_update(s: u32) -> Weight { (50_384_000 as Weight) // Standard Error: 0 .saturating_add((26_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn withdraw_unbonded_kill(s: u32, ) -> Weight { + fn withdraw_unbonded_kill(s: u32) -> Weight { (82_905_000 as Weight) // Standard Error: 1_000 .saturating_add((2_287_000 as Weight).saturating_mul(s as Weight)) @@ -78,7 +77,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn kick(k: u32, ) -> Weight { + fn kick(k: u32) -> Weight { (11_371_000 as Weight) // Standard Error: 7_000 .saturating_add((16_959_000 as Weight).saturating_mul(k as Weight)) @@ -86,7 +85,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(k as Weight))) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } - fn nominate(n: u32, ) -> Weight { + fn nominate(n: u32) -> Weight { (40_353_000 as Weight) // Standard Error: 12_000 .saturating_add((5_341_000 as Weight).saturating_mul(n as Weight)) @@ -95,8 +94,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn chill() -> Weight { - (17_740_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) + (17_740_000 as Weight).saturating_add(T::DbWeight::get().reads(3 as Weight)) } fn set_payee() -> Weight { (11_624_000 as Weight) @@ -109,28 +107,24 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn set_validator_count() -> Weight { - (2_082_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_082_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_no_eras() -> Weight { - (2_311_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_311_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_new_era() -> Weight { - (2_282_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_282_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn force_new_era_always() -> Weight { - (2_230_000 as Weight) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + (2_230_000 as Weight).saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn set_invulnerables(v: u32, ) -> Weight { + fn set_invulnerables(v: u32) -> Weight { (2_352_000 as Weight) // Standard Error: 0 .saturating_add((27_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn force_unstake(s: u32, ) -> Weight { + fn force_unstake(s: u32) -> Weight { (58_375_000 as Weight) // Standard Error: 1_000 .saturating_add((2_282_000 as Weight).saturating_mul(s as Weight)) @@ -138,14 +132,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(6 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn cancel_deferred_slash(s: u32, ) -> Weight { + fn cancel_deferred_slash(s: u32) -> Weight { (3_430_757_000 as Weight) // Standard Error: 222_000 .saturating_add((19_760_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn payout_stakers_dead_controller(n: u32, ) -> Weight { + fn payout_stakers_dead_controller(n: u32) -> Weight { (103_686_000 as Weight) // Standard Error: 17_000 .saturating_add((47_044_000 as Weight).saturating_mul(n as Weight)) @@ -154,7 +148,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(n as Weight))) } - fn payout_stakers_alive_staked(n: u32, ) -> Weight { + fn payout_stakers_alive_staked(n: u32) -> Weight { (128_168_000 as Weight) // Standard Error: 21_000 .saturating_add((59_293_000 as Weight).saturating_mul(n as Weight)) @@ -163,14 +157,14 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(n as Weight))) } - fn rebond(l: u32, ) -> Weight { + fn rebond(l: u32) -> Weight { (46_916_000 as Weight) // Standard Error: 1_000 .saturating_add((64_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn set_history_depth(e: u32, ) -> Weight { + fn set_history_depth(e: u32) -> Weight { (0 as Weight) // Standard Error: 63_000 .saturating_add((33_032_000 as Weight).saturating_mul(e as Weight)) @@ -178,7 +172,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((7 as Weight).saturating_mul(e as Weight))) } - fn reap_stash(s: u32, ) -> Weight { + fn reap_stash(s: u32) -> Weight { (69_690_000 as Weight) // Standard Error: 1_000 .saturating_add((2_271_000 as Weight).saturating_mul(s as Weight)) @@ -186,7 +180,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(8 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } - fn new_era(v: u32, n: u32, ) -> Weight { + fn new_era(v: u32, n: u32) -> Weight { (0 as Weight) // Standard Error: 787_000 .saturating_add((310_720_000 as Weight).saturating_mul(v as Weight)) @@ -198,7 +192,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(v as Weight))) } - fn get_npos_voters(v: u32, n: u32, s: u32, ) -> Weight { + fn get_npos_voters(v: u32, n: u32, s: u32) -> Weight { (0 as Weight) // Standard Error: 110_000 .saturating_add((25_641_000 as Weight).saturating_mul(v as Weight)) @@ -211,7 +205,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(s as Weight))) } - fn get_npos_targets(v: u32, ) -> Weight { + fn get_npos_targets(v: u32) -> Weight { (0 as Weight) // Standard Error: 36_000 .saturating_add((10_960_000 as Weight).saturating_mul(v as Weight)) @@ -219,8 +213,7 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(v as Weight))) } fn set_staking_limits() -> Weight { - (5_696_000 as Weight) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) + (5_696_000 as Weight).saturating_add(T::DbWeight::get().writes(5 as Weight)) } fn chill_other() -> Weight { (41_216_000 as Weight) diff --git a/polkadot/runtime/westend/src/weights/pallet_timestamp.rs b/polkadot/runtime/westend/src/weights/pallet_timestamp.rs index ca8250e8d80..f658a4424a7 100644 --- a/polkadot/runtime/westend/src/weights/pallet_timestamp.rs +++ b/polkadot/runtime/westend/src/weights/pallet_timestamp.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/westend/src/weights/pallet_utility.rs b/polkadot/runtime/westend/src/weights/pallet_utility.rs index 760a18f709a..f0d8871e2de 100644 --- a/polkadot/runtime/westend/src/weights/pallet_utility.rs +++ b/polkadot/runtime/westend/src/weights/pallet_utility.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,7 +42,7 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_utility`. pub struct WeightInfo(PhantomData); impl pallet_utility::WeightInfo for WeightInfo { - fn batch(c: u32, ) -> Weight { + fn batch(c: u32) -> Weight { (15_136_000 as Weight) // Standard Error: 0 .saturating_add((2_640_000 as Weight).saturating_mul(c as Weight)) @@ -51,7 +50,7 @@ impl pallet_utility::WeightInfo for WeightInfo { fn as_derivative() -> Weight { (5_428_000 as Weight) } - fn batch_all(c: u32, ) -> Weight { + fn batch_all(c: u32) -> Weight { (16_887_000 as Weight) // Standard Error: 0 .saturating_add((3_091_000 as Weight).saturating_mul(c as Weight)) diff --git a/polkadot/runtime/westend/src/weights/pallet_vesting.rs b/polkadot/runtime/westend/src/weights/pallet_vesting.rs index 9bcaea7be25..a269923abc6 100644 --- a/polkadot/runtime/westend/src/weights/pallet_vesting.rs +++ b/polkadot/runtime/westend/src/weights/pallet_vesting.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -43,42 +42,42 @@ use sp_std::marker::PhantomData; /// Weight functions for `pallet_vesting`. pub struct WeightInfo(PhantomData); impl pallet_vesting::WeightInfo for WeightInfo { - fn vest_locked(l: u32, ) -> Weight { + fn vest_locked(l: u32) -> Weight { (42_241_000 as Weight) // Standard Error: 13_000 .saturating_add((220_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn vest_unlocked(l: u32, ) -> Weight { + fn vest_unlocked(l: u32) -> Weight { (45_263_000 as Weight) // Standard Error: 10_000 .saturating_add((188_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vest_other_locked(l: u32, ) -> Weight { + fn vest_other_locked(l: u32) -> Weight { (41_538_000 as Weight) // Standard Error: 17_000 .saturating_add((239_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn vest_other_unlocked(l: u32, ) -> Weight { + fn vest_other_unlocked(l: u32) -> Weight { (44_715_000 as Weight) // Standard Error: 13_000 .saturating_add((207_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn vested_transfer(l: u32, ) -> Weight { + fn vested_transfer(l: u32) -> Weight { (100_413_000 as Weight) // Standard Error: 13_000 .saturating_add((103_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn force_vested_transfer(l: u32, ) -> Weight { + fn force_vested_transfer(l: u32) -> Weight { (99_525_000 as Weight) // Standard Error: 13_000 .saturating_add((108_000 as Weight).saturating_mul(l as Weight)) diff --git a/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs b/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs index 7dcf6e25859..53fb3178a6f 100644 --- a/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs +++ b/polkadot/runtime/westend/src/weights/runtime_common_auctions.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs index 217bfbb9e5b..25cb52a1865 100644 --- a/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs +++ b/polkadot/runtime/westend/src/weights/runtime_common_crowdloan.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -58,7 +57,7 @@ impl runtime_common::crowdloan::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn refund(k: u32, ) -> Weight { + fn refund(k: u32) -> Weight { (0 as Weight) // Standard Error: 28_000 .saturating_add((44_792_000 as Weight).saturating_mul(k as Weight)) @@ -87,7 +86,7 @@ impl runtime_common::crowdloan::WeightInfo for WeightIn .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - fn on_initialize(n: u32, ) -> Weight { + fn on_initialize(n: u32) -> Weight { (0 as Weight) // Standard Error: 20_000 .saturating_add((108_965_000 as Weight).saturating_mul(n as Weight)) diff --git a/polkadot/runtime/westend/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/westend/src/weights/runtime_common_paras_registrar.rs index 242fe9bf99d..a63f8feff11 100644 --- a/polkadot/runtime/westend/src/weights/runtime_common_paras_registrar.rs +++ b/polkadot/runtime/westend/src/weights/runtime_common_paras_registrar.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] diff --git a/polkadot/runtime/westend/src/weights/runtime_common_slots.rs b/polkadot/runtime/westend/src/weights/runtime_common_slots.rs index b4982ed5605..5d3c57066aa 100644 --- a/polkadot/runtime/westend/src/weights/runtime_common_slots.rs +++ b/polkadot/runtime/westend/src/weights/runtime_common_slots.rs @@ -33,7 +33,6 @@ // --header=./file_header.txt // --output=./runtime/westend/src/weights/ - #![allow(unused_parens)] #![allow(unused_imports)] @@ -48,7 +47,7 @@ impl runtime_common::slots::WeightInfo for WeightInfo Weight { + fn manage_lease_period_start(c: u32, t: u32) -> Weight { (0 as Weight) // Standard Error: 16_000 .saturating_add((16_002_000 as Weight).saturating_mul(c as Weight)) diff --git a/polkadot/rustfmt.toml b/polkadot/rustfmt.toml index 15e9bdcdf10..9b872649d84 100644 --- a/polkadot/rustfmt.toml +++ b/polkadot/rustfmt.toml @@ -18,3 +18,6 @@ match_block_trailing_comma = true trailing_comma = "Vertical" trailing_semicolon = false use_field_init_shorthand = true +ignore = [ + "bridges", +] diff --git a/polkadot/statement-table/src/generic.rs b/polkadot/statement-table/src/generic.rs index 7f93c26a7bc..9120010986a 100644 --- a/polkadot/statement-table/src/generic.rs +++ b/polkadot/statement-table/src/generic.rs @@ -24,13 +24,15 @@ //! indicating whether the candidate is valid or invalid. Once a threshold of the committee //! has signed validity statements, the candidate may be marked includable. -use std::collections::hash_map::{self, Entry, HashMap}; -use std::hash::Hash; -use std::fmt::Debug; +use std::{ + collections::hash_map::{self, Entry, HashMap}, + fmt::Debug, + hash::Hash, +}; -use primitives::v1::{ValidityAttestation as PrimitiveValidityAttestation, ValidatorSignature}; +use primitives::v1::{ValidatorSignature, ValidityAttestation as PrimitiveValidityAttestation}; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; /// Context for the statement table. pub trait Context { @@ -96,20 +98,18 @@ pub enum ValidityDoubleVote { impl ValidityDoubleVote { /// Deconstruct this misbehavior into two `(Statement, Signature)` pairs, erasing the information /// about precisely what the problem was. - pub fn deconstruct(self) -> ( - (Statement, Signature), - (Statement, Signature), - ) + pub fn deconstruct( + self, + ) -> ((Statement, Signature), (Statement, Signature)) where - Ctx: Context, + Ctx: Context, Candidate: Debug + Ord + Eq + Clone, Digest: Debug + Hash + Eq + Clone, Signature: Debug + Eq + Clone, { match self { - Self::IssuedAndValidity((c, s1), (d, s2)) => { - ((Statement::Seconded(c), s1), (Statement::Valid(d), s2)) - } + Self::IssuedAndValidity((c, s1), (d, s2)) => + ((Statement::Seconded(c), s1), (Statement::Valid(d), s2)), } } } @@ -233,20 +233,20 @@ pub struct CandidateData { impl CandidateData { /// Yield a full attestation for a candidate. /// If the candidate can be included, it will return `Some`. - pub fn attested(&self, validity_threshold: usize) - -> Option> - { + pub fn attested( + &self, + validity_threshold: usize, + ) -> Option> { let valid_votes = self.validity_votes.len(); if valid_votes < validity_threshold { - return None; + return None } - let validity_votes = self.validity_votes.iter() + let validity_votes = self + .validity_votes + .iter() .map(|(a, v)| match *v { - ValidityVote::Valid(ref s) => - (a.clone(), ValidityAttestation::Explicit(s.clone())), + ValidityVote::Valid(ref s) => (a.clone(), ValidityAttestation::Explicit(s.clone())), ValidityVote::Issued(ref s) => (a.clone(), ValidityAttestation::Implicit(s.clone())), }) @@ -275,16 +275,14 @@ struct AuthorityData { impl Default for AuthorityData { fn default() -> Self { - AuthorityData { - proposal: None, - } + AuthorityData { proposal: None } } } /// Type alias for the result of a statement import. pub type ImportResult = Result< Option::Digest, ::GroupId>>, - MisbehaviorFor + MisbehaviorFor, >; /// Stores votes @@ -308,11 +306,11 @@ impl Table { /// Get the attested candidate for `digest`. /// /// Returns `Some(_)` if the candidate exists and is includable. - pub fn attested_candidate(&self, digest: &Ctx::Digest, context: &Ctx) - -> Option> - { + pub fn attested_candidate( + &self, + digest: &Ctx::Digest, + context: &Ctx, + ) -> Option> { self.candidate_votes.get(digest).and_then(|data| { let v_threshold = context.requisite_votes(&data.group_id); data.attested(v_threshold) @@ -334,18 +332,10 @@ impl Table { let SignedStatement { statement, signature, sender: signer } = statement; let res = match statement { - Statement::Seconded(candidate) => self.import_candidate( - context, - signer.clone(), - candidate, - signature - ), - Statement::Valid(digest) => self.validity_vote( - context, - signer.clone(), - digest, - ValidityVote::Valid(signature), - ), + Statement::Seconded(candidate) => + self.import_candidate(context, signer.clone(), candidate, signature), + Statement::Valid(digest) => + self.validity_vote(context, signer.clone(), digest, ValidityVote::Valid(signature)), }; match res { @@ -355,7 +345,7 @@ impl Table { // punishments may be cumulative. self.detected_misbehavior.entry(signer).or_default().push(misbehavior); None - } + }, } } @@ -365,9 +355,7 @@ impl Table { } /// Access all witnessed misbehavior. - pub fn get_misbehavior(&self) - -> &HashMap>> - { + pub fn get_misbehavior(&self) -> &HashMap>> { &self.detected_misbehavior } @@ -375,9 +363,7 @@ impl Table { /// /// This consumes all detected misbehaviors, even if the iterator is not completely consumed. pub fn drain_misbehaviors(&mut self) -> DrainMisbehaviors<'_, Ctx> { - self.detected_misbehavior - .drain() - .into() + self.detected_misbehavior.drain().into() } fn import_candidate( @@ -395,7 +381,7 @@ impl Table { statement: Statement::Seconded(candidate), sender: authority, }, - })); + })) } // check that authority hasn't already specified another candidate. @@ -414,7 +400,9 @@ impl Table { votes entry is created. proposal here is `Some`, therefore \ candidate votes entry exists; qed"; - let old_candidate = self.candidate_votes.get(old_digest) + let old_candidate = self + .candidate_votes + .get(old_digest) .expect(EXISTENCE_PROOF) .candidate .clone(); @@ -422,7 +410,7 @@ impl Table { return Err(Misbehavior::MultipleCandidates(MultipleCandidates { first: (old_candidate, old_sig.clone()), second: (candidate, signature.clone()), - })); + })) } false @@ -430,31 +418,27 @@ impl Table { existing.proposal = Some((digest.clone(), signature.clone())); true } - } + }, Entry::Vacant(vacant) => { - vacant.insert(AuthorityData { - proposal: Some((digest.clone(), signature.clone())), - }); + vacant + .insert(AuthorityData { proposal: Some((digest.clone(), signature.clone())) }); true - } + }, }; // NOTE: altering this code may affect the existence proof above. ensure it remains // valid. if new_proposal { - self.candidate_votes.entry(digest.clone()).or_insert_with(move || CandidateData { - group_id: group, - candidate, - validity_votes: HashMap::new(), - }); + self.candidate_votes + .entry(digest.clone()) + .or_insert_with(move || CandidateData { + group_id: group, + candidate, + validity_votes: HashMap::new(), + }); } - self.validity_vote( - context, - authority, - digest, - ValidityVote::Issued(signature), - ) + self.validity_vote(context, authority, digest, ValidityVote::Issued(signature)) } fn validity_vote( @@ -473,9 +457,10 @@ impl Table { if !context.is_member_of(&from, &votes.group_id) { let sig = match vote { ValidityVote::Valid(s) => s, - ValidityVote::Issued(_) => - panic!("implicit issuance vote only cast from `import_candidate` after \ - checking group membership of issuer; qed"), + ValidityVote::Issued(_) => panic!( + "implicit issuance vote only cast from `import_candidate` after \ + checking group membership of issuer; qed" + ), }; return Err(Misbehavior::UnauthorizedStatement(UnauthorizedStatement { @@ -483,8 +468,8 @@ impl Table { signature: sig, sender: from, statement: Statement::Valid(digest), - } - })); + }, + })) } // check for double votes. @@ -497,7 +482,10 @@ impl Table { // valid vote conflicting with candidate statement (ValidityVote::Issued(iss), ValidityVote::Valid(good)) | (ValidityVote::Valid(good), ValidityVote::Issued(iss)) => - make_vdv(ValidityDoubleVote::IssuedAndValidity((votes.candidate.clone(), iss), (digest, good))), + make_vdv(ValidityDoubleVote::IssuedAndValidity( + (votes.candidate.clone(), iss), + (digest, good), + )), // two signatures on same candidate (ValidityVote::Issued(a), ValidityVote::Issued(b)) => @@ -510,10 +498,10 @@ impl Table { } else { Ok(None) } - } + }, Entry::Vacant(vacant) => { vacant.insert(vote); - } + }, } Ok(Some(votes.summary(digest))) @@ -527,7 +515,9 @@ struct MisbehaviorForAuthority { misbehaviors: Vec>, } -impl From<(Ctx::AuthorityId, Vec>)> for MisbehaviorForAuthority { +impl From<(Ctx::AuthorityId, Vec>)> + for MisbehaviorForAuthority +{ fn from((id, mut misbehaviors): (Ctx::AuthorityId, Vec>)) -> Self { // we're going to be popping items off this list in the iterator, so reverse it now to // preserve the original ordering. @@ -551,10 +541,7 @@ pub struct DrainMisbehaviors<'a, Ctx: Context> { impl<'a, Ctx: Context> From> for DrainMisbehaviors<'a, Ctx> { fn from(drain: Drain<'a, Ctx>) -> Self { - Self { - drain, - in_progress: None, - } + Self { drain, in_progress: None } } } @@ -607,7 +594,7 @@ mod tests { #[derive(Debug, PartialEq, Eq)] struct TestContext { // v -> parachain group - authorities: HashMap + authorities: HashMap, } impl Context for TestContext { @@ -625,11 +612,7 @@ mod tests { GroupId(candidate.0) } - fn is_member_of( - &self, - authority: &AuthorityId, - group: &GroupId - ) -> bool { + fn is_member_of(&self, authority: &AuthorityId, group: &GroupId) -> bool { self.authorities.get(authority).map(|v| v == group).unwrap_or(false) } @@ -637,7 +620,9 @@ mod tests { let mut total_validity = 0; for validity in self.authorities.values() { - if validity == id { total_validity += 1 } + if validity == id { + total_validity += 1 + } } total_validity / 2 + 1 @@ -651,7 +636,7 @@ mod tests { let mut map = HashMap::new(); map.insert(AuthorityId(1), GroupId(2)); map - } + }, }; let mut table = create(); @@ -687,7 +672,7 @@ mod tests { let mut map = HashMap::new(); map.insert(AuthorityId(1), GroupId(3)); map - } + }, }; let mut table = create(); @@ -719,7 +704,7 @@ mod tests { map.insert(AuthorityId(1), GroupId(2)); map.insert(AuthorityId(2), GroupId(3)); map - } + }, }; let mut table = create(); @@ -763,7 +748,7 @@ mod tests { map.insert(AuthorityId(1), GroupId(2)); map.insert(AuthorityId(2), GroupId(2)); map - } + }, }; let mut table = create(); @@ -793,7 +778,7 @@ mod tests { let mut map = HashMap::new(); map.insert(AuthorityId(1), GroupId(2)); map - } + }, }; let mut table = create(); @@ -836,7 +821,9 @@ mod tests { assert!(candidate.attested(validity_threshold).is_none()); for i in 0..validity_threshold { - candidate.validity_votes.insert(AuthorityId(i + 100), ValidityVote::Valid(Signature(i + 100))); + candidate + .validity_votes + .insert(AuthorityId(i + 100), ValidityVote::Valid(Signature(i + 100))); } assert!(candidate.attested(validity_threshold).is_some()); @@ -858,7 +845,7 @@ mod tests { map.insert(AuthorityId(2), GroupId(2)); map.insert(AuthorityId(3), GroupId(2)); map - } + }, }; // have 2/3 validity guarantors note validity. @@ -893,7 +880,7 @@ mod tests { let mut map = HashMap::new(); map.insert(AuthorityId(1), GroupId(2)); map - } + }, }; let mut table = create(); @@ -903,7 +890,8 @@ mod tests { sender: AuthorityId(1), }; - let summary = table.import_statement(&context, statement) + let summary = table + .import_statement(&context, statement) .expect("candidate import to give summary"); assert_eq!(summary.candidate, Digest(100)); @@ -919,7 +907,7 @@ mod tests { map.insert(AuthorityId(1), GroupId(2)); map.insert(AuthorityId(2), GroupId(2)); map - } + }, }; let mut table = create(); @@ -939,8 +927,8 @@ mod tests { sender: AuthorityId(2), }; - let summary = table.import_statement(&context, vote) - .expect("candidate vote to give summary"); + let summary = + table.import_statement(&context, vote).expect("candidate vote to give summary"); assert!(!table.detected_misbehavior.contains_key(&AuthorityId(2))); diff --git a/polkadot/statement-table/src/lib.rs b/polkadot/statement-table/src/lib.rs index 327afb497b8..37aac24d4e7 100644 --- a/polkadot/statement-table/src/lib.rs +++ b/polkadot/statement-table/src/lib.rs @@ -16,14 +16,14 @@ pub mod generic; -pub use generic::{Table, Context}; +pub use generic::{Context, Table}; /// Concrete instantiations suitable for v1 primitives. pub mod v1 { use crate::generic; use primitives::v1::{ - CandidateHash, Id, CommittedCandidateReceipt, CompactStatement as PrimitiveStatement, - ValidatorSignature, ValidatorIndex, + CandidateHash, CommittedCandidateReceipt, CompactStatement as PrimitiveStatement, Id, + ValidatorIndex, ValidatorSignature, }; /// Statements about candidates on the network. diff --git a/polkadot/tests/common.rs b/polkadot/tests/common.rs index 96060bf85d9..37fcaea688a 100644 --- a/polkadot/tests/common.rs +++ b/polkadot/tests/common.rs @@ -14,7 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{process::{Child, ExitStatus}, thread, time::Duration}; +use std::{ + process::{Child, ExitStatus}, + thread, + time::Duration, +}; /// Wait for the given `child` the given ammount of `secs`. /// diff --git a/polkadot/tests/purge_chain_works.rs b/polkadot/tests/purge_chain_works.rs index dcb5693e09e..d410ff1207c 100644 --- a/polkadot/tests/purge_chain_works.rs +++ b/polkadot/tests/purge_chain_works.rs @@ -23,8 +23,10 @@ mod common; #[test] #[cfg(unix)] fn purge_chain_works() { - use nix::sys::signal::{kill, Signal::SIGINT}; - use nix::unistd::Pid; + use nix::{ + sys::signal::{kill, Signal::SIGINT}, + unistd::Pid, + }; let tmpdir = tempdir().expect("could not create temp dir"); diff --git a/polkadot/tests/running_the_node_and_interrupt.rs b/polkadot/tests/running_the_node_and_interrupt.rs index 2e1b9ab6ba4..76029b6d1e7 100644 --- a/polkadot/tests/running_the_node_and_interrupt.rs +++ b/polkadot/tests/running_the_node_and_interrupt.rs @@ -23,8 +23,13 @@ mod common; #[test] #[cfg(unix)] fn running_the_node_works_and_can_be_interrupted() { - use nix::sys::signal::{kill, Signal::{self, SIGINT, SIGTERM}}; - use nix::unistd::Pid; + use nix::{ + sys::signal::{ + kill, + Signal::{self, SIGINT, SIGTERM}, + }, + unistd::Pid, + }; fn run_command_and_kill(signal: Signal) { let tmpdir = tempdir().expect("coult not create temp dir"); diff --git a/polkadot/utils/staking-miner/src/dry_run.rs b/polkadot/utils/staking-miner/src/dry_run.rs index 853e8da588b..254bbd4178b 100644 --- a/polkadot/utils/staking-miner/src/dry_run.rs +++ b/polkadot/utils/staking-miner/src/dry_run.rs @@ -62,7 +62,7 @@ fn find_threshold(ext: &mut Ext, count: usize) { None => { println!("requested truncation to {} voters but had only {}", count, voters.len()); println!("smallest current voter: {:?}", voters.last()); - } + }, } }) } diff --git a/polkadot/utils/staking-miner/src/emergency_solution.rs b/polkadot/utils/staking-miner/src/emergency_solution.rs index b41c69e1e0e..9cadef60750 100644 --- a/polkadot/utils/staking-miner/src/emergency_solution.rs +++ b/polkadot/utils/staking-miner/src/emergency_solution.rs @@ -16,9 +16,9 @@ //! The emergency-solution command. -use crate::{prelude::*, SharedConfig, Error}; -use std::io::Write; +use crate::{prelude::*, Error, SharedConfig}; use codec::Encode; +use std::io::Write; macro_rules! emergency_solution_cmd_for { ($runtime:ident) => { paste::paste! { /// Execute the emergency-solution command. diff --git a/polkadot/utils/staking-miner/src/main.rs b/polkadot/utils/staking-miner/src/main.rs index fe52805e5f7..a1b04f770cc 100644 --- a/polkadot/utils/staking-miner/src/main.rs +++ b/polkadot/utils/staking-miner/src/main.rs @@ -317,8 +317,7 @@ async fn create_election_ext( } else { vec![::PalletInfo::name::>() .expect("Pallet always has name; qed.") - .to_string() - ] + .to_string()] }, ..Default::default() })) @@ -339,7 +338,10 @@ fn mine_unchecked( ext.execute_with(|| { let (solution, _) = >::mine_solution(iterations)?; if do_feasibility { - let _ = >::feasibility_check(solution.clone(), EPM::ElectionCompute::Signed)?; + let _ = >::feasibility_check( + solution.clone(), + EPM::ElectionCompute::Signed, + )?; } let witness = >::decode_len().unwrap_or_default(); Ok((solution, witness as u32)) @@ -357,7 +359,7 @@ fn mine_dpos(ext: &mut Ext) -> Result<(), Error> { voters.into_iter().for_each(|(who, stake, targets)| { if targets.len() == 0 { println!("target = {:?}", (who, stake, targets)); - return; + return } let share: u128 = (stake as u128) / (targets.len() as u128); for target in targets { @@ -386,7 +388,10 @@ fn mine_dpos(ext: &mut Ext) -> Result<(), Error> { #[tokio::main] async fn main() { - env_logger::Builder::from_default_env().format_module_path(true).format_level(true).init(); + env_logger::Builder::from_default_env() + .format_module_path(true) + .format_level(true) + .init(); let Opt { shared, command } = Opt::from_args(); log::debug!(target: LOG_TARGET, "attempting to connect to {:?}", shared.uri); @@ -405,7 +410,7 @@ async fn main() { why ); std::thread::sleep(std::time::Duration::from_millis(2500)); - } + }, } }; @@ -422,7 +427,7 @@ async fn main() { unsafe { RUNTIME = AnyRuntime::Polkadot; } - } + }, "kusama" | "kusama-dev" => { sp_core::crypto::set_default_ss58_version( sp_core::crypto::Ss58AddressFormat::KusamaAccount, @@ -432,7 +437,7 @@ async fn main() { unsafe { RUNTIME = AnyRuntime::Kusama; } - } + }, "westend" => { sp_core::crypto::set_default_ss58_version( sp_core::crypto::Ss58AddressFormat::PolkadotAccount, @@ -442,11 +447,11 @@ async fn main() { unsafe { RUNTIME = AnyRuntime::Westend; } - } + }, _ => { eprintln!("unexpected chain: {:?}", chain); - return; - } + return + }, } log::info!(target: LOG_TARGET, "connected to chain {:?}", chain); diff --git a/polkadot/utils/staking-miner/src/monitor.rs b/polkadot/utils/staking-miner/src/monitor.rs index 33a3ca0b8e5..64cbb126489 100644 --- a/polkadot/utils/staking-miner/src/monitor.rs +++ b/polkadot/utils/staking-miner/src/monitor.rs @@ -21,8 +21,8 @@ use crate::{ }; use codec::Encode; use jsonrpsee_ws_client::{ + types::{traits::SubscriptionClient, v2::params::JsonRpcParams, Subscription}, WsClient, - types::{Subscription, traits::SubscriptionClient, v2::params::JsonRpcParams}, }; use sc_transaction_pool_api::TransactionStatus; diff --git a/polkadot/utils/staking-miner/src/signer.rs b/polkadot/utils/staking-miner/src/signer.rs index 6d7ffe8753a..d5a0d391b54 100644 --- a/polkadot/utils/staking-miner/src/signer.rs +++ b/polkadot/utils/staking-miner/src/signer.rs @@ -66,8 +66,9 @@ pub(crate) async fn read_signer_uri< let pair = Pair::from_string(&uri, None)?; let account = T::AccountId::from(pair.public()); - let _info = - get_account_info::(&client, &account, None).await?.ok_or(Error::AccountDoesNotExists)?; + let _info = get_account_info::(&client, &account, None) + .await? + .ok_or(Error::AccountDoesNotExists)?; log::info!(target: LOG_TARGET, "loaded account {:?}, info: {:?}", &account, _info); Ok(Signer { account, pair, uri: uri.to_string() }) } diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index a99d630fefe..bcd175f4bd8 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -18,23 +18,23 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::{prelude::*, marker::PhantomData, convert::TryInto, boxed::Box, vec}; -use codec::{Encode, Decode}; +use codec::{Decode, Encode}; +use frame_support::traits::{Contains, EnsureOrigin, Filter, Get, OriginTrait}; +use sp_runtime::{traits::BadOrigin, RuntimeDebug}; +use sp_std::{boxed::Box, convert::TryInto, marker::PhantomData, prelude::*, vec}; use xcm::v0::prelude::*; use xcm_executor::traits::ConvertOrigin; -use sp_runtime::{RuntimeDebug, traits::BadOrigin}; -use frame_support::traits::{EnsureOrigin, OriginTrait, Filter, Get, Contains}; -pub use pallet::*; use frame_support::PalletId; +pub use pallet::*; #[frame_support::pallet] pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use xcm_executor::traits::WeightBounds; use sp_runtime::traits::AccountIdConversion; + use xcm_executor::traits::WeightBounds; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -48,7 +48,7 @@ pub mod pallet { /// Required origin for sending XCM messages. If successful, the it resolves to `MultiLocation` /// which exists as an interior location within this chain's XCM context. - type SendXcmOrigin: EnsureOrigin; + type SendXcmOrigin: EnsureOrigin; /// The type used to actually dispatch an XCM to its destination. type XcmRouter: SendXcm; @@ -56,7 +56,7 @@ pub mod pallet { /// Required origin for executing XCM messages, including the teleport functionality. If successful, /// then it resolves to `MultiLocation` which exists as an interior location within this chain's XCM /// context. - type ExecuteXcmOrigin: EnsureOrigin; + type ExecuteXcmOrigin: EnsureOrigin; /// Our XCM filter which messages to be executed using `XcmExecutor` must pass. type XcmExecuteFilter: Contains<(MultiLocation, Xcm)>; @@ -99,11 +99,12 @@ pub mod pallet { #[pallet::weight(100_000_000)] pub fn send(origin: OriginFor, dest: MultiLocation, message: Xcm<()>) -> DispatchResult { let origin_location = T::SendXcmOrigin::ensure_origin(origin)?; - Self::send_xcm(origin_location.clone(), dest.clone(), message.clone()) - .map_err(|e| match e { + Self::send_xcm(origin_location.clone(), dest.clone(), message.clone()).map_err( + |e| match e { XcmError::CannotReachDestination(..) => Error::::Unreachable, _ => Error::::SendFailure, - })?; + }, + )?; Self::deposit_event(Event::Sent(origin_location, dest, message)); Ok(()) } @@ -143,27 +144,26 @@ pub mod pallet { let (origin_location, assets) = value; let mut message = Xcm::WithdrawAsset { assets, - effects: vec![ - InitiateTeleport { - assets: vec![ All ], - dest, - effects: vec![ - BuyExecution { - fees: All, - // Zero weight for additional XCM (since there are none to execute) - weight: 0, - debt: dest_weight, - halt_on_error: false, - xcm: vec![], - }, - DepositAsset { assets: vec![ All ], dest: beneficiary }, - ], - }, - ], + effects: vec![InitiateTeleport { + assets: vec![All], + dest, + effects: vec![ + BuyExecution { + fees: All, + // Zero weight for additional XCM (since there are none to execute) + weight: 0, + debt: dest_weight, + halt_on_error: false, + xcm: vec![], + }, + DepositAsset { assets: vec![All], dest: beneficiary }, + ], + }], }; - let weight = T::Weigher::weight(&mut message) - .map_err(|()| Error::::UnweighableMessage)?; - let outcome = T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let outcome = + T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); Self::deposit_event(Event::Attempted(outcome)); Ok(()) } @@ -211,12 +211,13 @@ pub mod pallet { halt_on_error: false, xcm: vec![], }, - DepositAsset { assets: vec![ All ], dest: beneficiary }, + DepositAsset { assets: vec![All], dest: beneficiary }, ], }; - let weight = T::Weigher::weight(&mut message) - .map_err(|()| Error::::UnweighableMessage)?; - let outcome = T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let outcome = + T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); Self::deposit_event(Event::Attempted(outcome)); Ok(()) } @@ -233,9 +234,11 @@ pub mod pallet { /// NOTE: A successful return to this does *not* imply that the `msg` was executed successfully /// to completion; only that *some* of it was executed. #[pallet::weight(max_weight.saturating_add(100_000_000u64))] - pub fn execute(origin: OriginFor, message: Box>, max_weight: Weight) - -> DispatchResult - { + pub fn execute( + origin: OriginFor, + message: Box>, + max_weight: Weight, + ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let value = (origin_location, *message); ensure!(T::XcmExecuteFilter::contains(&value), Error::::Filtered); @@ -249,7 +252,11 @@ pub mod pallet { impl Pallet { /// Relay an XCM `message` from a given `interior` location in this context to a given `dest` /// location. A null `dest` is not handled. - pub fn send_xcm(interior: MultiLocation, dest: MultiLocation, message: Xcm<()>) -> Result<(), XcmError> { + pub fn send_xcm( + interior: MultiLocation, + dest: MultiLocation, + message: Xcm<()>, + ) -> Result<(), XcmError> { let message = match interior { MultiLocation::Null => message, who => Xcm::<()>::RelayedFrom { who, message: Box::new(message) }, @@ -282,7 +289,8 @@ pub mod pallet { /// Ensure that the origin `o` represents a sibling parachain. /// Returns `Ok` with the parachain ID of the sibling or an `Err` otherwise. pub fn ensure_xcm(o: OuterOrigin) -> Result - where OuterOrigin: Into> +where + OuterOrigin: Into>, { match o.into() { Ok(Origin::Xcm(location)) => Ok(location), @@ -295,7 +303,9 @@ pub fn ensure_xcm(o: OuterOrigin) -> Result(PhantomData<(Prefix, Body)>); -impl, Body: Get> Filter for IsMajorityOfBody { +impl, Body: Get> Filter + for IsMajorityOfBody +{ fn filter(l: &MultiLocation) -> bool { let maybe_suffix = l.match_and_split(&Prefix::get()); matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part.is_majority()) @@ -306,19 +316,21 @@ impl, Body: Get> Filter for Is /// `Origin::Xcm` item. pub struct EnsureXcm(PhantomData); impl, F: Filter> EnsureOrigin for EnsureXcm - where O::PalletsOrigin: From + TryInto +where + O::PalletsOrigin: From + TryInto, { type Success = MultiLocation; fn try_origin(outer: O) -> Result { - outer.try_with_caller(|caller| caller.try_into() - .and_then(|Origin::Xcm(location)| + outer.try_with_caller(|caller| { + caller.try_into().and_then(|Origin::Xcm(location)| { if F::filter(&location) { Ok(location) } else { Err(Origin::Xcm(location).into()) } - )) + }) + }) } #[cfg(feature = "runtime-benchmarks")] @@ -330,9 +342,7 @@ impl, F: Filter> EnsureOrigin fo /// A simple passthrough where we reuse the `MultiLocation`-typed XCM origin as the inner value of /// this crate's `Origin::Xcm` value. pub struct XcmPassthrough(PhantomData); -impl< - Origin: From, -> ConvertOrigin for XcmPassthrough { +impl> ConvertOrigin for XcmPassthrough { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Xcm, l) => Ok(crate::Origin::Xcm(l).into()), diff --git a/polkadot/xcm/src/double_encoded.rs b/polkadot/xcm/src/double_encoded.rs index 4bd5dc0eb59..70592580d3c 100644 --- a/polkadot/xcm/src/double_encoded.rs +++ b/polkadot/xcm/src/double_encoded.rs @@ -15,7 +15,7 @@ // along with Polkadot. If not, see . use alloc::vec::Vec; -use parity_scale_codec::{Encode, Decode, DecodeLimit}; +use parity_scale_codec::{Decode, DecodeLimit, Encode}; /// Maximum nesting level for XCM decoding. pub const MAX_XCM_DECODE_DEPTH: u32 = 8; @@ -32,16 +32,22 @@ pub struct DoubleEncoded { } impl Clone for DoubleEncoded { - fn clone(&self) -> Self { Self { encoded: self.encoded.clone(), decoded: None } } + fn clone(&self) -> Self { + Self { encoded: self.encoded.clone(), decoded: None } + } } impl PartialEq for DoubleEncoded { - fn eq(&self, other: &Self) -> bool { self.encoded.eq(&other.encoded) } + fn eq(&self, other: &Self) -> bool { + self.encoded.eq(&other.encoded) + } } impl Eq for DoubleEncoded {} impl core::fmt::Debug for DoubleEncoded { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.encoded.fmt(f) } + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.encoded.fmt(f) + } } impl From> for DoubleEncoded { @@ -51,13 +57,12 @@ impl From> for DoubleEncoded { } impl DoubleEncoded { - pub fn into(self) -> DoubleEncoded { DoubleEncoded::from(self) } + pub fn into(self) -> DoubleEncoded { + DoubleEncoded::from(self) + } pub fn from(e: DoubleEncoded) -> Self { - Self { - encoded: e.encoded, - decoded: None, - } + Self { encoded: e.encoded, decoded: None } } /// Provides an API similar to `AsRef` that provides access to the inner value. @@ -72,22 +77,20 @@ impl DoubleEncoded { /// Returns a reference to the value in case of success and `Err(())` in case the decoding fails. pub fn ensure_decoded(&mut self) -> Result<&T, ()> { if self.decoded.is_none() { - self.decoded = T::decode_all_with_depth_limit( - MAX_XCM_DECODE_DEPTH, - &mut &self.encoded[..], - ).ok(); + self.decoded = + T::decode_all_with_depth_limit(MAX_XCM_DECODE_DEPTH, &mut &self.encoded[..]).ok(); } self.decoded.as_ref().ok_or(()) } /// Move the decoded value out or (if not present) decode `encoded`. pub fn take_decoded(&mut self) -> Result { - self.decoded.take().or_else(|| { - T::decode_all_with_depth_limit( - MAX_XCM_DECODE_DEPTH, - &mut &self.encoded[..], - ).ok() - }).ok_or(()) + self.decoded + .take() + .or_else(|| { + T::decode_all_with_depth_limit(MAX_XCM_DECODE_DEPTH, &mut &self.encoded[..]).ok() + }) + .ok_or(()) } /// Provides an API similar to `TryInto` that allows fallible conversion to the inner value type. diff --git a/polkadot/xcm/src/lib.rs b/polkadot/xcm/src/lib.rs index 1addc44bd55..b51b1b98514 100644 --- a/polkadot/xcm/src/lib.rs +++ b/polkadot/xcm/src/lib.rs @@ -23,8 +23,8 @@ #![no_std] extern crate alloc; -use parity_scale_codec::{Encode, Decode}; use derivative::Derivative; +use parity_scale_codec::{Decode, Encode}; pub mod v0; @@ -33,7 +33,7 @@ pub use double_encoded::DoubleEncoded; /// A single XCM message, together with its version code. #[derive(Derivative, Encode, Decode)] -#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] #[codec(encode_bound())] #[codec(decode_bound())] pub enum VersionedXcm { @@ -45,7 +45,7 @@ pub mod opaque { // Everything from v0 pub use crate::v0::*; // Then override with the opaque types in v0 - pub use crate::v0::opaque::{Xcm, Order}; + pub use crate::v0::opaque::{Order, Xcm}; } /// The basic `VersionedXcm` type which just uses the `Vec` as an encoded call. diff --git a/polkadot/xcm/src/v0/junction.rs b/polkadot/xcm/src/v0/junction.rs index b89c665a390..cf474f62851 100644 --- a/polkadot/xcm/src/v0/junction.rs +++ b/polkadot/xcm/src/v0/junction.rs @@ -17,7 +17,7 @@ //! Support data structures for `MultiLocation`, primarily the `Junction` datatype. use alloc::vec::Vec; -use parity_scale_codec::{self, Encode, Decode}; +use parity_scale_codec::{self, Decode, Encode}; /// A global identifier of an account-bearing consensus system. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)] @@ -41,7 +41,10 @@ pub enum BodyId { Named(Vec), /// An indexed body. // TODO: parity-scale-codec#262: Change to be a tuple. - Index { #[codec(compact)] id: u32 }, + Index { + #[codec(compact)] + id: u32, + }, /// The unambiguous executive body (for Polkadot, this would be the Polkadot council). Executive, /// The unambiguous technical body (for Polkadot, this would be the Technical Committee). @@ -60,13 +63,31 @@ pub enum BodyPart { /// The body's declaration, under whatever means it decides. Voice, /// A given number of members of the body. - Members { #[codec(compact)] count: u32 }, + Members { + #[codec(compact)] + count: u32, + }, /// A given number of members of the body, out of some larger caucus. - Fraction { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 }, + Fraction { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, /// No less than the given proportion of members of the body. - AtLeastProportion { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 }, + AtLeastProportion { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, /// More than than the given proportion of members of the body. - MoreThanProportion { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 }, + MoreThanProportion { + #[codec(compact)] + nom: u32, + #[codec(compact)] + denom: u32, + }, } impl BodyPart { @@ -104,7 +125,11 @@ pub enum Junction { /// the context. /// /// May be used when the context is a Frame-based chain and includes e.g. an indices pallet. - AccountIndex64 { network: NetworkId, #[codec(compact)] index: u64 }, + AccountIndex64 { + network: NetworkId, + #[codec(compact)] + index: u64, + }, /// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within /// the context. /// @@ -119,7 +144,10 @@ pub enum Junction { /// Usage will vary widely owing to its generality. /// /// NOTE: Try to avoid using this and instead use a more specific item. - GeneralIndex { #[codec(compact)] id: u128 }, + GeneralIndex { + #[codec(compact)] + id: u128, + }, /// A nondescript datum acting as a key within the context location. /// /// Usage will vary widely owing to its generality. @@ -152,16 +180,15 @@ impl Junction { match self { Junction::Parent => false, - Junction::Parachain(..) - | Junction::AccountId32 { .. } - | Junction::AccountIndex64 { .. } - | Junction::AccountKey20 { .. } - | Junction::PalletInstance { .. } - | Junction::GeneralIndex { .. } - | Junction::GeneralKey(..) - | Junction::OnlyChild - | Junction::Plurality { .. } - => true, + Junction::Parachain(..) | + Junction::AccountId32 { .. } | + Junction::AccountIndex64 { .. } | + Junction::AccountKey20 { .. } | + Junction::PalletInstance { .. } | + Junction::GeneralIndex { .. } | + Junction::GeneralKey(..) | + Junction::OnlyChild | + Junction::Plurality { .. } => true, } } } diff --git a/polkadot/xcm/src/v0/mod.rs b/polkadot/xcm/src/v0/mod.rs index 05aad9581b0..d775f9acfb0 100644 --- a/polkadot/xcm/src/v0/mod.rs +++ b/polkadot/xcm/src/v0/mod.rs @@ -16,31 +16,37 @@ //! Version 0 of the Cross-Consensus Message format data structures. -use core::{result, convert::TryFrom, fmt::Debug}; -use derivative::Derivative; +use crate::{DoubleEncoded, VersionedMultiAsset, VersionedXcm}; use alloc::vec::Vec; -use parity_scale_codec::{self, Encode, Decode}; -use crate::{VersionedMultiAsset, DoubleEncoded, VersionedXcm}; +use core::{convert::TryFrom, fmt::Debug, result}; +use derivative::Derivative; +use parity_scale_codec::{self, Decode, Encode}; mod junction; mod multi_asset; mod multi_location; mod order; mod traits; -pub use junction::{Junction, NetworkId, BodyId, BodyPart}; -pub use multi_asset::{MultiAsset, AssetInstance}; +pub use junction::{BodyId, BodyPart, Junction, NetworkId}; +pub use multi_asset::{AssetInstance, MultiAsset}; pub use multi_location::MultiLocation; pub use order::Order; -pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome}; +pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm}; /// A prelude for importing all types typically used when interacting with XCM messages. pub mod prelude { - pub use super::junction::{Junction::*, NetworkId, BodyId, BodyPart}; - pub use super::multi_asset::{MultiAsset::{self, *}, AssetInstance::{self, *}}; - pub use super::multi_location::MultiLocation::{self, *}; - pub use super::order::Order::{self, *}; - pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome}; - pub use super::{Xcm::{self, *}, OriginKind}; + pub use super::{ + junction::{BodyId, BodyPart, Junction::*, NetworkId}, + multi_asset::{ + AssetInstance::{self, *}, + MultiAsset::{self, *}, + }, + multi_location::MultiLocation::{self, *}, + order::Order::{self, *}, + traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm}, + OriginKind, + Xcm::{self, *}, + }; } // TODO: #2841 #XCMENCODE Efficient encodings for Vec, Vec, using initial byte values 128+ to encode @@ -147,7 +153,11 @@ pub enum Xcm { /// /// Errors: #[codec(index = 3)] - QueryResponse { #[codec(compact)] query_id: u64, response: Response }, + QueryResponse { + #[codec(compact)] + query_id: u64, + response: Response, + }, /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the /// ownership of `dest` within this consensus system. @@ -209,9 +219,12 @@ pub enum Xcm { /// Kind: *System Notification* #[codec(index = 7)] HrmpNewChannelOpenRequest { - #[codec(compact)] sender: u32, - #[codec(compact)] max_message_size: u32, - #[codec(compact)] max_capacity: u32, + #[codec(compact)] + sender: u32, + #[codec(compact)] + max_message_size: u32, + #[codec(compact)] + max_capacity: u32, }, /// A message to notify about that a previously sent open channel request has been accepted by @@ -225,7 +238,8 @@ pub enum Xcm { /// Errors: #[codec(index = 8)] HrmpChannelAccepted { - #[codec(compact)] recipient: u32, + #[codec(compact)] + recipient: u32, }, /// A message to notify that the other party in an open channel decided to close it. In particular, @@ -240,9 +254,12 @@ pub enum Xcm { /// Errors: #[codec(index = 9)] HrmpChannelClosing { - #[codec(compact)] initiator: u32, - #[codec(compact)] sender: u32, - #[codec(compact)] recipient: u32, + #[codec(compact)] + initiator: u32, + #[codec(compact)] + sender: u32, + #[codec(compact)] + recipient: u32, }, /// A message to indicate that the embedded XCM is actually arriving on behalf of some consensus @@ -255,10 +272,7 @@ pub enum Xcm { /// /// Errors: #[codec(index = 10)] - RelayedFrom { - who: MultiLocation, - message: alloc::boxed::Box>, - }, + RelayedFrom { who: MultiLocation, message: alloc::boxed::Box> }, } impl From> for VersionedXcm { @@ -277,32 +291,33 @@ impl TryFrom> for Xcm { } impl Xcm { - pub fn into(self) -> Xcm { Xcm::from(self) } + pub fn into(self) -> Xcm { + Xcm::from(self) + } pub fn from(xcm: Xcm) -> Self { use Xcm::*; match xcm { - WithdrawAsset { assets, effects } - => WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, - ReserveAssetDeposit { assets, effects } - => ReserveAssetDeposit { assets, effects: effects.into_iter().map(Order::into).collect() }, - TeleportAsset { assets, effects } - => TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, - QueryResponse { query_id: u64, response } - => QueryResponse { query_id: u64, response }, - TransferAsset { assets, dest } - => TransferAsset { assets, dest }, - TransferReserveAsset { assets, dest, effects } - => TransferReserveAsset { assets, dest, effects }, - HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity} - => HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}, - HrmpChannelAccepted { recipient} - => HrmpChannelAccepted { recipient}, - HrmpChannelClosing { initiator, sender, recipient} - => HrmpChannelClosing { initiator, sender, recipient}, - Transact { origin_type, require_weight_at_most, call} - => Transact { origin_type, require_weight_at_most, call: call.into() }, - RelayedFrom { who, message } - => RelayedFrom { who, message: alloc::boxed::Box::new((*message).into()) }, + WithdrawAsset { assets, effects } => + WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, + ReserveAssetDeposit { assets, effects } => ReserveAssetDeposit { + assets, + effects: effects.into_iter().map(Order::into).collect(), + }, + TeleportAsset { assets, effects } => + TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() }, + QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response }, + TransferAsset { assets, dest } => TransferAsset { assets, dest }, + TransferReserveAsset { assets, dest, effects } => + TransferReserveAsset { assets, dest, effects }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_type, require_weight_at_most, call } => + Transact { origin_type, require_weight_at_most, call: call.into() }, + RelayedFrom { who, message } => + RelayedFrom { who, message: alloc::boxed::Box::new((*message).into()) }, } } } diff --git a/polkadot/xcm/src/v0/multi_asset.rs b/polkadot/xcm/src/v0/multi_asset.rs index dc682902df6..c29c4d87e44 100644 --- a/polkadot/xcm/src/v0/multi_asset.rs +++ b/polkadot/xcm/src/v0/multi_asset.rs @@ -16,11 +16,11 @@ //! Cross-Consensus Message format data structures. -use core::{result, convert::TryFrom}; use alloc::vec::Vec; +use core::{convert::TryFrom, result}; -use parity_scale_codec::{self, Encode, Decode}; use super::{MultiLocation, VersionedMultiAsset}; +use parity_scale_codec::{self, Decode, Encode}; /// A general identifier for an instance of a non-fungible asset class. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)] @@ -30,7 +30,10 @@ pub enum AssetInstance { /// A compact index. Technically this could be greater than `u128`, but this implementation supports only /// values up to `2**128 - 1`. - Index { #[codec(compact)] id: u128 }, + Index { + #[codec(compact)] + id: u128, + }, /// A 4-byte fixed-length datum. Array4([u8; 4]), @@ -133,13 +136,21 @@ pub enum MultiAsset { AllConcreteNonFungible { class: MultiLocation }, /// Some specific `amount` of the fungible asset identified by an abstract `id`. - AbstractFungible { id: Vec, #[codec(compact)] amount: u128 }, + AbstractFungible { + id: Vec, + #[codec(compact)] + amount: u128, + }, /// Some specific `instance` of the non-fungible asset whose `class` is identified abstractly. AbstractNonFungible { class: Vec, instance: AssetInstance }, /// Some specific `amount` of the fungible asset identified by an concrete `id`. - ConcreteFungible { id: MultiLocation, #[codec(compact)] amount: u128 }, + ConcreteFungible { + id: MultiLocation, + #[codec(compact)] + amount: u128, + }, /// Some specific `instance` of the non-fungible asset whose `class` is identified concretely. ConcreteNonFungible { class: MultiLocation, instance: AssetInstance }, @@ -151,30 +162,27 @@ impl MultiAsset { /// Typically can also be inferred by the name starting with `All`. pub fn is_wildcard(&self) -> bool { match self { - MultiAsset::None - | MultiAsset::AbstractFungible {..} - | MultiAsset::AbstractNonFungible {..} - | MultiAsset::ConcreteFungible {..} - | MultiAsset::ConcreteNonFungible {..} - => false, - - MultiAsset::All - | MultiAsset::AllFungible - | MultiAsset::AllNonFungible - | MultiAsset::AllAbstractFungible {..} - | MultiAsset::AllConcreteFungible {..} - | MultiAsset::AllAbstractNonFungible {..} - | MultiAsset::AllConcreteNonFungible {..} - => true, + MultiAsset::None | + MultiAsset::AbstractFungible { .. } | + MultiAsset::AbstractNonFungible { .. } | + MultiAsset::ConcreteFungible { .. } | + MultiAsset::ConcreteNonFungible { .. } => false, + + MultiAsset::All | + MultiAsset::AllFungible | + MultiAsset::AllNonFungible | + MultiAsset::AllAbstractFungible { .. } | + MultiAsset::AllConcreteFungible { .. } | + MultiAsset::AllAbstractNonFungible { .. } | + MultiAsset::AllConcreteNonFungible { .. } => true, } } fn is_none(&self) -> bool { match self { - MultiAsset::None - | MultiAsset::AbstractFungible { amount: 0, .. } - | MultiAsset::ConcreteFungible { amount: 0, .. } - => true, + MultiAsset::None | + MultiAsset::AbstractFungible { amount: 0, .. } | + MultiAsset::ConcreteFungible { amount: 0, .. } => true, _ => false, } @@ -182,13 +190,12 @@ impl MultiAsset { fn is_fungible(&self) -> bool { match self { - MultiAsset::All - | MultiAsset::AllFungible - | MultiAsset::AllAbstractFungible {..} - | MultiAsset::AllConcreteFungible {..} - | MultiAsset::AbstractFungible {..} - | MultiAsset::ConcreteFungible {..} - => true, + MultiAsset::All | + MultiAsset::AllFungible | + MultiAsset::AllAbstractFungible { .. } | + MultiAsset::AllConcreteFungible { .. } | + MultiAsset::AbstractFungible { .. } | + MultiAsset::ConcreteFungible { .. } => true, _ => false, } @@ -196,13 +203,12 @@ impl MultiAsset { fn is_non_fungible(&self) -> bool { match self { - MultiAsset::All - | MultiAsset::AllNonFungible - | MultiAsset::AllAbstractNonFungible {..} - | MultiAsset::AllConcreteNonFungible {..} - | MultiAsset::AbstractNonFungible {..} - | MultiAsset::ConcreteNonFungible {..} - => true, + MultiAsset::All | + MultiAsset::AllNonFungible | + MultiAsset::AllAbstractNonFungible { .. } | + MultiAsset::AllConcreteNonFungible { .. } | + MultiAsset::AbstractNonFungible { .. } | + MultiAsset::ConcreteNonFungible { .. } => true, _ => false, } @@ -211,9 +217,8 @@ impl MultiAsset { fn is_concrete_fungible(&self, id: &MultiLocation) -> bool { match self { MultiAsset::AllFungible => true, - MultiAsset::AllConcreteFungible { id: i } - | MultiAsset::ConcreteFungible { id: i, .. } - => i == id, + MultiAsset::AllConcreteFungible { id: i } | + MultiAsset::ConcreteFungible { id: i, .. } => i == id, _ => false, } @@ -222,9 +227,8 @@ impl MultiAsset { fn is_abstract_fungible(&self, id: &[u8]) -> bool { match self { MultiAsset::AllFungible => true, - MultiAsset::AllAbstractFungible { id: i } - | MultiAsset::AbstractFungible { id: i, .. } - => i == id, + MultiAsset::AllAbstractFungible { id: i } | + MultiAsset::AbstractFungible { id: i, .. } => i == id, _ => false, } } @@ -232,9 +236,8 @@ impl MultiAsset { fn is_concrete_non_fungible(&self, class: &MultiLocation) -> bool { match self { MultiAsset::AllNonFungible => true, - MultiAsset::AllConcreteNonFungible { class: i } - | MultiAsset::ConcreteNonFungible { class: i, .. } - => i == class, + MultiAsset::AllConcreteNonFungible { class: i } | + MultiAsset::ConcreteNonFungible { class: i, .. } => i == class, _ => false, } } @@ -242,14 +245,15 @@ impl MultiAsset { fn is_abstract_non_fungible(&self, class: &[u8]) -> bool { match self { MultiAsset::AllNonFungible => true, - MultiAsset::AllAbstractNonFungible { class: i } - | MultiAsset::AbstractNonFungible { class: i, .. } - => i == class, + MultiAsset::AllAbstractNonFungible { class: i } | + MultiAsset::AbstractNonFungible { class: i, .. } => i == class, _ => false, } } - fn is_all(&self) -> bool { matches!(self, MultiAsset::All) } + fn is_all(&self) -> bool { + matches!(self, MultiAsset::All) + } /// Returns true if `self` is a super-set of the given `inner`. /// @@ -259,14 +263,22 @@ impl MultiAsset { use MultiAsset::*; // Inner cannot be wild - if inner.is_wildcard() { return false } + if inner.is_wildcard() { + return false + } // Everything contains nothing. - if inner.is_none() { return true } + if inner.is_none() { + return true + } // Everything contains anything. - if self.is_all() { return true } + if self.is_all() { + return true + } // Nothing contains nothing. - if self.is_none() { return false } + if self.is_none() { + return false + } match self { // Anything fungible contains "all fungibles" @@ -296,11 +308,11 @@ impl MultiAsset { pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> { use MultiAsset::*; match self { - AllConcreteFungible { ref mut id } - | AllConcreteNonFungible { class: ref mut id } - | ConcreteFungible { ref mut id, .. } - | ConcreteNonFungible { class: ref mut id, .. } - => id.prepend_with(prepend.clone()).map_err(|_| ()), + AllConcreteFungible { ref mut id } | + AllConcreteNonFungible { class: ref mut id } | + ConcreteFungible { ref mut id, .. } | + ConcreteNonFungible { class: ref mut id, .. } => + id.prepend_with(prepend.clone()).map_err(|_| ()), _ => Ok(()), } } @@ -345,35 +357,39 @@ mod tests { assert!(!AllNonFungible.contains(&AllNonFungible)); // For fungibles, containing is basically equality, or equal id with higher amount. - assert!( - !AbstractFungible { id: vec![99u8], amount: 99 } - .contains(&AbstractFungible { id: vec![1u8], amount: 99 }) - ); - assert!( - AbstractFungible { id: vec![99u8], amount: 99 } - .contains(&AbstractFungible { id: vec![99u8], amount: 99 }) - ); - assert!( - AbstractFungible { id: vec![99u8], amount: 99 } - .contains(&AbstractFungible { id: vec![99u8], amount: 9 }) - ); - assert!( - !AbstractFungible { id: vec![99u8], amount: 99 } - .contains(&AbstractFungible { id: vec![99u8], amount: 100 }) - ); + assert!(!AbstractFungible { id: vec![99u8], amount: 99 } + .contains(&AbstractFungible { id: vec![1u8], amount: 99 })); + assert!(AbstractFungible { id: vec![99u8], amount: 99 } + .contains(&AbstractFungible { id: vec![99u8], amount: 99 })); + assert!(AbstractFungible { id: vec![99u8], amount: 99 } + .contains(&AbstractFungible { id: vec![99u8], amount: 9 })); + assert!(!AbstractFungible { id: vec![99u8], amount: 99 } + .contains(&AbstractFungible { id: vec![99u8], amount: 100 })); // For non-fungibles, containing is equality. - assert!( - !AbstractNonFungible {class: vec![99u8], instance: AssetInstance::Index { id: 9 } } - .contains(&AbstractNonFungible { class: vec![98u8], instance: AssetInstance::Index { id: 9 } }) - ); - assert!( - !AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 8 } } - .contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } }) - ); - assert!( - AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } } - .contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } }) - ); + assert!(!AbstractNonFungible { + class: vec![99u8], + instance: AssetInstance::Index { id: 9 } + } + .contains(&AbstractNonFungible { + class: vec![98u8], + instance: AssetInstance::Index { id: 9 } + })); + assert!(!AbstractNonFungible { + class: vec![99u8], + instance: AssetInstance::Index { id: 8 } + } + .contains(&AbstractNonFungible { + class: vec![99u8], + instance: AssetInstance::Index { id: 9 } + })); + assert!(AbstractNonFungible { + class: vec![99u8], + instance: AssetInstance::Index { id: 9 } + } + .contains(&AbstractNonFungible { + class: vec![99u8], + instance: AssetInstance::Index { id: 9 } + })); } } diff --git a/polkadot/xcm/src/v0/multi_location.rs b/polkadot/xcm/src/v0/multi_location.rs index cd01fb320a7..e45df25a0ff 100644 --- a/polkadot/xcm/src/v0/multi_location.rs +++ b/polkadot/xcm/src/v0/multi_location.rs @@ -16,11 +16,11 @@ //! Cross-Consensus Message format data structures. -use core::{result, mem, convert::TryFrom}; +use core::{convert::TryFrom, mem, result}; -use parity_scale_codec::{self, Encode, Decode}; use super::Junction; use crate::VersionedMultiLocation; +use parity_scale_codec::{self, Decode, Encode}; /// A relative path between state-bearing consensus systems. /// @@ -110,13 +110,19 @@ impl From<(Junction, Junction, Junction, Junction, Junction, Junction)> for Mult MultiLocation::X6(x.0, x.1, x.2, x.3, x.4, x.5) } } -impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation { +impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction)> + for MultiLocation +{ fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self { MultiLocation::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6) } } -impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation { - fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self { +impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)> + for MultiLocation +{ + fn from( + x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction), + ) -> Self { MultiLocation::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7) } } @@ -249,11 +255,13 @@ impl MultiLocation { MultiLocation::X1(a) => (MultiLocation::Null, Some(a)), MultiLocation::X2(a, b) => (MultiLocation::X1(b), Some(a)), MultiLocation::X3(a, b, c) => (MultiLocation::X2(b, c), Some(a)), - MultiLocation::X4(a, b, c ,d) => (MultiLocation::X3(b, c, d), Some(a)), - MultiLocation::X5(a, b, c ,d, e) => (MultiLocation::X4(b, c, d, e), Some(a)), - MultiLocation::X6(a, b, c ,d, e, f) => (MultiLocation::X5(b, c, d, e, f), Some(a)), - MultiLocation::X7(a, b, c ,d, e, f, g) => (MultiLocation::X6(b, c, d, e, f, g), Some(a)), - MultiLocation::X8(a, b, c ,d, e, f, g, h) => (MultiLocation::X7(b, c, d, e, f, g, h), Some(a)), + MultiLocation::X4(a, b, c, d) => (MultiLocation::X3(b, c, d), Some(a)), + MultiLocation::X5(a, b, c, d, e) => (MultiLocation::X4(b, c, d, e), Some(a)), + MultiLocation::X6(a, b, c, d, e, f) => (MultiLocation::X5(b, c, d, e, f), Some(a)), + MultiLocation::X7(a, b, c, d, e, f, g) => + (MultiLocation::X6(b, c, d, e, f, g), Some(a)), + MultiLocation::X8(a, b, c, d, e, f, g, h) => + (MultiLocation::X7(b, c, d, e, f, g, h), Some(a)), } } @@ -265,11 +273,13 @@ impl MultiLocation { MultiLocation::X1(a) => (MultiLocation::Null, Some(a)), MultiLocation::X2(a, b) => (MultiLocation::X1(a), Some(b)), MultiLocation::X3(a, b, c) => (MultiLocation::X2(a, b), Some(c)), - MultiLocation::X4(a, b, c ,d) => (MultiLocation::X3(a, b, c), Some(d)), + MultiLocation::X4(a, b, c, d) => (MultiLocation::X3(a, b, c), Some(d)), MultiLocation::X5(a, b, c, d, e) => (MultiLocation::X4(a, b, c, d), Some(e)), MultiLocation::X6(a, b, c, d, e, f) => (MultiLocation::X5(a, b, c, d, e), Some(f)), - MultiLocation::X7(a, b, c, d, e, f, g) => (MultiLocation::X6(a, b, c, d, e, f), Some(g)), - MultiLocation::X8(a, b, c, d, e, f, g, h) => (MultiLocation::X7(a, b, c, d, e, f, g), Some(h)), + MultiLocation::X7(a, b, c, d, e, f, g) => + (MultiLocation::X6(a, b, c, d, e, f), Some(g)), + MultiLocation::X8(a, b, c, d, e, f, g, h) => + (MultiLocation::X7(a, b, c, d, e, f, g), Some(h)), } } @@ -474,19 +484,30 @@ impl MultiLocation { let mut n = MultiLocation::Null; mem::swap(&mut *self, &mut n); match n.pushed_with(new) { - Ok(result) => { *self = result; Ok(()) } - Err(old) => { *self = old; Err(()) } + Ok(result) => { + *self = result; + Ok(()) + }, + Err(old) => { + *self = old; + Err(()) + }, } } - /// Mutates `self`, prefixing it with `new`. Returns `Err` in case of overflow. pub fn push_front(&mut self, new: Junction) -> result::Result<(), ()> { let mut n = MultiLocation::Null; mem::swap(&mut *self, &mut n); match n.pushed_front_with(new) { - Ok(result) => { *self = result; Ok(()) } - Err(old) => { *self = old; Err(()) } + Ok(result) => { + *self = result; + Ok(()) + }, + Err(old) => { + *self = old; + Err(()) + }, } } @@ -558,10 +579,10 @@ impl MultiLocation { while let Some(j) = iter.next() { if j == &Junction::Parent { match normalized.last() { - None | Some(Junction::Parent) => {} + None | Some(Junction::Parent) => {}, Some(_) => { normalized.take_last(); - continue; + continue }, } } @@ -572,7 +593,6 @@ impl MultiLocation { core::mem::swap(self, &mut normalized); } - /// Mutate `self` so that it is suffixed with `suffix`. The correct normalized form is returned, /// removing any internal `[Non-Parent, Parent]` combinations. /// @@ -596,7 +616,7 @@ impl MultiLocation { let mut suffix = prefix; core::mem::swap(self, &mut suffix); Err(suffix) - } + }, } } @@ -630,7 +650,7 @@ impl MultiLocation { // Pre-pending this prefix would create a multi-location with too many junctions. if self.len() + prefix.len() - 2 * skipped > MAX_MULTILOCATION_LENGTH { - return Err(prefix); + return Err(prefix) } // Here we cancel out `[Non-Parent, Parent]` items (normalization), where @@ -638,21 +658,22 @@ impl MultiLocation { // comes from the front of the original location. // // We calculated already how many of these there should be above. - for _ in 0 .. skipped { - let _non_parent = prefix.take_last(); - let _parent = self.take_first(); - debug_assert!( - _non_parent.is_some() && _non_parent != Some(Junction::Parent), - "prepend_with should always remove a non-parent from the end of the prefix", - ); - debug_assert!( - _parent == Some(Junction::Parent), - "prepend_with should always remove a parent from the front of the location", - ); + for _ in 0..skipped { + let _non_parent = prefix.take_last(); + let _parent = self.take_first(); + debug_assert!( + _non_parent.is_some() && _non_parent != Some(Junction::Parent), + "prepend_with should always remove a non-parent from the end of the prefix", + ); + debug_assert!( + _parent == Some(Junction::Parent), + "prepend_with should always remove a parent from the front of the location", + ); } for j in prefix.into_iter_rev() { - self.push_front(j).expect("len + prefix minus 2*skipped is less than max length; qed"); + self.push_front(j) + .expect("len + prefix minus 2*skipped is less than max length; qed"); } Ok(()) } @@ -734,7 +755,16 @@ mod tests { // Can handle shared prefix and resizing correctly. let mut m = X1(Parent); - let prefix = X8(Parachain(100), OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, Parent); + let prefix = X8( + Parachain(100), + OnlyChild, + OnlyChild, + OnlyChild, + OnlyChild, + OnlyChild, + OnlyChild, + Parent, + ); assert_eq!(m.prepend_with(prefix.clone()), Ok(())); assert_eq!(m, X5(Parachain(100), OnlyChild, OnlyChild, OnlyChild, OnlyChild)); @@ -783,8 +813,8 @@ mod tests { m.canonicalize(); assert_eq!(m, Null); - let mut m = X4( Parent, Parent, Parachain(1), Parachain(2)); + let mut m = X4(Parent, Parent, Parachain(1), Parachain(2)); m.canonicalize(); - assert_eq!(m, X4( Parent, Parent, Parachain(1), Parachain(2))); + assert_eq!(m, X4(Parent, Parent, Parachain(1), Parachain(2))); } } diff --git a/polkadot/xcm/src/v0/order.rs b/polkadot/xcm/src/v0/order.rs index 776ac3691c7..c63df711758 100644 --- a/polkadot/xcm/src/v0/order.rs +++ b/polkadot/xcm/src/v0/order.rs @@ -16,14 +16,14 @@ //! Version 0 of the Cross-Consensus Message format data structures. +use super::{MultiAsset, MultiLocation, Xcm}; use alloc::vec::Vec; use derivative::Derivative; -use parity_scale_codec::{self, Encode, Decode}; -use super::{MultiAsset, MultiLocation, Xcm}; +use parity_scale_codec::{self, Decode, Encode}; /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages. #[derive(Derivative, Encode, Decode)] -#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] #[codec(encode_bound())] #[codec(decode_bound())] pub enum Order { @@ -77,7 +77,11 @@ pub enum Order { /// /// Errors: #[codec(index = 4)] - InitiateReserveWithdraw { assets: Vec, reserve: MultiLocation, effects: Vec> }, + InitiateReserveWithdraw { + assets: Vec, + reserve: MultiLocation, + effects: Vec>, + }, /// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location. /// @@ -99,14 +103,25 @@ pub enum Order { /// /// Errors: #[codec(index = 6)] - QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: Vec }, + QueryHolding { + #[codec(compact)] + query_id: u64, + dest: MultiLocation, + assets: Vec, + }, /// Pay for the execution of some XCM with up to `weight` picoseconds of execution time, paying for this with /// up to `fees` from the holding account. /// /// Errors: #[codec(index = 7)] - BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec> }, + BuyExecution { + fees: MultiAsset, + weight: u64, + debt: u64, + halt_on_error: bool, + xcm: Vec>, + }, } pub mod opaque { @@ -114,23 +129,22 @@ pub mod opaque { } impl Order { - pub fn into(self) -> Order { Order::from(self) } + pub fn into(self) -> Order { + Order::from(self) + } pub fn from(order: Order) -> Self { use Order::*; match order { Null => Null, - DepositAsset { assets, dest } - => DepositAsset { assets, dest }, - DepositReserveAsset { assets, dest, effects } - => DepositReserveAsset { assets, dest, effects }, - ExchangeAsset { give, receive } - => ExchangeAsset { give, receive }, - InitiateReserveWithdraw { assets, reserve, effects } - => InitiateReserveWithdraw { assets, reserve, effects }, - InitiateTeleport { assets, dest, effects } - => InitiateTeleport { assets, dest, effects }, - QueryHolding { query_id, dest, assets } - => QueryHolding { query_id, dest, assets }, + DepositAsset { assets, dest } => DepositAsset { assets, dest }, + DepositReserveAsset { assets, dest, effects } => + DepositReserveAsset { assets, dest, effects }, + ExchangeAsset { give, receive } => ExchangeAsset { give, receive }, + InitiateReserveWithdraw { assets, reserve, effects } => + InitiateReserveWithdraw { assets, reserve, effects }, + InitiateTeleport { assets, dest, effects } => + InitiateTeleport { assets, dest, effects }, + QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest, assets }, BuyExecution { fees, weight, debt, halt_on_error, xcm } => { let xcm = xcm.into_iter().map(Xcm::from).collect(); BuyExecution { fees, weight, debt, halt_on_error, xcm } diff --git a/polkadot/xcm/src/v0/traits.rs b/polkadot/xcm/src/v0/traits.rs index 9a01f227e76..e1673fd5d99 100644 --- a/polkadot/xcm/src/v0/traits.rs +++ b/polkadot/xcm/src/v0/traits.rs @@ -17,7 +17,7 @@ //! Cross-Consensus Message format data structures. use core::result; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; use super::{MultiLocation, Xcm}; diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs index ea3d8066094..17d5b721b3c 100644 --- a/polkadot/xcm/xcm-builder/src/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -16,11 +16,11 @@ //! Various implementations for `ShouldExecute`. -use sp_std::{result::Result, marker::PhantomData}; -use xcm::v0::{Xcm, Order, MultiLocation, Junction}; use frame_support::{ensure, traits::Contains, weights::Weight}; -use xcm_executor::traits::{OnResponse, ShouldExecute}; use polkadot_parachain::primitives::IsSystem; +use sp_std::{marker::PhantomData, result::Result}; +use xcm::v0::{Junction, MultiLocation, Order, Xcm}; +use xcm_executor::traits::{OnResponse, ShouldExecute}; /// Execution barrier that just takes `shallow_weight` from `weight_credit`. pub struct TakeWeightCredit; @@ -51,14 +51,14 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro ensure!(T::contains(origin), ()); ensure!(top_level, ()); match message { - Xcm::TeleportAsset { effects, .. } - | Xcm::WithdrawAsset { effects, ..} - | Xcm::ReserveAssetDeposit { effects, ..} - if matches!( + Xcm::TeleportAsset { effects, .. } | + Xcm::WithdrawAsset { effects, .. } | + Xcm::ReserveAssetDeposit { effects, .. } + if matches!( effects.first(), Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight - ) - => Ok(()), + ) => + Ok(()), _ => Err(()), } } @@ -82,9 +82,7 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { /// Allows a message only if it is from a system-level child parachain. pub struct IsChildSystemParachain(PhantomData); -impl< - ParaId: IsSystem + From, -> Contains for IsChildSystemParachain { +impl> Contains for IsChildSystemParachain { fn contains(l: &MultiLocation) -> bool { matches!(l, MultiLocation::X1(Junction::Parachain(id)) if ParaId::from(*id).is_system()) } @@ -101,8 +99,9 @@ impl ShouldExecute for AllowKnownQueryResponses Result<(), ()> { match message { - Xcm::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id) - => Ok(()), + Xcm::QueryResponse { query_id, .. } + if ResponseHandler::expecting_response(origin, *query_id) => + Ok(()), _ => Err(()), } } diff --git a/polkadot/xcm/xcm-builder/src/currency_adapter.rs b/polkadot/xcm/xcm-builder/src/currency_adapter.rs index 744835f0895..fcbaa93c599 100644 --- a/polkadot/xcm/xcm-builder/src/currency_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/currency_adapter.rs @@ -16,12 +16,14 @@ //! Adapters to work with `frame_support::traits::Currency` through XCM. -use sp_std::{result, convert::TryInto, marker::PhantomData}; -use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation}; -use sp_runtime::traits::{SaturatedConversion, CheckedSub}; -use frame_support::traits::{ExistenceRequirement::AllowDeath, WithdrawReasons, Get}; -use xcm_executor::traits::{MatchesFungible, Convert, TransactAsset}; -use xcm_executor::Assets; +use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons}; +use sp_runtime::traits::{CheckedSub, SaturatedConversion}; +use sp_std::{convert::TryInto, marker::PhantomData, result}; +use xcm::v0::{Error as XcmError, MultiAsset, MultiLocation, Result}; +use xcm_executor::{ + traits::{Convert, MatchesFungible, TransactAsset}, + Assets, +}; /// Asset transaction errors. enum Error { @@ -39,7 +41,8 @@ impl From for XcmError { match e { Error::AssetNotFound => XcmError::AssetNotFound, Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"), - Error::AmountToBalanceConversionFailed => FailedToTransactAsset("AmountToBalanceConversionFailed"), + Error::AmountToBalanceConversionFailed => + FailedToTransactAsset("AmountToBalanceConversionFailed"), } } } @@ -81,26 +84,33 @@ impl From for XcmError { /// >; /// ``` pub struct CurrencyAdapter( - PhantomData<(Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount)> + PhantomData<(Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount)>, ); impl< - Matcher: MatchesFungible, - AccountIdConverter: Convert, - Currency: frame_support::traits::Currency, - AccountId: Clone, // can't get away without it since Currency is generic over it. - CheckedAccount: Get>, -> TransactAsset for CurrencyAdapter { + Matcher: MatchesFungible, + AccountIdConverter: Convert, + Currency: frame_support::traits::Currency, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckedAccount: Get>, + > TransactAsset + for CurrencyAdapter +{ fn can_check_in(_origin: &MultiLocation, what: &MultiAsset) -> Result { // Check we handle this asset. - let amount: Currency::Balance = Matcher::matches_fungible(what) - .ok_or(Error::AssetNotFound)?; + let amount: Currency::Balance = + Matcher::matches_fungible(what).ok_or(Error::AssetNotFound)?; if let Some(checked_account) = CheckedAccount::get() { let new_balance = Currency::free_balance(&checked_account) .checked_sub(&amount) .ok_or(XcmError::NotWithdrawable)?; - Currency::ensure_can_withdraw(&checked_account, amount, WithdrawReasons::TRANSFER, new_balance) - .map_err(|_| XcmError::NotWithdrawable)?; + Currency::ensure_can_withdraw( + &checked_account, + amount, + WithdrawReasons::TRANSFER, + new_balance, + ) + .map_err(|_| XcmError::NotWithdrawable)?; } Ok(()) } @@ -108,8 +118,17 @@ impl< fn check_in(_origin: &MultiLocation, what: &MultiAsset) { if let Some(amount) = Matcher::matches_fungible(what) { if let Some(checked_account) = CheckedAccount::get() { - let ok = Currency::withdraw(&checked_account, amount, WithdrawReasons::TRANSFER, AllowDeath).is_ok(); - debug_assert!(ok, "`can_check_in` must have returned `true` immediately prior; qed"); + let ok = Currency::withdraw( + &checked_account, + amount, + WithdrawReasons::TRANSFER, + AllowDeath, + ) + .is_ok(); + debug_assert!( + ok, + "`can_check_in` must have returned `true` immediately prior; qed" + ); } } } @@ -124,31 +143,24 @@ impl< fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result { // Check we handle this asset. - let amount: u128 = Matcher::matches_fungible(&what) - .ok_or(Error::AssetNotFound)? - .saturated_into(); - let who = AccountIdConverter::convert_ref(who) - .map_err(|()| Error::AccountIdConversionFailed)?; - let balance_amount = amount - .try_into() - .map_err(|_| Error::AmountToBalanceConversionFailed)?; + let amount: u128 = + Matcher::matches_fungible(&what).ok_or(Error::AssetNotFound)?.saturated_into(); + let who = + AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?; + let balance_amount = + amount.try_into().map_err(|_| Error::AmountToBalanceConversionFailed)?; let _imbalance = Currency::deposit_creating(&who, balance_amount); Ok(()) } - fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation - ) -> result::Result { + fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> result::Result { // Check we handle this asset. - let amount: u128 = Matcher::matches_fungible(what) - .ok_or(Error::AssetNotFound)? - .saturated_into(); - let who = AccountIdConverter::convert_ref(who) - .map_err(|()| Error::AccountIdConversionFailed)?; - let balance_amount = amount - .try_into() - .map_err(|_| Error::AmountToBalanceConversionFailed)?; + let amount: u128 = + Matcher::matches_fungible(what).ok_or(Error::AssetNotFound)?.saturated_into(); + let who = + AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?; + let balance_amount = + amount.try_into().map_err(|_| Error::AmountToBalanceConversionFailed)?; Currency::withdraw(&who, balance_amount, WithdrawReasons::TRANSFER, AllowDeath) .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; Ok(what.clone().into()) diff --git a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs index 9ad4f40aa71..cd27065173f 100644 --- a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs +++ b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs @@ -16,9 +16,9 @@ //! Various implementations of `FilterAssetLocation`. +use frame_support::traits::Get; use sp_std::marker::PhantomData; use xcm::v0::{MultiAsset, MultiLocation}; -use frame_support::traits::Get; use xcm_executor::traits::FilterAssetLocation; /// Accepts an asset iff it is a native asset. diff --git a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs index 80cd74c0124..f3c98deb4b0 100644 --- a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs @@ -16,20 +16,20 @@ //! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM. -use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow}; -use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction}; -use frame_support::traits::{Get, tokens::fungibles, Contains}; -use xcm_executor::traits::{TransactAsset, Convert, MatchesFungibles, Error as MatchError}; +use frame_support::traits::{tokens::fungibles, Contains, Get}; +use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result}; +use xcm::v0::{Error as XcmError, Junction, MultiAsset, MultiLocation, Result}; +use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, TransactAsset}; /// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be `TryFrom/TryInto`) into /// a `GeneralIndex` junction, prefixed by some `MultiLocation` value. The `MultiLocation` value will typically be a /// `PalletInstance` junction. -pub struct AsPrefixedGeneralIndex(PhantomData<(Prefix, AssetId, ConvertAssetId)>); -impl< - Prefix: Get, - AssetId: Clone, - ConvertAssetId: Convert, -> Convert for AsPrefixedGeneralIndex { +pub struct AsPrefixedGeneralIndex( + PhantomData<(Prefix, AssetId, ConvertAssetId)>, +); +impl, AssetId: Clone, ConvertAssetId: Convert> + Convert for AsPrefixedGeneralIndex +{ fn convert_ref(id: impl Borrow) -> result::Result { let prefix = Prefix::get(); let id = id.borrow(); @@ -50,58 +50,63 @@ impl< } pub struct ConvertedConcreteAssetId( - PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)> + PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>, ); impl< - AssetId: Clone, - Balance: Clone, - ConvertAssetId: Convert, - ConvertBalance: Convert, -> MatchesFungibles for - ConvertedConcreteAssetId + AssetId: Clone, + Balance: Clone, + ConvertAssetId: Convert, + ConvertBalance: Convert, + > MatchesFungibles + for ConvertedConcreteAssetId { fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { let (id, amount) = match a { MultiAsset::ConcreteFungible { id, amount } => (id, amount), _ => return Err(MatchError::AssetNotFound), }; - let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?; - let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?; + let what = + ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?; + let amount = ConvertBalance::convert_ref(amount) + .map_err(|_| MatchError::AmountToBalanceConversionFailed)?; Ok((what, amount)) } } pub struct ConvertedAbstractAssetId( - PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)> + PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>, ); impl< - AssetId: Clone, - Balance: Clone, - ConvertAssetId: Convert, AssetId>, - ConvertBalance: Convert, -> MatchesFungibles for - ConvertedAbstractAssetId + AssetId: Clone, + Balance: Clone, + ConvertAssetId: Convert, AssetId>, + ConvertBalance: Convert, + > MatchesFungibles + for ConvertedAbstractAssetId { fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { let (id, amount) = match a { MultiAsset::AbstractFungible { id, amount } => (id, amount), _ => return Err(MatchError::AssetNotFound), }; - let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?; - let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?; + let what = + ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?; + let amount = ConvertBalance::convert_ref(amount) + .map_err(|_| MatchError::AmountToBalanceConversionFailed)?; Ok((what, amount)) } } pub struct FungiblesTransferAdapter( - PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)> + PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>, ); impl< - Assets: fungibles::Transfer, - Matcher: MatchesFungibles, - AccountIdConverter: Convert, - AccountId: Clone, // can't get away without it since Currency is generic over it. -> TransactAsset for FungiblesTransferAdapter { + Assets: fungibles::Transfer, + Matcher: MatchesFungibles, + AccountIdConverter: Convert, + AccountId: Clone, // can't get away without it since Currency is generic over it. + > TransactAsset for FungiblesTransferAdapter +{ fn transfer_asset( what: &MultiAsset, from: &MultiLocation, @@ -119,17 +124,31 @@ impl< } } -pub struct FungiblesMutateAdapter( - PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)> -); +pub struct FungiblesMutateAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, +>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>); impl< - Assets: fungibles::Mutate, - Matcher: MatchesFungibles, - AccountIdConverter: Convert, - AccountId: Clone, // can't get away without it since Currency is generic over it. - CheckAsset: Contains, - CheckingAccount: Get, -> TransactAsset for FungiblesMutateAdapter { + Assets: fungibles::Mutate, + Matcher: MatchesFungibles, + AccountIdConverter: Convert, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckAsset: Contains, + CheckingAccount: Get, + > TransactAsset + for FungiblesMutateAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + > +{ fn can_check_in(_origin: &MultiLocation, what: &MultiAsset) -> Result { // Check we handle this asset. let (asset_id, amount) = Matcher::matches_fungibles(what)?; @@ -148,7 +167,10 @@ impl< if CheckAsset::contains(&asset_id) { let checking_account = CheckingAccount::get(); let ok = Assets::burn_from(asset_id, &checking_account, amount).is_ok(); - debug_assert!(ok, "`can_check_in` must have returned `true` immediately prior; qed"); + debug_assert!( + ok, + "`can_check_in` must have returned `true` immediately prior; qed" + ); } } } @@ -174,7 +196,7 @@ impl< fn withdraw_asset( what: &MultiAsset, - who: &MultiLocation + who: &MultiLocation, ) -> result::Result { // Check we handle this asset. let (asset_id, amount) = Matcher::matches_fungibles(what)?; @@ -186,43 +208,80 @@ impl< } } -pub struct FungiblesAdapter( - PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)> -); +pub struct FungiblesAdapter< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, +>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>); impl< - Assets: fungibles::Mutate + fungibles::Transfer, - Matcher: MatchesFungibles, - AccountIdConverter: Convert, - AccountId: Clone, // can't get away without it since Currency is generic over it. - CheckAsset: Contains, - CheckingAccount: Get, -> TransactAsset for FungiblesAdapter { + Assets: fungibles::Mutate + fungibles::Transfer, + Matcher: MatchesFungibles, + AccountIdConverter: Convert, + AccountId: Clone, // can't get away without it since Currency is generic over it. + CheckAsset: Contains, + CheckingAccount: Get, + > TransactAsset + for FungiblesAdapter +{ fn can_check_in(origin: &MultiLocation, what: &MultiAsset) -> Result { - FungiblesMutateAdapter:: - ::can_check_in(origin, what) + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::can_check_in(origin, what) } fn check_in(origin: &MultiLocation, what: &MultiAsset) { - FungiblesMutateAdapter:: - ::check_in(origin, what) + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::check_in(origin, what) } fn check_out(dest: &MultiLocation, what: &MultiAsset) { - FungiblesMutateAdapter:: - ::check_out(dest, what) + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::check_out(dest, what) } fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result { - FungiblesMutateAdapter:: - ::deposit_asset(what, who) + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::deposit_asset(what, who) } fn withdraw_asset( what: &MultiAsset, - who: &MultiLocation + who: &MultiLocation, ) -> result::Result { - FungiblesMutateAdapter:: - ::withdraw_asset(what, who) + FungiblesMutateAdapter::< + Assets, + Matcher, + AccountIdConverter, + AccountId, + CheckAsset, + CheckingAccount, + >::withdraw_asset(what, who) } fn transfer_asset( @@ -230,6 +289,8 @@ impl< from: &MultiLocation, to: &MultiLocation, ) -> result::Result { - FungiblesTransferAdapter::::transfer_asset(what, from, to) + FungiblesTransferAdapter::::transfer_asset( + what, from, to, + ) } } diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs index 534261a9998..a6cccc2d288 100644 --- a/polkadot/xcm/xcm-builder/src/lib.rs +++ b/polkadot/xcm/xcm-builder/src/lib.rs @@ -27,21 +27,22 @@ mod tests; mod location_conversion; pub use location_conversion::{ - Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases, - AccountKey20Aliases, LocationInverter, + Account32Hash, AccountId32Aliases, AccountKey20Aliases, ChildParachainConvertsVia, + LocationInverter, ParentIsDefault, SiblingParachainConvertsVia, }; mod origin_conversion; pub use origin_conversion::{ - SovereignSignedViaLocation, ParentAsSuperuser, ChildSystemParachainAsSuperuser, SiblingSystemParachainAsSuperuser, - ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative, - SignedAccountKey20AsNative, EnsureXcmOrigin, SignedToAccountId32, BackingToPlurality, + BackingToPlurality, ChildParachainAsNative, ChildSystemParachainAsSuperuser, EnsureXcmOrigin, + ParentAsSuperuser, RelayChainAsNative, SiblingParachainAsNative, + SiblingSystemParachainAsSuperuser, SignedAccountId32AsNative, SignedAccountKey20AsNative, + SignedToAccountId32, SovereignSignedViaLocation, }; mod barriers; pub use barriers::{ - TakeWeightCredit, AllowUnpaidExecutionFrom, AllowTopLevelPaidExecutionFrom, AllowKnownQueryResponses, - IsChildSystemParachain, + AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + IsChildSystemParachain, TakeWeightCredit, }; mod currency_adapter; @@ -50,11 +51,11 @@ pub use currency_adapter::CurrencyAdapter; mod fungibles_adapter; pub use fungibles_adapter::{ AsPrefixedGeneralIndex, ConvertedAbstractAssetId, ConvertedConcreteAssetId, FungiblesAdapter, - FungiblesMutateAdapter, FungiblesTransferAdapter + FungiblesMutateAdapter, FungiblesTransferAdapter, }; mod weight; -pub use weight::{FixedRateOfConcreteFungible, FixedWeightBounds, UsingComponents, TakeRevenue}; +pub use weight::{FixedRateOfConcreteFungible, FixedWeightBounds, TakeRevenue, UsingComponents}; mod matches_fungible; pub use matches_fungible::{IsAbstract, IsConcrete}; diff --git a/polkadot/xcm/xcm-builder/src/location_conversion.rs b/polkadot/xcm/xcm-builder/src/location_conversion.rs index cdf0a2bf517..23612629946 100644 --- a/polkadot/xcm/xcm-builder/src/location_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/location_conversion.rs @@ -14,19 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::{marker::PhantomData, borrow::Borrow}; -use sp_io::hashing::blake2_256; -use sp_runtime::traits::AccountIdConversion; use frame_support::traits::Get; use parity_scale_codec::Encode; -use xcm::v0::{MultiLocation, NetworkId, Junction}; -use xcm_executor::traits::{InvertLocation, Convert}; +use sp_io::hashing::blake2_256; +use sp_runtime::traits::AccountIdConversion; +use sp_std::{borrow::Borrow, marker::PhantomData}; +use xcm::v0::{Junction, MultiLocation, NetworkId}; +use xcm_executor::traits::{Convert, InvertLocation}; pub struct Account32Hash(PhantomData<(Network, AccountId)>); -impl< - Network: Get, - AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone, -> Convert for Account32Hash { +impl, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> + Convert for Account32Hash +{ fn convert_ref(location: impl Borrow) -> Result { Ok(("multiloc", location.borrow()).using_encoded(blake2_256).into()) } @@ -39,9 +38,9 @@ impl< /// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the /// default value of `AccountId` (e.g. all zeros for `AccountId32`). pub struct ParentIsDefault(PhantomData); -impl< - AccountId: Default + Eq + Clone, -> Convert for ParentIsDefault { +impl Convert + for ParentIsDefault +{ fn convert_ref(location: impl Borrow) -> Result { if let &MultiLocation::X1(Junction::Parent) = location.borrow() { Ok(AccountId::default()) @@ -60,10 +59,9 @@ impl< } pub struct ChildParachainConvertsVia(PhantomData<(ParaId, AccountId)>); -impl< - ParaId: From + Into + AccountIdConversion, - AccountId: Clone, -> Convert for ChildParachainConvertsVia { +impl + Into + AccountIdConversion, AccountId: Clone> + Convert for ChildParachainConvertsVia +{ fn convert_ref(location: impl Borrow) -> Result { if let &MultiLocation::X1(Junction::Parachain(id)) = location.borrow() { Ok(ParaId::from(id).into_account()) @@ -82,10 +80,9 @@ impl< } pub struct SiblingParachainConvertsVia(PhantomData<(ParaId, AccountId)>); -impl< - ParaId: From + Into + AccountIdConversion, - AccountId: Clone, -> Convert for SiblingParachainConvertsVia { +impl + Into + AccountIdConversion, AccountId: Clone> + Convert for SiblingParachainConvertsVia +{ fn convert_ref(location: impl Borrow) -> Result { if let &MultiLocation::X2(Junction::Parent, Junction::Parachain(id)) = location.borrow() { Ok(ParaId::from(id).into_account()) @@ -105,14 +102,15 @@ impl< /// Extracts the `AccountId32` from the passed `location` if the network matches. pub struct AccountId32Aliases(PhantomData<(Network, AccountId)>); -impl< - Network: Get, - AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone, -> Convert for AccountId32Aliases { +impl, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> + Convert for AccountId32Aliases +{ fn convert(location: MultiLocation) -> Result { let id = match location { MultiLocation::X1(Junction::AccountId32 { id, network: NetworkId::Any }) => id, - MultiLocation::X1(Junction::AccountId32 { id, network }) if &network == &Network::get() => id, + MultiLocation::X1(Junction::AccountId32 { id, network }) + if &network == &Network::get() => + id, l => return Err(l), }; Ok(id.into()) @@ -124,14 +122,15 @@ impl< } pub struct AccountKey20Aliases(PhantomData<(Network, AccountId)>); -impl< - Network: Get, - AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone, -> Convert for AccountKey20Aliases { +impl, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone> + Convert for AccountKey20Aliases +{ fn convert(location: MultiLocation) -> Result { let key = match location { MultiLocation::X1(Junction::AccountKey20 { key, network: NetworkId::Any }) => key, - MultiLocation::X1(Junction::AccountKey20 { key, network }) if &network == &Network::get() => key, + MultiLocation::X1(Junction::AccountKey20 { key, network }) + if &network == &Network::get() => + key, l => return Err(l), }; Ok(key.into()) @@ -182,7 +181,8 @@ impl> InvertLocation for LocationInverter fn invert_location(location: &MultiLocation) -> MultiLocation { let mut ancestry = Ancestry::get(); let mut result = location.clone(); - for (i, j) in location.iter_rev() + for (i, j) in location + .iter_rev() .map(|j| match j { Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild), _ => Junction::Parent, @@ -200,7 +200,7 @@ mod tests { use super::*; use frame_support::parameter_types; - use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any}; + use xcm::v0::{Junction::*, MultiLocation::*, NetworkId::Any}; fn account20() -> Junction { AccountKey20 { network: Any, key: Default::default() } @@ -224,7 +224,7 @@ mod tests { // output (target to source): ../../para_1/account20_default/account20_default #[test] fn inverter_works_in_tree() { - parameter_types!{ + parameter_types! { pub Ancestry: MultiLocation = X3(Parachain(1), account20(), account20()); } @@ -239,7 +239,7 @@ mod tests { // ^ Target #[test] fn inverter_uses_ancestry_as_inverted_location() { - parameter_types!{ + parameter_types! { pub Ancestry: MultiLocation = X2(account20(), account20()); } @@ -254,7 +254,7 @@ mod tests { // ^ Target #[test] fn inverter_uses_only_child_on_missing_ancestry() { - parameter_types!{ + parameter_types! { pub Ancestry: MultiLocation = X1(PalletInstance(5)); } diff --git a/polkadot/xcm/xcm-builder/src/matches_fungible.rs b/polkadot/xcm/xcm-builder/src/matches_fungible.rs index 4d76a49b6bd..34871e5eba2 100644 --- a/polkadot/xcm/xcm-builder/src/matches_fungible.rs +++ b/polkadot/xcm/xcm-builder/src/matches_fungible.rs @@ -16,10 +16,10 @@ //! Various implementations for the `MatchesFungible` trait. -use sp_std::{marker::PhantomData, convert::TryFrom}; +use frame_support::traits::Get; use sp_runtime::traits::CheckedConversion; +use sp_std::{convert::TryFrom, marker::PhantomData}; use xcm::v0::{MultiAsset, MultiLocation}; -use frame_support::traits::Get; use xcm_executor::traits::MatchesFungible; /// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that diff --git a/polkadot/xcm/xcm-builder/src/mock.rs b/polkadot/xcm/xcm-builder/src/mock.rs index 56d7d753e49..86d54fa0fe9 100644 --- a/polkadot/xcm/xcm-builder/src/mock.rs +++ b/polkadot/xcm/xcm-builder/src/mock.rs @@ -14,26 +14,33 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell}; -pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; -pub use parity_scale_codec::{Encode, Decode}; -pub use xcm::v0::{ - SendXcm, MultiLocation::*, Junction::*, MultiAsset, Xcm, Order, Result as XcmResult, Error as XcmError, - OriginKind, MultiLocation, Junction, opaque, +pub use crate::{ + AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + FixedRateOfConcreteFungible, FixedWeightBounds, LocationInverter, TakeWeightCredit, }; pub use frame_support::{ + dispatch::{ + DispatchError, DispatchInfo, DispatchResultWithPostInfo, Dispatchable, Parameter, Weight, + }, ensure, parameter_types, - dispatch::{Dispatchable, Parameter, Weight, DispatchError, DispatchResultWithPostInfo, DispatchInfo}, - weights::{PostDispatchInfo, GetDispatchInfo}, sp_runtime::DispatchErrorWithPostInfo, - traits::{Get, Contains, IsInVec}, + traits::{Contains, Get, IsInVec}, + weights::{GetDispatchInfo, PostDispatchInfo}, }; -pub use xcm_executor::{ - Assets, Config, traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse} +pub use parity_scale_codec::{Decode, Encode}; +pub use sp_std::{ + cell::RefCell, + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + fmt::Debug, + marker::PhantomData, }; -pub use crate::{ - TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds, - FixedRateOfConcreteFungible, AllowKnownQueryResponses, LocationInverter, +pub use xcm::v0::{ + opaque, Error as XcmError, Junction, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, + Order, OriginKind, Result as XcmResult, SendXcm, Xcm, +}; +pub use xcm_executor::{ + traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset}, + Assets, Config, }; pub enum TestOrigin { @@ -62,20 +69,18 @@ impl Dispatchable for TestCall { fn dispatch(self, origin: Self::Origin) -> DispatchResultWithPostInfo { let mut post_info = PostDispatchInfo::default(); post_info.actual_weight = match self { - TestCall::OnlyRoot(_, maybe_actual) - | TestCall::OnlySigned(_, maybe_actual, _) - | TestCall::OnlyParachain(_, maybe_actual, _) - | TestCall::Any(_, maybe_actual) - => maybe_actual, + TestCall::OnlyRoot(_, maybe_actual) | + TestCall::OnlySigned(_, maybe_actual, _) | + TestCall::OnlyParachain(_, maybe_actual, _) | + TestCall::Any(_, maybe_actual) => maybe_actual, }; if match (&origin, &self) { (TestOrigin::Parachain(i), TestCall::OnlyParachain(_, _, Some(j))) => i == j, (TestOrigin::Signed(i), TestCall::OnlySigned(_, _, Some(j))) => i == j, - (TestOrigin::Root, TestCall::OnlyRoot(..)) - | (TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None)) - | (TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None)) - | (_, TestCall::Any(..)) - => true, + (TestOrigin::Root, TestCall::OnlyRoot(..)) | + (TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None)) | + (TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None)) | + (_, TestCall::Any(..)) => true, _ => false, } { Ok(post_info) @@ -88,13 +93,12 @@ impl Dispatchable for TestCall { impl GetDispatchInfo for TestCall { fn get_dispatch_info(&self) -> DispatchInfo { let weight = *match self { - TestCall::OnlyRoot(estimate, ..) - | TestCall::OnlyParachain(estimate, ..) - | TestCall::OnlySigned(estimate, ..) - | TestCall::Any(estimate, ..) - => estimate, + TestCall::OnlyRoot(estimate, ..) | + TestCall::OnlyParachain(estimate, ..) | + TestCall::OnlySigned(estimate, ..) | + TestCall::Any(estimate, ..) => estimate, }; - DispatchInfo { weight, .. Default::default() } + DispatchInfo { weight, ..Default::default() } } } @@ -119,11 +123,7 @@ pub fn assets(who: u64) -> Vec { ASSETS.with(|a| a.borrow().get(&who).map_or(vec![], |a| a.clone().into())) } pub fn add_asset(who: u64, what: MultiAsset) { - ASSETS.with(|a| a.borrow_mut() - .entry(who) - .or_insert(Assets::new()) - .saturating_subsume(what) - ); + ASSETS.with(|a| a.borrow_mut().entry(who).or_insert(Assets::new()).saturating_subsume(what)); } pub struct TestAssetTransactor; @@ -136,16 +136,16 @@ impl TransactAsset for TestAssetTransactor { fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result { let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?; - ASSETS.with(|a| a.borrow_mut() - .get_mut(&who) - .ok_or(XcmError::NotWithdrawable)? - .try_take(what.clone()) - .map_err(|()| XcmError::NotWithdrawable) - ) + ASSETS.with(|a| { + a.borrow_mut() + .get_mut(&who) + .ok_or(XcmError::NotWithdrawable)? + .try_take(what.clone()) + .map_err(|()| XcmError::NotWithdrawable) + }) } } - pub fn to_account(l: MultiLocation) -> Result { Ok(match l { // Siblings at 2000+id @@ -164,14 +164,17 @@ pub fn to_account(l: MultiLocation) -> Result { pub struct TestOriginConverter; impl ConvertOrigin for TestOriginConverter { - fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { + fn convert_origin( + origin: MultiLocation, + kind: OriginKind, + ) -> Result { use OriginKind::*; match (kind, origin) { (Superuser, _) => Ok(TestOrigin::Root), (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), (Native, X1(Parachain(id))) => Ok(TestOrigin::Parachain(id)), (Native, X1(Parent)) => Ok(TestOrigin::Relay), - (Native, X1(AccountIndex64 {index, ..})) => Ok(TestOrigin::Signed(index)), + (Native, X1(AccountIndex64 { index, .. })) => Ok(TestOrigin::Signed(index)), (_, origin) => Err(origin), } } @@ -191,17 +194,15 @@ pub fn add_teleporter(from: MultiLocation, asset: MultiAsset) { pub struct TestIsReserve; impl FilterAssetLocation for TestIsReserve { fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { - IS_RESERVE.with(|r| r.borrow().get(origin) - .map_or(false, |v| v.iter().any(|a| a.contains(asset))) - ) + IS_RESERVE + .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.contains(asset)))) } } pub struct TestIsTeleporter; impl FilterAssetLocation for TestIsTeleporter { fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { - IS_TELEPORTER.with(|r| r.borrow().get(origin) - .map_or(false, |v| v.iter().any(|a| a.contains(asset))) - ) + IS_TELEPORTER + .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.contains(asset)))) } } @@ -223,28 +224,25 @@ impl OnResponse for TestResponseHandler { } fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::v0::Response) -> Weight { QUERIES.with(|q| { - q.borrow_mut() - .entry(query_id) - .and_modify(|v| if matches!(*v, ResponseSlot::Expecting(..)) { + q.borrow_mut().entry(query_id).and_modify(|v| { + if matches!(*v, ResponseSlot::Expecting(..)) { *v = ResponseSlot::Received(response); - }); + } + }); }); 10 } } pub fn expect_response(query_id: u64, from: MultiLocation) { - QUERIES.with(|q| q.borrow_mut() - .insert(query_id, ResponseSlot::Expecting(from)) - ); + QUERIES.with(|q| q.borrow_mut().insert(query_id, ResponseSlot::Expecting(from))); } pub fn response(query_id: u64) -> Option { - QUERIES.with(|q| q.borrow() - .get(&query_id) - .and_then(|v| match v { + QUERIES.with(|q| { + q.borrow().get(&query_id).and_then(|v| match v { ResponseSlot::Received(r) => Some(r.clone()), _ => None, }) - ) + }) } parameter_types! { diff --git a/polkadot/xcm/xcm-builder/src/origin_conversion.rs b/polkadot/xcm/xcm-builder/src/origin_conversion.rs index 79dbf957240..2a1956ca79d 100644 --- a/polkadot/xcm/xcm-builder/src/origin_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/origin_conversion.rs @@ -16,21 +16,22 @@ //! Various implementations for `ConvertOrigin`. -use sp_std::{marker::PhantomData, convert::TryInto}; -use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction, BodyId, BodyPart}; -use xcm_executor::traits::{Convert, ConvertOrigin}; -use frame_support::traits::{EnsureOrigin, Get, OriginTrait, GetBacking}; +use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait}; use frame_system::RawOrigin as SystemRawOrigin; use polkadot_parachain::primitives::IsSystem; +use sp_std::{convert::TryInto, marker::PhantomData}; +use xcm::v0::{BodyId, BodyPart, Junction, MultiLocation, NetworkId, OriginKind}; +use xcm_executor::traits::{Convert, ConvertOrigin}; /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`. pub struct SovereignSignedViaLocation( - PhantomData<(LocationConverter, Origin)> + PhantomData<(LocationConverter, Origin)>, ); -impl< - LocationConverter: Convert, - Origin: OriginTrait, -> ConvertOrigin for SovereignSignedViaLocation where Origin::AccountId: Clone { +impl, Origin: OriginTrait> + ConvertOrigin for SovereignSignedViaLocation +where + Origin::AccountId: Clone, +{ fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { if let OriginKind::SovereignAccount = kind { let location = LocationConverter::convert(origin)?; @@ -42,27 +43,23 @@ impl< } pub struct ParentAsSuperuser(PhantomData); -impl< - Origin: OriginTrait, -> ConvertOrigin for ParentAsSuperuser { +impl ConvertOrigin for ParentAsSuperuser { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { - (OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) => - Ok(Origin::root()), + (OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) => Ok(Origin::root()), (_, origin) => Err(origin), } } } pub struct ChildSystemParachainAsSuperuser(PhantomData<(ParaId, Origin)>); -impl< - ParaId: IsSystem + From, - Origin: OriginTrait, -> ConvertOrigin for ChildSystemParachainAsSuperuser { +impl, Origin: OriginTrait> ConvertOrigin + for ChildSystemParachainAsSuperuser +{ fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Superuser, MultiLocation::X1(Junction::Parachain(id))) - if ParaId::from(id).is_system() => + if ParaId::from(id).is_system() => Ok(Origin::root()), (_, origin) => Err(origin), } @@ -70,60 +67,53 @@ impl< } pub struct SiblingSystemParachainAsSuperuser(PhantomData<(ParaId, Origin)>); -impl< - ParaId: IsSystem + From, - Origin: OriginTrait -> ConvertOrigin for SiblingSystemParachainAsSuperuser { +impl, Origin: OriginTrait> ConvertOrigin + for SiblingSystemParachainAsSuperuser +{ fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { - (OriginKind::Superuser, MultiLocation::X2(Junction::Parent, Junction::Parachain(id))) - if ParaId::from(id).is_system() => - Ok(Origin::root()), + ( + OriginKind::Superuser, + MultiLocation::X2(Junction::Parent, Junction::Parachain(id)), + ) if ParaId::from(id).is_system() => Ok(Origin::root()), (_, origin) => Err(origin), } } } -pub struct ChildParachainAsNative( - PhantomData<(ParachainOrigin, Origin)> -); -impl< - ParachainOrigin: From, - Origin: From, -> ConvertOrigin for ChildParachainAsNative { +pub struct ChildParachainAsNative(PhantomData<(ParachainOrigin, Origin)>); +impl, Origin: From> ConvertOrigin + for ChildParachainAsNative +{ fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { - (OriginKind::Native, MultiLocation::X1(Junction::Parachain(id))) - => Ok(Origin::from(ParachainOrigin::from(id))), + (OriginKind::Native, MultiLocation::X1(Junction::Parachain(id))) => + Ok(Origin::from(ParachainOrigin::from(id))), (_, origin) => Err(origin), } } } pub struct SiblingParachainAsNative( - PhantomData<(ParachainOrigin, Origin)> + PhantomData<(ParachainOrigin, Origin)>, ); -impl< - ParachainOrigin: From, - Origin: From, -> ConvertOrigin for SiblingParachainAsNative { +impl, Origin: From> ConvertOrigin + for SiblingParachainAsNative +{ fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { - (OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain(id))) - => Ok(Origin::from(ParachainOrigin::from(id))), + (OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain(id))) => + Ok(Origin::from(ParachainOrigin::from(id))), (_, origin) => Err(origin), } } } // Our Relay-chain has a native origin given by the `Get`ter. -pub struct RelayChainAsNative( - PhantomData<(RelayOrigin, Origin)> -); -impl< - RelayOrigin: Get, - Origin, -> ConvertOrigin for RelayChainAsNative { +pub struct RelayChainAsNative(PhantomData<(RelayOrigin, Origin)>); +impl, Origin> ConvertOrigin + for RelayChainAsNative +{ fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X1(Junction::Parent)) => Ok(RelayOrigin::get()), @@ -132,41 +122,33 @@ impl< } } -pub struct SignedAccountId32AsNative( - PhantomData<(Network, Origin)> -); -impl< - Network: Get, - Origin: OriginTrait, -> ConvertOrigin for SignedAccountId32AsNative where +pub struct SignedAccountId32AsNative(PhantomData<(Network, Origin)>); +impl, Origin: OriginTrait> ConvertOrigin + for SignedAccountId32AsNative +where Origin::AccountId: From<[u8; 32]>, { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X1(Junction::AccountId32 { id, network })) - if matches!(network, NetworkId::Any) || network == Network::get() - => Ok(Origin::signed(id.into())), + if matches!(network, NetworkId::Any) || network == Network::get() => + Ok(Origin::signed(id.into())), (_, origin) => Err(origin), } } } -pub struct SignedAccountKey20AsNative( - PhantomData<(Network, Origin)> -); -impl< - Network: Get, - Origin: OriginTrait -> ConvertOrigin for SignedAccountKey20AsNative where +pub struct SignedAccountKey20AsNative(PhantomData<(Network, Origin)>); +impl, Origin: OriginTrait> ConvertOrigin + for SignedAccountKey20AsNative +where Origin::AccountId: From<[u8; 20]>, { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X1(Junction::AccountKey20 { key, network })) if matches!(network, NetworkId::Any) || network == Network::get() => - { - Ok(Origin::signed(key.into())) - } + Ok(Origin::signed(key.into())), (_, origin) => Err(origin), } } @@ -174,10 +156,9 @@ impl< /// `EnsureOrigin` barrier to convert from dispatch origin to XCM origin, if one exists. pub struct EnsureXcmOrigin(PhantomData<(Origin, Conversion)>); -impl< - Origin: OriginTrait + Clone, - Conversion: Convert, -> EnsureOrigin for EnsureXcmOrigin where +impl> EnsureOrigin + for EnsureXcmOrigin +where Origin::PalletsOrigin: PartialEq, { type Success = MultiLocation; @@ -206,15 +187,13 @@ impl< /// Typically used when configuring `pallet-xcm` for allowing normal accounts to dispatch an XCM from an `AccountId32` /// origin. pub struct SignedToAccountId32( - PhantomData<(Origin, AccountId, Network)> + PhantomData<(Origin, AccountId, Network)>, ); -impl< - Origin: OriginTrait + Clone, - AccountId: Into<[u8; 32]>, - Network: Get, -> Convert for SignedToAccountId32 where - Origin::PalletsOrigin: From> + - TryInto, Error=Origin::PalletsOrigin> +impl, Network: Get> + Convert for SignedToAccountId32 +where + Origin::PalletsOrigin: From> + + TryInto, Error = Origin::PalletsOrigin>, { fn convert(o: Origin) -> Result { o.try_with_caller(|caller| match caller.try_into() { @@ -231,16 +210,11 @@ impl< /// /// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an XCM from a /// `Plurality` origin. -pub struct BackingToPlurality( - PhantomData<(Origin, COrigin, Body)> -); -impl< - Origin: OriginTrait + Clone, - COrigin: GetBacking, - Body: Get, -> Convert for BackingToPlurality where - Origin::PalletsOrigin: From + - TryInto +pub struct BackingToPlurality(PhantomData<(Origin, COrigin, Body)>); +impl> + Convert for BackingToPlurality +where + Origin::PalletsOrigin: From + TryInto, { fn convert(o: Origin) -> Result { o.try_with_caller(|caller| match caller.try_into() { @@ -248,9 +222,10 @@ impl< Some(backing) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Fraction { nom: backing.approvals, denom: backing.eligible }, - }.into()), + } + .into()), None => Err(co.into()), - } + }, Err(other) => Err(other), }) } diff --git a/polkadot/xcm/xcm-builder/src/tests.rs b/polkadot/xcm/xcm-builder/src/tests.rs index 0f04b89285d..4b5ace87bd7 100644 --- a/polkadot/xcm/xcm-builder/src/tests.rs +++ b/polkadot/xcm/xcm-builder/src/tests.rs @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use super::*; -use super::mock::*; -use {MultiAsset::*, Option::None}; -use xcm::v0::{Order, NetworkId::Any, Outcome, Response, ExecuteXcm}; -use xcm_executor::{XcmExecutor, Config, traits::*}; +use super::{mock::*, *}; +use xcm::v0::{ExecuteXcm, NetworkId::Any, Order, Outcome, Response}; +use xcm_executor::{traits::*, Config, XcmExecutor}; +use MultiAsset::*; +use Option::None; #[test] fn basic_setup_works() { @@ -32,8 +32,8 @@ fn basic_setup_works() { assert_eq!(to_account(X1(Parachain(50))), Ok(1050)); assert_eq!(to_account(X2(Parent, Parachain(1))), Ok(2001)); assert_eq!(to_account(X2(Parent, Parachain(50))), Ok(2050)); - assert_eq!(to_account(X1(AccountIndex64{index:1, network:Any})), Ok(1)); - assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any})), Ok(42)); + assert_eq!(to_account(X1(AccountIndex64 { index: 1, network: Any })), Ok(1)); + assert_eq!(to_account(X1(AccountIndex64 { index: 42, network: Any })), Ok(42)); assert_eq!(to_account(Null), Ok(3000)); } @@ -42,10 +42,17 @@ fn weigher_should_work() { let mut message = opaque::Xcm::ReserveAssetDeposit { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], effects: vec![ - Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, + Order::BuyExecution { + fees: All, + weight: 0, + debt: 30, + halt_on_error: true, + xcm: vec![], + }, Order::DepositAsset { assets: vec![All], dest: Null }, ], - }.into(); + } + .into(); assert_eq!(::Weigher::shallow(&mut message), Ok(30)); } @@ -57,23 +64,13 @@ fn take_weight_credit_barrier_should_work() { }; let mut weight_credit = 10; - let r = TakeWeightCredit::should_execute( - &X1(Parent), - true, - &mut message, - 10, - &mut weight_credit, - ); + let r = + TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit); assert_eq!(r, Ok(())); assert_eq!(weight_credit, 0); - let r = TakeWeightCredit::should_execute( - &X1(Parent), - true, - &mut message, - 10, - &mut weight_credit, - ); + let r = + TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit); assert_eq!(r, Err(())); assert_eq!(weight_credit, 0); } @@ -85,7 +82,7 @@ fn allow_unpaid_should_work() { dest: Null, }; - AllowUnpaidFrom::set(vec![ X1(Parent) ]); + AllowUnpaidFrom::set(vec![X1(Parent)]); let r = AllowUnpaidExecutionFrom::>::should_execute( &X1(Parachain(1)), @@ -108,7 +105,7 @@ fn allow_unpaid_should_work() { #[test] fn allow_paid_should_work() { - AllowPaidFrom::set(vec![ X1(Parent) ]); + AllowPaidFrom::set(vec![X1(Parent)]); let mut message = opaque::Xcm::TransferAsset { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], @@ -127,7 +124,13 @@ fn allow_paid_should_work() { let mut underpaying_message = opaque::Xcm::ReserveAssetDeposit { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], effects: vec![ - Order::BuyExecution { fees: All, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] }, + Order::BuyExecution { + fees: All, + weight: 0, + debt: 20, + halt_on_error: true, + xcm: vec![], + }, Order::DepositAsset { assets: vec![All], dest: Null }, ], }; @@ -144,7 +147,13 @@ fn allow_paid_should_work() { let mut paying_message = opaque::Xcm::ReserveAssetDeposit { assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], effects: vec![ - Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, + Order::BuyExecution { + fees: All, + weight: 0, + debt: 30, + halt_on_error: true, + xcm: vec![], + }, Order::DepositAsset { assets: vec![All], dest: Null }, ], }; @@ -170,79 +179,88 @@ fn allow_paid_should_work() { #[test] fn paying_reserve_deposit_should_work() { - AllowPaidFrom::set(vec![ X1(Parent) ]); + AllowPaidFrom::set(vec![X1(Parent)]); add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) }); WeightPrice::set((X1(Parent), 1_000_000_000_000)); let origin = X1(Parent); let message = Xcm::::ReserveAssetDeposit { - assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], effects: vec![ - Order::::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] }, - Order::::DepositAsset { assets: vec![ All ], dest: Null }, + Order::::BuyExecution { + fees: All, + weight: 0, + debt: 30, + halt_on_error: true, + xcm: vec![], + }, + Order::::DepositAsset { assets: vec![All], dest: Null }, ], }; let weight_limit = 50; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); assert_eq!(r, Outcome::Complete(30)); - assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]); + assert_eq!(assets(3000), vec![ConcreteFungible { id: X1(Parent), amount: 70 }]); } #[test] fn transfer_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]); + AllowUnpaidFrom::set(vec![X1(Parachain(1))]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(1001, ConcreteFungible { id: Null, amount: 1000 }); // They want to transfer 100 of them to their sibling parachain #2 let r = XcmExecutor::::execute_xcm( X1(Parachain(1)), Xcm::TransferAsset { - assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], - dest: X1(AccountIndex64{index:3, network:Any}), + assets: vec![ConcreteFungible { id: Null, amount: 100 }], + dest: X1(AccountIndex64 { index: 3, network: Any }), }, 50, ); assert_eq!(r, Outcome::Complete(10)); - assert_eq!(assets(3), vec![ ConcreteFungible { id: Null, amount: 100 } ]); - assert_eq!(assets(1001), vec![ ConcreteFungible { id: Null, amount: 900 } ]); + assert_eq!(assets(3), vec![ConcreteFungible { id: Null, amount: 100 }]); + assert_eq!(assets(1001), vec![ConcreteFungible { id: Null, amount: 900 }]); assert_eq!(sent_xcm(), vec![]); } #[test] fn reserve_transfer_should_work() { - AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]); + AllowUnpaidFrom::set(vec![X1(Parachain(1))]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(1001, ConcreteFungible { id: Null, amount: 1000 }); // The remote account owned by gav. - let three = X1(AccountIndex64{index:3, network:Any}); + let three = X1(AccountIndex64 { index: 3, network: Any }); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let r = XcmExecutor::::execute_xcm( X1(Parachain(1)), Xcm::TransferReserveAsset { - assets: vec![ ConcreteFungible { id: Null, amount: 100 } ], + assets: vec![ConcreteFungible { id: Null, amount: 100 }], dest: X1(Parachain(2)), - effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three.clone() } ], + effects: vec![Order::DepositAsset { assets: vec![All], dest: three.clone() }], }, 50, ); assert_eq!(r, Outcome::Complete(10)); - assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]); - assert_eq!(sent_xcm(), vec![( - X1(Parachain(2)), - Xcm::ReserveAssetDeposit { - assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], - effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ], - }) - ]); + assert_eq!(assets(1002), vec![ConcreteFungible { id: Null, amount: 100 }]); + assert_eq!( + sent_xcm(), + vec![( + X1(Parachain(2)), + Xcm::ReserveAssetDeposit { + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], + effects: vec![Order::DepositAsset { assets: vec![All], dest: three }], + } + )] + ); } #[test] fn transacting_should_work() { - AllowUnpaidFrom::set(vec![ X1(Parent) ]); + AllowUnpaidFrom::set(vec![X1(Parent)]); let origin = X1(Parent); let message = Xcm::::Transact { @@ -257,7 +275,7 @@ fn transacting_should_work() { #[test] fn transacting_should_respect_max_weight_requirement() { - AllowUnpaidFrom::set(vec![ X1(Parent) ]); + AllowUnpaidFrom::set(vec![X1(Parent)]); let origin = X1(Parent); let message = Xcm::::Transact { @@ -272,7 +290,7 @@ fn transacting_should_respect_max_weight_requirement() { #[test] fn transacting_should_refund_weight() { - AllowUnpaidFrom::set(vec![ X1(Parent) ]); + AllowUnpaidFrom::set(vec![X1(Parent)]); let origin = X1(Parent); let message = Xcm::::Transact { @@ -287,30 +305,34 @@ fn transacting_should_refund_weight() { #[test] fn paid_transacting_should_refund_payment_for_unused_weight() { - let one = X1(AccountIndex64{index:1, network:Any}); - AllowPaidFrom::set(vec![ one.clone() ]); + let one = X1(AccountIndex64 { index: 1, network: Any }); + AllowPaidFrom::set(vec![one.clone()]); add_asset(1, ConcreteFungible { id: X1(Parent), amount: 100 }); WeightPrice::set((X1(Parent), 1_000_000_000_000)); let origin = one.clone(); let message = Xcm::::WithdrawAsset { - assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ], // enough for 100 units of weight. + assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }], // enough for 100 units of weight. effects: vec![ - Order::::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![ - Xcm::::Transact { + Order::::BuyExecution { + fees: All, + weight: 70, + debt: 30, + halt_on_error: true, + xcm: vec![Xcm::::Transact { origin_type: OriginKind::Native, require_weight_at_most: 60, // call estimated at 70 but only takes 10. call: TestCall::Any(60, Some(10)).encode().into(), - } - ] }, - Order::::DepositAsset { assets: vec![ All ], dest: one.clone() }, + }], + }, + Order::::DepositAsset { assets: vec![All], dest: one.clone() }, ], }; let weight_limit = 100; let r = XcmExecutor::::execute_xcm(origin, message, weight_limit); assert_eq!(r, Outcome::Complete(50)); - assert_eq!(assets(1), vec![ ConcreteFungible { id: X1(Parent), amount: 50 } ]); + assert_eq!(assets(1), vec![ConcreteFungible { id: X1(Parent), amount: 50 }]); } #[test] @@ -320,11 +342,8 @@ fn prepaid_result_of_query_should_get_free_execution() { // We put this in manually here, but normally this would be done at the point of crafting the message. expect_response(query_id, origin.clone()); - let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]); - let message = Xcm::::QueryResponse { - query_id, - response: the_response.clone(), - }; + let the_response = Response::Assets(vec![ConcreteFungible { id: X1(Parent), amount: 100 }]); + let message = Xcm::::QueryResponse { query_id, response: the_response.clone() }; let weight_limit = 10; // First time the response gets through since we're expecting it... diff --git a/polkadot/xcm/xcm-builder/src/weight.rs b/polkadot/xcm/xcm-builder/src/weight.rs index e2096afcaa3..f86030b902b 100644 --- a/polkadot/xcm/xcm-builder/src/weight.rs +++ b/polkadot/xcm/xcm-builder/src/weight.rs @@ -14,27 +14,32 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::{result::Result, marker::PhantomData, convert::TryInto}; +use frame_support::{ + traits::{tokens::currency::Currency as CurrencyT, Get, OnUnbalanced as OnUnbalancedT}, + weights::{GetDispatchInfo, Weight, WeightToFeePolynomial}, +}; use parity_scale_codec::Decode; -use xcm::v0::{Xcm, Order, MultiAsset, MultiLocation, Error}; -use sp_runtime::traits::{Zero, Saturating, SaturatedConversion}; -use frame_support::traits::{Get, OnUnbalanced as OnUnbalancedT, tokens::currency::Currency as CurrencyT}; -use frame_support::weights::{Weight, GetDispatchInfo, WeightToFeePolynomial}; -use xcm_executor::{Assets, traits::{WeightBounds, WeightTrader}}; +use sp_runtime::traits::{SaturatedConversion, Saturating, Zero}; +use sp_std::{convert::TryInto, marker::PhantomData, result::Result}; +use xcm::v0::{Error, MultiAsset, MultiLocation, Order, Xcm}; +use xcm_executor::{ + traits::{WeightBounds, WeightTrader}, + Assets, +}; pub struct FixedWeightBounds(PhantomData<(T, C)>); impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeightBounds { fn shallow(message: &mut Xcm) -> Result { Ok(match message { - Xcm::Transact { call, .. } => { - call.ensure_decoded()?.get_dispatch_info().weight.saturating_add(T::get()) - } - Xcm::RelayedFrom { ref mut message, .. } => T::get().saturating_add(Self::shallow(message.as_mut())?), - Xcm::WithdrawAsset { effects, .. } - | Xcm::ReserveAssetDeposit { effects, .. } - | Xcm::TeleportAsset { effects, .. } - => { - let inner: Weight = effects.iter_mut() + Xcm::Transact { call, .. } => + call.ensure_decoded()?.get_dispatch_info().weight.saturating_add(T::get()), + Xcm::RelayedFrom { ref mut message, .. } => + T::get().saturating_add(Self::shallow(message.as_mut())?), + Xcm::WithdrawAsset { effects, .. } | + Xcm::ReserveAssetDeposit { effects, .. } | + Xcm::TeleportAsset { effects, .. } => { + let inner: Weight = effects + .iter_mut() .map(|effect| match effect { Order::BuyExecution { .. } => { // On success, execution of this will result in more weight being consumed but @@ -45,28 +50,29 @@ impl, C: Decode + GetDispatchInfo> WeightBounds for FixedWeigh T::get() }, _ => T::get(), - }).sum(); + }) + .sum(); T::get().saturating_add(inner) - } + }, _ => T::get(), }) } fn deep(message: &mut Xcm) -> Result { Ok(match message { Xcm::RelayedFrom { ref mut message, .. } => Self::deep(message.as_mut())?, - Xcm::WithdrawAsset { effects, .. } - | Xcm::ReserveAssetDeposit { effects, .. } - | Xcm::TeleportAsset { effects, .. } - => { + Xcm::WithdrawAsset { effects, .. } | + Xcm::ReserveAssetDeposit { effects, .. } | + Xcm::TeleportAsset { effects, .. } => { let mut extra = 0; for effect in effects.iter_mut() { match effect { - Order::BuyExecution { xcm, .. } => { + Order::BuyExecution { xcm, .. } => for message in xcm.iter_mut() { - extra.saturating_accrue(Self::shallow(message)?.saturating_add(Self::deep(message)?)); - } - }, - _ => {} + extra.saturating_accrue( + Self::shallow(message)?.saturating_add(Self::deep(message)?), + ); + }, + _ => {}, } } extra @@ -92,12 +98,17 @@ impl TakeRevenue for () { /// /// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for /// one second of weight. -pub struct FixedRateOfConcreteFungible< - T: Get<(MultiLocation, u128)>, - R: TakeRevenue, ->(Weight, u128, PhantomData<(T, R)>); -impl, R: TakeRevenue> WeightTrader for FixedRateOfConcreteFungible { - fn new() -> Self { Self(0, 0, PhantomData) } +pub struct FixedRateOfConcreteFungible, R: TakeRevenue>( + Weight, + u128, + PhantomData<(T, R)>, +); +impl, R: TakeRevenue> WeightTrader + for FixedRateOfConcreteFungible +{ + fn new() -> Self { + Self(0, 0, PhantomData) + } fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { let (id, units_per_second) = T::get(); @@ -131,20 +142,27 @@ impl, R: TakeRevenue> Drop for FixedRateOfConcrete /// Weight trader which uses the `TransactionPayment` pallet to set the right price for weight and then /// places any weight bought into the right account. pub struct UsingComponents< - WeightToFee: WeightToFeePolynomial, + WeightToFee: WeightToFeePolynomial, AssetId: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, ->(Weight, Currency::Balance, PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>); +>( + Weight, + Currency::Balance, + PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, +); impl< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, -> WeightTrader for UsingComponents { - fn new() -> Self { Self(0, Zero::zero(), PhantomData) } + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > WeightTrader for UsingComponents +{ + fn new() -> Self { + Self(0, Zero::zero(), PhantomData) + } fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { let amount = WeightToFee::calc(&weight); @@ -163,21 +181,19 @@ impl< let amount = WeightToFee::calc(&weight); self.0 -= weight; self.1 = self.1.saturating_sub(amount); - let result = MultiAsset::ConcreteFungible { - amount: amount.saturated_into(), - id: AssetId::get(), - }; + let result = + MultiAsset::ConcreteFungible { amount: amount.saturated_into(), id: AssetId::get() }; result } - } impl< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, -> Drop for UsingComponents { + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > Drop for UsingComponents +{ fn drop(&mut self) { OnUnbalanced::on_unbalanced(Currency::issue(self.1)); } diff --git a/polkadot/xcm/xcm-executor/src/assets.rs b/polkadot/xcm/xcm-executor/src/assets.rs index c0d35052482..a98560d2357 100644 --- a/polkadot/xcm/xcm-executor/src/assets.rs +++ b/polkadot/xcm/xcm-executor/src/assets.rs @@ -14,9 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::{prelude::*, mem, collections::{btree_map::BTreeMap, btree_set::BTreeSet}}; -use xcm::v0::{MultiAsset, MultiLocation, AssetInstance}; use sp_runtime::RuntimeDebug; +use sp_std::{ + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + mem, + prelude::*, +}; +use xcm::v0::{AssetInstance, MultiAsset, MultiLocation}; /// Classification of an asset being concrete or abstract. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] @@ -91,43 +95,43 @@ impl From for Assets { impl Assets { /// New value, containing no assets. - pub fn new() -> Self { Self::default() } + pub fn new() -> Self { + Self::default() + } /// An iterator over the fungible assets. - pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator + 'a { - self.fungible.iter() - .map(|(id, &amount)| match id.clone() { - AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount }, - AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount }, - }) + pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator + 'a { + self.fungible.iter().map(|(id, &amount)| match id.clone() { + AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount }, + AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount }, + }) } /// An iterator over the non-fungible assets. - pub fn non_fungible_assets_iter<'a>(&'a self) -> impl Iterator + 'a { - self.non_fungible.iter() - .map(|&(ref class, ref instance)| match class.clone() { - AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance: instance.clone() }, - AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance: instance.clone() }, - }) + pub fn non_fungible_assets_iter<'a>(&'a self) -> impl Iterator + 'a { + self.non_fungible.iter().map(|&(ref class, ref instance)| match class.clone() { + AssetId::Concrete(class) => + MultiAsset::ConcreteNonFungible { class, instance: instance.clone() }, + AssetId::Abstract(class) => + MultiAsset::AbstractNonFungible { class, instance: instance.clone() }, + }) } /// An iterator over all assets. - pub fn into_assets_iter(self) -> impl Iterator { - let fungible = self.fungible.into_iter() - .map(|(id, amount)| match id { - AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount }, - AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount }, - }); - let non_fungible = self.non_fungible.into_iter() - .map(|(id, instance)| match id { - AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance }, - AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance }, - }); + pub fn into_assets_iter(self) -> impl Iterator { + let fungible = self.fungible.into_iter().map(|(id, amount)| match id { + AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount }, + AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount }, + }); + let non_fungible = self.non_fungible.into_iter().map(|(id, instance)| match id { + AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance }, + AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance }, + }); fungible.chain(non_fungible) } /// An iterator over all assets. - pub fn assets_iter<'a>(&'a self) -> impl Iterator + 'a { + pub fn assets_iter<'a>(&'a self) -> impl Iterator + 'a { let fungible = self.fungible_assets_iter(); let non_fungible = self.non_fungible_assets_iter(); fungible.chain(non_fungible) @@ -151,16 +155,16 @@ impl Assets { match asset { MultiAsset::ConcreteFungible { id, amount } => { self.saturating_subsume_fungible(AssetId::Concrete(id), amount); - } + }, MultiAsset::AbstractFungible { id, amount } => { self.saturating_subsume_fungible(AssetId::Abstract(id), amount); - } - MultiAsset::ConcreteNonFungible { class, instance} => { + }, + MultiAsset::ConcreteNonFungible { class, instance } => { self.saturating_subsume_non_fungible(AssetId::Concrete(class), instance); - } - MultiAsset::AbstractNonFungible { class, instance} => { + }, + MultiAsset::AbstractNonFungible { class, instance } => { self.saturating_subsume_non_fungible(AssetId::Abstract(class), instance); - } + }, _ => (), } } @@ -191,14 +195,22 @@ impl Assets { pub fn try_take(&mut self, asset: MultiAsset) -> Result { match asset { MultiAsset::None => Ok(Assets::new()), - MultiAsset::ConcreteFungible { id, amount } => self.try_take_fungible(AssetId::Concrete(id), amount), - MultiAsset::AbstractFungible { id, amount } => self.try_take_fungible(AssetId::Abstract(id), amount), - MultiAsset::ConcreteNonFungible { class, instance} => self.try_take_non_fungible(AssetId::Concrete(class), instance), - MultiAsset::AbstractNonFungible { class, instance} => self.try_take_non_fungible(AssetId::Abstract(class), instance), - MultiAsset::AllAbstractFungible { id } => Ok(self.take_fungible(&AssetId::Abstract(id))), - MultiAsset::AllConcreteFungible { id } => Ok(self.take_fungible(&AssetId::Concrete(id))), - MultiAsset::AllAbstractNonFungible { class } => Ok(self.take_non_fungible(&AssetId::Abstract(class))), - MultiAsset::AllConcreteNonFungible { class } => Ok(self.take_non_fungible(&AssetId::Concrete(class))), + MultiAsset::ConcreteFungible { id, amount } => + self.try_take_fungible(AssetId::Concrete(id), amount), + MultiAsset::AbstractFungible { id, amount } => + self.try_take_fungible(AssetId::Abstract(id), amount), + MultiAsset::ConcreteNonFungible { class, instance } => + self.try_take_non_fungible(AssetId::Concrete(class), instance), + MultiAsset::AbstractNonFungible { class, instance } => + self.try_take_non_fungible(AssetId::Abstract(class), instance), + MultiAsset::AllAbstractFungible { id } => + Ok(self.take_fungible(&AssetId::Abstract(id))), + MultiAsset::AllConcreteFungible { id } => + Ok(self.take_fungible(&AssetId::Concrete(id))), + MultiAsset::AllAbstractNonFungible { class } => + Ok(self.take_non_fungible(&AssetId::Abstract(class))), + MultiAsset::AllConcreteNonFungible { class } => + Ok(self.take_non_fungible(&AssetId::Concrete(class))), MultiAsset::AllFungible => { let mut taken = Assets::new(); mem::swap(&mut self.fungible, &mut taken.fungible); @@ -218,7 +230,11 @@ impl Assets { Ok(id.into_fungible_multiasset(amount).into()) } - pub fn try_take_non_fungible(&mut self, id: AssetId, instance: AssetInstance) -> Result { + pub fn try_take_non_fungible( + &mut self, + id: AssetId, + instance: AssetInstance, + ) -> Result { let asset_id_instance = (id, instance); self.try_remove_non_fungible(&asset_id_instance)?; let (asset_id, instance) = asset_id_instance; @@ -252,7 +268,10 @@ impl Assets { Ok(()) } - pub fn try_remove_non_fungible(&mut self, class_instance: &(AssetId, AssetInstance)) -> Result<(), ()> { + pub fn try_remove_non_fungible( + &mut self, + class_instance: &(AssetId, AssetInstance), + ) -> Result<(), ()> { match self.non_fungible.remove(class_instance) { true => Ok(()), false => Err(()), @@ -280,13 +299,21 @@ impl Assets { pub fn prepend_location(&mut self, prepend: &MultiLocation) { let mut fungible = Default::default(); mem::swap(&mut self.fungible, &mut fungible); - self.fungible = fungible.into_iter() - .map(|(mut id, amount)| { let _ = id.prepend_location(prepend); (id, amount) }) + self.fungible = fungible + .into_iter() + .map(|(mut id, amount)| { + let _ = id.prepend_location(prepend); + (id, amount) + }) .collect(); let mut non_fungible = Default::default(); mem::swap(&mut self.non_fungible, &mut non_fungible); - self.non_fungible = non_fungible.into_iter() - .map(|(mut class, inst)| { let _ = class.prepend_location(prepend); (class, inst) }) + self.non_fungible = non_fungible + .into_iter() + .map(|(mut class, inst)| { + let _ = class.prepend_location(prepend); + (class, inst) + }) .collect(); } @@ -340,67 +367,77 @@ impl Assets { non_fungible: self.non_fungible.clone(), } }, - MultiAsset::AllAbstractFungible { id } => { + MultiAsset::AllAbstractFungible { id } => for asset in self.fungible_assets_iter() { match &asset { MultiAsset::AbstractFungible { id: identifier, .. } => { - if id == identifier { result.saturating_subsume(asset) } + if id == identifier { + result.saturating_subsume(asset) + } }, _ => (), } - } - }, + }, MultiAsset::AllAbstractNonFungible { class } => { for asset in self.non_fungible_assets_iter() { match &asset { - MultiAsset::AbstractNonFungible { class: c, .. } => { - if class == c { result.saturating_subsume(asset) } - }, + MultiAsset::AbstractNonFungible { class: c, .. } => + if class == c { + result.saturating_subsume(asset) + }, _ => (), } } - } - MultiAsset::AllConcreteFungible { id } => { + }, + MultiAsset::AllConcreteFungible { id } => for asset in self.fungible_assets_iter() { match &asset { MultiAsset::ConcreteFungible { id: identifier, .. } => { - if id == identifier { result.saturating_subsume(asset) } + if id == identifier { + result.saturating_subsume(asset) + } }, _ => (), } - } - }, + }, MultiAsset::AllConcreteNonFungible { class } => { for asset in self.non_fungible_assets_iter() { match &asset { - MultiAsset::ConcreteNonFungible { class: c, .. } => { - if class == c { result.saturating_subsume(asset) } - }, + MultiAsset::ConcreteNonFungible { class: c, .. } => + if class == c { + result.saturating_subsume(asset) + }, _ => (), } } - } - x @ MultiAsset::ConcreteFungible { .. } | x @ MultiAsset::AbstractFungible { .. } => { + }, + x @ MultiAsset::ConcreteFungible { .. } | + x @ MultiAsset::AbstractFungible { .. } => { let (id, amount) = match x { - MultiAsset::ConcreteFungible { id, amount } => (AssetId::Concrete(id.clone()), *amount), - MultiAsset::AbstractFungible { id, amount } => (AssetId::Abstract(id.clone()), *amount), + MultiAsset::ConcreteFungible { id, amount } => + (AssetId::Concrete(id.clone()), *amount), + MultiAsset::AbstractFungible { id, amount } => + (AssetId::Abstract(id.clone()), *amount), _ => unreachable!(), }; if let Some(v) = self.fungible.get(&id) { result.saturating_subsume_fungible(id, amount.min(*v)); } }, - x @ MultiAsset::ConcreteNonFungible { .. } | x @ MultiAsset::AbstractNonFungible { .. } => { + x @ MultiAsset::ConcreteNonFungible { .. } | + x @ MultiAsset::AbstractNonFungible { .. } => { let (class, instance) = match x { - MultiAsset::ConcreteNonFungible { class, instance } => (AssetId::Concrete(class.clone()), instance.clone()), - MultiAsset::AbstractNonFungible { class, instance } => (AssetId::Abstract(class.clone()), instance.clone()), + MultiAsset::ConcreteNonFungible { class, instance } => + (AssetId::Concrete(class.clone()), instance.clone()), + MultiAsset::AbstractNonFungible { class, instance } => + (AssetId::Abstract(class.clone()), instance.clone()), _ => unreachable!(), }; let item = (class, instance); if self.non_fungible.contains(&item) { result.non_fungible.insert(item); } - } + }, } } result @@ -455,7 +492,8 @@ impl Assets { result.saturating_subsume_non_fungible(class, instance); }); }, - x @ MultiAsset::AllAbstractFungible { .. } | x @ MultiAsset::AllConcreteFungible { .. } => { + x @ MultiAsset::AllAbstractFungible { .. } | + x @ MultiAsset::AllConcreteFungible { .. } => { let id = match x { MultiAsset::AllConcreteFungible { id } => AssetId::Concrete(id), MultiAsset::AllAbstractFungible { id } => AssetId::Abstract(id), @@ -465,36 +503,41 @@ impl Assets { let mut non_matching_fungibles = BTreeMap::::new(); let fungible = mem::replace(&mut self.fungible, Default::default()); fungible.into_iter().for_each(|(iden, amount)| { - if iden == id { - result.saturating_subsume_fungible(iden, amount); - } else { - non_matching_fungibles.insert(iden, amount); - } - }); + if iden == id { + result.saturating_subsume_fungible(iden, amount); + } else { + non_matching_fungibles.insert(iden, amount); + } + }); self.fungible = non_matching_fungibles; }, - x @ MultiAsset::AllAbstractNonFungible { .. } | x @ MultiAsset::AllConcreteNonFungible { .. } => { + x @ MultiAsset::AllAbstractNonFungible { .. } | + x @ MultiAsset::AllConcreteNonFungible { .. } => { let class = match x { MultiAsset::AllConcreteNonFungible { class } => AssetId::Concrete(class), MultiAsset::AllAbstractNonFungible { class } => AssetId::Abstract(class), _ => unreachable!(), }; // At the end of this block, we will be left with only the non-matching non-fungibles. - let mut non_matching_non_fungibles = BTreeSet::<(AssetId, AssetInstance)>::new(); + let mut non_matching_non_fungibles = + BTreeSet::<(AssetId, AssetInstance)>::new(); let non_fungible = mem::replace(&mut self.non_fungible, Default::default()); non_fungible.into_iter().for_each(|(c, instance)| { - if class == c { - result.saturating_subsume_non_fungible(c, instance); - } else { - non_matching_non_fungibles.insert((c, instance)); - } - }); + if class == c { + result.saturating_subsume_non_fungible(c, instance); + } else { + non_matching_non_fungibles.insert((c, instance)); + } + }); self.non_fungible = non_matching_non_fungibles; }, - x @ MultiAsset::ConcreteFungible {..} | x @ MultiAsset::AbstractFungible {..} => { + x @ MultiAsset::ConcreteFungible { .. } | + x @ MultiAsset::AbstractFungible { .. } => { let (id, amount) = match x { - MultiAsset::ConcreteFungible { id, amount } => (AssetId::Concrete(id), amount), - MultiAsset::AbstractFungible { id, amount } => (AssetId::Abstract(id), amount), + MultiAsset::ConcreteFungible { id, amount } => + (AssetId::Concrete(id), amount), + MultiAsset::AbstractFungible { id, amount } => + (AssetId::Abstract(id), amount), _ => unreachable!(), }; // remove the maxmimum possible up to id/amount from self, add the removed onto @@ -509,11 +552,14 @@ impl Assets { result.saturating_subsume_fungible(id, e.clone()); } } - } - x @ MultiAsset::ConcreteNonFungible {..} | x @ MultiAsset::AbstractNonFungible {..} => { + }, + x @ MultiAsset::ConcreteNonFungible { .. } | + x @ MultiAsset::AbstractNonFungible { .. } => { let (class, instance) = match x { - MultiAsset::ConcreteNonFungible { class, instance } => (AssetId::Concrete(class), instance), - MultiAsset::AbstractNonFungible { class, instance } => (AssetId::Abstract(class), instance), + MultiAsset::ConcreteNonFungible { class, instance } => + (AssetId::Concrete(class), instance), + MultiAsset::AbstractNonFungible { class, instance } => + (AssetId::Abstract(class), instance), _ => unreachable!(), }; // remove the maxmimum possible up to id/amount from self, add the removed onto @@ -521,7 +567,7 @@ impl Assets { if let Some(entry) = self.non_fungible.take(&(class, instance)) { result.non_fungible.insert(entry); } - } + }, } } result @@ -543,7 +589,10 @@ mod tests { } #[allow(non_snake_case)] fn ANF(class: u8, instance_id: u128) -> MultiAsset { - MultiAsset::AbstractNonFungible { class: vec![class], instance: AssetInstance::Index { id: instance_id } } + MultiAsset::AbstractNonFungible { + class: vec![class], + instance: AssetInstance::Index { id: instance_id }, + } } #[allow(non_snake_case)] fn CF(amount: u128) -> MultiAsset { @@ -551,7 +600,10 @@ mod tests { } #[allow(non_snake_case)] fn CNF(instance_id: u128) -> MultiAsset { - MultiAsset::ConcreteNonFungible { class: MultiLocation::Null, instance: AssetInstance::Index { id: instance_id } } + MultiAsset::ConcreteNonFungible { + class: MultiLocation::Null, + instance: AssetInstance::Index { id: instance_id }, + } } fn test_assets() -> Assets { diff --git a/polkadot/xcm/xcm-executor/src/config.rs b/polkadot/xcm/xcm-executor/src/config.rs index 1ab78ecb7ec..ff39be56ef5 100644 --- a/polkadot/xcm/xcm-executor/src/config.rs +++ b/polkadot/xcm/xcm-executor/src/config.rs @@ -14,18 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use xcm::v0::SendXcm; -use frame_support::dispatch::{Dispatchable, Parameter}; -use frame_support::weights::{PostDispatchInfo, GetDispatchInfo}; use crate::traits::{ - TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, ShouldExecute, WeightTrader, WeightBounds, - OnResponse, + ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, ShouldExecute, TransactAsset, + WeightBounds, WeightTrader, +}; +use frame_support::{ + dispatch::{Dispatchable, Parameter}, + weights::{GetDispatchInfo, PostDispatchInfo}, }; +use xcm::v0::SendXcm; /// The trait to parameterize the `XcmExecutor`. pub trait Config { /// The outer call dispatch type. - type Call: Parameter + Dispatchable + GetDispatchInfo; + type Call: Parameter + Dispatchable + GetDispatchInfo; /// How to send an onward XCM message. type XcmSender: SendXcm; diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 8f8a5c9ee61..bb0b8eb604a 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -16,24 +16,25 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::{prelude::*, marker::PhantomData}; use frame_support::{ - ensure, weights::GetDispatchInfo, - dispatch::{Weight, Dispatchable} + dispatch::{Dispatchable, Weight}, + ensure, + weights::GetDispatchInfo, }; +use sp_std::{marker::PhantomData, prelude::*}; use xcm::v0::{ - ExecuteXcm, SendXcm, Error as XcmError, Outcome, - MultiLocation, MultiAsset, Xcm, Order, Response, + Error as XcmError, ExecuteXcm, MultiAsset, MultiLocation, Order, Outcome, Response, SendXcm, + Xcm, }; pub mod traits; use traits::{ - TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, WeightBounds, WeightTrader, - ShouldExecute, OnResponse + ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, ShouldExecute, TransactAsset, + WeightBounds, WeightTrader, }; mod assets; -pub use assets::{Assets, AssetId}; +pub use assets::{AssetId, Assets}; mod config; pub use config::Config; @@ -70,10 +71,17 @@ impl ExecuteXcm for XcmExecutor { None => return Outcome::Error(XcmError::Overflow), }; if maximum_weight > weight_limit { - return Outcome::Error(XcmError::WeightLimitReached(maximum_weight)); + return Outcome::Error(XcmError::WeightLimitReached(maximum_weight)) } let mut trader = Config::Trader::new(); - let result = Self::do_execute_xcm(origin, true, message, &mut weight_credit, Some(shallow_weight), &mut trader); + let result = Self::do_execute_xcm( + origin, + true, + message, + &mut weight_credit, + Some(shallow_weight), + &mut trader, + ); drop(trader); log::trace!(target: "xcm::execute_xcm", "result: {:?}", &result); match result { @@ -106,10 +114,10 @@ impl XcmExecutor { log::trace!( target: "xcm::do_execute_xcm", "origin: {:?}, top_level: {:?}, message: {:?}, weight_credit: {:?}, maybe_shallow_weight: {:?}", - origin, - top_level, - message, - weight_credit, + origin, + top_level, + message, + weight_credit, maybe_shallow_weight, ); // This is the weight of everything that cannot be paid for. This basically means all computation @@ -118,8 +126,14 @@ impl XcmExecutor { .or_else(|| Config::Weigher::shallow(&mut message).ok()) .ok_or(XcmError::WeightNotComputable)?; - Config::Barrier::should_execute(&origin, top_level, &message, shallow_weight, weight_credit) - .map_err(|()| XcmError::Barrier)?; + Config::Barrier::should_execute( + &origin, + top_level, + &message, + shallow_weight, + weight_credit, + ) + .map_err(|()| XcmError::Barrier)?; // The surplus weight, defined as the amount by which `shallow_weight` plus all nested // `shallow_weight` values (ensuring no double-counting and also known as `deep_weight`) is an @@ -136,17 +150,20 @@ impl XcmExecutor { holding.saturating_subsume_all(withdrawn); } Some((holding, effects)) - } + }, (origin, Xcm::ReserveAssetDeposit { assets, effects }) => { // check whether we trust origin to be our reserve location for this asset. for asset in assets.iter() { ensure!(!asset.is_wildcard(), XcmError::Wildcard); // We only trust the origin to send us assets that they identify as their // sovereign assets. - ensure!(Config::IsReserve::filter_asset_location(asset, &origin), XcmError::UntrustedReserveLocation); + ensure!( + Config::IsReserve::filter_asset_location(asset, &origin), + XcmError::UntrustedReserveLocation + ); } Some((Assets::from(assets), effects)) - } + }, (origin, Xcm::TransferAsset { assets, dest }) => { // Take `assets` from the origin account (on-chain) and place into dest account. for asset in assets { @@ -154,7 +171,7 @@ impl XcmExecutor { Config::AssetTransactor::teleport_asset(&asset, &origin, &dest)?; } None - } + }, (origin, Xcm::TransferReserveAsset { mut assets, dest, effects }) => { // Take `assets` from the origin account (on-chain) and place into dest account. let inv_dest = Config::LocationInverter::invert_location(&dest); @@ -165,14 +182,17 @@ impl XcmExecutor { } Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; None - } + }, (origin, Xcm::TeleportAsset { assets, effects }) => { // check whether we trust origin to teleport this asset to us via config trait. for asset in assets.iter() { ensure!(!asset.is_wildcard(), XcmError::Wildcard); // We only trust the origin to send us assets that they identify as their // sovereign assets. - ensure!(Config::IsTeleporter::filter_asset_location(asset, &origin), XcmError::UntrustedTeleportLocation); + ensure!( + Config::IsTeleporter::filter_asset_location(asset, &origin), + XcmError::UntrustedTeleportLocation + ); // We should check that the asset can actually be teleported in (for this to be in error, there // would need to be an accounting violation by one of the trusted chains, so it's unlikely, but we // don't want to punish a possibly innocent chain/user). @@ -182,7 +202,7 @@ impl XcmExecutor { Config::AssetTransactor::check_in(&origin, asset); } Some((Assets::from(assets), effects)) - } + }, (origin, Xcm::Transact { origin_type, require_weight_at_most, mut call }) => { // We assume that the Relay-chain is allowed to use transact on this parachain. @@ -198,8 +218,9 @@ impl XcmExecutor { // Not much to do with the result as it is. It's up to the parachain to ensure that the // message makes sense. error_and_info.post_info.actual_weight - } - }.unwrap_or(weight); + }, + } + .unwrap_or(weight); let surplus = weight.saturating_sub(actual_weight); // Credit any surplus weight that we bought. This should be safe since it's work we // didn't realise that we didn't have to do. @@ -212,20 +233,21 @@ impl XcmExecutor { // Return the overestimated amount so we can adjust our expectations on how much this entire // execution has taken. None - } + }, (origin, Xcm::QueryResponse { query_id, response }) => { Config::ResponseHandler::on_response(origin, query_id, response); None - } + }, (origin, Xcm::RelayedFrom { who, message }) => { ensure!(who.is_interior(), XcmError::EscalationOfPrivilege); let mut origin = origin; origin.append_with(who).map_err(|_| XcmError::MultiLocationFull)?; - let surplus = Self::do_execute_xcm(origin, top_level, *message, weight_credit, None, trader)?; + let surplus = + Self::do_execute_xcm(origin, top_level, *message, weight_credit, None, trader)?; total_surplus = total_surplus.saturating_add(surplus); None - } - _ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message. + }, + _ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message. }; if let Some((mut holding, effects)) = maybe_holding_effects { @@ -266,11 +288,11 @@ impl XcmExecutor { let assets = Self::reanchored(deposited, &dest); Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?; }, - Order::InitiateReserveWithdraw { assets, reserve, effects} => { + Order::InitiateReserveWithdraw { assets, reserve, effects } => { let assets = Self::reanchored(holding.saturating_take(assets), &reserve); Config::XcmSender::send_xcm(reserve, Xcm::WithdrawAsset { assets, effects })?; - } - Order::InitiateTeleport { assets, dest, effects} => { + }, + Order::InitiateTeleport { assets, dest, effects } => { // We must do this first in order to resolve wildcards. let assets = holding.saturating_take(assets); for asset in assets.assets_iter() { @@ -278,28 +300,39 @@ impl XcmExecutor { } let assets = Self::reanchored(assets, &dest); Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects })?; - } + }, Order::QueryHolding { query_id, dest, assets } => { let assets = Self::reanchored(holding.min(assets.iter()), &dest); - Config::XcmSender::send_xcm(dest, Xcm::QueryResponse { query_id, response: Response::Assets(assets) })?; - } + Config::XcmSender::send_xcm( + dest, + Xcm::QueryResponse { query_id, response: Response::Assets(assets) }, + )?; + }, Order::BuyExecution { fees, weight, debt, halt_on_error, xcm } => { // pay for `weight` using up to `fees` of the holding account. - let purchasing_weight = Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?); + let purchasing_weight = + Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?); let max_fee = holding.try_take(fees).map_err(|()| XcmError::NotHoldingFees)?; let unspent = trader.buy_weight(purchasing_weight, max_fee)?; holding.saturating_subsume_all(unspent); let mut remaining_weight = weight; for message in xcm.into_iter() { - match Self::do_execute_xcm(origin.clone(), false, message, &mut remaining_weight, None, trader) { + match Self::do_execute_xcm( + origin.clone(), + false, + message, + &mut remaining_weight, + None, + trader, + ) { Err(e) if halt_on_error => return Err(e), - Err(_) => {} - Ok(surplus) => { total_surplus += surplus } + Err(_) => {}, + Ok(surplus) => total_surplus += surplus, } } holding.saturating_subsume(trader.refund_weight(remaining_weight)); - } + }, _ => return Err(XcmError::UnhandledEffect)?, } Ok(total_surplus) diff --git a/polkadot/xcm/xcm-executor/src/traits/conversion.rs b/polkadot/xcm/xcm-executor/src/traits/conversion.rs index 19b2de1a007..49f5db69898 100644 --- a/polkadot/xcm/xcm-executor/src/traits/conversion.rs +++ b/polkadot/xcm/xcm-executor/src/traits/conversion.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::{prelude::*, result::Result, borrow::Borrow, convert::TryFrom}; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Decode, Encode}; +use sp_std::{borrow::Borrow, convert::TryFrom, prelude::*, result::Result}; use xcm::v0::{MultiLocation, OriginKind}; /// Generic third-party conversion trait. Use this when you don't want to force the user to use default @@ -29,12 +29,16 @@ use xcm::v0::{MultiLocation, OriginKind}; /// the `Err(_)` of the last failing conversion (or `Err(())` for ref conversions). pub trait Convert { /// Convert from `value` (of type `A`) into an equivalent value of type `B`, `Err` if not possible. - fn convert(value: A) -> Result { Self::convert_ref(&value).map_err(|_| value) } + fn convert(value: A) -> Result { + Self::convert_ref(&value).map_err(|_| value) + } fn convert_ref(value: impl Borrow) -> Result { Self::convert(value.borrow().clone()).map_err(|_| ()) } /// Convert from `value` (of type `B`) into an equivalent value of type `A`, `Err` if not possible. - fn reverse(value: B) -> Result { Self::reverse_ref(&value).map_err(|_| value) } + fn reverse(value: B) -> Result { + Self::reverse_ref(&value).map_err(|_| value) + } fn reverse_ref(value: impl Borrow) -> Result { Self::reverse(value.borrow().clone()).map_err(|_| ()) } @@ -85,13 +89,19 @@ impl Convert for Tuple { /// Simple pass-through which implements `BytesConversion` while not doing any conversion. pub struct Identity; impl Convert for Identity { - fn convert(value: T) -> Result { Ok(value) } - fn reverse(value: T) -> Result { Ok(value) } + fn convert(value: T) -> Result { + Ok(value) + } + fn reverse(value: T) -> Result { + Ok(value) + } } /// Implementation of `Convert` trait using `TryFrom`. pub struct JustTry; -impl + Clone, Dest: TryFrom + Clone> Convert for JustTry { +impl + Clone, Dest: TryFrom + Clone> Convert + for JustTry +{ fn convert(value: Source) -> Result { Dest::try_from(value.clone()).map_err(|_| value) } @@ -103,7 +113,9 @@ impl + Clone, Dest: TryFrom + Clone> Convert>` using the parity scale codec. pub struct Encoded; impl Convert> for Encoded { - fn convert_ref(value: impl Borrow) -> Result, ()> { Ok(value.borrow().encode()) } + fn convert_ref(value: impl Borrow) -> Result, ()> { + Ok(value.borrow().encode()) + } fn reverse_ref(bytes: impl Borrow>) -> Result { T::decode(&mut &bytes.borrow()[..]).map_err(|_| ()) } @@ -115,7 +127,9 @@ impl Convert, T> for Decoded { fn convert_ref(bytes: impl Borrow>) -> Result { T::decode(&mut &bytes.borrow()[..]).map_err(|_| ()) } - fn reverse_ref(value: impl Borrow) -> Result, ()> { Ok(value.borrow().encode()) } + fn reverse_ref(value: impl Borrow) -> Result, ()> { + Ok(value.borrow().encode()) + } } /// A converter `trait` for origin types. diff --git a/polkadot/xcm/xcm-executor/src/traits/matches_fungibles.rs b/polkadot/xcm/xcm-executor/src/traits/matches_fungibles.rs index 963a0441ed6..c1722d000f0 100644 --- a/polkadot/xcm/xcm-executor/src/traits/matches_fungibles.rs +++ b/polkadot/xcm/xcm-executor/src/traits/matches_fungibles.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use xcm::v0::{MultiAsset, Error as XcmError}; use sp_std::result; +use xcm::v0::{Error as XcmError, MultiAsset}; /// Errors associated with [`MatchesFungibles`] operation. pub enum Error { @@ -35,7 +35,8 @@ impl From for XcmError { match e { Error::AssetNotFound => XcmError::AssetNotFound, Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"), - Error::AmountToBalanceConversionFailed => FailedToTransactAsset("AmountToBalanceConversionFailed"), + Error::AmountToBalanceConversionFailed => + FailedToTransactAsset("AmountToBalanceConversionFailed"), Error::AssetIdConversionFailed => FailedToTransactAsset("AssetIdConversionFailed"), } } @@ -46,10 +47,7 @@ pub trait MatchesFungibles { } #[impl_trait_for_tuples::impl_for_tuples(30)] -impl< - AssetId: Clone, - Balance: Clone, -> MatchesFungibles for Tuple { +impl MatchesFungibles for Tuple { fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> { for_tuples!( #( match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () } diff --git a/polkadot/xcm/xcm-executor/src/traits/mod.rs b/polkadot/xcm/xcm-executor/src/traits/mod.rs index 483b8746d72..0a304590b63 100644 --- a/polkadot/xcm/xcm-executor/src/traits/mod.rs +++ b/polkadot/xcm/xcm-executor/src/traits/mod.rs @@ -17,13 +17,13 @@ //! Various traits used in configuring the executor. mod conversion; -pub use conversion::{InvertLocation, ConvertOrigin, Convert, JustTry, Identity, Encoded, Decoded}; +pub use conversion::{Convert, ConvertOrigin, Decoded, Encoded, Identity, InvertLocation, JustTry}; mod filter_asset_location; -pub use filter_asset_location::{FilterAssetLocation}; +pub use filter_asset_location::FilterAssetLocation; mod matches_fungible; -pub use matches_fungible::{MatchesFungible}; +pub use matches_fungible::MatchesFungible; mod matches_fungibles; -pub use matches_fungibles::{MatchesFungibles, Error}; +pub use matches_fungibles::{Error, MatchesFungibles}; mod on_response; pub use on_response::OnResponse; mod should_execute; diff --git a/polkadot/xcm/xcm-executor/src/traits/on_response.rs b/polkadot/xcm/xcm-executor/src/traits/on_response.rs index a90586d27c7..134891b4b70 100644 --- a/polkadot/xcm/xcm-executor/src/traits/on_response.rs +++ b/polkadot/xcm/xcm-executor/src/traits/on_response.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use xcm::v0::{Response, MultiLocation}; use frame_support::weights::Weight; +use xcm::v0::{MultiLocation, Response}; /// Define what needs to be done upon receiving a query response. pub trait OnResponse { @@ -25,6 +25,10 @@ pub trait OnResponse { fn on_response(origin: MultiLocation, query_id: u64, response: Response) -> Weight; } impl OnResponse for () { - fn expecting_response(_origin: &MultiLocation, _query_id: u64) -> bool { false } - fn on_response(_origin: MultiLocation, _query_id: u64, _response: Response) -> Weight { 0 } + fn expecting_response(_origin: &MultiLocation, _query_id: u64) -> bool { + false + } + fn on_response(_origin: MultiLocation, _query_id: u64, _response: Response) -> Weight { + 0 + } } diff --git a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs index da64e441850..ed92866146c 100644 --- a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs +++ b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::result::Result; -use xcm::v0::{Xcm, MultiLocation}; use frame_support::weights::Weight; +use sp_std::result::Result; +use xcm::v0::{MultiLocation, Xcm}; /// Trait to determine whether the execution engine should actually execute a given XCM. /// diff --git a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs index a967f1f6909..e228e957e64 100644 --- a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs +++ b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::result::Result; -use xcm::v0::{Error as XcmError, Result as XcmResult, MultiAsset, MultiLocation}; use crate::Assets; +use sp_std::result::Result; +use xcm::v0::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult}; /// Facility for asset transacting. /// @@ -78,22 +78,30 @@ pub trait TransactAsset { /// Move an `asset` `from` one location in `to` another location. /// /// Returns `XcmError::FailedToTransactAsset` if transfer failed. - fn transfer_asset(_asset: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result { + fn transfer_asset( + _asset: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + ) -> Result { Err(XcmError::Unimplemented) } /// Move an `asset` `from` one location in `to` another location. /// /// Attempts to use `transfer_asset` and if not available then falls back to using a two-part withdraw/deposit. - fn teleport_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { + fn teleport_asset( + asset: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + ) -> Result { match Self::transfer_asset(asset, from, to) { Err(XcmError::Unimplemented) => { let assets = Self::withdraw_asset(asset, from)?; // Not a very forgiving attitude; once we implement roll-backs then it'll be nicer. Self::deposit_asset(asset, to)?; Ok(assets) - } - result => result + }, + result => result, } } } @@ -160,7 +168,11 @@ impl TransactAsset for Tuple { Err(XcmError::AssetNotFound) } - fn transfer_asset(what: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result { + fn transfer_asset( + what: &MultiAsset, + from: &MultiLocation, + to: &MultiLocation, + ) -> Result { for_tuples!( #( match Tuple::transfer_asset(what, from, to) { Err(XcmError::AssetNotFound | XcmError::Unimplemented) => (), @@ -199,7 +211,11 @@ mod tests { Err(XcmError::AssetNotFound) } - fn transfer_asset(_what: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result { + fn transfer_asset( + _what: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + ) -> Result { Err(XcmError::AssetNotFound) } } @@ -218,7 +234,11 @@ mod tests { Err(XcmError::Overflow) } - fn transfer_asset(_what: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result { + fn transfer_asset( + _what: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + ) -> Result { Err(XcmError::Overflow) } } @@ -237,16 +257,24 @@ mod tests { Ok(Assets::default()) } - fn transfer_asset(_what: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result { + fn transfer_asset( + _what: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + ) -> Result { Ok(Assets::default()) } } #[test] fn defaults_to_asset_not_found() { - type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor); + type MultiTransactor = + (UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor); - assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Err(XcmError::AssetNotFound)); + assert_eq!( + MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), + Err(XcmError::AssetNotFound) + ); } #[test] @@ -260,7 +288,10 @@ mod tests { fn unexpected_error_stops_iteration() { type MultiTransactor = (OverflowTransactor, SuccessfulTransactor); - assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Err(XcmError::Overflow)); + assert_eq!( + MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), + Err(XcmError::Overflow) + ); } #[test] diff --git a/polkadot/xcm/xcm-executor/src/traits/weight.rs b/polkadot/xcm/xcm-executor/src/traits/weight.rs index dc9589803af..824383da508 100644 --- a/polkadot/xcm/xcm-executor/src/traits/weight.rs +++ b/polkadot/xcm/xcm-executor/src/traits/weight.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use sp_std::result::Result; -use xcm::v0::{Xcm, MultiAsset, MultiLocation, Error}; -use frame_support::weights::Weight; use crate::Assets; +use frame_support::weights::Weight; +use sp_std::result::Result; +use xcm::v0::{Error, MultiAsset, MultiLocation, Xcm}; /// Determine the weight of an XCM message. pub trait WeightBounds { @@ -71,11 +71,15 @@ pub trait WeightTrader: Sized { /// purchased using `buy_weight`. /// /// Default implementation refunds nothing. - fn refund_weight(&mut self, _weight: Weight) -> MultiAsset { MultiAsset::None } + fn refund_weight(&mut self, _weight: Weight) -> MultiAsset { + MultiAsset::None + } } impl WeightTrader for () { - fn new() -> Self { () } + fn new() -> Self { + () + } fn buy_weight(&mut self, _: Weight, _: Assets) -> Result { Err(Error::Unimplemented) } diff --git a/polkadot/xcm/xcm-simulator/src/lib.rs b/polkadot/xcm/xcm-simulator/src/lib.rs index 096d62b6169..d68072858e8 100644 --- a/polkadot/xcm/xcm-simulator/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/src/lib.rs @@ -62,6 +62,7 @@ pub fn encode_xcm(message: Xcm<()>, message_kind: MessageKind) -> Vec { } #[macro_export] +#[rustfmt::skip] macro_rules! decl_test_relay_chain { ( pub struct $name:ident { -- GitLab