From 8f1606e9f9bd6269a4c2631a161dcc73e969a302 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Tue, 3 Dec 2024 12:55:50 +0200 Subject: [PATCH 01/51] Rococo People <> Bulletin bridge fixes (#6708) --- .../chains/chain-polkadot-bulletin/src/lib.rs | 2 +- bridges/relays/utils/src/initialize.rs | 7 ++-- .../src/bridge_to_bulletin_config.rs | 41 ++++--------------- .../src/genesis_config_presets.rs | 10 +++++ .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 1 - .../bridge-hub-rococo/tests/tests.rs | 12 +++--- 6 files changed, 28 insertions(+), 45 deletions(-) diff --git a/bridges/chains/chain-polkadot-bulletin/src/lib.rs b/bridges/chains/chain-polkadot-bulletin/src/lib.rs index c5c18beb2cad..070bc7b0ba3d 100644 --- a/bridges/chains/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/chains/chain-polkadot-bulletin/src/lib.rs @@ -225,4 +225,4 @@ impl ChainWithMessages for PolkadotBulletin { } decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa); -decl_bridge_messages_runtime_apis!(polkadot_bulletin, bp_messages::HashedLaneId); +decl_bridge_messages_runtime_apis!(polkadot_bulletin, bp_messages::LegacyLaneId); diff --git a/bridges/relays/utils/src/initialize.rs b/bridges/relays/utils/src/initialize.rs index 564ed1f0e5cc..deb9b9d059d5 100644 --- a/bridges/relays/utils/src/initialize.rs +++ b/bridges/relays/utils/src/initialize.rs @@ -52,9 +52,10 @@ pub fn initialize_logger(with_timestamp: bool) { format, ); - let env_filter = EnvFilter::from_default_env() - .add_directive(Level::WARN.into()) - .add_directive("bridge=info".parse().expect("static filter string is valid")); + let env_filter = EnvFilter::builder() + .with_default_directive(Level::WARN.into()) + .with_default_directive("bridge=info".parse().expect("static filter string is valid")) + .from_env_lossy(); let builder = SubscriberBuilder::default().with_env_filter(env_filter); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index b284fa9e7af7..1e733503f43b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -22,14 +22,13 @@ use crate::{ bridge_common_config::RelayersForPermissionlessLanesInstance, weights, xcm_config::UniversalLocation, AccountId, Balance, Balances, BridgeRococoBulletinGrandpa, - BridgeRococoBulletinMessages, PolkadotXcm, Runtime, RuntimeEvent, RuntimeHoldReason, - XcmOverRococoBulletin, XcmRouter, + BridgeRococoBulletinMessages, Runtime, RuntimeEvent, RuntimeHoldReason, XcmOverRococoBulletin, + XcmRouter, }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::FromBridgedChainMessagesProof, HashedLaneId, + target_chain::FromBridgedChainMessagesProof, LegacyLaneId, }; -use bridge_hub_common::xcm_version::XcmVersionOfDestAndRemoteBridge; use frame_support::{ parameter_types, @@ -46,6 +45,7 @@ use testnet_parachains_constants::rococo::currency::UNITS as ROC; use xcm::{ latest::prelude::*, prelude::{InteriorLocation, NetworkId}, + AlwaysV5, }; use xcm_builder::{BridgeBlobDispatcher, ParentIsPreset, SiblingParachainConvertsVia}; @@ -120,7 +120,7 @@ impl pallet_bridge_messages::Config for Runt type OutboundPayload = XcmAsPlainPayload; type InboundPayload = XcmAsPlainPayload; - type LaneId = HashedLaneId; + type LaneId = LegacyLaneId; type DeliveryPayments = (); type DeliveryConfirmationPayments = (); @@ -139,8 +139,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime type BridgeMessagesPalletInstance = WithRococoBulletinMessagesInstance; type MessageExportPrice = (); - type DestinationVersion = - XcmVersionOfDestAndRemoteBridge; + type DestinationVersion = AlwaysV5; type ForceOrigin = EnsureRoot; // We don't want to allow creating bridges for this instance. @@ -253,7 +252,7 @@ where let universal_source = [GlobalConsensus(ByGenesis(ROCOCO_GENESIS_HASH)), Parachain(sibling_para_id)].into(); let universal_destination = - [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get()), Parachain(2075)].into(); + [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())].into(); let bridge_id = BridgeId::new(&universal_source, &universal_destination); // insert only bridge metadata, because the benchmarks create lanes @@ -279,29 +278,3 @@ where universal_source } - -/// Contains the migration for the PeopleRococo<>RococoBulletin bridge. -pub mod migration { - use super::*; - use frame_support::traits::ConstBool; - - parameter_types! { - pub BulletinRococoLocation: InteriorLocation = [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())].into(); - pub RococoPeopleToRococoBulletinMessagesLane: HashedLaneId = pallet_xcm_bridge_hub::Pallet::< Runtime, XcmOverPolkadotBulletinInstance >::bridge_locations( - PeopleRococoLocation::get(), - BulletinRococoLocation::get() - ) - .unwrap() - .calculate_lane_id(xcm::latest::VERSION).expect("Valid locations"); - } - - /// Ensure that the existing lanes for the People<>Bulletin bridge are correctly configured. - pub type StaticToDynamicLanes = pallet_xcm_bridge_hub::migration::OpenBridgeForLane< - Runtime, - XcmOverPolkadotBulletinInstance, - RococoPeopleToRococoBulletinMessagesLane, - ConstBool, - PeopleRococoLocation, - BulletinRococoLocation, - >; -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index 98e2450ee832..55fd499c2f54 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -61,10 +61,20 @@ fn bridge_hub_rococo_genesis( .collect(), }, polkadot_xcm: PolkadotXcmConfig { safe_xcm_version: Some(SAFE_XCM_VERSION) }, + bridge_polkadot_bulletin_grandpa: BridgePolkadotBulletinGrandpaConfig { + owner: bridges_pallet_owner.clone(), + }, bridge_westend_grandpa: BridgeWestendGrandpaConfig { owner: bridges_pallet_owner.clone() }, bridge_westend_messages: BridgeWestendMessagesConfig { owner: bridges_pallet_owner.clone(), }, + xcm_over_polkadot_bulletin: XcmOverPolkadotBulletinConfig { + opened_bridges: vec![( + Location::new(1, [Parachain(1004)]), + Junctions::from([GlobalConsensus(NetworkId::PolkadotBulletin).into()]), + Some(bp_messages::LegacyLaneId([0, 0, 0, 0])), + )], + }, xcm_over_bridge_hub_westend: XcmOverBridgeHubWestendConfig { opened_bridges }, ethereum_system: EthereumSystemConfig { para_id: id, asset_hub_para_id }, }) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 598afeddb984..d87ff9b43fef 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -169,7 +169,6 @@ pub type Migrations = ( bridge_to_westend_config::WithBridgeHubWestendMessagesInstance, >, bridge_to_westend_config::migration::StaticToDynamicLanes, - bridge_to_bulletin_config::migration::StaticToDynamicLanes, frame_support::migrations::RemoveStorage< BridgeWestendMessagesPalletName, OutboundLanesCongestedSignalsKey, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 29f9615bff6a..44e69c31a560 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -501,10 +501,10 @@ mod bridge_hub_westend_tests { mod bridge_hub_bulletin_tests { use super::*; - use bp_messages::{HashedLaneId, LaneIdType}; + use bp_messages::LegacyLaneId; use bridge_common_config::BridgeGrandpaRococoBulletinInstance; use bridge_hub_rococo_runtime::{ - bridge_common_config::RelayersForPermissionlessLanesInstance, + bridge_common_config::RelayersForLegacyLaneIdsMessagesInstance, xcm_config::LocationToAccountId, }; use bridge_hub_test_utils::test_cases::from_grandpa_chain; @@ -528,7 +528,7 @@ mod bridge_hub_bulletin_tests { AllPalletsWithoutSystem, BridgeGrandpaRococoBulletinInstance, WithRococoBulletinMessagesInstance, - RelayersForPermissionlessLanesInstance, + RelayersForLegacyLaneIdsMessagesInstance, >; #[test] @@ -599,7 +599,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance - >(locations, HashedLaneId::try_new(1, 2).unwrap()) + >(locations, LegacyLaneId([0, 0, 0, 0])) } ).1 }, @@ -663,7 +663,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, HashedLaneId::try_new(1, 2).unwrap()) + >(locations, LegacyLaneId([0, 0, 0, 0])) }, ) .1 @@ -697,7 +697,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, HashedLaneId::try_new(1, 2).unwrap()) + >(locations, LegacyLaneId([0, 0, 0, 0])) }, ) .1 From 592bb3205be7569cf2d705b31a272340038bbed7 Mon Sep 17 00:00:00 2001 From: Egor_P Date: Tue, 3 Dec 2024 13:06:43 +0100 Subject: [PATCH 02/51] [Release/CICD] Re-worked Create Release Draft flow (#6734) This PR contains following changes in release pipelines: - re-built Create Release Draft workflow - binaries builds are moved completely to the `Release - Build node release candidate` flow - added upload of all the release artefacts to the S3 - adjusted `Release - Publish Docker Image` workflow, so that it will match now the new release flow. --- .github/scripts/common/lib.sh | 45 +++- .github/scripts/release/release_lib.sh | 22 ++ ...le.yml => release-10_branchoff-stable.yml} | 0 ...ation.yml => release-11_rc-automation.yml} | 0 ...e-build-rc.yml => release-20_build-rc.yml} | 96 +++++++- .../release-30_publish_release_draft.yml | 206 +++++++++++------- .../workflows/release-50_publish-docker.yml | 97 +++------ .../workflows/release-reusable-rc-buid.yml | 53 ++++- .github/workflows/release-srtool.yml | 18 +- 9 files changed, 373 insertions(+), 164 deletions(-) rename .github/workflows/{release-branchoff-stable.yml => release-10_branchoff-stable.yml} (100%) rename .github/workflows/{release-10_rc-automation.yml => release-11_rc-automation.yml} (100%) rename .github/workflows/{release-build-rc.yml => release-20_build-rc.yml} (62%) diff --git a/.github/scripts/common/lib.sh b/.github/scripts/common/lib.sh index 6b8f70a26d7e..41dc0ba06dd2 100755 --- a/.github/scripts/common/lib.sh +++ b/.github/scripts/common/lib.sh @@ -270,20 +270,19 @@ fetch_debian_package_from_s3() { } # Fetch the release artifacts like binary and signatures from S3. Assumes the ENV are set: -# - RELEASE_ID -# - GITHUB_TOKEN -# - REPO in the form paritytech/polkadot +# inputs: binary (polkadot), target(aarch64-apple-darwin) fetch_release_artifacts_from_s3() { BINARY=$1 - OUTPUT_DIR=${OUTPUT_DIR:-"./release-artifacts/${BINARY}"} + TARGET=$2 + OUTPUT_DIR=${OUTPUT_DIR:-"./release-artifacts/${TARGET}/${BINARY}"} echo "OUTPUT_DIR : $OUTPUT_DIR" URL_BASE=$(get_s3_url_base $BINARY) echo "URL_BASE=$URL_BASE" - URL_BINARY=$URL_BASE/$VERSION/$BINARY - URL_SHA=$URL_BASE/$VERSION/$BINARY.sha256 - URL_ASC=$URL_BASE/$VERSION/$BINARY.asc + URL_BINARY=$URL_BASE/$VERSION/$TARGET/$BINARY + URL_SHA=$URL_BASE/$VERSION/$TARGET/$BINARY.sha256 + URL_ASC=$URL_BASE/$VERSION/$TARGET/$BINARY.asc # Fetch artifacts mkdir -p "$OUTPUT_DIR" @@ -306,15 +305,26 @@ fetch_release_artifacts_from_s3() { function get_s3_url_base() { name=$1 case $name in - polkadot | polkadot-execute-worker | polkadot-prepare-worker | staking-miner) + polkadot | polkadot-execute-worker | polkadot-prepare-worker ) printf "https://releases.parity.io/polkadot" ;; - polkadot-parachain) - printf "https://releases.parity.io/cumulus" + polkadot-parachain) + printf "https://releases.parity.io/polkadot-parachain" + ;; + + polkadot-omni-node) + printf "https://releases.parity.io/polkadot-omni-node" + ;; + + chain-spec-builder) + printf "https://releases.parity.io/chain-spec-builder" ;; - *) + frame-omni-bencher) + printf "https://releases.parity.io/frame-omni-bencher" + ;; + *) printf "UNSUPPORTED BINARY $name" exit 1 ;; @@ -497,3 +507,16 @@ validate_stable_tag() { exit 1 fi } + +# Prepare docker stable tag form the polkadot stable tag +# input: tag (polkaodot-stableYYMM(-X) or polkadot-stableYYMM(-X)-rcX) +# output: stableYYMM(-X) or stableYYMM(-X)-rcX +prepare_docker_stable_tag() { + tag="$1" + if [[ "$tag" =~ stable[0-9]{4}(-[0-9]+)?(-rc[0-9]+)? ]]; then + echo "${BASH_REMATCH[0]}" + else + echo "Tag is invalid: $tag" + exit 1 + fi +} diff --git a/.github/scripts/release/release_lib.sh b/.github/scripts/release/release_lib.sh index 8b9254ec3f29..43227180cb7c 100644 --- a/.github/scripts/release/release_lib.sh +++ b/.github/scripts/release/release_lib.sh @@ -139,3 +139,25 @@ upload_s3_release() { aws s3 ls "s3://releases.parity.io/${product}/${version}/${target}" --recursive --human-readable --summarize echo "✅ The release should be at https://releases.parity.io/${product}/${version}/${target}" } + +# Upload runtimes artifacts to s3 release bucket +# +# input: version (stable release tage.g. polkadot-stable2412 or polkadot-stable2412-rc1) +# output: none +upload_s3_runtimes_release_artifacts() { + alias aws='podman run --rm -it docker.io/paritytech/awscli -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_BUCKET aws' + + version=$1 + + echo "Working on version: $version " + + echo "Current content, should be empty on new uploads:" + aws s3 ls "s3://releases.parity.io/polkadot/runtimes/${version}/" --recursive --human-readable --summarize || true + echo "Content to be uploaded:" + artifacts="artifacts/runtimes/" + ls "$artifacts" + aws s3 sync --acl public-read "$artifacts" "s3://releases.parity.io/polkadot/runtimes/${version}/" + echo "Uploaded files:" + aws s3 ls "s3://releases.parity.io/polkadot/runtimes/${version}/" --recursive --human-readable --summarize + echo "✅ The release should be at https://releases.parity.io/polkadot/runtimes/${version}" +} diff --git a/.github/workflows/release-branchoff-stable.yml b/.github/workflows/release-10_branchoff-stable.yml similarity index 100% rename from .github/workflows/release-branchoff-stable.yml rename to .github/workflows/release-10_branchoff-stable.yml diff --git a/.github/workflows/release-10_rc-automation.yml b/.github/workflows/release-11_rc-automation.yml similarity index 100% rename from .github/workflows/release-10_rc-automation.yml rename to .github/workflows/release-11_rc-automation.yml diff --git a/.github/workflows/release-build-rc.yml b/.github/workflows/release-20_build-rc.yml similarity index 62% rename from .github/workflows/release-build-rc.yml rename to .github/workflows/release-20_build-rc.yml index a43c2b282a8d..d4c7055c37c5 100644 --- a/.github/workflows/release-build-rc.yml +++ b/.github/workflows/release-20_build-rc.yml @@ -11,10 +11,12 @@ on: - polkadot - polkadot-parachain - polkadot-omni-node + - frame-omni-bencher + - chain-spec-builder - all release_tag: - description: Tag matching the actual release candidate with the format stableYYMM-rcX or stableYYMM + description: Tag matching the actual release candidate with the format polkadot-stableYYMM(-X)-rcX or polkadot-stableYYMM(-X) type: string jobs: @@ -106,6 +108,50 @@ jobs: attestations: write contents: read + build-frame-omni-bencher-binary: + needs: [validate-inputs] + if: ${{ inputs.binary == 'frame-omni-bencher' || inputs.binary == 'all' }} + uses: "./.github/workflows/release-reusable-rc-buid.yml" + with: + binary: '["frame-omni-bencher"]' + package: "frame-omni-bencher" + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: x86_64-unknown-linux-gnu + secrets: + PGP_KMS_KEY: ${{ secrets.PGP_KMS_KEY }} + PGP_KMS_HASH: ${{ secrets.PGP_KMS_HASH }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + permissions: + id-token: write + attestations: write + contents: read + + build-chain-spec-builder-binary: + needs: [validate-inputs] + if: ${{ inputs.binary == 'chain-spec-builder' || inputs.binary == 'all' }} + uses: "./.github/workflows/release-reusable-rc-buid.yml" + with: + binary: '["chain-spec-builder"]' + package: staging-chain-spec-builder + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: x86_64-unknown-linux-gnu + secrets: + PGP_KMS_KEY: ${{ secrets.PGP_KMS_KEY }} + PGP_KMS_HASH: ${{ secrets.PGP_KMS_HASH }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + permissions: + id-token: write + attestations: write + contents: read + build-polkadot-macos-binary: needs: [validate-inputs] if: ${{ inputs.binary == 'polkadot' || inputs.binary == 'all' }} @@ -134,7 +180,7 @@ jobs: uses: "./.github/workflows/release-reusable-rc-buid.yml" with: binary: '["polkadot-parachain"]' - package: "polkadot-parachain-bin" + package: polkadot-parachain-bin release_tag: ${{ needs.validate-inputs.outputs.release_tag }} target: aarch64-apple-darwin secrets: @@ -156,7 +202,51 @@ jobs: uses: "./.github/workflows/release-reusable-rc-buid.yml" with: binary: '["polkadot-omni-node"]' - package: "polkadot-omni-node" + package: polkadot-omni-node + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: aarch64-apple-darwin + secrets: + PGP_KMS_KEY: ${{ secrets.PGP_KMS_KEY }} + PGP_KMS_HASH: ${{ secrets.PGP_KMS_HASH }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + permissions: + id-token: write + attestations: write + contents: read + + build-frame-omni-bencher-macos-binary: + needs: [validate-inputs] + if: ${{ inputs.binary == 'frame-omni-bencher' || inputs.binary == 'all' }} + uses: "./.github/workflows/release-reusable-rc-buid.yml" + with: + binary: '["frame-omni-bencher"]' + package: frame-omni-bencher + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: aarch64-apple-darwin + secrets: + PGP_KMS_KEY: ${{ secrets.PGP_KMS_KEY }} + PGP_KMS_HASH: ${{ secrets.PGP_KMS_HASH }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + permissions: + id-token: write + attestations: write + contents: read + + build-chain-spec-builder-macos-binary: + needs: [validate-inputs] + if: ${{ inputs.binary == 'chain-spec-builder' || inputs.binary == 'all' }} + uses: "./.github/workflows/release-reusable-rc-buid.yml" + with: + binary: '["chain-spec-builder"]' + package: staging-chain-spec-builder release_tag: ${{ needs.validate-inputs.outputs.release_tag }} target: aarch64-apple-darwin secrets: diff --git a/.github/workflows/release-30_publish_release_draft.yml b/.github/workflows/release-30_publish_release_draft.yml index 4364b4f80457..78ceea91f100 100644 --- a/.github/workflows/release-30_publish_release_draft.yml +++ b/.github/workflows/release-30_publish_release_draft.yml @@ -1,19 +1,46 @@ name: Release - Publish draft -on: - push: - tags: - # Catches v1.2.3 and v1.2.3-rc1 - - v[0-9]+.[0-9]+.[0-9]+* - # - polkadot-stable[0-9]+* Activate when the release process from release org is setteled +# This workflow runs in paritytech-release and creates full release draft with: +# - release notes +# - info about the runtimes +# - attached artifacts: +# - runtimes +# - binaries +# - signatures +on: workflow_dispatch: inputs: - version: - description: Current release/rc version + release_tag: + description: Tag matching the actual release candidate with the format polkadot-stableYYMM(-X)-rcX or polkadot-stableYYMM(-X) + required: true + type: string jobs: + check-synchronization: + uses: paritytech-release/sync-workflows/.github/workflows/check-syncronization.yml@main + + validate-inputs: + needs: [ check-synchronization ] + if: ${{ needs.check-synchronization.outputs.checks_passed }} == 'true' + runs-on: ubuntu-latest + outputs: + release_tag: ${{ steps.validate_inputs.outputs.release_tag }} + + steps: + - name: Checkout sources + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Validate inputs + id: validate_inputs + run: | + . ./.github/scripts/common/lib.sh + + RELEASE_TAG=$(validate_stable_tag ${{ inputs.release_tag }}) + echo "release_tag=${RELEASE_TAG}" >> $GITHUB_OUTPUT + get-rust-versions: + needs: [ validate-inputs ] runs-on: ubuntu-latest outputs: rustc-stable: ${{ steps.get-rust-versions.outputs.stable }} @@ -24,47 +51,28 @@ jobs: echo "stable=$RUST_STABLE_VERSION" >> $GITHUB_OUTPUT build-runtimes: + needs: [ validate-inputs ] uses: "./.github/workflows/release-srtool.yml" with: excluded_runtimes: "asset-hub-rococo bridge-hub-rococo contracts-rococo coretime-rococo people-rococo rococo rococo-parachain substrate-test bp cumulus-test kitchensink minimal-template parachain-template penpal polkadot-test seedling shell frame-try sp solochain-template polkadot-sdk-docs-first" build_opts: "--features on-chain-release-build" - - build-binaries: - runs-on: ubuntu-latest - strategy: - matrix: - # Tuples of [package, binary-name] - binary: [ [frame-omni-bencher, frame-omni-bencher], [staging-chain-spec-builder, chain-spec-builder] ] - steps: - - name: Checkout sources - uses: actions/checkout@6d193bf28034eafb982f37bd894289fe649468fc # v4.0.0 - - - name: Install protobuf-compiler - run: | - sudo apt update - sudo apt install -y protobuf-compiler - - - name: Build ${{ matrix.binary[1] }} binary - run: | - cargo build --locked --profile=production -p ${{ matrix.binary[0] }} --bin ${{ matrix.binary[1] }} - target/production/${{ matrix.binary[1] }} --version - - - name: Upload ${{ matrix.binary[1] }} binary - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 - with: - name: ${{ matrix.binary[1] }} - path: target/production/${{ matrix.binary[1] }} - + profile: production + permissions: + id-token: write + attestations: write + contents: read publish-release-draft: runs-on: ubuntu-latest - needs: [ get-rust-versions, build-runtimes ] + environment: release + needs: [ validate-inputs, get-rust-versions, build-runtimes ] outputs: release_url: ${{ steps.create-release.outputs.html_url }} asset_upload_url: ${{ steps.create-release.outputs.upload_url }} + steps: - name: Checkout - uses: actions/checkout@6d193bf28034eafb982f37bd894289fe649468fc # v4.0.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -87,20 +95,21 @@ jobs: GLUTTON_WESTEND_DIGEST: ${{ github.workspace}}/glutton-westend-runtime/glutton-westend-srtool-digest.json PEOPLE_WESTEND_DIGEST: ${{ github.workspace}}/people-westend-runtime/people-westend-srtool-digest.json WESTEND_DIGEST: ${{ github.workspace}}/westend-runtime/westend-srtool-digest.json + RELEASE_TAG: ${{ needs.validate-inputs.outputs.release_tag }} shell: bash run: | . ./.github/scripts/common/lib.sh export REF1=$(get_latest_release_tag) - if [[ -z "${{ inputs.version }}" ]]; then + if [[ -z "$RELEASE_TAG" ]]; then export REF2="${{ github.ref_name }}" echo "REF2: ${REF2}" else - export REF2="${{ inputs.version }}" + export REF2="$RELEASE_TAG" echo "REF2: ${REF2}" fi echo "REL_TAG=$REF2" >> $GITHUB_ENV - export VERSION=$(echo "$REF2" | sed -E 's/.*(stable[0-9]+).*$/\1/') + export VERSION=$(echo "$REF2" | sed -E 's/.*(stable[0-9]{4}(-[0-9]+)?).*$/\1/') ./scripts/release/build-changelogs.sh @@ -112,19 +121,29 @@ jobs: scripts/release/context.json **/*-srtool-digest.json + - name: Generate content write token for the release automation + id: generate_write_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.POLKADOT_SDK_RELEASE_RW_APP_ID }} + private-key: ${{ secrets.POLKADOT_SDK_RELEASE_RW_APP_KEY }} + owner: paritytech + repositories: polkadot-sdk + - name: Create draft release id: create-release - uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e # v1.1.4 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ env.REL_TAG }} - release_name: Polkadot ${{ env.REL_TAG }} - body_path: ${{ github.workspace}}/scripts/release/RELEASE_DRAFT.md - draft: true + GITHUB_TOKEN: ${{ steps.generate_write_token.outputs.token }} + run: | + gh release create ${{ env.REL_TAG }} \ + --repo paritytech/polkadot-sdk \ + --draft \ + --title "Polkadot ${{ env.REL_TAG }}" \ + --notes-file ${{ github.workspace}}/scripts/release/RELEASE_DRAFT.md publish-runtimes: - needs: [ build-runtimes, publish-release-draft ] + needs: [ validate-inputs, build-runtimes, publish-release-draft ] + environment: release continue-on-error: true runs-on: ubuntu-latest strategy: @@ -132,7 +151,7 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@6d193bf28034eafb982f37bd894289fe649468fc # v4.0.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Download artifacts uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 @@ -144,44 +163,83 @@ jobs: >>$GITHUB_ENV echo ASSET=$(find ${{ matrix.chain }}-runtime -name '*.compact.compressed.wasm') >>$GITHUB_ENV echo SPEC=$(<${JSON} jq -r .runtimes.compact.subwasm.core_version.specVersion) + - name: Generate content write token for the release automation + id: generate_write_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.POLKADOT_SDK_RELEASE_RW_APP_ID }} + private-key: ${{ secrets.POLKADOT_SDK_RELEASE_RW_APP_KEY }} + owner: paritytech + repositories: polkadot-sdk + - name: Upload compressed ${{ matrix.chain }} v${{ env.SPEC }} wasm - if: ${{ matrix.chain != 'rococo-parachain' }} - uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 #v1.0.2 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.publish-release-draft.outputs.asset_upload_url }} - asset_path: ${{ env.ASSET }} - asset_name: ${{ matrix.chain }}_runtime-v${{ env.SPEC }}.compact.compressed.wasm - asset_content_type: application/wasm + GITHUB_TOKEN: ${{ steps.generate_write_token.outputs.token }} + run: | + gh release upload ${{ needs.validate-inputs.outputs.release_tag }} \ + --repo paritytech/polkadot-sdk \ + '${{ env.ASSET }}#${{ matrix.chain }}_runtime-v${{ env.SPEC }}.compact.compressed.wasm' - publish-binaries: - needs: [ publish-release-draft, build-binaries ] + publish-release-artifacts: + needs: [ validate-inputs, publish-release-draft ] + environment: release continue-on-error: true runs-on: ubuntu-latest strategy: matrix: - binary: [frame-omni-bencher, chain-spec-builder] + binary: [ polkadot, polkadot-execute-worker, polkadot-prepare-worker, polkadot-parachain, polkadot-omni-node, frame-omni-bencher, chain-spec-builder ] + target: [ x86_64-unknown-linux-gnu, aarch64-apple-darwin ] steps: - - name: Download artifacts - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + - name: Checkout sources + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Fetch binaries from s3 based on version + run: | + . ./.github/scripts/common/lib.sh + + VERSION="${{ needs.validate-inputs.outputs.release_tag }}" + fetch_release_artifacts_from_s3 ${{ matrix.binary }} ${{ matrix.target }} + + - name: Rename aarch64-apple-darwin binaries + if: ${{ matrix.target == 'aarch64-apple-darwin' }} + working-directory: ${{ github.workspace}}/release-artifacts/${{ matrix.target }}/${{ matrix.binary }} + run: | + mv ${{ matrix.binary }} ${{ matrix.binary }}-aarch64-apple-darwin + mv ${{ matrix.binary }}.asc ${{ matrix.binary }}-aarch64-apple-darwin.asc + mv ${{ matrix.binary }}.sha256 ${{ matrix.binary }}-aarch64-apple-darwin.sha256 + + - name: Generate content write token for the release automation + id: generate_write_token + uses: actions/create-github-app-token@v1 with: - name: ${{ matrix.binary }} + app-id: ${{ vars.POLKADOT_SDK_RELEASE_RW_APP_ID }} + private-key: ${{ secrets.POLKADOT_SDK_RELEASE_RW_APP_KEY }} + owner: paritytech + repositories: polkadot-sdk - - name: Upload ${{ matrix.binary }} binary - uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 #v1.0.2 + - name: Upload ${{ matrix.binary }} binary to release draft env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ needs.publish-release-draft.outputs.asset_upload_url }} - asset_path: ${{ github.workspace}}/${{ matrix.binary }} - asset_name: ${{ matrix.binary }} - asset_content_type: application/octet-stream + GITHUB_TOKEN: ${{ steps.generate_write_token.outputs.token }} + working-directory: ${{ github.workspace}}/release-artifacts/${{ matrix.target }}/${{ matrix.binary }} + run: | + if [[ ${{ matrix.target }} == "aarch64-apple-darwin" ]]; then + gh release upload ${{ needs.validate-inputs.outputs.release_tag }} \ + --repo paritytech/polkadot-sdk \ + ${{ matrix.binary }}-aarch64-apple-darwin \ + ${{ matrix.binary }}-aarch64-apple-darwin.asc \ + ${{ matrix.binary }}-aarch64-apple-darwin.sha256 + else + gh release upload ${{ needs.validate-inputs.outputs.release_tag }} \ + --repo paritytech/polkadot-sdk \ + ${{ matrix.binary }} \ + ${{ matrix.binary }}.asc \ + ${{ matrix.binary }}.sha256 + fi post_to_matrix: runs-on: ubuntu-latest - needs: publish-release-draft + needs: [ validate-inputs, publish-release-draft ] environment: release strategy: matrix: @@ -197,5 +255,5 @@ jobs: access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} server: m.parity.io message: | - **New version of polkadot tagged**: ${{ github.ref_name }}
- Draft release created: ${{ needs.publish-release-draft.outputs.release_url }} + **New version of polkadot tagged**: ${{ needs.validate-inputs.outputs.release_tag }}
+ And release draft is release created in [polkadot-sdk repo](https://github.com/paritytech/polkadot-sdk/releases) diff --git a/.github/workflows/release-50_publish-docker.yml b/.github/workflows/release-50_publish-docker.yml index 627e53bacd88..5c3c3a6e854d 100644 --- a/.github/workflows/release-50_publish-docker.yml +++ b/.github/workflows/release-50_publish-docker.yml @@ -4,10 +4,6 @@ name: Release - Publish Docker Image # It builds and published releases and rc candidates. on: - #TODO: activate automated run later - # release: - # types: - # - published workflow_dispatch: inputs: image_type: @@ -30,16 +26,6 @@ on: - polkadot-parachain - chain-spec-builder - release_id: - description: | - Release ID. - You can find it using the command: - curl -s \ - -H "Authorization: Bearer ${GITHUB_TOKEN}" https://api.github.com/repos/$OWNER/$REPO/releases | \ - jq '.[] | { name: .name, id: .id }' - required: true - type: number - registry: description: Container registry required: true @@ -55,7 +41,7 @@ on: default: parity version: - description: version to build/release + description: Version of the polkadot node release in format v1.16.0 or v1.16.0-rc1 default: v0.9.18 required: true @@ -78,11 +64,15 @@ env: IMAGE_TYPE: ${{ inputs.image_type }} jobs: + check-synchronization: + uses: paritytech-release/sync-workflows/.github/workflows/check-syncronization.yml@main + validate-inputs: + needs: [check-synchronization] + if: ${{ needs.check-synchronization.outputs.checks_passed }} == 'true' runs-on: ubuntu-latest outputs: version: ${{ steps.validate_inputs.outputs.VERSION }} - release_id: ${{ steps.validate_inputs.outputs.RELEASE_ID }} stable_tag: ${{ steps.validate_inputs.outputs.stable_tag }} steps: @@ -97,11 +87,6 @@ jobs: VERSION=$(filter_version_from_input "${{ inputs.version }}") echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - RELEASE_ID=$(check_release_id "${{ inputs.release_id }}") - echo "RELEASE_ID=${RELEASE_ID}" >> $GITHUB_OUTPUT - - echo "Release ID: $RELEASE_ID" - STABLE_TAG=$(validate_stable_tag ${{ inputs.stable_tag }}) echo "stable_tag=${STABLE_TAG}" >> $GITHUB_OUTPUT @@ -114,50 +99,26 @@ jobs: - name: Checkout sources uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - #TODO: this step will be needed when automated triggering will work - #this step runs only if the workflow is triggered automatically when new release is published - # if: ${{ env.EVENT_NAME == 'release' && env.EVENT_ACTION != '' && env.EVENT_ACTION == 'published' }} - # run: | - # mkdir -p release-artifacts && cd release-artifacts - - # for f in $BINARY $BINARY.asc $BINARY.sha256; do - # URL="https://github.com/${{ github.event.repository.full_name }}/releases/download/${{ github.event.release.tag_name }}/$f" - # echo " - Fetching $f from $URL" - # wget "$URL" -O "$f" - # done - # chmod a+x $BINARY - # ls -al - - name: Fetch rc artifacts or release artifacts from s3 based on version - #this step runs only if the workflow is triggered manually - if: ${{ env.EVENT_NAME == 'workflow_dispatch' && inputs.binary != 'polkadot-omni-node' && inputs.binary != 'chain-spec-builder'}} + # if: ${{ env.EVENT_NAME == 'workflow_dispatch' && inputs.binary != 'polkadot-omni-node' && inputs.binary != 'chain-spec-builder'}} run: | . ./.github/scripts/common/lib.sh - VERSION="${{ needs.validate-inputs.outputs.VERSION }}" + VERSION="${{ needs.validate-inputs.outputs.stable_tag }}" if [[ ${{ inputs.binary }} == 'polkadot' ]]; then bins=(polkadot polkadot-prepare-worker polkadot-execute-worker) for bin in "${bins[@]}"; do - fetch_release_artifacts_from_s3 $bin + fetch_release_artifacts_from_s3 $bin x86_64-unknown-linux-gnu done else - fetch_release_artifacts_from_s3 $BINARY + fetch_release_artifacts_from_s3 $BINARY x86_64-unknown-linux-gnu fi - - name: Fetch polkadot-omni-node/chain-spec-builder rc artifacts or release artifacts based on release id - #this step runs only if the workflow is triggered manually and only for chain-spec-builder - if: ${{ env.EVENT_NAME == 'workflow_dispatch' && (inputs.binary == 'polkadot-omni-node' || inputs.binary == 'chain-spec-builder') }} - run: | - . ./.github/scripts/common/lib.sh - - RELEASE_ID="${{ needs.validate-inputs.outputs.RELEASE_ID }}" - fetch_release_artifacts - - name: Upload artifacts uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: release-artifacts - path: release-artifacts/${{ env.BINARY }}/**/* + path: release-artifacts/x86_64-unknown-linux-gnu/${{ env.BINARY }}/**/* build-container: # this job will be triggered for the polkadot-parachain rc and release or polkadot rc image build if: ${{ inputs.binary == 'polkadot-omni-node' || inputs.binary == 'polkadot-parachain' || inputs.binary == 'chain-spec-builder' || inputs.image_type == 'rc' }} @@ -173,7 +134,7 @@ jobs: uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 - name: Check sha256 ${{ env.BINARY }} - if: ${{ inputs.binary == 'polkadot-parachain' || inputs.binary == 'polkadot' }} + # if: ${{ inputs.binary == 'polkadot-parachain' || inputs.binary == 'polkadot' }} working-directory: release-artifacts run: | . ../.github/scripts/common/lib.sh @@ -182,7 +143,7 @@ jobs: check_sha256 $BINARY && echo "OK" || echo "ERR" - name: Check GPG ${{ env.BINARY }} - if: ${{ inputs.binary == 'polkadot-parachain' || inputs.binary == 'polkadot' }} + # if: ${{ inputs.binary == 'polkadot-parachain' || inputs.binary == 'polkadot' }} working-directory: release-artifacts run: | . ../.github/scripts/common/lib.sh @@ -190,35 +151,29 @@ jobs: check_gpg $BINARY - name: Fetch rc commit and tag + working-directory: release-artifacts if: ${{ env.IMAGE_TYPE == 'rc' }} id: fetch_rc_refs + shell: bash run: | - . ./.github/scripts/common/lib.sh - - echo "release=${{ needs.validate-inputs.outputs.stable_tag }}" >> $GITHUB_OUTPUT + . ../.github/scripts/common/lib.sh commit=$(git rev-parse --short HEAD) && \ echo "commit=${commit}" >> $GITHUB_OUTPUT - - echo "tag=${{ needs.validate-inputs.outputs.version }}" >> $GITHUB_OUTPUT + echo "release=$(echo ${{ needs.validate-inputs.outputs.version }})" >> $GITHUB_OUTPUT + echo "tag=$(prepare_docker_stable_tag ${{ needs.validate-inputs.outputs.stable_tag }})" >> $GITHUB_OUTPUT - name: Fetch release tags working-directory: release-artifacts if: ${{ env.IMAGE_TYPE == 'release'}} id: fetch_release_refs + shell: bash run: | - chmod a+rx $BINARY - - if [[ $BINARY != 'chain-spec-builder' ]]; then - VERSION=$(./$BINARY --version | awk '{ print $2 }' ) - release=$( echo $VERSION | cut -f1 -d- ) - else - release=$(echo ${{ needs.validate-inputs.outputs.VERSION }} | sed 's/^v//') - fi + . ../.github/scripts/common/lib.sh echo "tag=latest" >> $GITHUB_OUTPUT - echo "release=${release}" >> $GITHUB_OUTPUT - echo "stable=${{ needs.validate-inputs.outputs.stable_tag }}" >> $GITHUB_OUTPUT + echo "release=$(echo ${{ needs.validate-inputs.outputs.version }})" >> $GITHUB_OUTPUT + echo "stable=$(prepare_docker_stable_tag ${{ needs.validate-inputs.outputs.stable_tag }})" >> $GITHUB_OUTPUT - name: Build Injected Container image for polkadot rc if: ${{ env.BINARY == 'polkadot' }} @@ -342,8 +297,10 @@ jobs: - name: Fetch values id: fetch-data run: | + . ./.github/scripts/common/lib.sh date=$(date -u '+%Y-%m-%dT%H:%M:%SZ') echo "date=$date" >> $GITHUB_OUTPUT + echo "stable=$(prepare_docker_stable_tag ${{ needs.validate-inputs.outputs.stable_tag }})" >> $GITHUB_OUTPUT - name: Build and push id: docker_build @@ -354,9 +311,9 @@ jobs: # TODO: The owner should be used below but buildx does not resolve the VARs # TODO: It would be good to get rid of this GHA that we don't really need. tags: | - parity/polkadot:${{ needs.validate-inputs.outputs.stable_tag }} - parity/polkadot:latest - parity/polkadot:${{ needs.fetch-latest-debian-package-version.outputs.polkadot_container_tag }} + egorpop/polkadot:${{ steps.fetch-data.outputs.stable }} + egorpop/polkadot:latest + egorpop/polkadot:${{ needs.fetch-latest-debian-package-version.outputs.polkadot_container_tag }} build-args: | VCS_REF=${{ github.ref }} POLKADOT_VERSION=${{ needs.fetch-latest-debian-package-version.outputs.polkadot_apt_version }} diff --git a/.github/workflows/release-reusable-rc-buid.yml b/.github/workflows/release-reusable-rc-buid.yml index f5240878cba2..dc1b4553eb9b 100644 --- a/.github/workflows/release-reusable-rc-buid.yml +++ b/.github/workflows/release-reusable-rc-buid.yml @@ -302,7 +302,6 @@ jobs: AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} - upload-polkadot-parachain-artifacts-to-s3: if: ${{ inputs.package == 'polkadot-parachain-bin' && inputs.target == 'x86_64-unknown-linux-gnu' }} needs: [build-rc] @@ -329,6 +328,32 @@ jobs: AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + upload-frame-omni-bencher-artifacts-to-s3: + if: ${{ inputs.package == 'frame-omni-bencher' && inputs.target == 'x86_64-unknown-linux-gnu' }} + needs: [build-rc] + uses: ./.github/workflows/release-reusable-s3-upload.yml + with: + package: ${{ inputs.package }} + release_tag: ${{ inputs.release_tag }} + target: ${{ inputs.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + + upload-chain-spec-builder-artifacts-to-s3: + if: ${{ inputs.package == 'staging-chain-spec-builder' && inputs.target == 'x86_64-unknown-linux-gnu' }} + needs: [build-rc] + uses: ./.github/workflows/release-reusable-s3-upload.yml + with: + package: chain-spec-builder + release_tag: ${{ inputs.release_tag }} + target: ${{ inputs.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + upload-polkadot-macos-artifacts-to-s3: if: ${{ inputs.package == 'polkadot' && inputs.target == 'aarch64-apple-darwin' }} # TODO: add and use a `build-polkadot-homebrew-package` which packs all `polkadot` binaries: @@ -395,3 +420,29 @@ jobs: AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + + upload-frame-omni-bencher-macos-artifacts-to-s3: + if: ${{ inputs.package == 'frame-omni-bencher' && inputs.target == 'aarch64-apple-darwin' }} + needs: [build-macos-rc] + uses: ./.github/workflows/release-reusable-s3-upload.yml + with: + package: ${{ inputs.package }} + release_tag: ${{ inputs.release_tag }} + target: ${{ inputs.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + + upload-chain-spec-builder-macos-artifacts-to-s3: + if: ${{ inputs.package == 'staging-chain-spec-builder' && inputs.target == 'aarch64-apple-darwin' }} + needs: [build-macos-rc] + uses: ./.github/workflows/release-reusable-s3-upload.yml + with: + package: chain-spec-builder + release_tag: ${{ inputs.release_tag }} + target: ${{ inputs.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/release-srtool.yml b/.github/workflows/release-srtool.yml index 9a29b46d2fc3..fc10496d481b 100644 --- a/.github/workflows/release-srtool.yml +++ b/.github/workflows/release-srtool.yml @@ -1,7 +1,7 @@ name: Srtool build env: - SUBWASM_VERSION: 0.20.0 + SUBWASM_VERSION: 0.21.0 TOML_CLI_VERSION: 0.2.4 on: @@ -11,14 +11,16 @@ on: type: string build_opts: type: string + profile: + type: string outputs: published_runtimes: value: ${{ jobs.find-runtimes.outputs.runtime }} - schedule: - - cron: "00 02 * * 1" # 2AM weekly on monday - - workflow_dispatch: +permissions: + id-token: write + attestations: write + contents: read jobs: find-runtimes: @@ -75,6 +77,7 @@ jobs: with: chain: ${{ matrix.chain }} runtime_dir: ${{ matrix.runtime_dir }} + profile: ${{ inputs.profile }} - name: Summary run: | @@ -83,6 +86,11 @@ jobs: echo "Compact Runtime: ${{ steps.srtool_build.outputs.wasm }}" echo "Compressed Runtime: ${{ steps.srtool_build.outputs.wasm_compressed }}" + - name: Generate artifact attestation + uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3 + with: + subject-path: ${{ steps.srtool_build.outputs.wasm }} + # We now get extra information thanks to subwasm - name: Install subwasm run: | From 76a292b23bf6f35156fd3dd832e9c4ec31b24b2c Mon Sep 17 00:00:00 2001 From: Lulu Date: Tue, 3 Dec 2024 13:22:45 +0100 Subject: [PATCH 03/51] Update parity-publish (#6549) --- .github/workflows/check-semver.yml | 4 +- .github/workflows/publish-check-crates.yml | 2 +- .github/workflows/publish-claim-crates.yml | 2 +- .../snowbridge/runtime/test-common/Cargo.toml | 2 + cumulus/client/cli/Cargo.toml | 2 + cumulus/client/collator/Cargo.toml | 2 + cumulus/client/consensus/aura/Cargo.toml | 2 + cumulus/client/consensus/common/Cargo.toml | 2 + cumulus/client/consensus/proposer/Cargo.toml | 2 + .../client/consensus/relay-chain/Cargo.toml | 2 + cumulus/client/network/Cargo.toml | 2 + cumulus/client/parachain-inherent/Cargo.toml | 2 + cumulus/client/pov-recovery/Cargo.toml | 2 + .../Cargo.toml | 2 + .../client/relay-chain-interface/Cargo.toml | 2 + .../relay-chain-minimal-node/Cargo.toml | 2 + .../relay-chain-rpc-interface/Cargo.toml | 2 + cumulus/client/service/Cargo.toml | 2 + cumulus/pallets/aura-ext/Cargo.toml | 2 + cumulus/pallets/parachain-system/Cargo.toml | 2 + .../parachain-system/proc-macro/Cargo.toml | 2 + cumulus/pallets/solo-to-para/Cargo.toml | 2 + cumulus/pallets/xcm/Cargo.toml | 2 + cumulus/pallets/xcmp-queue/Cargo.toml | 2 + cumulus/parachains/common/Cargo.toml | 2 + .../emulated/common/Cargo.toml | 2 + .../pallets/collective-content/Cargo.toml | 2 + .../pallets/parachain-info/Cargo.toml | 2 + cumulus/parachains/pallets/ping/Cargo.toml | 2 + .../assets/asset-hub-rococo/Cargo.toml | 2 + .../assets/asset-hub-westend/Cargo.toml | 2 + .../runtimes/assets/common/Cargo.toml | 2 + .../runtimes/assets/test-utils/Cargo.toml | 2 + .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 2 + .../bridge-hubs/bridge-hub-westend/Cargo.toml | 2 + .../runtimes/bridge-hubs/common/Cargo.toml | 2 + .../bridge-hubs/test-utils/Cargo.toml | 2 + .../collectives-westend/Cargo.toml | 2 + .../parachains/runtimes/constants/Cargo.toml | 2 + .../contracts/contracts-rococo/Cargo.toml | 2 + .../coretime/coretime-rococo/Cargo.toml | 2 + .../coretime/coretime-westend/Cargo.toml | 2 + .../glutton/glutton-westend/Cargo.toml | 2 + .../runtimes/people/people-rococo/Cargo.toml | 2 + .../runtimes/people/people-westend/Cargo.toml | 2 + .../parachains/runtimes/test-utils/Cargo.toml | 2 + .../testing/rococo-parachain/Cargo.toml | 2 + cumulus/polkadot-omni-node/Cargo.toml | 2 + cumulus/polkadot-omni-node/lib/Cargo.toml | 2 + cumulus/polkadot-parachain/Cargo.toml | 2 + cumulus/primitives/aura/Cargo.toml | 2 + cumulus/primitives/core/Cargo.toml | 2 + .../primitives/parachain-inherent/Cargo.toml | 2 + .../proof-size-hostfunction/Cargo.toml | 2 + .../storage-weight-reclaim/Cargo.toml | 2 + cumulus/primitives/timestamp/Cargo.toml | 2 + cumulus/primitives/utility/Cargo.toml | 2 + cumulus/test/relay-sproof-builder/Cargo.toml | 2 + cumulus/xcm/xcm-emulator/Cargo.toml | 2 + polkadot/Cargo.toml | 2 + polkadot/cli/Cargo.toml | 2 + polkadot/core-primitives/Cargo.toml | 2 + polkadot/erasure-coding/Cargo.toml | 2 + polkadot/node/collation-generation/Cargo.toml | 2 + .../core/approval-voting-parallel/Cargo.toml | 2 + polkadot/node/core/approval-voting/Cargo.toml | 2 + polkadot/node/core/av-store/Cargo.toml | 2 + polkadot/node/core/backing/Cargo.toml | 2 + .../node/core/bitfield-signing/Cargo.toml | 2 + .../node/core/candidate-validation/Cargo.toml | 2 + polkadot/node/core/chain-api/Cargo.toml | 2 + polkadot/node/core/chain-selection/Cargo.toml | 2 + .../node/core/dispute-coordinator/Cargo.toml | 2 + .../node/core/parachains-inherent/Cargo.toml | 2 + .../core/prospective-parachains/Cargo.toml | 2 + polkadot/node/core/provisioner/Cargo.toml | 2 + polkadot/node/core/pvf-checker/Cargo.toml | 2 + polkadot/node/core/pvf/Cargo.toml | 2 + polkadot/node/core/pvf/common/Cargo.toml | 2 + .../node/core/pvf/execute-worker/Cargo.toml | 2 + .../node/core/pvf/prepare-worker/Cargo.toml | 2 + polkadot/node/core/runtime-api/Cargo.toml | 2 + polkadot/node/gum/Cargo.toml | 2 + polkadot/node/gum/proc-macro/Cargo.toml | 2 + polkadot/node/metrics/Cargo.toml | 2 + .../network/approval-distribution/Cargo.toml | 2 + .../availability-distribution/Cargo.toml | 2 + .../network/availability-recovery/Cargo.toml | 2 + .../network/bitfield-distribution/Cargo.toml | 2 + polkadot/node/network/bridge/Cargo.toml | 2 + .../node/network/collator-protocol/Cargo.toml | 2 + .../network/dispute-distribution/Cargo.toml | 2 + .../node/network/gossip-support/Cargo.toml | 2 + polkadot/node/network/protocol/Cargo.toml | 2 + .../network/statement-distribution/Cargo.toml | 2 + polkadot/node/overseer/Cargo.toml | 2 + polkadot/node/primitives/Cargo.toml | 2 + polkadot/node/service/Cargo.toml | 2 + polkadot/node/subsystem-types/Cargo.toml | 2 + polkadot/node/subsystem-util/Cargo.toml | 2 + polkadot/node/subsystem/Cargo.toml | 2 + polkadot/node/tracking-allocator/Cargo.toml | 2 + polkadot/parachain/Cargo.toml | 2 + polkadot/primitives/Cargo.toml | 2 + polkadot/rpc/Cargo.toml | 2 + polkadot/runtime/common/Cargo.toml | 2 + .../common/slot_range_helper/Cargo.toml | 2 + polkadot/runtime/metrics/Cargo.toml | 2 + polkadot/runtime/parachains/Cargo.toml | 2 + polkadot/runtime/rococo/Cargo.toml | 2 + polkadot/runtime/rococo/constants/Cargo.toml | 2 + polkadot/runtime/westend/Cargo.toml | 2 + polkadot/runtime/westend/constants/Cargo.toml | 2 + polkadot/statement-table/Cargo.toml | 2 + polkadot/utils/generate-bags/Cargo.toml | 2 + polkadot/xcm/Cargo.toml | 2 + polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml | 2 + polkadot/xcm/pallet-xcm/Cargo.toml | 2 + polkadot/xcm/procedural/Cargo.toml | 2 + polkadot/xcm/xcm-builder/Cargo.toml | 2 + polkadot/xcm/xcm-executor/Cargo.toml | 2 + polkadot/xcm/xcm-simulator/Cargo.toml | 2 + polkadot/xcm/xcm-simulator/example/Cargo.toml | 2 + prdoc/pr_6549.prdoc | 247 ++++++++++++++++++ scripts/generate-umbrella.py | 2 + substrate/frame/revive/fixtures/Cargo.toml | 2 + umbrella/Cargo.toml | 6 + 127 files changed, 501 insertions(+), 4 deletions(-) create mode 100644 prdoc/pr_6549.prdoc diff --git a/.github/workflows/check-semver.yml b/.github/workflows/check-semver.yml index 8d77b6a31b75..e9bedd16e6d1 100644 --- a/.github/workflows/check-semver.yml +++ b/.github/workflows/check-semver.yml @@ -11,7 +11,7 @@ concurrency: cancel-in-progress: true env: - TOOLCHAIN: nightly-2024-10-19 + TOOLCHAIN: nightly-2024-11-19 jobs: preflight: @@ -74,7 +74,7 @@ jobs: - name: install parity-publish # Set the target dir to cache the build. - run: CARGO_TARGET_DIR=./target/ cargo install parity-publish@0.10.1 --locked -q + run: CARGO_TARGET_DIR=./target/ cargo install parity-publish@0.10.2 --locked -q - name: check semver run: | diff --git a/.github/workflows/publish-check-crates.yml b/.github/workflows/publish-check-crates.yml index 3fad3b641474..1e5a8054e2c7 100644 --- a/.github/workflows/publish-check-crates.yml +++ b/.github/workflows/publish-check-crates.yml @@ -24,7 +24,7 @@ jobs: cache-on-failure: true - name: install parity-publish - run: cargo install parity-publish@0.8.0 --locked -q + run: cargo install parity-publish@0.10.2 --locked -q - name: parity-publish check run: parity-publish --color always check --allow-unpublished diff --git a/.github/workflows/publish-claim-crates.yml b/.github/workflows/publish-claim-crates.yml index 37bf06bb82d8..845b57a61b96 100644 --- a/.github/workflows/publish-claim-crates.yml +++ b/.github/workflows/publish-claim-crates.yml @@ -18,7 +18,7 @@ jobs: cache-on-failure: true - name: install parity-publish - run: cargo install parity-publish@0.8.0 --locked -q + run: cargo install parity-publish@0.10.2 --locked -q - name: parity-publish claim env: diff --git a/bridges/snowbridge/runtime/test-common/Cargo.toml b/bridges/snowbridge/runtime/test-common/Cargo.toml index 6f8e586bf5ff..9f47f158ed4a 100644 --- a/bridges/snowbridge/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/runtime/test-common/Cargo.toml @@ -6,6 +6,8 @@ authors = ["Snowfork "] edition.workspace = true license = "Apache-2.0" categories = ["cryptography::cryptocurrencies"] +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/cli/Cargo.toml b/cumulus/client/cli/Cargo.toml index 9b6f6b73960b..198f9428f1dd 100644 --- a/cumulus/client/cli/Cargo.toml +++ b/cumulus/client/cli/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Parachain node CLI utilities." license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/collator/Cargo.toml b/cumulus/client/collator/Cargo.toml index 6ebde0c2c653..83a3f2661e7a 100644 --- a/cumulus/client/collator/Cargo.toml +++ b/cumulus/client/collator/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Common node-side functionality and glue code to collate parachain blocks." license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/consensus/aura/Cargo.toml b/cumulus/client/consensus/aura/Cargo.toml index 0bb2de6bb9b8..6e0c124591cb 100644 --- a/cumulus/client/consensus/aura/Cargo.toml +++ b/cumulus/client/consensus/aura/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" authors.workspace = true edition.workspace = true license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/consensus/common/Cargo.toml b/cumulus/client/consensus/common/Cargo.toml index 4bc2f1d1e600..0f532a2101c4 100644 --- a/cumulus/client/consensus/common/Cargo.toml +++ b/cumulus/client/consensus/common/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" authors.workspace = true edition.workspace = true license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/consensus/proposer/Cargo.toml b/cumulus/client/consensus/proposer/Cargo.toml index bb760ae03f4d..e391481bc445 100644 --- a/cumulus/client/consensus/proposer/Cargo.toml +++ b/cumulus/client/consensus/proposer/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" authors.workspace = true edition.workspace = true license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/consensus/relay-chain/Cargo.toml b/cumulus/client/consensus/relay-chain/Cargo.toml index f3ee6fc2f7d2..7f0f4333c961 100644 --- a/cumulus/client/consensus/relay-chain/Cargo.toml +++ b/cumulus/client/consensus/relay-chain/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" authors.workspace = true edition.workspace = true license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/network/Cargo.toml b/cumulus/client/network/Cargo.toml index bc67678eedeb..b78df8d73eae 100644 --- a/cumulus/client/network/Cargo.toml +++ b/cumulus/client/network/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true description = "Cumulus-specific networking protocol" edition.workspace = true license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/parachain-inherent/Cargo.toml b/cumulus/client/parachain-inherent/Cargo.toml index 0d82cf648743..4f53e2bc1bc2 100644 --- a/cumulus/client/parachain-inherent/Cargo.toml +++ b/cumulus/client/parachain-inherent/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Inherent that needs to be present in every parachain block. Contains messages and a relay chain storage-proof." license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [dependencies] async-trait = { workspace = true } diff --git a/cumulus/client/pov-recovery/Cargo.toml b/cumulus/client/pov-recovery/Cargo.toml index 3127dd26fcaa..762837e0bb11 100644 --- a/cumulus/client/pov-recovery/Cargo.toml +++ b/cumulus/client/pov-recovery/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true description = "Parachain PoV recovery" edition.workspace = true license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/relay-chain-inprocess-interface/Cargo.toml b/cumulus/client/relay-chain-inprocess-interface/Cargo.toml index 6f1b74191be7..9e6e8da929bb 100644 --- a/cumulus/client/relay-chain-inprocess-interface/Cargo.toml +++ b/cumulus/client/relay-chain-inprocess-interface/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" edition.workspace = true description = "Implementation of the RelayChainInterface trait for Polkadot full-nodes." license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/relay-chain-interface/Cargo.toml b/cumulus/client/relay-chain-interface/Cargo.toml index a496fab050dd..2b9e72bbeca6 100644 --- a/cumulus/client/relay-chain-interface/Cargo.toml +++ b/cumulus/client/relay-chain-interface/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" edition.workspace = true description = "Common interface for different relay chain datasources." license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/relay-chain-minimal-node/Cargo.toml b/cumulus/client/relay-chain-minimal-node/Cargo.toml index 95ecadc8bd06..0fad188bb1ab 100644 --- a/cumulus/client/relay-chain-minimal-node/Cargo.toml +++ b/cumulus/client/relay-chain-minimal-node/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" edition.workspace = true description = "Minimal node implementation to be used in tandem with RPC or light-client mode." license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/relay-chain-rpc-interface/Cargo.toml b/cumulus/client/relay-chain-rpc-interface/Cargo.toml index fb4cb4ceed4e..162f5ad0e9e8 100644 --- a/cumulus/client/relay-chain-rpc-interface/Cargo.toml +++ b/cumulus/client/relay-chain-rpc-interface/Cargo.toml @@ -5,6 +5,8 @@ version = "0.7.0" edition.workspace = true description = "Implementation of the RelayChainInterface trait that connects to a remote RPC-node." license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/client/service/Cargo.toml b/cumulus/client/service/Cargo.toml index 0a77b465d96a..193283648f19 100644 --- a/cumulus/client/service/Cargo.toml +++ b/cumulus/client/service/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Common functions used to assemble the components of a parachain node." license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/pallets/aura-ext/Cargo.toml b/cumulus/pallets/aura-ext/Cargo.toml index c08148928b7c..fcda79f1d5c1 100644 --- a/cumulus/pallets/aura-ext/Cargo.toml +++ b/cumulus/pallets/aura-ext/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "AURA consensus extension pallet for parachains" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/pallets/parachain-system/Cargo.toml b/cumulus/pallets/parachain-system/Cargo.toml index 3cb0394c4b95..05498a474e42 100644 --- a/cumulus/pallets/parachain-system/Cargo.toml +++ b/cumulus/pallets/parachain-system/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Base pallet for cumulus-based parachains" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/pallets/parachain-system/proc-macro/Cargo.toml b/cumulus/pallets/parachain-system/proc-macro/Cargo.toml index da6f0fd03efb..629818f9c4cc 100644 --- a/cumulus/pallets/parachain-system/proc-macro/Cargo.toml +++ b/cumulus/pallets/parachain-system/proc-macro/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Proc macros provided by the parachain-system pallet" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/pallets/solo-to-para/Cargo.toml b/cumulus/pallets/solo-to-para/Cargo.toml index 5fd1939e93a0..2088361bf11a 100644 --- a/cumulus/pallets/solo-to-para/Cargo.toml +++ b/cumulus/pallets/solo-to-para/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Adds functionality to migrate from a Solo to a Parachain" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/pallets/xcm/Cargo.toml b/cumulus/pallets/xcm/Cargo.toml index 35d7a083b061..ff9be866d48f 100644 --- a/cumulus/pallets/xcm/Cargo.toml +++ b/cumulus/pallets/xcm/Cargo.toml @@ -5,6 +5,8 @@ name = "cumulus-pallet-xcm" version = "0.7.0" license = "Apache-2.0" description = "Pallet for stuff specific to parachains' usage of XCM" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/pallets/xcmp-queue/Cargo.toml b/cumulus/pallets/xcmp-queue/Cargo.toml index 9c7470eda6da..af70a3169d8e 100644 --- a/cumulus/pallets/xcmp-queue/Cargo.toml +++ b/cumulus/pallets/xcmp-queue/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Pallet to queue outbound and inbound XCMP messages." license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/common/Cargo.toml b/cumulus/parachains/common/Cargo.toml index 6d436bdf799a..641693a6a01b 100644 --- a/cumulus/parachains/common/Cargo.toml +++ b/cumulus/parachains/common/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Logic which is common to all parachain runtimes" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml index 23edaf6bfe65..8282d12d317f 100644 --- a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license = "Apache-2.0" description = "Common resources for integration testing with xcm-emulator" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/pallets/collective-content/Cargo.toml b/cumulus/parachains/pallets/collective-content/Cargo.toml index c52021f67e36..09301bd738f3 100644 --- a/cumulus/parachains/pallets/collective-content/Cargo.toml +++ b/cumulus/parachains/pallets/collective-content/Cargo.toml @@ -5,6 +5,8 @@ authors = ["Parity Technologies "] edition.workspace = true description = "Managed content" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/pallets/parachain-info/Cargo.toml b/cumulus/parachains/pallets/parachain-info/Cargo.toml index e0bed23c4f8c..604441c65f29 100644 --- a/cumulus/parachains/pallets/parachain-info/Cargo.toml +++ b/cumulus/parachains/pallets/parachain-info/Cargo.toml @@ -5,6 +5,8 @@ name = "staging-parachain-info" version = "0.7.0" license = "Apache-2.0" description = "Pallet to store the parachain ID" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/pallets/ping/Cargo.toml b/cumulus/parachains/pallets/ping/Cargo.toml index 51fc384a4f14..ceb38f39fd80 100644 --- a/cumulus/parachains/pallets/ping/Cargo.toml +++ b/cumulus/parachains/pallets/ping/Cargo.toml @@ -5,6 +5,8 @@ name = "cumulus-ping" version = "0.7.0" license = "Apache-2.0" description = "Ping Pallet for Cumulus XCM/UMP testing." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index bfe8ed869758..949640dd4be6 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Rococo variant of Asset Hub parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml index a3eaebb59153..8e47146a06c3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Westend variant of Asset Hub parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/assets/common/Cargo.toml b/cumulus/parachains/runtimes/assets/common/Cargo.toml index fb66f0de2322..fa9efbca7a39 100644 --- a/cumulus/parachains/runtimes/assets/common/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/common/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Assets common utilities" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml index f6b3c13e8102..393d06f95b15 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Test utils for Asset Hub runtimes." license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 3eb06e3a18c1..a7710783a1e0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Rococo's BridgeHub parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index 871bf44ec5b2..91900c830ba6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Westend's BridgeHub parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml index 9cb24a2b2820..76a89bcb2e72 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Bridge hub common utilities" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [dependencies] codec = { features = ["derive"], workspace = true } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml index 915b3090092f..16fef951f328 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Utils for BridgeHub testing" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml index 810abcf572d4..dc4b73db69e3 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license = "Apache-2.0" description = "Westend Collectives Parachain Runtime" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/constants/Cargo.toml b/cumulus/parachains/runtimes/constants/Cargo.toml index d54f1e7db6c1..01b023e0fb89 100644 --- a/cumulus/parachains/runtimes/constants/Cargo.toml +++ b/cumulus/parachains/runtimes/constants/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Common constants for Testnet Parachains runtimes" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml index c98ca7ba3e74..1aeff5eb2e48 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml @@ -5,6 +5,8 @@ description = "Parachain testnet runtime for FRAME Contracts pallet." authors.workspace = true edition.workspace = true license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml index 02807827cf92..ab621134b252 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Rococo's Coretime parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml index 34353d312b1f..44dfbf93c30e 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Westend's Coretime parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml b/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml index 09b4ef679d24..9bbdb8d2ee08 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license = "Apache-2.0" description = "Glutton parachain runtime." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml index a55143b62071..893133bf3c1a 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Rococo's People parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [build-dependencies] substrate-wasm-builder = { optional = true, workspace = true, default-features = true } diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml index 4d66332e96dd..66b324b51af4 100644 --- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Westend's People parachain runtime" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [build-dependencies] substrate-wasm-builder = { optional = true, workspace = true, default-features = true } diff --git a/cumulus/parachains/runtimes/test-utils/Cargo.toml b/cumulus/parachains/runtimes/test-utils/Cargo.toml index e9d666617ee2..17c81ae4921a 100644 --- a/cumulus/parachains/runtimes/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/test-utils/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Utils for Runtimes testing" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml index b0581c8d43ff..4713f4398eaa 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Simple runtime used by the rococo parachain(s)" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/polkadot-omni-node/Cargo.toml b/cumulus/polkadot-omni-node/Cargo.toml index a736e1ef80c5..8b46bc882868 100644 --- a/cumulus/polkadot-omni-node/Cargo.toml +++ b/cumulus/polkadot-omni-node/Cargo.toml @@ -6,6 +6,8 @@ edition.workspace = true build = "build.rs" description = "Generic binary that can run a parachain node with u32 block number and Aura consensus" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/polkadot-omni-node/lib/Cargo.toml b/cumulus/polkadot-omni-node/lib/Cargo.toml index a690229f1695..cca4ac3b2b69 100644 --- a/cumulus/polkadot-omni-node/lib/Cargo.toml +++ b/cumulus/polkadot-omni-node/lib/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Helper library that can be used to build a parachain node" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 5520126d0742..f5ce040bb530 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -6,6 +6,8 @@ edition.workspace = true build = "build.rs" description = "Runs a polkadot parachain node" license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/primitives/aura/Cargo.toml b/cumulus/primitives/aura/Cargo.toml index 185b2d40833f..715ce3e1a03e 100644 --- a/cumulus/primitives/aura/Cargo.toml +++ b/cumulus/primitives/aura/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license = "Apache-2.0" description = "Core primitives for Aura in Cumulus" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/primitives/core/Cargo.toml b/cumulus/primitives/core/Cargo.toml index 533d368d3b00..b5bfe4fbc889 100644 --- a/cumulus/primitives/core/Cargo.toml +++ b/cumulus/primitives/core/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license = "Apache-2.0" description = "Cumulus related core primitive types and traits" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/primitives/parachain-inherent/Cargo.toml b/cumulus/primitives/parachain-inherent/Cargo.toml index a4271d3fd9cc..2ff990b8d514 100644 --- a/cumulus/primitives/parachain-inherent/Cargo.toml +++ b/cumulus/primitives/parachain-inherent/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Inherent that needs to be present in every parachain block. Contains messages and a relay chain storage-proof." license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/primitives/proof-size-hostfunction/Cargo.toml b/cumulus/primitives/proof-size-hostfunction/Cargo.toml index e61c865d05fb..6e8168091892 100644 --- a/cumulus/primitives/proof-size-hostfunction/Cargo.toml +++ b/cumulus/primitives/proof-size-hostfunction/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Hostfunction exposing storage proof size to the runtime." license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/primitives/storage-weight-reclaim/Cargo.toml b/cumulus/primitives/storage-weight-reclaim/Cargo.toml index e1ae6743335a..3c358bc25edb 100644 --- a/cumulus/primitives/storage-weight-reclaim/Cargo.toml +++ b/cumulus/primitives/storage-weight-reclaim/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Utilities to reclaim storage weight." license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/primitives/timestamp/Cargo.toml b/cumulus/primitives/timestamp/Cargo.toml index cb328e2f2cc6..70cb3e607b98 100644 --- a/cumulus/primitives/timestamp/Cargo.toml +++ b/cumulus/primitives/timestamp/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true description = "Provides timestamp related functionality for parachains." license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/primitives/utility/Cargo.toml b/cumulus/primitives/utility/Cargo.toml index 2ca8b82001d5..1444571edbe0 100644 --- a/cumulus/primitives/utility/Cargo.toml +++ b/cumulus/primitives/utility/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license = "Apache-2.0" description = "Helper datatypes for Cumulus" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/test/relay-sproof-builder/Cargo.toml b/cumulus/test/relay-sproof-builder/Cargo.toml index e266b5807081..c1efa141a45d 100644 --- a/cumulus/test/relay-sproof-builder/Cargo.toml +++ b/cumulus/test/relay-sproof-builder/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license = "Apache-2.0" description = "Mocked relay state proof builder for testing Cumulus." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/cumulus/xcm/xcm-emulator/Cargo.toml b/cumulus/xcm/xcm-emulator/Cargo.toml index 8598481fae76..d0c637d64d01 100644 --- a/cumulus/xcm/xcm-emulator/Cargo.toml +++ b/cumulus/xcm/xcm-emulator/Cargo.toml @@ -5,6 +5,8 @@ version = "0.5.0" authors.workspace = true edition.workspace = true license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml index 3a939464868f..101caac0e313 100644 --- a/polkadot/Cargo.toml +++ b/polkadot/Cargo.toml @@ -20,6 +20,8 @@ authors.workspace = true edition.workspace = true version = "6.0.0" default-run = "polkadot" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index da37f6062c57..3eff525b7b1e 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/core-primitives/Cargo.toml b/polkadot/core-primitives/Cargo.toml index 42ca27953738..33869f216f78 100644 --- a/polkadot/core-primitives/Cargo.toml +++ b/polkadot/core-primitives/Cargo.toml @@ -5,6 +5,8 @@ description = "Core Polkadot types used by Relay Chains and parachains." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/erasure-coding/Cargo.toml b/polkadot/erasure-coding/Cargo.toml index 969742c5bb0a..528b955c4db3 100644 --- a/polkadot/erasure-coding/Cargo.toml +++ b/polkadot/erasure-coding/Cargo.toml @@ -5,6 +5,8 @@ description = "Erasure coding used for Polkadot's availability system" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/collation-generation/Cargo.toml b/polkadot/node/collation-generation/Cargo.toml index 777458673f5b..c1716e2e6eb8 100644 --- a/polkadot/node/collation-generation/Cargo.toml +++ b/polkadot/node/collation-generation/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Collator-side subsystem that handles incoming candidate submissions from the parachain." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/approval-voting-parallel/Cargo.toml b/polkadot/node/core/approval-voting-parallel/Cargo.toml index 3a98cce80e92..995687fb4c11 100644 --- a/polkadot/node/core/approval-voting-parallel/Cargo.toml +++ b/polkadot/node/core/approval-voting-parallel/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Approval Voting Subsystem running approval work in parallel" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/approval-voting/Cargo.toml b/polkadot/node/core/approval-voting/Cargo.toml index f9754d2babc9..80f5dcb7f318 100644 --- a/polkadot/node/core/approval-voting/Cargo.toml +++ b/polkadot/node/core/approval-voting/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Approval Voting Subsystem of the Polkadot node" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/av-store/Cargo.toml b/polkadot/node/core/av-store/Cargo.toml index 1d14e4cfba37..9f6864269cef 100644 --- a/polkadot/node/core/av-store/Cargo.toml +++ b/polkadot/node/core/av-store/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/backing/Cargo.toml b/polkadot/node/core/backing/Cargo.toml index cd1acf9daa93..a81fe9486c63 100644 --- a/polkadot/node/core/backing/Cargo.toml +++ b/polkadot/node/core/backing/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "The Candidate Backing Subsystem. Tracks parachain candidates that can be backed, as well as the issuance of statements about candidates." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/bitfield-signing/Cargo.toml b/polkadot/node/core/bitfield-signing/Cargo.toml index 126a18a14166..f00ba5712661 100644 --- a/polkadot/node/core/bitfield-signing/Cargo.toml +++ b/polkadot/node/core/bitfield-signing/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Bitfield signing subsystem for the Polkadot node" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/candidate-validation/Cargo.toml b/polkadot/node/core/candidate-validation/Cargo.toml index 87855dbce415..fea16b1c7604 100644 --- a/polkadot/node/core/candidate-validation/Cargo.toml +++ b/polkadot/node/core/candidate-validation/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/chain-api/Cargo.toml b/polkadot/node/core/chain-api/Cargo.toml index a8e911e0c5c9..0f443868dada 100644 --- a/polkadot/node/core/chain-api/Cargo.toml +++ b/polkadot/node/core/chain-api/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "The Chain API subsystem provides access to chain related utility functions like block number to hash conversions." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/chain-selection/Cargo.toml b/polkadot/node/core/chain-selection/Cargo.toml index 755d5cadeaaf..d2cc425a4816 100644 --- a/polkadot/node/core/chain-selection/Cargo.toml +++ b/polkadot/node/core/chain-selection/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/dispute-coordinator/Cargo.toml b/polkadot/node/core/dispute-coordinator/Cargo.toml index 344b66af1933..11b4ac645c23 100644 --- a/polkadot/node/core/dispute-coordinator/Cargo.toml +++ b/polkadot/node/core/dispute-coordinator/Cargo.toml @@ -5,6 +5,8 @@ description = "The node-side components that participate in disputes" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/parachains-inherent/Cargo.toml b/polkadot/node/core/parachains-inherent/Cargo.toml index 1e4953f40d0b..b1cd5e971b00 100644 --- a/polkadot/node/core/parachains-inherent/Cargo.toml +++ b/polkadot/node/core/parachains-inherent/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Parachains inherent data provider for Polkadot node" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/prospective-parachains/Cargo.toml b/polkadot/node/core/prospective-parachains/Cargo.toml index 5629e4ef7fbe..ced6c30c64b6 100644 --- a/polkadot/node/core/prospective-parachains/Cargo.toml +++ b/polkadot/node/core/prospective-parachains/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "The Prospective Parachains subsystem. Tracks and handles prospective parachain fragments." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/provisioner/Cargo.toml b/polkadot/node/core/provisioner/Cargo.toml index 64a598b420f7..26dca1adbc79 100644 --- a/polkadot/node/core/provisioner/Cargo.toml +++ b/polkadot/node/core/provisioner/Cargo.toml @@ -5,6 +5,8 @@ description = "Responsible for assembling a relay chain block from a set of avai authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/pvf-checker/Cargo.toml b/polkadot/node/core/pvf-checker/Cargo.toml index 73ef17a2843a..cb7e3eadcf0a 100644 --- a/polkadot/node/core/pvf-checker/Cargo.toml +++ b/polkadot/node/core/pvf-checker/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/pvf/Cargo.toml b/polkadot/node/core/pvf/Cargo.toml index 37d5878ea597..1b2a16ae8b55 100644 --- a/polkadot/node/core/pvf/Cargo.toml +++ b/polkadot/node/core/pvf/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml index 903c8dd1af29..d058d582fc26 100644 --- a/polkadot/node/core/pvf/common/Cargo.toml +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/pvf/execute-worker/Cargo.toml b/polkadot/node/core/pvf/execute-worker/Cargo.toml index 6ad340d25612..8327cf8058cd 100644 --- a/polkadot/node/core/pvf/execute-worker/Cargo.toml +++ b/polkadot/node/core/pvf/execute-worker/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/pvf/prepare-worker/Cargo.toml b/polkadot/node/core/pvf/prepare-worker/Cargo.toml index 56235bd82192..9dc800a8ef56 100644 --- a/polkadot/node/core/pvf/prepare-worker/Cargo.toml +++ b/polkadot/node/core/pvf/prepare-worker/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/core/runtime-api/Cargo.toml b/polkadot/node/core/runtime-api/Cargo.toml index 834e4b300b9e..15cbf4665d06 100644 --- a/polkadot/node/core/runtime-api/Cargo.toml +++ b/polkadot/node/core/runtime-api/Cargo.toml @@ -5,6 +5,8 @@ description = "Wrapper around the parachain-related runtime APIs" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/gum/Cargo.toml b/polkadot/node/gum/Cargo.toml index 9b2df435a06a..84875ea121b6 100644 --- a/polkadot/node/gum/Cargo.toml +++ b/polkadot/node/gum/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Stick logs together with the TraceID as provided by tempo" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/gum/proc-macro/Cargo.toml b/polkadot/node/gum/proc-macro/Cargo.toml index da6364977cae..b4a3401b15e4 100644 --- a/polkadot/node/gum/proc-macro/Cargo.toml +++ b/polkadot/node/gum/proc-macro/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Generate an overseer including builder pattern and message wrapper from a single annotated struct definition." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/metrics/Cargo.toml b/polkadot/node/metrics/Cargo.toml index 41b08b66e9b4..05344993a75e 100644 --- a/polkadot/node/metrics/Cargo.toml +++ b/polkadot/node/metrics/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/approval-distribution/Cargo.toml b/polkadot/node/network/approval-distribution/Cargo.toml index 8d674a733470..abf345552f89 100644 --- a/polkadot/node/network/approval-distribution/Cargo.toml +++ b/polkadot/node/network/approval-distribution/Cargo.toml @@ -5,6 +5,8 @@ description = "Polkadot Approval Distribution subsystem for the distribution of authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/availability-distribution/Cargo.toml b/polkadot/node/network/availability-distribution/Cargo.toml index 8c5574f244e4..e87103d99f72 100644 --- a/polkadot/node/network/availability-distribution/Cargo.toml +++ b/polkadot/node/network/availability-distribution/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/availability-recovery/Cargo.toml b/polkadot/node/network/availability-recovery/Cargo.toml index 41f09b1f7044..be4323e74f02 100644 --- a/polkadot/node/network/availability-recovery/Cargo.toml +++ b/polkadot/node/network/availability-recovery/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/bitfield-distribution/Cargo.toml b/polkadot/node/network/bitfield-distribution/Cargo.toml index 6d007255c574..2ff30489b6c1 100644 --- a/polkadot/node/network/bitfield-distribution/Cargo.toml +++ b/polkadot/node/network/bitfield-distribution/Cargo.toml @@ -5,6 +5,8 @@ description = "Polkadot Bitfiled Distribution subsystem, which gossips signed av authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/bridge/Cargo.toml b/polkadot/node/network/bridge/Cargo.toml index b4b5743853cd..c4b46c1dc001 100644 --- a/polkadot/node/network/bridge/Cargo.toml +++ b/polkadot/node/network/bridge/Cargo.toml @@ -5,6 +5,8 @@ description = "The Network Bridge Subsystem — protocol multiplexer for Polkado authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/collator-protocol/Cargo.toml b/polkadot/node/network/collator-protocol/Cargo.toml index 304cb23bb6aa..a51d24c70807 100644 --- a/polkadot/node/network/collator-protocol/Cargo.toml +++ b/polkadot/node/network/collator-protocol/Cargo.toml @@ -5,6 +5,8 @@ description = "Polkadot Collator Protocol subsystem. Allows collators and valida authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/dispute-distribution/Cargo.toml b/polkadot/node/network/dispute-distribution/Cargo.toml index b4dcafe09eb6..4f2f9ccadf8b 100644 --- a/polkadot/node/network/dispute-distribution/Cargo.toml +++ b/polkadot/node/network/dispute-distribution/Cargo.toml @@ -5,6 +5,8 @@ description = "Polkadot Dispute Distribution subsystem, which ensures all concer authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/gossip-support/Cargo.toml b/polkadot/node/network/gossip-support/Cargo.toml index c8c19e5de070..7d17ea45eab9 100644 --- a/polkadot/node/network/gossip-support/Cargo.toml +++ b/polkadot/node/network/gossip-support/Cargo.toml @@ -5,6 +5,8 @@ description = "Polkadot Gossip Support subsystem. Responsible for keeping track authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/protocol/Cargo.toml b/polkadot/node/network/protocol/Cargo.toml index 3d51d3c0a565..0bcf224332bc 100644 --- a/polkadot/node/network/protocol/Cargo.toml +++ b/polkadot/node/network/protocol/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Primitives types for the Node-side" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/network/statement-distribution/Cargo.toml b/polkadot/node/network/statement-distribution/Cargo.toml index de07937ffb0a..d737c7bf8968 100644 --- a/polkadot/node/network/statement-distribution/Cargo.toml +++ b/polkadot/node/network/statement-distribution/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/overseer/Cargo.toml b/polkadot/node/overseer/Cargo.toml index 2253a5ae0c66..62634c1da090 100644 --- a/polkadot/node/overseer/Cargo.toml +++ b/polkadot/node/overseer/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "System overseer of the Polkadot node" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/primitives/Cargo.toml b/polkadot/node/primitives/Cargo.toml index 7185205f905b..50ee3a80ddb8 100644 --- a/polkadot/node/primitives/Cargo.toml +++ b/polkadot/node/primitives/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml index 6e8eade21a43..7f58a56d5d16 100644 --- a/polkadot/node/service/Cargo.toml +++ b/polkadot/node/service/Cargo.toml @@ -6,6 +6,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Utils to tie different Polkadot components together and allow instantiation of a node." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/subsystem-types/Cargo.toml b/polkadot/node/subsystem-types/Cargo.toml index b5686ec96be1..44bb7036d63d 100644 --- a/polkadot/node/subsystem-types/Cargo.toml +++ b/polkadot/node/subsystem-types/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/subsystem-util/Cargo.toml b/polkadot/node/subsystem-util/Cargo.toml index d12daa572055..9c21fede1c47 100644 --- a/polkadot/node/subsystem-util/Cargo.toml +++ b/polkadot/node/subsystem-util/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/subsystem/Cargo.toml b/polkadot/node/subsystem/Cargo.toml index ce4bceec7336..4f30d3ce9c09 100644 --- a/polkadot/node/subsystem/Cargo.toml +++ b/polkadot/node/subsystem/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/node/tracking-allocator/Cargo.toml b/polkadot/node/tracking-allocator/Cargo.toml index d98377e53759..0fbf526ccb8b 100644 --- a/polkadot/node/tracking-allocator/Cargo.toml +++ b/polkadot/node/tracking-allocator/Cargo.toml @@ -5,6 +5,8 @@ version = "2.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/parachain/Cargo.toml b/polkadot/parachain/Cargo.toml index 9d0518fd46ad..ea6c4423dc19 100644 --- a/polkadot/parachain/Cargo.toml +++ b/polkadot/parachain/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true version = "6.0.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/primitives/Cargo.toml b/polkadot/primitives/Cargo.toml index dd269caa2d60..150aaf153fa7 100644 --- a/polkadot/primitives/Cargo.toml +++ b/polkadot/primitives/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Shared primitives used by Polkadot runtime" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/rpc/Cargo.toml b/polkadot/rpc/Cargo.toml index d01528d4dee0..48980dde4bbc 100644 --- a/polkadot/rpc/Cargo.toml +++ b/polkadot/rpc/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Polkadot specific RPC functionality." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index 01b56b31cf20..1646db54455a 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -5,6 +5,8 @@ description = "Pallets and constants used in Relay Chain networks." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/runtime/common/slot_range_helper/Cargo.toml b/polkadot/runtime/common/slot_range_helper/Cargo.toml index 02810b75283f..3f110bdd76c6 100644 --- a/polkadot/runtime/common/slot_range_helper/Cargo.toml +++ b/polkadot/runtime/common/slot_range_helper/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Helper crate for generating slot ranges for the Polkadot runtime." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/runtime/metrics/Cargo.toml b/polkadot/runtime/metrics/Cargo.toml index 3709e1eb697e..0415e4754009 100644 --- a/polkadot/runtime/metrics/Cargo.toml +++ b/polkadot/runtime/metrics/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Runtime metric interface for the Polkadot node" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index a3eec3f9d961..b01778eeb424 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -5,6 +5,8 @@ description = "Relay Chain runtime code responsible for Parachains." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index 3b11c977edf3..764c53abbfcb 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -6,6 +6,8 @@ description = "Rococo testnet Relay Chain runtime." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/runtime/rococo/constants/Cargo.toml b/polkadot/runtime/rococo/constants/Cargo.toml index 1d0adac44af4..921bc8f5fe92 100644 --- a/polkadot/runtime/rococo/constants/Cargo.toml +++ b/polkadot/runtime/rococo/constants/Cargo.toml @@ -5,6 +5,8 @@ description = "Constants used throughout the Rococo network." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [package.metadata.polkadot-sdk] exclude-from-umbrella = true diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index f94301baab09..584f5855b7a4 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -6,6 +6,8 @@ description = "Westend testnet Relay Chain runtime." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/runtime/westend/constants/Cargo.toml b/polkadot/runtime/westend/constants/Cargo.toml index 27d5b19b8e77..a50e2f9cc639 100644 --- a/polkadot/runtime/westend/constants/Cargo.toml +++ b/polkadot/runtime/westend/constants/Cargo.toml @@ -5,6 +5,8 @@ description = "Constants used throughout the Westend network." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [package.metadata.polkadot-sdk] exclude-from-umbrella = true diff --git a/polkadot/statement-table/Cargo.toml b/polkadot/statement-table/Cargo.toml index 53ea0b74463b..d9519dafe12d 100644 --- a/polkadot/statement-table/Cargo.toml +++ b/polkadot/statement-table/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Stores messages other authorities issue about candidates in Polkadot." +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml index 16205b0f51f5..3006d8325ef9 100644 --- a/polkadot/utils/generate-bags/Cargo.toml +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "CLI to generate voter bags for Polkadot runtimes" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index 86c7067ad6fa..113e72c27ae1 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml b/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml index b07bdfdca3d1..fe2b78163223 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml +++ b/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml @@ -5,6 +5,8 @@ edition.workspace = true license.workspace = true version = "7.0.0" description = "Benchmarks for the XCM pallet" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/pallet-xcm/Cargo.toml b/polkadot/xcm/pallet-xcm/Cargo.toml index 4d44d75e34dd..e8cdd3b4931b 100644 --- a/polkadot/xcm/pallet-xcm/Cargo.toml +++ b/polkadot/xcm/pallet-xcm/Cargo.toml @@ -5,6 +5,8 @@ description = "A pallet for handling XCM programs." authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/procedural/Cargo.toml b/polkadot/xcm/procedural/Cargo.toml index 83b35d19cf7e..3167766158ff 100644 --- a/polkadot/xcm/procedural/Cargo.toml +++ b/polkadot/xcm/procedural/Cargo.toml @@ -6,6 +6,8 @@ edition.workspace = true license.workspace = true version = "7.0.0" publish = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/xcm-builder/Cargo.toml b/polkadot/xcm/xcm-builder/Cargo.toml index eaa115740f3e..2819a0b0a555 100644 --- a/polkadot/xcm/xcm-builder/Cargo.toml +++ b/polkadot/xcm/xcm-builder/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true version = "7.0.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/xcm-executor/Cargo.toml b/polkadot/xcm/xcm-executor/Cargo.toml index cc966f91fe4d..20ca40de5faa 100644 --- a/polkadot/xcm/xcm-executor/Cargo.toml +++ b/polkadot/xcm/xcm-executor/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true version = "7.0.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/xcm-simulator/Cargo.toml b/polkadot/xcm/xcm-simulator/Cargo.toml index c7caa49393ed..47900e226d48 100644 --- a/polkadot/xcm/xcm-simulator/Cargo.toml +++ b/polkadot/xcm/xcm-simulator/Cargo.toml @@ -5,6 +5,8 @@ version = "7.0.0" authors.workspace = true edition.workspace = true license.workspace = true +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/polkadot/xcm/xcm-simulator/example/Cargo.toml b/polkadot/xcm/xcm-simulator/example/Cargo.toml index e0aff9b7782a..6fbe9243944a 100644 --- a/polkadot/xcm/xcm-simulator/example/Cargo.toml +++ b/polkadot/xcm/xcm-simulator/example/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true version = "7.0.0" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/prdoc/pr_6549.prdoc b/prdoc/pr_6549.prdoc new file mode 100644 index 000000000000..61a64c724185 --- /dev/null +++ b/prdoc/pr_6549.prdoc @@ -0,0 +1,247 @@ +doc: [] + +crates: + - name: polkadot-sdk + bump: none + - name: asset-test-utils + bump: none + - name: cumulus-pallet-parachain-system + bump: none + - name: cumulus-pallet-parachain-system-proc-macro + bump: none + - name: cumulus-primitives-core + bump: none + - name: polkadot-core-primitives + bump: none + - name: polkadot-parachain-primitives + bump: none + - name: polkadot-primitives + bump: none + - name: staging-xcm + bump: none + - name: xcm-procedural + bump: none + - name: cumulus-primitives-parachain-inherent + bump: none + - name: cumulus-primitives-proof-size-hostfunction + bump: none + - name: polkadot-runtime-common + bump: none + - name: polkadot-runtime-parachains + bump: none + - name: polkadot-runtime-metrics + bump: none + - name: staging-xcm-executor + bump: none + - name: slot-range-helper + bump: none + - name: staging-xcm-builder + bump: none + - name: pallet-xcm + bump: none + - name: cumulus-primitives-storage-weight-reclaim + bump: none + - name: cumulus-pallet-aura-ext + bump: none + - name: cumulus-primitives-aura + bump: none + - name: staging-parachain-info + bump: none + - name: cumulus-test-relay-sproof-builder + bump: none + - name: cumulus-client-cli + bump: none + - name: cumulus-client-collator + bump: none + - name: cumulus-client-consensus-common + bump: none + - name: cumulus-client-pov-recovery + bump: none + - name: cumulus-relay-chain-interface + bump: none + - name: polkadot-overseer + bump: none + - name: tracing-gum + bump: none + - name: tracing-gum-proc-macro + bump: none + - name: polkadot-node-metrics + bump: none + - name: polkadot-node-primitives + bump: none + - name: polkadot-erasure-coding + bump: none + - name: polkadot-node-subsystem + bump: none + - name: polkadot-node-subsystem-types + bump: none + - name: polkadot-node-network-protocol + bump: none + - name: polkadot-statement-table + bump: none + - name: polkadot-rpc + bump: none + - name: polkadot-service + bump: none + - name: cumulus-client-parachain-inherent + bump: none + - name: westend-runtime + bump: none + - name: pallet-xcm-benchmarks + bump: none + - name: westend-runtime-constants + bump: none + - name: polkadot-approval-distribution + bump: none + - name: polkadot-node-subsystem-util + bump: none + - name: polkadot-availability-bitfield-distribution + bump: none + - name: polkadot-availability-distribution + bump: none + - name: polkadot-availability-recovery + bump: none + - name: polkadot-node-core-approval-voting + bump: none + - name: polkadot-node-core-approval-voting-parallel + bump: none + - name: polkadot-node-core-av-store + bump: none + - name: polkadot-node-core-chain-api + bump: none + - name: polkadot-statement-distribution + bump: none + - name: polkadot-collator-protocol + bump: none + - name: polkadot-dispute-distribution + bump: none + - name: polkadot-gossip-support + bump: none + - name: polkadot-network-bridge + bump: none + - name: polkadot-node-collation-generation + bump: none + - name: polkadot-node-core-backing + bump: none + - name: polkadot-node-core-bitfield-signing + bump: none + - name: polkadot-node-core-candidate-validation + bump: none + - name: polkadot-node-core-pvf + bump: none + - name: polkadot-node-core-pvf-common + bump: none + - name: polkadot-node-core-pvf-execute-worker + bump: none + - name: polkadot-node-core-pvf-prepare-worker + bump: none + - name: staging-tracking-allocator + bump: none + - name: rococo-runtime + bump: none + - name: rococo-runtime-constants + bump: none + - name: polkadot-node-core-chain-selection + bump: none + - name: polkadot-node-core-dispute-coordinator + bump: none + - name: polkadot-node-core-parachains-inherent + bump: none + - name: polkadot-node-core-prospective-parachains + bump: none + - name: polkadot-node-core-provisioner + bump: none + - name: polkadot-node-core-pvf-checker + bump: none + - name: polkadot-node-core-runtime-api + bump: none + - name: cumulus-client-network + bump: none + - name: cumulus-relay-chain-inprocess-interface + bump: none + - name: polkadot-cli + bump: none + - name: cumulus-client-consensus-aura + bump: none + - name: cumulus-client-consensus-proposer + bump: none + - name: cumulus-client-consensus-relay-chain + bump: none + - name: cumulus-client-service + bump: none + - name: cumulus-relay-chain-minimal-node + bump: none + - name: cumulus-relay-chain-rpc-interface + bump: none + - name: parachains-common + bump: none + - name: cumulus-primitives-utility + bump: none + - name: cumulus-pallet-xcmp-queue + bump: none + - name: parachains-runtimes-test-utils + bump: none + - name: assets-common + bump: none + - name: bridge-hub-common + bump: none + - name: bridge-hub-test-utils + bump: none + - name: cumulus-pallet-solo-to-para + bump: none + - name: cumulus-pallet-xcm + bump: none + - name: cumulus-ping + bump: none + - name: cumulus-primitives-timestamp + bump: none + - name: emulated-integration-tests-common + bump: none + - name: xcm-emulator + bump: none + - name: pallet-collective-content + bump: none + - name: xcm-simulator + bump: none + - name: pallet-revive-fixtures + bump: none + - name: polkadot-omni-node-lib + bump: none + - name: snowbridge-runtime-test-common + bump: none + - name: testnet-parachains-constants + bump: none + - name: asset-hub-rococo-runtime + bump: none + - name: asset-hub-westend-runtime + bump: none + - name: bridge-hub-rococo-runtime + bump: none + - name: bridge-hub-westend-runtime + bump: none + - name: collectives-westend-runtime + bump: none + - name: coretime-rococo-runtime + bump: none + - name: coretime-westend-runtime + bump: none + - name: people-rococo-runtime + bump: none + - name: people-westend-runtime + bump: none + - name: contracts-rococo-runtime + bump: none + - name: glutton-westend-runtime + bump: none + - name: rococo-parachain-runtime + bump: none + - name: polkadot-omni-node + bump: none + - name: polkadot-parachain-bin + bump: none + - name: polkadot + bump: none + - name: polkadot-voter-bags + bump: none + - name: xcm-simulator-example + bump: none diff --git a/scripts/generate-umbrella.py b/scripts/generate-umbrella.py index 8326909c3449..ae3873180553 100644 --- a/scripts/generate-umbrella.py +++ b/scripts/generate-umbrella.py @@ -120,6 +120,8 @@ def main(path, version): "edition": { "workspace": True }, "authors": { "workspace": True }, "description": "Polkadot SDK umbrella crate.", + "homepage": { "workspace": True }, + "repository": { "workspace": True }, "license": "Apache-2.0", "metadata": { "docs": { "rs": { "features": ["runtime-full", "node"], diff --git a/substrate/frame/revive/fixtures/Cargo.toml b/substrate/frame/revive/fixtures/Cargo.toml index 798ed8c75a5a..9fd434db6179 100644 --- a/substrate/frame/revive/fixtures/Cargo.toml +++ b/substrate/frame/revive/fixtures/Cargo.toml @@ -5,6 +5,8 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Fixtures for testing and benchmarking" +homepage.workspace = true +repository.workspace = true [lints] workspace = true diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 7f50658c4e16..9affcffd2ade 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -617,6 +617,12 @@ workspace = true [package.authors] workspace = true +[package.homepage] +workspace = true + +[package.repository] +workspace = true + [dependencies.assets-common] path = "../cumulus/parachains/runtimes/assets/common" default-features = false From c56a98b991e2cdce7419813886a74d5280b66d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 3 Dec 2024 13:44:52 +0100 Subject: [PATCH 04/51] pallet-revive-fixtures: Try not to re-create fixture dir (#6735) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some systems trying to re-create the output directory will lead to an error. Fixes https://github.com/paritytech/subxt/issues/1876 --------- Co-authored-by: Bastian Köcher --- substrate/frame/revive/fixtures/build.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/substrate/frame/revive/fixtures/build.rs b/substrate/frame/revive/fixtures/build.rs index 46cd5760ca4e..eca547bc6ddd 100644 --- a/substrate/frame/revive/fixtures/build.rs +++ b/substrate/frame/revive/fixtures/build.rs @@ -204,10 +204,15 @@ fn create_out_dir() -> Result { .join("pallet-revive-fixtures"); // clean up some leftover symlink from previous versions of this script - if out_dir.exists() && !out_dir.is_dir() { + let mut out_exists = out_dir.exists(); + if out_exists && !out_dir.is_dir() { fs::remove_file(&out_dir)?; + out_exists = false; + } + + if !out_exists { + fs::create_dir(&out_dir).context("Failed to create output directory")?; } - fs::create_dir_all(&out_dir).context("Failed to create output directory")?; // write the location of the out dir so it can be found later let mut file = fs::File::create(temp_dir.join("fixture_location.rs")) From d1d92ab76004ce349a97fc5d325eaf9a4a7101b7 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Tue, 3 Dec 2024 13:45:35 +0100 Subject: [PATCH 05/51] Bump Westend AH (#6583) Bump Asset-Hub westend spec version --------- Co-authored-by: GitHub Action --- .../runtimes/assets/asset-hub-westend/src/lib.rs | 2 +- prdoc/pr_6583.prdoc | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 prdoc/pr_6583.prdoc diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 98d647d868db..21368e9c2b4b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -124,7 +124,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: alloc::borrow::Cow::Borrowed("westmint"), impl_name: alloc::borrow::Cow::Borrowed("westmint"), authoring_version: 1, - spec_version: 1_016_008, + spec_version: 1_017_002, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 16, diff --git a/prdoc/pr_6583.prdoc b/prdoc/pr_6583.prdoc new file mode 100644 index 000000000000..0e67ed33e27c --- /dev/null +++ b/prdoc/pr_6583.prdoc @@ -0,0 +1,7 @@ +title: Bump Westend AH +doc: +- audience: Runtime Dev + description: Bump Asset-Hub westend spec version +crates: +- name: asset-hub-westend-runtime + bump: minor From 896c81440c1dd169bd2f5e65aba46eca228609f8 Mon Sep 17 00:00:00 2001 From: Lulu Date: Tue, 3 Dec 2024 14:18:05 +0100 Subject: [PATCH 06/51] Add publish-check-compile workflow (#6556) Add publish-check-compile workflow This Applies staged prdocs then configures crate deps to pull from crates.io for our already published crates and local paths for things to be published. Then runs cargo check on the result. This results in a build state consitent with that of publish time and should catch compile errors that we would of otherwise ran into mid pubish. This acts as a supplement to the check-semver job. check-semver works on a high level and judges what changes are incorrect and why. This job just runs the change, sees if it compiles, and if not spits out a compile error. --- .github/workflows/publish-check-compile.yml | 48 +++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/publish-check-compile.yml diff --git a/.github/workflows/publish-check-compile.yml b/.github/workflows/publish-check-compile.yml new file mode 100644 index 000000000000..83cd3ff8fa90 --- /dev/null +++ b/.github/workflows/publish-check-compile.yml @@ -0,0 +1,48 @@ +name: Check publish build + +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + merge_group: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + preflight: + uses: ./.github/workflows/reusable-preflight.yml + + check-publish: + timeout-minutes: 90 + needs: [preflight] + runs-on: ${{ needs.preflight.outputs.RUNNER }} + container: + image: ${{ needs.preflight.outputs.IMAGE }} + steps: + - uses: actions/checkout@6d193bf28034eafb982f37bd894289fe649468fc # v4.1.7 + + - name: Rust Cache + uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5 + with: + cache-on-failure: true + + - name: install parity-publish + run: cargo install parity-publish@0.10.2 --locked -q + + - name: parity-publish update plan + run: parity-publish --color always plan --skip-check --prdoc prdoc/ + + - name: parity-publish apply plan + run: parity-publish --color always apply --registry + + - name: parity-publish check compile + run: | + packages="$(parity-publish apply --print)" + + if [ -n "$packages" ]; then + cargo --color always check $(printf -- '-p %s ' $packages) + fi From 41a5d8ec5f3d3d0ff82899be66113b223395ade5 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:02:03 +0100 Subject: [PATCH 07/51] `fatxpool`: handling limits and priorities improvements (#6405) This PR provides a number of improvements around handling limits and priorities in the fork-aware transaction pool. #### Notes to reviewers. #### Following are the notable changes: 1. #### [Better support](https://github.com/paritytech/polkadot-sdk/pull/6405/commits/414ec3ccad154c9a2aab0586bfa2d2c884fd140f) for `Usurped` transactions When any view reports an `Usurped` transaction (replaced by other with higher priority) it is removed from all the views (also inactive). Removal is implemented by simply submitting usurper transaction to all the views. It is also ensured that usurped tx will not sneak into the `view_store` in newly created view (this is why `ViewStore::pending_txs_replacements` was added). 1. #### [`TimedTransactionSource`](https://github.com/paritytech/polkadot-sdk/pull/6405/commits/f10590f3bde69b31250761a5b10802fb139ab2b2) introduced: Every view now has an information when the transaction entered the pool. Enforce limits (now only for future txs) uses this timestamp to find worst transactions. Having common timestamp ensures coherent assessment of the transaction's importance across different views. This also could later be used to select which ready transaction shall be dropped. 1. #### `DroppedWatcher`: [improved logic](https://github.com/paritytech/polkadot-sdk/pull/6405/commits/560db28c987dd1e634119788ebc8318967df206b) for future transactions For future transaction - if the last referencing view is removed, the transaction will be dropped from the pool. This prevents future unincluded and un-promoted transactions from staying in the pool for long time. #### And some minor changes: 1. [simplified](https://github.com/paritytech/polkadot-sdk/pull/6405/commits/2d0bbf83e2df2b4c641ef84c1188907c4bfad3c6) the flow in `update_view_with_mempool` (code duplication + minor bug fix). 2. `graph::BasePool`: [handling priorities](https://github.com/paritytech/polkadot-sdk/pull/6405/commits/c9f2d39355853d034fdbc6ea31e4e0e5bf34cb6a) for future transaction improved (previously transaction with lower prio was reported as failed), 3. `graph::listener`: dedicated `limit_enforced`/`usurped`/`dropped` [calls added](https://github.com/paritytech/polkadot-sdk/pull/6405/commits/7b58a68cccfcf372321ea41826fbe9d4222829cf), 4. flaky test [fixed](https://github.com/paritytech/polkadot-sdk/pull/6405/commits/e0a7bc6c048245943796839b166505e2aecdbd7d) 5. new tests added, related to: #5809 --------- Co-authored-by: GitHub Action Co-authored-by: Iulian Barbu <14218860+iulianbarbu@users.noreply.github.com> --- prdoc/pr_6405.prdoc | 9 + .../client/transaction-pool/benches/basics.rs | 4 +- .../src/fork_aware_txpool/dropped_watcher.rs | 291 +++++++++++++----- .../fork_aware_txpool/fork_aware_txpool.rs | 199 +++++++----- .../import_notification_sink.rs | 19 +- .../fork_aware_txpool/multi_view_listener.rs | 38 ++- .../fork_aware_txpool/revalidation_worker.rs | 9 +- .../src/fork_aware_txpool/tx_mem_pool.rs | 88 ++++-- .../src/fork_aware_txpool/view.rs | 31 +- .../src/fork_aware_txpool/view_store.rs | 262 ++++++++++++++-- .../transaction-pool/src/graph/base_pool.rs | 159 +++++++++- .../transaction-pool/src/graph/listener.rs | 47 ++- .../client/transaction-pool/src/graph/pool.rs | 30 +- .../transaction-pool/src/graph/ready.rs | 5 +- .../transaction-pool/src/graph/rotator.rs | 5 +- .../src/graph/validated_pool.rs | 27 +- .../transaction-pool/src/graph/watcher.rs | 6 + substrate/client/transaction-pool/src/lib.rs | 5 +- .../src/single_state_txpool/revalidation.rs | 25 +- .../single_state_txpool.rs | 46 ++- .../client/transaction-pool/tests/fatp.rs | 14 +- .../transaction-pool/tests/fatp_common/mod.rs | 14 + .../transaction-pool/tests/fatp_limits.rs | 189 ++++++++++++ .../transaction-pool/tests/fatp_prios.rs | 249 +++++++++++++++ .../client/transaction-pool/tests/pool.rs | 28 +- 25 files changed, 1420 insertions(+), 379 deletions(-) create mode 100644 prdoc/pr_6405.prdoc create mode 100644 substrate/client/transaction-pool/tests/fatp_prios.rs diff --git a/prdoc/pr_6405.prdoc b/prdoc/pr_6405.prdoc new file mode 100644 index 000000000000..9e4e0b3c6c20 --- /dev/null +++ b/prdoc/pr_6405.prdoc @@ -0,0 +1,9 @@ +title: '`fatxpool`: handling limits and priorities improvements' +doc: +- audience: Node Dev + description: |- + This PR provides a number of improvements and fixes around handling limits and priorities in the fork-aware transaction pool. + +crates: +- name: sc-transaction-pool + bump: major diff --git a/substrate/client/transaction-pool/benches/basics.rs b/substrate/client/transaction-pool/benches/basics.rs index 0d8c1cbba9b4..5e40b0fb72d6 100644 --- a/substrate/client/transaction-pool/benches/basics.rs +++ b/substrate/client/transaction-pool/benches/basics.rs @@ -152,7 +152,7 @@ fn uxt(transfer: TransferData) -> Extrinsic { } fn bench_configured(pool: Pool, number: u64, api: Arc) { - let source = TransactionSource::External; + let source = TimedTransactionSource::new_external(false); let mut futures = Vec::new(); let mut tags = Vec::new(); let at = HashAndNumber { @@ -171,7 +171,7 @@ fn bench_configured(pool: Pool, number: u64, api: Arc) { tags.push(to_tag(nonce, AccountId::from_h256(H256::from_low_u64_be(1)))); - futures.push(pool.submit_one(&at, source, xt)); + futures.push(pool.submit_one(&at, source.clone(), xt)); } let res = block_on(futures::future::join_all(futures.into_iter())); diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/dropped_watcher.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/dropped_watcher.rs index ecae21395c91..7679e3b169d2 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/dropped_watcher.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/dropped_watcher.rs @@ -24,7 +24,7 @@ use crate::{ common::log_xt::log_xt_trace, fork_aware_txpool::stream_map_util::next_event, - graph::{BlockHash, ChainApi, ExtrinsicHash}, + graph::{self, BlockHash, ExtrinsicHash}, LOG_TARGET, }; use futures::stream::StreamExt; @@ -33,12 +33,44 @@ use sc_transaction_pool_api::TransactionStatus; use sc_utils::mpsc; use sp_runtime::traits::Block as BlockT; use std::{ - collections::{hash_map::Entry, HashMap, HashSet}, + collections::{ + hash_map::{Entry, OccupiedEntry}, + HashMap, HashSet, + }, fmt::{self, Debug, Formatter}, pin::Pin, }; use tokio_stream::StreamMap; +/// Represents a transaction that was removed from the transaction pool, including the reason of its +/// removal. +#[derive(Debug, PartialEq)] +pub struct DroppedTransaction { + /// Hash of the dropped extrinsic. + pub tx_hash: Hash, + /// Reason of the transaction being dropped. + pub reason: DroppedReason, +} + +impl DroppedTransaction { + fn new_usurped(tx_hash: Hash, by: Hash) -> Self { + Self { reason: DroppedReason::Usurped(by), tx_hash } + } + + fn new_enforced_by_limts(tx_hash: Hash) -> Self { + Self { reason: DroppedReason::LimitsEnforced, tx_hash } + } +} + +/// Provides reason of why transactions was dropped. +#[derive(Debug, PartialEq)] +pub enum DroppedReason { + /// Transaction was replaced by other transaction (e.g. because of higher priority). + Usurped(Hash), + /// Transaction was dropped because of internal pool limits being enforced. + LimitsEnforced, +} + /// Dropped-logic related event from the single view. pub type ViewStreamEvent = crate::graph::DroppedByLimitsEvent, BlockHash>; @@ -47,7 +79,8 @@ type ViewStream = Pin> + Se /// Stream of extrinsic hashes that were dropped by the views and have no references by existing /// views. -pub(crate) type StreamOfDropped = Pin> + Send>>; +pub(crate) type StreamOfDropped = + Pin>> + Send>>; /// A type alias for a sender used as the controller of the [`MultiViewDropWatcherContext`]. /// Used to send control commands from the [`MultiViewDroppedWatcherController`] to @@ -59,24 +92,24 @@ type Controller = mpsc::TracingUnboundedSender; type CommandReceiver = mpsc::TracingUnboundedReceiver; /// Commands to control the instance of dropped transactions stream [`StreamOfDropped`]. -enum Command +enum Command where - C: ChainApi, + ChainApi: graph::ChainApi, { /// Adds a new stream of dropped-related events originating in a view with a specific block /// hash - AddView(BlockHash, ViewStream), + AddView(BlockHash, ViewStream), /// Removes an existing view's stream associated with a specific block hash. - RemoveView(BlockHash), - /// Removes internal states for given extrinsic hashes. + RemoveView(BlockHash), + /// Removes referencing views for given extrinsic hashes. /// /// Intended to ba called on finalization. - RemoveFinalizedTxs(Vec>), + RemoveFinalizedTxs(Vec>), } -impl Debug for Command +impl Debug for Command where - C: ChainApi, + ChainApi: graph::ChainApi, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { @@ -92,30 +125,114 @@ where /// /// This struct maintains a mapping of active views and their corresponding streams, as well as the /// state of each transaction with respect to these views. -struct MultiViewDropWatcherContext +struct MultiViewDropWatcherContext where - C: ChainApi, + ChainApi: graph::ChainApi, { /// A map that associates the views identified by corresponding block hashes with their streams /// of dropped-related events. This map is used to keep track of active views and their event /// streams. - stream_map: StreamMap, ViewStream>, + stream_map: StreamMap, ViewStream>, /// A receiver for commands to control the state of the stream, allowing the addition and /// removal of views. This is used to dynamically update which views are being tracked. - command_receiver: CommandReceiver>, - + command_receiver: CommandReceiver>, /// For each transaction hash we keep the set of hashes representing the views that see this - /// transaction as ready or future. + /// transaction as ready or in_block. + /// + /// Even if all views referencing a ready transactions are removed, we still want to keep + /// transaction, there can be a fork which sees the transaction as ready. /// /// Once transaction is dropped, dropping view is removed from the set. - transaction_states: HashMap, HashSet>>, + ready_transaction_views: HashMap, HashSet>>, + /// For each transaction hash we keep the set of hashes representing the views that see this + /// transaction as future. + /// + /// Once all views referencing a future transactions are removed, the future can be dropped. + /// + /// Once transaction is dropped, dropping view is removed from the set. + future_transaction_views: HashMap, HashSet>>, + + /// Transactions that need to be notified as dropped. + pending_dropped_transactions: Vec>, } impl MultiViewDropWatcherContext where - C: ChainApi + 'static, - <::Block as BlockT>::Hash: Unpin, + C: graph::ChainApi + 'static, + <::Block as BlockT>::Hash: Unpin, { + /// Provides the ready or future `HashSet` containing views referencing given transaction. + fn transaction_views( + &mut self, + tx_hash: ExtrinsicHash, + ) -> Option, HashSet>>> { + if let Entry::Occupied(views_keeping_tx_valid) = self.ready_transaction_views.entry(tx_hash) + { + return Some(views_keeping_tx_valid) + } + if let Entry::Occupied(views_keeping_tx_valid) = + self.future_transaction_views.entry(tx_hash) + { + return Some(views_keeping_tx_valid) + } + None + } + + /// Processes the command and updates internal state accordingly. + fn handle_command(&mut self, cmd: Command) { + match cmd { + Command::AddView(key, stream) => { + trace!( + target: LOG_TARGET, + "dropped_watcher: Command::AddView {key:?} views:{:?}", + self.stream_map.keys().collect::>() + ); + self.stream_map.insert(key, stream); + }, + Command::RemoveView(key) => { + trace!( + target: LOG_TARGET, + "dropped_watcher: Command::RemoveView {key:?} views:{:?}", + self.stream_map.keys().collect::>() + ); + self.stream_map.remove(&key); + self.ready_transaction_views.iter_mut().for_each(|(tx_hash, views)| { + trace!( + target: LOG_TARGET, + "[{:?}] dropped_watcher: Command::RemoveView ready views: {:?}", + tx_hash, + views + ); + views.remove(&key); + }); + + self.future_transaction_views.iter_mut().for_each(|(tx_hash, views)| { + trace!( + target: LOG_TARGET, + "[{:?}] dropped_watcher: Command::RemoveView future views: {:?}", + tx_hash, + views + ); + views.remove(&key); + if views.is_empty() { + self.pending_dropped_transactions.push(*tx_hash); + } + }); + }, + Command::RemoveFinalizedTxs(xts) => { + log_xt_trace!( + target: LOG_TARGET, + xts.clone(), + "[{:?}] dropped_watcher: finalized xt removed" + ); + xts.iter().for_each(|xt| { + self.ready_transaction_views.remove(xt); + self.future_transaction_views.remove(xt); + }); + }, + } + } + /// Processes a `ViewStreamEvent` from a specific view and updates the internal state /// accordingly. /// @@ -125,41 +242,69 @@ where &mut self, block_hash: BlockHash, event: ViewStreamEvent, - ) -> Option> { + ) -> Option>> { trace!( target: LOG_TARGET, - "dropped_watcher: handle_event: event:{:?} views:{:?}, ", - event, + "dropped_watcher: handle_event: event:{event:?} from:{block_hash:?} future_views:{:?} ready_views:{:?} stream_map views:{:?}, ", + self.future_transaction_views.get(&event.0), + self.ready_transaction_views.get(&event.0), self.stream_map.keys().collect::>(), ); let (tx_hash, status) = event; match status { - TransactionStatus::Ready | TransactionStatus::Future => { - self.transaction_states.entry(tx_hash).or_default().insert(block_hash); + TransactionStatus::Future => { + self.future_transaction_views.entry(tx_hash).or_default().insert(block_hash); + }, + TransactionStatus::Ready | TransactionStatus::InBlock(..) => { + // note: if future transaction was once seens as the ready we may want to treat it + // as ready transactions. Unreferenced future transactions are more likely to be + // removed when the last referencing view is removed then ready transactions. + // Transcaction seen as ready is likely quite close to be included in some + // future fork. + if let Some(mut views) = self.future_transaction_views.remove(&tx_hash) { + views.insert(block_hash); + self.ready_transaction_views.insert(tx_hash, views); + } else { + self.ready_transaction_views.entry(tx_hash).or_default().insert(block_hash); + } }, - TransactionStatus::Dropped | TransactionStatus::Usurped(_) => { - if let Entry::Occupied(mut views_keeping_tx_valid) = - self.transaction_states.entry(tx_hash) - { + TransactionStatus::Dropped => { + if let Some(mut views_keeping_tx_valid) = self.transaction_views(tx_hash) { views_keeping_tx_valid.get_mut().remove(&block_hash); - if views_keeping_tx_valid.get().is_empty() || - views_keeping_tx_valid - .get() - .iter() - .all(|h| !self.stream_map.contains_key(h)) - { - return Some(tx_hash) + if views_keeping_tx_valid.get().is_empty() { + return Some(DroppedTransaction::new_enforced_by_limts(tx_hash)) } } else { debug!("[{:?}] dropped_watcher: removing (non-tracked) tx", tx_hash); - return Some(tx_hash) + return Some(DroppedTransaction::new_enforced_by_limts(tx_hash)) } }, + TransactionStatus::Usurped(by) => + return Some(DroppedTransaction::new_usurped(tx_hash, by)), _ => {}, }; None } + /// Gets pending dropped transactions if any. + fn get_pending_dropped_transaction(&mut self) -> Option>> { + while let Some(tx_hash) = self.pending_dropped_transactions.pop() { + // never drop transaction that was seen as ready. It may not have a referencing + // view now, but such fork can appear. + if self.ready_transaction_views.get(&tx_hash).is_some() { + continue + } + + if let Some(views) = self.future_transaction_views.get(&tx_hash) { + if views.is_empty() { + self.future_transaction_views.remove(&tx_hash); + return Some(DroppedTransaction::new_enforced_by_limts(tx_hash)) + } + } + } + None + } + /// Creates a new `StreamOfDropped` and its associated event stream controller. /// /// This method initializes the internal structures and unfolds the stream of dropped @@ -176,42 +321,29 @@ where let ctx = Self { stream_map: StreamMap::new(), command_receiver, - transaction_states: Default::default(), + ready_transaction_views: Default::default(), + future_transaction_views: Default::default(), + pending_dropped_transactions: Default::default(), }; let stream_map = futures::stream::unfold(ctx, |mut ctx| async move { loop { + if let Some(dropped) = ctx.get_pending_dropped_transaction() { + debug!("dropped_watcher: sending out (pending): {dropped:?}"); + return Some((dropped, ctx)); + } tokio::select! { biased; - cmd = ctx.command_receiver.next() => { - match cmd? { - Command::AddView(key,stream) => { - trace!(target: LOG_TARGET,"dropped_watcher: Command::AddView {key:?} views:{:?}",ctx.stream_map.keys().collect::>()); - ctx.stream_map.insert(key,stream); - }, - Command::RemoveView(key) => { - trace!(target: LOG_TARGET,"dropped_watcher: Command::RemoveView {key:?} views:{:?}",ctx.stream_map.keys().collect::>()); - ctx.stream_map.remove(&key); - ctx.transaction_states.iter_mut().for_each(|(_,state)| { - state.remove(&key); - }); - }, - Command::RemoveFinalizedTxs(xts) => { - log_xt_trace!(target: LOG_TARGET, xts.clone(), "[{:?}] dropped_watcher: finalized xt removed"); - xts.iter().for_each(|xt| { - ctx.transaction_states.remove(xt); - }); - - }, - } - }, - Some(event) = next_event(&mut ctx.stream_map) => { if let Some(dropped) = ctx.handle_event(event.0, event.1) { debug!("dropped_watcher: sending out: {dropped:?}"); return Some((dropped, ctx)); } + }, + cmd = ctx.command_receiver.next() => { + ctx.handle_command(cmd?); } + } } }) @@ -225,30 +357,30 @@ where /// /// This struct provides methods to add and remove streams associated with views to and from the /// stream. -pub struct MultiViewDroppedWatcherController { +pub struct MultiViewDroppedWatcherController { /// A controller allowing to update the state of the associated [`StreamOfDropped`]. - controller: Controller>, + controller: Controller>, } -impl Clone for MultiViewDroppedWatcherController { +impl Clone for MultiViewDroppedWatcherController { fn clone(&self) -> Self { Self { controller: self.controller.clone() } } } -impl MultiViewDroppedWatcherController +impl MultiViewDroppedWatcherController where - C: ChainApi + 'static, - <::Block as BlockT>::Hash: Unpin, + ChainApi: graph::ChainApi + 'static, + <::Block as BlockT>::Hash: Unpin, { /// Creates new [`StreamOfDropped`] and its controller. - pub fn new() -> (MultiViewDroppedWatcherController, StreamOfDropped) { - let (stream_map, ctrl) = MultiViewDropWatcherContext::::event_stream(); + pub fn new() -> (MultiViewDroppedWatcherController, StreamOfDropped) { + let (stream_map, ctrl) = MultiViewDropWatcherContext::::event_stream(); (Self { controller: ctrl }, stream_map.boxed()) } /// Notifies the [`StreamOfDropped`] that new view was created. - pub fn add_view(&self, key: BlockHash, view: ViewStream) { + pub fn add_view(&self, key: BlockHash, view: ViewStream) { let _ = self.controller.unbounded_send(Command::AddView(key, view)).map_err(|e| { trace!(target: LOG_TARGET, "dropped_watcher: add_view {key:?} send message failed: {e}"); }); @@ -256,14 +388,17 @@ where /// Notifies the [`StreamOfDropped`] that the view was destroyed and shall be removed the /// stream map. - pub fn remove_view(&self, key: BlockHash) { + pub fn remove_view(&self, key: BlockHash) { let _ = self.controller.unbounded_send(Command::RemoveView(key)).map_err(|e| { trace!(target: LOG_TARGET, "dropped_watcher: remove_view {key:?} send message failed: {e}"); }); } /// Removes status info for finalized transactions. - pub fn remove_finalized_txs(&self, xts: impl IntoIterator> + Clone) { + pub fn remove_finalized_txs( + &self, + xts: impl IntoIterator> + Clone, + ) { let _ = self .controller .unbounded_send(Command::RemoveFinalizedTxs(xts.into_iter().collect())) @@ -298,7 +433,7 @@ mod dropped_watcher_tests { watcher.add_view(block_hash, view_stream); let handle = tokio::spawn(async move { output_stream.take(1).collect::>().await }); - assert_eq!(handle.await.unwrap(), vec![tx_hash]); + assert_eq!(handle.await.unwrap(), vec![DroppedTransaction::new_enforced_by_limts(tx_hash)]); } #[tokio::test] @@ -348,7 +483,10 @@ mod dropped_watcher_tests { watcher.add_view(block_hash0, view_stream0); watcher.add_view(block_hash1, view_stream1); let handle = tokio::spawn(async move { output_stream.take(1).collect::>().await }); - assert_eq!(handle.await.unwrap(), vec![tx_hash1]); + assert_eq!( + handle.await.unwrap(), + vec![DroppedTransaction::new_enforced_by_limts(tx_hash1)] + ); } #[tokio::test] @@ -373,10 +511,11 @@ mod dropped_watcher_tests { watcher.add_view(block_hash0, view_stream0); assert!(output_stream.next().now_or_never().is_none()); + watcher.remove_view(block_hash0); watcher.add_view(block_hash1, view_stream1); let handle = tokio::spawn(async move { output_stream.take(1).collect::>().await }); - assert_eq!(handle.await.unwrap(), vec![tx_hash]); + assert_eq!(handle.await.unwrap(), vec![DroppedTransaction::new_enforced_by_limts(tx_hash)]); } #[tokio::test] @@ -419,6 +558,6 @@ mod dropped_watcher_tests { let block_hash2 = H256::repeat_byte(0x03); watcher.add_view(block_hash2, view_stream2); let handle = tokio::spawn(async move { output_stream.take(1).collect::>().await }); - assert_eq!(handle.await.unwrap(), vec![tx_hash]); + assert_eq!(handle.await.unwrap(), vec![DroppedTransaction::new_enforced_by_limts(tx_hash)]); } } diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs index 065d0cb3a274..4ec87f1fefa4 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs @@ -23,7 +23,7 @@ use super::{ import_notification_sink::MultiViewImportNotificationSink, metrics::MetricsLink as PrometheusMetrics, multi_view_listener::MultiViewListener, - tx_mem_pool::{TxInMemPool, TxMemPool, TXMEMPOOL_TRANSACTION_LIMIT_MULTIPLIER}, + tx_mem_pool::{InsertionInfo, TxInMemPool, TxMemPool, TXMEMPOOL_TRANSACTION_LIMIT_MULTIPLIER}, view::View, view_store::ViewStore, }; @@ -31,8 +31,12 @@ use crate::{ api::FullChainApi, common::log_xt::log_xt_trace, enactment_state::{EnactmentAction, EnactmentState}, - fork_aware_txpool::revalidation_worker, - graph::{self, base_pool::Transaction, ExtrinsicFor, ExtrinsicHash, IsValidator, Options}, + fork_aware_txpool::{dropped_watcher::DroppedReason, revalidation_worker}, + graph::{ + self, + base_pool::{TimedTransactionSource, Transaction}, + ExtrinsicFor, ExtrinsicHash, IsValidator, Options, + }, ReadyIteratorFor, LOG_TARGET, }; use async_trait::async_trait; @@ -197,9 +201,14 @@ where let (dropped_stream_controller, dropped_stream) = MultiViewDroppedWatcherController::::new(); + + let view_store = + Arc::new(ViewStore::new(pool_api.clone(), listener, dropped_stream_controller)); + let dropped_monitor_task = Self::dropped_monitor_task( dropped_stream, mempool.clone(), + view_store.clone(), import_notification_sink.clone(), ); @@ -216,8 +225,8 @@ where ( Self { mempool, - api: pool_api.clone(), - view_store: Arc::new(ViewStore::new(pool_api, listener, dropped_stream_controller)), + api: pool_api, + view_store, ready_poll: Arc::from(Mutex::from(ReadyPoll::new())), enactment_state: Arc::new(Mutex::new(EnactmentState::new( best_block_hash, @@ -233,14 +242,17 @@ where ) } - /// Monitors the stream of dropped transactions and removes them from the mempool. + /// Monitors the stream of dropped transactions and removes them from the mempool and + /// view_store. /// /// This asynchronous task continuously listens for dropped transaction notifications provided /// within `dropped_stream` and ensures that these transactions are removed from the `mempool` - /// and `import_notification_sink` instances. + /// and `import_notification_sink` instances. For Usurped events, the transaction is also + /// removed from the view_store. async fn dropped_monitor_task( mut dropped_stream: StreamOfDropped, mempool: Arc>, + view_store: Arc>, import_notification_sink: MultiViewImportNotificationSink< Block::Hash, ExtrinsicHash, @@ -251,9 +263,33 @@ where log::debug!(target: LOG_TARGET, "fatp::dropped_monitor_task: terminated..."); break; }; - log::trace!(target: LOG_TARGET, "[{:?}] fatp::dropped notification, removing", dropped); - mempool.remove_dropped_transactions(&[dropped]).await; - import_notification_sink.clean_notified_items(&[dropped]); + let dropped_tx_hash = dropped.tx_hash; + log::trace!(target: LOG_TARGET, "[{:?}] fatp::dropped notification {:?}, removing", dropped_tx_hash,dropped.reason); + match dropped.reason { + DroppedReason::Usurped(new_tx_hash) => { + if let Some(new_tx) = mempool.get_by_hash(new_tx_hash) { + view_store + .replace_transaction( + new_tx.source(), + new_tx.tx(), + dropped_tx_hash, + new_tx.is_watched(), + ) + .await; + } else { + log::trace!( + target:LOG_TARGET, + "error: dropped_monitor_task: no entry in mempool for new transaction {:?}", + new_tx_hash, + ); + } + }, + DroppedReason::LimitsEnforced => {}, + }; + + mempool.remove_dropped_transaction(&dropped_tx_hash).await; + view_store.listener.transaction_dropped(dropped); + import_notification_sink.clean_notified_items(&[dropped_tx_hash]); } } @@ -288,9 +324,13 @@ where let (dropped_stream_controller, dropped_stream) = MultiViewDroppedWatcherController::::new(); + + let view_store = + Arc::new(ViewStore::new(pool_api.clone(), listener, dropped_stream_controller)); let dropped_monitor_task = Self::dropped_monitor_task( dropped_stream, mempool.clone(), + view_store.clone(), import_notification_sink.clone(), ); @@ -306,8 +346,8 @@ where Self { mempool, - api: pool_api.clone(), - view_store: Arc::new(ViewStore::new(pool_api, listener, dropped_stream_controller)), + api: pool_api, + view_store, ready_poll: Arc::from(Mutex::from(ReadyPoll::new())), enactment_state: Arc::new(Mutex::new(EnactmentState::new( best_block_hash, @@ -366,6 +406,16 @@ where self.mempool.unwatched_and_watched_count() } + /// Returns a set of future transactions for given block hash. + /// + /// Intended for logging / tests. + pub fn futures_at( + &self, + at: Block::Hash, + ) -> Option, ExtrinsicFor>>> { + self.view_store.futures_at(at) + } + /// Returns a best-effort set of ready transactions for a given block, without executing full /// maintain process. /// @@ -600,31 +650,33 @@ where let mempool_results = self.mempool.extend_unwatched(source, &xts); if view_store.is_empty() { - return Ok(mempool_results) + return Ok(mempool_results.into_iter().map(|r| r.map(|r| r.hash)).collect::>()) } let to_be_submitted = mempool_results .iter() .zip(xts) - .filter_map(|(result, xt)| result.as_ref().ok().map(|_| xt)) + .filter_map(|(result, xt)| { + result.as_ref().ok().map(|insertion| (insertion.source.clone(), xt)) + }) .collect::>(); self.metrics .report(|metrics| metrics.submitted_transactions.inc_by(to_be_submitted.len() as _)); let mempool = self.mempool.clone(); - let results_map = view_store.submit(source, to_be_submitted.into_iter()).await; + let results_map = view_store.submit(to_be_submitted.into_iter()).await; let mut submission_results = reduce_multiview_result(results_map).into_iter(); Ok(mempool_results .into_iter() .map(|result| { - result.and_then(|xt_hash| { + result.and_then(|insertion| { submission_results .next() .expect("The number of Ok results in mempool is exactly the same as the size of to-views-submission result. qed.") .inspect_err(|_| - mempool.remove(xt_hash) + mempool.remove(insertion.hash) ) }) }) @@ -660,19 +712,18 @@ where ) -> Result>>, Self::Error> { log::trace!(target: LOG_TARGET, "[{:?}] fatp::submit_and_watch views:{}", self.tx_hash(&xt), self.active_views_count()); let xt = Arc::from(xt); - let xt_hash = match self.mempool.push_watched(source, xt.clone()) { - Ok(xt_hash) => xt_hash, - Err(e) => return Err(e), - }; + let InsertionInfo { hash: xt_hash, source: timed_source } = + match self.mempool.push_watched(source, xt.clone()) { + Ok(result) => result, + Err(e) => return Err(e), + }; self.metrics.report(|metrics| metrics.submitted_transactions.inc()); - let view_store = self.view_store.clone(); - let mempool = self.mempool.clone(); - view_store - .submit_and_watch(at, source, xt) + self.view_store + .submit_and_watch(at, timed_source, xt) .await - .inspect_err(|_| mempool.remove(xt_hash)) + .inspect_err(|_| self.mempool.remove(xt_hash)) } /// Intended to remove transactions identified by the given hashes, and any dependent @@ -801,12 +852,12 @@ where ) -> Result { log::debug!(target: LOG_TARGET, "fatp::submit_local views:{}", self.active_views_count()); let xt = Arc::from(xt); - let result = self + let InsertionInfo { hash: xt_hash, .. } = self .mempool .extend_unwatched(TransactionSource::Local, &[xt.clone()]) .remove(0)?; - self.view_store.submit_local(xt).or_else(|_| Ok(result)) + self.view_store.submit_local(xt).or_else(|_| Ok(xt_hash)) } } @@ -914,6 +965,9 @@ where let start = Instant::now(); let watched_xts = self.register_listeners(&mut view).await; let duration = start.elapsed(); + // sync the transactions statuses and referencing views in all the listeners with newly + // cloned view. + view.pool.validated_pool().retrigger_notifications(); log::debug!(target: LOG_TARGET, "register_listeners: at {at:?} took {duration:?}"); // 2. Handle transactions from the tree route. Pruning transactions from the view first @@ -1041,58 +1095,35 @@ where self.active_views_count() ); let included_xts = self.extrinsics_included_since_finalized(view.at.hash).await; - let xts = self.mempool.clone_unwatched(); - - let mut all_submitted_count = 0; - if !xts.is_empty() { - let unwatched_count = xts.len(); - let mut buckets = HashMap::>>::default(); - xts.into_iter() - .filter(|(hash, _)| !view.pool.validated_pool().pool.read().is_imported(hash)) - .filter(|(hash, _)| !included_xts.contains(&hash)) - .map(|(_, tx)| (tx.source(), tx.tx())) - .for_each(|(source, tx)| buckets.entry(source).or_default().push(tx)); - - for (source, xts) in buckets { - all_submitted_count += xts.len(); - let _ = view.submit_many(source, xts).await; - } - log::debug!(target: LOG_TARGET, "update_view_with_mempool: at {:?} unwatched {}/{}", view.at.hash, all_submitted_count, unwatched_count); - } - - let watched_submitted_count = watched_xts.len(); - let mut buckets = HashMap::< - TransactionSource, - Vec<(ExtrinsicHash, ExtrinsicFor)>, - >::default(); - watched_xts + let (hashes, xts_filtered): (Vec<_>, Vec<_>) = watched_xts .into_iter() + .chain(self.mempool.clone_unwatched().into_iter()) + .filter(|(hash, _)| !view.is_imported(hash)) .filter(|(hash, _)| !included_xts.contains(&hash)) - .map(|(tx_hash, tx)| (tx.source(), tx_hash, tx.tx())) - .for_each(|(source, tx_hash, tx)| { - buckets.entry(source).or_default().push((tx_hash, tx)) - }); + .map(|(tx_hash, tx)| (tx_hash, (tx.source(), tx.tx()))) + .unzip(); - let mut watched_results = Vec::default(); - for (source, watched_xts) in buckets { - let hashes = watched_xts.iter().map(|i| i.0).collect::>(); - let results = view - .submit_many(source, watched_xts.into_iter().map(|i| i.1)) - .await - .into_iter() - .zip(hashes) - .map(|(result, tx_hash)| result.or_else(|_| Err(tx_hash))) - .collect::>(); - watched_results.extend(results); - } + let watched_results = view + .submit_many(xts_filtered) + .await + .into_iter() + .zip(hashes) + .map(|(result, tx_hash)| result.or_else(|_| Err(tx_hash))) + .collect::>(); + + let submitted_count = watched_results.len(); - log::debug!(target: LOG_TARGET, "update_view_with_mempool: at {:?} watched {}/{}", view.at.hash, watched_submitted_count, self.mempool_len().1); + log::debug!( + target: LOG_TARGET, + "update_view_with_mempool: at {:?} submitted {}/{}", + view.at.hash, + submitted_count, + self.mempool.len() + ); - all_submitted_count += watched_submitted_count; - let _ = all_submitted_count - .try_into() - .map(|v| self.metrics.report(|metrics| metrics.submitted_from_mempool_txs.inc_by(v))); + self.metrics + .report(|metrics| metrics.submitted_from_mempool_txs.inc_by(submitted_count as _)); // if there are no views yet, and a single newly created view is reporting error, just send // out the invalid event, and remove transaction. @@ -1176,7 +1207,14 @@ where }) .map(|(tx_hash, tx)| { //find arc if tx is known - self.mempool.get_by_hash(tx_hash).unwrap_or_else(|| Arc::from(tx)) + self.mempool + .get_by_hash(tx_hash) + .map(|tx| (tx.source(), tx.tx())) + .unwrap_or_else(|| { + // These transactions are coming from retracted blocks, we + // should simply consider them external. + (TimedTransactionSource::new_external(true), Arc::from(tx)) + }) }), ); @@ -1185,16 +1223,7 @@ where }); } - let _ = view - .pool - .resubmit_at( - &hash_and_number, - // These transactions are coming from retracted blocks, we should - // simply consider them external. - TransactionSource::External, - resubmit_transactions, - ) - .await; + let _ = view.pool.resubmit_at(&hash_and_number, resubmit_transactions).await; } } diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/import_notification_sink.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/import_notification_sink.rs index 7fbdcade63b8..f9a41673bb8f 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/import_notification_sink.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/import_notification_sink.rs @@ -326,6 +326,7 @@ mod tests { let j0 = tokio::spawn(runnable); let stream = ctrl.event_stream(); + let stream2 = ctrl.event_stream(); let mut v1 = View::new(vec![(10, 1), (10, 2), (10, 3)]); let mut v2 = View::new(vec![(20, 1), (20, 2), (20, 6)]); @@ -342,20 +343,16 @@ mod tests { ctrl.add_view(1000, o1); ctrl.add_view(2000, o2); - let j4 = { - let ctrl = ctrl.clone(); - tokio::spawn(async move { - tokio::time::sleep(Duration::from_millis(70)).await; - ctrl.clean_notified_items(&vec![1, 3]); - ctrl.add_view(3000, o3.boxed()); - }) - }; + let out = stream.take(4).collect::>().await; + assert_eq!(out, vec![1, 2, 3, 6]); - let out = stream.take(6).collect::>().await; + ctrl.clean_notified_items(&vec![1, 3]); + ctrl.add_view(3000, o3.boxed()); + let out = stream2.take(6).collect::>().await; assert_eq!(out, vec![1, 2, 3, 6, 1, 3]); - drop(ctrl); - futures::future::join_all(vec![j0, j1, j2, j3, j4]).await; + drop(ctrl); + futures::future::join_all(vec![j0, j1, j2, j3]).await; } #[tokio::test] diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/multi_view_listener.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/multi_view_listener.rs index 8d0e69db2e9a..a00234a99808 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/multi_view_listener.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/multi_view_listener.rs @@ -36,6 +36,8 @@ use std::{ }; use tokio_stream::StreamMap; +use super::dropped_watcher::{DroppedReason, DroppedTransaction}; + /// A side channel allowing to control the external stream instance (one per transaction) with /// [`ControllerCommand`]. /// @@ -79,7 +81,7 @@ enum ControllerCommand { /// Notifies that a transaction was dropped from the pool. /// /// If all preconditions are met, an external dropped event will be sent out. - TransactionDropped, + TransactionDropped(DroppedReason>), } impl std::fmt::Debug for ControllerCommand @@ -99,8 +101,8 @@ where ControllerCommand::TransactionBroadcasted(_) => { write!(f, "ListenerAction::TransactionBroadcasted(...)") }, - ControllerCommand::TransactionDropped => { - write!(f, "ListenerAction::TransactionDropped") + ControllerCommand::TransactionDropped(r) => { + write!(f, "ListenerAction::TransactionDropped {r:?}") }, } } @@ -268,6 +270,7 @@ where /// stream map. fn remove_view(&mut self, block_hash: BlockHash) { self.status_stream_map.remove(&block_hash); + self.views_keeping_tx_valid.remove(&block_hash); trace!(target: LOG_TARGET, "[{:?}] RemoveView view: {:?} views:{:?}", self.tx_hash, block_hash, self.status_stream_map.keys().collect::>()); } } @@ -282,6 +285,11 @@ where Self { controllers: Default::default() } } + /// Returns `true` if the listener contains a stream controller for the specified hash. + pub fn contains_tx(&self, tx_hash: &ExtrinsicHash) -> bool { + self.controllers.read().contains_key(tx_hash) + } + /// Creates an external aggregated stream of events for given transaction. /// /// This method initializes an `ExternalWatcherContext` for the provided transaction hash, sets @@ -346,11 +354,16 @@ where log::trace!(target: LOG_TARGET, "[{:?}] mvl sending out: Broadcasted", ctx.tx_hash); return Some((TransactionStatus::Broadcast(peers), ctx)) }, - ControllerCommand::TransactionDropped => { + ControllerCommand::TransactionDropped(DroppedReason::LimitsEnforced) => { log::trace!(target: LOG_TARGET, "[{:?}] mvl sending out: Dropped", ctx.tx_hash); ctx.terminate = true; return Some((TransactionStatus::Dropped, ctx)) }, + ControllerCommand::TransactionDropped(DroppedReason::Usurped(by)) => { + log::trace!(target: LOG_TARGET, "[{:?}] mvl sending out: Usurped({:?})", ctx.tx_hash, by); + ctx.terminate = true; + return Some((TransactionStatus::Usurped(by), ctx)) + }, } }, }; @@ -445,16 +458,15 @@ where /// /// This method sends a `TransactionDropped` command to the controller of each requested /// transaction prompting and external `Broadcasted` event. - pub(crate) fn transactions_dropped(&self, dropped: &[ExtrinsicHash]) { + pub(crate) fn transaction_dropped(&self, dropped: DroppedTransaction>) { let mut controllers = self.controllers.write(); - debug!(target: LOG_TARGET, "mvl::transactions_dropped: {:?}", dropped); - for tx_hash in dropped { - if let Some(tx) = controllers.remove(&tx_hash) { - debug!(target: LOG_TARGET, "[{:?}] transaction_dropped", tx_hash); - if let Err(e) = tx.unbounded_send(ControllerCommand::TransactionDropped) { - trace!(target: LOG_TARGET, "[{:?}] transactions_dropped: send message failed: {:?}", tx_hash, e); - }; - } + debug!(target: LOG_TARGET, "mvl::transaction_dropped: {:?}", dropped); + if let Some(tx) = controllers.remove(&dropped.tx_hash) { + let DroppedTransaction { tx_hash, reason } = dropped; + debug!(target: LOG_TARGET, "[{:?}] transaction_dropped", tx_hash); + if let Err(e) = tx.unbounded_send(ControllerCommand::TransactionDropped(reason)) { + trace!(target: LOG_TARGET, "[{:?}] transaction_dropped: send message failed: {:?}", tx_hash, e); + }; } } diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs index 9464ab3f5766..eb898c35a134 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs @@ -186,9 +186,9 @@ mod tests { use crate::{ common::tests::{uxt, TestApi}, fork_aware_txpool::view::FinishRevalidationLocalChannels, + TimedTransactionSource, }; use futures::executor::block_on; - use sc_transaction_pool_api::TransactionSource; use substrate_test_runtime::{AccountId, Transfer, H256}; use substrate_test_runtime_client::AccountKeyring::Alice; #[test] @@ -212,9 +212,10 @@ mod tests { nonce: 0, }); - let _ = block_on( - view.submit_many(TransactionSource::External, std::iter::once(uxt.clone().into())), - ); + let _ = block_on(view.submit_many(std::iter::once(( + TimedTransactionSource::new_external(false), + uxt.clone().into(), + )))); assert_eq!(api.validation_requests().len(), 1); let (finish_revalidation_request_tx, finish_revalidation_request_rx) = diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs index 86c07008c3f3..7b824d4653c2 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs @@ -30,7 +30,7 @@ use super::{metrics::MetricsLink as PrometheusMetrics, multi_view_listener::Mult use crate::{ common::log_xt::log_xt_trace, graph, - graph::{tracked_map::Size, ExtrinsicFor, ExtrinsicHash}, + graph::{base_pool::TimedTransactionSource, tracked_map::Size, ExtrinsicFor, ExtrinsicHash}, LOG_TARGET, }; use futures::FutureExt; @@ -74,7 +74,7 @@ where /// Size of the extrinsics actual body. bytes: usize, /// Transaction source. - source: TransactionSource, + source: TimedTransactionSource, /// When the transaction was revalidated, used to periodically revalidate the mem pool buffer. validated_at: AtomicU64, //todo: we need to add future / ready status at finalized block. @@ -95,18 +95,30 @@ where /// Shall the progress of transaction be watched. /// /// Was transaction sent with `submit_and_watch`. - fn is_watched(&self) -> bool { + pub(crate) fn is_watched(&self) -> bool { self.watched } /// Creates a new instance of wrapper for unwatched transaction. fn new_unwatched(source: TransactionSource, tx: ExtrinsicFor, bytes: usize) -> Self { - Self { watched: false, tx, source, validated_at: AtomicU64::new(0), bytes } + Self { + watched: false, + tx, + source: TimedTransactionSource::from_transaction_source(source, true), + validated_at: AtomicU64::new(0), + bytes, + } } /// Creates a new instance of wrapper for watched transaction. fn new_watched(source: TransactionSource, tx: ExtrinsicFor, bytes: usize) -> Self { - Self { watched: true, tx, source, validated_at: AtomicU64::new(0), bytes } + Self { + watched: true, + tx, + source: TimedTransactionSource::from_transaction_source(source, true), + validated_at: AtomicU64::new(0), + bytes, + } } /// Provides a clone of actual transaction body. @@ -117,8 +129,8 @@ where } /// Returns the source of the transaction. - pub(crate) fn source(&self) -> TransactionSource { - self.source + pub(crate) fn source(&self) -> TimedTransactionSource { + self.source.clone() } } @@ -174,6 +186,19 @@ where max_transactions_total_bytes: usize, } +/// Helper structure to encapsulate a result of [`TxMemPool::try_insert`]. +#[derive(Debug)] +pub(super) struct InsertionInfo { + pub(super) hash: Hash, + pub(super) source: TimedTransactionSource, +} + +impl InsertionInfo { + fn new(hash: Hash, source: TimedTransactionSource) -> Self { + Self { hash, source } + } +} + impl TxMemPool where Block: BlockT, @@ -220,8 +245,8 @@ where pub(super) fn get_by_hash( &self, hash: ExtrinsicHash, - ) -> Option> { - self.transactions.read().get(&hash).map(|t| t.tx()) + ) -> Option>> { + self.transactions.read().get(&hash).map(Clone::clone) } /// Returns a tuple with the count of unwatched and watched transactions in the memory pool. @@ -231,6 +256,11 @@ where (transactions.len() - watched_count, watched_count) } + /// Returns a total number of transactions kept within mempool. + pub fn len(&self) -> usize { + self.transactions.read().len() + } + /// Returns the number of bytes used by all extrinsics in the the pool. #[cfg(test)] pub fn bytes(&self) -> usize { @@ -249,7 +279,7 @@ where &self, hash: ExtrinsicHash, tx: TxInMemPool, - ) -> Result, ChainApi::Error> { + ) -> Result>, ChainApi::Error> { let bytes = self.transactions.bytes(); let mut transactions = self.transactions.write(); let result = match ( @@ -257,14 +287,15 @@ where transactions.contains_key(&hash), ) { (true, false) => { + let source = tx.source(); transactions.insert(hash, Arc::from(tx)); - Ok(hash) + Ok(InsertionInfo::new(hash, source)) }, (_, true) => Err(sc_transaction_pool_api::error::Error::AlreadyImported(Box::new(hash)).into()), (false, _) => Err(sc_transaction_pool_api::error::Error::ImmediatelyDropped.into()), }; - log::trace!(target: LOG_TARGET, "[{:?}] mempool::try_insert: {:?}", hash, result); + log::trace!(target: LOG_TARGET, "[{:?}] mempool::try_insert: {:?}", hash, result.as_ref().map(|r| r.hash)); result } @@ -277,7 +308,7 @@ where &self, source: TransactionSource, xts: &[ExtrinsicFor], - ) -> Vec, ChainApi::Error>> { + ) -> Vec>, ChainApi::Error>> { let result = xts .iter() .map(|xt| { @@ -294,25 +325,18 @@ where &self, source: TransactionSource, xt: ExtrinsicFor, - ) -> Result, ChainApi::Error> { + ) -> Result>, ChainApi::Error> { let (hash, length) = self.api.hash_and_length(&xt); self.try_insert(hash, TxInMemPool::new_watched(source, xt.clone(), length)) } - /// Removes transactions from the memory pool which are specified by the given list of hashes - /// and send the `Dropped` event to the listeners of these transactions. - pub(super) async fn remove_dropped_transactions( + /// Removes transaction from the memory pool which are specified by the given list of hashes. + pub(super) async fn remove_dropped_transaction( &self, - to_be_removed: &[ExtrinsicHash], - ) { - log::debug!(target: LOG_TARGET, "remove_dropped_transactions count:{:?}", to_be_removed.len()); - log_xt_trace!(target: LOG_TARGET, to_be_removed, "[{:?}] mempool::remove_dropped_transactions"); - let mut transactions = self.transactions.write(); - to_be_removed.iter().for_each(|t| { - transactions.remove(t); - }); - - self.listener.transactions_dropped(to_be_removed); + dropped: &ExtrinsicHash, + ) -> Option>> { + log::debug!(target: LOG_TARGET, "[{:?}] mempool::remove_dropped_transaction", dropped); + self.transactions.write().remove(dropped) } /// Clones and returns a `HashMap` of references to all unwatched transactions in the memory @@ -369,13 +393,13 @@ where }; let validations_futures = input.into_iter().map(|(xt_hash, xt)| { - self.api.validate_transaction(finalized_block.hash, xt.source, xt.tx()).map( - move |validation_result| { + self.api + .validate_transaction(finalized_block.hash, xt.source.clone().into(), xt.tx()) + .map(move |validation_result| { xt.validated_at .store(finalized_block.number.into().as_u64(), atomic::Ordering::Relaxed); (xt_hash, validation_result) - }, - ) + }) }); let validation_results = futures::future::join_all(validations_futures).await; let input_len = validation_results.len(); @@ -403,7 +427,7 @@ where log::debug!( target: LOG_TARGET, - "mempool::revalidate: at {finalized_block:?} count:{input_len}/{count} purged:{} took {duration:?}", invalid_hashes.len(), + "mempool::revalidate: at {finalized_block:?} count:{input_len}/{count} invalid_hashes:{} took {duration:?}", invalid_hashes.len(), ); invalid_hashes diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/view.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/view.rs index 99095d88cb0a..3cbb8fa4871d 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/view.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/view.rs @@ -27,13 +27,13 @@ use super::metrics::MetricsLink as PrometheusMetrics; use crate::{ common::log_xt::log_xt_trace, graph::{ - self, watcher::Watcher, ExtrinsicFor, ExtrinsicHash, IsValidator, ValidatedTransaction, - ValidatedTransactionFor, + self, base_pool::TimedTransactionSource, watcher::Watcher, ExtrinsicFor, ExtrinsicHash, + IsValidator, ValidatedTransaction, ValidatedTransactionFor, }, LOG_TARGET, }; use parking_lot::Mutex; -use sc_transaction_pool_api::{error::Error as TxPoolError, PoolStatus, TransactionSource}; +use sc_transaction_pool_api::{error::Error as TxPoolError, PoolStatus}; use sp_blockchain::HashAndNumber; use sp_runtime::{ generic::BlockId, traits::Block as BlockT, transaction_validity::TransactionValidityError, @@ -157,22 +157,21 @@ where /// Imports many unvalidated extrinsics into the view. pub(super) async fn submit_many( &self, - source: TransactionSource, - xts: impl IntoIterator>, + xts: impl IntoIterator)>, ) -> Vec, ChainApi::Error>> { if log::log_enabled!(target: LOG_TARGET, log::Level::Trace) { let xts = xts.into_iter().collect::>(); - log_xt_trace!(target: LOG_TARGET, xts.iter().map(|xt| self.pool.validated_pool().api().hash_and_length(xt).0), "[{:?}] view::submit_many at:{}", self.at.hash); - self.pool.submit_at(&self.at, source, xts).await + log_xt_trace!(target: LOG_TARGET, xts.iter().map(|(_,xt)| self.pool.validated_pool().api().hash_and_length(xt).0), "[{:?}] view::submit_many at:{}", self.at.hash); + self.pool.submit_at(&self.at, xts).await } else { - self.pool.submit_at(&self.at, source, xts).await + self.pool.submit_at(&self.at, xts).await } } /// Import a single extrinsic and starts to watch its progress in the view. pub(super) async fn submit_and_watch( &self, - source: TransactionSource, + source: TimedTransactionSource, xt: ExtrinsicFor, ) -> Result, ExtrinsicHash>, ChainApi::Error> { log::trace!(target: LOG_TARGET, "[{:?}] view::submit_and_watch at:{}", self.pool.validated_pool().api().hash_and_length(&xt).0, self.at.hash); @@ -193,7 +192,7 @@ where .api() .validate_transaction_blocking( self.at.hash, - TransactionSource::Local, + sc_transaction_pool_api::TransactionSource::Local, Arc::from(xt.clone()), )? .map_err(|e| { @@ -214,7 +213,7 @@ where let validated = ValidatedTransaction::valid_at( block_number.saturated_into::(), hash, - TransactionSource::Local, + TimedTransactionSource::new_local(true), Arc::from(xt), length, validity, @@ -285,7 +284,7 @@ where } _ = async { if let Some(tx) = batch_iter.next() { - let validation_result = (api.validate_transaction(self.at.hash, tx.source, tx.data.clone()).await, tx.hash, tx); + let validation_result = (api.validate_transaction(self.at.hash, tx.source.clone().into(), tx.data.clone()).await, tx.hash, tx); validation_results.push(validation_result); } else { self.revalidation_worker_channels.lock().as_mut().map(|ch| ch.remove_sender()); @@ -324,7 +323,7 @@ where ValidatedTransaction::valid_at( self.at.number.saturated_into::(), tx_hash, - tx.source, + tx.source.clone(), tx.data.clone(), api.hash_and_length(&tx.data).1, validity, @@ -455,4 +454,10 @@ where ); } } + + /// Returns true if the transaction with given hash is already imported into the view. + pub(super) fn is_imported(&self, tx_hash: &ExtrinsicHash) -> bool { + const IGNORE_BANNED: bool = false; + self.pool.validated_pool().check_is_known(tx_hash, IGNORE_BANNED).is_err() + } } diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/view_store.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/view_store.rs index f23dcedd5bfd..a06c051f0a7e 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/view_store.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/view_store.rs @@ -24,17 +24,51 @@ use super::{ }; use crate::{ fork_aware_txpool::dropped_watcher::MultiViewDroppedWatcherController, - graph, - graph::{base_pool::Transaction, ExtrinsicFor, ExtrinsicHash, TransactionFor}, + graph::{ + self, + base_pool::{TimedTransactionSource, Transaction}, + ExtrinsicFor, ExtrinsicHash, TransactionFor, + }, ReadyIteratorFor, LOG_TARGET, }; use futures::prelude::*; use itertools::Itertools; use parking_lot::RwLock; -use sc_transaction_pool_api::{error::Error as PoolError, PoolStatus, TransactionSource}; +use sc_transaction_pool_api::{error::Error as PoolError, PoolStatus}; use sp_blockchain::TreeRoute; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; -use std::{collections::HashMap, sync::Arc, time::Instant}; +use std::{ + collections::{hash_map::Entry, HashMap}, + sync::Arc, + time::Instant, +}; + +/// Helper struct to keep the context for transaction replacements. +#[derive(Clone)] +struct PendingTxReplacement +where + ChainApi: graph::ChainApi, +{ + /// Indicates if the new transaction was already submitted to all the views in the view_store. + /// If true, it can be removed after inserting any new view. + processed: bool, + /// New transaction replacing the old one. + xt: ExtrinsicFor, + /// Source of the transaction. + source: TimedTransactionSource, + /// Inidicates if transaction is watched. + watched: bool, +} + +impl PendingTxReplacement +where + ChainApi: graph::ChainApi, +{ + /// Creates new unprocessed instance of pending transaction replacement. + fn new(xt: ExtrinsicFor, source: TimedTransactionSource, watched: bool) -> Self { + Self { processed: false, xt, source, watched } + } +} /// The helper structure encapsulates all the views. pub(super) struct ViewStore @@ -62,6 +96,13 @@ where pub(super) most_recent_view: RwLock>, /// The controller of multi view dropped stream. pub(super) dropped_stream_controller: MultiViewDroppedWatcherController, + /// The map used to synchronize replacement of transactions between maintain and dropped + /// notifcication threads. It is meant to assure that replaced transaction is also removed from + /// newly built views in maintain process. + /// + /// The map's key is hash of replaced extrinsic. + pending_txs_replacements: + RwLock, PendingTxReplacement>>, } impl ViewStore @@ -83,14 +124,14 @@ where listener, most_recent_view: RwLock::from(None), dropped_stream_controller, + pending_txs_replacements: Default::default(), } } /// Imports a bunch of unverified extrinsics to every active view. pub(super) async fn submit( &self, - source: TransactionSource, - xts: impl IntoIterator> + Clone, + xts: impl IntoIterator)> + Clone, ) -> HashMap, ChainApi::Error>>> { let submit_futures = { let active_views = self.active_views.read(); @@ -99,7 +140,7 @@ where .map(|(_, view)| { let view = view.clone(); let xts = xts.clone(); - async move { (view.at.hash, view.submit_many(source, xts).await) } + async move { (view.at.hash, view.submit_many(xts).await) } }) .collect::>() }; @@ -145,7 +186,7 @@ where pub(super) async fn submit_and_watch( &self, _at: Block::Hash, - source: TransactionSource, + source: TimedTransactionSource, xt: ExtrinsicFor, ) -> Result, ChainApi::Error> { let tx_hash = self.api.hash_and_length(&xt).0; @@ -159,6 +200,7 @@ where .map(|(_, view)| { let view = view.clone(); let xt = xt.clone(); + let source = source.clone(); async move { match view.submit_and_watch(source, xt).await { Ok(watcher) => { @@ -261,12 +303,20 @@ where ) -> Vec, ExtrinsicFor>> { self.most_recent_view .read() - .map(|at| self.get_view_at(at, true)) + .map(|at| self.futures_at(at)) .flatten() - .map(|(v, _)| v.pool.validated_pool().pool.read().futures().cloned().collect()) .unwrap_or_default() } + /// Returns a list of future transactions in the view at given block hash. + pub(super) fn futures_at( + &self, + at: Block::Hash, + ) -> Option, ExtrinsicFor>>> { + self.get_view_at(at, true) + .map(|(v, _)| v.pool.validated_pool().pool.read().futures().cloned().collect()) + } + /// Collects all the transactions included in the blocks on the provided `tree_route` and /// triggers finalization event for them. /// @@ -329,12 +379,16 @@ where /// - moved to the inactive views set (`inactive_views`), /// - removed from the multi view listeners. /// - /// The `most_recent_view` is update with the reference to the newly inserted view. + /// The `most_recent_view` is updated with the reference to the newly inserted view. + /// + /// If there are any pending tx replacments, they are applied to the new view. pub(super) async fn insert_new_view( &self, view: Arc>, tree_route: &TreeRoute, ) { + self.apply_pending_tx_replacements(view.clone()).await; + //note: most_recent_view must be synced with changes in in/active_views. { let mut most_recent_view_lock = self.most_recent_view.write(); @@ -386,8 +440,10 @@ where let mut removed_views = vec![]; { - self.active_views - .read() + let active_views = self.active_views.read(); + let inactive_views = self.inactive_views.read(); + + active_views .iter() .filter(|(hash, v)| !match finalized_number { Err(_) | Ok(None) => **hash == finalized_hash, @@ -396,11 +452,8 @@ where }) .map(|(_, v)| removed_views.push(v.at.hash)) .for_each(drop); - } - { - self.inactive_views - .read() + inactive_views .iter() .filter(|(_, v)| !match finalized_number { Err(_) | Ok(None) => false, @@ -438,30 +491,48 @@ where let finalized_xts = self.finalize_route(finalized_hash, tree_route).await; let finalized_number = self.api.block_id_to_number(&BlockId::Hash(finalized_hash)); + let mut dropped_views = vec![]; //clean up older then finalized { let mut active_views = self.active_views.write(); - active_views.retain(|hash, v| match finalized_number { - Err(_) | Ok(None) => *hash == finalized_hash, - Ok(Some(n)) if v.at.number == n => *hash == finalized_hash, - Ok(Some(n)) => v.at.number > n, + let mut inactive_views = self.inactive_views.write(); + active_views.retain(|hash, v| { + let retain = match finalized_number { + Err(_) | Ok(None) => *hash == finalized_hash, + Ok(Some(n)) if v.at.number == n => *hash == finalized_hash, + Ok(Some(n)) => v.at.number > n, + }; + if !retain { + dropped_views.push(*hash); + } + retain }); - } - { - let mut inactive_views = self.inactive_views.write(); - inactive_views.retain(|_, v| match finalized_number { - Err(_) | Ok(None) => false, - Ok(Some(n)) => v.at.number >= n, + inactive_views.retain(|hash, v| { + let retain = match finalized_number { + Err(_) | Ok(None) => false, + Ok(Some(n)) => v.at.number >= n, + }; + if !retain { + dropped_views.push(*hash); + } + retain }); log::trace!(target:LOG_TARGET,"handle_finalized: inactive_views: {:?}", inactive_views.keys()); } - self.listener.remove_view(finalized_hash); + log::trace!(target:LOG_TARGET,"handle_finalized: dropped_views: {:?}", dropped_views); + self.listener.remove_stale_controllers(); self.dropped_stream_controller.remove_finalized_txs(finalized_xts.clone()); + self.listener.remove_view(finalized_hash); + for view in dropped_views { + self.listener.remove_view(view); + self.dropped_stream_controller.remove_view(view); + } + finalized_xts } @@ -484,4 +555,139 @@ where futures::future::join_all(finish_revalidation_futures).await; log::trace!(target:LOG_TARGET,"finish_background_revalidations took {:?}", start.elapsed()); } + + /// Replaces an existing transaction in the view_store with a new one. + /// + /// Attempts to replace a transaction identified by `replaced` with a new transaction `xt`. + /// + /// Before submitting a transaction to the views, the new *unprocessed* transaction replacement + /// record will be inserted into a pending replacement map. Once the submission to all the views + /// is accomplished, the record is marked as *processed*. + /// + /// This map is later applied in `insert_new_view` method executed from different thread. + /// + /// If the transaction is already being replaced, it will simply return without making + /// changes. + pub(super) async fn replace_transaction( + &self, + source: TimedTransactionSource, + xt: ExtrinsicFor, + replaced: ExtrinsicHash, + watched: bool, + ) { + if let Entry::Vacant(entry) = self.pending_txs_replacements.write().entry(replaced) { + entry.insert(PendingTxReplacement::new(xt.clone(), source.clone(), watched)); + } else { + return + }; + + let xt_hash = self.api.hash_and_length(&xt).0; + log::trace!(target:LOG_TARGET,"[{replaced:?}] replace_transaction wtih {xt_hash:?}, w:{watched}"); + + self.replace_transaction_in_views(source, xt, xt_hash, replaced, watched).await; + + if let Some(replacement) = self.pending_txs_replacements.write().get_mut(&replaced) { + replacement.processed = true; + } + } + + /// Applies pending transaction replacements to the specified view. + /// + /// After application, all already processed replacements are removed. + async fn apply_pending_tx_replacements(&self, view: Arc>) { + let mut futures = vec![]; + for replacement in self.pending_txs_replacements.read().values() { + let xt_hash = self.api.hash_and_length(&replacement.xt).0; + futures.push(self.replace_transaction_in_view( + view.clone(), + replacement.source.clone(), + replacement.xt.clone(), + xt_hash, + replacement.watched, + )); + } + let _results = futures::future::join_all(futures).await; + self.pending_txs_replacements.write().retain(|_, r| r.processed); + } + + /// Submits `xt` to the given view. + /// + /// For watched transaction stream is added to the listener. + async fn replace_transaction_in_view( + &self, + view: Arc>, + source: TimedTransactionSource, + xt: ExtrinsicFor, + xt_hash: ExtrinsicHash, + watched: bool, + ) { + if watched { + match view.submit_and_watch(source, xt).await { + Ok(watcher) => { + self.listener.add_view_watcher_for_tx( + xt_hash, + view.at.hash, + watcher.into_stream().boxed(), + ); + }, + Err(e) => { + log::trace!( + target:LOG_TARGET, + "[{:?}] replace_transaction: submit_and_watch to {} failed {}", + xt_hash, view.at.hash, e + ); + }, + } + } else { + if let Some(Err(e)) = view.submit_many(std::iter::once((source, xt))).await.pop() { + log::trace!( + target:LOG_TARGET, + "[{:?}] replace_transaction: submit to {} failed {}", + xt_hash, view.at.hash, e + ); + } + } + } + + /// Sends `xt` to every view (both active and inactive) containing `replaced` extrinsics. + /// + /// It is assumed that transaction is already known by the pool. Intended to ba called when `xt` + /// is replacing `replaced` extrinsic. + async fn replace_transaction_in_views( + &self, + source: TimedTransactionSource, + xt: ExtrinsicFor, + xt_hash: ExtrinsicHash, + replaced: ExtrinsicHash, + watched: bool, + ) { + if watched && !self.listener.contains_tx(&xt_hash) { + log::trace!( + target:LOG_TARGET, + "error: replace_transaction_in_views: no listener for watched transaction {:?}", + xt_hash, + ); + return; + } + + let submit_futures = { + let active_views = self.active_views.read(); + let inactive_views = self.inactive_views.read(); + active_views + .iter() + .chain(inactive_views.iter()) + .filter(|(_, view)| view.is_imported(&replaced)) + .map(|(_, view)| { + self.replace_transaction_in_view( + view.clone(), + source.clone(), + xt.clone(), + xt_hash, + watched, + ) + }) + .collect::>() + }; + let _results = futures::future::join_all(submit_futures).await; + } } diff --git a/substrate/client/transaction-pool/src/graph/base_pool.rs b/substrate/client/transaction-pool/src/graph/base_pool.rs index e4c3a6c425a9..04eaa998f42e 100644 --- a/substrate/client/transaction-pool/src/graph/base_pool.rs +++ b/substrate/client/transaction-pool/src/graph/base_pool.rs @@ -20,7 +20,7 @@ //! //! For a more full-featured pool, have a look at the `pool` module. -use std::{cmp::Ordering, collections::HashSet, fmt, hash, sync::Arc}; +use std::{cmp::Ordering, collections::HashSet, fmt, hash, sync::Arc, time::Instant}; use crate::LOG_TARGET; use log::{trace, warn}; @@ -30,8 +30,8 @@ use sp_core::hexdisplay::HexDisplay; use sp_runtime::{ traits::Member, transaction_validity::{ - TransactionLongevity as Longevity, TransactionPriority as Priority, - TransactionSource as Source, TransactionTag as Tag, + TransactionLongevity as Longevity, TransactionPriority as Priority, TransactionSource, + TransactionTag as Tag, }, }; @@ -83,6 +83,44 @@ pub struct PruneStatus { pub pruned: Vec>>, } +/// A transaction source that includes a timestamp indicating when the transaction was submitted. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct TimedTransactionSource { + /// The original source of the transaction. + pub source: TransactionSource, + + /// The time at which the transaction was submitted. + pub timestamp: Option, +} + +impl From for TransactionSource { + fn from(value: TimedTransactionSource) -> Self { + value.source + } +} + +impl TimedTransactionSource { + /// Creates a new instance with an internal `TransactionSource::InBlock` source and an optional + /// timestamp. + pub fn new_in_block(with_timestamp: bool) -> Self { + Self { source: TransactionSource::InBlock, timestamp: with_timestamp.then(Instant::now) } + } + /// Creates a new instance with an internal `TransactionSource::External` source and an optional + /// timestamp. + pub fn new_external(with_timestamp: bool) -> Self { + Self { source: TransactionSource::External, timestamp: with_timestamp.then(Instant::now) } + } + /// Creates a new instance with an internal `TransactionSource::Local` source and an optional + /// timestamp. + pub fn new_local(with_timestamp: bool) -> Self { + Self { source: TransactionSource::Local, timestamp: with_timestamp.then(Instant::now) } + } + /// Creates a new instance with an given source and an optional timestamp. + pub fn from_transaction_source(source: TransactionSource, with_timestamp: bool) -> Self { + Self { source, timestamp: with_timestamp.then(Instant::now) } + } +} + /// Immutable transaction #[derive(PartialEq, Eq, Clone)] pub struct Transaction { @@ -102,8 +140,8 @@ pub struct Transaction { pub provides: Vec, /// Should that transaction be propagated. pub propagate: bool, - /// Source of that transaction. - pub source: Source, + /// Timed source of that transaction. + pub source: TimedTransactionSource, } impl AsRef for Transaction { @@ -157,7 +195,7 @@ impl Transaction { bytes: self.bytes, hash: self.hash.clone(), priority: self.priority, - source: self.source, + source: self.source.clone(), valid_till: self.valid_till, requires: self.requires.clone(), provides: self.provides.clone(), @@ -322,22 +360,36 @@ impl BasePool { if !first { - promoted.push(current_hash); + promoted.push(current_hash.clone()); } + // If there were conflicting future transactions promoted, removed them from + // promoted set. + promoted.retain(|hash| replaced.iter().all(|tx| *hash != tx.hash)); // The transactions were removed from the ready pool. We might attempt to // re-import them. removed.append(&mut replaced); }, + Err(e @ error::Error::TooLowPriority { .. }) => + if first { + trace!(target: LOG_TARGET, "[{:?}] Error importing {first}: {:?}", current_tx.hash, e); + return Err(e) + } else { + trace!(target: LOG_TARGET, "[{:?}] Error importing {first}: {:?}", current_tx.hash, e); + removed.push(current_tx); + promoted.retain(|hash| *hash != current_hash); + }, // transaction failed to be imported. Err(e) => if first { - trace!(target: LOG_TARGET, "[{:?}] Error importing: {:?}", current_hash, e); + trace!(target: LOG_TARGET, "[{:?}] Error importing {first}: {:?}", current_tx.hash, e); return Err(e) } else { - failed.push(current_hash); + trace!(target: LOG_TARGET, "[{:?}] Error importing {first}: {:?}", current_tx.hash, e); + failed.push(current_tx.hash.clone()); }, } first = false; @@ -434,8 +486,24 @@ impl BasePool Some(current.clone()), - Some(ref tx) if tx.imported_at > current.imported_at => Some(current.clone()), - other => other, + Some(worst) => Some( + match (worst.transaction.source.timestamp, current.transaction.source.timestamp) + { + (Some(worst_timestamp), Some(current_timestamp)) => { + if worst_timestamp > current_timestamp { + current.clone() + } else { + worst + } + }, + _ => + if worst.imported_at > current.imported_at { + current.clone() + } else { + worst + }, + }, + ), }); if let Some(worst) = worst { @@ -562,7 +630,7 @@ mod tests { requires: vec![], provides: vec![], propagate: true, - source: Source::External, + source: TimedTransactionSource::new_external(false), } } @@ -760,6 +828,58 @@ mod tests { ); } + #[test] + fn should_remove_conflicting_future() { + let mut pool = pool(); + pool.import(Transaction { + data: vec![3u8].into(), + hash: 3, + requires: vec![vec![1]], + priority: 50u64, + provides: vec![vec![3]], + ..default_tx().clone() + }) + .unwrap(); + assert_eq!(pool.ready().count(), 0); + assert_eq!(pool.ready.len(), 0); + + let tx2 = Transaction { + data: vec![2u8].into(), + hash: 2, + requires: vec![vec![1]], + provides: vec![vec![3]], + ..default_tx().clone() + }; + pool.import(tx2.clone()).unwrap(); + assert_eq!(pool.future.len(), 2); + + let res = pool + .import(Transaction { + data: vec![1u8].into(), + hash: 1, + provides: vec![vec![1]], + ..default_tx().clone() + }) + .unwrap(); + + assert_eq!( + res, + Imported::Ready { + hash: 1, + promoted: vec![3], + failed: vec![], + removed: vec![tx2.into()] + } + ); + + let mut it = pool.ready().into_iter().map(|tx| tx.data[0]); + assert_eq!(it.next(), Some(1)); + assert_eq!(it.next(), Some(3)); + assert_eq!(it.next(), None); + + assert_eq!(pool.future.len(), 0); + } + #[test] fn should_handle_a_cycle() { // given @@ -783,14 +903,14 @@ mod tests { assert_eq!(pool.ready.len(), 0); // when - pool.import(Transaction { + let tx2 = Transaction { data: vec![2u8].into(), hash: 2, requires: vec![vec![2]], provides: vec![vec![0]], ..default_tx().clone() - }) - .unwrap(); + }; + pool.import(tx2.clone()).unwrap(); // then { @@ -817,7 +937,12 @@ mod tests { assert_eq!(it.next(), None); assert_eq!( res, - Imported::Ready { hash: 4, promoted: vec![1, 3], failed: vec![2], removed: vec![] } + Imported::Ready { + hash: 4, + promoted: vec![1, 3], + failed: vec![], + removed: vec![tx2.into()] + } ); assert_eq!(pool.future.len(), 0); } @@ -1024,7 +1149,7 @@ mod tests { ), "Transaction { \ hash: 4, priority: 1000, valid_till: 64, bytes: 1, propagate: true, \ -source: TransactionSource::External, requires: [03, 02], provides: [04], data: [4]}" +source: TimedTransactionSource { source: TransactionSource::External, timestamp: None }, requires: [03, 02], provides: [04], data: [4]}" .to_owned() ); } diff --git a/substrate/client/transaction-pool/src/graph/listener.rs b/substrate/client/transaction-pool/src/graph/listener.rs index a5593920eec4..41daf5491f70 100644 --- a/substrate/client/transaction-pool/src/graph/listener.rs +++ b/substrate/client/transaction-pool/src/graph/listener.rs @@ -36,6 +36,7 @@ pub type DroppedByLimitsStream = TracingUnboundedReceiver { + /// Map containing per-transaction sinks for emitting transaction status events. watchers: HashMap>>, finality_watchers: LinkedHashMap, Vec>, @@ -119,32 +120,44 @@ impl Listener, limits_enforced: bool) { + /// Transaction was dropped from the pool because of enforcing the limit. + pub fn limit_enforced(&mut self, tx: &H) { + trace!(target: LOG_TARGET, "[{:?}] Dropped (limit enforced)", tx); + self.fire(tx, |watcher| watcher.limit_enforced()); + + if let Some(ref sink) = self.dropped_by_limits_sink { + if let Err(e) = sink.unbounded_send((tx.clone(), TransactionStatus::Dropped)) { + trace!(target: LOG_TARGET, "[{:?}] dropped_sink: send message failed: {:?}", tx, e); + } + } + } + + /// Transaction was replaced with other extrinsic. + pub fn usurped(&mut self, tx: &H, by: &H) { trace!(target: LOG_TARGET, "[{:?}] Dropped (replaced with {:?})", tx, by); - self.fire(tx, |watcher| match by { - Some(t) => watcher.usurped(t.clone()), - None => watcher.dropped(), - }); - - //note: LimitEnforced could be introduced as new status to get rid of this flag. - if limits_enforced { - if let Some(ref sink) = self.dropped_by_limits_sink { - if let Err(e) = sink.unbounded_send((tx.clone(), TransactionStatus::Dropped)) { - trace!(target: LOG_TARGET, "[{:?}] dropped_sink/future: send message failed: {:?}", tx, e); - } + self.fire(tx, |watcher| watcher.usurped(by.clone())); + + if let Some(ref sink) = self.dropped_by_limits_sink { + if let Err(e) = + sink.unbounded_send((tx.clone(), TransactionStatus::Usurped(by.clone()))) + { + trace!(target: LOG_TARGET, "[{:?}] dropped_sink: send message failed: {:?}", tx, e); } } } + /// Transaction was dropped from the pool because of the failure during the resubmission of + /// revalidate transactions or failure during pruning tags. + pub fn dropped(&mut self, tx: &H) { + trace!(target: LOG_TARGET, "[{:?}] Dropped", tx); + self.fire(tx, |watcher| watcher.dropped()); + } + /// Transaction was removed as invalid. pub fn invalid(&mut self, tx: &H) { trace!(target: LOG_TARGET, "[{:?}] Extrinsic invalid", tx); diff --git a/substrate/client/transaction-pool/src/graph/pool.rs b/substrate/client/transaction-pool/src/graph/pool.rs index 2dd8de352c6b..23b71ce437b3 100644 --- a/substrate/client/transaction-pool/src/graph/pool.rs +++ b/substrate/client/transaction-pool/src/graph/pool.rs @@ -181,10 +181,8 @@ impl Pool { pub async fn submit_at( &self, at: &HashAndNumber, - source: TransactionSource, - xts: impl IntoIterator>, + xts: impl IntoIterator)>, ) -> Vec, B::Error>> { - let xts = xts.into_iter().map(|xt| (source, xt)); let validated_transactions = self.verify(at, xts, CheckBannedBeforeVerify::Yes).await; self.validated_pool.submit(validated_transactions.into_values()) } @@ -195,10 +193,8 @@ impl Pool { pub async fn resubmit_at( &self, at: &HashAndNumber, - source: TransactionSource, - xts: impl IntoIterator>, + xts: impl IntoIterator)>, ) -> Vec, B::Error>> { - let xts = xts.into_iter().map(|xt| (source, xt)); let validated_transactions = self.verify(at, xts, CheckBannedBeforeVerify::No).await; self.validated_pool.submit(validated_transactions.into_values()) } @@ -207,10 +203,10 @@ impl Pool { pub async fn submit_one( &self, at: &HashAndNumber, - source: TransactionSource, + source: base::TimedTransactionSource, xt: ExtrinsicFor, ) -> Result, B::Error> { - let res = self.submit_at(at, source, std::iter::once(xt)).await.pop(); + let res = self.submit_at(at, std::iter::once((source, xt))).await.pop(); res.expect("One extrinsic passed; one result returned; qed") } @@ -218,7 +214,7 @@ impl Pool { pub async fn submit_and_watch( &self, at: &HashAndNumber, - source: TransactionSource, + source: base::TimedTransactionSource, xt: ExtrinsicFor, ) -> Result, ExtrinsicHash>, B::Error> { let (_, tx) = self @@ -368,7 +364,7 @@ impl Pool { // Try to re-validate pruned transactions since some of them might be still valid. // note that `known_imported_hashes` will be rejected here due to temporary ban. let pruned_transactions = - prune_status.pruned.into_iter().map(|tx| (tx.source, tx.data.clone())); + prune_status.pruned.into_iter().map(|tx| (tx.source.clone(), tx.data.clone())); let reverified_transactions = self.verify(at, pruned_transactions, CheckBannedBeforeVerify::Yes).await; @@ -396,7 +392,7 @@ impl Pool { async fn verify( &self, at: &HashAndNumber, - xts: impl IntoIterator)>, + xts: impl IntoIterator)>, check: CheckBannedBeforeVerify, ) -> IndexMap, ValidatedTransactionFor> { let HashAndNumber { number, hash } = *at; @@ -417,7 +413,7 @@ impl Pool { &self, block_hash: ::Hash, block_number: NumberFor, - source: TransactionSource, + source: base::TimedTransactionSource, xt: ExtrinsicFor, check: CheckBannedBeforeVerify, ) -> (ExtrinsicHash, ValidatedTransactionFor) { @@ -431,7 +427,7 @@ impl Pool { let validation_result = self .validated_pool .api() - .validate_transaction(block_hash, source, xt.clone()) + .validate_transaction(block_hash, source.clone().into(), xt.clone()) .await; let status = match validation_result { @@ -488,6 +484,7 @@ mod tests { use super::{super::base_pool::Limit, *}; use crate::common::tests::{pool, uxt, TestApi, INVALID_NONCE}; use assert_matches::assert_matches; + use base::TimedTransactionSource; use codec::Encode; use futures::executor::block_on; use parking_lot::Mutex; @@ -497,7 +494,8 @@ mod tests { use substrate_test_runtime::{AccountId, ExtrinsicBuilder, Transfer, H256}; use substrate_test_runtime_client::AccountKeyring::{Alice, Bob}; - const SOURCE: TransactionSource = TransactionSource::External; + const SOURCE: TimedTransactionSource = + TimedTransactionSource { source: TransactionSource::External, timestamp: None }; #[test] fn should_validate_and_import_transaction() { @@ -545,8 +543,8 @@ mod tests { let initial_hashes = txs.iter().map(|t| api.hash_and_length(t).0).collect::>(); // when - let txs = txs.into_iter().map(|x| Arc::from(x)).collect::>(); - let hashes = block_on(pool.submit_at(&api.expect_hash_and_number(0), SOURCE, txs)); + let txs = txs.into_iter().map(|x| (SOURCE, Arc::from(x))).collect::>(); + let hashes = block_on(pool.submit_at(&api.expect_hash_and_number(0), txs)); log::debug!("--> {hashes:#?}"); // then diff --git a/substrate/client/transaction-pool/src/graph/ready.rs b/substrate/client/transaction-pool/src/graph/ready.rs index 860bcff0bace..9061d0e25581 100644 --- a/substrate/client/transaction-pool/src/graph/ready.rs +++ b/substrate/client/transaction-pool/src/graph/ready.rs @@ -589,7 +589,6 @@ fn remove_item(vec: &mut Vec, item: &T) { #[cfg(test)] mod tests { use super::*; - use sp_runtime::transaction_validity::TransactionSource as Source; fn tx(id: u8) -> Transaction> { Transaction { @@ -601,7 +600,7 @@ mod tests { requires: vec![vec![1], vec![2]], provides: vec![vec![3], vec![4]], propagate: true, - source: Source::External, + source: crate::TimedTransactionSource::new_external(false), } } @@ -711,7 +710,7 @@ mod tests { requires: vec![tx1.provides[0].clone()], provides: vec![], propagate: true, - source: Source::External, + source: crate::TimedTransactionSource::new_external(false), }; // when diff --git a/substrate/client/transaction-pool/src/graph/rotator.rs b/substrate/client/transaction-pool/src/graph/rotator.rs index 61a26fb4138c..9a2e269b5eed 100644 --- a/substrate/client/transaction-pool/src/graph/rotator.rs +++ b/substrate/client/transaction-pool/src/graph/rotator.rs @@ -106,7 +106,6 @@ impl PoolRotator { #[cfg(test)] mod tests { use super::*; - use sp_runtime::transaction_validity::TransactionSource; type Hash = u64; type Ex = (); @@ -126,7 +125,7 @@ mod tests { requires: vec![], provides: vec![], propagate: true, - source: TransactionSource::External, + source: crate::TimedTransactionSource::new_external(false), }; (hash, tx) @@ -192,7 +191,7 @@ mod tests { requires: vec![], provides: vec![], propagate: true, - source: TransactionSource::External, + source: crate::TimedTransactionSource::new_external(false), } } diff --git a/substrate/client/transaction-pool/src/graph/validated_pool.rs b/substrate/client/transaction-pool/src/graph/validated_pool.rs index d7f55198a40a..14df63d9673e 100644 --- a/substrate/client/transaction-pool/src/graph/validated_pool.rs +++ b/substrate/client/transaction-pool/src/graph/validated_pool.rs @@ -30,7 +30,7 @@ use serde::Serialize; use sp_blockchain::HashAndNumber; use sp_runtime::{ traits::{self, SaturatedConversion}, - transaction_validity::{TransactionSource, TransactionTag as Tag, ValidTransaction}, + transaction_validity::{TransactionTag as Tag, ValidTransaction}, }; use std::time::Instant; @@ -62,7 +62,7 @@ impl ValidatedTransaction { pub fn valid_at( at: u64, hash: Hash, - source: TransactionSource, + source: base::TimedTransactionSource, data: Ex, bytes: usize, validity: ValidTransaction, @@ -280,7 +280,7 @@ impl ValidatedPool { // run notifications let mut listener = self.listener.write(); for h in &removed { - listener.dropped(h, None, true); + listener.limit_enforced(h); } removed @@ -453,7 +453,7 @@ impl ValidatedPool { match final_status { Status::Future => listener.future(&hash), Status::Ready => listener.ready(&hash, None), - Status::Dropped => listener.dropped(&hash, None, false), + Status::Dropped => listener.dropped(&hash), Status::Failed => listener.invalid(&hash), } } @@ -492,7 +492,7 @@ impl ValidatedPool { fire_events(&mut *listener, promoted); } for f in &status.failed { - listener.dropped(f, None, false); + listener.dropped(f); } } @@ -671,6 +671,21 @@ impl ValidatedPool { ) -> super::listener::DroppedByLimitsStream, BlockHash> { self.listener.write().create_dropped_by_limits_stream() } + + /// Resends ready and future events for all the ready and future transactions that are already + /// in the pool. + /// + /// Intended to be called after cloning the instance of `ValidatedPool`. + pub fn retrigger_notifications(&self) { + let pool = self.pool.read(); + let mut listener = self.listener.write(); + pool.ready().for_each(|r| { + listener.ready(&r.hash, None); + }); + pool.futures().for_each(|f| { + listener.future(&f.hash); + }); + } } fn fire_events(listener: &mut Listener, imported: &base::Imported) @@ -682,7 +697,7 @@ where base::Imported::Ready { ref promoted, ref failed, ref removed, ref hash } => { listener.ready(hash, None); failed.iter().for_each(|f| listener.invalid(f)); - removed.iter().for_each(|r| listener.dropped(&r.hash, Some(hash), false)); + removed.iter().for_each(|r| listener.usurped(&r.hash, hash)); promoted.iter().for_each(|p| listener.ready(p, None)); }, base::Imported::Future { ref hash } => listener.future(hash), diff --git a/substrate/client/transaction-pool/src/graph/watcher.rs b/substrate/client/transaction-pool/src/graph/watcher.rs index fb7cf99d4dc6..2fd31e772fd8 100644 --- a/substrate/client/transaction-pool/src/graph/watcher.rs +++ b/substrate/client/transaction-pool/src/graph/watcher.rs @@ -113,6 +113,12 @@ impl Sender { } /// Transaction has been dropped from the pool because of the limit. + pub fn limit_enforced(&mut self) { + self.send(TransactionStatus::Dropped); + self.is_finalized = true; + } + + /// Transaction has been dropped from the pool. pub fn dropped(&mut self) { self.send(TransactionStatus::Dropped); self.is_finalized = true; diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs index 3d3d596c291f..366d91a973d2 100644 --- a/substrate/client/transaction-pool/src/lib.rs +++ b/substrate/client/transaction-pool/src/lib.rs @@ -36,7 +36,10 @@ pub use api::FullChainApi; pub use builder::{Builder, TransactionPoolHandle, TransactionPoolOptions, TransactionPoolType}; pub use common::notification_future; pub use fork_aware_txpool::{ForkAwareTxPool, ForkAwareTxPoolTask}; -pub use graph::{base_pool::Limit as PoolLimit, ChainApi, Options, Pool}; +pub use graph::{ + base_pool::{Limit as PoolLimit, TimedTransactionSource}, + ChainApi, Options, Pool, +}; use single_state_txpool::prune_known_txs_for_block; pub use single_state_txpool::{BasicPool, RevalidationType}; pub use transaction_pool_wrapper::TransactionPoolWrapper; diff --git a/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs b/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs index 5ef726c9f7d3..74031b1e1c72 100644 --- a/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs +++ b/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs @@ -88,7 +88,7 @@ async fn batch_revalidate( let validation_results = futures::future::join_all(batch.into_iter().filter_map(|ext_hash| { pool.validated_pool().ready_by_hash(&ext_hash).map(|ext| { - api.validate_transaction(at, ext.source, ext.data.clone()) + api.validate_transaction(at, ext.source.clone().into(), ext.data.clone()) .map(move |validation_result| (validation_result, ext_hash, ext)) }) })) @@ -121,7 +121,7 @@ async fn batch_revalidate( ValidatedTransaction::valid_at( block_number.saturated_into::(), ext_hash, - ext.source, + ext.source.clone(), ext.data.clone(), api.hash_and_length(&ext.data).1, validity, @@ -375,9 +375,9 @@ mod tests { use crate::{ common::tests::{uxt, TestApi}, graph::Pool, + TimedTransactionSource, }; use futures::executor::block_on; - use sc_transaction_pool_api::TransactionSource; use substrate_test_runtime::{AccountId, Transfer, H256}; use substrate_test_runtime_client::AccountKeyring::{Alice, Bob}; @@ -398,7 +398,7 @@ mod tests { let uxt_hash = block_on(pool.submit_one( &han_of_block0, - TransactionSource::External, + TimedTransactionSource::new_external(false), uxt.clone().into(), )) .expect("Should be valid"); @@ -433,14 +433,15 @@ mod tests { let han_of_block0 = api.expect_hash_and_number(0); let unknown_block = H256::repeat_byte(0x13); - let uxt_hashes = block_on(pool.submit_at( - &han_of_block0, - TransactionSource::External, - vec![uxt0.into(), uxt1.into()], - )) - .into_iter() - .map(|r| r.expect("Should be valid")) - .collect::>(); + let source = TimedTransactionSource::new_external(false); + let uxt_hashes = + block_on(pool.submit_at( + &han_of_block0, + vec![(source.clone(), uxt0.into()), (source, uxt1.into())], + )) + .into_iter() + .map(|r| r.expect("Should be valid")) + .collect::>(); assert_eq!(api.validation_requests().len(), 2); assert_eq!(pool.validated_pool().status().ready, 2); diff --git a/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs b/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs index b29630b563bb..e7504012ca67 100644 --- a/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs +++ b/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs @@ -29,7 +29,7 @@ use crate::{ error, log_xt::log_xt_trace, }, - graph::{self, ExtrinsicHash, IsValidator}, + graph::{self, base_pool::TimedTransactionSource, ExtrinsicHash, IsValidator}, ReadyIteratorFor, LOG_TARGET, }; use async_trait::async_trait; @@ -254,14 +254,19 @@ where xts: Vec>, ) -> Result, Self::Error>>, Self::Error> { let pool = self.pool.clone(); - let xts = xts.into_iter().map(Arc::from).collect::>(); + let xts = xts + .into_iter() + .map(|xt| { + (TimedTransactionSource::from_transaction_source(source, false), Arc::from(xt)) + }) + .collect::>(); self.metrics .report(|metrics| metrics.submitted_transactions.inc_by(xts.len() as u64)); let number = self.api.resolve_block_number(at); let at = HashAndNumber { hash: at, number: number? }; - Ok(pool.submit_at(&at, source, xts).await) + Ok(pool.submit_at(&at, xts).await) } async fn submit_one( @@ -277,7 +282,8 @@ where let number = self.api.resolve_block_number(at); let at = HashAndNumber { hash: at, number: number? }; - pool.submit_one(&at, source, xt).await + pool.submit_one(&at, TimedTransactionSource::from_transaction_source(source, false), xt) + .await } async fn submit_and_watch( @@ -294,7 +300,13 @@ where let number = self.api.resolve_block_number(at); let at = HashAndNumber { hash: at, number: number? }; - let watcher = pool.submit_and_watch(&at, source, xt).await?; + let watcher = pool + .submit_and_watch( + &at, + TimedTransactionSource::from_transaction_source(source, false), + xt, + ) + .await?; Ok(watcher.into_stream().boxed()) } @@ -458,7 +470,7 @@ where let validated = ValidatedTransaction::valid_at( block_number.saturated_into::(), hash, - TransactionSource::Local, + TimedTransactionSource::new_local(false), Arc::from(xt), bytes, validity, @@ -662,8 +674,8 @@ where resubmit_transactions.extend( //todo: arctx - we need to get ref from somewhere - block_transactions.into_iter().map(Arc::from).filter(|tx| { - let tx_hash = pool.hash_of(tx); + block_transactions.into_iter().map(Arc::from).filter_map(|tx| { + let tx_hash = pool.hash_of(&tx); let contains = pruned_log.contains(&tx_hash); // need to count all transactions, not just filtered, here @@ -676,8 +688,15 @@ where tx_hash, hash, ); + Some(( + // These transactions are coming from retracted blocks, we should + // simply consider them external. + TimedTransactionSource::new_external(false), + tx, + )) + } else { + None } - !contains }), ); @@ -686,14 +705,7 @@ where }); } - pool.resubmit_at( - &hash_and_number, - // These transactions are coming from retracted blocks, we should - // simply consider them external. - TransactionSource::External, - resubmit_transactions, - ) - .await; + pool.resubmit_at(&hash_and_number, resubmit_transactions).await; } let extra_pool = pool.clone(); diff --git a/substrate/client/transaction-pool/tests/fatp.rs b/substrate/client/transaction-pool/tests/fatp.rs index 9f343a9bd029..c51ca6e17663 100644 --- a/substrate/client/transaction-pool/tests/fatp.rs +++ b/substrate/client/transaction-pool/tests/fatp.rs @@ -2267,19 +2267,13 @@ fn fatp_avoid_stuck_transaction() { assert_pool_status!(header06.hash(), &pool, 0, 0); - // Import enough blocks to make xt4i revalidated - let mut prev_header = header03; - // wait 10 blocks for revalidation - for n in 7..=11 { - let header = api.push_block(n, vec![], true); - let event = finalized_block_event(&pool, prev_header.hash(), header.hash()); - block_on(pool.maintain(event)); - prev_header = header; - } + let header07 = api.push_block(7, vec![], true); + let event = finalized_block_event(&pool, header03.hash(), header07.hash()); + block_on(pool.maintain(event)); let xt4i_events = futures::executor::block_on_stream(xt4i_watcher).collect::>(); log::debug!("xt4i_events: {:#?}", xt4i_events); - assert_eq!(xt4i_events, vec![TransactionStatus::Future, TransactionStatus::Invalid]); + assert_eq!(xt4i_events, vec![TransactionStatus::Future, TransactionStatus::Dropped]); assert_eq!(pool.mempool_len(), (0, 0)); } diff --git a/substrate/client/transaction-pool/tests/fatp_common/mod.rs b/substrate/client/transaction-pool/tests/fatp_common/mod.rs index 15f2b7f79c14..aecd83360f1e 100644 --- a/substrate/client/transaction-pool/tests/fatp_common/mod.rs +++ b/substrate/client/transaction-pool/tests/fatp_common/mod.rs @@ -201,6 +201,20 @@ macro_rules! assert_ready_iterator { }}; } +#[macro_export] +macro_rules! assert_future_iterator { + ($hash:expr, $pool:expr, [$( $xt:expr ),*]) => {{ + let futures = $pool.futures_at($hash).unwrap(); + let expected = vec![ $($pool.api().hash_and_length(&$xt).0),*]; + log::debug!(target:LOG_TARGET, "expected: {:#?}", futures); + log::debug!(target:LOG_TARGET, "output: {:#?}", expected); + assert_eq!(expected.len(), futures.len()); + let hsf = futures.iter().map(|a| a.hash).collect::>(); + let hse = expected.into_iter().collect::>(); + assert_eq!(hse,hsf); + }}; +} + pub const SOURCE: TransactionSource = TransactionSource::External; #[cfg(test)] diff --git a/substrate/client/transaction-pool/tests/fatp_limits.rs b/substrate/client/transaction-pool/tests/fatp_limits.rs index 03792fd89dfa..afd8183957a8 100644 --- a/substrate/client/transaction-pool/tests/fatp_limits.rs +++ b/substrate/client/transaction-pool/tests/fatp_limits.rs @@ -641,3 +641,192 @@ fn fatp_limits_future_size_works() { assert_pool_status!(header01.hash(), &pool, 0, 3); assert_eq!(pool.mempool_len().0, 3); } + +#[test] +fn fatp_limits_watcher_ready_transactions_are_not_droped_when_view_is_dropped() { + sp_tracing::try_init_simple(); + + let builder = TestPoolBuilder::new(); + let (pool, api, _) = builder.with_mempool_count_limit(6).with_ready_count(2).build(); + api.set_nonce(api.genesis_hash(), Bob.into(), 300); + api.set_nonce(api.genesis_hash(), Charlie.into(), 400); + api.set_nonce(api.genesis_hash(), Dave.into(), 500); + api.set_nonce(api.genesis_hash(), Eve.into(), 600); + api.set_nonce(api.genesis_hash(), Ferdie.into(), 700); + + let header01 = api.push_block(1, vec![], true); + let event = new_best_block_event(&pool, None, header01.hash()); + block_on(pool.maintain(event)); + + let xt0 = uxt(Alice, 200); + let xt1 = uxt(Bob, 300); + let xt2 = uxt(Charlie, 400); + + let xt3 = uxt(Dave, 500); + let xt4 = uxt(Eve, 600); + let xt5 = uxt(Ferdie, 700); + + let _xt0_watcher = + block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt0.clone())).unwrap(); + let _xt1_watcher = + block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt1.clone())).unwrap(); + + assert_pool_status!(header01.hash(), &pool, 2, 0); + assert_eq!(pool.mempool_len().1, 2); + + let header02 = api.push_block_with_parent(header01.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header01.hash()), header02.hash()))); + + let _xt2_watcher = + block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt2.clone())).unwrap(); + let _xt3_watcher = + block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt3.clone())).unwrap(); + + assert_pool_status!(header02.hash(), &pool, 2, 0); + assert_eq!(pool.mempool_len().1, 4); + + let header03 = api.push_block_with_parent(header02.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header02.hash()), header03.hash()))); + + let _xt4_watcher = + block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt4.clone())).unwrap(); + let _xt5_watcher = + block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt5.clone())).unwrap(); + + assert_pool_status!(header03.hash(), &pool, 2, 0); + assert_eq!(pool.mempool_len().1, 6); + + let header04 = + api.push_block_with_parent(header03.hash(), vec![xt4.clone(), xt5.clone()], true); + api.set_nonce(header04.hash(), Alice.into(), 201); + api.set_nonce(header04.hash(), Bob.into(), 301); + api.set_nonce(header04.hash(), Charlie.into(), 401); + api.set_nonce(header04.hash(), Dave.into(), 501); + api.set_nonce(header04.hash(), Eve.into(), 601); + api.set_nonce(header04.hash(), Ferdie.into(), 701); + block_on(pool.maintain(new_best_block_event(&pool, Some(header03.hash()), header04.hash()))); + + assert_ready_iterator!(header01.hash(), pool, [xt0, xt1]); + assert_ready_iterator!(header02.hash(), pool, [xt2, xt3]); + assert_ready_iterator!(header03.hash(), pool, [xt4, xt5]); + assert_ready_iterator!(header04.hash(), pool, []); + + block_on(pool.maintain(finalized_block_event(&pool, api.genesis_hash(), header01.hash()))); + assert!(!pool.status_all().contains_key(&header01.hash())); + + block_on(pool.maintain(finalized_block_event(&pool, header01.hash(), header02.hash()))); + assert!(!pool.status_all().contains_key(&header02.hash())); + + //view 01 was dropped + assert!(pool.ready_at(header01.hash()).now_or_never().is_none()); + assert_eq!(pool.mempool_len().1, 6); + + block_on(pool.maintain(finalized_block_event(&pool, header02.hash(), header03.hash()))); + + //no revalidation has happened yet, all txs are kept + assert_eq!(pool.mempool_len().1, 6); + + //view 03 is still there + assert!(!pool.status_all().contains_key(&header03.hash())); + + //view 02 was dropped + assert!(pool.ready_at(header02.hash()).now_or_never().is_none()); + + let mut prev_header = header03; + for n in 5..=11 { + let header = api.push_block(n, vec![], true); + let event = finalized_block_event(&pool, prev_header.hash(), header.hash()); + block_on(pool.maintain(event)); + prev_header = header; + } + + //now revalidation has happened, all txs are dropped + assert_eq!(pool.mempool_len().1, 0); +} + +#[test] +fn fatp_limits_watcher_future_transactions_are_droped_when_view_is_dropped() { + sp_tracing::try_init_simple(); + + let builder = TestPoolBuilder::new(); + let (pool, api, _) = builder.with_mempool_count_limit(6).with_future_count(2).build(); + api.set_nonce(api.genesis_hash(), Bob.into(), 300); + api.set_nonce(api.genesis_hash(), Charlie.into(), 400); + api.set_nonce(api.genesis_hash(), Dave.into(), 500); + api.set_nonce(api.genesis_hash(), Eve.into(), 600); + api.set_nonce(api.genesis_hash(), Ferdie.into(), 700); + + let header01 = api.push_block(1, vec![], true); + let event = new_best_block_event(&pool, None, header01.hash()); + block_on(pool.maintain(event)); + + let xt0 = uxt(Alice, 201); + let xt1 = uxt(Bob, 301); + let xt2 = uxt(Charlie, 401); + + let xt3 = uxt(Dave, 501); + let xt4 = uxt(Eve, 601); + let xt5 = uxt(Ferdie, 701); + + let xt0_watcher = block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt0.clone())).unwrap(); + let xt1_watcher = block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt1.clone())).unwrap(); + + assert_pool_status!(header01.hash(), &pool, 0, 2); + assert_eq!(pool.mempool_len().1, 2); + assert_future_iterator!(header01.hash(), pool, [xt0, xt1]); + + let header02 = api.push_block_with_parent(header01.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header01.hash()), header02.hash()))); + + let xt2_watcher = block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt2.clone())).unwrap(); + let xt3_watcher = block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt3.clone())).unwrap(); + + assert_pool_status!(header02.hash(), &pool, 0, 2); + assert_eq!(pool.mempool_len().1, 4); + assert_future_iterator!(header02.hash(), pool, [xt2, xt3]); + + let header03 = api.push_block_with_parent(header02.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header02.hash()), header03.hash()))); + + let xt4_watcher = block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt4.clone())).unwrap(); + let xt5_watcher = block_on(pool.submit_and_watch(invalid_hash(), SOURCE, xt5.clone())).unwrap(); + + assert_pool_status!(header03.hash(), &pool, 0, 2); + assert_eq!(pool.mempool_len().1, 6); + assert_future_iterator!(header03.hash(), pool, [xt4, xt5]); + + let header04 = api.push_block_with_parent(header03.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header03.hash()), header04.hash()))); + + assert_pool_status!(header04.hash(), &pool, 0, 2); + assert_eq!(pool.futures().len(), 2); + assert_future_iterator!(header04.hash(), pool, [xt4, xt5]); + + block_on(pool.maintain(finalized_block_event(&pool, api.genesis_hash(), header04.hash()))); + assert_eq!(pool.active_views_count(), 1); + assert_eq!(pool.inactive_views_count(), 0); + //todo: can we do better? We don't have API to check if event was processed internally. + let mut counter = 0; + while pool.mempool_len().1 != 2 { + sleep(std::time::Duration::from_millis(1)); + counter = counter + 1; + if counter > 20 { + assert!(false, "timeout {}", pool.mempool_len().1); + } + } + assert_eq!(pool.mempool_len().1, 2); + assert_pool_status!(header04.hash(), &pool, 0, 2); + assert_eq!(pool.futures().len(), 2); + + let to_be_checked = vec![xt0_watcher, xt1_watcher, xt2_watcher, xt3_watcher]; + for x in to_be_checked { + let x_status = futures::executor::block_on_stream(x).take(2).collect::>(); + assert_eq!(x_status, vec![TransactionStatus::Future, TransactionStatus::Dropped]); + } + + let to_be_checked = vec![xt4_watcher, xt5_watcher]; + for x in to_be_checked { + let x_status = futures::executor::block_on_stream(x).take(1).collect::>(); + assert_eq!(x_status, vec![TransactionStatus::Future]); + } +} diff --git a/substrate/client/transaction-pool/tests/fatp_prios.rs b/substrate/client/transaction-pool/tests/fatp_prios.rs new file mode 100644 index 000000000000..41bc374b38f4 --- /dev/null +++ b/substrate/client/transaction-pool/tests/fatp_prios.rs @@ -0,0 +1,249 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Tests of priorities for fork-aware transaction pool. + +pub mod fatp_common; + +use fatp_common::{new_best_block_event, TestPoolBuilder, LOG_TARGET, SOURCE}; +use futures::{executor::block_on, FutureExt}; +use sc_transaction_pool::ChainApi; +use sc_transaction_pool_api::{MaintainedTransactionPool, TransactionPool, TransactionStatus}; +use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_transaction_pool::uxt; + +#[test] +fn fatp_prio_ready_higher_evicts_lower() { + sp_tracing::try_init_simple(); + + let builder = TestPoolBuilder::new(); + let (pool, api, _) = builder.with_mempool_count_limit(3).with_ready_count(2).build(); + + let header01 = api.push_block(1, vec![], true); + + let event = new_best_block_event(&pool, None, header01.hash()); + block_on(pool.maintain(event)); + + let xt0 = uxt(Alice, 200); + let xt1 = uxt(Alice, 200); + + api.set_priority(&xt0, 2); + api.set_priority(&xt1, 3); + + let result0 = block_on(pool.submit_one(header01.hash(), SOURCE, xt0.clone())); + let result1 = block_on(pool.submit_one(header01.hash(), SOURCE, xt1.clone())); + + log::info!("r0 => {:?}", result0); + log::info!("r1 => {:?}", result1); + log::info!("len: {:?}", pool.mempool_len()); + log::info!("len: {:?}", pool.status_all()[&header01.hash()]); + assert_ready_iterator!(header01.hash(), pool, [xt1]); + assert_pool_status!(header01.hash(), &pool, 1, 0); +} + +#[test] +fn fatp_prio_watcher_ready_higher_evicts_lower() { + sp_tracing::try_init_simple(); + + let builder = TestPoolBuilder::new(); + let (pool, api, _) = builder.with_mempool_count_limit(3).with_ready_count(2).build(); + + let header01 = api.push_block(1, vec![], true); + + let event = new_best_block_event(&pool, None, header01.hash()); + block_on(pool.maintain(event)); + + let xt0 = uxt(Alice, 200); + let xt1 = uxt(Alice, 200); + + api.set_priority(&xt0, 2); + api.set_priority(&xt1, 3); + + let xt0_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt0.clone())).unwrap(); + let xt1_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt1.clone())).unwrap(); + + let xt0_status = futures::executor::block_on_stream(xt0_watcher).take(2).collect::>(); + assert_eq!( + xt0_status, + vec![TransactionStatus::Ready, TransactionStatus::Usurped(api.hash_and_length(&xt1).0)] + ); + let xt1_status = futures::executor::block_on_stream(xt1_watcher).take(1).collect::>(); + assert_eq!(xt1_status, vec![TransactionStatus::Ready]); + + log::info!("len: {:?}", pool.mempool_len()); + log::info!("len: {:?}", pool.status_all()[&header01.hash()]); + assert_ready_iterator!(header01.hash(), pool, [xt1]); + assert_pool_status!(header01.hash(), &pool, 1, 0); +} + +#[test] +fn fatp_prio_watcher_future_higher_evicts_lower() { + sp_tracing::try_init_simple(); + + let builder = TestPoolBuilder::new(); + let (pool, api, _) = builder.with_mempool_count_limit(3).with_ready_count(3).build(); + + let header01 = api.push_block(1, vec![], true); + + let event = new_best_block_event(&pool, None, header01.hash()); + block_on(pool.maintain(event)); + + let xt0 = uxt(Alice, 201); + let xt1 = uxt(Alice, 201); + let xt2 = uxt(Alice, 200); + + api.set_priority(&xt0, 2); + api.set_priority(&xt1, 3); + + let xt0_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt0.clone())).unwrap(); + let xt1_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt1.clone())).unwrap(); + let xt2_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt2.clone())).unwrap(); + + let xt0_status = futures::executor::block_on_stream(xt0_watcher).take(2).collect::>(); + + assert_eq!( + xt0_status, + vec![TransactionStatus::Future, TransactionStatus::Usurped(api.hash_and_length(&xt2).0)] + ); + let xt1_status = futures::executor::block_on_stream(xt1_watcher).take(2).collect::>(); + assert_eq!(xt1_status, vec![TransactionStatus::Future, TransactionStatus::Ready]); + let xt2_status = futures::executor::block_on_stream(xt2_watcher).take(1).collect::>(); + assert_eq!(xt2_status, vec![TransactionStatus::Ready]); + + assert_eq!(pool.mempool_len().1, 2); + assert_ready_iterator!(header01.hash(), pool, [xt2, xt1]); + assert_pool_status!(header01.hash(), &pool, 2, 0); +} + +#[test] +fn fatp_prio_watcher_ready_lower_prio_gets_dropped_from_all_views() { + sp_tracing::try_init_simple(); + + let builder = TestPoolBuilder::new(); + let (pool, api, _) = builder.with_mempool_count_limit(3).with_ready_count(2).build(); + + let header01 = api.push_block(1, vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, None, header01.hash()))); + + let xt0 = uxt(Alice, 200); + let xt1 = uxt(Alice, 200); + + api.set_priority(&xt0, 2); + api.set_priority(&xt1, 3); + + let xt0_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt0.clone())).unwrap(); + + let header02 = api.push_block_with_parent(header01.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header01.hash()), header02.hash()))); + + let header03a = api.push_block_with_parent(header02.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header01.hash()), header03a.hash()))); + + let header03b = api.push_block_with_parent(header02.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header03a.hash()), header03b.hash()))); + + assert_pool_status!(header03a.hash(), &pool, 1, 0); + assert_ready_iterator!(header03a.hash(), pool, [xt0]); + assert_pool_status!(header03b.hash(), &pool, 1, 0); + assert_ready_iterator!(header03b.hash(), pool, [xt0]); + assert_ready_iterator!(header01.hash(), pool, [xt0]); + assert_ready_iterator!(header02.hash(), pool, [xt0]); + + let xt1_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt1.clone())).unwrap(); + + let xt1_status = futures::executor::block_on_stream(xt1_watcher).take(1).collect::>(); + assert_eq!(xt1_status, vec![TransactionStatus::Ready]); + let xt0_status = futures::executor::block_on_stream(xt0_watcher).take(2).collect::>(); + assert_eq!( + xt0_status, + vec![TransactionStatus::Ready, TransactionStatus::Usurped(api.hash_and_length(&xt1).0)] + ); + assert_ready_iterator!(header03a.hash(), pool, [xt1]); + assert_ready_iterator!(header03b.hash(), pool, [xt1]); + assert_ready_iterator!(header01.hash(), pool, [xt1]); + assert_ready_iterator!(header02.hash(), pool, [xt1]); +} + +#[test] +fn fatp_prio_watcher_future_lower_prio_gets_dropped_from_all_views() { + sp_tracing::try_init_simple(); + + let builder = TestPoolBuilder::new(); + let (pool, api, _) = builder.with_mempool_count_limit(3).with_ready_count(2).build(); + + let header01 = api.push_block(1, vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, None, header01.hash()))); + + let xt0 = uxt(Alice, 201); + let xt1 = uxt(Alice, 201); + let xt2 = uxt(Alice, 200); + + api.set_priority(&xt0, 2); + api.set_priority(&xt1, 3); + + let xt0_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt0.clone())).unwrap(); + + let xt1_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt1.clone())).unwrap(); + + let header02 = api.push_block_with_parent(header01.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header01.hash()), header02.hash()))); + + let header03a = api.push_block_with_parent(header02.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header01.hash()), header03a.hash()))); + + let header03b = api.push_block_with_parent(header02.hash(), vec![], true); + block_on(pool.maintain(new_best_block_event(&pool, Some(header03a.hash()), header03b.hash()))); + + assert_pool_status!(header03a.hash(), &pool, 0, 2); + assert_future_iterator!(header03a.hash(), pool, [xt0, xt1]); + assert_pool_status!(header03b.hash(), &pool, 0, 2); + assert_future_iterator!(header03b.hash(), pool, [xt0, xt1]); + assert_future_iterator!(header01.hash(), pool, [xt0, xt1]); + assert_future_iterator!(header02.hash(), pool, [xt0, xt1]); + + let xt2_watcher = + block_on(pool.submit_and_watch(header01.hash(), SOURCE, xt2.clone())).unwrap(); + + let xt2_status = futures::executor::block_on_stream(xt2_watcher).take(1).collect::>(); + assert_eq!(xt2_status, vec![TransactionStatus::Ready]); + let xt1_status = futures::executor::block_on_stream(xt1_watcher).take(1).collect::>(); + assert_eq!(xt1_status, vec![TransactionStatus::Future]); + let xt0_status = futures::executor::block_on_stream(xt0_watcher).take(2).collect::>(); + assert_eq!( + xt0_status, + vec![TransactionStatus::Future, TransactionStatus::Usurped(api.hash_and_length(&xt2).0)] + ); + assert_future_iterator!(header03a.hash(), pool, []); + assert_future_iterator!(header03b.hash(), pool, []); + assert_future_iterator!(header01.hash(), pool, []); + assert_future_iterator!(header02.hash(), pool, []); + + assert_ready_iterator!(header03a.hash(), pool, [xt2, xt1]); + assert_ready_iterator!(header03b.hash(), pool, [xt2, xt1]); + assert_ready_iterator!(header01.hash(), pool, [xt2, xt1]); + assert_ready_iterator!(header02.hash(), pool, [xt2, xt1]); +} diff --git a/substrate/client/transaction-pool/tests/pool.rs b/substrate/client/transaction-pool/tests/pool.rs index ed0fd7d4e655..e556ba9875f1 100644 --- a/substrate/client/transaction-pool/tests/pool.rs +++ b/substrate/client/transaction-pool/tests/pool.rs @@ -80,12 +80,14 @@ fn create_basic_pool(test_api: TestApi) -> BasicPool { create_basic_pool_with_genesis(Arc::from(test_api)).0 } +const TSOURCE: TimedTransactionSource = + TimedTransactionSource { source: TransactionSource::External, timestamp: None }; const SOURCE: TransactionSource = TransactionSource::External; #[test] fn submission_should_work() { let (pool, api) = pool(); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 209).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 209).into())) .unwrap(); let pending: Vec<_> = pool @@ -99,9 +101,9 @@ fn submission_should_work() { #[test] fn multiple_submission_should_work() { let (pool, api) = pool(); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 209).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 209).into())) .unwrap(); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 210).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 210).into())) .unwrap(); let pending: Vec<_> = pool @@ -116,7 +118,7 @@ fn multiple_submission_should_work() { fn early_nonce_should_be_culled() { sp_tracing::try_init_simple(); let (pool, api) = pool(); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 208).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 208).into())) .unwrap(); log::debug!("-> {:?}", pool.validated_pool().status()); @@ -132,7 +134,7 @@ fn early_nonce_should_be_culled() { fn late_nonce_should_be_queued() { let (pool, api) = pool(); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 210).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 210).into())) .unwrap(); let pending: Vec<_> = pool .validated_pool() @@ -141,7 +143,7 @@ fn late_nonce_should_be_queued() { .collect(); assert_eq!(pending, Vec::::new()); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 209).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 209).into())) .unwrap(); let pending: Vec<_> = pool .validated_pool() @@ -155,9 +157,9 @@ fn late_nonce_should_be_queued() { fn prune_tags_should_work() { let (pool, api) = pool(); let hash209 = - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 209).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 209).into())) .unwrap(); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt(Alice, 210).into())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt(Alice, 210).into())) .unwrap(); let pending: Vec<_> = pool @@ -183,9 +185,9 @@ fn should_ban_invalid_transactions() { let (pool, api) = pool(); let uxt = Arc::from(uxt(Alice, 209)); let hash = - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt.clone())).unwrap(); + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt.clone())).unwrap(); pool.validated_pool().remove_invalid(&[hash]); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt.clone())).unwrap_err(); + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt.clone())).unwrap_err(); // when let pending: Vec<_> = pool @@ -196,7 +198,7 @@ fn should_ban_invalid_transactions() { assert_eq!(pending, Vec::::new()); // then - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, uxt.clone())).unwrap_err(); + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, uxt.clone())).unwrap_err(); } #[test] @@ -224,7 +226,7 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { })); let pool = Pool::new(Default::default(), true.into(), api.clone()); let xt0 = Arc::from(uxt(Alice, 209)); - block_on(pool.submit_one(&api.expect_hash_and_number(0), SOURCE, xt0.clone())) + block_on(pool.submit_one(&api.expect_hash_and_number(0), TSOURCE, xt0.clone())) .expect("1. Imported"); assert_eq!(pool.validated_pool().status().ready, 1); assert_eq!(api.validation_requests().len(), 1); @@ -242,7 +244,7 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { api.increment_nonce(Alice.into()); api.push_block(2, Vec::new(), true); let xt1 = uxt(Alice, 211); - block_on(pool.submit_one(&api.expect_hash_and_number(2), SOURCE, xt1.clone().into())) + block_on(pool.submit_one(&api.expect_hash_and_number(2), TSOURCE, xt1.clone().into())) .expect("2. Imported"); assert_eq!(api.validation_requests().len(), 3); assert_eq!(pool.validated_pool().status().ready, 1); From a2ffae303e8b6c52cff720fb2f3e2019d65d91b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 4 Dec 2024 10:06:57 +0100 Subject: [PATCH 08/51] umbrella: Remove `pallet-revive-fixtures` (#6743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to have them in the umbrella crate also by having them in the umbrella crate they are bleeding into the normal build. --------- Co-authored-by: GitHub Action Co-authored-by: Alexander Theißen --- Cargo.lock | 1 - prdoc/pr_6743.prdoc | 10 ++++++++++ substrate/frame/revive/fixtures/Cargo.toml | 3 +++ umbrella/Cargo.toml | 8 +------- umbrella/src/lib.rs | 4 ---- 5 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 prdoc/pr_6743.prdoc diff --git a/Cargo.lock b/Cargo.lock index bc2ebb2a057d..863822f4ffd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18577,7 +18577,6 @@ dependencies = [ "pallet-remark 28.0.0", "pallet-revive 0.1.0", "pallet-revive-eth-rpc", - "pallet-revive-fixtures 0.1.0", "pallet-revive-mock-network 0.1.0", "pallet-revive-proc-macro 0.1.0", "pallet-revive-uapi 0.1.0", diff --git a/prdoc/pr_6743.prdoc b/prdoc/pr_6743.prdoc new file mode 100644 index 000000000000..4c35ff46ca67 --- /dev/null +++ b/prdoc/pr_6743.prdoc @@ -0,0 +1,10 @@ +title: 'umbrella: Remove `pallet-revive-fixtures`' +doc: +- audience: Runtime Dev + description: |- + No need to have them in the umbrella crate also by having them in the umbrella crate they are bleeding into the normal build. +crates: +- name: pallet-revive-fixtures + bump: major +- name: polkadot-sdk + bump: major diff --git a/substrate/frame/revive/fixtures/Cargo.toml b/substrate/frame/revive/fixtures/Cargo.toml index 9fd434db6179..88921cca08ec 100644 --- a/substrate/frame/revive/fixtures/Cargo.toml +++ b/substrate/frame/revive/fixtures/Cargo.toml @@ -8,6 +8,9 @@ description = "Fixtures for testing and benchmarking" homepage.workspace = true repository.workspace = true +[package.metadata.polkadot-sdk] +exclude-from-umbrella = true + [lints] workspace = true diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 9affcffd2ade..8ed9c3dcb02c 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -120,7 +120,6 @@ std = [ "pallet-recovery?/std", "pallet-referenda?/std", "pallet-remark?/std", - "pallet-revive-fixtures?/std", "pallet-revive-mock-network?/std", "pallet-revive?/std", "pallet-root-offences?/std", @@ -541,7 +540,7 @@ with-tracing = [ "sp-tracing?/with-tracing", "sp-tracing?/with-tracing", ] -runtime-full = ["assets-common", "binary-merkle-tree", "bp-header-chain", "bp-messages", "bp-parachains", "bp-polkadot", "bp-polkadot-core", "bp-relayers", "bp-runtime", "bp-test-utils", "bp-xcm-bridge-hub", "bp-xcm-bridge-hub-router", "bridge-hub-common", "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", "cumulus-pallet-parachain-system-proc-macro", "cumulus-pallet-session-benchmarking", "cumulus-pallet-solo-to-para", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-ping", "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-primitives-proof-size-hostfunction", "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-timestamp", "cumulus-primitives-utility", "frame-benchmarking", "frame-benchmarking-pallet-pov", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-executive", "frame-metadata-hash-extension", "frame-support", "frame-support-procedural", "frame-support-procedural-tools-derive", "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", "pallet-alliance", "pallet-asset-conversion", "pallet-asset-conversion-ops", "pallet-asset-conversion-tx-payment", "pallet-asset-rate", "pallet-asset-tx-payment", "pallet-assets", "pallet-assets-freezer", "pallet-atomic-swap", "pallet-aura", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", "pallet-bags-list", "pallet-balances", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", "pallet-bridge-grandpa", "pallet-bridge-messages", "pallet-bridge-parachains", "pallet-bridge-relayers", "pallet-broker", "pallet-child-bounties", "pallet-collator-selection", "pallet-collective", "pallet-collective-content", "pallet-contracts", "pallet-contracts-proc-macro", "pallet-contracts-uapi", "pallet-conviction-voting", "pallet-core-fellowship", "pallet-delegated-staking", "pallet-democracy", "pallet-dev-mode", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-elections-phragmen", "pallet-fast-unstake", "pallet-glutton", "pallet-grandpa", "pallet-identity", "pallet-im-online", "pallet-indices", "pallet-insecure-randomness-collective-flip", "pallet-lottery", "pallet-membership", "pallet-message-queue", "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-nis", "pallet-node-authorization", "pallet-nomination-pools", "pallet-nomination-pools-benchmarking", "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", "pallet-paged-list", "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-ranked-collective", "pallet-recovery", "pallet-referenda", "pallet-remark", "pallet-revive", "pallet-revive-fixtures", "pallet-revive-proc-macro", "pallet-revive-uapi", "pallet-root-offences", "pallet-root-testing", "pallet-safe-mode", "pallet-salary", "pallet-scheduler", "pallet-scored-pool", "pallet-session", "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-state-trie-migration", "pallet-statement", "pallet-sudo", "pallet-timestamp", "pallet-tips", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-transaction-storage", "pallet-treasury", "pallet-tx-pause", "pallet-uniques", "pallet-utility", "pallet-verify-signature", "pallet-vesting", "pallet-whitelist", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub", "pallet-xcm-bridge-hub-router", "parachains-common", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-metrics", "polkadot-runtime-parachains", "polkadot-sdk-frame", "sc-chain-spec-derive", "sc-tracing-proc-macro", "slot-range-helper", "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", "snowbridge-outbound-queue-merkle-tree", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-ethereum-client-fixtures", "snowbridge-pallet-inbound-queue", "snowbridge-pallet-inbound-queue-fixtures", "snowbridge-pallet-outbound-queue", "snowbridge-pallet-system", "snowbridge-router-primitives", "snowbridge-runtime-common", "snowbridge-system-runtime-api", "sp-api", "sp-api-proc-macro", "sp-application-crypto", "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", "sp-consensus-pow", "sp-consensus-slots", "sp-core", "sp-crypto-ec-utils", "sp-crypto-hashing", "sp-crypto-hashing-proc-macro", "sp-debug-derive", "sp-externalities", "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", "sp-keystore", "sp-metadata-ir", "sp-mixnet", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-runtime-interface", "sp-runtime-interface-proc-macro", "sp-session", "sp-staking", "sp-state-machine", "sp-statement-store", "sp-std", "sp-storage", "sp-timestamp", "sp-tracing", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", "sp-version", "sp-version-proc-macro", "sp-wasm-interface", "sp-weights", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", "substrate-bip39", "testnet-parachains-constants", "tracing-gum-proc-macro", "xcm-procedural", "xcm-runtime-apis"] +runtime-full = ["assets-common", "binary-merkle-tree", "bp-header-chain", "bp-messages", "bp-parachains", "bp-polkadot", "bp-polkadot-core", "bp-relayers", "bp-runtime", "bp-test-utils", "bp-xcm-bridge-hub", "bp-xcm-bridge-hub-router", "bridge-hub-common", "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", "cumulus-pallet-parachain-system-proc-macro", "cumulus-pallet-session-benchmarking", "cumulus-pallet-solo-to-para", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-ping", "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-primitives-proof-size-hostfunction", "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-timestamp", "cumulus-primitives-utility", "frame-benchmarking", "frame-benchmarking-pallet-pov", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-executive", "frame-metadata-hash-extension", "frame-support", "frame-support-procedural", "frame-support-procedural-tools-derive", "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", "pallet-alliance", "pallet-asset-conversion", "pallet-asset-conversion-ops", "pallet-asset-conversion-tx-payment", "pallet-asset-rate", "pallet-asset-tx-payment", "pallet-assets", "pallet-assets-freezer", "pallet-atomic-swap", "pallet-aura", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", "pallet-bags-list", "pallet-balances", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", "pallet-bridge-grandpa", "pallet-bridge-messages", "pallet-bridge-parachains", "pallet-bridge-relayers", "pallet-broker", "pallet-child-bounties", "pallet-collator-selection", "pallet-collective", "pallet-collective-content", "pallet-contracts", "pallet-contracts-proc-macro", "pallet-contracts-uapi", "pallet-conviction-voting", "pallet-core-fellowship", "pallet-delegated-staking", "pallet-democracy", "pallet-dev-mode", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-elections-phragmen", "pallet-fast-unstake", "pallet-glutton", "pallet-grandpa", "pallet-identity", "pallet-im-online", "pallet-indices", "pallet-insecure-randomness-collective-flip", "pallet-lottery", "pallet-membership", "pallet-message-queue", "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-nis", "pallet-node-authorization", "pallet-nomination-pools", "pallet-nomination-pools-benchmarking", "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", "pallet-paged-list", "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-ranked-collective", "pallet-recovery", "pallet-referenda", "pallet-remark", "pallet-revive", "pallet-revive-proc-macro", "pallet-revive-uapi", "pallet-root-offences", "pallet-root-testing", "pallet-safe-mode", "pallet-salary", "pallet-scheduler", "pallet-scored-pool", "pallet-session", "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-state-trie-migration", "pallet-statement", "pallet-sudo", "pallet-timestamp", "pallet-tips", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-transaction-storage", "pallet-treasury", "pallet-tx-pause", "pallet-uniques", "pallet-utility", "pallet-verify-signature", "pallet-vesting", "pallet-whitelist", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub", "pallet-xcm-bridge-hub-router", "parachains-common", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-metrics", "polkadot-runtime-parachains", "polkadot-sdk-frame", "sc-chain-spec-derive", "sc-tracing-proc-macro", "slot-range-helper", "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", "snowbridge-outbound-queue-merkle-tree", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-ethereum-client-fixtures", "snowbridge-pallet-inbound-queue", "snowbridge-pallet-inbound-queue-fixtures", "snowbridge-pallet-outbound-queue", "snowbridge-pallet-system", "snowbridge-router-primitives", "snowbridge-runtime-common", "snowbridge-system-runtime-api", "sp-api", "sp-api-proc-macro", "sp-application-crypto", "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", "sp-consensus-pow", "sp-consensus-slots", "sp-core", "sp-crypto-ec-utils", "sp-crypto-hashing", "sp-crypto-hashing-proc-macro", "sp-debug-derive", "sp-externalities", "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", "sp-keystore", "sp-metadata-ir", "sp-mixnet", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-runtime-interface", "sp-runtime-interface-proc-macro", "sp-session", "sp-staking", "sp-state-machine", "sp-statement-store", "sp-std", "sp-storage", "sp-timestamp", "sp-tracing", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", "sp-version", "sp-version-proc-macro", "sp-wasm-interface", "sp-weights", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", "substrate-bip39", "testnet-parachains-constants", "tracing-gum-proc-macro", "xcm-procedural", "xcm-runtime-apis"] runtime = [ "frame-benchmarking", "frame-benchmarking-pallet-pov", @@ -1193,11 +1192,6 @@ path = "../substrate/frame/revive" default-features = false optional = true -[dependencies.pallet-revive-fixtures] -path = "../substrate/frame/revive/fixtures" -default-features = false -optional = true - [dependencies.pallet-revive-proc-macro] path = "../substrate/frame/revive/proc-macro" default-features = false diff --git a/umbrella/src/lib.rs b/umbrella/src/lib.rs index 2216864fad0f..3712fb3343cf 100644 --- a/umbrella/src/lib.rs +++ b/umbrella/src/lib.rs @@ -584,10 +584,6 @@ pub use pallet_revive; #[cfg(feature = "pallet-revive-eth-rpc")] pub use pallet_revive_eth_rpc; -/// Fixtures for testing and benchmarking. -#[cfg(feature = "pallet-revive-fixtures")] -pub use pallet_revive_fixtures; - /// A mock network for testing pallet-revive. #[cfg(feature = "pallet-revive-mock-network")] pub use pallet_revive_mock_network; From 377bc3f830a63e277dd94fed490670d1be6d840f Mon Sep 17 00:00:00 2001 From: Egor_P Date: Wed, 4 Dec 2024 11:06:55 +0100 Subject: [PATCH 09/51] [Release|CI/CD] Add pipeline to promote release candidate from rcX to final in S3 (#6748) This PR adds the pipeline, that moves release candidate artefacts from `polkadot-stableYYMM-rcX` bucket to the one that is going to be the final `polkadot-stableYYMM` (bucket name matches the tag name). So that it could be used for publishing later without a need to re-build it again. --- .github/scripts/common/lib.sh | 2 +- .github/scripts/release/release_lib.sh | 44 +++++- .../release-31_promote-rc-to-final.yml | 125 ++++++++++++++++++ .../release-reusable-promote-to-final.yml | 83 ++++++++++++ .../workflows/release-reusable-rc-buid.yml | 4 +- .../workflows/release-reusable-s3-upload.yml | 14 +- 6 files changed, 253 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/release-31_promote-rc-to-final.yml create mode 100644 .github/workflows/release-reusable-promote-to-final.yml diff --git a/.github/scripts/common/lib.sh b/.github/scripts/common/lib.sh index 41dc0ba06dd2..00f8c089831e 100755 --- a/.github/scripts/common/lib.sh +++ b/.github/scripts/common/lib.sh @@ -297,7 +297,7 @@ fetch_release_artifacts_from_s3() { pwd ls -al --color popd > /dev/null - + unset OUTPUT_DIR } # Pass the name of the binary as input, it will diff --git a/.github/scripts/release/release_lib.sh b/.github/scripts/release/release_lib.sh index 43227180cb7c..984709f2ea03 100644 --- a/.github/scripts/release/release_lib.sh +++ b/.github/scripts/release/release_lib.sh @@ -129,15 +129,17 @@ upload_s3_release() { echo "Working on version: $version " echo "Working on platform: $target " + URL_BASE=$(get_s3_url_base $product) + echo "Current content, should be empty on new uploads:" - aws s3 ls "s3://releases.parity.io/${product}/${version}/${target}" --recursive --human-readable --summarize || true + aws s3 ls "s3://${URL_BASE}/${version}/${target}" --recursive --human-readable --summarize || true echo "Content to be uploaded:" - artifacts="artifacts/$product/" + artifacts="release-artifacts/$target/$product/" ls "$artifacts" - aws s3 sync --acl public-read "$artifacts" "s3://releases.parity.io/${product}/${version}/${target}" + aws s3 sync --acl public-read "$artifacts" "s3://${URL_BASE}/${version}/${target}" echo "Uploaded files:" - aws s3 ls "s3://releases.parity.io/${product}/${version}/${target}" --recursive --human-readable --summarize - echo "✅ The release should be at https://releases.parity.io/${product}/${version}/${target}" + aws s3 ls "s3://${URL_BASE}/${version}/${target}" --recursive --human-readable --summarize + echo "✅ The release should be at https://${URL_BASE}/${version}/${target}" } # Upload runtimes artifacts to s3 release bucket @@ -161,3 +163,35 @@ upload_s3_runtimes_release_artifacts() { aws s3 ls "s3://releases.parity.io/polkadot/runtimes/${version}/" --recursive --human-readable --summarize echo "✅ The release should be at https://releases.parity.io/polkadot/runtimes/${version}" } + + +# Pass the name of the binary as input, it will +# return the s3 base url +function get_s3_url_base() { + name=$1 + case $name in + polkadot | polkadot-execute-worker | polkadot-prepare-worker ) + printf "releases.parity.io/polkadot" + ;; + + polkadot-parachain) + printf "releases.parity.io/polkadot-parachain" + ;; + + polkadot-omni-node) + printf "releases.parity.io/polkadot-omni-node" + ;; + + chain-spec-builder) + printf "releases.parity.io/chain-spec-builder" + ;; + + frame-omni-bencher) + printf "releases.parity.io/frame-omni-bencher" + ;; + *) + printf "UNSUPPORTED BINARY $name" + exit 1 + ;; + esac +} diff --git a/.github/workflows/release-31_promote-rc-to-final.yml b/.github/workflows/release-31_promote-rc-to-final.yml new file mode 100644 index 000000000000..6aa9d4bddd1d --- /dev/null +++ b/.github/workflows/release-31_promote-rc-to-final.yml @@ -0,0 +1,125 @@ +name: Release - Promote RC to final candidate on S3 + +on: + workflow_dispatch: + inputs: + binary: + description: Binary to be build for the release + default: all + type: choice + options: + - polkadot + - polkadot-parachain + - polkadot-omni-node + - frame-omni-bencher + - chain-spec-builder + - all + release_tag: + description: Tag matching the actual release candidate with the format polkadot-stableYYMM(-X)-rcX + type: string + + +jobs: + + check-synchronization: + uses: paritytech-release/sync-workflows/.github/workflows/check-syncronization.yml@main + + validate-inputs: + needs: [ check-synchronization ] + if: ${{ needs.check-synchronization.outputs.checks_passed }} == 'true' + runs-on: ubuntu-latest + outputs: + release_tag: ${{ steps.validate_inputs.outputs.release_tag }} + final_tag: ${{ steps.validate_inputs.outputs.final_tag }} + + steps: + - name: Checkout sources + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Validate inputs + id: validate_inputs + run: | + . ./.github/scripts/common/lib.sh + + RELEASE_TAG=$(validate_stable_tag ${{ inputs.release_tag }}) + echo "release_tag=${RELEASE_TAG}" >> $GITHUB_OUTPUT + + promote-polkadot-rc-to-final: + if: ${{ inputs.binary == 'polkadot' || inputs.binary == 'all' }} + needs: [ validate-inputs ] + uses: ./.github/workflows/release-reusable-promote-to-final.yml + strategy: + matrix: + target: [ x86_64-unknown-linux-gnu, aarch64-apple-darwin ] + with: + package: polkadot + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: ${{ matrix.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + + promote-polkadot-parachain-rc-to-final: + if: ${{ inputs.binary == 'polkadot-parachain' || inputs.binary == 'all' }} + needs: [ validate-inputs ] + uses: ./.github/workflows/release-reusable-promote-to-final.yml + strategy: + matrix: + target: [ x86_64-unknown-linux-gnu, aarch64-apple-darwin ] + with: + package: polkadot-parachain + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: ${{ matrix.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + + promote-polkadot-omni-node-rc-to-final: + if: ${{ inputs.binary == 'polkadot-omni-node' || inputs.binary == 'all' }} + needs: [ validate-inputs ] + uses: ./.github/workflows/release-reusable-promote-to-final.yml + strategy: + matrix: + target: [ x86_64-unknown-linux-gnu, aarch64-apple-darwin ] + with: + package: polkadot-omni-node + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: ${{ matrix.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + + promote-frame-omni-bencher-rc-to-final: + if: ${{ inputs.binary == 'frame-omni-bencher' || inputs.binary == 'all' }} + needs: [ validate-inputs ] + uses: ./.github/workflows/release-reusable-promote-to-final.yml + strategy: + matrix: + target: [ x86_64-unknown-linux-gnu, aarch64-apple-darwin ] + with: + package: frame-omni-bencher + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: ${{ matrix.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + + promote-chain-spec-builder-rc-to-final: + if: ${{ inputs.binary == 'chain-spec-builder' || inputs.binary == 'all' }} + needs: [ validate-inputs ] + uses: ./.github/workflows/release-reusable-promote-to-final.yml + strategy: + matrix: + target: [ x86_64-unknown-linux-gnu, aarch64-apple-darwin ] + with: + package: chain-spec-builder + release_tag: ${{ needs.validate-inputs.outputs.release_tag }} + target: ${{ matrix.target }} + secrets: + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + AWS_RELEASE_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_RELEASE_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/release-reusable-promote-to-final.yml b/.github/workflows/release-reusable-promote-to-final.yml new file mode 100644 index 000000000000..ed4a80a01e82 --- /dev/null +++ b/.github/workflows/release-reusable-promote-to-final.yml @@ -0,0 +1,83 @@ +name: Promote rc to final + +on: + workflow_call: + inputs: + package: + description: Package to be promoted + required: true + type: string + + release_tag: + description: Tag matching the actual release candidate with the format polkadot-stableYYMM(-X)-rcX taht will be changed to final in form of polkadot-stableYYMM(-X) + required: true + type: string + + target: + description: Target triple for which the artifacts are being uploaded (e.g aarch64-apple-darwin) + required: true + type: string + + secrets: + AWS_DEFAULT_REGION: + required: true + AWS_RELEASE_ACCESS_KEY_ID: + required: true + AWS_RELEASE_SECRET_ACCESS_KEY: + required: true + +jobs: + + promote-release-artifacts: + environment: release + runs-on: ubuntu-latest + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_RELEASE_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_RELEASE_SECRET_ACCESS_KEY }} + AWS_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + + steps: + - name: Checkout sources + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Prepare final tag + id: prepare_final_tag + shell: bash + run: | + tag="$(echo ${{ inputs.release_tag }} | sed 's/-rc[0-9]*$//')" + echo $tag + echo "FINAL_TAG=${tag}" >> $GITHUB_OUTPUT + + - name: Fetch binaries from s3 based on version + run: | + . ./.github/scripts/common/lib.sh + + VERSION="${{ inputs.release_tag }}" + if [[ ${{ inputs.package }} == 'polkadot' ]]; then + packages=(polkadot polkadot-prepare-worker polkadot-execute-worker) + for package in "${packages[@]}"; do + fetch_release_artifacts_from_s3 $package ${{ inputs.target }} + done + else + fetch_release_artifacts_from_s3 ${{ inputs.package }} ${{ inputs.target }} + fi + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.AWS_REGION }} + + - name: Upload ${{ inputs.package }} ${{ inputs.target }} artifacts to s3 + run: | + . ./.github/scripts/release/release_lib.sh + + if [[ ${{ inputs.package }} == 'polkadot' ]]; then + packages=(polkadot polkadot-prepare-worker polkadot-execute-worker) + for package in "${packages[@]}"; do + upload_s3_release $package ${{ steps.prepare_final_tag.outputs.final_tag }} ${{ inputs.target }} + done + else + upload_s3_release ${{ inputs.package }} ${{ steps.prepare_final_tag.outputs.final_tag }} ${{ inputs.target }} + fi diff --git a/.github/workflows/release-reusable-rc-buid.yml b/.github/workflows/release-reusable-rc-buid.yml index dc1b4553eb9b..0222b2aa91e2 100644 --- a/.github/workflows/release-reusable-rc-buid.yml +++ b/.github/workflows/release-reusable-rc-buid.yml @@ -133,7 +133,7 @@ jobs: - name: Upload ${{ matrix.binaries }} artifacts uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: ${{ matrix.binaries }} + name: ${{ matrix.binaries }}_${{ inputs.target }} path: /artifacts/${{ matrix.binaries }} build-macos-rc: @@ -285,7 +285,7 @@ jobs: - name: Upload ${{inputs.package }} artifacts uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: ${{ inputs.package }} + name: ${{ inputs.package }}_${{ inputs.target }} path: target/production overwrite: true diff --git a/.github/workflows/release-reusable-s3-upload.yml b/.github/workflows/release-reusable-s3-upload.yml index f85466bc8c07..48c7e53c6c8f 100644 --- a/.github/workflows/release-reusable-s3-upload.yml +++ b/.github/workflows/release-reusable-s3-upload.yml @@ -9,7 +9,7 @@ on: type: string release_tag: - description: Tag matching the actual release candidate with the format stableYYMM-rcX or stableYYMM-rcX + description: Tag matching the actual release candidate with the format polkadot-stableYYMM(-X)-rcX or polkadot-stableYYMM-rcX required: true type: string @@ -40,18 +40,10 @@ jobs: uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Download amd64 artifacts - if: ${{ inputs.target == 'x86_64-unknown-linux-gnu' }} uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: - name: ${{ inputs.package }} - path: artifacts/${{ inputs.package }} - - - name: Download arm artifacts - if: ${{ inputs.target == 'aarch64-apple-darwin' }} - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 - with: - name: ${{ inputs.package }}_aarch64-apple-darwin - path: artifacts/${{ inputs.package }} + name: ${{ inputs.package }}_${{ inputs.target }} + path: release-artifacts/${{ inputs.target }}/${{ inputs.package }} - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 From 34632ed68272ce2c250cb085c5ab9e53f0a2ced6 Mon Sep 17 00:00:00 2001 From: Javier Viola <363911+pepoviola@users.noreply.github.com> Date: Wed, 4 Dec 2024 13:29:13 +0100 Subject: [PATCH 10/51] Disable flaky tests reported in #6574/#6644 (#6749) Reference issues #6574 #6644 --- .gitlab/pipeline/zombienet/polkadot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/pipeline/zombienet/polkadot.yml b/.gitlab/pipeline/zombienet/polkadot.yml index 3dab49a118e5..ac4bdac7ad15 100644 --- a/.gitlab/pipeline/zombienet/polkadot.yml +++ b/.gitlab/pipeline/zombienet/polkadot.yml @@ -179,7 +179,7 @@ zombienet-polkadot-elastic-scaling-0001-basic-3cores-6s-blocks: --local-dir="${LOCAL_DIR}/elastic_scaling" --test="0001-basic-3cores-6s-blocks.zndsl" -zombienet-polkadot-elastic-scaling-0002-elastic-scaling-doesnt-break-parachains: +.zombienet-polkadot-elastic-scaling-0002-elastic-scaling-doesnt-break-parachains: extends: - .zombienet-polkadot-common before_script: @@ -233,7 +233,7 @@ zombienet-polkadot-functional-0015-coretime-shared-core: --local-dir="${LOCAL_DIR}/functional" --test="0016-approval-voting-parallel.zndsl" -zombienet-polkadot-functional-0017-sync-backing: +.zombienet-polkadot-functional-0017-sync-backing: extends: - .zombienet-polkadot-common script: From 5ca726750da563c46449f9aa915296e6c6967e61 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:47:47 +0100 Subject: [PATCH 11/51] chore: Update litep2p to v0.8.3 (#6742) ## [0.8.3] - 2024-12-03 This release includes two fixes for small memory leaks on edge-cases in the notification and request-response protocols. ### Fixed - req-resp: Fix memory leak of pending substreams ([#297](https://github.com/paritytech/litep2p/pull/297)) - notification: Fix memory leak of pending substreams ([#296](https://github.com/paritytech/litep2p/pull/296)) cc @paritytech/networking --------- Signed-off-by: Alexandru Vasile --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- prdoc/pr_6742.prdoc | 11 +++++++++++ substrate/client/network/src/litep2p/mod.rs | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 prdoc/pr_6742.prdoc diff --git a/Cargo.lock b/Cargo.lock index 863822f4ffd5..eee12dc5bc40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10225,9 +10225,9 @@ dependencies = [ [[package]] name = "litep2p" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "569e7dbec8a0d4b08d30f4942cd579cfe8db5d3f83f8604abe61697c38d17e73" +checksum = "14e490b5a6d486711fd0284bd30e607a287343f2935a59a9192bd7109e85f443" dependencies = [ "async-trait", "bs58", diff --git a/Cargo.toml b/Cargo.toml index ecc385504181..49fdc198fe33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -848,7 +848,7 @@ linked-hash-map = { version = "0.5.4" } linked_hash_set = { version = "0.1.4" } linregress = { version = "0.5.1" } lite-json = { version = "0.2.0", default-features = false } -litep2p = { version = "0.8.2", features = ["websocket"] } +litep2p = { version = "0.8.3", features = ["websocket"] } log = { version = "0.4.22", default-features = false } macro_magic = { version = "0.5.1" } maplit = { version = "1.0.2" } diff --git a/prdoc/pr_6742.prdoc b/prdoc/pr_6742.prdoc new file mode 100644 index 000000000000..92c3755a3c28 --- /dev/null +++ b/prdoc/pr_6742.prdoc @@ -0,0 +1,11 @@ +title: Update litep2p backend to v0.8.3 +doc: +- audience: Node Dev + description: |- + This release includes two fixes for small memory leaks on edge-cases in the notification and request-response protocols. + While at it, have downgraded a log message from litep2p. + +crates: +- name: sc-network + bump: patch + diff --git a/substrate/client/network/src/litep2p/mod.rs b/substrate/client/network/src/litep2p/mod.rs index 6d3575fc2b6b..b6d64b34d64a 100644 --- a/substrate/client/network/src/litep2p/mod.rs +++ b/substrate/client/network/src/litep2p/mod.rs @@ -753,7 +753,7 @@ impl NetworkBackend for Litep2pNetworkBac } if self.litep2p.add_known_address(peer.into(), iter::once(address.clone())) == 0usize { - log::warn!( + log::debug!( target: LOG_TARGET, "couldn't add known address ({address}) for {peer:?}, unsupported transport" ); From 2779043b0f667b75062cdc085e8052190b78cb20 Mon Sep 17 00:00:00 2001 From: Egor_P Date: Wed, 4 Dec 2024 17:43:51 +0100 Subject: [PATCH 12/51] [CI/CD] Fix permissions issue in the backport to stable flow (#6754) This PR has changes to the `command-backport.yml`: - swapped action that creates backports PRs from master to the stable branches and added another app with more permissions --- .github/workflows/command-backport.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/command-backport.yml b/.github/workflows/command-backport.yml index eecf0ac72d2c..53dcea2f1d6d 100644 --- a/.github/workflows/command-backport.yml +++ b/.github/workflows/command-backport.yml @@ -29,12 +29,13 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Generate token - id: generate_token - uses: tibdex/github-app-token@v2.1.0 + - name: Generate content write token for the release automation + id: generate_write_token + uses: actions/create-github-app-token@v1 with: - app_id: ${{ secrets.CMD_BOT_APP_ID }} - private_key: ${{ secrets.CMD_BOT_APP_KEY }} + app-id: ${{ vars.RELEASE_AUTOMATION_APP_ID }} + private-key: ${{ secrets.RELEASE_AUTOMATION_APP_PRIVATE_KEY }} + owner: paritytech - name: Create backport pull requests uses: korthout/backport-action@v3 @@ -42,7 +43,7 @@ jobs: with: target_branches: stable2407 stable2409 stable2412 merge_commits: skip - github_token: ${{ steps.generate_token.outputs.token }} + github_token: ${{ steps.generate_write_token.outputs.token }} pull_description: | Backport #${pull_number} into `${target_branch}` from ${pull_author}. @@ -86,7 +87,7 @@ jobs: const reviewer = '${{ github.event.pull_request.user.login }}'; for (const pullNumber of pullNumbers) { - await github.pulls.createReviewRequest({ + await github.pulls.requestReviewers({ owner: context.repo.owner, repo: context.repo.repo, pull_number: parseInt(pullNumber), From 82117ad53fc68e8097183e759926b62265ffff0a Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Wed, 4 Dec 2024 18:55:33 +0100 Subject: [PATCH 13/51] wasm-builder: Use riscv32emac-unknown-none-polkavm.json target (#6419) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Closes #6335. ## Integration N/A ## Review Notes `RuntimeTarget` is converted to return path to the custom target JSON file --------- Signed-off-by: Jarkko Sakkinen Co-authored-by: Alexander Theißen Co-authored-by: Koute --- Cargo.lock | 12 +- Cargo.toml | 4 +- prdoc/pr_6419.prdoc | 12 ++ substrate/utils/wasm-builder/src/builder.rs | 3 +- substrate/utils/wasm-builder/src/lib.rs | 105 +++++++----------- .../utils/wasm-builder/src/prerequisites.rs | 7 +- .../utils/wasm-builder/src/wasm_project.rs | 28 +++-- 7 files changed, 87 insertions(+), 84 deletions(-) create mode 100644 prdoc/pr_6419.prdoc diff --git a/Cargo.lock b/Cargo.lock index eee12dc5bc40..dad578ba0c1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14752,7 +14752,7 @@ dependencies = [ "anyhow", "frame-system 28.0.0", "log", - "polkavm-linker 0.17.0", + "polkavm-linker 0.17.1", "sp-core 28.0.0", "sp-io 30.0.0", "sp-runtime 31.0.1", @@ -19936,9 +19936,9 @@ dependencies = [ [[package]] name = "polkavm-linker" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d359dc721d2cc9b555ebb3558c305112ddc5bdac09d26f95f2f7b49c1f2db7e9" +checksum = "0422ead3030d5cde69e2206dbc7d65da872b121876507cd5363f6c6e6aa45157" dependencies = [ "dirs", "gimli 0.31.1", @@ -26495,7 +26495,7 @@ dependencies = [ "libsecp256k1", "log", "parity-scale-codec", - "polkavm-derive 0.9.1", + "polkavm-derive 0.17.0", "rustversion", "secp256k1 0.28.2", "sp-core 28.0.0", @@ -26979,7 +26979,7 @@ dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec", - "polkavm-derive 0.9.1", + "polkavm-derive 0.17.0", "primitive-types 0.13.1", "rustversion", "sp-core 28.0.0", @@ -28623,7 +28623,7 @@ dependencies = [ "merkleized-metadata", "parity-scale-codec", "parity-wasm", - "polkavm-linker 0.9.2", + "polkavm-linker 0.17.1", "sc-executor 0.32.0", "shlex", "sp-core 28.0.0", diff --git a/Cargo.toml b/Cargo.toml index 49fdc198fe33..383fc46c4e76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1090,8 +1090,8 @@ polkadot-test-client = { path = "polkadot/node/test/client" } polkadot-test-runtime = { path = "polkadot/runtime/test-runtime" } polkadot-test-service = { path = "polkadot/node/test/service" } polkavm = { version = "0.9.3", default-features = false } -polkavm-derive = "0.9.1" -polkavm-linker = "0.9.2" +polkavm-derive = "0.17.0" +polkavm-linker = "0.17.1" portpicker = { version = "0.1.1" } pretty_assertions = { version = "1.3.0" } primitive-types = { version = "0.13.1", default-features = false, features = [ diff --git a/prdoc/pr_6419.prdoc b/prdoc/pr_6419.prdoc new file mode 100644 index 000000000000..6cc155d64b91 --- /dev/null +++ b/prdoc/pr_6419.prdoc @@ -0,0 +1,12 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Use the custom target riscv32emac-unknown-none-polkavm +doc: + - audience: Runtime Dev + description: | + Closes: https://github.com/paritytech/polkadot-sdk/issues/6335 + +crates: +- name: substrate-wasm-builder + bump: patch diff --git a/substrate/utils/wasm-builder/src/builder.rs b/substrate/utils/wasm-builder/src/builder.rs index a40aafe1d812..5bdc743eac31 100644 --- a/substrate/utils/wasm-builder/src/builder.rs +++ b/substrate/utils/wasm-builder/src/builder.rs @@ -235,7 +235,8 @@ impl WasmBuilder { /// Build the WASM binary. pub fn build(mut self) { - let target = crate::runtime_target(); + let target = RuntimeTarget::new(); + if target == RuntimeTarget::Wasm { if self.export_heap_base { self.rust_flags.push("-Clink-arg=--export=__heap_base".into()); diff --git a/substrate/utils/wasm-builder/src/lib.rs b/substrate/utils/wasm-builder/src/lib.rs index 420ecd63e1dc..ce90f492e08f 100644 --- a/substrate/utils/wasm-builder/src/lib.rs +++ b/substrate/utils/wasm-builder/src/lib.rs @@ -112,7 +112,6 @@ //! wasm32-unknown-unknown --toolchain nightly-2020-02-20`. use std::{ - collections::BTreeSet, env, fs, io::BufRead, path::{Path, PathBuf}, @@ -254,26 +253,22 @@ struct CargoCommand { program: String, args: Vec, version: Option, - target_list: Option>, } impl CargoCommand { fn new(program: &str) -> Self { let version = Self::extract_version(program, &[]); - let target_list = Self::extract_target_list(program, &[]); - CargoCommand { program: program.into(), args: Vec::new(), version, target_list } + CargoCommand { program: program.into(), args: Vec::new(), version } } fn new_with_args(program: &str, args: &[&str]) -> Self { let version = Self::extract_version(program, args); - let target_list = Self::extract_target_list(program, args); CargoCommand { program: program.into(), args: args.iter().map(ToString::to_string).collect(), version, - target_list, } } @@ -294,23 +289,6 @@ impl CargoCommand { Version::extract(&version) } - fn extract_target_list(program: &str, args: &[&str]) -> Option> { - // This is technically an unstable option, but we don't care because we only need this - // to build RISC-V runtimes, and those currently require a specific nightly toolchain - // anyway, so it's totally fine for this to fail in other cases. - let list = Command::new(program) - .args(args) - .args(&["rustc", "-Z", "unstable-options", "--print", "target-list"]) - // Make sure if we're called from within a `build.rs` the host toolchain won't override - // a rustup toolchain we've picked. - .env_remove("RUSTC") - .output() - .ok() - .and_then(|o| String::from_utf8(o.stdout).ok())?; - - Some(list.trim().split("\n").map(ToString::to_string).collect()) - } - /// Returns the version of this cargo command or `None` if it failed to extract the version. fn version(&self) -> Option { self.version @@ -326,19 +304,10 @@ impl CargoCommand { fn supports_substrate_runtime_env(&self, target: RuntimeTarget) -> bool { match target { RuntimeTarget::Wasm => self.supports_substrate_runtime_env_wasm(), - RuntimeTarget::Riscv => self.supports_substrate_runtime_env_riscv(), + RuntimeTarget::Riscv => true, } } - /// Check if the supplied cargo command supports our RISC-V runtime environment. - fn supports_substrate_runtime_env_riscv(&self) -> bool { - let Some(target_list) = self.target_list.as_ref() else { return false }; - // This is our custom target which currently doesn't exist on any upstream toolchain, - // so if it exists it's guaranteed to be our custom toolchain and have have everything - // we need, so any further version checks are unnecessary at this point. - target_list.contains("riscv32ema-unknown-none-elf") - } - /// Check if the supplied cargo command supports our Substrate wasm environment. /// /// This means that either the cargo version is at minimum 1.68.0 or this is a nightly cargo. @@ -409,13 +378,6 @@ fn get_bool_environment_variable(name: &str) -> Option { } } -/// Returns whether we need to also compile the standard library when compiling the runtime. -fn build_std_required() -> bool { - let default = runtime_target() == RuntimeTarget::Wasm; - - crate::get_bool_environment_variable(crate::WASM_BUILD_STD).unwrap_or(default) -} - #[derive(Copy, Clone, PartialEq, Eq)] enum RuntimeTarget { Wasm, @@ -423,36 +385,55 @@ enum RuntimeTarget { } impl RuntimeTarget { - fn rustc_target(self) -> &'static str { + /// Creates a new instance. + fn new() -> Self { + let Some(value) = env::var_os(RUNTIME_TARGET) else { + return Self::Wasm; + }; + + if value == "wasm" { + Self::Wasm + } else if value == "riscv" { + Self::Riscv + } else { + build_helper::warning!( + "RUNTIME_TARGET environment variable must be set to either \"wasm\" or \"riscv\"" + ); + std::process::exit(1); + } + } + + /// Figures out the target parameter value for rustc. + fn rustc_target(self) -> String { match self { - RuntimeTarget::Wasm => "wasm32-unknown-unknown", - RuntimeTarget::Riscv => "riscv32ema-unknown-none-elf", + RuntimeTarget::Wasm => "wasm32-unknown-unknown".to_string(), + RuntimeTarget::Riscv => { + let path = polkavm_linker::target_json_32_path().expect("riscv not found"); + path.into_os_string().into_string().unwrap() + }, } } - fn build_subdirectory(self) -> &'static str { - // Keep the build directories separate so that when switching between - // the targets we won't trigger unnecessary rebuilds. + /// Figures out the target directory name used by cargo. + fn rustc_target_dir(self) -> &'static str { match self { - RuntimeTarget::Wasm => "wbuild", - RuntimeTarget::Riscv => "rbuild", + RuntimeTarget::Wasm => "wasm32-unknown-unknown", + RuntimeTarget::Riscv => "riscv32emac-unknown-none-polkavm", } } -} -fn runtime_target() -> RuntimeTarget { - let Some(value) = env::var_os(RUNTIME_TARGET) else { - return RuntimeTarget::Wasm; - }; + /// Figures out the build-std argument. + fn rustc_target_build_std(self) -> Option<&'static str> { + if !crate::get_bool_environment_variable(crate::WASM_BUILD_STD).unwrap_or(true) { + return None; + } - if value == "wasm" { - RuntimeTarget::Wasm - } else if value == "riscv" { - RuntimeTarget::Riscv - } else { - build_helper::warning!( - "the '{RUNTIME_TARGET}' environment variable has an invalid value; it must be either 'wasm' or 'riscv'" - ); - std::process::exit(1); + // This is a nightly-only flag. + let arg = match self { + RuntimeTarget::Wasm => "build-std", + RuntimeTarget::Riscv => "build-std=core,alloc", + }; + + Some(arg) } } diff --git a/substrate/utils/wasm-builder/src/prerequisites.rs b/substrate/utils/wasm-builder/src/prerequisites.rs index 4de6b87f618d..9abfd1725237 100644 --- a/substrate/utils/wasm-builder/src/prerequisites.rs +++ b/substrate/utils/wasm-builder/src/prerequisites.rs @@ -196,11 +196,14 @@ fn check_wasm_toolchain_installed( error, colorize_aux_message(&"-".repeat(60)), )) - } + }; } let version = dummy_crate.get_rustc_version(); - if crate::build_std_required() { + + let target = RuntimeTarget::new(); + assert!(target == RuntimeTarget::Wasm); + if target.rustc_target_build_std().is_some() { if let Some(sysroot) = dummy_crate.get_sysroot() { let src_path = Path::new(sysroot.trim()).join("lib").join("rustlib").join("src").join("rust"); diff --git a/substrate/utils/wasm-builder/src/wasm_project.rs b/substrate/utils/wasm-builder/src/wasm_project.rs index 26edd2ea1f22..6530e4c22fb9 100644 --- a/substrate/utils/wasm-builder/src/wasm_project.rs +++ b/substrate/utils/wasm-builder/src/wasm_project.rs @@ -109,6 +109,15 @@ fn crate_metadata(cargo_manifest: &Path) -> Metadata { crate_metadata } +/// Keep the build directories separate so that when switching between the +/// targets we won't trigger unnecessary rebuilds. +fn build_subdirectory(target: RuntimeTarget) -> &'static str { + match target { + RuntimeTarget::Wasm => "wbuild", + RuntimeTarget::Riscv => "rbuild", + } +} + /// Creates the WASM project, compiles the WASM binary and compacts the WASM binary. /// /// # Returns @@ -125,7 +134,7 @@ pub(crate) fn create_and_compile( #[cfg(feature = "metadata-hash")] enable_metadata_hash: Option, ) -> (Option, WasmBinaryBloaty) { let runtime_workspace_root = get_wasm_workspace_root(); - let runtime_workspace = runtime_workspace_root.join(target.build_subdirectory()); + let runtime_workspace = runtime_workspace_root.join(build_subdirectory(target)); let crate_metadata = crate_metadata(orig_project_cargo_toml); @@ -770,7 +779,7 @@ impl BuildConfiguration { .collect::>() .iter() .rev() - .take_while(|c| c.as_os_str() != target.build_subdirectory()) + .take_while(|c| c.as_os_str() != build_subdirectory(target)) .last() .expect("We put the runtime project within a `target/.../[rw]build` path; qed") .as_os_str() @@ -841,9 +850,7 @@ fn build_bloaty_blob( "-C target-cpu=mvp -C target-feature=-sign-ext -C link-arg=--export-table ", ); }, - RuntimeTarget::Riscv => { - rustflags.push_str("-C target-feature=+lui-addi-fusion -C relocation-model=pie -C link-arg=--emit-relocs -C link-arg=--unique "); - }, + RuntimeTarget::Riscv => (), } rustflags.push_str(default_rustflags); @@ -907,10 +914,9 @@ fn build_bloaty_blob( // // So here we force the compiler to also compile the standard library crates for us // to make sure that they also only use the MVP features. - if crate::build_std_required() { - // Unfortunately this is still a nightly-only flag, but FWIW it is pretty widely used - // so it's unlikely to break without a replacement. - build_cmd.arg("-Z").arg("build-std"); + if let Some(arg) = target.rustc_target_build_std() { + build_cmd.arg("-Z").arg(arg); + if !cargo_cmd.supports_nightly_features() { build_cmd.env("RUSTC_BOOTSTRAP", "1"); } @@ -934,7 +940,7 @@ fn build_bloaty_blob( let blob_name = get_blob_name(target, &manifest_path); let target_directory = project .join("target") - .join(target.rustc_target()) + .join(target.rustc_target_dir()) .join(blob_build_profile.directory()); match target { RuntimeTarget::Riscv => { @@ -968,7 +974,7 @@ fn build_bloaty_blob( }, }; - std::fs::write(&polkavm_path, program.as_bytes()) + std::fs::write(&polkavm_path, program) .expect("writing the blob to a file always works"); } From 654d60c3a373cb5268f50e6cd9274580e12dce87 Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Thu, 5 Dec 2024 09:42:32 +0100 Subject: [PATCH 14/51] ci: skip check-semver in master and merge queue (#6762) tbd --- .github/workflows/check-semver.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/check-semver.yml b/.github/workflows/check-semver.yml index e9bedd16e6d1..11b386da21e9 100644 --- a/.github/workflows/check-semver.yml +++ b/.github/workflows/check-semver.yml @@ -78,6 +78,11 @@ jobs: - name: check semver run: | + if [ -z "$PR" ]; then + echo "Skipping master/merge queue" + exit 0 + fi + export CARGO_TARGET_DIR=target export RUSTFLAGS='-A warnings -A missing_docs' export SKIP_WASM_BUILD=1 From f4a196ab1473856c9c5992239fcc2f14c2c42914 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Thu, 5 Dec 2024 09:54:31 +0100 Subject: [PATCH 15/51] Optimize initialization of networking protocol benchmarks (#6636) # Description These changes should enhance the quality of benchmark results by excluding worker initialization time from the measurements and reducing the overall duration of the benchmarks. ### Integration It should not affect any downstream projects. ### Review Notes - Workers initialize once per benchmark to avoid side effects. - The listen address is assigned when a worker starts. - Benchmarks are divided into two groups by size to create better charts for comparison. --------- Co-authored-by: GitHub Action --- prdoc/pr_6636.prdoc | 9 + .../network/benches/notifications_protocol.rs | 386 ++++++++---------- .../benches/request_response_protocol.rs | 318 ++++++++------- 3 files changed, 353 insertions(+), 360 deletions(-) create mode 100644 prdoc/pr_6636.prdoc diff --git a/prdoc/pr_6636.prdoc b/prdoc/pr_6636.prdoc new file mode 100644 index 000000000000..1db5fd54d971 --- /dev/null +++ b/prdoc/pr_6636.prdoc @@ -0,0 +1,9 @@ +title: Optimize initialization of networking protocol benchmarks +doc: +- audience: Node Dev + description: |- + These changes should enhance the quality of benchmark results by excluding worker initialization time from the measurements and reducing the overall duration of the benchmarks. + +crates: +- name: sc-network + validate: false diff --git a/substrate/client/network/benches/notifications_protocol.rs b/substrate/client/network/benches/notifications_protocol.rs index c1e18c7b7f47..40a810d616b5 100644 --- a/substrate/client/network/benches/notifications_protocol.rs +++ b/substrate/client/network/benches/notifications_protocol.rs @@ -25,55 +25,42 @@ use sc_network::{ FullNetworkConfiguration, MultiaddrWithPeerId, NetworkConfiguration, NonReservedPeerMode, NotificationHandshake, Params, ProtocolId, Role, SetConfig, }, - service::traits::NotificationEvent, + service::traits::{NetworkService, NotificationEvent}, Litep2pNetworkBackend, NetworkBackend, NetworkWorker, NotificationMetrics, NotificationService, - Roles, + PeerId, Roles, }; use sc_network_common::{sync::message::BlockAnnouncesHandshake, ExHashT}; -use sc_network_types::build_multiaddr; use sp_core::H256; use sp_runtime::traits::{Block as BlockT, Zero}; -use std::{ - net::{IpAddr, Ipv4Addr, TcpListener}, - str::FromStr, -}; +use std::{sync::Arc, time::Duration}; use substrate_test_runtime_client::runtime; +use tokio::{sync::Mutex, task::JoinHandle}; -const MAX_SIZE: u64 = 2u64.pow(30); -const SAMPLE_SIZE: usize = 50; -const NOTIFICATIONS: usize = 50; -const EXPONENTS: &[(u32, &'static str)] = &[ - (6, "64B"), - (9, "512B"), - (12, "4KB"), - (15, "64KB"), - (18, "256KB"), - (21, "2MB"), - (24, "16MB"), - (27, "128MB"), +const SMALL_PAYLOAD: &[(u32, usize, &'static str)] = &[ + // (Exponent of size, number of notifications, label) + (6, 100, "64B"), + (9, 100, "512B"), + (12, 100, "4KB"), + (15, 100, "64KB"), ]; - -// TODO: It's be better to bind system-provided port when initializing the worker -fn get_listen_address() -> sc_network::Multiaddr { - let ip = Ipv4Addr::from_str("127.0.0.1").unwrap(); - let listener = TcpListener::bind((IpAddr::V4(ip), 0)).unwrap(); // Bind to a random port - let local_addr = listener.local_addr().unwrap(); - let port = local_addr.port(); - - build_multiaddr!(Ip4(ip), Tcp(port)) -} +const LARGE_PAYLOAD: &[(u32, usize, &'static str)] = &[ + // (Exponent of size, number of notifications, label) + (18, 10, "256KB"), + (21, 10, "2MB"), + (24, 10, "16MB"), + (27, 10, "128MB"), +]; +const MAX_SIZE: u64 = 2u64.pow(30); fn create_network_worker( - listen_addr: sc_network::Multiaddr, -) -> (N, Box) +) -> (N, Arc, Arc>>) where B: BlockT + 'static, H: ExHashT, N: NetworkBackend, { let role = Role::Full; - let mut net_conf = NetworkConfiguration::new_local(); - net_conf.listen_addresses = vec![listen_addr]; + let net_conf = NetworkConfiguration::new_local(); let network_config = FullNetworkConfiguration::::new(&net_conf, None); let genesis_hash = runtime::Hash::zero(); let (block_announce_config, notification_service) = N::notification_config( @@ -110,96 +97,122 @@ where notification_metrics: NotificationMetrics::new(None), }) .unwrap(); + let network_service = worker.network_service(); + let notification_service = Arc::new(Mutex::new(notification_service)); - (worker, notification_service) + (worker, network_service, notification_service) } -async fn run_serially(size: usize, limit: usize) +struct BenchSetup { + notification_service1: Arc>>, + notification_service2: Arc>>, + peer_id2: PeerId, + handle1: JoinHandle<()>, + handle2: JoinHandle<()>, +} + +impl Drop for BenchSetup { + fn drop(&mut self) { + self.handle1.abort(); + self.handle2.abort(); + } +} + +fn setup_workers(rt: &tokio::runtime::Runtime) -> Arc where B: BlockT + 'static, H: ExHashT, N: NetworkBackend, { - let listen_address1 = get_listen_address(); - let listen_address2 = get_listen_address(); - let (worker1, mut notification_service1) = create_network_worker::(listen_address1); - let (worker2, mut notification_service2) = - create_network_worker::(listen_address2.clone()); - let peer_id2: sc_network::PeerId = worker2.network_service().local_peer_id().into(); + let _guard = rt.enter(); - worker1 - .network_service() - .add_reserved_peer(MultiaddrWithPeerId { multiaddr: listen_address2, peer_id: peer_id2 }) - .unwrap(); + let (worker1, network_service1, notification_service1) = create_network_worker::(); + let (worker2, network_service2, notification_service2) = create_network_worker::(); + let peer_id2: sc_network::PeerId = network_service2.local_peer_id().into(); + let handle1 = tokio::spawn(worker1.run()); + let handle2 = tokio::spawn(worker2.run()); - let network1_run = worker1.run(); - let network2_run = worker2.run(); - let (tx, rx) = async_channel::bounded(10); + let ready = tokio::spawn({ + let notification_service1 = Arc::clone(¬ification_service1); + let notification_service2 = Arc::clone(¬ification_service2); - let network1 = tokio::spawn(async move { - let mut sent_counter = 0; - tokio::pin!(network1_run); - loop { - tokio::select! { - _ = &mut network1_run => {}, - event = notification_service1.next_event() => { - match event { - Some(NotificationEvent::NotificationStreamOpened { .. }) => { - sent_counter += 1; - notification_service1 - .send_async_notification(&peer_id2, vec![0; size]) - .await - .unwrap(); - }, - Some(NotificationEvent::NotificationStreamClosed { .. }) => { - if sent_counter >= limit { - break; - } - panic!("Unexpected stream closure {:?}", event); - } - event => panic!("Unexpected event {:?}", event), - }; - }, - message = rx.recv() => { - match message { - Ok(Some(_)) => { - sent_counter += 1; - notification_service1 - .send_async_notification(&peer_id2, vec![0; size]) - .await - .unwrap(); - }, - Ok(None) => break, - Err(err) => panic!("Unexpected error {:?}", err), + async move { + let listen_address2 = { + while network_service2.listen_addresses().is_empty() { + tokio::time::sleep(Duration::from_millis(10)).await; + } + network_service2.listen_addresses()[0].clone() + }; + network_service1 + .add_reserved_peer(MultiaddrWithPeerId { + multiaddr: listen_address2, + peer_id: peer_id2, + }) + .unwrap(); - } + let mut notification_service1 = notification_service1.lock().await; + let mut notification_service2 = notification_service2.lock().await; + loop { + tokio::select! { + Some(event) = notification_service1.next_event() => { + if let NotificationEvent::NotificationStreamOpened { .. } = event { + break; + } + }, + Some(event) = notification_service2.next_event() => { + if let NotificationEvent::ValidateInboundSubstream { result_tx, .. } = event { + result_tx.send(sc_network::service::traits::ValidationResult::Accept).unwrap(); + } + }, } } } }); - let network2 = tokio::spawn(async move { - let mut received_counter = 0; - tokio::pin!(network2_run); - loop { - tokio::select! { - _ = &mut network2_run => {}, - event = notification_service2.next_event() => { - match event { - Some(NotificationEvent::ValidateInboundSubstream { result_tx, .. }) => { - result_tx.send(sc_network::service::traits::ValidationResult::Accept).unwrap(); - }, - Some(NotificationEvent::NotificationStreamOpened { .. }) => {}, - Some(NotificationEvent::NotificationReceived { .. }) => { - received_counter += 1; - if received_counter >= limit { - let _ = tx.send(None).await; - break - } - let _ = tx.send(Some(())).await; - }, - event => panic!("Unexpected event {:?}", event), - }; - }, + + tokio::task::block_in_place(|| { + let _ = tokio::runtime::Handle::current().block_on(ready); + }); + + Arc::new(BenchSetup { + notification_service1, + notification_service2, + peer_id2, + handle1, + handle2, + }) +} + +async fn run_serially(setup: Arc, size: usize, limit: usize) { + let (tx, rx) = async_channel::bounded(1); + let _ = tx.send(Some(())).await; + let network1 = tokio::spawn({ + let notification_service1 = Arc::clone(&setup.notification_service1); + let peer_id2 = setup.peer_id2; + async move { + let mut notification_service1 = notification_service1.lock().await; + while let Ok(message) = rx.recv().await { + let Some(_) = message else { break }; + notification_service1 + .send_async_notification(&peer_id2, vec![0; size]) + .await + .unwrap(); + } + } + }); + let network2 = tokio::spawn({ + let notification_service2 = Arc::clone(&setup.notification_service2); + async move { + let mut notification_service2 = notification_service2.lock().await; + let mut received_counter = 0; + while let Some(event) = notification_service2.next_event().await { + if let NotificationEvent::NotificationReceived { .. } = event { + received_counter += 1; + if received_counter >= limit { + let _ = tx.send(None).await; + break; + } + let _ = tx.send(Some(())).await; + } } } }); @@ -207,77 +220,34 @@ where let _ = tokio::join!(network1, network2); } -async fn run_with_backpressure(size: usize, limit: usize) -where - B: BlockT + 'static, - H: ExHashT, - N: NetworkBackend, -{ - let listen_address1 = get_listen_address(); - let listen_address2 = get_listen_address(); - let (worker1, mut notification_service1) = create_network_worker::(listen_address1); - let (worker2, mut notification_service2) = - create_network_worker::(listen_address2.clone()); - let peer_id2: sc_network::PeerId = worker2.network_service().local_peer_id().into(); - - worker1 - .network_service() - .add_reserved_peer(MultiaddrWithPeerId { multiaddr: listen_address2, peer_id: peer_id2 }) - .unwrap(); - - let network1_run = worker1.run(); - let network2_run = worker2.run(); - - let network1 = tokio::spawn(async move { - let mut sent_counter = 0; - tokio::pin!(network1_run); - loop { - tokio::select! { - _ = &mut network1_run => {}, - event = notification_service1.next_event() => { - match event { - Some(NotificationEvent::NotificationStreamOpened { .. }) => { - while sent_counter < limit { - sent_counter += 1; - notification_service1 - .send_async_notification(&peer_id2, vec![0; size]) - .await - .unwrap(); - } - }, - Some(NotificationEvent::NotificationStreamClosed { .. }) => { - if sent_counter != limit { panic!("Stream closed unexpectedly") } - break - }, - event => panic!("Unexpected event {:?}", event), - }; - }, +async fn run_with_backpressure(setup: Arc, size: usize, limit: usize) { + let (tx, rx) = async_channel::bounded(1); + let network1 = tokio::spawn({ + let setup = Arc::clone(&setup); + async move { + let mut notification_service1 = setup.notification_service1.lock().await; + for _ in 0..limit { + notification_service1 + .send_async_notification(&setup.peer_id2, vec![0; size]) + .await + .unwrap(); } + let _ = rx.recv().await; } }); - let network2 = tokio::spawn(async move { - let mut received_counter = 0; - tokio::pin!(network2_run); - loop { - tokio::select! { - _ = &mut network2_run => {}, - event = notification_service2.next_event() => { - match event { - Some(NotificationEvent::ValidateInboundSubstream { result_tx, .. }) => { - result_tx.send(sc_network::service::traits::ValidationResult::Accept).unwrap(); - }, - Some(NotificationEvent::NotificationStreamOpened { .. }) => {}, - Some(NotificationEvent::NotificationStreamClosed { .. }) => { - if received_counter != limit { panic!("Stream closed unexpectedly") } - break - }, - Some(NotificationEvent::NotificationReceived { .. }) => { - received_counter += 1; - if received_counter >= limit { break } - }, - event => panic!("Unexpected event {:?}", event), - }; - }, + let network2 = tokio::spawn({ + let setup = Arc::clone(&setup); + async move { + let mut notification_service2 = setup.notification_service2.lock().await; + let mut received_counter = 0; + while let Some(event) = notification_service2.next_event().await { + if let NotificationEvent::NotificationReceived { .. } = event { + received_counter += 1; + if received_counter >= limit { + let _ = tx.send(()).await; + break; + } + } } } }); @@ -285,64 +255,64 @@ where let _ = tokio::join!(network1, network2); } -fn run_benchmark(c: &mut Criterion) { +fn run_benchmark(c: &mut Criterion, payload: &[(u32, usize, &'static str)], group: &str) { let rt = tokio::runtime::Runtime::new().unwrap(); let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); - let mut group = c.benchmark_group("notifications_benchmark"); + let mut group = c.benchmark_group(group); group.plot_config(plot_config); - for &(exponent, label) in EXPONENTS.iter() { + let libp2p_setup = setup_workers::>(&rt); + for &(exponent, limit, label) in payload.iter() { let size = 2usize.pow(exponent); - group.throughput(Throughput::Bytes(NOTIFICATIONS as u64 * size as u64)); - + group.throughput(Throughput::Bytes(limit as u64 * size as u64)); group.bench_with_input( BenchmarkId::new("libp2p/serially", label), - &(size, NOTIFICATIONS), + &(size, limit), |b, &(size, limit)| { - b.to_async(&rt).iter(|| { - run_serially::>(size, limit) - }); + b.to_async(&rt).iter(|| run_serially(Arc::clone(&libp2p_setup), size, limit)); }, ); group.bench_with_input( - BenchmarkId::new("litep2p/serially", label), - &(size, NOTIFICATIONS), + BenchmarkId::new("libp2p/with_backpressure", label), + &(size, limit), |b, &(size, limit)| { - b.to_async(&rt).iter(|| { - run_serially::( - size, limit, - ) - }); + b.to_async(&rt) + .iter(|| run_with_backpressure(Arc::clone(&libp2p_setup), size, limit)); }, ); + } + drop(libp2p_setup); + + let litep2p_setup = setup_workers::(&rt); + for &(exponent, limit, label) in payload.iter() { + let size = 2usize.pow(exponent); + group.throughput(Throughput::Bytes(limit as u64 * size as u64)); group.bench_with_input( - BenchmarkId::new("libp2p/with_backpressure", label), - &(size, NOTIFICATIONS), + BenchmarkId::new("litep2p/serially", label), + &(size, limit), |b, &(size, limit)| { - b.to_async(&rt).iter(|| { - run_with_backpressure::>( - size, limit, - ) - }); + b.to_async(&rt).iter(|| run_serially(Arc::clone(&litep2p_setup), size, limit)); }, ); group.bench_with_input( BenchmarkId::new("litep2p/with_backpressure", label), - &(size, NOTIFICATIONS), + &(size, limit), |b, &(size, limit)| { - b.to_async(&rt).iter(|| { - run_with_backpressure::( - size, limit, - ) - }); + b.to_async(&rt) + .iter(|| run_with_backpressure(Arc::clone(&litep2p_setup), size, limit)); }, ); } + drop(litep2p_setup); } -criterion_group! { - name = benches; - config = Criterion::default().sample_size(SAMPLE_SIZE); - targets = run_benchmark +fn run_benchmark_with_small_payload(c: &mut Criterion) { + run_benchmark(c, SMALL_PAYLOAD, "notifications_protocol/small_payload"); } + +fn run_benchmark_with_large_payload(c: &mut Criterion) { + run_benchmark(c, LARGE_PAYLOAD, "notifications_protocol/large_payload"); +} + +criterion_group!(benches, run_benchmark_with_small_payload, run_benchmark_with_large_payload); criterion_main!(benches); diff --git a/substrate/client/network/benches/request_response_protocol.rs b/substrate/client/network/benches/request_response_protocol.rs index b428d0d75ac5..85381112b753 100644 --- a/substrate/client/network/benches/request_response_protocol.rs +++ b/substrate/client/network/benches/request_response_protocol.rs @@ -25,46 +25,39 @@ use sc_network::{ FullNetworkConfiguration, IncomingRequest, NetworkConfiguration, NonReservedPeerMode, NotificationHandshake, OutgoingResponse, Params, ProtocolId, Role, SetConfig, }, + service::traits::NetworkService, IfDisconnected, Litep2pNetworkBackend, NetworkBackend, NetworkRequest, NetworkWorker, - NotificationMetrics, NotificationService, Roles, + NotificationMetrics, NotificationService, PeerId, Roles, }; use sc_network_common::{sync::message::BlockAnnouncesHandshake, ExHashT}; -use sc_network_types::build_multiaddr; use sp_core::H256; use sp_runtime::traits::{Block as BlockT, Zero}; -use std::{ - net::{IpAddr, Ipv4Addr, TcpListener}, - str::FromStr, - time::Duration, -}; +use std::{sync::Arc, time::Duration}; use substrate_test_runtime_client::runtime; +use tokio::{sync::Mutex, task::JoinHandle}; const MAX_SIZE: u64 = 2u64.pow(30); -const SAMPLE_SIZE: usize = 50; -const REQUESTS: usize = 50; -const EXPONENTS: &[(u32, &'static str)] = &[ - (6, "64B"), - (9, "512B"), - (12, "4KB"), - (15, "64KB"), - (18, "256KB"), - (21, "2MB"), - (24, "16MB"), - (27, "128MB"), +const SMALL_PAYLOAD: &[(u32, usize, &'static str)] = &[ + // (Exponent of size, number of requests, label) + (6, 100, "64B"), + (9, 100, "512B"), + (12, 100, "4KB"), + (15, 100, "64KB"), +]; +const LARGE_PAYLOAD: &[(u32, usize, &'static str)] = &[ + // (Exponent of size, number of requests, label) + (18, 10, "256KB"), + (21, 10, "2MB"), + (24, 10, "16MB"), + (27, 10, "128MB"), ]; -fn get_listen_address() -> sc_network::Multiaddr { - let ip = Ipv4Addr::from_str("127.0.0.1").unwrap(); - let listener = TcpListener::bind((IpAddr::V4(ip), 0)).unwrap(); // Bind to a random port - let local_addr = listener.local_addr().unwrap(); - let port = local_addr.port(); - - build_multiaddr!(Ip4(ip), Tcp(port)) -} - -pub fn create_network_worker( - listen_addr: sc_network::Multiaddr, -) -> (N, async_channel::Receiver, Box) +pub fn create_network_worker() -> ( + N, + Arc, + async_channel::Receiver, + Arc>>, +) where B: BlockT + 'static, H: ExHashT, @@ -80,8 +73,7 @@ where Some(tx), ); let role = Role::Full; - let mut net_conf = NetworkConfiguration::new_local(); - net_conf.listen_addresses = vec![listen_addr]; + let net_conf = NetworkConfiguration::new_local(); let mut network_config = FullNetworkConfiguration::new(&net_conf, None); network_config.add_request_response_protocol(request_response_config); let genesis_hash = runtime::Hash::zero(); @@ -119,71 +111,115 @@ where notification_metrics: NotificationMetrics::new(None), }) .unwrap(); + let notification_service = Arc::new(Mutex::new(notification_service)); + let network_service = worker.network_service(); - (worker, rx, notification_service) + (worker, network_service, rx, notification_service) } -async fn run_serially(size: usize, limit: usize) +struct BenchSetup { + #[allow(dead_code)] + notification_service1: Arc>>, + #[allow(dead_code)] + notification_service2: Arc>>, + network_service1: Arc, + peer_id2: PeerId, + handle1: JoinHandle<()>, + handle2: JoinHandle<()>, + #[allow(dead_code)] + rx1: async_channel::Receiver, + rx2: async_channel::Receiver, +} + +impl Drop for BenchSetup { + fn drop(&mut self) { + self.handle1.abort(); + self.handle2.abort(); + } +} + +fn setup_workers(rt: &tokio::runtime::Runtime) -> Arc where B: BlockT + 'static, H: ExHashT, N: NetworkBackend, { - let listen_address1 = get_listen_address(); - let listen_address2 = get_listen_address(); - let (worker1, _rx1, _notification_service1) = create_network_worker::(listen_address1); - let service1 = worker1.network_service().clone(); - let (worker2, rx2, _notification_service2) = - create_network_worker::(listen_address2.clone()); + let _guard = rt.enter(); + + let (worker1, network_service1, rx1, notification_service1) = + create_network_worker::(); + let (worker2, network_service2, rx2, notification_service2) = + create_network_worker::(); let peer_id2 = worker2.network_service().local_peer_id(); + let handle1 = tokio::spawn(worker1.run()); + let handle2 = tokio::spawn(worker2.run()); - worker1.network_service().add_known_address(peer_id2, listen_address2.into()); + let ready = tokio::spawn({ + let network_service1 = Arc::clone(&network_service1); - let network1_run = worker1.run(); - let network2_run = worker2.run(); - let (break_tx, break_rx) = async_channel::bounded(10); - let requests = async move { - let mut sent_counter = 0; - while sent_counter < limit { - let _ = service1 - .request( - peer_id2.into(), - "/request-response/1".into(), - vec![0; 2], - None, - IfDisconnected::TryConnect, - ) - .await - .unwrap(); - sent_counter += 1; + async move { + let listen_address2 = { + while network_service2.listen_addresses().is_empty() { + tokio::time::sleep(Duration::from_millis(10)).await; + } + network_service2.listen_addresses()[0].clone() + }; + network_service1.add_known_address(peer_id2, listen_address2.into()); } - let _ = break_tx.send(()).await; - }; + }); - let network1 = tokio::spawn(async move { - tokio::pin!(requests); - tokio::pin!(network1_run); - loop { - tokio::select! { - _ = &mut network1_run => {}, - _ = &mut requests => break, + tokio::task::block_in_place(|| { + let _ = tokio::runtime::Handle::current().block_on(ready); + }); + + Arc::new(BenchSetup { + notification_service1, + notification_service2, + network_service1, + peer_id2, + handle1, + handle2, + rx1, + rx2, + }) +} + +async fn run_serially(setup: Arc, size: usize, limit: usize) { + let (break_tx, break_rx) = async_channel::bounded(1); + let network1 = tokio::spawn({ + let network_service1 = Arc::clone(&setup.network_service1); + let peer_id2 = setup.peer_id2; + async move { + for _ in 0..limit { + let _ = network_service1 + .request( + peer_id2.into(), + "/request-response/1".into(), + vec![0; 2], + None, + IfDisconnected::TryConnect, + ) + .await + .unwrap(); } + let _ = break_tx.send(()).await; } }); - let network2 = tokio::spawn(async move { - tokio::pin!(network2_run); - loop { - tokio::select! { - _ = &mut network2_run => {}, - res = rx2.recv() => { - let IncomingRequest { pending_response, .. } = res.unwrap(); - pending_response.send(OutgoingResponse { - result: Ok(vec![0; size]), - reputation_changes: vec![], - sent_feedback: None, - }).unwrap(); - }, - _ = break_rx.recv() => break, + let network2 = tokio::spawn({ + let rx2 = setup.rx2.clone(); + async move { + loop { + tokio::select! { + res = rx2.recv() => { + let IncomingRequest { pending_response, .. } = res.unwrap(); + pending_response.send(OutgoingResponse { + result: Ok(vec![0; size]), + reputation_changes: vec![], + sent_feedback: None, + }).unwrap(); + }, + _ = break_rx.recv() => break, + } } } }); @@ -194,29 +230,12 @@ where // The libp2p request-response implementation does not provide any backpressure feedback. // So this benchmark is useless until we implement it for litep2p. #[allow(dead_code)] -async fn run_with_backpressure(size: usize, limit: usize) -where - B: BlockT + 'static, - H: ExHashT, - N: NetworkBackend, -{ - let listen_address1 = get_listen_address(); - let listen_address2 = get_listen_address(); - let (worker1, _rx1, _notification_service1) = create_network_worker::(listen_address1); - let service1 = worker1.network_service().clone(); - let (worker2, rx2, _notification_service2) = - create_network_worker::(listen_address2.clone()); - let peer_id2 = worker2.network_service().local_peer_id(); - - worker1.network_service().add_known_address(peer_id2, listen_address2.into()); - - let network1_run = worker1.run(); - let network2_run = worker2.run(); - let (break_tx, break_rx) = async_channel::bounded(10); +async fn run_with_backpressure(setup: Arc, size: usize, limit: usize) { + let (break_tx, break_rx) = async_channel::bounded(1); let requests = futures::future::join_all((0..limit).into_iter().map(|_| { let (tx, rx) = futures::channel::oneshot::channel(); - service1.start_request( - peer_id2.into(), + setup.network_service1.start_request( + setup.peer_id2.into(), "/request-response/1".into(), vec![0; 8], None, @@ -227,77 +246,72 @@ where })); let network1 = tokio::spawn(async move { - tokio::pin!(requests); - tokio::pin!(network1_run); - loop { - tokio::select! { - _ = &mut network1_run => {}, - responses = &mut requests => { - for res in responses { - res.unwrap().unwrap(); - } - let _ = break_tx.send(()).await; - break; - }, - } + let responses = requests.await; + for res in responses { + res.unwrap().unwrap(); } + let _ = break_tx.send(()).await; }); let network2 = tokio::spawn(async move { - tokio::pin!(network2_run); - loop { - tokio::select! { - _ = &mut network2_run => {}, - res = rx2.recv() => { - let IncomingRequest { pending_response, .. } = res.unwrap(); - pending_response.send(OutgoingResponse { - result: Ok(vec![0; size]), - reputation_changes: vec![], - sent_feedback: None, - }).unwrap(); - }, - _ = break_rx.recv() => break, - } + for _ in 0..limit { + let IncomingRequest { pending_response, .. } = setup.rx2.recv().await.unwrap(); + pending_response + .send(OutgoingResponse { + result: Ok(vec![0; size]), + reputation_changes: vec![], + sent_feedback: None, + }) + .unwrap(); } + break_rx.recv().await }); let _ = tokio::join!(network1, network2); } -fn run_benchmark(c: &mut Criterion) { +fn run_benchmark(c: &mut Criterion, payload: &[(u32, usize, &'static str)], group: &str) { let rt = tokio::runtime::Runtime::new().unwrap(); let plot_config = PlotConfiguration::default().summary_scale(AxisScale::Logarithmic); - let mut group = c.benchmark_group("request_response_benchmark"); + let mut group = c.benchmark_group(group); group.plot_config(plot_config); - for &(exponent, label) in EXPONENTS.iter() { + let libp2p_setup = setup_workers::>(&rt); + for &(exponent, limit, label) in payload.iter() { let size = 2usize.pow(exponent); - group.throughput(Throughput::Bytes(REQUESTS as u64 * size as u64)); + group.throughput(Throughput::Bytes(limit as u64 * size as u64)); group.bench_with_input( BenchmarkId::new("libp2p/serially", label), - &(size, REQUESTS), - |b, &(size, limit)| { - b.to_async(&rt).iter(|| { - run_serially::>(size, limit) - }); - }, - ); - group.bench_with_input( - BenchmarkId::new("litep2p/serially", label), - &(size, REQUESTS), + &(size, limit), |b, &(size, limit)| { - b.to_async(&rt).iter(|| { - run_serially::( - size, limit, - ) - }); + b.to_async(&rt).iter(|| run_serially(Arc::clone(&libp2p_setup), size, limit)); }, ); } + drop(libp2p_setup); + + // TODO: NetworkRequest::request should be implemented for Litep2pNetworkService + let litep2p_setup = setup_workers::(&rt); + // for &(exponent, limit, label) in payload.iter() { + // let size = 2usize.pow(exponent); + // group.throughput(Throughput::Bytes(limit as u64 * size as u64)); + // group.bench_with_input( + // BenchmarkId::new("litep2p/serially", label), + // &(size, limit), + // |b, &(size, limit)| { + // b.to_async(&rt).iter(|| run_serially(Arc::clone(&litep2p_setup), size, limit)); + // }, + // ); + // } + drop(litep2p_setup); } -criterion_group! { - name = benches; - config = Criterion::default().sample_size(SAMPLE_SIZE); - targets = run_benchmark +fn run_benchmark_with_small_payload(c: &mut Criterion) { + run_benchmark(c, SMALL_PAYLOAD, "request_response_benchmark/small_payload"); } + +fn run_benchmark_with_large_payload(c: &mut Criterion) { + run_benchmark(c, LARGE_PAYLOAD, "request_response_benchmark/large_payload"); +} + +criterion_group!(benches, run_benchmark_with_small_payload, run_benchmark_with_large_payload); criterion_main!(benches); From df1375ea8dabda5ba0b79f268b4883c65f59bf2f Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:55:13 +0100 Subject: [PATCH 16/51] chainHead: Always report discarded items for storage operations (#6760) This PR ensures that substrate always reports discarded items as zero. This is needed to align with the rpc-v2 spec Closes: https://github.com/paritytech/polkadot-sdk/issues/6683 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile Co-authored-by: GitHub Action --- prdoc/pr_6760.prdoc | 9 +++++++++ .../client/rpc-spec-v2/src/chain_head/chain_head.rs | 10 ++++++---- substrate/client/rpc-spec-v2/src/chain_head/tests.rs | 7 +++++-- 3 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 prdoc/pr_6760.prdoc diff --git a/prdoc/pr_6760.prdoc b/prdoc/pr_6760.prdoc new file mode 100644 index 000000000000..8224b72fb0a4 --- /dev/null +++ b/prdoc/pr_6760.prdoc @@ -0,0 +1,9 @@ +title: 'chainHead: Always report discarded items for storage operations' +doc: +- audience: [Node Dev, Node Operator] + description: |- + This PR ensures that substrate always reports discarded items as zero. + This is needed to align with the rpc-v2 spec +crates: +- name: sc-rpc-spec-v2 + bump: patch diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs index 61eb47d1b9ab..b949fb25402b 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs @@ -318,7 +318,7 @@ where }), }; - let (rp, rp_fut) = method_started_response(operation_id); + let (rp, rp_fut) = method_started_response(operation_id, None); let fut = async move { // Wait for the server to send out the response and if it produces an error no event // should be generated. @@ -432,7 +432,8 @@ where let mut storage_client = ChainHeadStorage::::new(self.client.clone()); - let (rp, rp_fut) = method_started_response(block_guard.operation().operation_id()); + // Storage items are never discarded. + let (rp, rp_fut) = method_started_response(block_guard.operation().operation_id(), Some(0)); let fut = async move { // Wait for the server to send out the response and if it produces an error no event @@ -507,7 +508,7 @@ where let operation_id = block_guard.operation().operation_id(); let client = self.client.clone(); - let (rp, rp_fut) = method_started_response(operation_id.clone()); + let (rp, rp_fut) = method_started_response(operation_id.clone(), None); let fut = async move { // Wait for the server to send out the response and if it produces an error no event // should be generated. @@ -630,8 +631,9 @@ where fn method_started_response( operation_id: String, + discarded_items: Option, ) -> (ResponsePayload<'static, MethodResponse>, MethodResponseFuture) { - let rp = MethodResponse::Started(MethodResponseStarted { operation_id, discarded_items: None }); + let rp = MethodResponse::Started(MethodResponseStarted { operation_id, discarded_items }); ResponsePayload::success(rp).notify_on_completion() } diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs index 21e8365622a1..43b52175bd6d 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs @@ -2871,7 +2871,7 @@ async fn ensure_operation_limits_works() { let operation_id = match response { MethodResponse::Started(started) => { // Check discarded items. - assert!(started.discarded_items.is_none()); + assert_eq!(started.discarded_items, Some(0)); started.operation_id }, MethodResponse::LimitReached => panic!("Expected started response"), @@ -3228,7 +3228,10 @@ async fn storage_closest_merkle_value() { .await .unwrap(); let operation_id = match response { - MethodResponse::Started(started) => started.operation_id, + MethodResponse::Started(started) => { + assert_eq!(started.discarded_items, Some(0)); + started.operation_id + }, MethodResponse::LimitReached => panic!("Expected started response"), }; From 44766de645c741fd03d159fca7f17cd6e99c33e3 Mon Sep 17 00:00:00 2001 From: Javier Viola <363911+pepoviola@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:12:32 +0100 Subject: [PATCH 17/51] bump zombienet and re-enable test (#6090) Re-enable zombienet test for `solochain`. Thx! --- .gitlab/pipeline/zombienet/parachain-template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/pipeline/zombienet/parachain-template.yml b/.gitlab/pipeline/zombienet/parachain-template.yml index 896ba7913be7..d5c1b6558b39 100644 --- a/.gitlab/pipeline/zombienet/parachain-template.yml +++ b/.gitlab/pipeline/zombienet/parachain-template.yml @@ -43,4 +43,4 @@ zombienet-parachain-template-smoke: - ls -ltr $(pwd)/artifacts - cargo test -p template-zombienet-tests --features zombienet --tests minimal_template_block_production_test - cargo test -p template-zombienet-tests --features zombienet --tests parachain_template_block_production_test - # - cargo test -p template-zombienet-tests --features zombienet --tests solochain_template_block_production_test + - cargo test -p template-zombienet-tests --features zombienet --tests solochain_template_block_production_test From 0d3d450273af6ddb9a6733683726628a8d1d3c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Thu, 5 Dec 2024 16:50:45 +0100 Subject: [PATCH 18/51] pallet-revive: Adjust error handling of sub calls (#6741) We were trapping the host context in case a sub call was exhausting the storage deposit limit set for this sub call. This prevents the caller from handling this error. In this PR we added a new error code that is returned when either gas or storage deposit limit is exhausted by the sub call. We also remove the longer used `NotCallable` error. No longer used because this is no longer an error: It will just be a balance transfer. We also make `set_code_hash` infallible to be consistent with other host functions which just trap on any error condition. --------- Co-authored-by: GitHub Action --- prdoc/pr_6741.prdoc | 16 ++++ .../fixtures/contracts/caller_contract.rs | 8 +- .../contracts/create_storage_and_call.rs | 8 +- .../create_storage_and_instantiate.rs | 8 +- .../contracts/delegate_call_deposit_limit.rs | 6 +- .../fixtures/contracts/set_code_hash.rs | 2 +- substrate/frame/revive/src/exec.rs | 16 ++-- substrate/frame/revive/src/tests.rs | 75 ++++++++----------- substrate/frame/revive/src/wasm/runtime.rs | 46 ++++-------- substrate/frame/revive/uapi/src/host.rs | 12 +-- .../frame/revive/uapi/src/host/riscv64.rs | 7 +- substrate/frame/revive/uapi/src/lib.rs | 18 ++--- 12 files changed, 109 insertions(+), 113 deletions(-) create mode 100644 prdoc/pr_6741.prdoc diff --git a/prdoc/pr_6741.prdoc b/prdoc/pr_6741.prdoc new file mode 100644 index 000000000000..d4b795038bcd --- /dev/null +++ b/prdoc/pr_6741.prdoc @@ -0,0 +1,16 @@ +title: 'pallet-revive: Adjust error handling of sub calls' +doc: +- audience: Runtime Dev + description: |- + We were trapping the host context in case a sub call was exhausting the storage deposit limit set for this sub call. This prevents the caller from handling this error. In this PR we added a new error code that is returned when either gas or storage deposit limit is exhausted by the sub call. + + We also remove the longer used `NotCallable` error. No longer used because this is no longer an error: It will just be a balance transfer. + + We also make `set_code_hash` infallible to be consistent with other host functions which just trap on any error condition. +crates: +- name: pallet-revive + bump: major +- name: pallet-revive-uapi + bump: major +- name: pallet-revive-fixtures + bump: major diff --git a/substrate/frame/revive/fixtures/contracts/caller_contract.rs b/substrate/frame/revive/fixtures/contracts/caller_contract.rs index f9a30b87df47..edad43fae251 100644 --- a/substrate/frame/revive/fixtures/contracts/caller_contract.rs +++ b/substrate/frame/revive/fixtures/contracts/caller_contract.rs @@ -65,7 +65,7 @@ pub extern "C" fn call() { None, Some(&salt), ); - assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + assert!(matches!(res, Err(ReturnErrorCode::OutOfResources))); // Fail to deploy the contract due to insufficient proof_size weight. let res = api::instantiate( @@ -79,7 +79,7 @@ pub extern "C" fn call() { None, Some(&salt), ); - assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + assert!(matches!(res, Err(ReturnErrorCode::OutOfResources))); // Deploy the contract successfully. let mut callee = [0u8; 20]; @@ -121,7 +121,7 @@ pub extern "C" fn call() { &input, None, ); - assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + assert!(matches!(res, Err(ReturnErrorCode::OutOfResources))); // Fail to call the contract due to insufficient proof_size weight. let res = api::call( @@ -134,7 +134,7 @@ pub extern "C" fn call() { &input, None, ); - assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + assert!(matches!(res, Err(ReturnErrorCode::OutOfResources))); // Call the contract successfully. let mut output = [0u8; 4]; diff --git a/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs b/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs index 4fa2db0c8c1c..a12c36af856a 100644 --- a/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs +++ b/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs @@ -40,7 +40,7 @@ pub extern "C" fn call() { api::set_storage(StorageFlags::empty(), buffer, &[1u8; 4]); // Call the callee - api::call( + let ret = api::call( uapi::CallFlags::empty(), callee, 0u64, // How much ref_time weight to devote for the execution. 0 = all. @@ -49,8 +49,10 @@ pub extern "C" fn call() { &[0u8; 32], // Value transferred to the contract. input, None, - ) - .unwrap(); + ); + if let Err(code) = ret { + api::return_value(uapi::ReturnFlags::REVERT, &(code as u32).to_le_bytes()); + }; // create 8 byte of storage after calling // item of 12 bytes because we override 4 bytes diff --git a/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs b/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs index 463706457a15..ecc0fc79e6fd 100644 --- a/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs +++ b/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs @@ -39,7 +39,7 @@ pub extern "C" fn call() { let salt = [0u8; 32]; let mut address = [0u8; 20]; - api::instantiate( + let ret = api::instantiate( code_hash, 0u64, // How much ref_time weight to devote for the execution. 0 = all. 0u64, // How much proof_size weight to devote for the execution. 0 = all. @@ -49,8 +49,10 @@ pub extern "C" fn call() { Some(&mut address), None, Some(&salt), - ) - .unwrap(); + ); + if let Err(code) = ret { + api::return_value(uapi::ReturnFlags::REVERT, &(code as u32).to_le_bytes()); + }; // Return the deployed contract address. api::return_value(uapi::ReturnFlags::empty(), &address); diff --git a/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs b/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs index 55203d534c9b..0f157f5a18ac 100644 --- a/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs +++ b/substrate/frame/revive/fixtures/contracts/delegate_call_deposit_limit.rs @@ -34,7 +34,11 @@ pub extern "C" fn call() { ); let input = [0u8; 0]; - api::delegate_call(uapi::CallFlags::empty(), address, 0, 0, Some(&u256_bytes(deposit_limit)), &input, None).unwrap(); + let ret = api::delegate_call(uapi::CallFlags::empty(), address, 0, 0, Some(&u256_bytes(deposit_limit)), &input, None); + + if let Err(code) = ret { + api::return_value(uapi::ReturnFlags::REVERT, &(code as u32).to_le_bytes()); + }; let mut key = [0u8; 32]; key[0] = 1u8; diff --git a/substrate/frame/revive/fixtures/contracts/set_code_hash.rs b/substrate/frame/revive/fixtures/contracts/set_code_hash.rs index 75995d7bb8a2..7292c6fd10ae 100644 --- a/substrate/frame/revive/fixtures/contracts/set_code_hash.rs +++ b/substrate/frame/revive/fixtures/contracts/set_code_hash.rs @@ -29,7 +29,7 @@ pub extern "C" fn deploy() {} #[polkavm_derive::polkavm_export] pub extern "C" fn call() { input!(addr: &[u8; 32],); - api::set_code_hash(addr).unwrap(); + api::set_code_hash(addr); // we return 1 after setting new code_hash // next `call` will NOT return this value, because contract code has been changed diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs index b23d7e4e60ef..b6f0e3ae1a81 100644 --- a/substrate/frame/revive/src/exec.rs +++ b/substrate/frame/revive/src/exec.rs @@ -1068,7 +1068,7 @@ where self.transient_storage.start_transaction(); - let do_transaction = || { + let do_transaction = || -> ExecResult { let caller = self.caller(); let frame = top_frame_mut!(self); @@ -1107,11 +1107,8 @@ where let call_span = T::Debug::new_call_span(&contract_address, entry_point, &input_data); let output = T::Debug::intercept_call(&contract_address, entry_point, &input_data) - .unwrap_or_else(|| { - executable - .execute(self, entry_point, input_data) - .map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee }) - })?; + .unwrap_or_else(|| executable.execute(self, entry_point, input_data)) + .map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?; call_span.after_call(&output); @@ -1136,7 +1133,10 @@ where // If a special limit was set for the sub-call, we enforce it here. // The sub-call will be rolled back in case the limit is exhausted. let contract = frame.contract_info.as_contract(); - frame.nested_storage.enforce_subcall_limit(contract)?; + frame + .nested_storage + .enforce_subcall_limit(contract) + .map_err(|e| ExecError { error: e, origin: ErrorOrigin::Callee })?; let account_id = T::AddressMapper::to_address(&frame.account_id); match (entry_point, delegated_code_hash) { @@ -3412,7 +3412,7 @@ mod tests { true, false ), - >::TransferFailed + >::TransferFailed, ); exec_success() }); diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index 1df300f031a7..a612e7760acb 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -38,8 +38,8 @@ use crate::{ wasm::Memory, weights::WeightInfo, AccountId32Mapper, BalanceOf, Code, CodeInfoOf, CollectEvents, Config, ContractInfo, - ContractInfoOf, DebugInfo, DeletionQueueCounter, Error, HoldReason, Origin, Pallet, - PristineCode, H160, + ContractInfoOf, DebugInfo, DeletionQueueCounter, DepositLimit, Error, HoldReason, Origin, + Pallet, PristineCode, H160, }; use crate::test_utils::builder::Contract; @@ -1211,14 +1211,11 @@ fn delegate_call_with_deposit_limit() { // Delegate call will write 1 storage and deposit of 2 (1 item) + 32 (bytes) is required. // Fails, not enough deposit - assert_err!( - builder::bare_call(caller_addr) - .value(1337) - .data((callee_addr, 33u64).encode()) - .build() - .result, - Error::::StorageDepositLimitExhausted, - ); + let ret = builder::bare_call(caller_addr) + .value(1337) + .data((callee_addr, 33u64).encode()) + .build_and_unwrap_result(); + assert_return_code!(ret, RuntimeReturnCode::OutOfResources); assert_ok!(builder::call(caller_addr) .value(1337) @@ -1678,8 +1675,8 @@ fn instantiate_return_code() { // Contract has enough balance but the passed code hash is invalid ::Currency::set_balance(&contract.account_id, min_balance + 10_000); - let result = builder::bare_call(contract.addr).data(vec![0; 33]).build_and_unwrap_result(); - assert_return_code!(result, RuntimeReturnCode::CodeNotFound); + let result = builder::bare_call(contract.addr).data(vec![0; 33]).build(); + assert_err!(result.result, >::CodeNotFound); // Contract has enough balance but callee reverts because "1" is passed. let result = builder::bare_call(contract.addr) @@ -3463,13 +3460,11 @@ fn deposit_limit_in_nested_calls() { // nested call. This should fail as callee adds up 2 bytes to the storage, meaning // that the nested call should have a deposit limit of at least 2 Balance. The // sub-call should be rolled back, which is covered by the next test case. - assert_err_ignore_postinfo!( - builder::call(addr_caller) - .storage_deposit_limit(16) - .data((102u32, &addr_callee, U256::from(1u64)).encode()) - .build(), - >::StorageDepositLimitExhausted, - ); + let ret = builder::bare_call(addr_caller) + .storage_deposit_limit(DepositLimit::Balance(16)) + .data((102u32, &addr_callee, U256::from(1u64)).encode()) + .build_and_unwrap_result(); + assert_return_code!(ret, RuntimeReturnCode::OutOfResources); // Refund in the callee contract but not enough to cover the 14 Balance required by the // caller. Note that if previous sub-call wouldn't roll back, this call would pass @@ -3485,13 +3480,11 @@ fn deposit_limit_in_nested_calls() { let _ = ::Currency::set_balance(&ALICE, 511); // Require more than the sender's balance. - // We don't set a special limit for the nested call. - assert_err_ignore_postinfo!( - builder::call(addr_caller) - .data((512u32, &addr_callee, U256::from(1u64)).encode()) - .build(), - >::StorageDepositLimitExhausted, - ); + // Limit the sub call to little balance so it should fail in there + let ret = builder::bare_call(addr_caller) + .data((512u32, &addr_callee, U256::from(1u64)).encode()) + .build_and_unwrap_result(); + assert_return_code!(ret, RuntimeReturnCode::OutOfResources); // Same as above but allow for the additional deposit of 1 Balance in parent. // We set the special deposit limit of 1 Balance for the nested call, which isn't @@ -3563,14 +3556,12 @@ fn deposit_limit_in_nested_instantiate() { // Now we set enough limit in parent call, but an insufficient limit for child // instantiate. This should fail during the charging for the instantiation in // `RawMeter::charge_instantiate()` - assert_err_ignore_postinfo!( - builder::call(addr_caller) - .origin(RuntimeOrigin::signed(BOB)) - .storage_deposit_limit(callee_info_len + 2 + ED + 2) - .data((0u32, &code_hash_callee, U256::from(callee_info_len + 2 + ED + 1)).encode()) - .build(), - >::StorageDepositLimitExhausted, - ); + let ret = builder::bare_call(addr_caller) + .origin(RuntimeOrigin::signed(BOB)) + .storage_deposit_limit(DepositLimit::Balance(callee_info_len + 2 + ED + 2)) + .data((0u32, &code_hash_callee, U256::from(callee_info_len + 2 + ED + 1)).encode()) + .build_and_unwrap_result(); + assert_return_code!(ret, RuntimeReturnCode::OutOfResources); // The charges made on the instantiation should be rolled back. assert_eq!(::Currency::free_balance(&BOB), 1_000_000); @@ -3578,14 +3569,12 @@ fn deposit_limit_in_nested_instantiate() { // item of 1 byte to be covered by the limit, which implies 3 more Balance. // Now we set enough limit for the parent call, but insufficient limit for child // instantiate. This should fail right after the constructor execution. - assert_err_ignore_postinfo!( - builder::call(addr_caller) - .origin(RuntimeOrigin::signed(BOB)) - .storage_deposit_limit(callee_info_len + 2 + ED + 3) // enough parent limit - .data((1u32, &code_hash_callee, U256::from(callee_info_len + 2 + ED + 2)).encode()) - .build(), - >::StorageDepositLimitExhausted, - ); + let ret = builder::bare_call(addr_caller) + .origin(RuntimeOrigin::signed(BOB)) + .storage_deposit_limit(DepositLimit::Balance(callee_info_len + 2 + ED + 3)) // enough parent limit + .data((1u32, &code_hash_callee, U256::from(callee_info_len + 2 + ED + 2)).encode()) + .build_and_unwrap_result(); + assert_return_code!(ret, RuntimeReturnCode::OutOfResources); // The charges made on the instantiation should be rolled back. assert_eq!(::Currency::free_balance(&BOB), 1_000_000); @@ -3890,7 +3879,7 @@ fn locking_delegate_dependency_works() { assert_ok!(Contracts::remove_code(RuntimeOrigin::signed(ALICE_FALLBACK), callee_hashes[0])); // Calling should fail since the delegated contract is not on chain anymore. - assert_err!(call(&addr_caller, &noop_input).result, Error::::ContractTrapped); + assert_err!(call(&addr_caller, &noop_input).result, Error::::CodeNotFound); // Add the dependency back. Contracts::upload_code( diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs index 7ea518081e23..8fb7e5c27470 100644 --- a/substrate/frame/revive/src/wasm/runtime.rs +++ b/substrate/frame/revive/src/wasm/runtime.rs @@ -745,29 +745,24 @@ impl<'a, E: Ext, M: ?Sized + Memory> Runtime<'a, E, M> { Ok(()) } - /// Fallible conversion of `DispatchError` to `ReturnErrorCode`. - fn err_into_return_code(from: DispatchError) -> Result { - use ReturnErrorCode::*; - - let transfer_failed = Error::::TransferFailed.into(); - let no_code = Error::::CodeNotFound.into(); - let not_found = Error::::ContractNotFound.into(); - - match from { - x if x == transfer_failed => Ok(TransferFailed), - x if x == no_code => Ok(CodeNotFound), - x if x == not_found => Ok(NotCallable), - err => Err(err), - } - } - /// Fallible conversion of a `ExecError` to `ReturnErrorCode`. + /// + /// This is used when converting the error returned from a subcall in order to decide + /// whether to trap the caller or allow handling of the error. fn exec_error_into_return_code(from: ExecError) -> Result { use crate::exec::ErrorOrigin::Callee; + use ReturnErrorCode::*; + let transfer_failed = Error::::TransferFailed.into(); + let out_of_gas = Error::::OutOfGas.into(); + let out_of_deposit = Error::::StorageDepositLimitExhausted.into(); + + // errors in the callee do not trap the caller match (from.error, from.origin) { - (_, Callee) => Ok(ReturnErrorCode::CalleeTrapped), - (err, _) => Self::err_into_return_code(err), + (err, _) if err == transfer_failed => Ok(TransferFailed), + (err, Callee) if err == out_of_gas || err == out_of_deposit => Ok(OutOfResources), + (_, Callee) => Ok(CalleeTrapped), + (err, _) => Err(err), } } @@ -1971,20 +1966,11 @@ pub mod env { /// Disabled until the internal implementation takes care of collecting /// the immutable data of the new code hash. #[mutating] - fn set_code_hash( - &mut self, - memory: &mut M, - code_hash_ptr: u32, - ) -> Result { + fn set_code_hash(&mut self, memory: &mut M, code_hash_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::SetCodeHash)?; let code_hash: H256 = memory.read_h256(code_hash_ptr)?; - match self.ext.set_code_hash(code_hash) { - Err(err) => { - let code = Self::err_into_return_code(err)?; - Ok(code) - }, - Ok(()) => Ok(ReturnErrorCode::Success), - } + self.ext.set_code_hash(code_hash)?; + Ok(()) } /// Calculates Ethereum address from the ECDSA compressed public key and stores diff --git a/substrate/frame/revive/uapi/src/host.rs b/substrate/frame/revive/uapi/src/host.rs index d3fd4ac8d03e..400a12879363 100644 --- a/substrate/frame/revive/uapi/src/host.rs +++ b/substrate/frame/revive/uapi/src/host.rs @@ -138,7 +138,7 @@ pub trait HostFn: private::Sealed { /// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned. /// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped] /// - [TransferFailed][`crate::ReturnErrorCode::TransferFailed] - /// - [NotCallable][`crate::ReturnErrorCode::NotCallable] + /// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources] fn call( flags: CallFlags, callee: &[u8; 20], @@ -341,7 +341,7 @@ pub trait HostFn: private::Sealed { /// /// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned. /// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped] - /// - [CodeNotFound][`crate::ReturnErrorCode::CodeNotFound] + /// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources] fn delegate_call( flags: CallFlags, address: &[u8; 20], @@ -468,7 +468,7 @@ pub trait HostFn: private::Sealed { /// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned. /// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped] /// - [TransferFailed][`crate::ReturnErrorCode::TransferFailed] - /// - [CodeNotFound][`crate::ReturnErrorCode::CodeNotFound] + /// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources] fn instantiate( code_hash: &[u8; 32], ref_time_limit: u64, @@ -566,10 +566,10 @@ pub trait HostFn: private::Sealed { /// - `code_hash`: The hash of the new code. Should be decodable as an `T::Hash`. Traps /// otherwise. /// - /// # Errors + /// # Panics /// - /// - [CodeNotFound][`crate::ReturnErrorCode::CodeNotFound] - fn set_code_hash(code_hash: &[u8; 32]) -> Result; + /// Panics if there is no code on-chain with the specified hash. + fn set_code_hash(code_hash: &[u8; 32]); /// Set the value at the given key in the contract storage. /// diff --git a/substrate/frame/revive/uapi/src/host/riscv64.rs b/substrate/frame/revive/uapi/src/host/riscv64.rs index 3cba14db6a04..b76320718a69 100644 --- a/substrate/frame/revive/uapi/src/host/riscv64.rs +++ b/substrate/frame/revive/uapi/src/host/riscv64.rs @@ -115,7 +115,7 @@ mod sys { message_len: u32, message_ptr: *const u8, ) -> ReturnCode; - pub fn set_code_hash(code_hash_ptr: *const u8) -> ReturnCode; + pub fn set_code_hash(code_hash_ptr: *const u8); pub fn ecdsa_to_eth_address(key_ptr: *const u8, out_ptr: *mut u8) -> ReturnCode; pub fn instantiation_nonce() -> u64; pub fn lock_delegate_dependency(code_hash_ptr: *const u8); @@ -531,9 +531,8 @@ impl HostFn for HostFnImpl { ret_val.into_bool() } - fn set_code_hash(code_hash: &[u8; 32]) -> Result { - let ret_val = unsafe { sys::set_code_hash(code_hash.as_ptr()) }; - ret_val.into() + fn set_code_hash(code_hash: &[u8; 32]) { + unsafe { sys::set_code_hash(code_hash.as_ptr()) } } fn code_hash(address: &[u8; 20], output: &mut [u8; 32]) { diff --git a/substrate/frame/revive/uapi/src/lib.rs b/substrate/frame/revive/uapi/src/lib.rs index 91c2543bb719..14a5e3f28889 100644 --- a/substrate/frame/revive/uapi/src/lib.rs +++ b/substrate/frame/revive/uapi/src/lib.rs @@ -85,23 +85,21 @@ define_error_codes! { /// Transfer failed for other not further specified reason. Most probably /// reserved or locked balance of the sender that was preventing the transfer. TransferFailed = 4, - /// No code could be found at the supplied code hash. - CodeNotFound = 5, - /// The account that was called is no contract. - NotCallable = 6, /// The call to `debug_message` had no effect because debug message /// recording was disabled. - LoggingDisabled = 7, + LoggingDisabled = 5, /// The call dispatched by `call_runtime` was executed but returned an error. - CallRuntimeFailed = 8, + CallRuntimeFailed = 6, /// ECDSA public key recovery failed. Most probably wrong recovery id or signature. - EcdsaRecoveryFailed = 9, + EcdsaRecoveryFailed = 7, /// sr25519 signature verification failed. - Sr25519VerifyFailed = 10, + Sr25519VerifyFailed = 8, /// The `xcm_execute` call failed. - XcmExecutionFailed = 11, + XcmExecutionFailed = 9, /// The `xcm_send` call failed. - XcmSendFailed = 12, + XcmSendFailed = 10, + /// The subcall ran out of weight or storage deposit. + OutOfResources = 11, } /// The raw return code returned by the host side. From 4f43b72f2c479656fdee8bc10341d221a4a1e4b9 Mon Sep 17 00:00:00 2001 From: Egor_P Date: Thu, 5 Dec 2024 16:53:31 +0100 Subject: [PATCH 19/51] [CI/CD] Add release environment to the backport job (#6765) Fix adds release environment to the backport job, so that token could be properly generated --- .github/workflows/command-backport.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/command-backport.yml b/.github/workflows/command-backport.yml index 53dcea2f1d6d..db006e9bd907 100644 --- a/.github/workflows/command-backport.yml +++ b/.github/workflows/command-backport.yml @@ -16,6 +16,7 @@ jobs: backport: name: Backport pull request runs-on: ubuntu-latest + environment: release # The 'github.event.pull_request.merged' ensures that it got into master: if: > From f31c70aad4f90168824871c3c094008f3120b333 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Thu, 5 Dec 2024 17:27:39 +0100 Subject: [PATCH 20/51] Added fallback_max_weight to Transact for sending messages to V4 chains (#6643) Closes: https://github.com/paritytech/polkadot-sdk/issues/6585 Removing the `require_weight_at_most` parameter in V5 Transact had only one problem. Converting a message from V5 to V4 to send to chains that didn't upgrade yet. The conversion would not know what weight to give to the Transact, since V4 and below require it. To fix this, I added back the weight in the form of an `Option` called `fallback_max_weight`. This can be set to `None` if you don't intend to deal with a chain that hasn't upgraded yet. If you set it to `Some(_)`, the behaviour is the same. The plan is to totally remove this in V6 since there will be a good conversion path from V6 to V5. --------- Co-authored-by: GitHub Action Co-authored-by: Adrian Catangiu --- .../pallets/inbound-queue/src/test.rs | 4 +- .../primitives/router/src/inbound/mod.rs | 1 + .../emulated/common/src/xcm_helpers.rs | 4 +- .../asset-hub-westend/src/tests/transact.rs | 2 +- .../bridge-hub-rococo/src/tests/snowbridge.rs | 18 ++++- .../bridge-hub-westend/src/tests/transact.rs | 2 +- .../src/tests/fellowship.rs | 1 + .../people-westend/src/tests/governance.rs | 43 +++++++++-- cumulus/parachains/pallets/ping/src/lib.rs | 2 + .../asset-hub-rococo/src/weights/xcm/mod.rs | 6 +- .../asset-hub-westend/src/weights/xcm/mod.rs | 6 +- .../assets/test-utils/src/test_cases.rs | 14 +++- .../bridge-hub-rococo/src/weights/xcm/mod.rs | 6 +- .../bridge-hub-westend/src/weights/xcm/mod.rs | 6 +- .../coretime/coretime-rococo/src/coretime.rs | 4 + .../coretime-rococo/src/weights/xcm/mod.rs | 6 +- .../coretime/coretime-westend/src/coretime.rs | 16 ++++ .../coretime-westend/src/weights/xcm/mod.rs | 6 +- .../people-rococo/src/weights/xcm/mod.rs | 6 +- .../people-westend/src/weights/xcm/mod.rs | 6 +- .../parachains/runtimes/test-utils/src/lib.rs | 8 +- .../runtime/parachains/src/coretime/mod.rs | 6 ++ polkadot/runtime/parachains/src/mock.rs | 2 + polkadot/runtime/rococo/src/impls.rs | 14 +++- polkadot/runtime/rococo/src/lib.rs | 2 + .../runtime/rococo/src/weights/xcm/mod.rs | 6 +- polkadot/runtime/test-runtime/src/lib.rs | 2 + polkadot/runtime/westend/src/impls.rs | 14 +++- polkadot/runtime/westend/src/lib.rs | 2 + .../runtime/westend/src/weights/xcm/mod.rs | 6 +- .../src/generic/benchmarking.rs | 1 + polkadot/xcm/src/v4/mod.rs | 16 +++- polkadot/xcm/src/v5/mod.rs | 76 +++++++++++++++++-- polkadot/xcm/src/v5/traits.rs | 1 + .../xcm/xcm-builder/src/tests/transacting.rs | 11 +++ .../xcm-executor/integration-tests/src/lib.rs | 6 +- polkadot/xcm/xcm-executor/src/lib.rs | 3 +- .../xcm/xcm-simulator/example/src/tests.rs | 4 + prdoc/pr_6643.prdoc | 47 ++++++++++++ 39 files changed, 341 insertions(+), 45 deletions(-) create mode 100644 prdoc/pr_6643.prdoc diff --git a/bridges/snowbridge/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/pallets/inbound-queue/src/test.rs index 76d0b98e9eb4..5386b845f2ec 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/test.rs @@ -40,8 +40,8 @@ fn test_submit_happy_path() { .into(), nonce: 1, message_id: [ - 11, 25, 133, 51, 23, 68, 111, 211, 132, 94, 254, 17, 194, 252, 198, 233, 10, 193, - 156, 93, 72, 140, 65, 69, 79, 155, 154, 28, 141, 166, 171, 255, + 97, 161, 116, 204, 182, 115, 192, 144, 130, 243, 240, 193, 122, 154, 108, 91, 247, + 41, 226, 237, 202, 158, 238, 239, 210, 8, 147, 131, 84, 146, 171, 176, ], fee_burned: 110000000000, } diff --git a/bridges/snowbridge/primitives/router/src/inbound/mod.rs b/bridges/snowbridge/primitives/router/src/inbound/mod.rs index e03560f66e24..54a578b988a4 100644 --- a/bridges/snowbridge/primitives/router/src/inbound/mod.rs +++ b/bridges/snowbridge/primitives/router/src/inbound/mod.rs @@ -279,6 +279,7 @@ where // Call create_asset on foreign assets pallet. Transact { origin_kind: OriginKind::Xcm, + fallback_max_weight: None, call: ( create_call_index, asset_id, diff --git a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs index 9125c976525e..380f4983ad98 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs @@ -31,7 +31,7 @@ pub fn xcm_transact_paid_execution( VersionedXcm::from(Xcm(vec![ WithdrawAsset(fees.clone().into()), BuyExecution { fees, weight_limit }, - Transact { origin_kind, call }, + Transact { origin_kind, call, fallback_max_weight: None }, RefundSurplus, DepositAsset { assets: All.into(), @@ -53,7 +53,7 @@ pub fn xcm_transact_unpaid_execution( VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit, check_origin }, - Transact { origin_kind, call }, + Transact { origin_kind, call, fallback_max_weight: None }, ])) } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs index 3c53cfb261be..592c2845255c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs @@ -43,7 +43,7 @@ fn transfer_and_transact_in_same_xcm( // xcm to be executed at dest let xcm_on_dest = Xcm(vec![ - Transact { origin_kind: OriginKind::Xcm, call }, + Transact { origin_kind: OriginKind::Xcm, call, fallback_max_weight: None }, ExpectTransactStatus(MaybeErrorCode::Success), // since this is the last hop, we don't need to further use any assets previously // reserved for fees (there are no further hops to cover transport fees for); we diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index d59553574c26..c72d5045ddc0 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -84,7 +84,11 @@ fn create_agent() { let remote_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, DescendOrigin(Parachain(origin_para).into()), - Transact { origin_kind: OriginKind::Xcm, call: create_agent_call.encode().into() }, + Transact { + origin_kind: OriginKind::Xcm, + call: create_agent_call.encode().into(), + fallback_max_weight: None, + }, ])); // Rococo Global Consensus @@ -138,7 +142,11 @@ fn create_channel() { let create_agent_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, DescendOrigin(Parachain(origin_para).into()), - Transact { origin_kind: OriginKind::Xcm, call: create_agent_call.encode().into() }, + Transact { + origin_kind: OriginKind::Xcm, + call: create_agent_call.encode().into(), + fallback_max_weight: None, + }, ])); let create_channel_call = @@ -147,7 +155,11 @@ fn create_channel() { let create_channel_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, DescendOrigin(Parachain(origin_para).into()), - Transact { origin_kind: OriginKind::Xcm, call: create_channel_call.encode().into() }, + Transact { + origin_kind: OriginKind::Xcm, + call: create_channel_call.encode().into(), + fallback_max_weight: None, + }, ])); // Rococo Global Consensus diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs index db42704dae61..7831c8d66357 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs @@ -49,7 +49,7 @@ fn transfer_and_transact_in_same_xcm( // xcm to be executed at dest let xcm_on_dest = Xcm(vec![ - Transact { origin_kind: OriginKind::Xcm, call }, + Transact { origin_kind: OriginKind::Xcm, call, fallback_max_weight: None }, ExpectTransactStatus(MaybeErrorCode::Success), // since this is the last hop, we don't need to further use any assets previously // reserved for fees (there are no further hops to cover transport fees for); we diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship.rs index 80b82e0c446f..802fed1e681d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship.rs @@ -41,6 +41,7 @@ fn fellows_whitelist_call() { ) .encode() .into(), + fallback_max_weight: None } ]))), }); diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs index 3dadcdd94870..1ba787aaec52 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs @@ -48,7 +48,11 @@ fn relay_commands_add_registrar() { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), message: bx!(VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind, call: add_registrar_call.encode().into() } + Transact { + origin_kind, + call: add_registrar_call.encode().into(), + fallback_max_weight: None + } ]))), }); @@ -107,7 +111,11 @@ fn relay_commands_add_registrar_wrong_origin() { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), message: bx!(VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind, call: add_registrar_call.encode().into() } + Transact { + origin_kind, + call: add_registrar_call.encode().into(), + fallback_max_weight: None + } ]))), }); @@ -194,7 +202,11 @@ fn relay_commands_kill_identity() { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), message: bx!(VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind, call: kill_identity_call.encode().into() } + Transact { + origin_kind, + call: kill_identity_call.encode().into(), + fallback_max_weight: None + } ]))), }); @@ -252,7 +264,11 @@ fn relay_commands_kill_identity_wrong_origin() { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), message: bx!(VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind, call: kill_identity_call.encode().into() } + Transact { + origin_kind, + call: kill_identity_call.encode().into(), + fallback_max_weight: None + } ]))), }); @@ -298,7 +314,11 @@ fn relay_commands_add_remove_username_authority() { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), message: bx!(VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind, call: add_username_authority.encode().into() } + Transact { + origin_kind, + call: add_username_authority.encode().into(), + fallback_max_weight: None + } ]))), }); @@ -383,7 +403,11 @@ fn relay_commands_add_remove_username_authority() { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), message: bx!(VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind, call: remove_username_authority.encode().into() } + Transact { + origin_kind, + call: remove_username_authority.encode().into(), + fallback_max_weight: None + } ]))), }); @@ -443,7 +467,11 @@ fn relay_commands_add_remove_username_authority_wrong_origin() { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), message: bx!(VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind, call: add_username_authority.encode().into() } + Transact { + origin_kind, + call: add_username_authority.encode().into(), + fallback_max_weight: None + } ]))), }); @@ -483,6 +511,7 @@ fn relay_commands_add_remove_username_authority_wrong_origin() { Transact { origin_kind: OriginKind::SovereignAccount, call: remove_username_authority.encode().into(), + fallback_max_weight: None, } ]))), }); diff --git a/cumulus/parachains/pallets/ping/src/lib.rs b/cumulus/parachains/pallets/ping/src/lib.rs index 2cf32c891fc0..b6423a81db3c 100644 --- a/cumulus/parachains/pallets/ping/src/lib.rs +++ b/cumulus/parachains/pallets/ping/src/lib.rs @@ -114,6 +114,7 @@ pub mod pallet { }) .encode() .into(), + fallback_max_weight: None, }]), ) { Ok((hash, cost)) => { @@ -214,6 +215,7 @@ pub mod pallet { }) .encode() .into(), + fallback_max_weight: None, }]), ) { Ok((hash, cost)) => diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs index 025c39bcee07..74f564037400 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs @@ -84,7 +84,11 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs index 35ff2dc367c0..ff99f1242b22 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs @@ -83,7 +83,11 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs index aeacc1a5471e..b1577e0ca7f6 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -1205,14 +1205,20 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor let xcm = Xcm(vec![ WithdrawAsset(buy_execution_fee.clone().into()), BuyExecution { fees: buy_execution_fee.clone(), weight_limit: Unlimited }, - Transact { origin_kind: OriginKind::Xcm, call: foreign_asset_create.into() }, + Transact { + origin_kind: OriginKind::Xcm, + call: foreign_asset_create.into(), + fallback_max_weight: None, + }, Transact { origin_kind: OriginKind::SovereignAccount, call: foreign_asset_set_metadata.into(), + fallback_max_weight: None, }, Transact { origin_kind: OriginKind::SovereignAccount, call: foreign_asset_set_team.into(), + fallback_max_weight: None, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); @@ -1318,7 +1324,11 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor let xcm = Xcm(vec![ WithdrawAsset(buy_execution_fee.clone().into()), BuyExecution { fees: buy_execution_fee.clone(), weight_limit: Unlimited }, - Transact { origin_kind: OriginKind::Xcm, call: foreign_asset_create.into() }, + Transact { + origin_kind: OriginKind::Xcm, + call: foreign_asset_create.into(), + fallback_max_weight: None, + }, ExpectTransactStatus(MaybeErrorCode::from(DispatchError::BadOrigin.encode())), ]); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs index 288aac38563c..e5c6f493d6dc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs @@ -84,7 +84,11 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs index fa1304d11c6f..939b1c7a287b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs @@ -85,7 +85,11 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs index d76ac443a147..35c3dd8836a8 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs @@ -135,6 +135,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: request_core_count_call.encode().into(), + fallback_max_weight: Some(Weight::from_parts(1_000_000_000, 200_000)), }, ]); @@ -164,6 +165,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: request_revenue_info_at_call.encode().into(), + fallback_max_weight: Some(Weight::from_parts(1_000_000_000, 200_000)), }, ]); @@ -192,6 +194,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: credit_account_call.encode().into(), + fallback_max_weight: Some(Weight::from_parts(1_000_000_000, 200_000)), }, ]); @@ -256,6 +259,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: assign_core_call.encode().into(), + fallback_max_weight: Some(Weight::from_parts(1_000_000_000, 200_000)), }, ]); diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs index f69736e31451..2c4a97601c64 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs @@ -84,7 +84,11 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs index f0c03849750a..985e64fb76f9 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs @@ -127,6 +127,12 @@ impl CoretimeInterface for CoretimeAllocator { use crate::coretime::CoretimeProviderCalls::RequestCoreCount; let request_core_count_call = RelayRuntimePallets::Coretime(RequestCoreCount(count)); + // Weight for `request_core_count` from westend benchmarks: + // `ref_time` = 7889000 + (3 * 25000000) + (1 * 100000000) = 182889000 + // `proof_size` = 1636 + // Add 5% to each component and round to 2 significant figures. + let call_weight = Weight::from_parts(190_000_000, 1700); + let message = Xcm(vec![ Instruction::UnpaidExecution { weight_limit: WeightLimit::Unlimited, @@ -135,6 +141,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: request_core_count_call.encode().into(), + fallback_max_weight: Some(call_weight), }, ]); @@ -164,6 +171,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: request_revenue_info_at_call.encode().into(), + fallback_max_weight: Some(Weight::from_parts(1_000_000_000, 200_000)), }, ]); @@ -192,6 +200,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: credit_account_call.encode().into(), + fallback_max_weight: Some(Weight::from_parts(1_000_000_000, 200_000)), }, ]); @@ -216,6 +225,12 @@ impl CoretimeInterface for CoretimeAllocator { ) { use crate::coretime::CoretimeProviderCalls::AssignCore; + // Weight for `assign_core` from westend benchmarks: + // `ref_time` = 10177115 + (1 * 25000000) + (2 * 100000000) + (57600 * 13932) = 937660315 + // `proof_size` = 3612 + // Add 5% to each component and round to 2 significant figures. + let call_weight = Weight::from_parts(980_000_000, 3800); + // The relay chain currently only allows `assign_core` to be called with a complete mask // and only ever with increasing `begin`. The assignments must be truncated to avoid // dropping that core's assignment completely. @@ -256,6 +271,7 @@ impl CoretimeInterface for CoretimeAllocator { Instruction::Transact { origin_kind: OriginKind::Native, call: assign_core_call.encode().into(), + fallback_max_weight: Some(call_weight), }, ]); diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs index 1640baa38c99..906088a1df86 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs @@ -83,7 +83,11 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs index 631cc7b7f0b0..47008a2943e5 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs @@ -83,7 +83,11 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs index 4b51a3ba411b..27fd499ebba7 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs @@ -83,7 +83,11 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } - fn transact(_origin_type: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_type: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 3f2e721d13f6..5c33809ba67b 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -445,7 +445,11 @@ impl< // prepare xcm as governance will do let xcm = Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { origin_kind: OriginKind::Superuser, call: call.into() }, + Transact { + origin_kind: OriginKind::Superuser, + call: call.into(), + fallback_max_weight: None, + }, ExpectTransactStatus(MaybeErrorCode::Success), ]); @@ -476,7 +480,7 @@ impl< // prepare `Transact` xcm instructions.extend(vec![ - Transact { origin_kind, call: call.encode().into() }, + Transact { origin_kind, call: call.encode().into(), fallback_max_weight: None }, ExpectTransactStatus(MaybeErrorCode::Success), ]); let xcm = Xcm(instructions); diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index 966b7997a277..5656e92b90be 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -136,6 +136,11 @@ pub mod pallet { type AssetTransactor: TransactAsset; /// AccountId to Location converter type AccountToLocation: for<'a> TryConvert<&'a Self::AccountId, Location>; + + /// Maximum weight for any XCM transact call that should be executed on the coretime chain. + /// + /// Basically should be `max_weight(set_leases, reserve, notify_core_count)`. + type MaxXcmTransactWeight: Get; } #[pallet::event] @@ -333,6 +338,7 @@ impl OnNewSession> for Pallet { fn mk_coretime_call(call: crate::coretime::CoretimeCalls) -> Instruction<()> { Instruction::Transact { origin_kind: OriginKind::Superuser, + fallback_max_weight: Some(T::MaxXcmTransactWeight::get()), call: BrokerRuntimePallets::Broker(call).encode().into(), } } diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index d701e1f9bd80..ee1990a7b618 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -421,6 +421,7 @@ impl assigner_coretime::Config for Test {} parameter_types! { pub const BrokerId: u32 = 10u32; + pub MaxXcmTransactWeight: Weight = Weight::from_parts(10_000_000, 10_000); } pub struct BrokerPot; @@ -437,6 +438,7 @@ impl coretime::Config for Test { type BrokerId = BrokerId; type WeightInfo = crate::coretime::TestWeightInfo; type SendXcm = DummyXcmSender; + type MaxXcmTransactWeight = MaxXcmTransactWeight; type BrokerPotLocation = BrokerPot; type AssetTransactor = (); type AccountToLocation = (); diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index ab796edc54b1..7d7e9fa9f06c 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -21,7 +21,7 @@ use core::marker::PhantomData; use frame_support::pallet_prelude::DispatchResult; use frame_system::RawOrigin; use polkadot_primitives::Balance; -use polkadot_runtime_common::identity_migrator::OnReapIdentity; +use polkadot_runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use rococo_runtime_constants::currency::*; use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; @@ -88,7 +88,10 @@ where AccountId: Into<[u8; 32]> + Clone + Encode, { fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { - use crate::impls::IdentityMigratorCalls::PokeDeposit; + use crate::{ + impls::IdentityMigratorCalls::PokeDeposit, + weights::polkadot_runtime_common_identity_migrator::WeightInfo as MigratorWeights, + }; let total_to_send = Self::calculate_remote_deposit(fields, subs); @@ -141,6 +144,7 @@ where .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); + let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); // Actual program to execute on People Chain. let program: Xcm<()> = Xcm(vec![ @@ -157,7 +161,11 @@ where .into(), }, // Poke the deposit to reserve the appropriate amount on the parachain. - Transact { origin_kind: OriginKind::Superuser, call: poke.encode().into() }, + Transact { + origin_kind: OriginKind::Superuser, + fallback_max_weight: Some(remote_weight_limit), + call: poke.encode().into(), + }, ]); // send diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 5da9da86f02e..c832ace91c07 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1100,6 +1100,7 @@ impl parachains_scheduler::Config for Runtime { parameter_types! { pub const BrokerId: u32 = BROKER_ID; pub const BrokerPalletId: PalletId = PalletId(*b"py/broke"); + pub MaxXcmTransactWeight: Weight = Weight::from_parts(200_000_000, 20_000); } pub struct BrokerPot; @@ -1123,6 +1124,7 @@ impl coretime::Config for Runtime { xcm_config::ThisNetwork, ::AccountId, >; + type MaxXcmTransactWeight = MaxXcmTransactWeight; } parameter_types! { diff --git a/polkadot/runtime/rococo/src/weights/xcm/mod.rs b/polkadot/runtime/rococo/src/weights/xcm/mod.rs index a28b46800874..16f51a778917 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/mod.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/mod.rs @@ -111,7 +111,11 @@ impl XcmWeightInfo for RococoXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } - fn transact(_origin_kind: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_kind: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 69ce187dce40..d4031f7ac57a 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -584,6 +584,7 @@ impl parachains_paras::Config for Runtime { parameter_types! { pub const BrokerId: u32 = 10u32; + pub MaxXcmTransactWeight: Weight = Weight::from_parts(10_000_000, 10_000); } pub struct BrokerPot; @@ -657,6 +658,7 @@ impl coretime::Config for Runtime { type BrokerId = BrokerId; type WeightInfo = crate::coretime::TestWeightInfo; type SendXcm = DummyXcmSender; + type MaxXcmTransactWeight = MaxXcmTransactWeight; type BrokerPotLocation = BrokerPot; type AssetTransactor = (); type AccountToLocation = (); diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index d7281dad56d4..8cb597cbaa95 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -21,7 +21,7 @@ use core::marker::PhantomData; use frame_support::pallet_prelude::DispatchResult; use frame_system::RawOrigin; use polkadot_primitives::Balance; -use polkadot_runtime_common::identity_migrator::OnReapIdentity; +use polkadot_runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use westend_runtime_constants::currency::*; use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; @@ -88,7 +88,10 @@ where AccountId: Into<[u8; 32]> + Clone + Encode, { fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { - use crate::impls::IdentityMigratorCalls::PokeDeposit; + use crate::{ + impls::IdentityMigratorCalls::PokeDeposit, + weights::polkadot_runtime_common_identity_migrator::WeightInfo as MigratorWeights, + }; let total_to_send = Self::calculate_remote_deposit(fields, subs); @@ -141,6 +144,7 @@ where .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); + let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); // Actual program to execute on People Chain. let program: Xcm<()> = Xcm(vec![ @@ -157,7 +161,11 @@ where .into(), }, // Poke the deposit to reserve the appropriate amount on the parachain. - Transact { origin_kind: OriginKind::Superuser, call: poke.encode().into() }, + Transact { + origin_kind: OriginKind::Superuser, + call: poke.encode().into(), + fallback_max_weight: Some(remote_weight_limit), + }, ]); // send diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 9f0b701f20be..f25ed33012a2 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1326,6 +1326,7 @@ impl parachains_scheduler::Config for Runtime { parameter_types! { pub const BrokerId: u32 = BROKER_ID; pub const BrokerPalletId: PalletId = PalletId(*b"py/broke"); + pub MaxXcmTransactWeight: Weight = Weight::from_parts(200_000_000, 20_000); } pub struct BrokerPot; @@ -1349,6 +1350,7 @@ impl coretime::Config for Runtime { xcm_config::ThisNetwork, ::AccountId, >; + type MaxXcmTransactWeight = MaxXcmTransactWeight; } parameter_types! { diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs index 5be9bad824da..60265445334d 100644 --- a/polkadot/runtime/westend/src/weights/xcm/mod.rs +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -114,7 +114,11 @@ impl XcmWeightInfo for WestendXcmWeight { fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } - fn transact(_origin_kind: &OriginKind, _call: &DoubleEncoded) -> Weight { + fn transact( + _origin_kind: &OriginKind, + _fallback_max_weight: &Option, + _call: &DoubleEncoded, + ) -> Weight { XcmGeneric::::transact() } fn hrmp_new_channel_open_request( diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index f4836b7cdde1..285322891c63 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -186,6 +186,7 @@ mod benchmarks { let instruction = Instruction::Transact { origin_kind: OriginKind::SovereignAccount, call: double_encoded_noop_call, + fallback_max_weight: None, }; let xcm = Xcm(vec![instruction]); #[block] diff --git a/polkadot/xcm/src/v4/mod.rs b/polkadot/xcm/src/v4/mod.rs index 9baf58eacfb0..3ae94b6ede88 100644 --- a/polkadot/xcm/src/v4/mod.rs +++ b/polkadot/xcm/src/v4/mod.rs @@ -1314,8 +1314,20 @@ impl TryFrom> for Instructi HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, HrmpChannelClosing { initiator, sender, recipient } => Self::HrmpChannelClosing { initiator, sender, recipient }, - Transact { origin_kind, mut call } => { - let require_weight_at_most = call.take_decoded()?.get_dispatch_info().call_weight; + Transact { origin_kind, mut call, fallback_max_weight } => { + // We first try to decode the call, if we can't, we use the fallback weight, + // if there's no fallback, we just return `Weight::MAX`. + let require_weight_at_most = match call.take_decoded() { + Ok(decoded) => decoded.get_dispatch_info().call_weight, + Err(error) => { + log::error!( + target: "xcm::versions::v5Tov4", + "Couldn't decode call in Transact: {:?}, using fallback weight.", + error, + ); + fallback_max_weight.unwrap_or(Weight::MAX) + }, + }; Self::Transact { origin_kind, require_weight_at_most, call: call.into() } }, ReportError(response_info) => Self::ReportError(QueryResponseInfo { diff --git a/polkadot/xcm/src/v5/mod.rs b/polkadot/xcm/src/v5/mod.rs index 830b23cc44b7..193b82b6c223 100644 --- a/polkadot/xcm/src/v5/mod.rs +++ b/polkadot/xcm/src/v5/mod.rs @@ -493,13 +493,21 @@ pub enum Instruction { /// /// - `origin_kind`: The means of expressing the message origin as a dispatch origin. /// - `call`: The encoded transaction to be applied. + /// - `fallback_max_weight`: Used for compatibility with previous versions. Corresponds to the + /// `require_weight_at_most` parameter in previous versions. If you don't care about + /// compatibility you can just put `None`. WARNING: If you do, your XCM might not work with + /// older versions. Make sure to dry-run and validate. /// /// Safety: No concerns. /// /// Kind: *Command*. /// /// Errors: - Transact { origin_kind: OriginKind, call: DoubleEncoded }, + Transact { + origin_kind: OriginKind, + fallback_max_weight: Option, + call: DoubleEncoded, + }, /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by /// the relay-chain to a para. @@ -1159,7 +1167,8 @@ impl Instruction { HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient }, HrmpChannelClosing { initiator, sender, recipient } => HrmpChannelClosing { initiator, sender, recipient }, - Transact { origin_kind, call } => Transact { origin_kind, call: call.into() }, + Transact { origin_kind, call, fallback_max_weight } => + Transact { origin_kind, call: call.into(), fallback_max_weight }, ReportError(response_info) => ReportError(response_info), DepositAsset { assets, beneficiary } => DepositAsset { assets, beneficiary }, DepositReserveAsset { assets, dest, xcm } => DepositReserveAsset { assets, dest, xcm }, @@ -1227,7 +1236,8 @@ impl> GetWeight for Instruction { TransferAsset { assets, beneficiary } => W::transfer_asset(assets, beneficiary), TransferReserveAsset { assets, dest, xcm } => W::transfer_reserve_asset(&assets, dest, xcm), - Transact { origin_kind, call } => W::transact(origin_kind, call), + Transact { origin_kind, fallback_max_weight, call } => + W::transact(origin_kind, fallback_max_weight, call), HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => W::hrmp_new_channel_open_request(sender, max_message_size, max_capacity), HrmpChannelAccepted { recipient } => W::hrmp_channel_accepted(recipient), @@ -1343,8 +1353,11 @@ impl TryFrom> for Instruction { HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, HrmpChannelClosing { initiator, sender, recipient } => Self::HrmpChannelClosing { initiator, sender, recipient }, - Transact { origin_kind, require_weight_at_most: _, call } => - Self::Transact { origin_kind, call: call.into() }, + Transact { origin_kind, require_weight_at_most, call } => Self::Transact { + origin_kind, + call: call.into(), + fallback_max_weight: Some(require_weight_at_most), + }, ReportError(response_info) => Self::ReportError(QueryResponseInfo { query_id: response_info.query_id, destination: response_info.destination.try_into().map_err(|_| ())?, @@ -1577,6 +1590,59 @@ mod tests { assert_eq!(new_xcm, xcm); } + #[test] + fn transact_roundtrip_works() { + // We can convert as long as there's a fallback. + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + Transact { + origin_kind: OriginKind::SovereignAccount, + call: vec![200, 200, 200].into(), + fallback_max_weight: Some(Weight::from_parts(1_000_000, 1_024)), + }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::Transact { + origin_kind: OriginKind::SovereignAccount, + call: vec![200, 200, 200].into(), + require_weight_at_most: Weight::from_parts(1_000_000, 1_024), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + + // If we have no fallback the resulting message won't know the weight. + let xcm_without_fallback = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + Transact { + origin_kind: OriginKind::SovereignAccount, + call: vec![200, 200, 200].into(), + fallback_max_weight: None, + }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::Transact { + origin_kind: OriginKind::SovereignAccount, + call: vec![200, 200, 200].into(), + require_weight_at_most: Weight::MAX, + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm_without_fallback.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + let xcm_with_max_weight_fallback = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + Transact { + origin_kind: OriginKind::SovereignAccount, + call: vec![200, 200, 200].into(), + fallback_max_weight: Some(Weight::MAX), + }, + ]); + assert_eq!(new_xcm, xcm_with_max_weight_fallback); + } + #[test] fn decoding_respects_limit() { let max_xcm = Xcm::<()>(vec![ClearOrigin; MAX_INSTRUCTIONS_TO_DECODE as usize]); diff --git a/polkadot/xcm/src/v5/traits.rs b/polkadot/xcm/src/v5/traits.rs index dd067b774fcd..71b67e97d5fe 100644 --- a/polkadot/xcm/src/v5/traits.rs +++ b/polkadot/xcm/src/v5/traits.rs @@ -428,6 +428,7 @@ pub type SendResult = result::Result<(T, Assets), SendError>; /// let message = Xcm(vec![Instruction::Transact { /// origin_kind: OriginKind::Superuser, /// call: call.into(), +/// fallback_max_weight: None, /// }]); /// let message_hash = message.using_encoded(sp_io::hashing::blake2_256); /// diff --git a/polkadot/xcm/xcm-builder/src/tests/transacting.rs b/polkadot/xcm/xcm-builder/src/tests/transacting.rs index 8963e7147fdc..ba932beaeb3d 100644 --- a/polkadot/xcm/xcm-builder/src/tests/transacting.rs +++ b/polkadot/xcm/xcm-builder/src/tests/transacting.rs @@ -23,6 +23,7 @@ fn transacting_should_work() { let message = Xcm::(vec![Transact { origin_kind: OriginKind::Native, call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }]); let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); @@ -43,6 +44,7 @@ fn transacting_should_respect_max_weight_requirement() { let message = Xcm::(vec![Transact { origin_kind: OriginKind::Native, call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }]); let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); @@ -65,6 +67,7 @@ fn transacting_should_refund_weight() { call: TestCall::Any(Weight::from_parts(50, 50), Some(Weight::from_parts(30, 30))) .encode() .into(), + fallback_max_weight: None, }]); let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); @@ -96,6 +99,7 @@ fn paid_transacting_should_refund_payment_for_unused_weight() { call: TestCall::Any(Weight::from_parts(50, 50), Some(Weight::from_parts(10, 10))) .encode() .into(), + fallback_max_weight: None, }, RefundSurplus, DepositAsset { assets: AllCounted(1).into(), beneficiary: one }, @@ -124,6 +128,7 @@ fn report_successful_transact_status_should_work() { Transact { origin_kind: OriginKind::Native, call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }, ReportTransactStatus(QueryResponseInfo { destination: Parent.into(), @@ -159,6 +164,7 @@ fn report_failed_transact_status_should_work() { Transact { origin_kind: OriginKind::Native, call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }, ReportTransactStatus(QueryResponseInfo { destination: Parent.into(), @@ -194,6 +200,7 @@ fn expect_successful_transact_status_should_work() { Transact { origin_kind: OriginKind::Native, call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); @@ -212,6 +219,7 @@ fn expect_successful_transact_status_should_work() { Transact { origin_kind: OriginKind::Native, call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); @@ -238,6 +246,7 @@ fn expect_failed_transact_status_should_work() { Transact { origin_kind: OriginKind::Native, call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }, ExpectTransactStatus(vec![2].into()), ]); @@ -256,6 +265,7 @@ fn expect_failed_transact_status_should_work() { Transact { origin_kind: OriginKind::Native, call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }, ExpectTransactStatus(vec![2].into()), ]); @@ -282,6 +292,7 @@ fn clear_transact_status_should_work() { Transact { origin_kind: OriginKind::Native, call: TestCall::OnlyRoot(Weight::from_parts(50, 50), None).encode().into(), + fallback_max_weight: None, }, ClearTransactStatus, ReportTransactStatus(QueryResponseInfo { diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs index 9b918fd7eeed..699a081e4f22 100644 --- a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs +++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs @@ -79,7 +79,11 @@ fn transact_recursion_limit_works() { Xcm(vec![ WithdrawAsset((Here, 1_000).into()), BuyExecution { fees: (Here, 1).into(), weight_limit: Unlimited }, - Transact { origin_kind: OriginKind::Native, call: call.encode().into() }, + Transact { + origin_kind: OriginKind::Native, + call: call.encode().into(), + fallback_max_weight: None, + }, ]) }; let mut call: Option = None; diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 4e051f24050c..11fd4e04761f 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -939,7 +939,8 @@ impl XcmExecutor { Ok(()) }) }, - Transact { origin_kind, mut call } => { + // `fallback_max_weight` is not used in the executor, it's only for conversions. + Transact { origin_kind, mut call, .. } => { // We assume that the Relay-chain is allowed to use transact on this parachain. let origin = self.cloned_origin().ok_or_else(|| { tracing::trace!( diff --git a/polkadot/xcm/xcm-simulator/example/src/tests.rs b/polkadot/xcm/xcm-simulator/example/src/tests.rs index bbac44ed8a1f..f971812f4f4d 100644 --- a/polkadot/xcm/xcm-simulator/example/src/tests.rs +++ b/polkadot/xcm/xcm-simulator/example/src/tests.rs @@ -47,6 +47,7 @@ fn dmp() { Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, call: remark.encode().into(), + fallback_max_weight: None, }]), )); }); @@ -74,6 +75,7 @@ fn ump() { Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, call: remark.encode().into(), + fallback_max_weight: None, }]), )); }); @@ -101,6 +103,7 @@ fn xcmp() { Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, call: remark.encode().into(), + fallback_max_weight: None, }]), )); }); @@ -388,6 +391,7 @@ fn reserve_asset_class_create_and_reserve_transfer() { ) .encode() .into(), + fallback_max_weight: None, }]); // Send creation. assert_ok!(RelayChainPalletXcm::send_xcm(Here, Parachain(1), message)); diff --git a/prdoc/pr_6643.prdoc b/prdoc/pr_6643.prdoc new file mode 100644 index 000000000000..c111f6356519 --- /dev/null +++ b/prdoc/pr_6643.prdoc @@ -0,0 +1,47 @@ +title: Added fallback_max_weight to Transact for sending messages to V4 chains +doc: +- audience: Runtime Dev + description: |- + Removing the `require_weight_at_most` parameter in V5 Transact introduced a problem when converting a message from V5 to V4 to send to chains that didn't upgrade yet. + The local chain doesn't know how to decode calls for remote chains so it can't automatically populate `require_weight_at_most` required by V4 Transact. + To fix this, XCM v5 Transact now also takes a `fallback_max_weight: Option` parameter. + This can be set to `None` if the instruction is not meant to be sent to chains running XCM versions lower than V5. + If set to `Some(weight)`, a subsequent conversion to V4 will result in `Transact { require_weight_at_most: weight, .. }`. + The plan is to remove this workaround in V6 since there will be a good conversion path from V6 to V5. +crates: +- name: snowbridge-router-primitives + bump: major +- name: emulated-integration-tests-common + bump: major +- name: asset-hub-rococo-runtime + bump: major +- name: asset-hub-westend-runtime + bump: major +- name: asset-test-utils + bump: major +- name: bridge-hub-rococo-runtime + bump: major +- name: bridge-hub-westend-runtime + bump: major +- name: coretime-rococo-runtime + bump: major +- name: coretime-westend-runtime + bump: major +- name: people-rococo-runtime + bump: major +- name: people-westend-runtime + bump: major +- name: parachains-runtimes-test-utils + bump: major +- name: polkadot-runtime-parachains + bump: major +- name: rococo-runtime + bump: major +- name: westend-runtime + bump: major +- name: staging-xcm + bump: major +- name: staging-xcm-builder + bump: major +- name: staging-xcm-executor + bump: major From f7838db506f48e48671f867f23d8c12858c5b67c Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Thu, 5 Dec 2024 22:27:24 +0100 Subject: [PATCH 21/51] `basic-authorship`: debug level is now less spammy (#6768) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `debug` level in `sc-basic-authorship` is now less spammy. Previously it was outputing logs per individual transactions. It was quite hard to follow the logs (and also generates unneeded traffic in grafana). Now `debug` level only show some internal details, without spamming output with per-transaction logs. They were moved to `trace` level. I also added the `EndProposingReason` to the summary INFO message. This allows us to know what was the block limit (which is very useful for debugging). Example: ``` 🎁 Prepared block for proposing at 64 (1186 ms) hash: 0x4b5386c13c507d0dbab319ac054cc1bcfa08311e184452221ad07f12ecc6091c; parent_hash: 0x157c…ca5e; end: HitBlockWeightLimit; extrinsics_count: 7032; ``` --------- Co-authored-by: GitHub Action --- prdoc/pr_6768.prdoc | 14 ++++++++++++++ .../basic-authorship/src/basic_authorship.rs | 12 +++++++----- substrate/client/proposer-metrics/src/lib.rs | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 prdoc/pr_6768.prdoc diff --git a/prdoc/pr_6768.prdoc b/prdoc/pr_6768.prdoc new file mode 100644 index 000000000000..3e194078df26 --- /dev/null +++ b/prdoc/pr_6768.prdoc @@ -0,0 +1,14 @@ +title: '`basic-authorship`: debug level is now less spammy' +doc: +- audience: Node Dev + description: |- + The `debug` level in `sc-basic-authorship` is now less spammy. Previously it was outputing logs per individual transactions. It made quite hard to follow the logs (and also generates unneeded traffic in grafana). + + Now debug level only show some internal details, without spamming output with per-transaction logs. They were moved to `trace` level. + + I also added the `EndProposingReason` to the summary INFO message. This allows us to know what was the block limit (which is very useful for debugging). +crates: +- name: sc-basic-authorship + bump: major +- name: sc-proposer-metrics + bump: major diff --git a/substrate/client/basic-authorship/src/basic_authorship.rs b/substrate/client/basic-authorship/src/basic_authorship.rs index 79e6fddae99f..848ac724c6b8 100644 --- a/substrate/client/basic-authorship/src/basic_authorship.rs +++ b/substrate/client/basic-authorship/src/basic_authorship.rs @@ -483,7 +483,7 @@ where match sc_block_builder::BlockBuilder::push(block_builder, pending_tx_data) { Ok(()) => { transaction_pushed = true; - debug!(target: LOG_TARGET, "[{:?}] Pushed to the block.", pending_tx_hash); + trace!(target: LOG_TARGET, "[{:?}] Pushed to the block.", pending_tx_hash); }, Err(ApplyExtrinsicFailed(Validity(e))) if e.exhausted_resources() => { pending_iterator.report_invalid(&pending_tx); @@ -565,20 +565,22 @@ where if log::log_enabled!(log::Level::Info) { info!( - "🎁 Prepared block for proposing at {} ({} ms) [hash: {:?}; parent_hash: {}; extrinsics_count: {}", + "🎁 Prepared block for proposing at {} ({} ms) hash: {:?}; parent_hash: {}; end: {:?}; extrinsics_count: {}", block.header().number(), block_took.as_millis(), ::Hash::from(block.header().hash()), block.header().parent_hash(), + end_reason, extrinsics.len() ) - } else if log::log_enabled!(log::Level::Debug) { - debug!( - "🎁 Prepared block for proposing at {} ({} ms) [hash: {:?}; parent_hash: {}; {extrinsics_summary}", + } else if log::log_enabled!(log::Level::Trace) { + trace!( + "🎁 Prepared block for proposing at {} ({} ms) hash: {:?}; parent_hash: {}; end: {:?}; {extrinsics_summary}", block.header().number(), block_took.as_millis(), ::Hash::from(block.header().hash()), block.header().parent_hash(), + end_reason ); } diff --git a/substrate/client/proposer-metrics/src/lib.rs b/substrate/client/proposer-metrics/src/lib.rs index 2856300cf802..a62278988f12 100644 --- a/substrate/client/proposer-metrics/src/lib.rs +++ b/substrate/client/proposer-metrics/src/lib.rs @@ -44,7 +44,7 @@ impl MetricsLink { } /// The reason why proposing a block ended. -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum EndProposingReason { NoMoreTransactions, HitDeadline, From 526a440203d1ff96640c6163291e57e10c8e4f9b Mon Sep 17 00:00:00 2001 From: Maksym H <1177472+mordamax@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:34:08 +0100 Subject: [PATCH 22/51] Update weights for westend pallet balances (#6777) Co-authored-by: command-bot <> --- .../westend/src/weights/pallet_balances.rs | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/polkadot/runtime/westend/src/weights/pallet_balances.rs b/polkadot/runtime/westend/src/weights/pallet_balances.rs index 5e91f31920ca..b303a1a21766 100644 --- a/polkadot/runtime/westend/src/weights/pallet_balances.rs +++ b/polkadot/runtime/westend/src/weights/pallet_balances.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_balances` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-05-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-unxyhko3-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -54,8 +54,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 43_248_000 picoseconds. - Weight::from_parts(43_872_000, 0) + // Minimum execution time: 50_394_000 picoseconds. + Weight::from_parts(51_666_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -66,8 +66,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 33_990_000 picoseconds. - Weight::from_parts(34_693_000, 0) + // Minimum execution time: 40_307_000 picoseconds. + Weight::from_parts(41_722_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,8 +78,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 12_681_000 picoseconds. - Weight::from_parts(13_183_000, 0) + // Minimum execution time: 19_110_000 picoseconds. + Weight::from_parts(19_623_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +90,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 17_474_000 picoseconds. - Weight::from_parts(18_063_000, 0) + // Minimum execution time: 26_837_000 picoseconds. + Weight::from_parts(27_672_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -102,8 +102,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 45_699_000 picoseconds. - Weight::from_parts(46_099_000, 0) + // Minimum execution time: 53_032_000 picoseconds. + Weight::from_parts(54_040_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -114,8 +114,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 42_453_000 picoseconds. - Weight::from_parts(43_133_000, 0) + // Minimum execution time: 49_429_000 picoseconds. + Weight::from_parts(50_020_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -126,8 +126,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 15_066_000 picoseconds. - Weight::from_parts(15_605_000, 0) + // Minimum execution time: 22_114_000 picoseconds. + Weight::from_parts(22_526_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -139,11 +139,11 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0 + u * (136 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 14_180_000 picoseconds. - Weight::from_parts(14_598_000, 0) + // Minimum execution time: 17_550_000 picoseconds. + Weight::from_parts(17_860_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 13_221 - .saturating_add(Weight::from_parts(13_422_901, 0).saturating_mul(u.into())) + // Standard Error: 11_891 + .saturating_add(Weight::from_parts(15_027_705, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -152,24 +152,24 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_130_000 picoseconds. - Weight::from_parts(5_257_000, 0) + // Minimum execution time: 6_605_000 picoseconds. + Weight::from_parts(6_922_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn burn_allow_death() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 27_328_000 picoseconds. - Weight::from_parts(27_785_000, 0) + // Minimum execution time: 31_182_000 picoseconds. + Weight::from_parts(32_104_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn burn_keep_alive() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 17_797_000 picoseconds. - Weight::from_parts(18_103_000, 0) + // Minimum execution time: 21_105_000 picoseconds. + Weight::from_parts(21_533_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } From 906fa9e51306635245a22e03160d1c761fae6cc3 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Mon, 9 Dec 2024 00:02:38 +0100 Subject: [PATCH 23/51] XCM V5 - SetHints instruction (#6566) Last feature we wanted for V5, changing `SetAssetClaimer` to be just one of many possible "hints" that you can specify at the beginning of your program to change its behaviour. This makes it easier to add new hints in the future and have barriers accept them. --------- Co-authored-by: GitHub Action --- Cargo.lock | 1 + .../pallets/inbound-queue/src/test.rs | 4 +- .../src/tests/set_asset_claimer.rs | 4 +- .../asset-hub-rococo/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../asset-hub-westend/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../bridge-hub-rococo/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../bridge-hub-westend/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../coretime-rococo/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../coretime-westend/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../people-rococo/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../people-westend/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../runtime/rococo/src/weights/xcm/mod.rs | 13 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../runtime/westend/src/weights/xcm/mod.rs | 15 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 2 +- .../src/generic/benchmarking.rs | 8 +- polkadot/xcm/procedural/Cargo.toml | 2 + .../xcm/procedural/src/builder_pattern.rs | 394 ++++++++++-------- .../enum_variants.rs} | 36 +- polkadot/xcm/procedural/src/lib.rs | 9 + .../xcm/procedural/tests/builder_pattern.rs | 59 +++ ...ution_named_fields.rs => enum_variants.rs} | 23 +- .../loads_holding_no_operands.stderr | 6 - .../unexpected_attribute.stderr | 5 + .../unpaid_execution_named_fields.stderr | 5 - polkadot/xcm/src/v4/mod.rs | 2 +- polkadot/xcm/src/v5/mod.rs | 34 +- polkadot/xcm/xcm-builder/src/barriers.rs | 3 +- .../xcm/xcm-builder/src/tests/barriers.rs | 20 + polkadot/xcm/xcm-executor/src/lib.rs | 10 +- .../src/tests/set_asset_claimer.rs | 6 +- prdoc/pr_6566.prdoc | 45 ++ 40 files changed, 559 insertions(+), 269 deletions(-) rename polkadot/xcm/procedural/{tests/ui/builder_pattern/loads_holding_no_operands.rs => src/enum_variants.rs} (51%) rename polkadot/xcm/procedural/tests/{ui/builder_pattern/unpaid_execution_named_fields.rs => enum_variants.rs} (70%) delete mode 100644 polkadot/xcm/procedural/tests/ui/builder_pattern/loads_holding_no_operands.stderr create mode 100644 polkadot/xcm/procedural/tests/ui/builder_pattern/unexpected_attribute.stderr delete mode 100644 polkadot/xcm/procedural/tests/ui/builder_pattern/unpaid_execution_named_fields.stderr create mode 100644 prdoc/pr_6566.prdoc diff --git a/Cargo.lock b/Cargo.lock index dad578ba0c1b..cee1e2ce7411 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31675,6 +31675,7 @@ name = "xcm-procedural" version = "7.0.0" dependencies = [ "Inflector", + "frame-support 28.0.0", "proc-macro2 1.0.86", "quote 1.0.37", "staging-xcm 7.0.0", diff --git a/bridges/snowbridge/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/pallets/inbound-queue/src/test.rs index 5386b845f2ec..1e0bd8acc925 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/test.rs @@ -40,8 +40,8 @@ fn test_submit_happy_path() { .into(), nonce: 1, message_id: [ - 97, 161, 116, 204, 182, 115, 192, 144, 130, 243, 240, 193, 122, 154, 108, 91, 247, - 41, 226, 237, 202, 158, 238, 239, 210, 8, 147, 131, 84, 146, 171, 176, + 86, 101, 80, 125, 84, 10, 227, 145, 230, 209, 152, 38, 206, 251, 206, 208, 244, + 221, 22, 215, 1, 252, 79, 181, 99, 207, 166, 220, 98, 3, 81, 7, ], fee_burned: 110000000000, } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_asset_claimer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_asset_claimer.rs index 544b05360521..bc00106b47c1 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_asset_claimer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_asset_claimer.rs @@ -44,7 +44,7 @@ fn test_set_asset_claimer_within_a_chain() { type RuntimeCall = ::RuntimeCall; let asset_trap_xcm = Xcm::::builder_unsafe() - .set_asset_claimer(bob_location.clone()) + .set_hints(vec![AssetClaimer { location: bob_location.clone() }]) .withdraw_asset(assets.clone()) .clear_origin() .build(); @@ -116,7 +116,7 @@ fn test_set_asset_claimer_between_the_chains() { let assets: Assets = (Parent, trap_amount).into(); type RuntimeCall = ::RuntimeCall; let trap_xcm = Xcm::::builder_unsafe() - .set_asset_claimer(alice_bh_sibling.clone()) + .set_hints(vec![AssetClaimer { location: alice_bh_sibling.clone() }]) .withdraw_asset(assets.clone()) .clear_origin() .build(); diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs index 74f564037400..ccf473484cad 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs @@ -22,6 +22,7 @@ use alloc::vec::Vec; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -176,8 +177,16 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index b69c136b29d9..d48debef94c8 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -87,7 +87,7 @@ impl WeightInfo { // Minimum execution time: 5_803_000 picoseconds. Weight::from_parts(5_983_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs index ff99f1242b22..a0e9705ff01d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs @@ -21,6 +21,7 @@ use alloc::vec::Vec; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -176,8 +177,16 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 528694123115..0ec2741c0490 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -87,7 +87,7 @@ impl WeightInfo { // Minimum execution time: 5_580_000 picoseconds. Weight::from_parts(5_950_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs index e5c6f493d6dc..efc2798999bf 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs @@ -22,6 +22,7 @@ use codec::Encode; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -257,8 +258,16 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn execute_with_origin(_: &Option, _: &Xcm) -> Weight { XcmGeneric::::execute_with_origin() diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index bac73e0e0567..daf22190a42b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -373,7 +373,7 @@ impl WeightInfo { // Minimum execution time: 1_085_000 picoseconds. Weight::from_parts(1_161_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs index 939b1c7a287b..15a1dae09d9b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs @@ -23,6 +23,7 @@ use codec::Encode; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -178,8 +179,16 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 6434f6206fbe..03cbaa866ad8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -373,7 +373,7 @@ impl WeightInfo { // Minimum execution time: 995_000 picoseconds. Weight::from_parts(1_060_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs index 2c4a97601c64..dc21e2ea117f 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs @@ -22,6 +22,7 @@ use alloc::vec::Vec; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -255,8 +256,16 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn execute_with_origin(_: &Option, _: &Xcm) -> Weight { XcmGeneric::::execute_with_origin() diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index d207c09ffcd8..cdcba6134bf8 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -331,7 +331,7 @@ impl WeightInfo { // Minimum execution time: 650_000 picoseconds. Weight::from_parts(673_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs index 906088a1df86..29466b3718c1 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs @@ -21,6 +21,7 @@ use alloc::vec::Vec; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -176,8 +177,16 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index fb6e4631736d..6c6d3cf8c525 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -331,7 +331,7 @@ impl WeightInfo { // Minimum execution time: 624_000 picoseconds. Weight::from_parts(659_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs index 47008a2943e5..d55198f60a00 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs @@ -21,6 +21,7 @@ use alloc::vec::Vec; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -254,8 +255,16 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn execute_with_origin(_: &Option, _: &Xcm) -> Weight { XcmGeneric::::execute_with_origin() diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 6aac6119e7ec..caa916507348 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -331,7 +331,7 @@ impl WeightInfo { // Minimum execution time: 685_000 picoseconds. Weight::from_parts(757_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs index 27fd499ebba7..915a499cb77c 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs @@ -21,6 +21,7 @@ use alloc::vec::Vec; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::{ latest::{prelude::*, AssetTransferFilter}, DoubleEncoded, @@ -254,8 +255,16 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn execute_with_origin(_: &Option, _: &Xcm) -> Weight { XcmGeneric::::execute_with_origin() diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 36400f2c1e66..ad2cde22a075 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -331,7 +331,7 @@ impl WeightInfo { // Minimum execution time: 598_000 picoseconds. Weight::from_parts(655_000, 0) } - pub fn set_asset_claimer() -> Weight { + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/polkadot/runtime/rococo/src/weights/xcm/mod.rs b/polkadot/runtime/rococo/src/weights/xcm/mod.rs index 16f51a778917..eb27e5c5a897 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/mod.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/mod.rs @@ -24,6 +24,7 @@ use xcm::{latest::prelude::*, DoubleEncoded}; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::latest::AssetTransferFilter; /// Types of asset supported by the Rococo runtime. @@ -290,8 +291,16 @@ impl XcmWeightInfo for RococoXcmWeight { fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } fn execute_with_origin(_: &Option, _: &Xcm) -> Weight { XcmGeneric::::execute_with_origin() diff --git a/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index e5915a7986bf..2dc8880c8326 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -82,7 +82,7 @@ impl WeightInfo { // Minimum execution time: 2_899_000 picoseconds. Weight::from_parts(3_090_000, 0) } - pub(crate) fn set_asset_claimer() -> Weight { + pub(crate) fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs index 60265445334d..d2691c998d99 100644 --- a/polkadot/runtime/westend/src/weights/xcm/mod.rs +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -27,6 +27,7 @@ use xcm::{ use pallet_xcm_benchmarks_fungible::WeightInfo as XcmBalancesWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; +use sp_runtime::BoundedVec; use xcm::latest::AssetTransferFilter; /// Types of asset supported by the westend runtime. @@ -208,11 +209,17 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - - fn set_asset_claimer(_location: &Location) -> Weight { - XcmGeneric::::set_asset_claimer() + fn set_hints(hints: &BoundedVec) -> Weight { + let mut weight = Weight::zero(); + for hint in hints { + match hint { + AssetClaimer { .. } => { + weight = weight.saturating_add(XcmGeneric::::asset_claimer()); + }, + } + } + weight } - fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } diff --git a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 076744a59753..dfc02fd20bc3 100644 --- a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -82,7 +82,7 @@ impl WeightInfo { // Minimum execution time: 3_096_000 picoseconds. Weight::from_parts(3_313_000, 0) } - pub(crate) fn set_asset_claimer() -> Weight { + pub(crate) fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index 285322891c63..431c7a5f1371 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -20,7 +20,7 @@ use crate::{account_and_location, new_executor, EnsureDelivery, XcmCallOf}; use alloc::{vec, vec::Vec}; use codec::Encode; use frame_benchmarking::v2::*; -use frame_support::traits::fungible::Inspect; +use frame_support::{traits::fungible::Inspect, BoundedVec}; use xcm::{ latest::{prelude::*, MaxDispatchErrorLen, MaybeErrorCode, Weight, MAX_ITEMS_IN_ASSETS}, DoubleEncoded, @@ -144,7 +144,11 @@ mod benchmarks { let mut executor = new_executor::(Default::default()); let (_, sender_location) = account_and_location::(1); - let instruction = Instruction::SetAssetClaimer { location: sender_location.clone() }; + let instruction = Instruction::SetHints { + hints: BoundedVec::::truncate_from(vec![AssetClaimer { + location: sender_location.clone(), + }]), + }; let xcm = Xcm(vec![instruction]); #[block] diff --git a/polkadot/xcm/procedural/Cargo.toml b/polkadot/xcm/procedural/Cargo.toml index 3167766158ff..88ed3c94ddf4 100644 --- a/polkadot/xcm/procedural/Cargo.toml +++ b/polkadot/xcm/procedural/Cargo.toml @@ -26,3 +26,5 @@ trybuild = { features = ["diff"], workspace = true } # NOTE: we have to explicitly specify `std` because of trybuild # https://github.com/paritytech/polkadot-sdk/pull/5167 xcm = { workspace = true, default-features = true, features = ["std"] } +# For testing macros. +frame-support = { workspace = true } diff --git a/polkadot/xcm/procedural/src/builder_pattern.rs b/polkadot/xcm/procedural/src/builder_pattern.rs index b65290332af9..34b89f13422c 100644 --- a/polkadot/xcm/procedural/src/builder_pattern.rs +++ b/polkadot/xcm/procedural/src/builder_pattern.rs @@ -20,8 +20,8 @@ use inflector::Inflector; use proc_macro2::TokenStream as TokenStream2; use quote::{format_ident, quote}; use syn::{ - Data, DataEnum, DeriveInput, Error, Expr, ExprLit, Fields, Ident, Lit, Meta, MetaNameValue, - Result, Variant, + Data, DataEnum, DeriveInput, Error, Expr, ExprLit, Fields, GenericArgument, Ident, Lit, Meta, + MetaNameValue, PathArguments, Result, Type, TypePath, Variant, }; pub fn derive(input: DeriveInput) -> Result { @@ -29,7 +29,7 @@ pub fn derive(input: DeriveInput) -> Result { Data::Enum(data_enum) => data_enum, _ => return Err(Error::new_spanned(&input, "Expected the `Instruction` enum")), }; - let builder_raw_impl = generate_builder_raw_impl(&input.ident, data_enum); + let builder_raw_impl = generate_builder_raw_impl(&input.ident, data_enum)?; let builder_impl = generate_builder_impl(&input.ident, data_enum)?; let builder_unpaid_impl = generate_builder_unpaid_impl(&input.ident, data_enum)?; let output = quote! { @@ -83,54 +83,12 @@ pub fn derive(input: DeriveInput) -> Result { Ok(output) } -fn generate_builder_raw_impl(name: &Ident, data_enum: &DataEnum) -> TokenStream2 { - let methods = data_enum.variants.iter().map(|variant| { - let variant_name = &variant.ident; - let method_name_string = &variant_name.to_string().to_snake_case(); - let method_name = syn::Ident::new(method_name_string, variant_name.span()); - let docs = get_doc_comments(variant); - let method = match &variant.fields { - Fields::Unit => { - quote! { - pub fn #method_name(mut self) -> Self { - self.instructions.push(#name::::#variant_name); - self - } - } - }, - Fields::Unnamed(fields) => { - let arg_names: Vec<_> = fields - .unnamed - .iter() - .enumerate() - .map(|(index, _)| format_ident!("arg{}", index)) - .collect(); - let arg_types: Vec<_> = fields.unnamed.iter().map(|field| &field.ty).collect(); - quote! { - pub fn #method_name(mut self, #(#arg_names: impl Into<#arg_types>),*) -> Self { - #(let #arg_names = #arg_names.into();)* - self.instructions.push(#name::::#variant_name(#(#arg_names),*)); - self - } - } - }, - Fields::Named(fields) => { - let arg_names: Vec<_> = fields.named.iter().map(|field| &field.ident).collect(); - let arg_types: Vec<_> = fields.named.iter().map(|field| &field.ty).collect(); - quote! { - pub fn #method_name(mut self, #(#arg_names: impl Into<#arg_types>),*) -> Self { - #(let #arg_names = #arg_names.into();)* - self.instructions.push(#name::::#variant_name { #(#arg_names),* }); - self - } - } - }, - }; - quote! { - #(#docs)* - #method - } - }); +fn generate_builder_raw_impl(name: &Ident, data_enum: &DataEnum) -> Result { + let methods = data_enum + .variants + .iter() + .map(|variant| convert_variant_to_method(name, variant, None)) + .collect::>>()?; let output = quote! { impl XcmBuilder { #(#methods)* @@ -140,7 +98,7 @@ fn generate_builder_raw_impl(name: &Ident, data_enum: &DataEnum) -> TokenStream2 } } }; - output + Ok(output) } fn generate_builder_impl(name: &Ident, data_enum: &DataEnum) -> Result { @@ -165,11 +123,17 @@ fn generate_builder_impl(name: &Ident, data_enum: &DataEnum) -> Result>>()?; @@ -178,57 +142,14 @@ fn generate_builder_impl(name: &Ident, data_enum: &DataEnum) -> Result { - let arg_names: Vec<_> = fields - .unnamed - .iter() - .enumerate() - .map(|(index, _)| format_ident!("arg{}", index)) - .collect(); - let arg_types: Vec<_> = fields.unnamed.iter().map(|field| &field.ty).collect(); - quote! { - #(#docs)* - pub fn #method_name(self, #(#arg_names: impl Into<#arg_types>),*) -> XcmBuilder { - let mut new_instructions = self.instructions; - #(let #arg_names = #arg_names.into();)* - new_instructions.push(#name::::#variant_name(#(#arg_names),*)); - XcmBuilder { - instructions: new_instructions, - state: core::marker::PhantomData, - } - } - } - }, - Fields::Named(fields) => { - let arg_names: Vec<_> = fields.named.iter().map(|field| &field.ident).collect(); - let arg_types: Vec<_> = fields.named.iter().map(|field| &field.ty).collect(); - quote! { - #(#docs)* - pub fn #method_name(self, #(#arg_names: impl Into<#arg_types>),*) -> XcmBuilder { - let mut new_instructions = self.instructions; - #(let #arg_names = #arg_names.into();)* - new_instructions.push(#name::::#variant_name { #(#arg_names),* }); - XcmBuilder { - instructions: new_instructions, - state: core::marker::PhantomData, - } - } - } - }, - _ => - return Err(Error::new_spanned( - variant, - "Instructions that load the holding register should take operands", - )), - }; + let method = convert_variant_to_method( + name, + variant, + Some(quote! { XcmBuilder }), + )?; Ok(method) }) - .collect::, _>>()?; + .collect::>>()?; let first_impl = quote! { impl XcmBuilder { @@ -240,27 +161,12 @@ fn generate_builder_impl(name: &Ident, data_enum: &DataEnum) -> Result = data_enum .variants .iter() - .filter(|variant| variant.ident == "ClearOrigin") + .filter(|variant| variant.ident == "ClearOrigin" || variant.ident == "SetHints") .map(|variant| { - let variant_name = &variant.ident; - let method_name_string = &variant_name.to_string().to_snake_case(); - let method_name = syn::Ident::new(method_name_string, variant_name.span()); - let docs = get_doc_comments(variant); - let method = match &variant.fields { - Fields::Unit => { - quote! { - #(#docs)* - pub fn #method_name(mut self) -> XcmBuilder { - self.instructions.push(#name::::#variant_name); - self - } - } - }, - _ => return Err(Error::new_spanned(variant, "ClearOrigin should have no fields")), - }; + let method = convert_variant_to_method(name, variant, None)?; Ok(method) }) - .collect::, _>>()?; + .collect::>>()?; // Then we require fees to be paid let pay_fees_variants = data_enum @@ -295,36 +201,12 @@ fn generate_builder_impl(name: &Ident, data_enum: &DataEnum) -> Result { - let arg_names: Vec<_> = - fields.named.iter().map(|field| &field.ident).collect(); - let arg_types: Vec<_> = - fields.named.iter().map(|field| &field.ty).collect(); - quote! { - #(#docs)* - pub fn #method_name(self, #(#arg_names: impl Into<#arg_types>),*) -> XcmBuilder { - let mut new_instructions = self.instructions; - #(let #arg_names = #arg_names.into();)* - new_instructions.push(#name::::#variant_name { #(#arg_names),* }); - XcmBuilder { - instructions: new_instructions, - state: core::marker::PhantomData, - } - } - } - }, - _ => - return Err(Error::new_spanned( - variant, - "Both BuyExecution and PayFees have named fields", - )), - }; - Ok(fields) + let method = convert_variant_to_method( + name, + variant, + Some(quote! { XcmBuilder }), + )?; + Ok(method) }) .collect::>>()?; @@ -349,35 +231,156 @@ fn generate_builder_unpaid_impl(name: &Ident, data_enum: &DataEnum) -> Result fields, - _ => - return Err(Error::new_spanned( - unpaid_execution_variant, - "UnpaidExecution should have named fields", - )), - }; - let arg_names: Vec<_> = fields.named.iter().map(|field| &field.ident).collect(); - let arg_types: Vec<_> = fields.named.iter().map(|field| &field.ty).collect(); + let method = convert_variant_to_method( + name, + &unpaid_execution_variant, + Some(quote! { XcmBuilder }), + )?; Ok(quote! { impl XcmBuilder { - #(#docs)* - pub fn #unpaid_execution_method_name(self, #(#arg_names: impl Into<#arg_types>),*) -> XcmBuilder { - let mut new_instructions = self.instructions; - #(let #arg_names = #arg_names.into();)* - new_instructions.push(#name::::#unpaid_execution_ident { #(#arg_names),* }); - XcmBuilder { - instructions: new_instructions, - state: core::marker::PhantomData, + #method + } + }) +} + +// Have to call with `XcmBuilder` in allowed_after_load_holding_methods. +fn convert_variant_to_method( + name: &Ident, + variant: &Variant, + maybe_return_type: Option, +) -> Result { + let variant_name = &variant.ident; + let method_name_string = &variant_name.to_string().to_snake_case(); + let method_name = syn::Ident::new(method_name_string, variant_name.span()); + let docs = get_doc_comments(variant); + let method = match &variant.fields { + Fields::Unit => + if let Some(return_type) = maybe_return_type { + quote! { + pub fn #method_name(self) -> #return_type { + let mut new_instructions = self.instructions; + new_instructions.push(#name::::#variant_name); + XcmBuilder { + instructions: new_instructions, + state: core::marker::PhantomData, + } + } + } + } else { + quote! { + pub fn #method_name(mut self) -> Self { + self.instructions.push(#name::::#variant_name); + self + } + } + }, + Fields::Unnamed(fields) => { + let arg_names: Vec<_> = fields + .unnamed + .iter() + .enumerate() + .map(|(index, _)| format_ident!("arg{}", index)) + .collect(); + let arg_types: Vec<_> = fields.unnamed.iter().map(|field| &field.ty).collect(); + if let Some(return_type) = maybe_return_type { + quote! { + pub fn #method_name(self, #(#arg_names: impl Into<#arg_types>),*) -> #return_type { + let mut new_instructions = self.instructions; + #(let #arg_names = #arg_names.into();)* + new_instructions.push(#name::::#variant_name(#(#arg_names),*)); + XcmBuilder { + instructions: new_instructions, + state: core::marker::PhantomData, + } + } + } + } else { + quote! { + pub fn #method_name(mut self, #(#arg_names: impl Into<#arg_types>),*) -> Self { + #(let #arg_names = #arg_names.into();)* + self.instructions.push(#name::::#variant_name(#(#arg_names),*)); + self + } } } - } + }, + Fields::Named(fields) => { + let normal_fields: Vec<_> = fields + .named + .iter() + .filter(|field| { + if let Type::Path(TypePath { path, .. }) = &field.ty { + for segment in &path.segments { + if segment.ident == format_ident!("BoundedVec") { + return false; + } + } + true + } else { + true + } + }) + .collect(); + let bounded_fields: Vec<_> = fields + .named + .iter() + .filter(|field| { + if let Type::Path(TypePath { path, .. }) = &field.ty { + for segment in &path.segments { + if segment.ident == format_ident!("BoundedVec") { + return true; + } + } + false + } else { + false + } + }) + .collect(); + let arg_names: Vec<_> = normal_fields.iter().map(|field| &field.ident).collect(); + let arg_types: Vec<_> = normal_fields.iter().map(|field| &field.ty).collect(); + let bounded_names: Vec<_> = bounded_fields.iter().map(|field| &field.ident).collect(); + let bounded_types = bounded_fields + .iter() + .map(|field| extract_generic_argument(&field.ty, 0, "BoundedVec's inner type")) + .collect::>>()?; + let bounded_sizes = bounded_fields + .iter() + .map(|field| extract_generic_argument(&field.ty, 1, "BoundedVec's size")) + .collect::>>()?; + let comma_in_the_middle = if normal_fields.is_empty() { + quote! {} + } else { + quote! {,} + }; + if let Some(return_type) = maybe_return_type { + quote! { + pub fn #method_name(self, #(#arg_names: impl Into<#arg_types>),* #comma_in_the_middle #(#bounded_names: Vec<#bounded_types>),*) -> #return_type { + let mut new_instructions = self.instructions; + #(let #arg_names = #arg_names.into();)* + #(let #bounded_names = BoundedVec::<#bounded_types, #bounded_sizes>::truncate_from(#bounded_names);)* + new_instructions.push(#name::::#variant_name { #(#arg_names),* #comma_in_the_middle #(#bounded_names),* }); + XcmBuilder { + instructions: new_instructions, + state: core::marker::PhantomData, + } + } + } + } else { + quote! { + pub fn #method_name(mut self, #(#arg_names: impl Into<#arg_types>),* #comma_in_the_middle #(#bounded_names: Vec<#bounded_types>),*) -> Self { + #(let #arg_names = #arg_names.into();)* + #(let #bounded_names = BoundedVec::<#bounded_types, #bounded_sizes>::truncate_from(#bounded_names);)* + self.instructions.push(#name::::#variant_name { #(#arg_names),* #comma_in_the_middle #(#bounded_names),* }); + self + } + } + } + }, + }; + Ok(quote! { + #(#docs)* + #method }) } @@ -395,3 +398,40 @@ fn get_doc_comments(variant: &Variant) -> Vec { .map(|doc| syn::parse_str::(&format!("/// {}", doc)).unwrap()) .collect() } + +fn extract_generic_argument<'a>( + field_ty: &'a Type, + index: usize, + expected_msg: &str, +) -> Result<&'a Ident> { + if let Type::Path(type_path) = field_ty { + if let Some(segment) = type_path.path.segments.last() { + if let PathArguments::AngleBracketed(angle_brackets) = &segment.arguments { + let args: Vec<_> = angle_brackets.args.iter().collect(); + if let Some(GenericArgument::Type(Type::Path(TypePath { path, .. }))) = + args.get(index) + { + return path.get_ident().ok_or_else(|| { + Error::new_spanned( + path, + format!("Expected an identifier for {}", expected_msg), + ) + }); + } + return Err(Error::new_spanned( + angle_brackets, + format!("Expected a generic argument at index {} for {}", index, expected_msg), + )); + } + return Err(Error::new_spanned( + &segment.arguments, + format!("Expected angle-bracketed arguments for {}", expected_msg), + )); + } + return Err(Error::new_spanned( + &type_path.path, + format!("Expected at least one path segment for {}", expected_msg), + )); + } + Err(Error::new_spanned(field_ty, format!("Expected a path type for {}", expected_msg))) +} diff --git a/polkadot/xcm/procedural/tests/ui/builder_pattern/loads_holding_no_operands.rs b/polkadot/xcm/procedural/src/enum_variants.rs similarity index 51% rename from polkadot/xcm/procedural/tests/ui/builder_pattern/loads_holding_no_operands.rs rename to polkadot/xcm/procedural/src/enum_variants.rs index 070f0be6bacc..f9f2d9e15675 100644 --- a/polkadot/xcm/procedural/tests/ui/builder_pattern/loads_holding_no_operands.rs +++ b/polkadot/xcm/procedural/src/enum_variants.rs @@ -14,19 +14,25 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Test error when an instruction that loads the holding register doesn't take operands. - -use xcm_procedural::Builder; - -struct Xcm(pub Vec>); - -#[derive(Builder)] -enum Instruction { - #[builder(loads_holding)] - WithdrawAsset, - BuyExecution { fees: u128 }, - UnpaidExecution { weight_limit: (u32, u32) }, - Transact { call: Call }, +//! Simple derive macro for getting the number of variants in an enum. + +use proc_macro2::TokenStream as TokenStream2; +use quote::{format_ident, quote}; +use syn::{Data, DeriveInput, Error, Result}; + +pub fn derive(input: DeriveInput) -> Result { + let data_enum = match &input.data { + Data::Enum(data_enum) => data_enum, + _ => return Err(Error::new_spanned(&input, "Expected an enum.")), + }; + let ident = format_ident!("{}NumVariants", input.ident); + let number_of_variants: usize = data_enum.variants.iter().count(); + Ok(quote! { + pub struct #ident; + impl ::frame_support::traits::Get for #ident { + fn get() -> u32 { + #number_of_variants as u32 + } + } + }) } - -fn main() {} diff --git a/polkadot/xcm/procedural/src/lib.rs b/polkadot/xcm/procedural/src/lib.rs index 9971fdceb69a..0dd270286f69 100644 --- a/polkadot/xcm/procedural/src/lib.rs +++ b/polkadot/xcm/procedural/src/lib.rs @@ -20,6 +20,7 @@ use proc_macro::TokenStream; use syn::{parse_macro_input, DeriveInput}; mod builder_pattern; +mod enum_variants; mod v3; mod v4; mod v5; @@ -86,3 +87,11 @@ pub fn derive_builder(input: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro_derive(NumVariants)] +pub fn derive_num_variants(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + enum_variants::derive(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/polkadot/xcm/procedural/tests/builder_pattern.rs b/polkadot/xcm/procedural/tests/builder_pattern.rs index 4202309bf3f7..3915621916d4 100644 --- a/polkadot/xcm/procedural/tests/builder_pattern.rs +++ b/polkadot/xcm/procedural/tests/builder_pattern.rs @@ -17,6 +17,7 @@ //! Test the methods generated by the Builder derive macro. //! Tests directly on the actual Xcm struct and Instruction enum. +use frame_support::BoundedVec; use xcm::latest::prelude::*; #[test] @@ -100,3 +101,61 @@ fn default_builder_allows_clear_origin_before_buy_execution() { ]) ); } + +#[test] +fn bounded_vecs_use_vecs_and_truncate_them() { + let claimer = Location::parent(); + // We can use a vec instead of a bounded vec for specifying hints. + let xcm: Xcm<()> = Xcm::builder_unsafe() + .set_hints(vec![AssetClaimer { location: claimer.clone() }]) + .build(); + assert_eq!( + xcm, + Xcm(vec![SetHints { + hints: BoundedVec::::truncate_from(vec![AssetClaimer { + location: Location::parent() + },]), + },]) + ); + + // If we include more than the limit they'll get truncated. + let xcm: Xcm<()> = Xcm::builder_unsafe() + .set_hints(vec![ + AssetClaimer { location: claimer.clone() }, + AssetClaimer { location: Location::here() }, + ]) + .build(); + assert_eq!( + xcm, + Xcm(vec![SetHints { + hints: BoundedVec::::truncate_from(vec![AssetClaimer { + location: Location::parent() + },]), + },]) + ); + + let xcm: Xcm<()> = Xcm::builder() + .withdraw_asset((Here, 100u128)) + .set_hints(vec![AssetClaimer { location: claimer }]) + .clear_origin() + .pay_fees((Here, 10u128)) + .deposit_asset(All, [0u8; 32]) + .build(); + assert_eq!( + xcm, + Xcm(vec![ + WithdrawAsset(Asset { id: AssetId(Location::here()), fun: Fungible(100) }.into()), + SetHints { + hints: BoundedVec::::truncate_from(vec![AssetClaimer { + location: Location::parent() + }]) + }, + ClearOrigin, + PayFees { asset: Asset { id: AssetId(Location::here()), fun: Fungible(10) } }, + DepositAsset { + assets: All.into(), + beneficiary: AccountId32 { id: [0u8; 32], network: None }.into() + }, + ]) + ); +} diff --git a/polkadot/xcm/procedural/tests/ui/builder_pattern/unpaid_execution_named_fields.rs b/polkadot/xcm/procedural/tests/enum_variants.rs similarity index 70% rename from polkadot/xcm/procedural/tests/ui/builder_pattern/unpaid_execution_named_fields.rs rename to polkadot/xcm/procedural/tests/enum_variants.rs index bb98d603fd91..4a5362c1579a 100644 --- a/polkadot/xcm/procedural/tests/ui/builder_pattern/unpaid_execution_named_fields.rs +++ b/polkadot/xcm/procedural/tests/enum_variants.rs @@ -14,17 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Test error when the `BuyExecution` instruction doesn't take named fields. +//! Test the struct generated by the `NumVariants` derive macro. -use xcm_procedural::Builder; +use frame_support::traits::Get; +use xcm_procedural::NumVariants; -struct Xcm(pub Vec>); - -#[derive(Builder)] -enum Instruction { - BuyExecution { fees: u128 }, - UnpaidExecution(u32, u32), - Transact { call: Call }, +#[allow(dead_code)] +#[derive(NumVariants)] +enum SomeEnum { + Variant1, + Variant2, + Variant3, } -fn main() {} +#[test] +fn num_variants_works() { + assert_eq!(SomeEnumNumVariants::get(), 3); +} diff --git a/polkadot/xcm/procedural/tests/ui/builder_pattern/loads_holding_no_operands.stderr b/polkadot/xcm/procedural/tests/ui/builder_pattern/loads_holding_no_operands.stderr deleted file mode 100644 index 0358a35ad3dd..000000000000 --- a/polkadot/xcm/procedural/tests/ui/builder_pattern/loads_holding_no_operands.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: Instructions that load the holding register should take operands - --> tests/ui/builder_pattern/loads_holding_no_operands.rs:25:5 - | -25 | / #[builder(loads_holding)] -26 | | WithdrawAsset, - | |_________________^ diff --git a/polkadot/xcm/procedural/tests/ui/builder_pattern/unexpected_attribute.stderr b/polkadot/xcm/procedural/tests/ui/builder_pattern/unexpected_attribute.stderr new file mode 100644 index 000000000000..c4d711e0d455 --- /dev/null +++ b/polkadot/xcm/procedural/tests/ui/builder_pattern/unexpected_attribute.stderr @@ -0,0 +1,5 @@ +error: Expected `builder(loads_holding)` or `builder(pays_fees)` + --> tests/ui/builder_pattern/unexpected_attribute.rs:25:5 + | +25 | #[builder(funds_holding)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/polkadot/xcm/procedural/tests/ui/builder_pattern/unpaid_execution_named_fields.stderr b/polkadot/xcm/procedural/tests/ui/builder_pattern/unpaid_execution_named_fields.stderr deleted file mode 100644 index 0a3c0a40a33b..000000000000 --- a/polkadot/xcm/procedural/tests/ui/builder_pattern/unpaid_execution_named_fields.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: UnpaidExecution should have named fields - --> tests/ui/builder_pattern/unpaid_execution_named_fields.rs:26:5 - | -26 | UnpaidExecution(u32, u32), - | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/polkadot/xcm/src/v4/mod.rs b/polkadot/xcm/src/v4/mod.rs index 3ae94b6ede88..bbf5ca049228 100644 --- a/polkadot/xcm/src/v4/mod.rs +++ b/polkadot/xcm/src/v4/mod.rs @@ -1435,7 +1435,7 @@ impl TryFrom> for Instructi }, InitiateTransfer { .. } | PayFees { .. } | - SetAssetClaimer { .. } | + SetHints { .. } | ExecuteWithOrigin { .. } => { log::debug!(target: "xcm::versions::v5tov4", "`{new_instruction:?}` not supported by v4"); return Err(()); diff --git a/polkadot/xcm/src/v5/mod.rs b/polkadot/xcm/src/v5/mod.rs index 193b82b6c223..21845d07529e 100644 --- a/polkadot/xcm/src/v5/mod.rs +++ b/polkadot/xcm/src/v5/mod.rs @@ -196,6 +196,8 @@ pub mod prelude { AssetInstance::{self, *}, Assets, BodyId, BodyPart, Error as XcmError, ExecuteXcm, Fungibility::{self, *}, + Hint::{self, *}, + HintNumVariants, Instruction::*, InteriorLocation, Junction::{self, *}, @@ -747,15 +749,6 @@ pub enum Instruction { /// Errors: None. ClearError, - /// Set asset claimer for all the trapped assets during the execution. - /// - /// - `location`: The claimer of any assets potentially trapped during the execution of current - /// XCM. It can be an arbitrary location, not necessarily the caller or origin. - /// - /// Kind: *Command* - /// - /// Errors: None. - SetAssetClaimer { location: Location }, /// Create some assets which are being held on behalf of the origin. /// /// - `assets`: The assets which are to be claimed. This must match exactly with the assets @@ -1136,6 +1129,25 @@ pub enum Instruction { /// Errors: /// - `BadOrigin` ExecuteWithOrigin { descendant_origin: Option, xcm: Xcm }, + + /// Set hints for XCM execution. + /// + /// These hints change the behaviour of the XCM program they are present in. + /// + /// Parameters: + /// + /// - `hints`: A bounded vector of `ExecutionHint`, specifying the different hints that will + /// be activated. + SetHints { hints: BoundedVec }, +} + +#[derive(Encode, Decode, TypeInfo, Debug, PartialEq, Eq, Clone, xcm_procedural::NumVariants)] +pub enum Hint { + /// Set asset claimer for all the trapped assets during the execution. + /// + /// - `location`: The claimer of any assets potentially trapped during the execution of current + /// XCM. It can be an arbitrary location, not necessarily the caller or origin. + AssetClaimer { location: Location }, } impl Xcm { @@ -1184,7 +1196,7 @@ impl Instruction { SetErrorHandler(xcm) => SetErrorHandler(xcm.into()), SetAppendix(xcm) => SetAppendix(xcm.into()), ClearError => ClearError, - SetAssetClaimer { location } => SetAssetClaimer { location }, + SetHints { hints } => SetHints { hints }, ClaimAsset { assets, ticket } => ClaimAsset { assets, ticket }, Trap(code) => Trap(code), SubscribeVersion { query_id, max_response_weight } => @@ -1259,7 +1271,7 @@ impl> GetWeight for Instruction { SetErrorHandler(xcm) => W::set_error_handler(xcm), SetAppendix(xcm) => W::set_appendix(xcm), ClearError => W::clear_error(), - SetAssetClaimer { location } => W::set_asset_claimer(location), + SetHints { hints } => W::set_hints(hints), ClaimAsset { assets, ticket } => W::claim_asset(assets, ticket), Trap(code) => W::trap(code), SubscribeVersion { query_id, max_response_weight } => diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs index 56a8493ef0ab..adba9a3ef79f 100644 --- a/polkadot/xcm/xcm-builder/src/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -95,7 +95,8 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFrom })? .skip_inst_while(|inst| { matches!(inst, ClearOrigin | AliasOrigin(..)) || - matches!(inst, DescendOrigin(child) if child != &Here) + matches!(inst, DescendOrigin(child) if child != &Here) || + matches!(inst, SetHints { .. }) })? .match_next_inst(|inst| match inst { BuyExecution { weight_limit: Limited(ref mut weight), .. } diff --git a/polkadot/xcm/xcm-builder/src/tests/barriers.rs b/polkadot/xcm/xcm-builder/src/tests/barriers.rs index cd2b6db66efc..d8805274d3a5 100644 --- a/polkadot/xcm/xcm-builder/src/tests/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/tests/barriers.rs @@ -333,6 +333,26 @@ fn allow_paid_should_deprivilege_origin() { assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(30, 30)))); } +#[test] +fn allow_paid_should_allow_hints() { + AllowPaidFrom::set(vec![Parent.into()]); + let fees = (Parent, 1).into(); + + let mut paying_message_with_hints = Xcm::<()>(vec![ + ReserveAssetDeposited((Parent, 100).into()), + SetHints { hints: vec![AssetClaimer { location: Location::here() }].try_into().unwrap() }, + BuyExecution { fees, weight_limit: Limited(Weight::from_parts(30, 30)) }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, + ]); + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message_with_hints.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); +} + #[test] fn suspension_should_work() { TestSuspender::set_suspended(true); diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 11fd4e04761f..64a32f488420 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -1371,8 +1371,14 @@ impl XcmExecutor { self.error = None; Ok(()) }, - SetAssetClaimer { location } => { - self.asset_claimer = Some(location); + SetHints { hints } => { + for hint in hints.into_iter() { + match hint { + AssetClaimer { location } => { + self.asset_claimer = Some(location) + }, + } + } Ok(()) }, ClaimAsset { assets, ticket } => { diff --git a/polkadot/xcm/xcm-executor/src/tests/set_asset_claimer.rs b/polkadot/xcm/xcm-executor/src/tests/set_asset_claimer.rs index bc504b8db2a2..cc97e2b3a16e 100644 --- a/polkadot/xcm/xcm-executor/src/tests/set_asset_claimer.rs +++ b/polkadot/xcm/xcm-executor/src/tests/set_asset_claimer.rs @@ -38,7 +38,7 @@ fn set_asset_claimer() { // if withdrawing fails we're not missing any corner case. .withdraw_asset((Here, 100u128)) .clear_origin() - .set_asset_claimer(bob.clone()) + .set_hints(vec![AssetClaimer { location: bob.clone() }]) .pay_fees((Here, 10u128)) // 10% destined for fees, not more. .build(); @@ -93,7 +93,7 @@ fn trap_then_set_asset_claimer() { .withdraw_asset((Here, 100u128)) .clear_origin() .trap(0u64) - .set_asset_claimer(bob) + .set_hints(vec![AssetClaimer { location: bob }]) .pay_fees((Here, 10u128)) // 10% destined for fees, not more. .build(); @@ -121,7 +121,7 @@ fn set_asset_claimer_then_trap() { // if withdrawing fails we're not missing any corner case. .withdraw_asset((Here, 100u128)) .clear_origin() - .set_asset_claimer(bob.clone()) + .set_hints(vec![AssetClaimer { location: bob.clone() }]) .trap(0u64) .pay_fees((Here, 10u128)) // 10% destined for fees, not more. .build(); diff --git a/prdoc/pr_6566.prdoc b/prdoc/pr_6566.prdoc new file mode 100644 index 000000000000..bbd48b799538 --- /dev/null +++ b/prdoc/pr_6566.prdoc @@ -0,0 +1,45 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: XCMv5 - SetHints instruction + +doc: + - audience: Runtime Dev + description: | + Implementation of fellowship RFC 107. + The new SetHints instruction is a repackaging of SetAssetClaimer that also allows future + "hints" which alter the default behaviour of the executor. + The AllowTopLevelPaidExecutionFrom barrier allows this instruction between WithdrawAsset and + BuyExecution/PayFees to configure things before the actual meat of the program. + +crates: + - name: asset-hub-rococo-runtime + bump: major + - name: asset-hub-westend-runtime + bump: major + - name: bridge-hub-rococo-runtime + bump: major + - name: bridge-hub-westend-runtime + bump: major + - name: coretime-rococo-runtime + bump: major + - name: coretime-westend-runtime + bump: major + - name: people-rococo-runtime + bump: major + - name: people-westend-runtime + bump: major + - name: rococo-runtime + bump: major + - name: westend-runtime + bump: major + - name: pallet-xcm-benchmarks + bump: major + - name: xcm-procedural + bump: minor + - name: staging-xcm + bump: major + - name: staging-xcm-builder + bump: major + - name: staging-xcm-executor + bump: major From b2e1e592008f2d8f89ff988c6d6975156aa03567 Mon Sep 17 00:00:00 2001 From: Egor_P Date: Mon, 9 Dec 2024 13:44:07 +0100 Subject: [PATCH 24/51] [CI/CD]Revert the token changes in backport flow (#6794) Set back the token for the cmd_bot in the backport flow so that it work again, till the new set up will be figured out with the sec team --- .github/workflows/command-backport.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/command-backport.yml b/.github/workflows/command-backport.yml index db006e9bd907..8a017a434525 100644 --- a/.github/workflows/command-backport.yml +++ b/.github/workflows/command-backport.yml @@ -16,7 +16,6 @@ jobs: backport: name: Backport pull request runs-on: ubuntu-latest - environment: release # The 'github.event.pull_request.merged' ensures that it got into master: if: > @@ -30,13 +29,12 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Generate content write token for the release automation - id: generate_write_token - uses: actions/create-github-app-token@v1 + - name: Generate token + id: generate_token + uses: tibdex/github-app-token@v2.1.0 with: - app-id: ${{ vars.RELEASE_AUTOMATION_APP_ID }} - private-key: ${{ secrets.RELEASE_AUTOMATION_APP_PRIVATE_KEY }} - owner: paritytech + app_id: ${{ secrets.CMD_BOT_APP_ID }} + private_key: ${{ secrets.CMD_BOT_APP_KEY }} - name: Create backport pull requests uses: korthout/backport-action@v3 @@ -44,7 +42,7 @@ jobs: with: target_branches: stable2407 stable2409 stable2412 merge_commits: skip - github_token: ${{ steps.generate_write_token.outputs.token }} + github_token: ${{ steps.generate_token.outputs.token }} pull_description: | Backport #${pull_number} into `${target_branch}` from ${pull_author}. From 81b979ae2a23842e8ed5a879e73b1deae577dc47 Mon Sep 17 00:00:00 2001 From: Maksym H <1177472+mordamax@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:49:35 +0000 Subject: [PATCH 25/51] Mak cmd swap omnibench (#6769) - change bench to default to old CLI - fix profile to production --------- Co-authored-by: GitHub Action Co-authored-by: command-bot <> --- .github/scripts/cmd/cmd.py | 195 +++++++++++++++++- .github/scripts/cmd/test_cmd.py | 38 ++-- .github/workflows/cmd.yml | 24 ++- .github/workflows/runtimes-matrix.json | 33 ++- .../westend/src/weights/pallet_balances.rs | 68 +++--- 5 files changed, 289 insertions(+), 69 deletions(-) diff --git a/.github/scripts/cmd/cmd.py b/.github/scripts/cmd/cmd.py index 9da05cac17b9..2c017b7d0c3e 100755 --- a/.github/scripts/cmd/cmd.py +++ b/.github/scripts/cmd/cmd.py @@ -58,7 +58,7 @@ def setup_logging(): %(prog)s --runtime westend rococo --pallet pallet_balances pallet_multisig --quiet --clean ''' -parser_bench = subparsers.add_parser('bench', help='Runs benchmarks', epilog=bench_example, formatter_class=argparse.RawDescriptionHelpFormatter) +parser_bench = subparsers.add_parser('bench', help='Runs benchmarks (old CLI)', epilog=bench_example, formatter_class=argparse.RawDescriptionHelpFormatter) for arg, config in common_args.items(): parser_bench.add_argument(arg, **config) @@ -67,6 +67,35 @@ def setup_logging(): parser_bench.add_argument('--pallet', help='Pallet(s) space separated', nargs='*', default=[]) parser_bench.add_argument('--fail-fast', help='Fail fast on first failed benchmark', action='store_true') + +""" +BENCH OMNI +""" + +bench_example = '''**Examples**: + Runs all benchmarks + %(prog)s + + Runs benchmarks for pallet_balances and pallet_multisig for all runtimes which have these pallets. **--quiet** makes it to output nothing to PR but reactions + %(prog)s --pallet pallet_balances pallet_xcm_benchmarks::generic --quiet + + Runs bench for all pallets for westend runtime and fails fast on first failed benchmark + %(prog)s --runtime westend --fail-fast + + Does not output anything and cleans up the previous bot's & author command triggering comments in PR + %(prog)s --runtime westend rococo --pallet pallet_balances pallet_multisig --quiet --clean +''' + +parser_bench_old = subparsers.add_parser('bench-omni', help='Runs benchmarks (frame omni bencher)', epilog=bench_example, formatter_class=argparse.RawDescriptionHelpFormatter) + +for arg, config in common_args.items(): + parser_bench_old.add_argument(arg, **config) + +parser_bench_old.add_argument('--runtime', help='Runtime(s) space separated', choices=runtimeNames, nargs='*', default=runtimeNames) +parser_bench_old.add_argument('--pallet', help='Pallet(s) space separated', nargs='*', default=[]) +parser_bench_old.add_argument('--fail-fast', help='Fail fast on first failed benchmark', action='store_true') + + """ FMT """ @@ -98,12 +127,12 @@ def main(): print(f'args: {args}') - if args.command == 'bench': + if args.command == 'bench-omni': runtime_pallets_map = {} failed_benchmarks = {} successful_benchmarks = {} - profile = "release" + profile = "production" print(f'Provided runtimes: {args.runtime}') # convert to mapped dict @@ -113,11 +142,22 @@ def main(): # loop over remaining runtimes to collect available pallets for runtime in runtimesMatrix.values(): - os.system(f"forklift cargo build -p {runtime['package']} --profile {profile} --features={runtime['bench_features']}") + build_command = f"forklift cargo build -p {runtime['package']} --profile {profile} --features={runtime['bench_features']}" + print(f'-- building "{runtime["name"]}" with `{build_command}`') + os.system(build_command) print(f'-- listing pallets for benchmark for {runtime["name"]}') wasm_file = f"target/{profile}/wbuild/{runtime['package']}/{runtime['package'].replace('-', '_')}.wasm" - output = os.popen( - f"frame-omni-bencher v1 benchmark pallet --no-csv-header --no-storage-info --no-min-squares --no-median-slopes --all --list --runtime={wasm_file} {runtime['bench_flags']}").read() + list_command = f"frame-omni-bencher v1 benchmark pallet " \ + f"--no-csv-header " \ + f"--no-storage-info " \ + f"--no-min-squares " \ + f"--no-median-slopes " \ + f"--all " \ + f"--list " \ + f"--runtime={wasm_file} " \ + f"{runtime['bench_flags']}" + print(f'-- running: {list_command}') + output = os.popen(list_command).read() raw_pallets = output.strip().split('\n') all_pallets = set() @@ -230,6 +270,149 @@ def main(): print_and_log('✅ Successful benchmarks of runtimes/pallets:') for runtime, pallets in successful_benchmarks.items(): print_and_log(f'-- {runtime}: {pallets}') + + if args.command == 'bench': + runtime_pallets_map = {} + failed_benchmarks = {} + successful_benchmarks = {} + + profile = "production" + + print(f'Provided runtimes: {args.runtime}') + # convert to mapped dict + runtimesMatrix = list(filter(lambda x: x['name'] in args.runtime, runtimesMatrix)) + runtimesMatrix = {x['name']: x for x in runtimesMatrix} + print(f'Filtered out runtimes: {runtimesMatrix}') + + # loop over remaining runtimes to collect available pallets + for runtime in runtimesMatrix.values(): + build_command = f"forklift cargo build -p {runtime['old_package']} --profile {profile} --features={runtime['bench_features']} --locked" + print(f'-- building {runtime["name"]} with `{build_command}`') + os.system(build_command) + + chain = runtime['name'] if runtime['name'] == 'dev' else f"{runtime['name']}-dev" + + machine_test = f"target/{profile}/{runtime['old_bin']} benchmark machine --chain={chain}" + print(f"Running machine test for `{machine_test}`") + os.system(machine_test) + + print(f'-- listing pallets for benchmark for {chain}') + list_command = f"target/{profile}/{runtime['old_bin']} " \ + f"benchmark pallet " \ + f"--no-csv-header " \ + f"--no-storage-info " \ + f"--no-min-squares " \ + f"--no-median-slopes " \ + f"--all " \ + f"--list " \ + f"--chain={chain}" + print(f'-- running: {list_command}') + output = os.popen(list_command).read() + raw_pallets = output.strip().split('\n') + + all_pallets = set() + for pallet in raw_pallets: + if pallet: + all_pallets.add(pallet.split(',')[0].strip()) + + pallets = list(all_pallets) + print(f'Pallets in {runtime["name"]}: {pallets}') + runtime_pallets_map[runtime['name']] = pallets + + print(f'\n') + + # filter out only the specified pallets from collected runtimes/pallets + if args.pallet: + print(f'Pallets: {args.pallet}') + new_pallets_map = {} + # keep only specified pallets if they exist in the runtime + for runtime in runtime_pallets_map: + if set(args.pallet).issubset(set(runtime_pallets_map[runtime])): + new_pallets_map[runtime] = args.pallet + + runtime_pallets_map = new_pallets_map + + print(f'Filtered out runtimes & pallets: {runtime_pallets_map}\n') + + if not runtime_pallets_map: + if args.pallet and not args.runtime: + print(f"No pallets {args.pallet} found in any runtime") + elif args.runtime and not args.pallet: + print(f"{args.runtime} runtime does not have any pallets") + elif args.runtime and args.pallet: + print(f"No pallets {args.pallet} found in {args.runtime}") + else: + print('No runtimes found') + sys.exit(1) + + for runtime in runtime_pallets_map: + for pallet in runtime_pallets_map[runtime]: + config = runtimesMatrix[runtime] + header_path = os.path.abspath(config['header']) + template = None + + chain = config['name'] if runtime == 'dev' else f"{config['name']}-dev" + + print(f'-- config: {config}') + if runtime == 'dev': + # to support sub-modules (https://github.com/paritytech/command-bot/issues/275) + search_manifest_path = f"cargo metadata --locked --format-version 1 --no-deps | jq -r '.packages[] | select(.name == \"{pallet.replace('_', '-')}\") | .manifest_path'" + print(f'-- running: {search_manifest_path}') + manifest_path = os.popen(search_manifest_path).read() + if not manifest_path: + print(f'-- pallet {pallet} not found in dev runtime') + if args.fail_fast: + print_and_log(f'Error: {pallet} not found in dev runtime') + sys.exit(1) + package_dir = os.path.dirname(manifest_path) + print(f'-- package_dir: {package_dir}') + print(f'-- manifest_path: {manifest_path}') + output_path = os.path.join(package_dir, "src", "weights.rs") + template = config['template'] + else: + default_path = f"./{config['path']}/src/weights" + xcm_path = f"./{config['path']}/src/weights/xcm" + output_path = default_path + if pallet.startswith("pallet_xcm_benchmarks"): + template = config['template'] + output_path = xcm_path + + print(f'-- benchmarking {pallet} in {runtime} into {output_path}') + cmd = f"target/{profile}/{config['old_bin']} benchmark pallet " \ + f"--extrinsic=* " \ + f"--chain={chain} " \ + f"--pallet={pallet} " \ + f"--header={header_path} " \ + f"--output={output_path} " \ + f"--wasm-execution=compiled " \ + f"--steps=50 " \ + f"--repeat=20 " \ + f"--heap-pages=4096 " \ + f"{f'--template={template} ' if template else ''}" \ + f"--no-storage-info --no-min-squares --no-median-slopes " + print(f'-- Running: {cmd} \n') + status = os.system(cmd) + + if status != 0 and args.fail_fast: + print_and_log(f'❌ Failed to benchmark {pallet} in {runtime}') + sys.exit(1) + + # Otherwise collect failed benchmarks and print them at the end + # push failed pallets to failed_benchmarks + if status != 0: + failed_benchmarks[f'{runtime}'] = failed_benchmarks.get(f'{runtime}', []) + [pallet] + else: + successful_benchmarks[f'{runtime}'] = successful_benchmarks.get(f'{runtime}', []) + [pallet] + + if failed_benchmarks: + print_and_log('❌ Failed benchmarks of runtimes/pallets:') + for runtime, pallets in failed_benchmarks.items(): + print_and_log(f'-- {runtime}: {pallets}') + + if successful_benchmarks: + print_and_log('✅ Successful benchmarks of runtimes/pallets:') + for runtime, pallets in successful_benchmarks.items(): + print_and_log(f'-- {runtime}: {pallets}') elif args.command == 'fmt': command = f"cargo +nightly fmt" diff --git a/.github/scripts/cmd/test_cmd.py b/.github/scripts/cmd/test_cmd.py index 7b29fbfe90d8..68998b989909 100644 --- a/.github/scripts/cmd/test_cmd.py +++ b/.github/scripts/cmd/test_cmd.py @@ -47,7 +47,7 @@ def get_mock_bench_output(runtime, pallets, output_path, header, bench_flags, template = None): return f"frame-omni-bencher v1 benchmark pallet --extrinsic=* " \ - f"--runtime=target/release/wbuild/{runtime}-runtime/{runtime.replace('-', '_')}_runtime.wasm " \ + f"--runtime=target/production/wbuild/{runtime}-runtime/{runtime.replace('-', '_')}_runtime.wasm " \ f"--pallet={pallets} --header={header} " \ f"--output={output_path} " \ f"--wasm-execution=compiled " \ @@ -93,7 +93,7 @@ def tearDown(self): def test_bench_command_normal_execution_all_runtimes(self): self.mock_parse_args.return_value = (argparse.Namespace( - command='bench', + command='bench-omni', runtime=list(map(lambda x: x['name'], mock_runtimes_matrix)), pallet=['pallet_balances'], fail_fast=True, @@ -117,10 +117,10 @@ def test_bench_command_normal_execution_all_runtimes(self): expected_calls = [ # Build calls - call("forklift cargo build -p kitchensink-runtime --profile release --features=runtime-benchmarks"), - call("forklift cargo build -p westend-runtime --profile release --features=runtime-benchmarks"), - call("forklift cargo build -p rococo-runtime --profile release --features=runtime-benchmarks"), - call("forklift cargo build -p asset-hub-westend-runtime --profile release --features=runtime-benchmarks"), + call("forklift cargo build -p kitchensink-runtime --profile production --features=runtime-benchmarks"), + call("forklift cargo build -p westend-runtime --profile production --features=runtime-benchmarks"), + call("forklift cargo build -p rococo-runtime --profile production --features=runtime-benchmarks"), + call("forklift cargo build -p asset-hub-westend-runtime --profile production --features=runtime-benchmarks"), call(get_mock_bench_output( runtime='kitchensink', @@ -150,7 +150,7 @@ def test_bench_command_normal_execution_all_runtimes(self): def test_bench_command_normal_execution(self): self.mock_parse_args.return_value = (argparse.Namespace( - command='bench', + command='bench-omni', runtime=['westend'], pallet=['pallet_balances', 'pallet_staking'], fail_fast=True, @@ -170,7 +170,7 @@ def test_bench_command_normal_execution(self): expected_calls = [ # Build calls - call("forklift cargo build -p westend-runtime --profile release --features=runtime-benchmarks"), + call("forklift cargo build -p westend-runtime --profile production --features=runtime-benchmarks"), # Westend runtime calls call(get_mock_bench_output( @@ -193,7 +193,7 @@ def test_bench_command_normal_execution(self): def test_bench_command_normal_execution_xcm(self): self.mock_parse_args.return_value = (argparse.Namespace( - command='bench', + command='bench-omni', runtime=['westend'], pallet=['pallet_xcm_benchmarks::generic'], fail_fast=True, @@ -213,7 +213,7 @@ def test_bench_command_normal_execution_xcm(self): expected_calls = [ # Build calls - call("forklift cargo build -p westend-runtime --profile release --features=runtime-benchmarks"), + call("forklift cargo build -p westend-runtime --profile production --features=runtime-benchmarks"), # Westend runtime calls call(get_mock_bench_output( @@ -229,7 +229,7 @@ def test_bench_command_normal_execution_xcm(self): def test_bench_command_two_runtimes_two_pallets(self): self.mock_parse_args.return_value = (argparse.Namespace( - command='bench', + command='bench-omni', runtime=['westend', 'rococo'], pallet=['pallet_balances', 'pallet_staking'], fail_fast=True, @@ -250,8 +250,8 @@ def test_bench_command_two_runtimes_two_pallets(self): expected_calls = [ # Build calls - call("forklift cargo build -p westend-runtime --profile release --features=runtime-benchmarks"), - call("forklift cargo build -p rococo-runtime --profile release --features=runtime-benchmarks"), + call("forklift cargo build -p westend-runtime --profile production --features=runtime-benchmarks"), + call("forklift cargo build -p rococo-runtime --profile production --features=runtime-benchmarks"), # Westend runtime calls call(get_mock_bench_output( runtime='westend', @@ -287,7 +287,7 @@ def test_bench_command_two_runtimes_two_pallets(self): def test_bench_command_one_dev_runtime(self): self.mock_parse_args.return_value = (argparse.Namespace( - command='bench', + command='bench-omni', runtime=['dev'], pallet=['pallet_balances'], fail_fast=True, @@ -309,7 +309,7 @@ def test_bench_command_one_dev_runtime(self): expected_calls = [ # Build calls - call("forklift cargo build -p kitchensink-runtime --profile release --features=runtime-benchmarks"), + call("forklift cargo build -p kitchensink-runtime --profile production --features=runtime-benchmarks"), # Westend runtime calls call(get_mock_bench_output( runtime='kitchensink', @@ -324,7 +324,7 @@ def test_bench_command_one_dev_runtime(self): def test_bench_command_one_cumulus_runtime(self): self.mock_parse_args.return_value = (argparse.Namespace( - command='bench', + command='bench-omni', runtime=['asset-hub-westend'], pallet=['pallet_assets'], fail_fast=True, @@ -344,7 +344,7 @@ def test_bench_command_one_cumulus_runtime(self): expected_calls = [ # Build calls - call("forklift cargo build -p asset-hub-westend-runtime --profile release --features=runtime-benchmarks"), + call("forklift cargo build -p asset-hub-westend-runtime --profile production --features=runtime-benchmarks"), # Asset-hub-westend runtime calls call(get_mock_bench_output( runtime='asset-hub-westend', @@ -359,7 +359,7 @@ def test_bench_command_one_cumulus_runtime(self): def test_bench_command_one_cumulus_runtime_xcm(self): self.mock_parse_args.return_value = (argparse.Namespace( - command='bench', + command='bench-omni', runtime=['asset-hub-westend'], pallet=['pallet_xcm_benchmarks::generic', 'pallet_assets'], fail_fast=True, @@ -379,7 +379,7 @@ def test_bench_command_one_cumulus_runtime_xcm(self): expected_calls = [ # Build calls - call("forklift cargo build -p asset-hub-westend-runtime --profile release --features=runtime-benchmarks"), + call("forklift cargo build -p asset-hub-westend-runtime --profile production --features=runtime-benchmarks"), # Asset-hub-westend runtime calls call(get_mock_bench_output( runtime='asset-hub-westend', diff --git a/.github/workflows/cmd.yml b/.github/workflows/cmd.yml index 525ab0c0fc23..6cd1adec1d8b 100644 --- a/.github/workflows/cmd.yml +++ b/.github/workflows/cmd.yml @@ -227,7 +227,8 @@ jobs: cat .github/env >> $GITHUB_OUTPUT if [ -n "$IMAGE_OVERRIDE" ]; then - echo "IMAGE=$IMAGE_OVERRIDE" >> $GITHUB_OUTPUT + IMAGE=$IMAGE_OVERRIDE + echo "IMAGE=$IMAGE" >> $GITHUB_OUTPUT fi if [[ $BODY == "/cmd bench"* ]]; then @@ -237,6 +238,10 @@ jobs: else echo "RUNNER=ubuntu-latest" >> $GITHUB_OUTPUT fi + - name: Print outputs + run: | + echo "RUNNER=${{ steps.set-image.outputs.RUNNER }}" + echo "IMAGE=${{ steps.set-image.outputs.IMAGE }}" # Get PR branch name, because the issue_comment event does not contain the PR branch name get-pr-branch: @@ -283,10 +288,16 @@ jobs: env: JOB_NAME: "cmd" runs-on: ${{ needs.set-image.outputs.RUNNER }} - timeout-minutes: 4320 # 72 hours -> 3 days; as it could take a long time to run all the runtimes/pallets container: image: ${{ needs.set-image.outputs.IMAGE }} + timeout-minutes: 1440 # 24 hours per runtime steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: ${{ needs.get-pr-branch.outputs.repo }} + ref: ${{ needs.get-pr-branch.outputs.pr-branch }} + - name: Get command uses: actions-ecosystem/action-regex-match@v2 id: get-pr-comment @@ -340,13 +351,7 @@ jobs: repo: context.repo.repo, body: `Command "${{ steps.get-pr-comment.outputs.group2 }}" has started 🚀 [See logs here](${job_url})` }) - - - name: Checkout - uses: actions/checkout@v4 - with: - repository: ${{ needs.get-pr-branch.outputs.repo }} - ref: ${{ needs.get-pr-branch.outputs.pr-branch }} - + - name: Install dependencies for bench if: startsWith(steps.get-pr-comment.outputs.group2, 'bench') run: | @@ -364,6 +369,7 @@ jobs: # Fixes "detected dubious ownership" error in the ci git config --global --add safe.directory '*' git remote -v + cat /proc/cpuinfo python3 -m pip install -r .github/scripts/generate-prdoc.requirements.txt python3 .github/scripts/cmd/cmd.py $CMD $PR_ARG git status diff --git a/.github/workflows/runtimes-matrix.json b/.github/workflows/runtimes-matrix.json index f991db55b86d..104e73521331 100644 --- a/.github/workflows/runtimes-matrix.json +++ b/.github/workflows/runtimes-matrix.json @@ -8,6 +8,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "--genesis-builder-policy=none --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic,pallet_nomination_pools,pallet_remark,pallet_transaction_storage", "uri": null, + "old_package": "staging-node-cli", + "old_bin": "substrate-node", "is_relay": false }, { @@ -19,6 +21,8 @@ "bench_flags": "", "bench_features": "runtime-benchmarks", "uri": "wss://try-runtime-westend.polkadot.io:443", + "old_package": "polkadot", + "old_bin": "polkadot", "is_relay": true }, { @@ -27,9 +31,11 @@ "path": "polkadot/runtime/rococo", "header": "polkadot/file_header.txt", "template": "polkadot/xcm/pallet-xcm-benchmarks/template.hbs", - "uri": "wss://try-runtime-rococo.polkadot.io:443", "bench_features": "runtime-benchmarks", "bench_flags": "", + "uri": "wss://try-runtime-rococo.polkadot.io:443", + "old_package": "polkadot", + "old_bin": "polkadot", "is_relay": true }, { @@ -41,6 +47,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "", "uri": "wss://westend-asset-hub-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -52,6 +60,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "", "uri": "wss://rococo-asset-hub-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -63,6 +73,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "", "uri": "wss://rococo-bridge-hub-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -74,6 +86,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "", "uri": "wss://westend-bridge-hub-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -84,7 +98,10 @@ "template": "cumulus/templates/xcm-bench-template.hbs", "bench_features": "runtime-benchmarks", "bench_flags": "", - "uri": "wss://westend-collectives-rpc.polkadot.io:443" + "uri": "wss://westend-collectives-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", + "is_relay": false }, { "name": "contracts-rococo", @@ -95,6 +112,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "--genesis-builder-policy=none --exclude-pallets=pallet_xcm", "uri": "wss://rococo-contracts-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -106,6 +125,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "--genesis-builder-policy=none --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic", "uri": "wss://rococo-coretime-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -117,6 +138,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "--genesis-builder-policy=none --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic", "uri": "wss://westend-coretime-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -128,6 +151,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "--genesis-builder-policy=none", "uri": null, + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -139,6 +164,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "--genesis-builder-policy=none --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic", "uri": "wss://rococo-people-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false }, { @@ -150,6 +177,8 @@ "bench_features": "runtime-benchmarks", "bench_flags": "--genesis-builder-policy=none --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic", "uri": "wss://westend-people-rpc.polkadot.io:443", + "old_package": "polkadot-parachain-bin", + "old_bin": "polkadot-parachain", "is_relay": false } ] diff --git a/polkadot/runtime/westend/src/weights/pallet_balances.rs b/polkadot/runtime/westend/src/weights/pallet_balances.rs index b303a1a21766..deaf8840462b 100644 --- a/polkadot/runtime/westend/src/weights/pallet_balances.rs +++ b/polkadot/runtime/westend/src/weights/pallet_balances.rs @@ -17,25 +17,27 @@ //! Autogenerated weights for `pallet_balances` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `95c137a642c3`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: // target/production/polkadot // benchmark // pallet -// --steps=50 -// --repeat=20 // --extrinsic=* +// --chain=westend-dev +// --pallet=pallet_balances +// --header=/__w/polkadot-sdk/polkadot-sdk/polkadot/file_header.txt +// --output=./polkadot/runtime/westend/src/weights // --wasm-execution=compiled +// --steps=50 +// --repeat=20 // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_balances -// --chain=westend-dev -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/westend/src/weights/ +// --no-storage-info +// --no-min-squares +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -54,8 +56,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 50_394_000 picoseconds. - Weight::from_parts(51_666_000, 0) + // Minimum execution time: 51_474_000 picoseconds. + Weight::from_parts(52_840_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -66,8 +68,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 40_307_000 picoseconds. - Weight::from_parts(41_722_000, 0) + // Minimum execution time: 39_875_000 picoseconds. + Weight::from_parts(41_408_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,8 +80,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 19_110_000 picoseconds. - Weight::from_parts(19_623_000, 0) + // Minimum execution time: 19_614_000 picoseconds. + Weight::from_parts(20_194_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +92,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 26_837_000 picoseconds. - Weight::from_parts(27_672_000, 0) + // Minimum execution time: 27_430_000 picoseconds. + Weight::from_parts(28_151_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -102,8 +104,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 53_032_000 picoseconds. - Weight::from_parts(54_040_000, 0) + // Minimum execution time: 54_131_000 picoseconds. + Weight::from_parts(54_810_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -114,8 +116,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 49_429_000 picoseconds. - Weight::from_parts(50_020_000, 0) + // Minimum execution time: 48_692_000 picoseconds. + Weight::from_parts(51_416_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -126,8 +128,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 22_114_000 picoseconds. - Weight::from_parts(22_526_000, 0) + // Minimum execution time: 22_604_000 picoseconds. + Weight::from_parts(23_336_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -139,11 +141,11 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0 + u * (136 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 17_550_000 picoseconds. - Weight::from_parts(17_860_000, 0) + // Minimum execution time: 18_118_000 picoseconds. + Weight::from_parts(18_352_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 11_891 - .saturating_add(Weight::from_parts(15_027_705, 0).saturating_mul(u.into())) + // Standard Error: 14_688 + .saturating_add(Weight::from_parts(15_412_440, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -152,24 +154,24 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_605_000 picoseconds. - Weight::from_parts(6_922_000, 0) + // Minimum execution time: 6_779_000 picoseconds. + Weight::from_parts(7_246_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn burn_allow_death() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 31_182_000 picoseconds. - Weight::from_parts(32_104_000, 0) + // Minimum execution time: 30_935_000 picoseconds. + Weight::from_parts(32_251_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn burn_keep_alive() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 21_105_000 picoseconds. - Weight::from_parts(21_533_000, 0) + // Minimum execution time: 21_002_000 picoseconds. + Weight::from_parts(21_760_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } From da953454aa4b381c5b44ee6a32ff1c43e744390c Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:00:19 +0100 Subject: [PATCH 26/51] Fix `Possible bug: Vote import failed` after aggression is enabled (#6690) After finality started lagging on kusama around 025-11-25 15:55:40 validators started seeing ocassionally this log, when importing votes covering more than one assignment. ``` Possible bug: Vote import failed ``` That happens because the assumption that assignments from the same validator would have the same required routing doesn't hold after you enabled aggression, so you might end up receiving the first assignment then you modify the routing for it in `enable_aggression` then your receive the second assignment and the vote covering both assignments, so the rouing for the first and second assingment wouldn't match and we would fail to import the vote. From the logs I've seen, I don't think this is the reason the network didn't fully recover until the failsafe kicked it, because the votes had been already imported in approval-voting before this error. --------- Signed-off-by: Alexandru Gheorghe --- .../network/approval-distribution/src/lib.rs | 19 ++---- .../network/protocol/src/grid_topology.rs | 60 +++++++++++++++++++ prdoc/pr_6690.prdoc | 17 ++++++ 3 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 prdoc/pr_6690.prdoc diff --git a/polkadot/node/network/approval-distribution/src/lib.rs b/polkadot/node/network/approval-distribution/src/lib.rs index 876cc59b9c28..d6bbb0dca83c 100644 --- a/polkadot/node/network/approval-distribution/src/lib.rs +++ b/polkadot/node/network/approval-distribution/src/lib.rs @@ -163,8 +163,6 @@ enum ApprovalEntryError { InvalidCandidateIndex, DuplicateApproval, UnknownAssignment, - #[allow(dead_code)] - AssignmentsFollowedDifferentPaths(RequiredRouting, RequiredRouting), } impl ApprovalEntry { @@ -568,7 +566,7 @@ impl BlockEntry { &mut self, approval: IndirectSignedApprovalVoteV2, ) -> Result<(RequiredRouting, HashSet), ApprovalEntryError> { - let mut required_routing = None; + let mut required_routing: Option = None; let mut peers_randomly_routed_to = HashSet::new(); if self.candidates.len() < approval.candidate_indices.len() as usize { @@ -595,16 +593,11 @@ impl BlockEntry { peers_randomly_routed_to .extend(approval_entry.routing_info().peers_randomly_routed.iter()); - if let Some(required_routing) = required_routing { - if required_routing != approval_entry.routing_info().required_routing { - // This shouldn't happen since the required routing is computed based on the - // validator_index, so two assignments from the same validators will have - // the same required routing. - return Err(ApprovalEntryError::AssignmentsFollowedDifferentPaths( - required_routing, - approval_entry.routing_info().required_routing, - )) - } + if let Some(current_required_routing) = required_routing { + required_routing = Some( + current_required_routing + .combine(approval_entry.routing_info().required_routing), + ); } else { required_routing = Some(approval_entry.routing_info().required_routing) } diff --git a/polkadot/node/network/protocol/src/grid_topology.rs b/polkadot/node/network/protocol/src/grid_topology.rs index 4dd7d29fc25c..f4c1a07ba3c2 100644 --- a/polkadot/node/network/protocol/src/grid_topology.rs +++ b/polkadot/node/network/protocol/src/grid_topology.rs @@ -575,6 +575,22 @@ impl RequiredRouting { _ => false, } } + + /// Combine two required routing sets into one that would cover both routing modes. + pub fn combine(self, other: Self) -> Self { + match (self, other) { + (RequiredRouting::All, _) | (_, RequiredRouting::All) => RequiredRouting::All, + (RequiredRouting::GridXY, _) | (_, RequiredRouting::GridXY) => RequiredRouting::GridXY, + (RequiredRouting::GridX, RequiredRouting::GridY) | + (RequiredRouting::GridY, RequiredRouting::GridX) => RequiredRouting::GridXY, + (RequiredRouting::GridX, RequiredRouting::GridX) => RequiredRouting::GridX, + (RequiredRouting::GridY, RequiredRouting::GridY) => RequiredRouting::GridY, + (RequiredRouting::None, RequiredRouting::PendingTopology) | + (RequiredRouting::PendingTopology, RequiredRouting::None) => RequiredRouting::PendingTopology, + (RequiredRouting::None, _) | (RequiredRouting::PendingTopology, _) => other, + (_, RequiredRouting::None) | (_, RequiredRouting::PendingTopology) => self, + } + } } #[cfg(test)] @@ -587,6 +603,50 @@ mod tests { rand_chacha::ChaCha12Rng::seed_from_u64(12345) } + #[test] + fn test_required_routing_combine() { + assert_eq!(RequiredRouting::All.combine(RequiredRouting::None), RequiredRouting::All); + assert_eq!(RequiredRouting::All.combine(RequiredRouting::GridXY), RequiredRouting::All); + assert_eq!(RequiredRouting::GridXY.combine(RequiredRouting::All), RequiredRouting::All); + assert_eq!(RequiredRouting::None.combine(RequiredRouting::All), RequiredRouting::All); + assert_eq!(RequiredRouting::None.combine(RequiredRouting::None), RequiredRouting::None); + assert_eq!( + RequiredRouting::PendingTopology.combine(RequiredRouting::GridX), + RequiredRouting::GridX + ); + + assert_eq!( + RequiredRouting::GridX.combine(RequiredRouting::PendingTopology), + RequiredRouting::GridX + ); + assert_eq!(RequiredRouting::GridX.combine(RequiredRouting::GridY), RequiredRouting::GridXY); + assert_eq!(RequiredRouting::GridY.combine(RequiredRouting::GridX), RequiredRouting::GridXY); + assert_eq!( + RequiredRouting::GridXY.combine(RequiredRouting::GridXY), + RequiredRouting::GridXY + ); + assert_eq!(RequiredRouting::GridX.combine(RequiredRouting::GridX), RequiredRouting::GridX); + assert_eq!(RequiredRouting::GridY.combine(RequiredRouting::GridY), RequiredRouting::GridY); + + assert_eq!(RequiredRouting::None.combine(RequiredRouting::GridY), RequiredRouting::GridY); + assert_eq!(RequiredRouting::None.combine(RequiredRouting::GridX), RequiredRouting::GridX); + assert_eq!(RequiredRouting::None.combine(RequiredRouting::GridXY), RequiredRouting::GridXY); + + assert_eq!(RequiredRouting::GridY.combine(RequiredRouting::None), RequiredRouting::GridY); + assert_eq!(RequiredRouting::GridX.combine(RequiredRouting::None), RequiredRouting::GridX); + assert_eq!(RequiredRouting::GridXY.combine(RequiredRouting::None), RequiredRouting::GridXY); + + assert_eq!( + RequiredRouting::PendingTopology.combine(RequiredRouting::None), + RequiredRouting::PendingTopology + ); + + assert_eq!( + RequiredRouting::None.combine(RequiredRouting::PendingTopology), + RequiredRouting::PendingTopology + ); + } + #[test] fn test_random_routing_sample() { // This test is fragile as it relies on a specific ChaCha12Rng diff --git a/prdoc/pr_6690.prdoc b/prdoc/pr_6690.prdoc new file mode 100644 index 000000000000..0e4a2437ef96 --- /dev/null +++ b/prdoc/pr_6690.prdoc @@ -0,0 +1,17 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Fix Possible bug, Vote import failed after aggression is enabled + +doc: + - audience: Node Dev + description: | + Fix the appearance of Possible bug: Vote import failed after aggression is enabled, the log itself is + harmless because approval gets imported anyway and aggression is able to distribute it, nevertheless + is something that can be easily be fixed by picking the highest required routing possible. + +crates: + - name: polkadot-node-network-protocol + bump: minor + - name: polkadot-approval-distribution + bump: minor From 4198dc95b20e7a157fa0d1b8ef4a2e01a223af1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Mon, 9 Dec 2024 15:57:00 +0100 Subject: [PATCH 27/51] pallet-revive: Remove unused dependencies (#6796) The dependency on `pallet_balances` doesn't seem to be necessary. At least everything compiles for me without it. Removed this dependency and a few others that seem to be left overs. --------- Co-authored-by: GitHub Action --- Cargo.lock | 4 ---- prdoc/pr_6796.prdoc | 9 +++++++++ substrate/frame/revive/Cargo.toml | 19 ++++--------------- .../revive/src/benchmarking/call_builder.rs | 4 ++-- .../frame/revive/src/benchmarking/mod.rs | 8 +++----- 5 files changed, 18 insertions(+), 26 deletions(-) create mode 100644 prdoc/pr_6796.prdoc diff --git a/Cargo.lock b/Cargo.lock index cee1e2ce7411..aa91d9284a10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14633,7 +14633,6 @@ dependencies = [ "assert_matches", "bitflags 1.3.2", "derive_more 0.99.17", - "env_logger 0.11.3", "environmental", "ethereum-types 0.15.1", "frame-benchmarking 28.0.0", @@ -14642,11 +14641,8 @@ dependencies = [ "hex", "hex-literal", "impl-trait-for-tuples", - "jsonrpsee", "log", - "pallet-assets 29.1.0", "pallet-balances 28.0.0", - "pallet-message-queue 31.0.0", "pallet-proxy 28.0.0", "pallet-revive-fixtures 0.1.0", "pallet-revive-proc-macro 0.1.0", diff --git a/prdoc/pr_6796.prdoc b/prdoc/pr_6796.prdoc new file mode 100644 index 000000000000..aeb305847bf8 --- /dev/null +++ b/prdoc/pr_6796.prdoc @@ -0,0 +1,9 @@ +title: 'pallet-revive: Remove unused dependencies' +doc: +- audience: Runtime Dev + description: The dependency on `pallet_balances` doesn't seem to be necessary. At + least everything compiles for me without it. Removed this dependency and a few + others that seem to be left overs. +crates: +- name: pallet-revive + bump: major diff --git a/substrate/frame/revive/Cargo.toml b/substrate/frame/revive/Cargo.toml index 098a66df8dee..2e069bacf737 100644 --- a/substrate/frame/revive/Cargo.toml +++ b/substrate/frame/revive/Cargo.toml @@ -32,17 +32,15 @@ impl-trait-for-tuples = { workspace = true } rlp = { workspace = true } derive_more = { workspace = true } hex = { workspace = true } -jsonrpsee = { workspace = true, features = ["full"], optional = true } ethereum-types = { workspace = true, features = ["codec", "rlp", "serialize"] } # Polkadot SDK Dependencies frame-benchmarking = { optional = true, workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } -pallet-balances = { optional = true, workspace = true } -pallet-revive-fixtures = { workspace = true, default-features = false, optional = true } -pallet-revive-uapi = { workspace = true, default-features = true } -pallet-revive-proc-macro = { workspace = true, default-features = true } +pallet-revive-fixtures = { workspace = true, optional = true } +pallet-revive-uapi = { workspace = true, features = ["scale"] } +pallet-revive-proc-macro = { workspace = true } pallet-transaction-payment = { workspace = true } sp-api = { workspace = true } sp-arithmetic = { workspace = true } @@ -61,19 +59,16 @@ subxt-signer = { workspace = true, optional = true, features = [ array-bytes = { workspace = true, default-features = true } assert_matches = { workspace = true } pretty_assertions = { workspace = true } -pallet-revive-fixtures = { workspace = true, default-features = true } secp256k1 = { workspace = true, features = ["recovery"] } serde_json = { workspace = true } hex-literal = { workspace = true } -env_logger = { workspace = true } # Polkadot SDK Dependencies pallet-balances = { workspace = true, default-features = true } pallet-timestamp = { workspace = true, default-features = true } -pallet-message-queue = { workspace = true, default-features = true } pallet-utility = { workspace = true, default-features = true } -pallet-assets = { workspace = true, default-features = true } pallet-proxy = { workspace = true, default-features = true } +pallet-revive-fixtures = { workspace = true, default-features = true } sp-keystore = { workspace = true, default-features = true } sp-tracing = { workspace = true, default-features = true } xcm-builder = { workspace = true, default-features = true } @@ -88,9 +83,7 @@ std = [ "frame-support/std", "frame-system/std", "hex/std", - "jsonrpsee", "log/std", - "pallet-balances?/std", "pallet-proxy/std", "pallet-revive-fixtures?/std", "pallet-timestamp/std", @@ -118,9 +111,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", - "pallet-message-queue/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-revive-fixtures", "pallet-timestamp/runtime-benchmarks", @@ -132,9 +123,7 @@ runtime-benchmarks = [ try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", - "pallet-assets/try-runtime", "pallet-balances/try-runtime", - "pallet-message-queue/try-runtime", "pallet-proxy/try-runtime", "pallet-timestamp/try-runtime", "pallet-transaction-payment/try-runtime", diff --git a/substrate/frame/revive/src/benchmarking/call_builder.rs b/substrate/frame/revive/src/benchmarking/call_builder.rs index c666383abb2f..8d3157541168 100644 --- a/substrate/frame/revive/src/benchmarking/call_builder.rs +++ b/substrate/frame/revive/src/benchmarking/call_builder.rs @@ -45,7 +45,7 @@ pub struct CallSetup { impl Default for CallSetup where - T: Config + pallet_balances::Config, + T: Config, BalanceOf: Into + TryFrom, MomentOf: Into, T::Hash: frame_support::traits::IsType, @@ -57,7 +57,7 @@ where impl CallSetup where - T: Config + pallet_balances::Config, + T: Config, BalanceOf: Into + TryFrom, MomentOf: Into, T::Hash: frame_support::traits::IsType, diff --git a/substrate/frame/revive/src/benchmarking/mod.rs b/substrate/frame/revive/src/benchmarking/mod.rs index b73815bfb9ea..ebdea8675824 100644 --- a/substrate/frame/revive/src/benchmarking/mod.rs +++ b/substrate/frame/revive/src/benchmarking/mod.rs @@ -34,11 +34,10 @@ use frame_benchmarking::v2::*; use frame_support::{ self, assert_ok, storage::child, - traits::{fungible::InspectHold, Currency}, + traits::fungible::InspectHold, weights::{Weight, WeightMeter}, }; use frame_system::RawOrigin; -use pallet_balances; use pallet_revive_uapi::{CallFlags, ReturnErrorCode, StorageFlags}; use sp_runtime::traits::{Bounded, Hash}; @@ -68,7 +67,7 @@ struct Contract { impl Contract where - T: Config + pallet_balances::Config, + T: Config, BalanceOf: Into + TryFrom, MomentOf: Into, T::Hash: frame_support::traits::IsType, @@ -220,11 +219,10 @@ fn default_deposit_limit() -> BalanceOf { #[benchmarks( where BalanceOf: Into + TryFrom, - T: Config + pallet_balances::Config, + T: Config, MomentOf: Into, ::RuntimeEvent: From>, ::RuntimeCall: From>, - as Currency>::Balance: From>, ::Hash: frame_support::traits::IsType, )] mod benchmarks { From e79fd2bb9926be7d94be0c002676fca57b6116bf Mon Sep 17 00:00:00 2001 From: Adrian Catangiu Date: Mon, 9 Dec 2024 21:58:10 +0200 Subject: [PATCH 28/51] xcm-executor: take transport fee from transferred assets if necessary (#4834) # Description Sending XCM messages to other chains requires paying a "transport fee". This can be paid either: - from `origin` local account if `jit_withdraw = true`, - taken from Holding register otherwise. This currently works for following hops/scenarios: 1. On destination no transport fee needed (only sending costs, not receiving), 2. Local/originating chain: just set JIT=true and fee will be paid from signed account, 3. Intermediary hops - only if intermediary is acting as reserve between two untrusted chains (aka only for `DepositReserveAsset` instruction) - this was fixed in https://github.com/paritytech/polkadot-sdk/pull/3142 But now we're seeing more complex asset transfers that are mixing reserve transfers with teleports depending on the involved chains. # Example E.g. transferring DOT between Relay and parachain, but through AH (using AH instead of the Relay chain as parachain's DOT reserve). In the `Parachain --1--> AssetHub --2--> Relay` scenario, DOT has to be reserve-withdrawn in leg `1`, then teleported in leg `2`. On the intermediary hop (AssetHub), `InitiateTeleport` fails to send onward message because of missing transport fees. We also can't rely on `jit_withdraw` because the original origin is lost on the way, and even if it weren't we can't rely on the user having funded accounts on each hop along the way. # Solution/Changes - Charge the transport fee in the executor from the transferred assets (if available), - Only charge from transferred assets if JIT_WITHDRAW was not set, - Only charge from transferred assets if unless using XCMv5 `PayFees` where we do not have this problem. # Testing Added regression tests in emulated transfers. Fixes https://github.com/paritytech/polkadot-sdk/issues/4832 Fixes https://github.com/paritytech/polkadot-sdk/issues/6637 --------- Signed-off-by: Adrian Catangiu Co-authored-by: Francisco Aguirre --- .../primitives/router/src/inbound/mod.rs | 4 +- .../src/tests/reserve_transfer.rs | 6 +- .../tests/assets/asset-hub-westend/src/lib.rs | 1 + .../src/tests/hybrid_transfers.rs | 141 +++++++++++++++++- .../src/tests/reserve_transfer.rs | 6 +- .../asset-hub-westend/src/tests/transact.rs | 2 +- .../src/tests/asset_transfers.rs | 2 +- .../src/tests/register_bridged_assets.rs | 2 +- .../bridge-hub-rococo/src/tests/send_xcm.rs | 2 +- .../src/tests/asset_transfers.rs | 4 +- .../src/tests/register_bridged_assets.rs | 2 +- .../bridge-hub-westend/src/tests/send_xcm.rs | 2 +- .../bridge-hub-westend/src/tests/transact.rs | 2 +- polkadot/xcm/xcm-executor/src/lib.rs | 83 ++++++++--- prdoc/pr_4834.prdoc | 15 ++ 15 files changed, 230 insertions(+), 44 deletions(-) create mode 100644 prdoc/pr_4834.prdoc diff --git a/bridges/snowbridge/primitives/router/src/inbound/mod.rs b/bridges/snowbridge/primitives/router/src/inbound/mod.rs index 54a578b988a4..a7bd0dfc1234 100644 --- a/bridges/snowbridge/primitives/router/src/inbound/mod.rs +++ b/bridges/snowbridge/primitives/router/src/inbound/mod.rs @@ -358,7 +358,9 @@ where }])), // Perform a deposit reserve to send to destination chain. DepositReserveAsset { - assets: Definite(vec![dest_para_fee_asset.clone(), asset].into()), + // Send over assets and unspent fees, XCM delivery fee will be charged from + // here. + assets: Wild(AllCounted(2)), dest: Location::new(1, [Parachain(dest_para_id)]), xcm: vec![ // Buy execution on target. diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs index 698ef2c9e792..d642e877f002 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs @@ -115,7 +115,7 @@ pub fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { assert_expected_events!( AssetHubRococo, vec![ - // Transport fees are paid + // Delivery fees are paid RuntimeEvent::PolkadotXcm(pallet_xcm::Event::FeesPaid { .. }) => {}, ] ); @@ -274,7 +274,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { t.args.dest.clone() ), }, - // Transport fees are paid + // Delivery fees are paid RuntimeEvent::PolkadotXcm( pallet_xcm::Event::FeesPaid { .. } ) => {}, @@ -305,7 +305,7 @@ fn para_to_system_para_assets_sender_assertions(t: ParaToSystemParaTest) { owner: *owner == t.sender.account_id, balance: *balance == t.args.amount, }, - // Transport fees are paid + // Delivery fees are paid RuntimeEvent::PolkadotXcm( pallet_xcm::Event::FeesPaid { .. } ) => {}, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs index 3cca99fbfe5c..36630e2d2221 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs @@ -106,6 +106,7 @@ mod imports { pub type ParaToParaThroughRelayTest = Test; pub type ParaToParaThroughAHTest = Test; pub type RelayToParaThroughAHTest = Test; + pub type PenpalToRelayThroughAHTest = Test; } #[cfg(test)] diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs index a0fc82fba6ef..0686bd71d085 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs @@ -658,13 +658,13 @@ fn bidirectional_teleport_foreign_asset_between_para_and_asset_hub_using_explici } // =============================================================== -// ===== Transfer - Native Asset - Relay->AssetHub->Parachain ==== +// ====== Transfer - Native Asset - Relay->AssetHub->Penpal ====== // =============================================================== -/// Transfers of native asset Relay to Parachain (using AssetHub reserve). Parachains want to avoid +/// Transfers of native asset Relay to Penpal (using AssetHub reserve). Parachains want to avoid /// managing SAs on all system chains, thus want all their DOT-in-reserve to be held in their /// Sovereign Account on Asset Hub. #[test] -fn transfer_native_asset_from_relay_to_para_through_asset_hub() { +fn transfer_native_asset_from_relay_to_penpal_through_asset_hub() { // Init values for Relay let destination = Westend::child_location_of(PenpalA::para_id()); let sender = WestendSender::get(); @@ -820,6 +820,137 @@ fn transfer_native_asset_from_relay_to_para_through_asset_hub() { assert!(receiver_assets_after < receiver_assets_before + amount_to_send); } +// =============================================================== +// ===== Transfer - Native Asset - Penpal->AssetHub->Relay ======= +// =============================================================== +/// Transfers of native asset Penpal to Relay (using AssetHub reserve). Parachains want to avoid +/// managing SAs on all system chains, thus want all their DOT-in-reserve to be held in their +/// Sovereign Account on Asset Hub. +#[test] +fn transfer_native_asset_from_penpal_to_relay_through_asset_hub() { + // Init values for Penpal + let destination = RelayLocation::get(); + let sender = PenpalASender::get(); + let amount_to_send: Balance = WESTEND_ED * 100; + + // Init values for Penpal + let relay_native_asset_location = RelayLocation::get(); + let receiver = WestendReceiver::get(); + + // Init Test + let test_args = TestContext { + sender: sender.clone(), + receiver: receiver.clone(), + args: TestArgs::new_para( + destination.clone(), + receiver.clone(), + amount_to_send, + (Parent, amount_to_send).into(), + None, + 0, + ), + }; + let mut test = PenpalToRelayThroughAHTest::new(test_args); + + let sov_penpal_on_ah = AssetHubWestend::sovereign_account_id_of( + AssetHubWestend::sibling_location_of(PenpalA::para_id()), + ); + // fund Penpal's sender account + PenpalA::mint_foreign_asset( + ::RuntimeOrigin::signed(PenpalAssetOwner::get()), + relay_native_asset_location.clone(), + sender.clone(), + amount_to_send * 2, + ); + // fund Penpal's SA on AssetHub with the assets held in reserve + AssetHubWestend::fund_accounts(vec![(sov_penpal_on_ah.clone().into(), amount_to_send * 2)]); + + // prefund Relay checking account so we accept teleport "back" from AssetHub + let check_account = + Westend::execute_with(|| ::XcmPallet::check_account()); + Westend::fund_accounts(vec![(check_account, amount_to_send)]); + + // Query initial balances + let sender_balance_before = PenpalA::execute_with(|| { + type ForeignAssets = ::ForeignAssets; + >::balance(relay_native_asset_location.clone(), &sender) + }); + let sov_penpal_on_ah_before = AssetHubWestend::execute_with(|| { + ::Balances::free_balance(sov_penpal_on_ah.clone()) + }); + let receiver_balance_before = Westend::execute_with(|| { + ::Balances::free_balance(receiver.clone()) + }); + + fn transfer_assets_dispatchable(t: PenpalToRelayThroughAHTest) -> DispatchResult { + let fee_idx = t.args.fee_asset_item as usize; + let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let asset_hub_location = PenpalA::sibling_location_of(AssetHubWestend::para_id()); + let context = PenpalUniversalLocation::get(); + + // reanchor fees to the view of destination (Westend Relay) + let mut remote_fees = fee.clone().reanchored(&t.args.dest, &context).unwrap(); + if let Fungible(ref mut amount) = remote_fees.fun { + // we already spent some fees along the way, just use half of what we started with + *amount = *amount / 2; + } + let xcm_on_final_dest = Xcm::<()>(vec![ + BuyExecution { fees: remote_fees, weight_limit: t.args.weight_limit.clone() }, + DepositAsset { + assets: Wild(AllCounted(t.args.assets.len() as u32)), + beneficiary: t.args.beneficiary, + }, + ]); + + // reanchor final dest (Westend Relay) to the view of hop (Asset Hub) + let mut dest = t.args.dest.clone(); + dest.reanchor(&asset_hub_location, &context).unwrap(); + // on Asset Hub + let xcm_on_hop = Xcm::<()>(vec![InitiateTeleport { + assets: Wild(AllCounted(t.args.assets.len() as u32)), + dest, + xcm: xcm_on_final_dest, + }]); + + // First leg is a reserve-withdraw, from there a teleport to final dest + ::PolkadotXcm::transfer_assets_using_type_and_then( + t.signed_origin, + bx!(asset_hub_location.into()), + bx!(t.args.assets.into()), + bx!(TransferType::DestinationReserve), + bx!(fee.id.into()), + bx!(TransferType::DestinationReserve), + bx!(VersionedXcm::from(xcm_on_hop)), + t.args.weight_limit, + ) + } + test.set_dispatchable::(transfer_assets_dispatchable); + test.assert(); + + // Query final balances + let sender_balance_after = PenpalA::execute_with(|| { + type ForeignAssets = ::ForeignAssets; + >::balance(relay_native_asset_location.clone(), &sender) + }); + let sov_penpal_on_ah_after = AssetHubWestend::execute_with(|| { + ::Balances::free_balance(sov_penpal_on_ah.clone()) + }); + let receiver_balance_after = Westend::execute_with(|| { + ::Balances::free_balance(receiver.clone()) + }); + + // Sender's asset balance is reduced by amount sent plus delivery fees + assert!(sender_balance_after < sender_balance_before - amount_to_send); + // SA on AH balance is decreased by `amount_to_send` + assert_eq!(sov_penpal_on_ah_after, sov_penpal_on_ah_before - amount_to_send); + // Receiver's balance is increased + assert!(receiver_balance_after > receiver_balance_before); + // Receiver's balance increased by `amount_to_send - delivery_fees - bought_execution`; + // `delivery_fees` might be paid from transfer or JIT, also `bought_execution` is unknown but + // should be non-zero + assert!(receiver_balance_after < receiver_balance_before + amount_to_send); +} + // ============================================================================================== // ==== Bidirectional Transfer - Native + Teleportable Foreign Assets - Parachain<->AssetHub ==== // ============================================================================================== @@ -839,7 +970,7 @@ fn bidirectional_transfer_multiple_assets_between_penpal_and_asset_hub() { // xcm to be executed at dest let xcm_on_dest = Xcm(vec![ // since this is the last hop, we don't need to further use any assets previously - // reserved for fees (there are no further hops to cover transport fees for); we + // reserved for fees (there are no further hops to cover delivery fees for); we // RefundSurplus to get back any unspent fees RefundSurplus, DepositAsset { assets: Wild(All), beneficiary: t.args.beneficiary }, @@ -875,7 +1006,7 @@ fn bidirectional_transfer_multiple_assets_between_penpal_and_asset_hub() { // xcm to be executed at dest let xcm_on_dest = Xcm(vec![ // since this is the last hop, we don't need to further use any assets previously - // reserved for fees (there are no further hops to cover transport fees for); we + // reserved for fees (there are no further hops to cover delivery fees for); we // RefundSurplus to get back any unspent fees RefundSurplus, DepositAsset { assets: Wild(All), beneficiary: t.args.beneficiary }, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs index 558eab13e5c7..707e8adc8a56 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs @@ -115,7 +115,7 @@ pub fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { assert_expected_events!( AssetHubWestend, vec![ - // Transport fees are paid + // Delivery fees are paid RuntimeEvent::PolkadotXcm(pallet_xcm::Event::FeesPaid { .. }) => {}, ] ); @@ -274,7 +274,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { t.args.dest.clone() ), }, - // Transport fees are paid + // Delivery fees are paid RuntimeEvent::PolkadotXcm( pallet_xcm::Event::FeesPaid { .. } ) => {}, @@ -305,7 +305,7 @@ fn para_to_system_para_assets_sender_assertions(t: ParaToSystemParaTest) { owner: *owner == t.sender.account_id, balance: *balance == t.args.amount, }, - // Transport fees are paid + // Delivery fees are paid RuntimeEvent::PolkadotXcm( pallet_xcm::Event::FeesPaid { .. } ) => {}, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs index 592c2845255c..7e881a332a53 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transact.rs @@ -46,7 +46,7 @@ fn transfer_and_transact_in_same_xcm( Transact { origin_kind: OriginKind::Xcm, call, fallback_max_weight: None }, ExpectTransactStatus(MaybeErrorCode::Success), // since this is the last hop, we don't need to further use any assets previously - // reserved for fees (there are no further hops to cover transport fees for); we + // reserved for fees (there are no further hops to cover delivery fees for); we // RefundSurplus to get back any unspent fees RefundSurplus, DepositAsset { assets: Wild(All), beneficiary }, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs index 33ab1e70b97b..a2a61660afff 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs @@ -16,7 +16,7 @@ use crate::tests::*; fn send_assets_over_bridge(send_fn: F) { - // fund the AHR's SA on BHR for paying bridge transport fees + // fund the AHR's SA on BHR for paying bridge delivery fees BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128); // set XCM versions diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/register_bridged_assets.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/register_bridged_assets.rs index 1ae3a1b15805..70e7a7a3ddd3 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/register_bridged_assets.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/register_bridged_assets.rs @@ -58,7 +58,7 @@ fn register_rococo_asset_on_wah_from_rah() { let destination = asset_hub_westend_location(); - // fund the RAH's SA on RBH for paying bridge transport fees + // fund the RAH's SA on RBH for paying bridge delivery fees BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128); // set XCM versions diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs index 931a3128f826..116ec4dc0e55 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs @@ -65,7 +65,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { let native_token = Location::parent(); let amount = ASSET_HUB_ROCOCO_ED * 1_000; - // fund the AHR's SA on BHR for paying bridge transport fees + // fund the AHR's SA on BHR for paying bridge delivery fees BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128); // fund sender AssetHubRococo::fund_accounts(vec![(AssetHubRococoSender::get().into(), amount * 10)]); diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs index ab09517339db..cc90c10b54bc 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs @@ -17,7 +17,7 @@ use crate::{create_pool_with_native_on, tests::*}; use xcm::latest::AssetTransferFilter; fn send_assets_over_bridge(send_fn: F) { - // fund the AHW's SA on BHW for paying bridge transport fees + // fund the AHW's SA on BHW for paying bridge delivery fees BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), 10_000_000_000_000u128); // set XCM versions @@ -592,7 +592,7 @@ fn do_send_pens_and_wnds_from_penpal_westend_via_ahw_to_asset_hub_rococo( // XCM to be executed at dest (Rococo Asset Hub) let xcm_on_dest = Xcm(vec![ // since this is the last hop, we don't need to further use any assets previously - // reserved for fees (there are no further hops to cover transport fees for); we + // reserved for fees (there are no further hops to cover delivery fees for); we // RefundSurplus to get back any unspent fees RefundSurplus, // deposit everything to final beneficiary diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/register_bridged_assets.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/register_bridged_assets.rs index 424f1e55956b..952fc35e6703 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/register_bridged_assets.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/register_bridged_assets.rs @@ -82,7 +82,7 @@ fn register_asset_on_rah_from_wah(bridged_asset_at_rah: Location) { let destination = asset_hub_rococo_location(); - // fund the WAH's SA on WBH for paying bridge transport fees + // fund the WAH's SA on WBH for paying bridge delivery fees BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), 10_000_000_000_000u128); // set XCM versions diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs index 787d7dc842cb..acce60b4fa76 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs @@ -65,7 +65,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { let native_token = Location::parent(); let amount = ASSET_HUB_WESTEND_ED * 1_000; - // fund the AHR's SA on BHR for paying bridge transport fees + // fund the AHR's SA on BHR for paying bridge delivery fees BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), 10_000_000_000_000u128); // fund sender AssetHubWestend::fund_accounts(vec![(AssetHubWestendSender::get().into(), amount * 10)]); diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs index 7831c8d66357..f6a3c53c4bf5 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/transact.rs @@ -52,7 +52,7 @@ fn transfer_and_transact_in_same_xcm( Transact { origin_kind: OriginKind::Xcm, call, fallback_max_weight: None }, ExpectTransactStatus(MaybeErrorCode::Success), // since this is the last hop, we don't need to further use any assets previously - // reserved for fees (there are no further hops to cover transport fees for); we + // reserved for fees (there are no further hops to cover delivery fees for); we // RefundSurplus to get back any unspent fees RefundSurplus, DepositAsset { assets: Wild(All), beneficiary }, diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 64a32f488420..d0f18aea1ab3 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -1087,18 +1087,19 @@ impl XcmExecutor { DepositReserveAsset { assets, dest, xcm } => { let old_holding = self.holding.clone(); let result = Config::TransactionalProcessor::process(|| { - let maybe_delivery_fee_from_holding = if self.fees.is_empty() { - self.get_delivery_fee_from_holding(&assets, &dest, &xcm)? + let mut assets = self.holding.saturating_take(assets); + // When not using `PayFees`, nor `JIT_WITHDRAW`, delivery fees are paid from + // transferred assets. + let maybe_delivery_fee_from_assets = if self.fees.is_empty() && !self.fees_mode.jit_withdraw { + // Deduct and return the part of `assets` that shall be used for delivery fees. + self.take_delivery_fee_from_assets(&mut assets, &dest, FeeReason::DepositReserveAsset, &xcm)? } else { None }; - let mut message = Vec::with_capacity(xcm.len() + 2); - // now take assets to deposit (after having taken delivery fees) - let deposited = self.holding.saturating_take(assets); - tracing::trace!(target: "xcm::DepositReserveAsset", ?deposited, "Assets except delivery fee"); + tracing::trace!(target: "xcm::DepositReserveAsset", ?assets, "Assets except delivery fee"); Self::do_reserve_deposit_assets( - deposited, + assets, &dest, &mut message, Some(&self.context), @@ -1107,7 +1108,7 @@ impl XcmExecutor { message.push(ClearOrigin); // append custom instructions message.extend(xcm.0.into_iter()); - if let Some(delivery_fee) = maybe_delivery_fee_from_holding { + if let Some(delivery_fee) = maybe_delivery_fee_from_assets { // Put back delivery_fee in holding register to be charged by XcmSender. self.holding.subsume_assets(delivery_fee); } @@ -1122,7 +1123,15 @@ impl XcmExecutor { InitiateReserveWithdraw { assets, reserve, xcm } => { let old_holding = self.holding.clone(); let result = Config::TransactionalProcessor::process(|| { - let assets = self.holding.saturating_take(assets); + let mut assets = self.holding.saturating_take(assets); + // When not using `PayFees`, nor `JIT_WITHDRAW`, delivery fees are paid from + // transferred assets. + let maybe_delivery_fee_from_assets = if self.fees.is_empty() && !self.fees_mode.jit_withdraw { + // Deduct and return the part of `assets` that shall be used for delivery fees. + self.take_delivery_fee_from_assets(&mut assets, &reserve, FeeReason::InitiateReserveWithdraw, &xcm)? + } else { + None + }; let mut message = Vec::with_capacity(xcm.len() + 2); Self::do_reserve_withdraw_assets( assets, @@ -1134,6 +1143,10 @@ impl XcmExecutor { message.push(ClearOrigin); // append custom instructions message.extend(xcm.0.into_iter()); + if let Some(delivery_fee) = maybe_delivery_fee_from_assets { + // Put back delivery_fee in holding register to be charged by XcmSender. + self.holding.subsume_assets(delivery_fee); + } self.send(reserve, Xcm(message), FeeReason::InitiateReserveWithdraw)?; Ok(()) }); @@ -1145,13 +1158,25 @@ impl XcmExecutor { InitiateTeleport { assets, dest, xcm } => { let old_holding = self.holding.clone(); let result = Config::TransactionalProcessor::process(|| { - let assets = self.holding.saturating_take(assets); + let mut assets = self.holding.saturating_take(assets); + // When not using `PayFees`, nor `JIT_WITHDRAW`, delivery fees are paid from + // transferred assets. + let maybe_delivery_fee_from_assets = if self.fees.is_empty() && !self.fees_mode.jit_withdraw { + // Deduct and return the part of `assets` that shall be used for delivery fees. + self.take_delivery_fee_from_assets(&mut assets, &dest, FeeReason::InitiateTeleport, &xcm)? + } else { + None + }; let mut message = Vec::with_capacity(xcm.len() + 2); Self::do_teleport_assets(assets, &dest, &mut message, &self.context)?; // clear origin for subsequent custom instructions message.push(ClearOrigin); // append custom instructions message.extend(xcm.0.into_iter()); + if let Some(delivery_fee) = maybe_delivery_fee_from_assets { + // Put back delivery_fee in holding register to be charged by XcmSender. + self.holding.subsume_assets(delivery_fee); + } self.send(dest.clone(), Xcm(message), FeeReason::InitiateTeleport)?; Ok(()) }); @@ -1714,36 +1739,48 @@ impl XcmExecutor { Ok(()) } - /// Gets the necessary delivery fee to send a reserve transfer message to `destination` from - /// holding. + /// Take from transferred `assets` the delivery fee required to send an onward transfer message + /// to `destination`. /// /// Will be removed once the transition from `BuyExecution` to `PayFees` is complete. - fn get_delivery_fee_from_holding( - &mut self, - assets: &AssetFilter, + fn take_delivery_fee_from_assets( + &self, + assets: &mut AssetsInHolding, destination: &Location, + reason: FeeReason, xcm: &Xcm<()>, ) -> Result, XcmError> { - // we need to do this take/put cycle to solve wildcards and get exact assets to - // be weighed - let to_weigh = self.holding.saturating_take(assets.clone()); - self.holding.subsume_assets(to_weigh.clone()); + let to_weigh = assets.clone(); let to_weigh_reanchored = Self::reanchored(to_weigh, &destination, None); - let mut message_to_weigh = vec![ReserveAssetDeposited(to_weigh_reanchored), ClearOrigin]; + let remote_instruction = match reason { + FeeReason::DepositReserveAsset => ReserveAssetDeposited(to_weigh_reanchored), + FeeReason::InitiateReserveWithdraw => WithdrawAsset(to_weigh_reanchored), + FeeReason::InitiateTeleport => ReceiveTeleportedAsset(to_weigh_reanchored), + _ => { + tracing::debug!( + target: "xcm::take_delivery_fee_from_assets", + "Unexpected delivery fee reason", + ); + return Err(XcmError::NotHoldingFees); + }, + }; + let mut message_to_weigh = Vec::with_capacity(xcm.len() + 2); + message_to_weigh.push(remote_instruction); + message_to_weigh.push(ClearOrigin); message_to_weigh.extend(xcm.0.clone().into_iter()); let (_, fee) = validate_send::(destination.clone(), Xcm(message_to_weigh))?; let maybe_delivery_fee = fee.get(0).map(|asset_needed_for_fees| { tracing::trace!( - target: "xcm::fees::DepositReserveAsset", + target: "xcm::fees::take_delivery_fee_from_assets", "Asset provided to pay for fees {:?}, asset required for delivery fees: {:?}", self.asset_used_in_buy_execution, asset_needed_for_fees, ); let asset_to_pay_for_fees = self.calculate_asset_for_delivery_fees(asset_needed_for_fees.clone()); // set aside fee to be charged by XcmSender - let delivery_fee = self.holding.saturating_take(asset_to_pay_for_fees.into()); - tracing::trace!(target: "xcm::fees::DepositReserveAsset", ?delivery_fee); + let delivery_fee = assets.saturating_take(asset_to_pay_for_fees.into()); + tracing::trace!(target: "xcm::fees::take_delivery_fee_from_assets", ?delivery_fee); delivery_fee }); Ok(maybe_delivery_fee) diff --git a/prdoc/pr_4834.prdoc b/prdoc/pr_4834.prdoc new file mode 100644 index 000000000000..b7c8b15cb073 --- /dev/null +++ b/prdoc/pr_4834.prdoc @@ -0,0 +1,15 @@ +title: "xcm-executor: take delivery fee from transferred assets if necessary" + +doc: + - audience: Runtime Dev + description: | + In asset transfers, as a last resort, XCM delivery fees are taken from + transferred assets rather than failing the transfer. + +crates: + - name: staging-xcm-executor + bump: patch + - name: snowbridge-router-primitives + bump: patch + - name: snowbridge-pallet-inbound-queue + bump: patch From 4fc9248629fe8cd913bd05025c7690f99d7203d7 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Tue, 10 Dec 2024 01:32:21 -0300 Subject: [PATCH 29/51] Add fallback_max_weight to snowbridge Transact (#6792) We removed the `require_weight_at_most` field and later changed it to `fallback_max_weight`. This was to have a fallback when sending a message to v4 chains, which happens in the small time window when chains are upgrading. We originally put no fallback for a message in snowbridge's inbound queue but we should have one. This PR adds it. --------- Co-authored-by: GitHub Action --- bridges/snowbridge/pallets/inbound-queue/src/test.rs | 4 ++-- .../snowbridge/primitives/router/src/inbound/mod.rs | 2 +- prdoc/pr_6792.prdoc | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 prdoc/pr_6792.prdoc diff --git a/bridges/snowbridge/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/pallets/inbound-queue/src/test.rs index 1e0bd8acc925..beb9f7614574 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/test.rs @@ -40,8 +40,8 @@ fn test_submit_happy_path() { .into(), nonce: 1, message_id: [ - 86, 101, 80, 125, 84, 10, 227, 145, 230, 209, 152, 38, 206, 251, 206, 208, 244, - 221, 22, 215, 1, 252, 79, 181, 99, 207, 166, 220, 98, 3, 81, 7, + 118, 166, 139, 182, 84, 52, 165, 189, 54, 14, 178, 73, 2, 228, 192, 97, 153, 201, + 4, 75, 151, 15, 82, 6, 164, 187, 162, 133, 26, 183, 186, 126, ], fee_burned: 110000000000, } diff --git a/bridges/snowbridge/primitives/router/src/inbound/mod.rs b/bridges/snowbridge/primitives/router/src/inbound/mod.rs index a7bd0dfc1234..bc5d401cd4f7 100644 --- a/bridges/snowbridge/primitives/router/src/inbound/mod.rs +++ b/bridges/snowbridge/primitives/router/src/inbound/mod.rs @@ -279,7 +279,7 @@ where // Call create_asset on foreign assets pallet. Transact { origin_kind: OriginKind::Xcm, - fallback_max_weight: None, + fallback_max_weight: Some(Weight::from_parts(400_000_000, 8_000)), call: ( create_call_index, asset_id, diff --git a/prdoc/pr_6792.prdoc b/prdoc/pr_6792.prdoc new file mode 100644 index 000000000000..80982a34b3e8 --- /dev/null +++ b/prdoc/pr_6792.prdoc @@ -0,0 +1,11 @@ +title: Add fallback_max_weight to snowbridge Transact +doc: +- audience: Runtime Dev + description: |- + We removed the `require_weight_at_most` field and later changed it to `fallback_max_weight`. + This was to have a fallback when sending a message to v4 chains, which happens in the small time window when chains are upgrading. + We originally put no fallback for a message in snowbridge's inbound queue but we should have one. + This PR adds it. +crates: +- name: snowbridge-router-primitives + bump: patch From 3fb99c0b48b59fd49e14b853e278989d9ca52483 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 10 Dec 2024 05:44:45 +0100 Subject: [PATCH 30/51] Add fallback_weight to the log (#6782) Co-authored-by: Francisco Aguirre --- polkadot/xcm/src/v4/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/polkadot/xcm/src/v4/mod.rs b/polkadot/xcm/src/v4/mod.rs index bbf5ca049228..a0ce551b7608 100644 --- a/polkadot/xcm/src/v4/mod.rs +++ b/polkadot/xcm/src/v4/mod.rs @@ -1320,12 +1320,14 @@ impl TryFrom> for Instructi let require_weight_at_most = match call.take_decoded() { Ok(decoded) => decoded.get_dispatch_info().call_weight, Err(error) => { - log::error!( + let fallback_weight = fallback_max_weight.unwrap_or(Weight::MAX); + log::debug!( target: "xcm::versions::v5Tov4", - "Couldn't decode call in Transact: {:?}, using fallback weight.", + "Couldn't decode call in Transact: {:?}, using fallback weight: {:?}", error, + fallback_weight, ); - fallback_max_weight.unwrap_or(Weight::MAX) + fallback_weight }, }; Self::Transact { origin_kind, require_weight_at_most, call: call.into() } From 8f4b99cffabbe9edaa9c29f451e45cfdb4674adc Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 10 Dec 2024 06:37:57 +0100 Subject: [PATCH 31/51] Bridges - revert-back congestion mechanism (#6781) Closes: https://github.com/paritytech/polkadot-sdk/issues/5551 ## Description With [permissionless lanes PR#4949](https://github.com/paritytech/polkadot-sdk/pull/4949), the congestion mechanism based on sending `Transact(report_bridge_status(is_congested))` from `pallet-xcm-bridge-hub` to `pallet-xcm-bridge-hub-router` was replaced with a congestion mechanism that relied on monitoring XCMP queues. However, this approach could cause issues, such as suspending the entire XCMP queue instead of isolating the affected bridge. This PR reverts back to using `report_bridge_status` as before. ## TODO - [x] benchmarks - [x] prdoc ## Follow-up https://github.com/paritytech/polkadot-sdk/pull/6231 --------- Co-authored-by: GitHub Action Co-authored-by: command-bot <> Co-authored-by: Adrian Catangiu --- Cargo.lock | 7 + .../chains/chain-asset-hub-rococo/Cargo.toml | 6 + .../chains/chain-asset-hub-rococo/src/lib.rs | 25 ++ .../chains/chain-asset-hub-westend/Cargo.toml | 6 + .../chains/chain-asset-hub-westend/src/lib.rs | 25 ++ .../xcm-bridge-hub-router/src/benchmarking.rs | 27 +- .../modules/xcm-bridge-hub-router/src/lib.rs | 230 ++++++++++++------ .../modules/xcm-bridge-hub-router/src/mock.rs | 1 + .../xcm-bridge-hub-router/src/weights.rs | 27 ++ bridges/modules/xcm-bridge-hub/Cargo.toml | 2 + .../modules/xcm-bridge-hub/src/exporter.rs | 115 +++++++-- bridges/modules/xcm-bridge-hub/src/lib.rs | 4 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 150 ++++++++++-- bridges/primitives/xcm-bridge-hub/src/lib.rs | 5 + .../assets/asset-hub-rococo/src/lib.rs | 7 +- .../weights/pallet_xcm_bridge_hub_router.rs | 30 ++- .../assets/asset-hub-rococo/tests/tests.rs | 55 ++++- .../assets/asset-hub-westend/src/lib.rs | 9 +- .../weights/pallet_xcm_bridge_hub_router.rs | 32 ++- .../assets/asset-hub-westend/tests/tests.rs | 52 +++- .../test-utils/src/test_cases_over_bridge.rs | 5 +- .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 2 + .../src/bridge_to_westend_config.rs | 43 +++- .../bridge-hubs/bridge-hub-westend/Cargo.toml | 2 + .../src/bridge_to_rococo_config.rs | 43 +++- prdoc/pr_6781.prdoc | 28 +++ 26 files changed, 781 insertions(+), 157 deletions(-) create mode 100644 prdoc/pr_6781.prdoc diff --git a/Cargo.lock b/Cargo.lock index aa91d9284a10..007cd1f05ba7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1938,6 +1938,8 @@ dependencies = [ "frame-support 28.0.0", "parity-scale-codec", "scale-info", + "sp-core 28.0.0", + "staging-xcm 7.0.0", ] [[package]] @@ -1948,6 +1950,8 @@ dependencies = [ "frame-support 28.0.0", "parity-scale-codec", "scale-info", + "sp-core 28.0.0", + "staging-xcm 7.0.0", ] [[package]] @@ -2541,6 +2545,7 @@ dependencies = [ "bp-rococo", "bp-runtime 0.7.0", "bp-westend", + "bp-xcm-bridge-hub-router 0.6.0", "bridge-hub-common 0.1.0", "bridge-hub-test-utils 0.7.0", "bridge-runtime-common 0.7.0", @@ -2779,6 +2784,7 @@ dependencies = [ "bp-rococo", "bp-runtime 0.7.0", "bp-westend", + "bp-xcm-bridge-hub-router 0.6.0", "bridge-hub-common 0.1.0", "bridge-hub-test-utils 0.7.0", "bridge-runtime-common 0.7.0", @@ -15982,6 +15988,7 @@ dependencies = [ "bp-messages 0.7.0", "bp-runtime 0.7.0", "bp-xcm-bridge-hub 0.2.0", + "bp-xcm-bridge-hub-router 0.6.0", "frame-support 28.0.0", "frame-system 28.0.0", "log", diff --git a/bridges/chains/chain-asset-hub-rococo/Cargo.toml b/bridges/chains/chain-asset-hub-rococo/Cargo.toml index 363a869048aa..4eb93ab52bc9 100644 --- a/bridges/chains/chain-asset-hub-rococo/Cargo.toml +++ b/bridges/chains/chain-asset-hub-rococo/Cargo.toml @@ -19,10 +19,14 @@ scale-info = { features = ["derive"], workspace = true } # Substrate Dependencies frame-support = { workspace = true } +sp-core = { workspace = true } # Bridge Dependencies bp-xcm-bridge-hub-router = { workspace = true } +# Polkadot dependencies +xcm = { workspace = true } + [features] default = ["std"] std = [ @@ -30,4 +34,6 @@ std = [ "codec/std", "frame-support/std", "scale-info/std", + "sp-core/std", + "xcm/std", ] diff --git a/bridges/chains/chain-asset-hub-rococo/src/lib.rs b/bridges/chains/chain-asset-hub-rococo/src/lib.rs index de2e9ae856d1..4ff7b391acd0 100644 --- a/bridges/chains/chain-asset-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-asset-hub-rococo/src/lib.rs @@ -18,10 +18,13 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + use codec::{Decode, Encode}; use scale_info::TypeInfo; pub use bp_xcm_bridge_hub_router::XcmBridgeHubRouterCall; +use xcm::latest::prelude::*; /// `AssetHubRococo` Runtime `Call` enum. /// @@ -44,5 +47,27 @@ frame_support::parameter_types! { pub const XcmBridgeHubRouterTransactCallMaxWeight: frame_support::weights::Weight = frame_support::weights::Weight::from_parts(200_000_000, 6144); } +/// Builds an (un)congestion XCM program with the `report_bridge_status` call for +/// `ToWestendXcmRouter`. +pub fn build_congestion_message( + bridge_id: sp_core::H256, + is_congested: bool, +) -> alloc::vec::Vec> { + alloc::vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + fallback_max_weight: Some(XcmBridgeHubRouterTransactCallMaxWeight::get()), + call: Call::ToWestendXcmRouter(XcmBridgeHubRouterCall::report_bridge_status { + bridge_id, + is_congested, + }) + .encode() + .into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ] +} + /// Identifier of AssetHubRococo in the Rococo relay chain. pub const ASSET_HUB_ROCOCO_PARACHAIN_ID: u32 = 1000; diff --git a/bridges/chains/chain-asset-hub-westend/Cargo.toml b/bridges/chains/chain-asset-hub-westend/Cargo.toml index 430d9b6116cf..22071399f4d1 100644 --- a/bridges/chains/chain-asset-hub-westend/Cargo.toml +++ b/bridges/chains/chain-asset-hub-westend/Cargo.toml @@ -19,10 +19,14 @@ scale-info = { features = ["derive"], workspace = true } # Substrate Dependencies frame-support = { workspace = true } +sp-core = { workspace = true } # Bridge Dependencies bp-xcm-bridge-hub-router = { workspace = true } +# Polkadot dependencies +xcm = { workspace = true } + [features] default = ["std"] std = [ @@ -30,4 +34,6 @@ std = [ "codec/std", "frame-support/std", "scale-info/std", + "sp-core/std", + "xcm/std", ] diff --git a/bridges/chains/chain-asset-hub-westend/src/lib.rs b/bridges/chains/chain-asset-hub-westend/src/lib.rs index 9de1c8809894..9d245e08f7cc 100644 --- a/bridges/chains/chain-asset-hub-westend/src/lib.rs +++ b/bridges/chains/chain-asset-hub-westend/src/lib.rs @@ -18,10 +18,13 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + use codec::{Decode, Encode}; use scale_info::TypeInfo; pub use bp_xcm_bridge_hub_router::XcmBridgeHubRouterCall; +use xcm::latest::prelude::*; /// `AssetHubWestend` Runtime `Call` enum. /// @@ -44,5 +47,27 @@ frame_support::parameter_types! { pub const XcmBridgeHubRouterTransactCallMaxWeight: frame_support::weights::Weight = frame_support::weights::Weight::from_parts(200_000_000, 6144); } +/// Builds an (un)congestion XCM program with the `report_bridge_status` call for +/// `ToRococoXcmRouter`. +pub fn build_congestion_message( + bridge_id: sp_core::H256, + is_congested: bool, +) -> alloc::vec::Vec> { + alloc::vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + fallback_max_weight: Some(XcmBridgeHubRouterTransactCallMaxWeight::get()), + call: Call::ToRococoXcmRouter(XcmBridgeHubRouterCall::report_bridge_status { + bridge_id, + is_congested, + }) + .encode() + .into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ] +} + /// Identifier of AssetHubWestend in the Westend relay chain. pub const ASSET_HUB_WESTEND_PARACHAIN_ID: u32 = 1000; diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 3c4a10f82e7d..ff06a1e3c8c5 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -18,9 +18,9 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{DeliveryFeeFactor, MINIMAL_DELIVERY_FEE_FACTOR}; +use crate::{Bridge, BridgeState, Call, MINIMAL_DELIVERY_FEE_FACTOR}; use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError}; -use frame_support::traits::{Get, Hooks}; +use frame_support::traits::{EnsureOrigin, Get, Hooks, UnfilteredDispatchable}; use sp_runtime::traits::Zero; use xcm::prelude::*; @@ -45,16 +45,35 @@ pub trait Config: crate::Config { benchmarks_instance_pallet! { on_initialize_when_non_congested { - DeliveryFeeFactor::::put(MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR); + Bridge::::put(BridgeState { + is_congested: false, + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR, + }); }: { crate::Pallet::::on_initialize(Zero::zero()) } on_initialize_when_congested { - DeliveryFeeFactor::::put(MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR); + Bridge::::put(BridgeState { + is_congested: false, + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR, + }); let _ = T::ensure_bridged_target_destination()?; T::make_congested(); }: { crate::Pallet::::on_initialize(Zero::zero()) } + + report_bridge_status { + Bridge::::put(BridgeState::default()); + + let origin: T::RuntimeOrigin = T::BridgeHubOrigin::try_successful_origin().expect("expected valid BridgeHubOrigin"); + let bridge_id = Default::default(); + let is_congested = true; + + let call = Call::::report_bridge_status { bridge_id, is_congested }; + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert!(Bridge::::get().is_congested); + } } diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index fe8f5a2efdfb..7361696faba7 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -30,9 +30,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub use bp_xcm_bridge_hub_router::XcmChannelStatusProvider; +pub use bp_xcm_bridge_hub_router::{BridgeState, XcmChannelStatusProvider}; use codec::Encode; use frame_support::traits::Get; +use sp_core::H256; use sp_runtime::{FixedPointNumber, FixedU128, Saturating}; use sp_std::vec::Vec; use xcm::prelude::*; @@ -98,6 +99,8 @@ pub mod pallet { /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; + /// Origin of the sibling bridge hub that is allowed to report bridge status. + type BridgeHubOrigin: EnsureOrigin; /// Actual message sender (`HRMP` or `DMP`) to the sibling bridge hub location. type ToBridgeHubSender: SendXcm; /// Local XCM channel manager. @@ -120,95 +123,112 @@ pub mod pallet { return T::WeightInfo::on_initialize_when_congested() } + // if bridge has reported congestion, we don't change anything + let mut bridge = Self::bridge(); + if bridge.is_congested { + return T::WeightInfo::on_initialize_when_congested() + } + // if we can't decrease the delivery fee factor anymore, we don't change anything - let mut delivery_fee_factor = Self::delivery_fee_factor(); - if delivery_fee_factor == MINIMAL_DELIVERY_FEE_FACTOR { + if bridge.delivery_fee_factor == MINIMAL_DELIVERY_FEE_FACTOR { return T::WeightInfo::on_initialize_when_congested() } - let previous_factor = delivery_fee_factor; - delivery_fee_factor = - MINIMAL_DELIVERY_FEE_FACTOR.max(delivery_fee_factor / EXPONENTIAL_FEE_BASE); + let previous_factor = bridge.delivery_fee_factor; + bridge.delivery_fee_factor = + MINIMAL_DELIVERY_FEE_FACTOR.max(bridge.delivery_fee_factor / EXPONENTIAL_FEE_BASE); + log::info!( target: LOG_TARGET, "Bridge channel is uncongested. Decreased fee factor from {} to {}", previous_factor, - delivery_fee_factor, + bridge.delivery_fee_factor, ); Self::deposit_event(Event::DeliveryFeeFactorDecreased { - new_value: delivery_fee_factor, + new_value: bridge.delivery_fee_factor, }); - DeliveryFeeFactor::::put(delivery_fee_factor); + Bridge::::put(bridge); T::WeightInfo::on_initialize_when_non_congested() } } - /// Initialization value for the delivery fee factor. - #[pallet::type_value] - pub fn InitialFactor() -> FixedU128 { - MINIMAL_DELIVERY_FEE_FACTOR + #[pallet::call] + impl, I: 'static> Pallet { + /// Notification about congested bridge queue. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::report_bridge_status())] + pub fn report_bridge_status( + origin: OriginFor, + // this argument is not currently used, but to ease future migration, we'll keep it + // here + bridge_id: H256, + is_congested: bool, + ) -> DispatchResult { + let _ = T::BridgeHubOrigin::ensure_origin(origin)?; + + log::info!( + target: LOG_TARGET, + "Received bridge status from {:?}: congested = {}", + bridge_id, + is_congested, + ); + + Bridge::::mutate(|bridge| { + bridge.is_congested = is_congested; + }); + Ok(()) + } } - /// The number to multiply the base delivery fee by. + /// Bridge that we are using. /// - /// This factor is shared by all bridges, served by this pallet. For example, if this - /// chain (`Config::UniversalLocation`) opens two bridges ( - /// `X2(GlobalConsensus(Config::BridgedNetworkId::get()), Parachain(1000))` and - /// `X2(GlobalConsensus(Config::BridgedNetworkId::get()), Parachain(2000))`), then they - /// both will be sharing the same fee factor. This is because both bridges are sharing - /// the same local XCM channel with the child/sibling bridge hub, which we are using - /// to detect congestion: - /// - /// ```nocompile - /// ThisChain --- Local XCM channel --> Sibling Bridge Hub ------ - /// | | - /// | | - /// | | - /// Lane1 Lane2 - /// | | - /// | | - /// | | - /// \ / | - /// Parachain1 <-- Local XCM channel --- Remote Bridge Hub <------ - /// | - /// | - /// Parachain1 <-- Local XCM channel --------- - /// ``` - /// - /// If at least one of other channels is congested, the local XCM channel with sibling - /// bridge hub eventually becomes congested too. And we have no means to detect - which - /// bridge exactly causes the congestion. So the best solution here is not to make - /// any differences between all bridges, started by this chain. + /// **bridges-v1** assumptions: all outbound messages through this router are using single lane + /// and to single remote consensus. If there is some other remote consensus that uses the same + /// bridge hub, the separate pallet instance shall be used, In `v2` we'll have all required + /// primitives (lane-id aka bridge-id, derived from XCM locations) to support multiple bridges + /// by the same pallet instance. #[pallet::storage] - #[pallet::getter(fn delivery_fee_factor)] - pub type DeliveryFeeFactor, I: 'static = ()> = - StorageValue<_, FixedU128, ValueQuery, InitialFactor>; + #[pallet::getter(fn bridge)] + pub type Bridge, I: 'static = ()> = StorageValue<_, BridgeState, ValueQuery>; impl, I: 'static> Pallet { /// Called when new message is sent (queued to local outbound XCM queue) over the bridge. pub(crate) fn on_message_sent_to_bridge(message_size: u32) { - // if outbound channel is not congested, do nothing - if !T::LocalXcmChannelManager::is_congested(&T::SiblingBridgeHubLocation::get()) { - return - } + log::trace!( + target: LOG_TARGET, + "on_message_sent_to_bridge - message_size: {message_size:?}", + ); + let _ = Bridge::::try_mutate(|bridge| { + let is_channel_with_bridge_hub_congested = + T::LocalXcmChannelManager::is_congested(&T::SiblingBridgeHubLocation::get()); + let is_bridge_congested = bridge.is_congested; + + // if outbound queue is not congested AND bridge has not reported congestion, do + // nothing + if !is_channel_with_bridge_hub_congested && !is_bridge_congested { + return Err(()) + } + + // ok - we need to increase the fee factor, let's do that + let message_size_factor = FixedU128::from_u32(message_size.saturating_div(1024)) + .saturating_mul(MESSAGE_SIZE_FEE_BASE); + let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); + let previous_factor = bridge.delivery_fee_factor; + bridge.delivery_fee_factor = + bridge.delivery_fee_factor.saturating_mul(total_factor); - // ok - we need to increase the fee factor, let's do that - let message_size_factor = FixedU128::from_u32(message_size.saturating_div(1024)) - .saturating_mul(MESSAGE_SIZE_FEE_BASE); - let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); - DeliveryFeeFactor::::mutate(|f| { - let previous_factor = *f; - *f = f.saturating_mul(total_factor); log::info!( target: LOG_TARGET, "Bridge channel is congested. Increased fee factor from {} to {}", previous_factor, - f, + bridge.delivery_fee_factor, ); - Self::deposit_event(Event::DeliveryFeeFactorIncreased { new_value: *f }); - *f + Self::deposit_event(Event::DeliveryFeeFactorIncreased { + new_value: bridge.delivery_fee_factor, + }); + Ok(()) }); } } @@ -310,9 +330,9 @@ impl, I: 'static> ExporterFor for Pallet { let message_size = message.encoded_size(); let message_fee = (message_size as u128).saturating_mul(T::ByteFee::get()); let fee_sum = base_fee.saturating_add(message_fee); - - let fee_factor = Self::delivery_fee_factor(); + let fee_factor = Self::bridge().delivery_fee_factor; let fee = fee_factor.saturating_mul_int(fee_sum); + let fee = if fee > 0 { Some((T::FeeAsset::get(), fee).into()) } else { None }; log::info!( @@ -427,24 +447,47 @@ mod tests { use frame_system::{EventRecord, Phase}; use sp_runtime::traits::One; + fn congested_bridge(delivery_fee_factor: FixedU128) -> BridgeState { + BridgeState { is_congested: true, delivery_fee_factor } + } + + fn uncongested_bridge(delivery_fee_factor: FixedU128) -> BridgeState { + BridgeState { is_congested: false, delivery_fee_factor } + } + #[test] fn initial_fee_factor_is_one() { run_test(|| { - assert_eq!(DeliveryFeeFactor::::get(), MINIMAL_DELIVERY_FEE_FACTOR); + assert_eq!( + Bridge::::get(), + uncongested_bridge(MINIMAL_DELIVERY_FEE_FACTOR), + ); }) } #[test] fn fee_factor_is_not_decreased_from_on_initialize_when_xcm_channel_is_congested() { run_test(|| { - DeliveryFeeFactor::::put(FixedU128::from_rational(125, 100)); + Bridge::::put(uncongested_bridge(FixedU128::from_rational(125, 100))); TestLocalXcmChannelManager::make_congested(&SiblingBridgeHubLocation::get()); // it should not decrease, because queue is congested - let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor(); + let old_delivery = XcmBridgeHubRouter::bridge(); XcmBridgeHubRouter::on_initialize(One::one()); - assert_eq!(XcmBridgeHubRouter::delivery_fee_factor(), old_delivery_fee_factor); + assert_eq!(XcmBridgeHubRouter::bridge(), old_delivery); + assert_eq!(System::events(), vec![]); + }) + } + + #[test] + fn fee_factor_is_not_decreased_from_on_initialize_when_bridge_has_reported_congestion() { + run_test(|| { + Bridge::::put(congested_bridge(FixedU128::from_rational(125, 100))); + // it should not decrease, because bridge congested + let old_bridge = XcmBridgeHubRouter::bridge(); + XcmBridgeHubRouter::on_initialize(One::one()); + assert_eq!(XcmBridgeHubRouter::bridge(), old_bridge); assert_eq!(System::events(), vec![]); }) } @@ -453,16 +496,19 @@ mod tests { fn fee_factor_is_decreased_from_on_initialize_when_xcm_channel_is_uncongested() { run_test(|| { let initial_fee_factor = FixedU128::from_rational(125, 100); - DeliveryFeeFactor::::put(initial_fee_factor); + Bridge::::put(uncongested_bridge(initial_fee_factor)); - // it shold eventually decreased to one - while XcmBridgeHubRouter::delivery_fee_factor() > MINIMAL_DELIVERY_FEE_FACTOR { + // it should eventually decrease to one + while XcmBridgeHubRouter::bridge().delivery_fee_factor > MINIMAL_DELIVERY_FEE_FACTOR { XcmBridgeHubRouter::on_initialize(One::one()); } - // verify that it doesn't decreases anymore + // verify that it doesn't decrease anymore XcmBridgeHubRouter::on_initialize(One::one()); - assert_eq!(XcmBridgeHubRouter::delivery_fee_factor(), MINIMAL_DELIVERY_FEE_FACTOR); + assert_eq!( + XcmBridgeHubRouter::bridge(), + uncongested_bridge(MINIMAL_DELIVERY_FEE_FACTOR) + ); // check emitted event let first_system_event = System::events().first().cloned(); @@ -582,7 +628,7 @@ mod tests { // but when factor is larger than one, it increases the fee, so it becomes: // `(BASE_FEE + BYTE_FEE * msg_size) * F + HRMP_FEE` let factor = FixedU128::from_rational(125, 100); - DeliveryFeeFactor::::put(factor); + Bridge::::put(uncongested_bridge(factor)); let expected_fee = (FixedU128::saturating_from_integer(BASE_FEE + BYTE_FEE * (msg_size as u128)) * factor) @@ -598,7 +644,7 @@ mod tests { #[test] fn sent_message_doesnt_increase_factor_if_queue_is_uncongested() { run_test(|| { - let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor(); + let old_bridge = XcmBridgeHubRouter::bridge(); assert_eq!( send_xcm::( Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), @@ -609,7 +655,7 @@ mod tests { ); assert!(TestToBridgeHubSender::is_message_sent()); - assert_eq!(old_delivery_fee_factor, XcmBridgeHubRouter::delivery_fee_factor()); + assert_eq!(old_bridge, XcmBridgeHubRouter::bridge()); assert_eq!(System::events(), vec![]); }); @@ -620,7 +666,39 @@ mod tests { run_test(|| { TestLocalXcmChannelManager::make_congested(&SiblingBridgeHubLocation::get()); - let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor(); + let old_bridge = XcmBridgeHubRouter::bridge(); + assert_ok!(send_xcm::( + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), + vec![ClearOrigin].into(), + ) + .map(drop)); + + assert!(TestToBridgeHubSender::is_message_sent()); + assert!( + old_bridge.delivery_fee_factor < XcmBridgeHubRouter::bridge().delivery_fee_factor + ); + + // check emitted event + let first_system_event = System::events().first().cloned(); + assert!(matches!( + first_system_event, + Some(EventRecord { + phase: Phase::Initialization, + event: RuntimeEvent::XcmBridgeHubRouter( + Event::DeliveryFeeFactorIncreased { .. } + ), + .. + }) + )); + }); + } + + #[test] + fn sent_message_increases_factor_if_bridge_has_reported_congestion() { + run_test(|| { + Bridge::::put(congested_bridge(MINIMAL_DELIVERY_FEE_FACTOR)); + + let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), @@ -628,7 +706,9 @@ mod tests { .map(drop)); assert!(TestToBridgeHubSender::is_message_sent()); - assert!(old_delivery_fee_factor < XcmBridgeHubRouter::delivery_fee_factor()); + assert!( + old_bridge.delivery_fee_factor < XcmBridgeHubRouter::bridge().delivery_fee_factor + ); // check emitted event let first_system_event = System::events().first().cloned(); diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 095572883920..ac642e108c2a 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -80,6 +80,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type DestinationVersion = LatestOrNoneForLocationVersionChecker>; + type BridgeHubOrigin = frame_system::EnsureRoot; type ToBridgeHubSender = TestToBridgeHubSender; type LocalXcmChannelManager = TestLocalXcmChannelManager; diff --git a/bridges/modules/xcm-bridge-hub-router/src/weights.rs b/bridges/modules/xcm-bridge-hub-router/src/weights.rs index d9a0426fecaf..8f5012c9de26 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/weights.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/weights.rs @@ -52,6 +52,7 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn on_initialize_when_non_congested() -> Weight; fn on_initialize_when_congested() -> Weight; + fn report_bridge_status() -> Weight; } /// Weights for `pallet_xcm_bridge_hub_router` that are generated using one of the Bridge testnets. @@ -85,6 +86,19 @@ impl WeightInfo for BridgeWeight { // Minimum execution time: 4_239 nanoseconds. Weight::from_parts(4_383_000, 3547).saturating_add(T::DbWeight::get().reads(1_u64)) } + /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) + /// + /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: + /// 512, mode: `MaxEncodedLen`) + fn report_bridge_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `53` + // Estimated: `1502` + // Minimum execution time: 10_427 nanoseconds. + Weight::from_parts(10_682_000, 1502) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } } // For backwards compatibility and tests @@ -120,4 +134,17 @@ impl WeightInfo for () { // Minimum execution time: 4_239 nanoseconds. Weight::from_parts(4_383_000, 3547).saturating_add(RocksDbWeight::get().reads(1_u64)) } + /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) + /// + /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: + /// 512, mode: `MaxEncodedLen`) + fn report_bridge_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `53` + // Estimated: `1502` + // Minimum execution time: 10_427 nanoseconds. + Weight::from_parts(10_682_000, 1502) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } } diff --git a/bridges/modules/xcm-bridge-hub/Cargo.toml b/bridges/modules/xcm-bridge-hub/Cargo.toml index fe58b910a94e..251dcfb45bcb 100644 --- a/bridges/modules/xcm-bridge-hub/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub/Cargo.toml @@ -39,6 +39,7 @@ sp-io = { workspace = true } bp-runtime = { workspace = true } bp-header-chain = { workspace = true } pallet-xcm-bridge-hub-router = { workspace = true } +bp-xcm-bridge-hub-router = { workspace = true } polkadot-parachain-primitives = { workspace = true } [features] @@ -47,6 +48,7 @@ std = [ "bp-header-chain/std", "bp-messages/std", "bp-runtime/std", + "bp-xcm-bridge-hub-router/std", "bp-xcm-bridge-hub/std", "codec/std", "frame-support/std", diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 5afb9f36bc94..93b6093b42af 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -364,7 +364,7 @@ mod tests { use bp_runtime::RangeInclusiveExt; use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState}; - use frame_support::assert_ok; + use frame_support::{assert_ok, traits::EnsureOrigin}; use pallet_bridge_messages::InboundLaneStorage; use xcm_builder::{NetworkExportTable, UnpaidRemoteExporter}; use xcm_executor::traits::{export_xcm, ConvertLocation}; @@ -381,9 +381,8 @@ mod tests { BridgedUniversalDestination::get() } - fn open_lane() -> (BridgeLocations, TestLaneIdType) { + fn open_lane(origin: RuntimeOrigin) -> (BridgeLocations, TestLaneIdType) { // open expected outbound lane - let origin = OpenBridgeOrigin::sibling_parachain_origin(); let with = bridged_asset_hub_universal_location(); let locations = XcmOverBridge::bridge_locations_from_origin(origin, Box::new(with.into())).unwrap(); @@ -439,7 +438,7 @@ mod tests { } fn open_lane_and_send_regular_message() -> (BridgeId, TestLaneIdType) { - let (locations, lane_id) = open_lane(); + let (locations, lane_id) = open_lane(OpenBridgeOrigin::sibling_parachain_origin()); // now let's try to enqueue message using our `ExportXcm` implementation export_xcm::( @@ -473,7 +472,7 @@ mod tests { fn exporter_does_not_suspend_the_bridge_if_outbound_bridge_queue_is_not_congested() { run_test(|| { let (bridge_id, _) = open_lane_and_send_regular_message(); - assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(!TestLocalXcmChannelManager::is_bridge_suspended(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -490,7 +489,7 @@ mod tests { } open_lane_and_send_regular_message(); - assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(!TestLocalXcmChannelManager::is_bridge_suspended(&bridge_id)); }); } @@ -502,11 +501,11 @@ mod tests { open_lane_and_send_regular_message(); } - assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(!TestLocalXcmChannelManager::is_bridge_suspended(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); open_lane_and_send_regular_message(); - assert!(TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(TestLocalXcmChannelManager::is_bridge_suspended(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); }); } @@ -523,7 +522,7 @@ mod tests { OUTBOUND_LANE_UNCONGESTED_THRESHOLD + 1, ); - assert!(!TestLocalXcmChannelManager::is_bridge_resumed()); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); }); } @@ -537,7 +536,7 @@ mod tests { OUTBOUND_LANE_UNCONGESTED_THRESHOLD, ); - assert!(!TestLocalXcmChannelManager::is_bridge_resumed()); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -554,7 +553,7 @@ mod tests { OUTBOUND_LANE_UNCONGESTED_THRESHOLD, ); - assert!(TestLocalXcmChannelManager::is_bridge_resumed()); + assert!(TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -648,7 +647,10 @@ mod tests { let dest = Location::new(2, BridgedUniversalDestination::get()); // open bridge - let (_, expected_lane_id) = open_lane(); + let origin = OpenBridgeOrigin::sibling_parachain_origin(); + let origin_as_location = + OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); + let (_, expected_lane_id) = open_lane(origin); // check before - no messages assert_eq!( @@ -662,18 +664,24 @@ mod tests { ); // send `ExportMessage(message)` by `UnpaidRemoteExporter`. - TestExportXcmWithXcmOverBridge::set_origin_for_execute(SiblingLocation::get()); + ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location); assert_ok!(send_xcm::< UnpaidRemoteExporter< NetworkExportTable, - TestExportXcmWithXcmOverBridge, + ExecuteXcmOverSendXcm, UniversalLocation, >, >(dest.clone(), Xcm::<()>::default())); + // we need to set `UniversalLocation` for `sibling_parachain_origin` for + // `XcmOverBridgeWrappedWithExportMessageRouterInstance`. + ExportMessageOriginUniversalLocation::set(Some(SiblingUniversalLocation::get())); // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. - TestExportXcmWithXcmOverBridge::set_origin_for_execute(SiblingLocation::get()); - assert_ok!(send_xcm::(dest.clone(), Xcm::<()>::default())); + ExecuteXcmOverSendXcm::set_origin_for_execute(SiblingLocation::get()); + assert_ok!(send_xcm::( + dest.clone(), + Xcm::<()>::default() + )); // check after - a message ready to be relayed assert_eq!( @@ -765,7 +773,7 @@ mod tests { ); // ok - let _ = open_lane(); + let _ = open_lane(OpenBridgeOrigin::sibling_parachain_origin()); let mut dest_wrapper = Some(bridged_relative_destination()); assert_ok!(XcmOverBridge::validate( BridgedRelayNetwork::get(), @@ -780,4 +788,77 @@ mod tests { assert_eq!(None, dest_wrapper); }); } + + #[test] + fn congestion_with_pallet_xcm_bridge_hub_router_works() { + run_test(|| { + // valid routable destination + let dest = Location::new(2, BridgedUniversalDestination::get()); + + fn router_bridge_state() -> pallet_xcm_bridge_hub_router::BridgeState { + pallet_xcm_bridge_hub_router::Bridge::< + TestRuntime, + XcmOverBridgeWrappedWithExportMessageRouterInstance, + >::get() + } + + // open two bridges + let origin = OpenBridgeOrigin::sibling_parachain_origin(); + let origin_as_location = + OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); + let (bridge_1, expected_lane_id_1) = open_lane(origin); + + // we need to set `UniversalLocation` for `sibling_parachain_origin` for + // `XcmOverBridgeWrappedWithExportMessageRouterInstance`. + ExportMessageOriginUniversalLocation::set(Some(SiblingUniversalLocation::get())); + + // check before + // bridges are opened + assert_eq!( + XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, + BridgeState::Opened + ); + + // the router is uncongested + assert!(!router_bridge_state().is_congested); + assert!(!TestLocalXcmChannelManager::is_bridge_suspended(bridge_1.bridge_id())); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); + + // make bridges congested with sending too much messages + for _ in 1..(OUTBOUND_LANE_CONGESTED_THRESHOLD + 2) { + // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. + ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location.clone()); + assert_ok!(send_xcm::( + dest.clone(), + Xcm::<()>::default() + )); + } + + // checks after + // bridges are suspended + assert_eq!( + XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, + BridgeState::Suspended, + ); + // the router is congested + assert!(router_bridge_state().is_congested); + assert!(TestLocalXcmChannelManager::is_bridge_suspended(bridge_1.bridge_id())); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); + + // make bridges uncongested to trigger resume signal + XcmOverBridge::on_bridge_messages_delivered( + expected_lane_id_1, + OUTBOUND_LANE_UNCONGESTED_THRESHOLD, + ); + + // bridge is again opened + assert_eq!( + XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, + BridgeState::Opened + ); + // the router is uncongested + assert!(!router_bridge_state().is_congested); + assert!(TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); + }) + } } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 1b2536598a20..682db811efa7 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -145,8 +145,8 @@ use bp_messages::{LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; -pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; -use bp_xcm_bridge_hub::{BridgeLocations, BridgeLocationsError, LocalXcmChannelManager}; +pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState, LocalXcmChannelManager}; +use bp_xcm_bridge_hub::{BridgeLocations, BridgeLocationsError}; use frame_support::{traits::fungible::MutateHold, DefaultNoBound}; use frame_system::Config as SystemConfig; use pallet_bridge_messages::{Config as BridgeMessagesConfig, LanesManagerError}; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 9f06b99ef6d5..d186507dab17 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -24,10 +24,10 @@ use bp_messages::{ }; use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf}; use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager}; -use codec::Encode; +use codec::{Decode, Encode}; use frame_support::{ assert_ok, derive_impl, parameter_types, - traits::{EnsureOrigin, Equals, Everything, OriginTrait}, + traits::{EnsureOrigin, Equals, Everything, Get, OriginTrait}, weights::RuntimeDbWeight, }; use polkadot_parachain_primitives::primitives::Sibling; @@ -44,7 +44,7 @@ use xcm_builder::{ InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, SiblingParachainConvertsVia, }; -use xcm_executor::XcmExecutor; +use xcm_executor::{traits::ConvertOrigin, XcmExecutor}; pub type AccountId = AccountId32; pub type Balance = u64; @@ -63,7 +63,7 @@ frame_support::construct_runtime! { Balances: pallet_balances::{Pallet, Event}, Messages: pallet_bridge_messages::{Pallet, Call, Event}, XcmOverBridge: pallet_xcm_bridge_hub::{Pallet, Call, HoldReason, Event}, - XcmOverBridgeRouter: pallet_xcm_bridge_hub_router, + XcmOverBridgeWrappedWithExportMessageRouter: pallet_xcm_bridge_hub_router = 57, } } @@ -208,17 +208,27 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type BlobDispatcher = TestBlobDispatcher; } -impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { +/// A router instance simulates a scenario where the router is deployed on a different chain than +/// the `MessageExporter`. This means that the router sends an `ExportMessage`. +pub type XcmOverBridgeWrappedWithExportMessageRouterInstance = (); +impl pallet_xcm_bridge_hub_router::Config + for TestRuntime +{ type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type UniversalLocation = UniversalLocation; + type UniversalLocation = ExportMessageOriginUniversalLocation; type SiblingBridgeHubLocation = BridgeHubLocation; type BridgedNetworkId = BridgedRelayNetwork; type Bridges = NetworkExportTable; type DestinationVersion = AlwaysLatest; - type ToBridgeHubSender = TestExportXcmWithXcmOverBridge; + // We convert to root `here` location with `BridgeHubLocationXcmOriginAsRoot` + type BridgeHubOrigin = frame_system::EnsureRoot; + // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which + // calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the + // `MessageExporter`. + type ToBridgeHubSender = ExecuteXcmOverSendXcm; type LocalXcmChannelManager = TestLocalXcmChannelManager; type ByteFee = ConstU128<0>; @@ -230,7 +240,7 @@ impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; type XcmSender = (); type AssetTransactor = (); - type OriginConverter = (); + type OriginConverter = BridgeHubLocationXcmOriginAsRoot; type IsReserve = (); type IsTeleporter = (); type UniversalLocation = UniversalLocation; @@ -270,8 +280,8 @@ thread_local! { /// /// Note: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which calls the /// `ExportXcm` implementation of `pallet_xcm_bridge_hub` as `MessageExporter`. -pub struct TestExportXcmWithXcmOverBridge; -impl SendXcm for TestExportXcmWithXcmOverBridge { +pub struct ExecuteXcmOverSendXcm; +impl SendXcm for ExecuteXcmOverSendXcm { type Ticket = Xcm<()>; fn validate( @@ -298,7 +308,7 @@ impl SendXcm for TestExportXcmWithXcmOverBridge { Ok(hash) } } -impl InspectMessageQueues for TestExportXcmWithXcmOverBridge { +impl InspectMessageQueues for ExecuteXcmOverSendXcm { fn clear_messages() { todo!() } @@ -307,12 +317,51 @@ impl InspectMessageQueues for TestExportXcmWithXcmOverBridge { todo!() } } -impl TestExportXcmWithXcmOverBridge { +impl ExecuteXcmOverSendXcm { pub fn set_origin_for_execute(origin: Location) { EXECUTE_XCM_ORIGIN.with(|o| *o.borrow_mut() = Some(origin)); } } +/// A dynamic way to set different universal location for the origin which sends `ExportMessage`. +pub struct ExportMessageOriginUniversalLocation; +impl ExportMessageOriginUniversalLocation { + pub(crate) fn set(universal_location: Option) { + EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION.with(|o| *o.borrow_mut() = universal_location); + } +} +impl Get for ExportMessageOriginUniversalLocation { + fn get() -> InteriorLocation { + EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION.with(|o| { + o.borrow() + .clone() + .expect("`EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION` is not set!") + }) + } +} +thread_local! { + pub static EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION: RefCell> = RefCell::new(None); +} + +pub struct BridgeHubLocationXcmOriginAsRoot( + sp_std::marker::PhantomData, +); +impl ConvertOrigin + for BridgeHubLocationXcmOriginAsRoot +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + if kind == OriginKind::Xcm && origin.eq(&BridgeHubLocation::get()) { + Ok(RuntimeOrigin::root()) + } else { + Err(origin) + } + } +} + /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. @@ -396,6 +445,9 @@ impl EnsureOrigin for OpenBridgeOrigin { } } +pub(crate) type OpenBridgeOriginOf = + >::OpenBridgeOrigin; + pub struct TestLocalXcmChannelManager; impl TestLocalXcmChannelManager { @@ -403,30 +455,82 @@ impl TestLocalXcmChannelManager { frame_support::storage::unhashed::put(b"TestLocalXcmChannelManager.Congested", &true); } - pub fn is_bridge_suspened() -> bool { - frame_support::storage::unhashed::get_or_default(b"TestLocalXcmChannelManager.Suspended") + fn suspended_key(bridge: &BridgeId) -> Vec { + [b"TestLocalXcmChannelManager.Suspended", bridge.encode().as_slice()].concat() + } + fn resumed_key(bridge: &BridgeId) -> Vec { + [b"TestLocalXcmChannelManager.Resumed", bridge.encode().as_slice()].concat() + } + + pub fn is_bridge_suspended(bridge: &BridgeId) -> bool { + frame_support::storage::unhashed::get_or_default(&Self::suspended_key(bridge)) } - pub fn is_bridge_resumed() -> bool { - frame_support::storage::unhashed::get_or_default(b"TestLocalXcmChannelManager.Resumed") + pub fn is_bridge_resumed(bridge: &BridgeId) -> bool { + frame_support::storage::unhashed::get_or_default(&Self::resumed_key(bridge)) + } + + fn build_congestion_message(bridge: &BridgeId, is_congested: bool) -> Vec> { + use bp_xcm_bridge_hub_router::XcmBridgeHubRouterCall; + #[allow(clippy::large_enum_variant)] + #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, scale_info::TypeInfo)] + enum Call { + #[codec(index = 57)] + XcmOverBridgeWrappedWithExportMessageRouter(XcmBridgeHubRouterCall), + } + + sp_std::vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + fallback_max_weight: None, + call: Call::XcmOverBridgeWrappedWithExportMessageRouter( + XcmBridgeHubRouterCall::report_bridge_status { + bridge_id: bridge.inner(), + is_congested, + } + ) + .encode() + .into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ] + } + + fn report_bridge_status( + local_origin: &Location, + bridge: &BridgeId, + is_congested: bool, + key: Vec, + ) -> Result<(), SendError> { + // send as BridgeHub would send to sibling chain + ExecuteXcmOverSendXcm::set_origin_for_execute(BridgeHubLocation::get()); + let result = send_xcm::( + local_origin.clone(), + Self::build_congestion_message(&bridge, is_congested).into(), + ); + + if result.is_ok() { + frame_support::storage::unhashed::put(&key, &true); + } + + result.map(|_| ()) } } impl LocalXcmChannelManager for TestLocalXcmChannelManager { - type Error = (); + type Error = SendError; fn is_congested(_with: &Location) -> bool { frame_support::storage::unhashed::get_or_default(b"TestLocalXcmChannelManager.Congested") } - fn suspend_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> { - frame_support::storage::unhashed::put(b"TestLocalXcmChannelManager.Suspended", &true); - Ok(()) + fn suspend_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + Self::report_bridge_status(local_origin, &bridge, true, Self::suspended_key(&bridge)) } - fn resume_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> { - frame_support::storage::unhashed::put(b"TestLocalXcmChannelManager.Resumed", &true); - Ok(()) + fn resume_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + Self::report_bridge_status(local_origin, &bridge, false, Self::resumed_key(&bridge)) } } diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 63beb1bc3041..471cf402c34f 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -87,6 +87,11 @@ impl BridgeId { .into(), ) } + + /// Access the inner representation. + pub fn inner(&self) -> H256 { + self.0 + } } impl core::fmt::Debug for BridgeId { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index b6f3ccd3901b..7e1fb247ad3c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -62,7 +62,8 @@ use frame_support::{ ord_parameter_types, parameter_types, traits::{ fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool, - ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, InstanceFilter, TransformOrigin, + ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, + TransformOrigin, }, weights::{ConstantMultiplier, Weight, WeightToFee as _}, BoundedVec, PalletId, @@ -936,6 +937,10 @@ impl pallet_xcm_bridge_hub_router::Config for Runtim type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; + type BridgeHubOrigin = frame_support::traits::EitherOfDiverse< + EnsureRoot, + EnsureXcm>, + >; type ToBridgeHubSender = XcmpQueue; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs index 00ecf239428f..9a75428ada8b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-acd6uxux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -52,14 +52,14 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - /// Storage: `ToWestendXcmRouter::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `ToWestendXcmRouter::DeliveryFeeFactor` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `ToWestendXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToWestendXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) fn on_initialize_when_non_congested() -> Weight { // Proof Size summary in bytes: - // Measured: `153` + // Measured: `154` // Estimated: `5487` - // Minimum execution time: 12_993_000 picoseconds. - Weight::from_parts(13_428_000, 0) + // Minimum execution time: 13_884_000 picoseconds. + Weight::from_parts(14_312_000, 0) .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -72,9 +72,21 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `144` // Estimated: `5487` - // Minimum execution time: 6_305_000 picoseconds. - Weight::from_parts(6_536_000, 0) + // Minimum execution time: 6_909_000 picoseconds. + Weight::from_parts(7_115_000, 0) .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(2)) } + /// Storage: `ToWestendXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToWestendXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + fn report_bridge_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `150` + // Estimated: `1502` + // Minimum execution time: 12_394_000 picoseconds. + Weight::from_parts(12_883_000, 0) + .saturating_add(Weight::from_parts(0, 1502)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index d056405adff8..144934ecd4ab 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -27,7 +27,8 @@ use asset_hub_rococo_runtime::{ AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, Block, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, SessionKeys, TrustBackedAssetsInstance, XcmpQueue, + RuntimeEvent, RuntimeOrigin, SessionKeys, ToWestendXcmRouterInstance, + TrustBackedAssetsInstance, XcmpQueue, }; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, @@ -1242,6 +1243,58 @@ mod asset_hub_rococo_tests { ) } + #[test] + fn report_bridge_status_from_xcm_bridge_router_for_westend_works() { + asset_test_utils::test_cases_over_bridge::report_bridge_status_from_xcm_bridge_router_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ToWestendXcmRouterInstance, + >( + collator_session_keys(), + bridging_to_asset_hub_westend, + || bp_asset_hub_rococo::build_congestion_message(Default::default(), true).into(), + || bp_asset_hub_rococo::build_congestion_message(Default::default(), false).into(), + ) + } + + #[test] + fn test_report_bridge_status_call_compatibility() { + // if this test fails, make sure `bp_asset_hub_rococo` has valid encoding + assert_eq!( + RuntimeCall::ToWestendXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + } + ) + .encode(), + bp_asset_hub_rococo::Call::ToWestendXcmRouter( + bp_asset_hub_rococo::XcmBridgeHubRouterCall::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + } + ) + .encode() + ); + } + + #[test] + fn check_sane_weight_report_bridge_status_for_westend() { + use pallet_xcm_bridge_hub_router::WeightInfo; + let actual = >::WeightInfo::report_bridge_status(); + let max_weight = bp_asset_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(); + assert!( + actual.all_lte(max_weight), + "max_weight: {:?} should be adjusted to actual {:?}", + max_weight, + actual + ); + } + #[test] fn reserve_transfer_native_asset_to_non_teleport_para_works() { asset_test_utils::test_cases::reserve_transfer_native_asset_to_non_teleport_para_works::< diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 21368e9c2b4b..ffd54ce4c8ac 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -46,8 +46,8 @@ use frame_support::{ traits::{ fungible, fungibles, tokens::{imbalance::ResolveAssetTo, nonfungibles_v2::Inspect}, - AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, InstanceFilter, - Nothing, TransformOrigin, + AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, Equals, + InstanceFilter, Nothing, TransformOrigin, }, weights::{ConstantMultiplier, Weight, WeightToFee as _}, BoundedVec, PalletId, @@ -59,6 +59,7 @@ use frame_system::{ use pallet_asset_conversion_tx_payment::SwapAssetAdapter; use pallet_nfts::{DestroyWitness, PalletFeatures}; use pallet_revive::{evm::runtime::EthExtra, AddressMapper}; +use pallet_xcm::EnsureXcm; use parachains_common::{ impls::DealWithFees, message_queue::*, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, @@ -930,6 +931,10 @@ impl pallet_xcm_bridge_hub_router::Config for Runtime type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; + type BridgeHubOrigin = frame_support::traits::EitherOfDiverse< + EnsureRoot, + EnsureXcm>, + >; type ToBridgeHubSender = XcmpQueue; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs index c0898012e9f3..78aa839deacd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-acd6uxux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -52,14 +52,14 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh /// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - /// Storage: `ToRococoXcmRouter::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `ToRococoXcmRouter::DeliveryFeeFactor` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `ToRococoXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToRococoXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) fn on_initialize_when_non_congested() -> Weight { // Proof Size summary in bytes: - // Measured: `225` + // Measured: `259` // Estimated: `5487` - // Minimum execution time: 13_483_000 picoseconds. - Weight::from_parts(13_862_000, 0) + // Minimum execution time: 14_643_000 picoseconds. + Weight::from_parts(14_992_000, 0) .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -70,11 +70,23 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) fn on_initialize_when_congested() -> Weight { // Proof Size summary in bytes: - // Measured: `111` + // Measured: `144` // Estimated: `5487` - // Minimum execution time: 5_078_000 picoseconds. - Weight::from_parts(5_233_000, 0) + // Minimum execution time: 5_367_000 picoseconds. + Weight::from_parts(5_604_000, 0) .saturating_add(Weight::from_parts(0, 5487)) .saturating_add(T::DbWeight::get().reads(2)) } + /// Storage: `ToRococoXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToRococoXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + fn report_bridge_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `150` + // Estimated: `1502` + // Minimum execution time: 12_562_000 picoseconds. + Weight::from_parts(12_991_000, 0) + .saturating_add(Weight::from_parts(0, 1502)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 109a5dd2c029..24b6d83ffae4 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -27,7 +27,7 @@ use asset_hub_westend_runtime::{ AllPalletsWithoutSystem, Assets, Balances, Block, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, - TrustBackedAssetsInstance, XcmpQueue, + ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, }; pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ @@ -1250,6 +1250,56 @@ fn receive_reserve_asset_deposited_roc_from_asset_hub_rococo_fees_paid_by_suffic ) } +#[test] +fn report_bridge_status_from_xcm_bridge_router_for_rococo_works() { + asset_test_utils::test_cases_over_bridge::report_bridge_status_from_xcm_bridge_router_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ToRococoXcmRouterInstance, + >( + collator_session_keys(), + bridging_to_asset_hub_rococo, + || bp_asset_hub_westend::build_congestion_message(Default::default(), true).into(), + || bp_asset_hub_westend::build_congestion_message(Default::default(), false).into(), + ) +} + +#[test] +fn test_report_bridge_status_call_compatibility() { + // if this test fails, make sure `bp_asset_hub_rococo` has valid encoding + assert_eq!( + RuntimeCall::ToRococoXcmRouter(pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + }) + .encode(), + bp_asset_hub_westend::Call::ToRococoXcmRouter( + bp_asset_hub_westend::XcmBridgeHubRouterCall::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + } + ) + .encode() + ) +} + +#[test] +fn check_sane_weight_report_bridge_status() { + use pallet_xcm_bridge_hub_router::WeightInfo; + let actual = >::WeightInfo::report_bridge_status(); + let max_weight = bp_asset_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(); + assert!( + actual.all_lte(max_weight), + "max_weight: {:?} should be adjusted to actual {:?}", + max_weight, + actual + ); +} + #[test] fn change_xcm_bridge_hub_router_byte_fee_by_governance_works() { asset_test_utils::test_cases::change_storage_constant_by_governance_works::< diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 4f144e24aa30..9b05f2d46dfb 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -551,10 +551,7 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< Weight::zero(), ); assert_ok!(outcome.ensure_complete()); - assert_eq!( - is_congested, - <>::LocalXcmChannelManager as pallet_xcm_bridge_hub_router::XcmChannelStatusProvider>::is_congested(&local_bridge_hub_location) - ); + assert_eq!(is_congested, pallet_xcm_bridge_hub_router::Pallet::::bridge().is_congested); }; report_bridge_status(true); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index a7710783a1e0..c0d6db5ad500 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -98,6 +98,7 @@ bp-relayers = { workspace = true } bp-runtime = { workspace = true } bp-rococo = { workspace = true } bp-westend = { workspace = true } +bp-xcm-bridge-hub-router = { workspace = true } pallet-bridge-grandpa = { workspace = true } pallet-bridge-messages = { workspace = true } pallet-bridge-parachains = { workspace = true } @@ -143,6 +144,7 @@ std = [ "bp-rococo/std", "bp-runtime/std", "bp-westend/std", + "bp-xcm-bridge-hub-router/std", "bridge-hub-common/std", "bridge-runtime-common/std", "codec/std", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 2710d033d64b..a14101eb454b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -24,14 +24,14 @@ use crate::{ weights, xcm_config::UniversalLocation, AccountId, Balance, Balances, BridgeWestendMessages, PolkadotXcm, Runtime, RuntimeEvent, - RuntimeHoldReason, XcmOverBridgeHubWestend, XcmRouter, + RuntimeHoldReason, XcmOverBridgeHubWestend, XcmRouter, XcmpQueue, }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, LegacyLaneId, }; use bridge_hub_common::xcm_version::XcmVersionOfDestAndRemoteBridge; -use pallet_xcm_bridge_hub::XcmAsPlainPayload; +use pallet_xcm_bridge_hub::{BridgeId, XcmAsPlainPayload}; use frame_support::{parameter_types, traits::PalletInfoAccess}; use frame_system::{EnsureNever, EnsureRoot}; @@ -157,11 +157,46 @@ impl pallet_xcm_bridge_hub::Config for Runtime type AllowWithoutBridgeDeposit = RelayOrOtherSystemParachains; - // TODO:(bridges-v2) - add `LocalXcmChannelManager` impl - https://github.com/paritytech/parity-bridges-common/issues/3047 - type LocalXcmChannelManager = (); + type LocalXcmChannelManager = CongestionManager; type BlobDispatcher = FromWestendMessageBlobDispatcher; } +/// Implementation of `bp_xcm_bridge_hub::LocalXcmChannelManager` for congestion management. +pub struct CongestionManager; +impl pallet_xcm_bridge_hub::LocalXcmChannelManager for CongestionManager { + type Error = SendError; + + fn is_congested(with: &Location) -> bool { + // This is used to check the inbound bridge queue/messages to determine if they can be + // dispatched and sent to the sibling parachain. Therefore, checking outbound `XcmpQueue` + // is sufficient here. + use bp_xcm_bridge_hub_router::XcmChannelStatusProvider; + cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider::::is_congested( + with, + ) + } + + fn suspend_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + // This bridge is intended for AH<>AH communication with a hard-coded/static lane, + // so `local_origin` is expected to represent only the local AH. + send_xcm::( + local_origin.clone(), + bp_asset_hub_rococo::build_congestion_message(bridge.inner(), true).into(), + ) + .map(|_| ()) + } + + fn resume_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + // This bridge is intended for AH<>AH communication with a hard-coded/static lane, + // so `local_origin` is expected to represent only the local AH. + send_xcm::( + local_origin.clone(), + bp_asset_hub_rococo::build_congestion_message(bridge.inner(), false).into(), + ) + .map(|_| ()) + } +} + #[cfg(feature = "runtime-benchmarks")] pub(crate) fn open_bridge_for_benchmarks( with: pallet_xcm_bridge_hub::LaneIdOf, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index 91900c830ba6..f429a28a2e52 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -97,6 +97,7 @@ bp-relayers = { workspace = true } bp-runtime = { workspace = true } bp-rococo = { workspace = true } bp-westend = { workspace = true } +bp-xcm-bridge-hub-router = { workspace = true } pallet-bridge-grandpa = { workspace = true } pallet-bridge-messages = { workspace = true } pallet-bridge-parachains = { workspace = true } @@ -140,6 +141,7 @@ std = [ "bp-rococo/std", "bp-runtime/std", "bp-westend/std", + "bp-xcm-bridge-hub-router/std", "bridge-hub-common/std", "bridge-runtime-common/std", "codec/std", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index cd3465513144..24e5482b7b09 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -21,7 +21,7 @@ use crate::{ weights, xcm_config::UniversalLocation, AccountId, Balance, Balances, BridgeRococoMessages, PolkadotXcm, Runtime, RuntimeEvent, - RuntimeHoldReason, XcmOverBridgeHubRococo, XcmRouter, + RuntimeHoldReason, XcmOverBridgeHubRococo, XcmRouter, XcmpQueue, }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, @@ -29,7 +29,7 @@ use bp_messages::{ }; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bridge_hub_common::xcm_version::XcmVersionOfDestAndRemoteBridge; -use pallet_xcm_bridge_hub::XcmAsPlainPayload; +use pallet_xcm_bridge_hub::{BridgeId, XcmAsPlainPayload}; use frame_support::{ parameter_types, @@ -186,11 +186,46 @@ impl pallet_xcm_bridge_hub::Config for Runtime { type AllowWithoutBridgeDeposit = RelayOrOtherSystemParachains; - // TODO:(bridges-v2) - add `LocalXcmChannelManager` impl - https://github.com/paritytech/parity-bridges-common/issues/3047 - type LocalXcmChannelManager = (); + type LocalXcmChannelManager = CongestionManager; type BlobDispatcher = FromRococoMessageBlobDispatcher; } +/// Implementation of `bp_xcm_bridge_hub::LocalXcmChannelManager` for congestion management. +pub struct CongestionManager; +impl pallet_xcm_bridge_hub::LocalXcmChannelManager for CongestionManager { + type Error = SendError; + + fn is_congested(with: &Location) -> bool { + // This is used to check the inbound bridge queue/messages to determine if they can be + // dispatched and sent to the sibling parachain. Therefore, checking outbound `XcmpQueue` + // is sufficient here. + use bp_xcm_bridge_hub_router::XcmChannelStatusProvider; + cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider::::is_congested( + with, + ) + } + + fn suspend_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + // This bridge is intended for AH<>AH communication with a hard-coded/static lane, + // so `local_origin` is expected to represent only the local AH. + send_xcm::( + local_origin.clone(), + bp_asset_hub_westend::build_congestion_message(bridge.inner(), true).into(), + ) + .map(|_| ()) + } + + fn resume_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + // This bridge is intended for AH<>AH communication with a hard-coded/static lane, + // so `local_origin` is expected to represent only the local AH. + send_xcm::( + local_origin.clone(), + bp_asset_hub_westend::build_congestion_message(bridge.inner(), false).into(), + ) + .map(|_| ()) + } +} + #[cfg(feature = "runtime-benchmarks")] pub(crate) fn open_bridge_for_benchmarks( with: pallet_xcm_bridge_hub::LaneIdOf, diff --git a/prdoc/pr_6781.prdoc b/prdoc/pr_6781.prdoc new file mode 100644 index 000000000000..8090be420341 --- /dev/null +++ b/prdoc/pr_6781.prdoc @@ -0,0 +1,28 @@ +title: Bridges - revert-back congestion mechanism + +doc: +- audience: Runtime Dev + description: |- + With [permissionless lanes PR#4949](https://github.com/paritytech/polkadot-sdk/pull/4949), the congestion mechanism based on sending `Transact(report_bridge_status(is_congested))` from `pallet-xcm-bridge-hub` to `pallet-xcm-bridge-hub-router` was replaced with a congestion mechanism that relied on monitoring XCMP queues. However, this approach could cause issues, such as suspending the entire XCMP queue instead of isolating the affected bridge. This PR reverts back to using `report_bridge_status` as before. + +crates: +- name: pallet-xcm-bridge-hub-router + bump: patch +- name: pallet-xcm-bridge-hub + bump: patch +- name: bp-xcm-bridge-hub + bump: patch +- name: bp-asset-hub-rococo + bump: patch +- name: bp-asset-hub-westend + bump: patch +- name: asset-hub-rococo-runtime + bump: patch +- name: asset-hub-westend-runtime + bump: patch +- name: asset-test-utils + bump: patch +- name: bridge-hub-rococo-runtime + bump: patch +- name: bridge-hub-westend-runtime + bump: patch From 311ea43886a875f350726af52ce4a8b0210ba55f Mon Sep 17 00:00:00 2001 From: Joseph Zhao <65984904+programskillforverification@users.noreply.github.com> Date: Tue, 10 Dec 2024 17:30:07 +0800 Subject: [PATCH 32/51] Remove AccountKeyring everywhere (#5899) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close: #5858 --------- Co-authored-by: Bastian Köcher --- Cargo.lock | 32 ++--- .../pallets/inbound-queue/src/test.rs | 2 +- .../snowbridge/runtime/test-common/src/lib.rs | 6 +- .../bridge-hub-rococo/tests/snowbridge.rs | 6 +- .../bridge-hub-rococo/tests/tests.rs | 6 +- .../bridge-hub-westend/tests/snowbridge.rs | 6 +- .../bridge-hub-westend/tests/tests.rs | 6 +- .../src/test_cases/from_grandpa_chain.rs | 8 +- .../src/test_cases/from_parachain.rs | 8 +- .../test-utils/src/test_cases/helpers.rs | 8 +- cumulus/test/client/src/lib.rs | 6 +- .../packages/guides/first-runtime/src/lib.rs | 4 +- .../chain_spec_runtime/src/presets.rs | 6 +- polkadot/node/metrics/src/tests.rs | 2 +- polkadot/node/test/service/src/lib.rs | 4 +- .../adder/collator/tests/integration.rs | 2 +- .../undying/collator/tests/integration.rs | 2 +- polkadot/runtime/rococo/src/tests.rs | 2 +- polkadot/runtime/westend/src/tests.rs | 2 +- prdoc/pr_5899.prdoc | 52 +++++++++ substrate/bin/node/cli/src/service.rs | 6 +- .../basic-authorship/src/basic_authorship.rs | 10 +- substrate/client/basic-authorship/src/lib.rs | 2 +- substrate/client/chain-spec/src/chain_spec.rs | 14 +-- .../client/consensus/manual-seal/src/lib.rs | 2 +- substrate/client/network/test/src/lib.rs | 6 +- .../client/rpc-spec-v2/src/archive/tests.rs | 18 +-- .../rpc-spec-v2/src/chain_head/tests.rs | 46 ++++---- .../tests/transaction_broadcast_tests.rs | 2 +- .../transaction/tests/transaction_tests.rs | 2 +- substrate/client/rpc/src/author/tests.rs | 20 ++-- substrate/client/rpc/src/state/tests.rs | 12 +- substrate/client/service/src/lib.rs | 4 +- .../client/service/test/src/client/mod.rs | 110 +++++++++--------- .../fork_aware_txpool/revalidation_worker.rs | 2 +- .../src/fork_aware_txpool/tx_mem_pool.rs | 2 +- .../client/transaction-pool/src/graph/pool.rs | 2 +- .../src/single_state_txpool/revalidation.rs | 2 +- .../client/transaction-pool/tests/fatp.rs | 2 +- .../transaction-pool/tests/fatp_common/mod.rs | 2 +- .../transaction-pool/tests/fatp_limits.rs | 2 +- .../transaction-pool/tests/fatp_prios.rs | 2 +- .../client/transaction-pool/tests/pool.rs | 2 +- substrate/docs/Upgrading-2.0-to-3.0.md | 4 +- .../authorization-tx-extension/src/tests.rs | 16 +-- substrate/frame/src/lib.rs | 2 +- substrate/frame/support/Cargo.toml | 4 +- .../api/test/tests/runtime_calls.rs | 4 +- substrate/primitives/keyring/src/lib.rs | 9 -- substrate/test-utils/client/src/lib.rs | 4 +- .../test-utils/runtime/client/src/lib.rs | 2 +- .../runtime/client/src/trait_tests.rs | 38 +++--- substrate/test-utils/runtime/src/extrinsic.rs | 8 +- .../test-utils/runtime/src/genesismap.rs | 10 +- substrate/test-utils/runtime/src/lib.rs | 32 ++--- .../runtime/transaction-pool/src/lib.rs | 6 +- substrate/utils/frame/rpc/system/src/lib.rs | 16 +-- templates/minimal/runtime/src/lib.rs | 6 +- .../runtime/src/genesis_config_presets.rs | 18 +-- 59 files changed, 330 insertions(+), 291 deletions(-) create mode 100644 prdoc/pr_5899.prdoc diff --git a/Cargo.lock b/Cargo.lock index 007cd1f05ba7..8aa03954467d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1295,7 +1295,7 @@ dependencies = [ "futures-lite 2.3.0", "parking", "polling 3.4.0", - "rustix 0.38.25", + "rustix 0.38.21", "slab", "tracing", "windows-sys 0.52.0", @@ -1377,7 +1377,7 @@ dependencies = [ "cfg-if", "event-listener 5.3.1", "futures-lite 2.3.0", - "rustix 0.38.25", + "rustix 0.38.21", "tracing", ] @@ -1393,7 +1393,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.25", + "rustix 0.38.21", "signal-hook-registry", "slab", "windows-sys 0.52.0", @@ -7714,7 +7714,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -8972,7 +8972,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.9", - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -10195,9 +10195,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lioness" @@ -19996,7 +19996,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", - "rustix 0.38.25", + "rustix 0.38.21", "tracing", "windows-sys 0.52.0", ] @@ -20315,7 +20315,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.25", + "rustix 0.38.21", ] [[package]] @@ -21715,14 +21715,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.25" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.11", + "linux-raw-sys 0.4.10", "windows-sys 0.48.0", ] @@ -26239,7 +26239,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.4.1" -source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0" +source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -27062,7 +27062,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0" +source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" dependencies = [ "Inflector", "proc-macro-crate 1.3.1", @@ -29110,7 +29110,7 @@ dependencies = [ "cfg-if", "fastrand 2.1.0", "redox_syscall 0.4.1", - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -29140,7 +29140,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] diff --git a/bridges/snowbridge/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/pallets/inbound-queue/src/test.rs index beb9f7614574..053a341b54a0 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/test.rs @@ -5,7 +5,7 @@ use super::*; use frame_support::{assert_noop, assert_ok}; use hex_literal::hex; use snowbridge_core::{inbound::Proof, ChannelId}; -use sp_keyring::AccountKeyring as Keyring; +use sp_keyring::Sr25519Keyring as Keyring; use sp_runtime::DispatchError; use sp_std::convert::From; diff --git a/bridges/snowbridge/runtime/test-common/src/lib.rs b/bridges/snowbridge/runtime/test-common/src/lib.rs index dca5062ab310..5441dd822cac 100644 --- a/bridges/snowbridge/runtime/test-common/src/lib.rs +++ b/bridges/snowbridge/runtime/test-common/src/lib.rs @@ -13,7 +13,7 @@ use parachains_runtimes_test_utils::{ use snowbridge_core::{ChannelId, ParaId}; use snowbridge_pallet_ethereum_client_fixtures::*; use sp_core::{Get, H160, U256}; -use sp_keyring::AccountKeyring::*; +use sp_keyring::Sr25519Keyring::*; use sp_runtime::{traits::Header, AccountId32, DigestItem, SaturatedConversion, Saturating}; use xcm::latest::prelude::*; use xcm_executor::XcmExecutor; @@ -431,7 +431,7 @@ pub fn ethereum_extrinsic( collator_session_key: CollatorSessionKeys, runtime_para_id: u32, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, ::RuntimeCall, ) -> sp_runtime::DispatchOutcome, ) where @@ -567,7 +567,7 @@ pub fn ethereum_to_polkadot_message_extrinsics_work( collator_session_key: CollatorSessionKeys, runtime_para_id: u32, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, ::RuntimeCall, ) -> sp_runtime::DispatchOutcome, ) where diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs index 8be2993c68f4..d5baa1c71dfd 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs @@ -29,7 +29,7 @@ use frame_support::parameter_types; use parachains_common::{AccountId, AuraId, Balance}; use snowbridge_pallet_ethereum_client::WeightInfo; use sp_core::H160; -use sp_keyring::AccountKeyring::Alice; +use sp_keyring::Sr25519Keyring::Alice; use sp_runtime::{ generic::{Era, SignedPayload}, AccountId32, @@ -166,7 +166,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works() { } fn construct_extrinsic( - sender: sp_keyring::AccountKeyring, + sender: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); @@ -192,7 +192,7 @@ fn construct_extrinsic( } fn construct_and_apply_extrinsic( - origin: sp_keyring::AccountKeyring, + origin: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> sp_runtime::DispatchOutcome { let xt = construct_extrinsic(origin, call); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 44e69c31a560..8d74b221a609 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -31,7 +31,7 @@ use parachains_common::{AccountId, AuraId, Balance}; use snowbridge_core::ChannelId; use sp_consensus_aura::SlotDuration; use sp_core::{crypto::Ss58Codec, H160}; -use sp_keyring::AccountKeyring::Alice; +use sp_keyring::Sr25519Keyring::Alice; use sp_runtime::{ generic::{Era, SignedPayload}, AccountId32, Perbill, @@ -45,7 +45,7 @@ parameter_types! { } fn construct_extrinsic( - sender: sp_keyring::AccountKeyring, + sender: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); @@ -72,7 +72,7 @@ fn construct_extrinsic( } fn construct_and_apply_extrinsic( - relayer_at_target: sp_keyring::AccountKeyring, + relayer_at_target: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> sp_runtime::DispatchOutcome { let xt = construct_extrinsic(relayer_at_target, call); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs index 1a1ce2a28ea3..d71400fa71b6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs @@ -30,7 +30,7 @@ use frame_support::parameter_types; use parachains_common::{AccountId, AuraId, Balance}; use snowbridge_pallet_ethereum_client::WeightInfo; use sp_core::H160; -use sp_keyring::AccountKeyring::Alice; +use sp_keyring::Sr25519Keyring::Alice; use sp_runtime::{ generic::{Era, SignedPayload}, AccountId32, @@ -167,7 +167,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works() { } fn construct_extrinsic( - sender: sp_keyring::AccountKeyring, + sender: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); @@ -193,7 +193,7 @@ fn construct_extrinsic( } fn construct_and_apply_extrinsic( - origin: sp_keyring::AccountKeyring, + origin: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> sp_runtime::DispatchOutcome { let xt = construct_extrinsic(origin, call); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index d7e70ed769b1..9d32f28f4fc6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -40,7 +40,7 @@ use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8} use parachains_common::{AccountId, AuraId, Balance}; use sp_consensus_aura::SlotDuration; use sp_core::crypto::Ss58Codec; -use sp_keyring::AccountKeyring::Alice; +use sp_keyring::Sr25519Keyring::Alice; use sp_runtime::{ generic::{Era, SignedPayload}, AccountId32, Perbill, @@ -77,7 +77,7 @@ parameter_types! { } fn construct_extrinsic( - sender: sp_keyring::AccountKeyring, + sender: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); @@ -104,7 +104,7 @@ fn construct_extrinsic( } fn construct_and_apply_extrinsic( - relayer_at_target: sp_keyring::AccountKeyring, + relayer_at_target: sp_keyring::Sr25519Keyring, call: RuntimeCall, ) -> sp_runtime::DispatchOutcome { let xt = construct_extrinsic(relayer_at_target, call); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index 320f3030b60a..358c184c815d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -34,7 +34,7 @@ use parachains_runtimes_test_utils::{ AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_core::Get; -use sp_keyring::AccountKeyring::*; +use sp_keyring::Sr25519Keyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; use xcm::latest::prelude::*; @@ -103,7 +103,7 @@ pub fn relayed_incoming_message_works( local_relay_chain_id: NetworkId, prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, RuntimeCallOf, ) -> sp_runtime::DispatchOutcome, expect_rewards: bool, @@ -210,7 +210,7 @@ pub fn free_relay_extrinsic_works( local_relay_chain_id: NetworkId, prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, RuntimeCallOf, ) -> sp_runtime::DispatchOutcome, expect_rewards: bool, @@ -344,7 +344,7 @@ pub fn complex_relay_extrinsic_works( local_relay_chain_id: NetworkId, prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, RuntimeCallOf, ) -> sp_runtime::DispatchOutcome, ) where diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 1da901e0bcdf..d8fff55b4b50 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -36,7 +36,7 @@ use parachains_runtimes_test_utils::{ AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_core::Get; -use sp_keyring::AccountKeyring::*; +use sp_keyring::Sr25519Keyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; use xcm::latest::prelude::*; @@ -112,7 +112,7 @@ pub fn relayed_incoming_message_works( local_relay_chain_id: NetworkId, prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, ::RuntimeCall, ) -> sp_runtime::DispatchOutcome, expect_rewards: bool, @@ -246,7 +246,7 @@ pub fn free_relay_extrinsic_works( local_relay_chain_id: NetworkId, prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, ::RuntimeCall, ) -> sp_runtime::DispatchOutcome, expect_rewards: bool, @@ -414,7 +414,7 @@ pub fn complex_relay_extrinsic_works( local_relay_chain_id: NetworkId, prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, ::RuntimeCall, ) -> sp_runtime::DispatchOutcome, ) where diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index 03ddc4313b45..a99bda5bfdf4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -39,7 +39,7 @@ use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_core::Get; -use sp_keyring::AccountKeyring::*; +use sp_keyring::Sr25519Keyring::*; use sp_runtime::{traits::TrailingZeroInput, AccountId32}; use xcm::latest::prelude::*; use xcm_executor::traits::ConvertLocation; @@ -264,7 +264,7 @@ pub fn relayed_incoming_message_works( sibling_parachain_id: u32, local_relay_chain_id: NetworkId, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, RuntimeCallOf, ) -> sp_runtime::DispatchOutcome, prepare_message_proof_import: impl FnOnce( @@ -374,9 +374,9 @@ pub fn relayed_incoming_message_works( /// Execute every call and verify its outcome. fn execute_and_verify_calls( - submitter: sp_keyring::AccountKeyring, + submitter: sp_keyring::Sr25519Keyring, construct_and_apply_extrinsic: fn( - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, RuntimeCallOf, ) -> sp_runtime::DispatchOutcome, calls_and_verifiers: CallsAndVerifiers, diff --git a/cumulus/test/client/src/lib.rs b/cumulus/test/client/src/lib.rs index 863a8fa93f6f..26cf02b3dea9 100644 --- a/cumulus/test/client/src/lib.rs +++ b/cumulus/test/client/src/lib.rs @@ -167,7 +167,7 @@ pub fn generate_extrinsic_with_pair( /// Generate an extrinsic from the provided function call, origin and [`Client`]. pub fn generate_extrinsic( client: &Client, - origin: sp_keyring::AccountKeyring, + origin: sp_keyring::Sr25519Keyring, function: impl Into, ) -> UncheckedExtrinsic { generate_extrinsic_with_pair(client, origin.into(), function, None) @@ -176,8 +176,8 @@ pub fn generate_extrinsic( /// Transfer some token from one account to another using a provided test [`Client`]. pub fn transfer( client: &Client, - origin: sp_keyring::AccountKeyring, - dest: sp_keyring::AccountKeyring, + origin: sp_keyring::Sr25519Keyring, + dest: sp_keyring::Sr25519Keyring, value: Balance, ) -> UncheckedExtrinsic { let function = RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { diff --git a/docs/sdk/packages/guides/first-runtime/src/lib.rs b/docs/sdk/packages/guides/first-runtime/src/lib.rs index 61ca550c8750..2ab060c8c43f 100644 --- a/docs/sdk/packages/guides/first-runtime/src/lib.rs +++ b/docs/sdk/packages/guides/first-runtime/src/lib.rs @@ -139,11 +139,11 @@ pub mod genesis_config_presets { let endowment = >::get().max(1) * 1000; build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: AccountKeyring::iter() + balances: Sr25519Keyring::iter() .map(|a| (a.to_account_id(), endowment)) .collect::>(), }, - sudo: SudoConfig { key: Some(AccountKeyring::Alice.to_account_id()) }, + sudo: SudoConfig { key: Some(Sr25519Keyring::Alice.to_account_id()) }, }) } diff --git a/docs/sdk/src/reference_docs/chain_spec_runtime/src/presets.rs b/docs/sdk/src/reference_docs/chain_spec_runtime/src/presets.rs index 5918f2b8ccd5..5432d37e907d 100644 --- a/docs/sdk/src/reference_docs/chain_spec_runtime/src/presets.rs +++ b/docs/sdk/src/reference_docs/chain_spec_runtime/src/presets.rs @@ -25,7 +25,7 @@ use alloc::vec; use frame_support::build_struct_json_patch; use serde_json::{json, to_string, Value}; use sp_application_crypto::Ss58Codec; -use sp_keyring::AccountKeyring; +use sp_keyring::Sr25519Keyring; /// A demo preset with strings only. pub const PRESET_1: &str = "preset_1"; @@ -70,7 +70,7 @@ fn preset_2() -> Value { some_integer: 200, some_enum: FooEnum::Data2(SomeFooData2 { values: vec![0x0c, 0x10] }) }, - bar: BarConfig { initial_account: Some(AccountKeyring::Ferdie.public().into()) }, + bar: BarConfig { initial_account: Some(Sr25519Keyring::Ferdie.public().into()) }, }) } @@ -80,7 +80,7 @@ fn preset_2() -> Value { fn preset_3() -> Value { json!({ "bar": { - "initialAccount": AccountKeyring::Alice.public().to_ss58check(), + "initialAccount": Sr25519Keyring::Alice.public().to_ss58check(), }, "foo": { "someEnum": FooEnum::Data1( diff --git a/polkadot/node/metrics/src/tests.rs b/polkadot/node/metrics/src/tests.rs index 4760138058eb..43dce0ec2ffe 100644 --- a/polkadot/node/metrics/src/tests.rs +++ b/polkadot/node/metrics/src/tests.rs @@ -21,7 +21,7 @@ use hyper::Uri; use hyper_util::{client::legacy::Client, rt::TokioExecutor}; use polkadot_primitives::metric_definitions::PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED; use polkadot_test_service::{node_config, run_validator_node, test_prometheus_config}; -use sp_keyring::AccountKeyring::*; +use sp_keyring::Sr25519Keyring::*; use std::collections::HashMap; const DEFAULT_PROMETHEUS_PORT: u16 = 9616; diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs index 6e09bb9e4310..f34bb62a7cf0 100644 --- a/polkadot/node/test/service/src/lib.rs +++ b/polkadot/node/test/service/src/lib.rs @@ -451,8 +451,8 @@ pub fn construct_extrinsic( /// Construct a transfer extrinsic. pub fn construct_transfer_extrinsic( client: &Client, - origin: sp_keyring::AccountKeyring, - dest: sp_keyring::AccountKeyring, + origin: sp_keyring::Sr25519Keyring, + dest: sp_keyring::Sr25519Keyring, value: Balance, ) -> UncheckedExtrinsic { let function = diff --git a/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs index 85abf8bf36b9..5d728517c4bb 100644 --- a/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs +++ b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs @@ -23,7 +23,7 @@ #[tokio::test(flavor = "multi_thread")] async fn collating_using_adder_collator() { use polkadot_primitives::Id as ParaId; - use sp_keyring::AccountKeyring::*; + use sp_keyring::Sr25519Keyring::*; let mut builder = sc_cli::LoggerBuilder::new(""); builder.with_colors(false); diff --git a/polkadot/parachain/test-parachains/undying/collator/tests/integration.rs b/polkadot/parachain/test-parachains/undying/collator/tests/integration.rs index 8be535b9bb4c..b8e32b13bc9c 100644 --- a/polkadot/parachain/test-parachains/undying/collator/tests/integration.rs +++ b/polkadot/parachain/test-parachains/undying/collator/tests/integration.rs @@ -22,7 +22,7 @@ #[tokio::test(flavor = "multi_thread")] async fn collating_using_undying_collator() { use polkadot_primitives::Id as ParaId; - use sp_keyring::AccountKeyring::*; + use sp_keyring::Sr25519Keyring::*; let mut builder = sc_cli::LoggerBuilder::new(""); builder.with_colors(false); diff --git a/polkadot/runtime/rococo/src/tests.rs b/polkadot/runtime/rococo/src/tests.rs index 01eaad87e342..0b46caec5a35 100644 --- a/polkadot/runtime/rococo/src/tests.rs +++ b/polkadot/runtime/rococo/src/tests.rs @@ -22,7 +22,7 @@ use std::collections::HashSet; use crate::xcm_config::LocationConverter; use frame_support::traits::WhitelistedStorageKeys; use sp_core::{crypto::Ss58Codec, hexdisplay::HexDisplay}; -use sp_keyring::AccountKeyring::Alice; +use sp_keyring::Sr25519Keyring::Alice; use xcm_runtime_apis::conversions::LocationToAccountHelper; #[test] diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index 02fd6b61496b..fcdaf7ff2de6 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -23,7 +23,7 @@ use approx::assert_relative_eq; use frame_support::traits::WhitelistedStorageKeys; use pallet_staking::EraPayout; use sp_core::{crypto::Ss58Codec, hexdisplay::HexDisplay}; -use sp_keyring::AccountKeyring::Alice; +use sp_keyring::Sr25519Keyring::Alice; use xcm_runtime_apis::conversions::LocationToAccountHelper; const MILLISECONDS_PER_HOUR: u64 = 60 * 60 * 1000; diff --git a/prdoc/pr_5899.prdoc b/prdoc/pr_5899.prdoc new file mode 100644 index 000000000000..fef810dd5f20 --- /dev/null +++ b/prdoc/pr_5899.prdoc @@ -0,0 +1,52 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Remove usage of AccountKeyring" + +doc: + - audience: Runtime Dev + description: | + Compared with AccountKeyring, Sr25519Keyring and Ed25519Keyring are more intuitive. + When both Sr25519Keyring and Ed25519Keyring are required, using AccountKeyring bring confusion. + There are two AccountKeyring definitions, it becomes more complex if export two AccountKeyring from frame. + +crates: + - name: frame-support + bump: patch + - name: sp-keyring + bump: major + - name: sc-service + bump: patch + - name: sc-chain-spec + bump: patch + - name: sc-rpc + bump: patch + - name: sc-transaction-pool + bump: patch + - name: sc-rpc-spec-v2 + bump: patch + - name: polkadot-node-metrics + bump: patch + - name: substrate-frame-rpc-system + bump: patch + - name: westend-runtime + bump: patch + - name: polkadot-sdk-frame + bump: patch + - name: rococo-runtime + bump: patch + - name: sc-basic-authorship + bump: patch + - name: bridge-hub-test-utils + bump: patch + - name: sc-consensus-manual-seal + bump: patch + - name: snowbridge-pallet-inbound-queue + bump: patch + - name: snowbridge-runtime-test-common + bump: patch + - name: bridge-hub-rococo-runtime + bump: patch + - name: bridge-hub-westend-runtime + bump: patch + diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 5cde85ae5790..5f6806c235f6 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -871,7 +871,7 @@ mod tests { use sp_consensus::{BlockOrigin, Environment, Proposer}; use sp_core::crypto::Pair; use sp_inherents::InherentDataProvider; - use sp_keyring::AccountKeyring; + use sp_keyring::Sr25519Keyring; use sp_keystore::KeystorePtr; use sp_runtime::{ generic::{self, Digest, Era, SignedPayload}, @@ -906,8 +906,8 @@ mod tests { let mut slot = 1u64; // For the extrinsics factory - let bob = Arc::new(AccountKeyring::Bob.pair()); - let charlie = Arc::new(AccountKeyring::Charlie.pair()); + let bob = Arc::new(Sr25519Keyring::Bob.pair()); + let charlie = Arc::new(Sr25519Keyring::Charlie.pair()); let mut index = 0; sc_service_test::sync( diff --git a/substrate/client/basic-authorship/src/basic_authorship.rs b/substrate/client/basic-authorship/src/basic_authorship.rs index 848ac724c6b8..2096af1c25bb 100644 --- a/substrate/client/basic-authorship/src/basic_authorship.rs +++ b/substrate/client/basic-authorship/src/basic_authorship.rs @@ -910,8 +910,8 @@ mod tests { let extrinsics_num = 5; let extrinsics = std::iter::once( Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), amount: 100, nonce: 0, } @@ -1016,7 +1016,7 @@ mod tests { }; let huge = |who| { ExtrinsicBuilder::new_fill_block(Perbill::from_parts(HUGE)) - .signer(AccountKeyring::numeric(who)) + .signer(Sr25519Keyring::numeric(who)) .build() }; @@ -1082,13 +1082,13 @@ mod tests { let tiny = |who| { ExtrinsicBuilder::new_fill_block(Perbill::from_parts(TINY)) - .signer(AccountKeyring::numeric(who)) + .signer(Sr25519Keyring::numeric(who)) .nonce(1) .build() }; let huge = |who| { ExtrinsicBuilder::new_fill_block(Perbill::from_parts(HUGE)) - .signer(AccountKeyring::numeric(who)) + .signer(Sr25519Keyring::numeric(who)) .build() }; diff --git a/substrate/client/basic-authorship/src/lib.rs b/substrate/client/basic-authorship/src/lib.rs index adea7a3571dd..13c75fd08c3c 100644 --- a/substrate/client/basic-authorship/src/lib.rs +++ b/substrate/client/basic-authorship/src/lib.rs @@ -26,7 +26,7 @@ //! # use sp_runtime::generic::BlockId; //! # use std::{sync::Arc, time::Duration}; //! # use substrate_test_runtime_client::{ -//! # runtime::Transfer, AccountKeyring, +//! # runtime::Transfer, Sr25519Keyring, //! # DefaultTestClientBuilderExt, TestClientBuilderExt, //! # }; //! # use sc_transaction_pool::{BasicPool, FullChainApi}; diff --git a/substrate/client/chain-spec/src/chain_spec.rs b/substrate/client/chain-spec/src/chain_spec.rs index aa3c1ba3e6f1..fa161f1202ab 100644 --- a/substrate/client/chain-spec/src/chain_spec.rs +++ b/substrate/client/chain-spec/src/chain_spec.rs @@ -782,7 +782,7 @@ mod tests { use serde_json::{from_str, json, Value}; use sp_application_crypto::Ss58Codec; use sp_core::storage::well_known_keys; - use sp_keyring::AccountKeyring; + use sp_keyring::Sr25519Keyring; type TestSpec = ChainSpec; @@ -924,8 +924,8 @@ mod tests { }, "substrateTest": { "authorities": [ - AccountKeyring::Ferdie.public().to_ss58check(), - AccountKeyring::Alice.public().to_ss58check() + Sr25519Keyring::Ferdie.public().to_ss58check(), + Sr25519Keyring::Alice.public().to_ss58check() ], } })) @@ -980,8 +980,8 @@ mod tests { }, "substrateTest": { "authorities": [ - AccountKeyring::Ferdie.public().to_ss58check(), - AccountKeyring::Alice.public().to_ss58check() + Sr25519Keyring::Ferdie.public().to_ss58check(), + Sr25519Keyring::Alice.public().to_ss58check() ], } })) @@ -1083,8 +1083,8 @@ mod tests { "invalid_pallet": {}, "substrateTest": { "authorities": [ - AccountKeyring::Ferdie.public().to_ss58check(), - AccountKeyring::Alice.public().to_ss58check() + Sr25519Keyring::Ferdie.public().to_ss58check(), + Sr25519Keyring::Alice.public().to_ss58check() ], } })) diff --git a/substrate/client/consensus/manual-seal/src/lib.rs b/substrate/client/consensus/manual-seal/src/lib.rs index 39f8f8609d8d..af9bcc8d56d6 100644 --- a/substrate/client/consensus/manual-seal/src/lib.rs +++ b/substrate/client/consensus/manual-seal/src/lib.rs @@ -353,7 +353,7 @@ mod tests { use sp_inherents::InherentData; use sp_runtime::generic::{Digest, DigestItem}; use substrate_test_runtime_client::{ - AccountKeyring::*, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt, + DefaultTestClientBuilderExt, Sr25519Keyring::*, TestClientBuilder, TestClientBuilderExt, }; use substrate_test_runtime_transaction_pool::{uxt, TestApi}; diff --git a/substrate/client/network/test/src/lib.rs b/substrate/client/network/test/src/lib.rs index 825481314c67..3cdf211e07f6 100644 --- a/substrate/client/network/test/src/lib.rs +++ b/substrate/client/network/test/src/lib.rs @@ -91,7 +91,7 @@ use sp_runtime::{ traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}, Justification, Justifications, }; -use substrate_test_runtime_client::AccountKeyring; +use substrate_test_runtime_client::Sr25519Keyring; pub use substrate_test_runtime_client::{ runtime::{Block, ExtrinsicBuilder, Hash, Header, Transfer}, TestClient, TestClientBuilder, TestClientBuilderExt, @@ -475,8 +475,8 @@ where BlockOrigin::File, |mut builder| { let transfer = Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Alice.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Alice.into(), amount: 1, nonce, }; diff --git a/substrate/client/rpc-spec-v2/src/archive/tests.rs b/substrate/client/rpc-spec-v2/src/archive/tests.rs index cddaafde6659..48cbbaa4934a 100644 --- a/substrate/client/rpc-spec-v2/src/archive/tests.rs +++ b/substrate/client/rpc-spec-v2/src/archive/tests.rs @@ -117,8 +117,8 @@ async fn archive_body() { builder .push_transfer(runtime::Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 42, nonce: 0, }) @@ -151,8 +151,8 @@ async fn archive_header() { builder .push_transfer(runtime::Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 42, nonce: 0, }) @@ -249,8 +249,8 @@ async fn archive_hash_by_height() { // imported block_builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -330,7 +330,7 @@ async fn archive_call() { client.import(BlockOrigin::Own, block_1.clone()).await.unwrap(); // Valid call. - let alice_id = AccountKeyring::Alice.to_account_id(); + let alice_id = Sr25519Keyring::Alice.to_account_id(); // Hex encoded scale encoded bytes representing the call parameters. let call_parameters = hex_string(&alice_id.encode()); let result: MethodResult = api @@ -929,8 +929,8 @@ async fn archive_storage_diff_deleted_changes() { .unwrap(); builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs index 43b52175bd6d..3ec5e805ecd5 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs @@ -506,8 +506,8 @@ async fn get_body() { .unwrap(); builder .push_transfer(runtime::Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 42, nonce: 0, }) @@ -580,7 +580,7 @@ async fn call_runtime() { ); // Valid call. - let alice_id = AccountKeyring::Alice.to_account_id(); + let alice_id = Sr25519Keyring::Alice.to_account_id(); // Hex encoded scale encoded bytes representing the call parameters. let call_parameters = hex_string(&alice_id.encode()); let response: MethodResponse = api @@ -670,7 +670,7 @@ async fn call_runtime_without_flag() { ); // Valid runtime call on a subscription started with `with_runtime` false. - let alice_id = AccountKeyring::Alice.to_account_id(); + let alice_id = Sr25519Keyring::Alice.to_account_id(); let call_parameters = hex_string(&alice_id.encode()); let err = api .call::<_, serde_json::Value>( @@ -1256,7 +1256,7 @@ async fn unique_operation_ids() { assert!(op_ids.insert(operation_id)); // Valid `chainHead_v1_call` call. - let alice_id = AccountKeyring::Alice.to_account_id(); + let alice_id = Sr25519Keyring::Alice.to_account_id(); let call_parameters = hex_string(&alice_id.encode()); let response: MethodResponse = api .call( @@ -1423,8 +1423,8 @@ async fn follow_generates_initial_blocks() { // imported block_builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -2046,8 +2046,8 @@ async fn follow_prune_best_block() { // imported block_builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -2217,8 +2217,8 @@ async fn follow_forks_pruned_block() { // imported block_builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -2233,8 +2233,8 @@ async fn follow_forks_pruned_block() { .unwrap(); block_builder .push_transfer(Transfer { - from: AccountKeyring::Bob.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Bob.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -2379,8 +2379,8 @@ async fn follow_report_multiple_pruned_block() { // imported block_builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -2397,8 +2397,8 @@ async fn follow_report_multiple_pruned_block() { block_builder .push_transfer(Transfer { - from: AccountKeyring::Bob.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Bob.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -2883,7 +2883,7 @@ async fn ensure_operation_limits_works() { ); // The storage is finished and capacity must be released. - let alice_id = AccountKeyring::Alice.to_account_id(); + let alice_id = Sr25519Keyring::Alice.to_account_id(); // Hex encoded scale encoded bytes representing the call parameters. let call_parameters = hex_string(&alice_id.encode()); let response: MethodResponse = api @@ -3537,7 +3537,7 @@ async fn chain_head_single_connection_context() { .unwrap(); assert_matches!(response, MethodResponse::LimitReached); - let alice_id = AccountKeyring::Alice.to_account_id(); + let alice_id = Sr25519Keyring::Alice.to_account_id(); // Hex encoded scale encoded bytes representing the call parameters. let call_parameters = hex_string(&alice_id.encode()); let response: MethodResponse = ChainHeadApiClient::::chain_head_unstable_call( @@ -3663,8 +3663,8 @@ async fn follow_unique_pruned_blocks() { let block_6_hash = import_block(client.clone(), block_2_f_hash, 2).await.hash(); // Import block 2 as best on the fork. let mut tx_alice_ferdie = Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }; @@ -3846,8 +3846,8 @@ async fn follow_report_best_block_of_a_known_block() { // imported block_builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs index efb3bd94ddbf..c2f11878e8fc 100644 --- a/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs @@ -23,7 +23,7 @@ use jsonrpsee::{rpc_params, MethodsError as Error}; use sc_transaction_pool::{Options, PoolLimit}; use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool, TransactionPool}; use std::sync::Arc; -use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_client::Sr25519Keyring::*; use substrate_test_runtime_transaction_pool::uxt; const MAX_TX_PER_CONNECTION: usize = 4; diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_tests.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_tests.rs index 53c5b8ce3895..879d51eaf5f3 100644 --- a/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_tests.rs +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_tests.rs @@ -26,7 +26,7 @@ use jsonrpsee::rpc_params; use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool}; use sp_core::H256; use std::{sync::Arc, vec}; -use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_client::Sr25519Keyring::*; use substrate_test_runtime_transaction_pool::uxt; // Test helpers. diff --git a/substrate/client/rpc/src/author/tests.rs b/substrate/client/rpc/src/author/tests.rs index ab0b8bdab699..b1c899667624 100644 --- a/substrate/client/rpc/src/author/tests.rs +++ b/substrate/client/rpc/src/author/tests.rs @@ -39,15 +39,15 @@ use std::sync::Arc; use substrate_test_runtime_client::{ self, runtime::{Block, Extrinsic, ExtrinsicBuilder, SessionKeys, Transfer}, - AccountKeyring, Backend, Client, DefaultTestClientBuilderExt, TestClientBuilderExt, + Backend, Client, DefaultTestClientBuilderExt, Sr25519Keyring, TestClientBuilderExt, }; -fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { +fn uxt(sender: Sr25519Keyring, nonce: u64) -> Extrinsic { let tx = Transfer { amount: Default::default(), nonce, from: sender.into(), - to: AccountKeyring::Bob.into(), + to: Sr25519Keyring::Bob.into(), }; ExtrinsicBuilder::new_transfer(tx).build() } @@ -99,7 +99,7 @@ impl TestSetup { async fn author_submit_transaction_should_not_cause_error() { let api = TestSetup::into_rpc(); - let xt: Bytes = uxt(AccountKeyring::Alice, 1).encode().into(); + let xt: Bytes = uxt(Sr25519Keyring::Alice, 1).encode().into(); let extrinsic_hash: H256 = blake2_256(&xt).into(); let response: H256 = api.call("author_submitExtrinsic", [xt.clone()]).await.unwrap(); @@ -116,7 +116,7 @@ async fn author_should_watch_extrinsic() { let api = TestSetup::into_rpc(); let xt = to_hex( &ExtrinsicBuilder::new_call_with_priority(0) - .signer(AccountKeyring::Alice.into()) + .signer(Sr25519Keyring::Alice.into()) .build() .encode(), true, @@ -135,7 +135,7 @@ async fn author_should_watch_extrinsic() { // Replace the extrinsic and observe the subscription is notified. let (xt_replacement, xt_hash) = { let tx = ExtrinsicBuilder::new_call_with_priority(1) - .signer(AccountKeyring::Alice.into()) + .signer(Sr25519Keyring::Alice.into()) .build() .encode(); let hash = blake2_256(&tx); @@ -172,7 +172,7 @@ async fn author_should_return_watch_validation_error() { async fn author_should_return_pending_extrinsics() { let api = TestSetup::into_rpc(); - let xt_bytes: Bytes = uxt(AccountKeyring::Alice, 0).encode().into(); + let xt_bytes: Bytes = uxt(Sr25519Keyring::Alice, 0).encode().into(); api.call::<_, H256>("author_submitExtrinsic", [to_hex(&xt_bytes, true)]) .await .unwrap(); @@ -190,14 +190,14 @@ async fn author_should_remove_extrinsics() { // Submit three extrinsics, then remove two of them (will cause the third to be removed as well, // having a higher nonce) - let xt1_bytes = uxt(AccountKeyring::Alice, 0).encode(); + let xt1_bytes = uxt(Sr25519Keyring::Alice, 0).encode(); let xt1 = to_hex(&xt1_bytes, true); let xt1_hash: H256 = api.call("author_submitExtrinsic", [xt1]).await.unwrap(); - let xt2 = to_hex(&uxt(AccountKeyring::Alice, 1).encode(), true); + let xt2 = to_hex(&uxt(Sr25519Keyring::Alice, 1).encode(), true); let xt2_hash: H256 = api.call("author_submitExtrinsic", [xt2]).await.unwrap(); - let xt3 = to_hex(&uxt(AccountKeyring::Bob, 0).encode(), true); + let xt3 = to_hex(&uxt(Sr25519Keyring::Bob, 0).encode(), true); let xt3_hash: H256 = api.call("author_submitExtrinsic", [xt3]).await.unwrap(); assert_eq!(setup.pool.status().ready, 3); diff --git a/substrate/client/rpc/src/state/tests.rs b/substrate/client/rpc/src/state/tests.rs index 6b711f2425e9..c02f0d0b759b 100644 --- a/substrate/client/rpc/src/state/tests.rs +++ b/substrate/client/rpc/src/state/tests.rs @@ -228,8 +228,8 @@ async fn should_notify_about_storage_changes() { .unwrap(); builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 42, nonce: 0, }) @@ -255,11 +255,11 @@ async fn should_send_initial_storage_changes_and_notifications() { let alice_balance_key = [ sp_crypto_hashing::twox_128(b"System"), sp_crypto_hashing::twox_128(b"Account"), - sp_crypto_hashing::blake2_128(&AccountKeyring::Alice.public()), + sp_crypto_hashing::blake2_128(&Sr25519Keyring::Alice.public()), ] .concat() .iter() - .chain(AccountKeyring::Alice.public().0.iter()) + .chain(Sr25519Keyring::Alice.public().0.iter()) .cloned() .collect::>(); @@ -281,8 +281,8 @@ async fn should_send_initial_storage_changes_and_notifications() { .unwrap(); builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 42, nonce: 0, }) diff --git a/substrate/client/service/src/lib.rs b/substrate/client/service/src/lib.rs index b5a38d875e3b..2a3144a33e1a 100644 --- a/substrate/client/service/src/lib.rs +++ b/substrate/client/service/src/lib.rs @@ -596,8 +596,8 @@ mod tests { let transaction = Transfer { amount: 5, nonce: 0, - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), } .into_unchecked_extrinsic(); block_on(pool.submit_one(best.hash(), source, transaction.clone())).unwrap(); diff --git a/substrate/client/service/test/src/client/mod.rs b/substrate/client/service/test/src/client/mod.rs index ead90c4c65d8..ef5de93d64ca 100644 --- a/substrate/client/service/test/src/client/mod.rs +++ b/substrate/client/service/test/src/client/mod.rs @@ -48,8 +48,8 @@ use substrate_test_runtime_client::{ genesismap::{insert_genesis_block, GenesisStorageBuilder}, Block, BlockNumber, Digest, Hash, Header, RuntimeApi, Transfer, }, - AccountKeyring, BlockBuilderExt, ClientBlockImportExt, ClientExt, DefaultTestClientBuilderExt, - Sr25519Keyring, TestClientBuilder, TestClientBuilderExt, + BlockBuilderExt, ClientBlockImportExt, ClientExt, DefaultTestClientBuilderExt, Sr25519Keyring, + TestClientBuilder, TestClientBuilderExt, }; mod db; @@ -126,8 +126,8 @@ fn block1(genesis_hash: Hash, backend: &InMemoryBackend) -> Vec 1, genesis_hash, vec![Transfer { - from: AccountKeyring::One.into(), - to: AccountKeyring::Two.into(), + from: Sr25519Keyring::One.into(), + to: Sr25519Keyring::Two.into(), amount: 69 * DOLLARS, nonce: 0, }], @@ -158,7 +158,7 @@ fn finality_notification_check( fn construct_genesis_should_work_with_native() { let mut storage = GenesisStorageBuilder::new( vec![Sr25519Keyring::One.public().into(), Sr25519Keyring::Two.public().into()], - vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], + vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()], 1000 * DOLLARS, ) .build(); @@ -189,7 +189,7 @@ fn construct_genesis_should_work_with_native() { fn construct_genesis_should_work_with_wasm() { let mut storage = GenesisStorageBuilder::new( vec![Sr25519Keyring::One.public().into(), Sr25519Keyring::Two.public().into()], - vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], + vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()], 1000 * DOLLARS, ) .build(); @@ -223,14 +223,14 @@ fn client_initializes_from_genesis_ok() { assert_eq!( client .runtime_api() - .balance_of(client.chain_info().best_hash, AccountKeyring::Alice.into()) + .balance_of(client.chain_info().best_hash, Sr25519Keyring::Alice.into()) .unwrap(), 1000 * DOLLARS ); assert_eq!( client .runtime_api() - .balance_of(client.chain_info().best_hash, AccountKeyring::Ferdie.into()) + .balance_of(client.chain_info().best_hash, Sr25519Keyring::Ferdie.into()) .unwrap(), 0 * DOLLARS ); @@ -266,8 +266,8 @@ fn block_builder_works_with_transactions() { builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 42 * DOLLARS, nonce: 0, }) @@ -301,14 +301,14 @@ fn block_builder_works_with_transactions() { assert_eq!( client .runtime_api() - .balance_of(client.chain_info().best_hash, AccountKeyring::Alice.into()) + .balance_of(client.chain_info().best_hash, Sr25519Keyring::Alice.into()) .unwrap(), 958 * DOLLARS ); assert_eq!( client .runtime_api() - .balance_of(client.chain_info().best_hash, AccountKeyring::Ferdie.into()) + .balance_of(client.chain_info().best_hash, Sr25519Keyring::Ferdie.into()) .unwrap(), 42 * DOLLARS ); @@ -325,8 +325,8 @@ fn block_builder_does_not_include_invalid() { builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 42 * DOLLARS, nonce: 0, }) @@ -334,8 +334,8 @@ fn block_builder_does_not_include_invalid() { assert!(builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 30 * DOLLARS, nonce: 0, }) @@ -491,8 +491,8 @@ fn uncles_with_multiple_forks() { // this push is required as otherwise B2 has the same hash as A2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41 * DOLLARS, nonce: 0, }) @@ -531,8 +531,8 @@ fn uncles_with_multiple_forks() { // this push is required as otherwise C3 has the same hash as B3 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 1, }) @@ -549,8 +549,8 @@ fn uncles_with_multiple_forks() { // this push is required as otherwise D2 has the same hash as B2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 0, }) @@ -691,8 +691,8 @@ fn finality_target_on_longest_chain_with_multiple_forks() { // this push is required as otherwise B2 has the same hash as A2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41 * DOLLARS, nonce: 0, }) @@ -732,8 +732,8 @@ fn finality_target_on_longest_chain_with_multiple_forks() { // this push is required as otherwise C3 has the same hash as B3 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 1, }) @@ -751,8 +751,8 @@ fn finality_target_on_longest_chain_with_multiple_forks() { // this push is required as otherwise D2 has the same hash as B2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 0, }) @@ -982,8 +982,8 @@ fn finality_target_with_best_not_on_longest_chain() { // this push is required as otherwise B2 has the same hash as A2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41 * DOLLARS, nonce: 0, }) @@ -1134,8 +1134,8 @@ fn importing_diverged_finalized_block_should_trigger_reorg() { .unwrap(); // needed to make sure B1 gets a different hash from A1 b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 0, }) @@ -1195,8 +1195,8 @@ fn finalizing_diverged_block_should_trigger_reorg() { .unwrap(); // needed to make sure B1 gets a different hash from A1 b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 0, }) @@ -1303,8 +1303,8 @@ fn finality_notifications_content() { .unwrap(); // needed to make sure B1 gets a different hash from A1 b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1, nonce: 0, }) @@ -1329,8 +1329,8 @@ fn finality_notifications_content() { .unwrap(); // needed to make sure B1 gets a different hash from A1 c1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 2 * DOLLARS, nonce: 0, }) @@ -1346,8 +1346,8 @@ fn finality_notifications_content() { // needed to make sure D3 gets a different hash from A3 d3.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 2 * DOLLARS, nonce: 0, }) @@ -1415,7 +1415,7 @@ fn state_reverted_on_reorg() { let current_balance = |client: &substrate_test_runtime_client::TestClient| { client .runtime_api() - .balance_of(client.chain_info().best_hash, AccountKeyring::Alice.into()) + .balance_of(client.chain_info().best_hash, Sr25519Keyring::Alice.into()) .unwrap() }; @@ -1428,8 +1428,8 @@ fn state_reverted_on_reorg() { .build() .unwrap(); a1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), amount: 10 * DOLLARS, nonce: 0, }) @@ -1443,8 +1443,8 @@ fn state_reverted_on_reorg() { .build() .unwrap(); b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 50 * DOLLARS, nonce: 0, }) @@ -1460,8 +1460,8 @@ fn state_reverted_on_reorg() { .build() .unwrap(); a2.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Charlie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Charlie.into(), amount: 10 * DOLLARS, nonce: 1, }) @@ -1530,8 +1530,8 @@ fn doesnt_import_blocks_that_revert_finality() { // needed to make sure B1 gets a different hash from A1 b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 0, }) @@ -1580,8 +1580,8 @@ fn doesnt_import_blocks_that_revert_finality() { // needed to make sure C1 gets a different hash from A1 and B1 c1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 2 * DOLLARS, nonce: 0, }) @@ -1788,8 +1788,8 @@ fn returns_status_for_pruned_blocks() { // b1 is created, but not imported b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 0, }) @@ -2191,8 +2191,8 @@ fn reorg_triggers_a_notification_even_for_sources_that_should_not_trigger_notifi // needed to make sure B1 gets a different hash from A1 b1.push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1 * DOLLARS, nonce: 0, }) diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs index eb898c35a134..e1c65a08a70b 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/revalidation_worker.rs @@ -190,7 +190,7 @@ mod tests { }; use futures::executor::block_on; use substrate_test_runtime::{AccountId, Transfer, H256}; - use substrate_test_runtime_client::AccountKeyring::Alice; + use substrate_test_runtime_client::Sr25519Keyring::Alice; #[test] fn revalidation_queue_works() { let api = Arc::new(TestApi::default()); diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs index 7b824d4653c2..989ae4425dc4 100644 --- a/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs +++ b/substrate/client/transaction-pool/src/fork_aware_txpool/tx_mem_pool.rs @@ -469,7 +469,7 @@ mod tx_mem_pool_tests { use super::*; use crate::{common::tests::TestApi, graph::ChainApi}; use substrate_test_runtime::{AccountId, Extrinsic, ExtrinsicBuilder, Transfer, H256}; - use substrate_test_runtime_client::AccountKeyring::*; + use substrate_test_runtime_client::Sr25519Keyring::*; fn uxt(nonce: u64) -> Extrinsic { crate::common::tests::uxt(Transfer { from: Alice.into(), diff --git a/substrate/client/transaction-pool/src/graph/pool.rs b/substrate/client/transaction-pool/src/graph/pool.rs index 23b71ce437b3..ff9cc1541af4 100644 --- a/substrate/client/transaction-pool/src/graph/pool.rs +++ b/substrate/client/transaction-pool/src/graph/pool.rs @@ -492,7 +492,7 @@ mod tests { use sp_runtime::transaction_validity::TransactionSource; use std::{collections::HashMap, time::Instant}; use substrate_test_runtime::{AccountId, ExtrinsicBuilder, Transfer, H256}; - use substrate_test_runtime_client::AccountKeyring::{Alice, Bob}; + use substrate_test_runtime_client::Sr25519Keyring::{Alice, Bob}; const SOURCE: TimedTransactionSource = TimedTransactionSource { source: TransactionSource::External, timestamp: None }; diff --git a/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs b/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs index 74031b1e1c72..f22fa2ddabde 100644 --- a/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs +++ b/substrate/client/transaction-pool/src/single_state_txpool/revalidation.rs @@ -379,7 +379,7 @@ mod tests { }; use futures::executor::block_on; use substrate_test_runtime::{AccountId, Transfer, H256}; - use substrate_test_runtime_client::AccountKeyring::{Alice, Bob}; + use substrate_test_runtime_client::Sr25519Keyring::{Alice, Bob}; #[test] fn revalidation_queue_works() { diff --git a/substrate/client/transaction-pool/tests/fatp.rs b/substrate/client/transaction-pool/tests/fatp.rs index c51ca6e17663..8bf08122995c 100644 --- a/substrate/client/transaction-pool/tests/fatp.rs +++ b/substrate/client/transaction-pool/tests/fatp.rs @@ -30,7 +30,7 @@ use sc_transaction_pool_api::{ }; use sp_runtime::transaction_validity::InvalidTransaction; use std::{sync::Arc, time::Duration}; -use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_client::Sr25519Keyring::*; use substrate_test_runtime_transaction_pool::uxt; pub mod fatp_common; diff --git a/substrate/client/transaction-pool/tests/fatp_common/mod.rs b/substrate/client/transaction-pool/tests/fatp_common/mod.rs index aecd83360f1e..aaffebc0db0a 100644 --- a/substrate/client/transaction-pool/tests/fatp_common/mod.rs +++ b/substrate/client/transaction-pool/tests/fatp_common/mod.rs @@ -24,7 +24,7 @@ use sp_runtime::transaction_validity::TransactionSource; use std::sync::Arc; use substrate_test_runtime_client::{ runtime::{Block, Hash, Header}, - AccountKeyring::*, + Sr25519Keyring::*, }; use substrate_test_runtime_transaction_pool::{uxt, TestApi}; pub const LOG_TARGET: &str = "txpool"; diff --git a/substrate/client/transaction-pool/tests/fatp_limits.rs b/substrate/client/transaction-pool/tests/fatp_limits.rs index afd8183957a8..fb02b21ebc2b 100644 --- a/substrate/client/transaction-pool/tests/fatp_limits.rs +++ b/substrate/client/transaction-pool/tests/fatp_limits.rs @@ -29,7 +29,7 @@ use sc_transaction_pool_api::{ error::Error as TxPoolError, MaintainedTransactionPool, TransactionPool, TransactionStatus, }; use std::thread::sleep; -use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_client::Sr25519Keyring::*; use substrate_test_runtime_transaction_pool::uxt; #[test] diff --git a/substrate/client/transaction-pool/tests/fatp_prios.rs b/substrate/client/transaction-pool/tests/fatp_prios.rs index 41bc374b38f4..4ed9b4503861 100644 --- a/substrate/client/transaction-pool/tests/fatp_prios.rs +++ b/substrate/client/transaction-pool/tests/fatp_prios.rs @@ -24,7 +24,7 @@ use fatp_common::{new_best_block_event, TestPoolBuilder, LOG_TARGET, SOURCE}; use futures::{executor::block_on, FutureExt}; use sc_transaction_pool::ChainApi; use sc_transaction_pool_api::{MaintainedTransactionPool, TransactionPool, TransactionStatus}; -use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_client::Sr25519Keyring::*; use substrate_test_runtime_transaction_pool::uxt; #[test] diff --git a/substrate/client/transaction-pool/tests/pool.rs b/substrate/client/transaction-pool/tests/pool.rs index e556ba9875f1..20997606c607 100644 --- a/substrate/client/transaction-pool/tests/pool.rs +++ b/substrate/client/transaction-pool/tests/pool.rs @@ -40,8 +40,8 @@ use sp_runtime::{ use std::{collections::BTreeSet, pin::Pin, sync::Arc}; use substrate_test_runtime_client::{ runtime::{Block, Extrinsic, ExtrinsicBuilder, Hash, Header, Nonce, Transfer, TransferData}, - AccountKeyring::*, ClientBlockImportExt, + Sr25519Keyring::*, }; use substrate_test_runtime_transaction_pool::{uxt, TestApi}; diff --git a/substrate/docs/Upgrading-2.0-to-3.0.md b/substrate/docs/Upgrading-2.0-to-3.0.md index 1be41a34ef34..f6fc5cf4b079 100644 --- a/substrate/docs/Upgrading-2.0-to-3.0.md +++ b/substrate/docs/Upgrading-2.0-to-3.0.md @@ -1003,7 +1003,7 @@ modified your chain you should probably try to apply these patches: }; use sp_timestamp; - use sp_finality_tracker; - use sp_keyring::AccountKeyring; + use sp_keyring::Sr25519Keyring; use sc_service_test::TestNetNode; use crate::service::{new_full_base, new_light_base, NewFullBase}; - use sp_runtime::traits::IdentifyAccount; @@ -1034,7 +1034,7 @@ modified your chain you should probably try to apply these patches: + let mut slot = 1u64; // For the extrinsics factory - let bob = Arc::new(AccountKeyring::Bob.pair()); + let bob = Arc::new(Sr25519Keyring::Bob.pair()); @@ -528,14 +539,13 @@ mod tests { Ok((node, (inherent_data_providers, setup_handles.unwrap()))) }, diff --git a/substrate/frame/examples/authorization-tx-extension/src/tests.rs b/substrate/frame/examples/authorization-tx-extension/src/tests.rs index 8ca35c099556..5579e7a98416 100644 --- a/substrate/frame/examples/authorization-tx-extension/src/tests.rs +++ b/substrate/frame/examples/authorization-tx-extension/src/tests.rs @@ -24,7 +24,7 @@ use frame_support::{ pallet_prelude::{InvalidTransaction, TransactionValidityError}, }; use pallet_verify_signature::VerifySignature; -use sp_keyring::AccountKeyring; +use sp_keyring::Sr25519Keyring; use sp_runtime::{ generic::ExtensionVersion, traits::{Applyable, Checkable, IdentityLookup, TransactionExtension}, @@ -36,7 +36,7 @@ use crate::{extensions::AuthorizeCoownership, mock::*, pallet_assets}; #[test] fn create_asset_works() { new_test_ext().execute_with(|| { - let alice_keyring = AccountKeyring::Alice; + let alice_keyring = Sr25519Keyring::Alice; let alice_account = AccountId::from(alice_keyring.public()); // Simple call to create asset with Id `42`. let create_asset_call = @@ -99,9 +99,9 @@ fn create_asset_works() { #[test] fn create_coowned_asset_works() { new_test_ext().execute_with(|| { - let alice_keyring = AccountKeyring::Alice; - let bob_keyring = AccountKeyring::Bob; - let charlie_keyring = AccountKeyring::Charlie; + let alice_keyring = Sr25519Keyring::Alice; + let bob_keyring = Sr25519Keyring::Bob; + let charlie_keyring = Sr25519Keyring::Charlie; let alice_account = AccountId::from(alice_keyring.public()); let bob_account = AccountId::from(bob_keyring.public()); let charlie_account = AccountId::from(charlie_keyring.public()); @@ -189,9 +189,9 @@ fn create_coowned_asset_works() { #[test] fn inner_authorization_works() { new_test_ext().execute_with(|| { - let alice_keyring = AccountKeyring::Alice; - let bob_keyring = AccountKeyring::Bob; - let charlie_keyring = AccountKeyring::Charlie; + let alice_keyring = Sr25519Keyring::Alice; + let bob_keyring = Sr25519Keyring::Bob; + let charlie_keyring = Sr25519Keyring::Charlie; let charlie_account = AccountId::from(charlie_keyring.public()); // Simple call to create asset with Id `42`. let create_asset_call = diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index 03d815e349df..8031ddf96e6a 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -391,7 +391,7 @@ pub mod runtime { LOCAL_TESTNET_RUNTIME_PRESET, }; pub use sp_inherents::{CheckInherentsResult, InherentData}; - pub use sp_keyring::AccountKeyring; + pub use sp_keyring::Sr25519Keyring; pub use sp_runtime::{ApplyExtrinsicResult, ExtrinsicInclusionMode}; } diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index d48c80510581..4348bd275605 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -35,9 +35,7 @@ sp-api = { features = [ ], workspace = true } sp-std = { workspace = true } sp-io = { workspace = true } -sp-runtime = { features = [ - "serde", -], workspace = true } +sp-runtime = { features = ["serde"], workspace = true } sp-tracing = { workspace = true } sp-core = { workspace = true } sp-arithmetic = { workspace = true } diff --git a/substrate/primitives/api/test/tests/runtime_calls.rs b/substrate/primitives/api/test/tests/runtime_calls.rs index 5a524d1c7f4d..0470b8b72aa0 100644 --- a/substrate/primitives/api/test/tests/runtime_calls.rs +++ b/substrate/primitives/api/test/tests/runtime_calls.rs @@ -99,8 +99,8 @@ fn record_proof_works() { let transaction = Transfer { amount: 1000, nonce: 0, - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), } .into_unchecked_extrinsic(); diff --git a/substrate/primitives/keyring/src/lib.rs b/substrate/primitives/keyring/src/lib.rs index 008c01b150f0..36e77dabd601 100644 --- a/substrate/primitives/keyring/src/lib.rs +++ b/substrate/primitives/keyring/src/lib.rs @@ -32,20 +32,11 @@ pub mod ed25519; #[cfg(feature = "bandersnatch-experimental")] pub mod bandersnatch; -/// Convenience export: Sr25519's Keyring is exposed as `AccountKeyring`, since it tends to be -/// used for accounts (although it may also be used by authorities). -pub use sr25519::Keyring as AccountKeyring; - #[cfg(feature = "bandersnatch-experimental")] pub use bandersnatch::Keyring as BandersnatchKeyring; pub use ed25519::Keyring as Ed25519Keyring; pub use sr25519::Keyring as Sr25519Keyring; -pub mod test { - /// The keyring for use with accounts when using the test runtime. - pub use super::ed25519::Keyring as AccountKeyring; -} - #[derive(Debug)] /// Represents an error that occurs when parsing a string into a `KeyRing`. pub struct ParseKeyringError; diff --git a/substrate/test-utils/client/src/lib.rs b/substrate/test-utils/client/src/lib.rs index c07640653d56..5a4e6c911694 100644 --- a/substrate/test-utils/client/src/lib.rs +++ b/substrate/test-utils/client/src/lib.rs @@ -27,9 +27,7 @@ pub use sc_client_db::{self, Backend, BlocksPruning}; pub use sc_executor::{self, WasmExecutionMethod, WasmExecutor}; pub use sc_service::{client, RpcHandlers}; pub use sp_consensus; -pub use sp_keyring::{ - ed25519::Keyring as Ed25519Keyring, sr25519::Keyring as Sr25519Keyring, AccountKeyring, -}; +pub use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; pub use sp_keystore::{Keystore, KeystorePtr}; pub use sp_runtime::{Storage, StorageChild}; diff --git a/substrate/test-utils/runtime/client/src/lib.rs b/substrate/test-utils/runtime/client/src/lib.rs index 435f3f5ebacb..a5a37660660c 100644 --- a/substrate/test-utils/runtime/client/src/lib.rs +++ b/substrate/test-utils/runtime/client/src/lib.rs @@ -45,7 +45,7 @@ pub mod prelude { Backend, ExecutorDispatch, TestClient, TestClientBuilder, WasmExecutionMethod, }; // Keyring - pub use super::{AccountKeyring, Sr25519Keyring}; + pub use super::Sr25519Keyring; } /// Test client database backend. diff --git a/substrate/test-utils/runtime/client/src/trait_tests.rs b/substrate/test-utils/runtime/client/src/trait_tests.rs index c3a5f173d14e..815e05163281 100644 --- a/substrate/test-utils/runtime/client/src/trait_tests.rs +++ b/substrate/test-utils/runtime/client/src/trait_tests.rs @@ -23,7 +23,7 @@ use std::sync::Arc; use crate::{ - AccountKeyring, BlockBuilderExt, ClientBlockImportExt, TestClientBuilder, TestClientBuilderExt, + BlockBuilderExt, ClientBlockImportExt, Sr25519Keyring, TestClientBuilder, TestClientBuilderExt, }; use futures::executor::block_on; use sc_block_builder::BlockBuilderBuilder; @@ -132,8 +132,8 @@ where // this push is required as otherwise B2 has the same hash as A2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -179,8 +179,8 @@ where // this push is required as otherwise C3 has the same hash as B3 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1, nonce: 1, }) @@ -199,8 +199,8 @@ where // this push is required as otherwise D2 has the same hash as B2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1, nonce: 0, }) @@ -295,8 +295,8 @@ where // this push is required as otherwise B2 has the same hash as A2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -338,8 +338,8 @@ where // this push is required as otherwise C3 has the same hash as B3 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1, nonce: 1, }) @@ -357,8 +357,8 @@ where // this push is required as otherwise D2 has the same hash as B2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1, nonce: 0, }) @@ -464,8 +464,8 @@ where // this push is required as otherwise B2 has the same hash as A2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 41, nonce: 0, }) @@ -507,8 +507,8 @@ where // this push is required as otherwise C3 has the same hash as B3 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1, nonce: 1, }) @@ -526,8 +526,8 @@ where // this push is required as otherwise D2 has the same hash as B2 and won't get imported builder .push_transfer(Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Ferdie.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Ferdie.into(), amount: 1, nonce: 0, }) diff --git a/substrate/test-utils/runtime/src/extrinsic.rs b/substrate/test-utils/runtime/src/extrinsic.rs index 4c884d4174ff..491086bef497 100644 --- a/substrate/test-utils/runtime/src/extrinsic.rs +++ b/substrate/test-utils/runtime/src/extrinsic.rs @@ -25,7 +25,7 @@ use codec::Encode; use frame_metadata_hash_extension::CheckMetadataHash; use frame_system::{CheckNonce, CheckWeight}; use sp_core::crypto::Pair as TraitPair; -use sp_keyring::AccountKeyring; +use sp_keyring::Sr25519Keyring; use sp_runtime::{ generic::Preamble, traits::TransactionExtension, transaction_validity::TransactionPriority, Perbill, @@ -54,8 +54,8 @@ impl Transfer { impl Default for TransferData { fn default() -> Self { Self { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), amount: 0, nonce: 0, } @@ -93,7 +93,7 @@ impl ExtrinsicBuilder { pub fn new(function: impl Into) -> Self { Self { function: function.into(), - signer: Some(AccountKeyring::Alice.pair()), + signer: Some(Sr25519Keyring::Alice.pair()), nonce: None, metadata_hash: None, } diff --git a/substrate/test-utils/runtime/src/genesismap.rs b/substrate/test-utils/runtime/src/genesismap.rs index 9e972886b377..5c0c146d45a5 100644 --- a/substrate/test-utils/runtime/src/genesismap.rs +++ b/substrate/test-utils/runtime/src/genesismap.rs @@ -27,7 +27,7 @@ use sp_core::{ storage::{well_known_keys, StateVersion, Storage}, Pair, }; -use sp_keyring::{AccountKeyring, Sr25519Keyring}; +use sp_keyring::Sr25519Keyring; use sp_runtime::{ traits::{Block as BlockT, Hash as HashT, Header as HeaderT}, BuildStorage, @@ -60,11 +60,11 @@ impl Default for GenesisStorageBuilder { ], (0..16_usize) .into_iter() - .map(|i| AccountKeyring::numeric(i).public()) + .map(|i| Sr25519Keyring::numeric(i).public()) .chain(vec![ - AccountKeyring::Alice.into(), - AccountKeyring::Bob.into(), - AccountKeyring::Charlie.into(), + Sr25519Keyring::Alice.into(), + Sr25519Keyring::Bob.into(), + Sr25519Keyring::Charlie.into(), ]) .collect(), 1000 * currency::DOLLARS, diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index 461d583b5cc6..666776865316 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -47,7 +47,7 @@ use frame_system::{ }; use scale_info::TypeInfo; use sp_application_crypto::Ss58Codec; -use sp_keyring::AccountKeyring; +use sp_keyring::Sr25519Keyring; use sp_application_crypto::{ecdsa, ed25519, sr25519, RuntimeAppPublic}; use sp_core::{OpaqueMetadata, RuntimeDebug}; @@ -731,8 +731,8 @@ impl_runtime_apis! { let patch = match name.as_ref() { "staging" => { let endowed_accounts: Vec = vec![ - AccountKeyring::Bob.public().into(), - AccountKeyring::Charlie.public().into(), + Sr25519Keyring::Bob.public().into(), + Sr25519Keyring::Charlie.public().into(), ]; json!({ @@ -741,8 +741,8 @@ impl_runtime_apis! { }, "substrateTest": { "authorities": [ - AccountKeyring::Alice.public().to_ss58check(), - AccountKeyring::Ferdie.public().to_ss58check() + Sr25519Keyring::Alice.public().to_ss58check(), + Sr25519Keyring::Ferdie.public().to_ss58check() ], } }) @@ -911,11 +911,11 @@ pub mod storage_key_generator { let balances_map_keys = (0..16_usize) .into_iter() - .map(|i| AccountKeyring::numeric(i).public().to_vec()) + .map(|i| Sr25519Keyring::numeric(i).public().to_vec()) .chain(vec![ - AccountKeyring::Alice.public().to_vec(), - AccountKeyring::Bob.public().to_vec(), - AccountKeyring::Charlie.public().to_vec(), + Sr25519Keyring::Alice.public().to_vec(), + Sr25519Keyring::Bob.public().to_vec(), + Sr25519Keyring::Charlie.public().to_vec(), ]) .map(|pubkey| { sp_crypto_hashing::blake2_128(&pubkey) @@ -1133,8 +1133,8 @@ mod tests { pub fn new_test_ext() -> sp_io::TestExternalities { genesismap::GenesisStorageBuilder::new( - vec![AccountKeyring::One.public().into(), AccountKeyring::Two.public().into()], - vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], + vec![Sr25519Keyring::One.public().into(), Sr25519Keyring::Two.public().into()], + vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()], 1000 * currency::DOLLARS, ) .build() @@ -1202,7 +1202,7 @@ mod tests { fn check_substrate_check_signed_extension_works() { sp_tracing::try_init_simple(); new_test_ext().execute_with(|| { - let x = AccountKeyring::Alice.into(); + let x = Sr25519Keyring::Alice.into(); let info = DispatchInfo::default(); let len = 0_usize; assert_eq!( @@ -1472,8 +1472,8 @@ mod tests { }, "substrateTest": { "authorities": [ - AccountKeyring::Ferdie.public().to_ss58check(), - AccountKeyring::Alice.public().to_ss58check() + Sr25519Keyring::Ferdie.public().to_ss58check(), + Sr25519Keyring::Alice.public().to_ss58check() ], } }); @@ -1502,8 +1502,8 @@ mod tests { let authority_key_vec = Vec::::decode(&mut &value[..]).unwrap(); assert_eq!(authority_key_vec.len(), 2); - assert_eq!(authority_key_vec[0], AccountKeyring::Ferdie.public()); - assert_eq!(authority_key_vec[1], AccountKeyring::Alice.public()); + assert_eq!(authority_key_vec[0], Sr25519Keyring::Ferdie.public()); + assert_eq!(authority_key_vec[1], Sr25519Keyring::Alice.public()); //Babe|Authorities let value: Vec = get_from_storage( diff --git a/substrate/test-utils/runtime/transaction-pool/src/lib.rs b/substrate/test-utils/runtime/transaction-pool/src/lib.rs index 6a4f38f63e82..93e5855eefc6 100644 --- a/substrate/test-utils/runtime/transaction-pool/src/lib.rs +++ b/substrate/test-utils/runtime/transaction-pool/src/lib.rs @@ -43,7 +43,7 @@ use substrate_test_runtime_client::{ AccountId, Block, BlockNumber, Extrinsic, ExtrinsicBuilder, Hash, Header, Nonce, Transfer, TransferData, }, - AccountKeyring::{self, *}, + Sr25519Keyring::{self, *}, }; /// Error type used by [`TestApi`]. @@ -338,7 +338,7 @@ trait TagFrom { impl TagFrom for AccountId { fn tag_from(&self) -> u8 { - let f = AccountKeyring::iter().enumerate().find(|k| AccountId::from(k.1) == *self); + let f = Sr25519Keyring::iter().enumerate().find(|k| AccountId::from(k.1) == *self); u8::try_from(f.unwrap().0).unwrap() } } @@ -534,7 +534,7 @@ impl sp_blockchain::HeaderMetadata for TestApi { /// Generate transfer extrinsic with a given nonce. /// /// Part of the test api. -pub fn uxt(who: AccountKeyring, nonce: Nonce) -> Extrinsic { +pub fn uxt(who: Sr25519Keyring, nonce: Nonce) -> Extrinsic { let dummy = codec::Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap(); let transfer = Transfer { from: who.into(), to: dummy, nonce, amount: 1 }; ExtrinsicBuilder::new_transfer(transfer).build() diff --git a/substrate/utils/frame/rpc/system/src/lib.rs b/substrate/utils/frame/rpc/system/src/lib.rs index 824c871a3562..e1b3994c03dd 100644 --- a/substrate/utils/frame/rpc/system/src/lib.rs +++ b/substrate/utils/frame/rpc/system/src/lib.rs @@ -224,7 +224,7 @@ mod tests { transaction_validity::{InvalidTransaction, TransactionValidityError}, ApplyExtrinsicResult, }; - use substrate_test_runtime_client::{runtime::Transfer, AccountKeyring}; + use substrate_test_runtime_client::{runtime::Transfer, Sr25519Keyring}; fn deny_unsafe() -> Extensions { let mut ext = Extensions::new(); @@ -256,8 +256,8 @@ mod tests { let source = sp_runtime::transaction_validity::TransactionSource::External; let new_transaction = |nonce: u64| { let t = Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), amount: 5, nonce, }; @@ -273,7 +273,7 @@ mod tests { let accounts = System::new(client, pool); // when - let nonce = accounts.nonce(AccountKeyring::Alice.into()).await; + let nonce = accounts.nonce(Sr25519Keyring::Alice.into()).await; // then assert_eq!(nonce.unwrap(), 2); @@ -321,8 +321,8 @@ mod tests { let accounts = System::new(client, pool); let tx = Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), amount: 5, nonce: 0, } @@ -357,8 +357,8 @@ mod tests { let accounts = System::new(client, pool); let tx = Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), + from: Sr25519Keyring::Alice.into(), + to: Sr25519Keyring::Bob.into(), amount: 5, nonce: 100, } diff --git a/templates/minimal/runtime/src/lib.rs b/templates/minimal/runtime/src/lib.rs index 7b8449f2abe4..72eded5bfd13 100644 --- a/templates/minimal/runtime/src/lib.rs +++ b/templates/minimal/runtime/src/lib.rs @@ -41,7 +41,7 @@ pub mod genesis_config_presets { use super::*; use crate::{ interface::{Balance, MinimumBalance}, - sp_keyring::AccountKeyring, + sp_keyring::Sr25519Keyring, BalancesConfig, RuntimeGenesisConfig, SudoConfig, }; @@ -53,11 +53,11 @@ pub mod genesis_config_presets { let endowment = >::get().max(1) * 1000; frame_support::build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { - balances: AccountKeyring::iter() + balances: Sr25519Keyring::iter() .map(|a| (a.to_account_id(), endowment)) .collect::>(), }, - sudo: SudoConfig { key: Some(AccountKeyring::Alice.to_account_id()) }, + sudo: SudoConfig { key: Some(Sr25519Keyring::Alice.to_account_id()) }, }) } diff --git a/templates/solochain/runtime/src/genesis_config_presets.rs b/templates/solochain/runtime/src/genesis_config_presets.rs index 049f4593451b..6af8dc9cd18a 100644 --- a/templates/solochain/runtime/src/genesis_config_presets.rs +++ b/templates/solochain/runtime/src/genesis_config_presets.rs @@ -22,7 +22,7 @@ use serde_json::Value; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_genesis_builder::{self, PresetId}; -use sp_keyring::AccountKeyring; +use sp_keyring::Sr25519Keyring; // Returns the genesis config presets populated with given parameters. fn testnet_genesis( @@ -56,12 +56,12 @@ pub fn development_config_genesis() -> Value { sp_keyring::Ed25519Keyring::Alice.public().into(), )], vec![ - AccountKeyring::Alice.to_account_id(), - AccountKeyring::Bob.to_account_id(), - AccountKeyring::AliceStash.to_account_id(), - AccountKeyring::BobStash.to_account_id(), + Sr25519Keyring::Alice.to_account_id(), + Sr25519Keyring::Bob.to_account_id(), + Sr25519Keyring::AliceStash.to_account_id(), + Sr25519Keyring::BobStash.to_account_id(), ], - sp_keyring::AccountKeyring::Alice.to_account_id(), + sp_keyring::Sr25519Keyring::Alice.to_account_id(), ) } @@ -78,11 +78,11 @@ pub fn local_config_genesis() -> Value { sp_keyring::Ed25519Keyring::Bob.public().into(), ), ], - AccountKeyring::iter() - .filter(|v| v != &AccountKeyring::One && v != &AccountKeyring::Two) + Sr25519Keyring::iter() + .filter(|v| v != &Sr25519Keyring::One && v != &Sr25519Keyring::Two) .map(|v| v.to_account_id()) .collect::>(), - AccountKeyring::Alice.to_account_id(), + Sr25519Keyring::Alice.to_account_id(), ) } From c808a0097cd83c141b8ff6362876ee689d5fdabf Mon Sep 17 00:00:00 2001 From: Maksym H <1177472+mordamax@users.noreply.github.com> Date: Tue, 10 Dec 2024 10:47:15 +0000 Subject: [PATCH 33/51] Let cmd bot to trigger ci on commit (#6813) Fixes: https://github.com/paritytech/ci_cd/issues/1079 Improvements: - switch to github native token creation action - refresh branch in CI from HEAD, to prevent failure - add APP token when pushing, to allow CI to be retriggering by bot --- .github/workflows/cmd.yml | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cmd.yml b/.github/workflows/cmd.yml index 6cd1adec1d8b..b6a50ea0d15e 100644 --- a/.github/workflows/cmd.yml +++ b/.github/workflows/cmd.yml @@ -19,10 +19,10 @@ jobs: steps: - name: Generate token id: generate_token - uses: tibdex/github-app-token@v2.1.0 + uses: actions/create-github-app-token@v1 with: - app_id: ${{ secrets.CMD_BOT_APP_ID }} - private_key: ${{ secrets.CMD_BOT_APP_KEY }} + app-id: ${{ secrets.CMD_BOT_APP_ID }} + private-key: ${{ secrets.CMD_BOT_APP_KEY }} - name: Check if user is a member of the organization id: is-member @@ -292,9 +292,17 @@ jobs: image: ${{ needs.set-image.outputs.IMAGE }} timeout-minutes: 1440 # 24 hours per runtime steps: + - name: Generate token + uses: actions/create-github-app-token@v1 + id: generate_token + with: + app-id: ${{ secrets.CMD_BOT_APP_ID }} + private-key: ${{ secrets.CMD_BOT_APP_KEY }} + - name: Checkout uses: actions/checkout@v4 with: + token: ${{ steps.generate_token.outputs.token }} repository: ${{ needs.get-pr-branch.outputs.repo }} ref: ${{ needs.get-pr-branch.outputs.pr-branch }} @@ -395,16 +403,30 @@ jobs: - name: Commit changes run: | if [ -n "$(git status --porcelain)" ]; then - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" + git config --global user.name command-bot + git config --global user.email "<>" + git config --global pull.rebase false + + # Push the results to the target branch + git remote add \ + github \ + "https://token:${{ steps.generate_token.outputs.token }}@github.com/${{ github.event.repository.owner.login }}/${{ github.event.repository.name }}.git" || : + + push_changes() { + git push github "HEAD:${{ needs.get-pr-branch.outputs.pr-branch }}" + } git add . git restore --staged Cargo.lock # ignore changes in Cargo.lock git commit -m "Update from ${{ github.actor }} running command '${{ steps.get-pr-comment.outputs.group2 }}'" || true - git pull --rebase origin ${{ needs.get-pr-branch.outputs.pr-branch }} - - git push origin ${{ needs.get-pr-branch.outputs.pr-branch }} + # Attempt to push changes + if ! push_changes; then + echo "Push failed, trying to rebase..." + git pull --rebase github "${{ needs.get-pr-branch.outputs.pr-branch }}" + # After successful rebase, try pushing again + push_changes + fi else echo "Nothing to commit"; fi From 19bc578e60d13a17f42e1ee7a960b1671985b9e4 Mon Sep 17 00:00:00 2001 From: Kazunobu Ndong <33208377+ndkazu@users.noreply.github.com> Date: Tue, 10 Dec 2024 20:26:25 +0900 Subject: [PATCH 34/51] polkadot-sdk-docs: Use command_macro! (#6624) # Description **Understood assignment:** Initial assignment description is in #6194. In order to Simplify the display of commands and ensure they are tested for chain spec builder's `polkadot-sdk` reference docs, find every occurrence of `#[docify::export]` where `process:Command` is used, and replace the use of `process:Command` by `run_cmd!` from the `cmd_lib crate`. --------- Co-authored-by: Iulian Barbu <14218860+iulianbarbu@users.noreply.github.com> --- Cargo.lock | 2 + docs/sdk/Cargo.toml | 1 + docs/sdk/src/guides/your_first_node.rs | 24 +- .../src/reference_docs/chain_spec_genesis.rs | 8 +- .../chain_spec_runtime/Cargo.toml | 1 + .../tests/chain_spec_builder_tests.rs | 290 +++++++++--------- prdoc/pr_6624.prdoc | 11 + 7 files changed, 171 insertions(+), 166 deletions(-) create mode 100644 prdoc/pr_6624.prdoc diff --git a/Cargo.lock b/Cargo.lock index 8aa03954467d..989430fdfe29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3171,6 +3171,7 @@ dependencies = [ name = "chain-spec-guide-runtime" version = "0.0.0" dependencies = [ + "cmd_lib", "docify", "frame-support 28.0.0", "pallet-balances 28.0.0", @@ -19054,6 +19055,7 @@ version = "0.0.1" dependencies = [ "assert_cmd", "chain-spec-guide-runtime", + "cmd_lib", "cumulus-client-service", "cumulus-pallet-aura-ext 0.7.0", "cumulus-pallet-parachain-system 0.7.0", diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml index 0c39367eeed3..0e4a5c001382 100644 --- a/docs/sdk/Cargo.toml +++ b/docs/sdk/Cargo.toml @@ -138,4 +138,5 @@ first-pallet = { workspace = true, default-features = true } [dev-dependencies] assert_cmd = "2.0.14" +cmd_lib = { workspace = true } rand = "0.8" diff --git a/docs/sdk/src/guides/your_first_node.rs b/docs/sdk/src/guides/your_first_node.rs index da37c11c206f..3c782e4793ba 100644 --- a/docs/sdk/src/guides/your_first_node.rs +++ b/docs/sdk/src/guides/your_first_node.rs @@ -103,6 +103,7 @@ #[cfg(test)] mod tests { use assert_cmd::Command; + use cmd_lib::*; use rand::Rng; use sc_chain_spec::{DEV_RUNTIME_PRESET, LOCAL_TESTNET_RUNTIME_PRESET}; use sp_genesis_builder::PresetId; @@ -173,13 +174,10 @@ mod tests { println!("Building polkadot-sdk-docs-first-runtime..."); #[docify::export_content] fn build_runtime() { - Command::new("cargo") - .arg("build") - .arg("--release") - .arg("-p") - .arg(FIRST_RUNTIME) - .assert() - .success(); + run_cmd!( + cargo build --release -p $FIRST_RUNTIME + ) + .expect("Failed to run command"); } build_runtime() } @@ -274,14 +272,10 @@ mod tests { let chain_spec_builder = find_release_binary(&CHAIN_SPEC_BUILDER).unwrap(); let runtime_path = find_wasm(PARA_RUNTIME).unwrap(); let output = "/tmp/demo-chain-spec.json"; - Command::new(chain_spec_builder) - .args(["-c", output]) - .arg("create") - .args(["--para-id", "1000", "--relay-chain", "dontcare"]) - .args(["-r", runtime_path.to_str().unwrap()]) - .args(["named-preset", "development"]) - .assert() - .success(); + let runtime_str = runtime_path.to_str().unwrap(); + run_cmd!( + $chain_spec_builder -c $output create --para-id 1000 --relay-chain dontcare -r $runtime_str named-preset development + ).expect("Failed to run command"); std::fs::remove_file(output).unwrap(); } build_para_chain_spec_works(); diff --git a/docs/sdk/src/reference_docs/chain_spec_genesis.rs b/docs/sdk/src/reference_docs/chain_spec_genesis.rs index b7a0a648d0cf..d5cc482711ad 100644 --- a/docs/sdk/src/reference_docs/chain_spec_genesis.rs +++ b/docs/sdk/src/reference_docs/chain_spec_genesis.rs @@ -174,13 +174,13 @@ //! ``` //! Here are some examples in the form of rust tests: //! ## Listing available preset names: -#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", list_presets)] +#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_list_presets)] //! ## Displaying preset with given name -#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", get_preset)] +#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_get_preset)] //! ## Building a solo chain-spec (the default) using given preset -#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", generate_chain_spec)] +#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_generate_chain_spec)] //! ## Building a parachain chain-spec using given preset -#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", generate_para_chain_spec)] +#![doc = docify::embed!("./src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs", cmd_generate_para_chain_spec)] //! //! [`RuntimeGenesisConfig`]: //! chain_spec_guide_runtime::runtime::RuntimeGenesisConfig diff --git a/docs/sdk/src/reference_docs/chain_spec_runtime/Cargo.toml b/docs/sdk/src/reference_docs/chain_spec_runtime/Cargo.toml index 07c0342f5fbe..307e2daa38c6 100644 --- a/docs/sdk/src/reference_docs/chain_spec_runtime/Cargo.toml +++ b/docs/sdk/src/reference_docs/chain_spec_runtime/Cargo.toml @@ -42,6 +42,7 @@ substrate-wasm-builder = { optional = true, workspace = true, default-features = [dev-dependencies] chain-spec-builder = { workspace = true, default-features = true } +cmd_lib = { workspace = true } sc-chain-spec = { workspace = true, default-features = true } [features] diff --git a/docs/sdk/src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs b/docs/sdk/src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs index df400b68f79d..b773af24de80 100644 --- a/docs/sdk/src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs +++ b/docs/sdk/src/reference_docs/chain_spec_runtime/tests/chain_spec_builder_tests.rs @@ -1,5 +1,6 @@ +use cmd_lib::*; use serde_json::{json, Value}; -use std::{process::Command, str}; +use std::str; fn wasm_file_path() -> &'static str { chain_spec_guide_runtime::runtime::WASM_BINARY_PATH @@ -8,189 +9,184 @@ fn wasm_file_path() -> &'static str { const CHAIN_SPEC_BUILDER_PATH: &str = "../../../../../target/release/chain-spec-builder"; +macro_rules! bash( + ( chain-spec-builder $($a:tt)* ) => {{ + let path = get_chain_spec_builder_path(); + spawn_with_output!( + $path $($a)* + ) + .expect("a process running. qed") + .wait_with_output() + .expect("to get output. qed.") + + }} +); + fn get_chain_spec_builder_path() -> &'static str { - // dev-dependencies do not build binary. So let's do the naive work-around here: - let _ = std::process::Command::new("cargo") - .arg("build") - .arg("--release") - .arg("-p") - .arg("staging-chain-spec-builder") - .arg("--bin") - .arg("chain-spec-builder") - .status() - .expect("Failed to execute command"); + run_cmd!( + cargo build --release -p staging-chain-spec-builder --bin chain-spec-builder + ) + .expect("Failed to execute command"); CHAIN_SPEC_BUILDER_PATH } +#[docify::export_content] +fn cmd_list_presets(runtime_path: &str) -> String { + bash!( + chain-spec-builder list-presets -r $runtime_path + ) +} + #[test] -#[docify::export] fn list_presets() { - let output = Command::new(get_chain_spec_builder_path()) - .arg("list-presets") - .arg("-r") - .arg(wasm_file_path()) - .output() - .expect("Failed to execute command"); - - let output: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); + let output: serde_json::Value = + serde_json::from_slice(cmd_list_presets(wasm_file_path()).as_bytes()).unwrap(); + assert_eq!( + output, + json!({ + "presets":[ + "preset_1", + "preset_2", + "preset_3", + "preset_4", + "preset_invalid" + ] + }), + "Output did not match expected" + ); +} - let expected_output = json!({ - "presets":[ - "preset_1", - "preset_2", - "preset_3", - "preset_4", - "preset_invalid" - ] - }); - assert_eq!(output, expected_output, "Output did not match expected"); +#[docify::export_content] +fn cmd_get_preset(runtime_path: &str) -> String { + bash!( + chain-spec-builder display-preset -r $runtime_path -p preset_2 + ) } #[test] -#[docify::export] fn get_preset() { - let output = Command::new(get_chain_spec_builder_path()) - .arg("display-preset") - .arg("-r") - .arg(wasm_file_path()) - .arg("-p") - .arg("preset_2") - .output() - .expect("Failed to execute command"); - - let output: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); - - //note: copy of chain_spec_guide_runtime::preset_2 - let expected_output = json!({ - "bar": { - "initialAccount": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", - }, - "foo": { - "someEnum": { - "Data2": { - "values": "0x0c10" - } + let output: serde_json::Value = + serde_json::from_slice(cmd_get_preset(wasm_file_path()).as_bytes()).unwrap(); + assert_eq!( + output, + json!({ + "bar": { + "initialAccount": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", }, - "someInteger": 200 - }, - }); - assert_eq!(output, expected_output, "Output did not match expected"); + "foo": { + "someEnum": { + "Data2": { + "values": "0x0c10" + } + }, + "someInteger": 200 + }, + }), + "Output did not match expected" + ); +} + +#[docify::export_content] +fn cmd_generate_chain_spec(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c /dev/stdout create -r $runtime_path named-preset preset_2 + ) } #[test] -#[docify::export] fn generate_chain_spec() { - let output = Command::new(get_chain_spec_builder_path()) - .arg("-c") - .arg("/dev/stdout") - .arg("create") - .arg("-r") - .arg(wasm_file_path()) - .arg("named-preset") - .arg("preset_2") - .output() - .expect("Failed to execute command"); - - let mut output: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); - - //remove code field for better readability + let mut output: serde_json::Value = + serde_json::from_slice(cmd_generate_chain_spec(wasm_file_path()).as_bytes()).unwrap(); if let Some(code) = output["genesis"]["runtimeGenesis"].as_object_mut().unwrap().get_mut("code") { *code = Value::String("0x123".to_string()); } - - let expected_output = json!({ - "name": "Custom", - "id": "custom", - "chainType": "Live", - "bootNodes": [], - "telemetryEndpoints": null, - "protocolId": null, - "properties": { "tokenDecimals": 12, "tokenSymbol": "UNIT" }, - "codeSubstitutes": {}, - "genesis": { - "runtimeGenesis": { - "code": "0x123", - "patch": { - "bar": { - "initialAccount": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL" - }, - "foo": { - "someEnum": { - "Data2": { - "values": "0x0c10" + assert_eq!( + output, + json!({ + "name": "Custom", + "id": "custom", + "chainType": "Live", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "properties": { "tokenDecimals": 12, "tokenSymbol": "UNIT" }, + "codeSubstitutes": {}, + "genesis": { + "runtimeGenesis": { + "code": "0x123", + "patch": { + "bar": { + "initialAccount": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL" + }, + "foo": { + "someEnum": { + "Data2": { + "values": "0x0c10" + } + }, + "someInteger": 200 } - }, - "someInteger": 200 + } } } - } - } - }); - assert_eq!(output, expected_output, "Output did not match expected"); + }), + "Output did not match expected" + ); +} + +#[docify::export_content] +fn cmd_generate_para_chain_spec(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c /dev/stdout create -c polkadot -p 1000 -r $runtime_path named-preset preset_2 + ) } #[test] -#[docify::export] fn generate_para_chain_spec() { - let output = Command::new(get_chain_spec_builder_path()) - .arg("-c") - .arg("/dev/stdout") - .arg("create") - .arg("-c") - .arg("polkadot") - .arg("-p") - .arg("1000") - .arg("-r") - .arg(wasm_file_path()) - .arg("named-preset") - .arg("preset_2") - .output() - .expect("Failed to execute command"); - - let mut output: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); - - //remove code field for better readability + let mut output: serde_json::Value = + serde_json::from_slice(cmd_generate_para_chain_spec(wasm_file_path()).as_bytes()).unwrap(); if let Some(code) = output["genesis"]["runtimeGenesis"].as_object_mut().unwrap().get_mut("code") { *code = Value::String("0x123".to_string()); } - - let expected_output = json!({ - "name": "Custom", - "id": "custom", - "chainType": "Live", - "bootNodes": [], - "telemetryEndpoints": null, - "protocolId": null, - "relay_chain": "polkadot", - "para_id": 1000, - "properties": { "tokenDecimals": 12, "tokenSymbol": "UNIT" }, - "codeSubstitutes": {}, - "genesis": { - "runtimeGenesis": { - "code": "0x123", - "patch": { - "bar": { - "initialAccount": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL" - }, - "foo": { - "someEnum": { - "Data2": { - "values": "0x0c10" - } + assert_eq!( + output, + json!({ + "name": "Custom", + "id": "custom", + "chainType": "Live", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "relay_chain": "polkadot", + "para_id": 1000, + "properties": { "tokenDecimals": 12, "tokenSymbol": "UNIT" }, + "codeSubstitutes": {}, + "genesis": { + "runtimeGenesis": { + "code": "0x123", + "patch": { + "bar": { + "initialAccount": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL" }, - "someInteger": 200 + "foo": { + "someEnum": { + "Data2": { + "values": "0x0c10" + } + }, + "someInteger": 200 + } } } - } - } - }); - assert_eq!(output, expected_output, "Output did not match expected"); + }}), + "Output did not match expected" + ); } #[test] -#[docify::export] +#[docify::export_content] fn preset_4_json() { assert_eq!( chain_spec_guide_runtime::presets::preset_4(), diff --git a/prdoc/pr_6624.prdoc b/prdoc/pr_6624.prdoc new file mode 100644 index 000000000000..4db55a46e8df --- /dev/null +++ b/prdoc/pr_6624.prdoc @@ -0,0 +1,11 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Use `cmd_lib` instead of `std::process::Command` when using `#[docify::export]` + +doc: + - audience: Runtime Dev + description: | + Simplified the display of commands and ensured they are tested for chain spec builder's `polkadot-sdk` reference docs. + +crates: [] \ No newline at end of file From 65a4e5ee06b11844d536730379d4e1cab337beb4 Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:40:28 +0200 Subject: [PATCH 35/51] Fix order of resending messages after restart (#6729) The way we build the messages we need to send to approval-distribution can result in a situation where is we have multiple assignments covered by a coalesced approval, the messages are sent in this order: ASSIGNMENT1, APPROVAL, ASSIGNMENT2, because we iterate over each candidate and add to the queue of messages both the assignment and the approval for that candidate, and when the approval reaches the approval-distribution subsystem it won't be imported and gossiped because one of the assignment for it is not known. So in a network where a lot of nodes are restarting at the same time we could end up in a situation where a set of the nodes correctly received the assignments and approvals before the restart and approve their blocks and don't trigger their assignments. The other set of nodes should receive the assignments and approvals after the restart, but because the approvals never get broacasted anymore because of this bug, the only way they could approve is if other nodes start broadcasting their assignments. I think this bug contribute to the reason the network did not recovered on `25-11-25 15:55:40` after the restarts. Tested this scenario with a `zombienet` where `nodes` are finalising blocks because of aggression and all nodes are restarted at once and confirmed the network lags and doesn't recover before and it does after the fix --------- Signed-off-by: Alexandru Gheorghe --- polkadot/node/core/approval-voting/src/lib.rs | 12 +- .../node/core/approval-voting/src/tests.rs | 314 ++++++++++++++++++ prdoc/pr_6729.prdoc | 15 + 3 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 prdoc/pr_6729.prdoc diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 2176cc7675be..7cea22d1a6a7 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -1582,8 +1582,9 @@ async fn handle_actions< session_info_provider, ) .await?; - - approval_voting_sender.send_messages(messages.into_iter()).await; + for message in messages.into_iter() { + approval_voting_sender.send_unbounded_message(message); + } let next_actions: Vec = next_actions.into_iter().map(|v| v.clone()).chain(actions_iter).collect(); @@ -1668,6 +1669,7 @@ async fn distribution_messages_for_activation, +) -> (ChainBuilder, SessionInfo) { + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + let candidates = Some( + candidate_receipt + .iter() + .enumerate() + .map(|(i, receipt)| (receipt.clone(), CoreIndex(i as u32), GroupIndex(i as u32))) + .collect(), + ); + let mut chain_builder = ChainBuilder::new(); + + chain_builder + .major_syncing(sync_oracle_handle.is_major_syncing.clone()) + .add_block( + block_hash1, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot, + candidates: candidates.clone(), + session_info: Some(session_info.clone()), + end_syncing: true, + }, + ); + (chain_builder, session_info) +} + +async fn setup_overseer_with_blocks_with_two_assignments_triggered( + virtual_overseer: &mut VirtualOverseer, + store: TestStore, + clock: &Arc, + sync_oracle_handle: TestSyncOracleHandle, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt_v2(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let candidate_hash = candidate_receipt.hash(); + + let mut candidate_commitments2 = CandidateCommitments::default(); + candidate_commitments2.processed_downward_messages = 3; + let mut candidate_receipt2 = dummy_candidate_receipt_v2(block_hash); + candidate_receipt2.commitments_hash = candidate_commitments2.hash(); + let candidate_hash2 = candidate_receipt2.hash(); + + let slot = Slot::from(1); + let (chain_builder, _session_info) = build_chain_with_block_with_two_candidates( + block_hash, + slot, + sync_oracle_handle, + vec![candidate_receipt, candidate_receipt2], + ) + .await; + chain_builder.build(virtual_overseer).await; + + assert!(!clock.inner.lock().current_wakeup_is(1)); + clock.inner.lock().wakeup_all(1); + + assert!(clock.inner.lock().current_wakeup_is(slot_to_tick(slot))); + clock.inner.lock().wakeup_all(slot_to_tick(slot)); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + clock.inner.lock().wakeup_all(slot_to_tick(slot + 2)); + + assert_eq!(clock.inner.lock().wakeups.len(), 0); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + let our_assignment = + candidate_entry.approval_entry(&block_hash).unwrap().our_assignment().unwrap(); + assert!(our_assignment.triggered()); + + let candidate_entry = store.load_candidate_entry(&candidate_hash2).unwrap().unwrap(); + let our_assignment = + candidate_entry.approval_entry(&block_hash).unwrap().our_assignment().unwrap(); + assert!(our_assignment.triggered()); +} + // Tests that for candidates that we did not approve yet, for which we triggered the assignment and // the approval work we restart the work to approve it. #[test] @@ -4920,6 +5028,212 @@ fn subsystem_sends_pending_approvals_on_approval_restart() { }); } +// Test that after restart approvals are sent after all assignments have been distributed. +#[test] +fn subsystem_sends_assignment_approval_in_correct_order_on_approval_restart() { + let assignment_criteria = Box::new(MockAssignmentCriteria( + || { + let mut assignments = HashMap::new(); + + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert_v2(AssignmentCertKindV2::RelayVRFModuloCompact { + core_bitfield: vec![CoreIndex(0), CoreIndex(2)].try_into().unwrap(), + }), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + + let _ = assignments.insert( + CoreIndex(1), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert_v2(AssignmentCertKindV2::RelayVRFDelay { + core_index: CoreIndex(1), + }), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + assignments + }, + |_| Ok(0), + )); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + let store_clone = config.backend(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + setup_overseer_with_blocks_with_two_assignments_triggered( + &mut virtual_overseer, + store, + &clock, + sync_oracle_handle, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _ + )) => { + } + ); + + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive { + exec_kind, + response_sender, + .. + }) if exec_kind == PvfExecKind::Approval => { + response_sender.send(Ok(ValidationResult::Valid(Default::default(), Default::default()))) + .unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive { + exec_kind, + response_sender, + .. + }) if exec_kind == PvfExecKind::Approval => { + response_sender.send(Ok(ValidationResult::Valid(Default::default(), Default::default()))) + .unwrap(); + } + ); + + // Configure a big coalesce number, so that the signature is cached instead of being sent to + // approval-distribution. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 2, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 2, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); + + let config = HarnessConfigBuilder::default().backend(store_clone).major_syncing(true).build(); + // On restart we should first distribute all assignments covering a coalesced approval. + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt_v2(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + + let mut candidate_commitments2 = CandidateCommitments::default(); + candidate_commitments2.processed_downward_messages = 3; + let mut candidate_receipt2 = dummy_candidate_receipt_v2(block_hash); + candidate_receipt2.commitments_hash = candidate_commitments2.hash(); + + let slot = Slot::from(1); + + clock.inner.lock().set_tick(slot_to_tick(slot + 2)); + let (chain_builder, _session_info) = build_chain_with_block_with_two_candidates( + block_hash, + slot, + sync_oracle_handle, + vec![candidate_receipt.into(), candidate_receipt2.into()], + ) + .await; + chain_builder.build(&mut virtual_overseer).await; + + futures_timer::Delay::new(Duration::from_millis(2000)).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks( + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(approval)) => { + assert_eq!(approval.candidate_indices.count_ones(), 2); + } + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); +} + // Test we correctly update the timer when we mark the beginning of gathering assignments. #[test] fn test_gathering_assignments_statements() { diff --git a/prdoc/pr_6729.prdoc b/prdoc/pr_6729.prdoc new file mode 100644 index 000000000000..9eaa67363c9a --- /dev/null +++ b/prdoc/pr_6729.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Fix order of resending messages after restart + +doc: + - audience: Node Dev + description: | + At restart when dealing with a coalesced approval we might end up in a situation where we sent to + approval-distribution the approval before all assignments covering it, in that case, the approval + is ignored and never distribute, which will lead to no-shows. + +crates: + - name: polkadot-node-core-approval-voting + bump: minor From fe4846f54838c23de9fadf6ac92b0739e82c25b1 Mon Sep 17 00:00:00 2001 From: Ron Date: Wed, 11 Dec 2024 00:17:15 +0800 Subject: [PATCH 36/51] XCMv5: Fix for compatibility with V4 (#6503) ## Description Our smoke tests transfer `WETH` from Sepolia to Westend-AssetHub breaks, try to reregister `WETH` on AH but fails as following: https://bridgehub-westend.subscan.io/xcm_message/westend-4796d6b3600aca32ef63b9953acf6a456cfd2fbe https://assethub-westend.subscan.io/extrinsic/9731267-0?event=9731267-2 The reason is that the transact call encoded on BH to register the asset https://github.com/paritytech/polkadot-sdk/blob/a77940bac783108fcae783c553528c8d5328e5b2/bridges/snowbridge/primitives/router/src/inbound/mod.rs#L282-L289 ``` 0x3500020209079edaa8020300fff9976782d46cc05630d1f6ebab18b2324d6b1400ce796ae65569a670d0c1cc1ac12515a3ce21b5fbf729d63d7b289baad070139d01000000000000000000000000000000 ``` the `asset_id` which is the xcm location can't be decoded on AH in V5 Issue initial post in https://matrix.to/#/!qUtSTcfMJzBdPmpFKa:parity.io/$RNMAxIIOKGtBAqkgwiFuQf4eNaYpmOK-Pfw4d6vv1aU?via=parity.io&via=matrix.org&via=web3.foundation --------- Co-authored-by: Adrian Catangiu Co-authored-by: Francisco Aguirre --- .../pallets/inbound-queue/src/mock.rs | 14 ----------- .../pallets/inbound-queue/src/test.rs | 23 +++++++++---------- polkadot/xcm/src/v5/junction.rs | 4 ++++ prdoc/pr_6503.prdoc | 10 ++++++++ 4 files changed, 25 insertions(+), 26 deletions(-) create mode 100644 prdoc/pr_6503.prdoc diff --git a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs index 675d4b691593..eed0656e9ca7 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs @@ -248,20 +248,6 @@ impl inbound_queue::Config for Test { type AssetTransactor = SuccessfulTransactor; } -pub fn last_events(n: usize) -> Vec { - frame_system::Pallet::::events() - .into_iter() - .rev() - .take(n) - .rev() - .map(|e| e.event) - .collect() -} - -pub fn expect_events(e: Vec) { - assert_eq!(last_events(e.len()), e); -} - pub fn setup() { System::set_block_number(1); Balances::mint_into( diff --git a/bridges/snowbridge/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/pallets/inbound-queue/src/test.rs index 053a341b54a0..aa99d63b4bf9 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/test.rs @@ -9,7 +9,7 @@ use sp_keyring::Sr25519Keyring as Keyring; use sp_runtime::DispatchError; use sp_std::convert::From; -use crate::{Error, Event as InboundQueueEvent}; +use crate::Error; use crate::mock::*; @@ -35,17 +35,16 @@ fn test_submit_happy_path() { assert_eq!(Balances::balance(&channel_sovereign), initial_fund); assert_ok!(InboundQueue::submit(origin.clone(), message.clone())); - expect_events(vec![InboundQueueEvent::MessageReceived { - channel_id: hex!("c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539") - .into(), - nonce: 1, - message_id: [ - 118, 166, 139, 182, 84, 52, 165, 189, 54, 14, 178, 73, 2, 228, 192, 97, 153, 201, - 4, 75, 151, 15, 82, 6, 164, 187, 162, 133, 26, 183, 186, 126, - ], - fee_burned: 110000000000, - } - .into()]); + + let events = frame_system::Pallet::::events(); + assert!( + events.iter().any(|event| matches!( + event.event, + RuntimeEvent::InboundQueue(Event::MessageReceived { nonce, ..}) + if nonce == 1 + )), + "no event emit." + ); let delivery_cost = InboundQueue::calculate_delivery_cost(message.encode().len() as u32); assert!( diff --git a/polkadot/xcm/src/v5/junction.rs b/polkadot/xcm/src/v5/junction.rs index 952b61cd9ffe..d86a762fcf44 100644 --- a/polkadot/xcm/src/v5/junction.rs +++ b/polkadot/xcm/src/v5/junction.rs @@ -143,16 +143,20 @@ pub enum NetworkId { /// The Kusama canary-net Relay-chain. Kusama, /// An Ethereum network specified by its chain ID. + #[codec(index = 7)] Ethereum { /// The EIP-155 chain ID. #[codec(compact)] chain_id: u64, }, /// The Bitcoin network, including hard-forks supported by Bitcoin Core development team. + #[codec(index = 8)] BitcoinCore, /// The Bitcoin network, including hard-forks supported by Bitcoin Cash developers. + #[codec(index = 9)] BitcoinCash, /// The Polkadot Bulletin chain. + #[codec(index = 10)] PolkadotBulletin, } diff --git a/prdoc/pr_6503.prdoc b/prdoc/pr_6503.prdoc new file mode 100644 index 000000000000..dc296a93f0eb --- /dev/null +++ b/prdoc/pr_6503.prdoc @@ -0,0 +1,10 @@ +title: "xcm: minor fix for compatibility with V4" + +doc: + - audience: ["Runtime Dev", "Runtime User"] + description: | + Following the removal of `Rococo`, `Westend` and `Wococo` from `NetworkId`, fixed `xcm::v5::NetworkId` encoding/decoding to be compatible with `xcm::v4::NetworkId` + +crates: +- name: staging-xcm + bump: patch From 48c28d4c8b396307fbc9130ad491cb7b15f99c4b Mon Sep 17 00:00:00 2001 From: Iulian Barbu <14218860+iulianbarbu@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:33:13 +0200 Subject: [PATCH 37/51] omni-node: --dev sets manual seal and allows --chain to be set (#6646) # Description This PR changes a few things: * `--dev` flag will not conflict with `--chain` anymore, but if `--chain` is not given will set `--chain=dev`. * `--dev-block-time` is optional and it defaults to 3000ms if not set after setting `--dev`. * to start OmniNode with manual seal it is enough to pass just `--dev`. * `--dev-block-time` can still be used to start a node with manual seal, but it will not set it up as `--dev` does (it will not set a bunch of flags which are enabled by default when `--dev` is set: e.g. `--tmp`, `--alice` and `--force-authoring`. Closes: #6537 ## Integration Relevant for node/runtime developers that use OmniNode lib, including `polkadot-omni-node` binary, although the recommended way for runtime development is to use `chopsticks`. ## Review Notes * Decided to focus only on OmniNode & templates docs in relation to it, and leave the `parachain-template-node` as is (meaning `--dev` isn't usable and testing a runtime with the `parachain-template-node` still needs a relay chain here). I am doing this because I think we want either way to phase out `parachain-template-node` and adding manual seal support for it is wasted effort. We might add support though if the demand is for `parachain-template-node`. * Decided to not infer the block time based on AURA config yet because there is still the option of setting a specific block time by using `--dev-block-time`. Also, would want first to align & merge on runtime metadata checks we added in Omni Node here: https://github.com/paritytech/polkadot-sdk/pull/6450 before starting to infer AURA config slot duration via the same way. - [x] update the docs to mention `--dev` now. - [x] mention about chopsticks in the context of runtime development --------- Signed-off-by: Iulian Barbu Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> --- cumulus/polkadot-omni-node/README.md | 4 +- cumulus/polkadot-omni-node/lib/src/cli.rs | 11 +++-- cumulus/polkadot-omni-node/lib/src/command.rs | 15 ++++++- prdoc/pr_6646.prdoc | 19 +++++++++ .../client/cli/src/params/shared_params.rs | 18 ++++----- templates/minimal/README.md | 9 ++--- templates/minimal/zombienet-omni-node.toml | 2 +- templates/parachain/README.md | 40 ++++++++++++++++--- 8 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 prdoc/pr_6646.prdoc diff --git a/cumulus/polkadot-omni-node/README.md b/cumulus/polkadot-omni-node/README.md index d87b3b63c407..015019961c9f 100644 --- a/cumulus/polkadot-omni-node/README.md +++ b/cumulus/polkadot-omni-node/README.md @@ -49,10 +49,10 @@ chain-spec-builder create --relay-chain --para-id -r +polkadot-omni-node --dev --chain ``` ## Useful links diff --git a/cumulus/polkadot-omni-node/lib/src/cli.rs b/cumulus/polkadot-omni-node/lib/src/cli.rs index dc59c185d909..9c4e2561592d 100644 --- a/cumulus/polkadot-omni-node/lib/src/cli.rs +++ b/cumulus/polkadot-omni-node/lib/src/cli.rs @@ -126,9 +126,14 @@ pub struct Cli { /// Start a dev node that produces a block each `dev_block_time` ms. /// - /// This is a dev option, and it won't result in starting or connecting to a parachain network. - /// The resulting node will work on its own, running the wasm blob and artificially producing - /// a block each `dev_block_time` ms, as if it was part of a parachain. + /// This is a dev option. It enables a manual sealing, meaning blocks are produced manually + /// rather than being part of an actual network consensus process. Using the option won't + /// result in starting or connecting to a parachain network. The resulting node will work on + /// its own, running the wasm blob and artificially producing a block each `dev_block_time` ms, + /// as if it was part of a parachain. + /// + /// The `--dev` flag sets the `dev_block_time` to a default value of 3000ms unless explicitly + /// provided. #[arg(long)] pub dev_block_time: Option, diff --git a/cumulus/polkadot-omni-node/lib/src/command.rs b/cumulus/polkadot-omni-node/lib/src/command.rs index cf283819966f..fe7f7cac0971 100644 --- a/cumulus/polkadot-omni-node/lib/src/command.rs +++ b/cumulus/polkadot-omni-node/lib/src/command.rs @@ -34,11 +34,13 @@ use cumulus_client_service::storage_proof_size::HostFunctions as ReclaimHostFunc use cumulus_primitives_core::ParaId; use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; use log::info; -use sc_cli::{Result, SubstrateCli}; +use sc_cli::{CliConfiguration, Result, SubstrateCli}; use sp_runtime::traits::AccountIdConversion; #[cfg(feature = "runtime-benchmarks")] use sp_runtime::traits::HashingFor; +const DEFAULT_DEV_BLOCK_TIME_MS: u64 = 3000; + /// Structure that can be used in order to provide customizers for different functionalities of the /// node binary that is being built using this library. pub struct RunConfig { @@ -230,10 +232,19 @@ pub fn run(cmd_config: RunConfig) -> Result<() .ok_or("Could not find parachain extension in chain-spec.")?, ); + if cli.run.base.is_dev()? { + // Set default dev block time to 3000ms if not set. + // TODO: take block time from AURA config if set. + let dev_block_time = cli.dev_block_time.unwrap_or(DEFAULT_DEV_BLOCK_TIME_MS); + return node_spec + .start_manual_seal_node(config, para_id, dev_block_time) + .map_err(Into::into); + } + if let Some(dev_block_time) = cli.dev_block_time { return node_spec .start_manual_seal_node(config, para_id, dev_block_time) - .map_err(Into::into) + .map_err(Into::into); } // If Statemint (Statemine, Westmint, Rockmine) DB exists and we're using the diff --git a/prdoc/pr_6646.prdoc b/prdoc/pr_6646.prdoc new file mode 100644 index 000000000000..4dcda8d41bda --- /dev/null +++ b/prdoc/pr_6646.prdoc @@ -0,0 +1,19 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: OmniNode --dev flag starts node with manual seal + +doc: + - audience: [ Runtime Dev, Node Dev ] + description: | + `polkadot-omni-node` lib supports `--dev` flag now by allowing also to pass over a chain spec, + and starts the node with manual seal. It will seal the node at each `dev_block_time` milliseconds, + which can be set via `--dev-block-time`, and if not set will default to `3000ms`. + +crates: + - name: sc-cli + bump: patch + - name: polkadot-omni-node-lib + bump: patch + - name: polkadot-omni-node + bump: patch diff --git a/substrate/client/cli/src/params/shared_params.rs b/substrate/client/cli/src/params/shared_params.rs index 465372fba17d..e0c52deb44ca 100644 --- a/substrate/client/cli/src/params/shared_params.rs +++ b/substrate/client/cli/src/params/shared_params.rs @@ -33,10 +33,12 @@ pub struct SharedParams { /// Specify the development chain. /// - /// This flag sets `--chain=dev`, `--force-authoring`, `--rpc-cors=all`, - /// `--alice`, and `--tmp` flags, unless explicitly overridden. - /// It also disables local peer discovery (see --no-mdns and --discover-local) - #[arg(long, conflicts_with_all = &["chain"])] + /// This flag sets `--chain=dev`, `--force-authoring`, `--rpc-cors=all`, `--alice`, and `--tmp` + /// flags, unless explicitly overridden. It also disables local peer discovery (see `--no-mdns` + /// and `--discover-local`). With this flag some nodes might start with manual seal, producing + /// blocks at certain events (e.g. `polkadot-omni-node`, which produces blocks at certain + /// intervals dictated by `--dev-block-time`). + #[arg(long)] pub dev: bool, /// Specify custom base path. @@ -109,12 +111,8 @@ impl SharedParams { pub fn chain_id(&self, is_dev: bool) -> String { match self.chain { Some(ref chain) => chain.clone(), - None => - if is_dev { - "dev".into() - } else { - "".into() - }, + None if is_dev => "dev".into(), + _ => "".into(), } } diff --git a/templates/minimal/README.md b/templates/minimal/README.md index cf43d71d8849..22f396c243ef 100644 --- a/templates/minimal/README.md +++ b/templates/minimal/README.md @@ -105,12 +105,11 @@ Omni Node, nonetheless. #### Run Omni Node -Start Omni Node with manual seal (3 seconds block times), minimal template runtime based -chain spec. We'll use `--tmp` flag to start the node with its configurations stored in a -temporary directory, which will be deleted at the end of the process. +Start Omni Node in development mode (sets up block production and finalization based on manual seal, +sealing a new block every 3 seconds), with a minimal template runtime chain spec. ```sh -polkadot-omni-node --chain --dev-block-time 3000 --tmp +polkadot-omni-node --chain --dev ``` ### Minimal Template Node @@ -160,7 +159,7 @@ Then make the changes in the network specification like so: # ... chain = "dev" chain_spec_path = "" -default_args = ["--dev-block-time 3000"] +default_args = ["--dev"] # .. ``` diff --git a/templates/minimal/zombienet-omni-node.toml b/templates/minimal/zombienet-omni-node.toml index 33b0fceba68c..acd5b121c674 100644 --- a/templates/minimal/zombienet-omni-node.toml +++ b/templates/minimal/zombienet-omni-node.toml @@ -2,7 +2,7 @@ default_command = "polkadot-omni-node" chain = "dev" chain_spec_path = "" -default_args = ["--dev-block-time 3000"] +default_args = ["--dev"] [[relaychain.nodes]] name = "alice" diff --git a/templates/parachain/README.md b/templates/parachain/README.md index 65a6979041f2..c1e333df9e9e 100644 --- a/templates/parachain/README.md +++ b/templates/parachain/README.md @@ -27,6 +27,7 @@ - [Connect with the Polkadot-JS Apps Front-End](#connect-with-the-polkadot-js-apps-front-end) - [Takeaways](#takeaways) +- [Runtime development](#runtime-development) - [Contributing](#contributing) - [Getting Help](#getting-help) @@ -107,13 +108,11 @@ with the relay chain ID where this instantiation of parachain-template will conn #### Run Omni Node -Start Omni Node with the generated chain spec. We'll start it development mode (without a relay chain config), -with a temporary directory for configuration (given `--tmp`), and block production set to create a block with -every second. +Start Omni Node with the generated chain spec. We'll start it in development mode (without a relay chain config), producing +and finalizing blocks based on manual seal, configured below to seal a block with each second. ```bash -polkadot-omni-node --chain --tmp --dev-block-time 1000 - +polkadot-omni-node --chain --dev --dev-block-time 1000 ``` However, such a setup is not close to what would run in production, and for that we need to setup a local @@ -197,6 +196,37 @@ Development parachains: - 💰 Are preconfigured with a genesis state that includes several prefunded development accounts. - 🧑‍⚖️ Development accounts are used as validators, collators, and `sudo` accounts. +## Runtime development + +We recommend using [`chopsticks`](https://github.com/AcalaNetwork/chopsticks) when the focus is more on the runtime +development and `OmniNode` is enough as is. + +### Install chopsticks + +To use `chopsticks`, please install the latest version according to the installation [guide](https://github.com/AcalaNetwork/chopsticks?tab=readme-ov-file#install). + +### Build a raw chain spec + +Build the `parachain-template-runtime` as mentioned before in this guide and use `chain-spec-builder` +again but this time by passing `--raw-storage` flag: + +```sh +chain-spec-builder create --raw-storage --relay-chain "rococo-local" --para-id 1000 --runtime \ + target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm named-preset development +``` + +### Start `chopsticks` with the chain spec + +```sh +npx @acala-network/chopsticks@latest --chain-spec +``` + +### Alternatives + +`OmniNode` can be still used for runtime development if using the `--dev` flag, while `parachain-template-node` doesn't +support it at this moment. It can still be used to test a runtime in a full setup where it is started alongside a +relay chain network (see [Parachain Template node](#parachain-template-node) setup). + ## Contributing - 🔄 This template is automatically updated after releases in the main [Polkadot SDK monorepo](https://github.com/paritytech/polkadot-sdk). From 99be9b1e8079315cb8fe2ce68497841f6049cde1 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Tue, 10 Dec 2024 20:26:30 -0500 Subject: [PATCH 38/51] [pallet-revive] eth-rpc add missing tests (#6728) Add tests for #6608 fix https://github.com/paritytech/contract-issues/issues/12 --------- Co-authored-by: command-bot <> --- prdoc/pr_6728.prdoc | 12 + substrate/frame/revive/rpc/Cargo.toml | 2 +- .../rpc/examples/js/abi/ErrorTester.json | 106 +++++++++ .../revive/rpc/examples/js/abi/ErrorTester.ts | 106 +++++++++ .../rpc/examples/js/abi/EventExample.json | 34 +++ .../rpc/examples/js/abi/EventExample.ts | 34 +++ .../revive/rpc/examples/js/abi/Flipper.json | 35 +++ .../revive/rpc/examples/js/abi/Flipper.ts | 35 +++ .../rpc/examples/js/abi/FlipperCaller.json | 46 ++++ .../rpc/examples/js/abi/FlipperCaller.ts | 46 ++++ .../revive/rpc/examples/js/abi/PiggyBank.json | 65 ++++++ .../rpc/examples/js/abi/RevertExample.ts | 14 ++ .../revive/rpc/examples/js/abi/errorTester.ts | 212 +++++++++--------- .../frame/revive/rpc/examples/js/abi/event.ts | 34 --- .../revive/rpc/examples/js/abi/piggyBank.ts | 130 +++++------ .../frame/revive/rpc/examples/js/bun.lockb | Bin 33662 -> 40649 bytes .../rpc/examples/js/contracts/Flipper.sol | 35 +++ .../rpc/examples/js/contracts/Revert.sol | 11 - .../frame/revive/rpc/examples/js/evm/.gitkeep | 0 .../rpc/examples/js/pvm/ErrorTester.polkavm | Bin 0 -> 8919 bytes .../rpc/examples/js/pvm/EventExample.polkavm | Bin 0 -> 4104 bytes .../rpc/examples/js/pvm/Flipper.polkavm | Bin 0 -> 1842 bytes .../rpc/examples/js/pvm/FlipperCaller.polkavm | Bin 0 -> 5803 bytes .../rpc/examples/js/pvm/PiggyBank.polkavm | Bin 0 -> 6470 bytes .../rpc/examples/js/pvm/errorTester.polkavm | Bin 12890 -> 0 bytes .../revive/rpc/examples/js/pvm/event.polkavm | Bin 5186 -> 0 bytes .../rpc/examples/js/pvm/piggyBank.polkavm | Bin 12334 -> 0 bytes .../revive/rpc/examples/js/pvm/revert.polkavm | Bin 2490 -> 0 bytes .../rpc/examples/js/src/build-contracts.ts | 79 ++++--- .../rpc/examples/js/src/geth-diff-setup.ts | 53 +++-- .../rpc/examples/js/src/geth-diff.test.ts | 106 +++++++-- substrate/frame/revive/rpc/src/tests.rs | 18 +- substrate/frame/revive/src/tests.rs | 102 ++++++++- 33 files changed, 1019 insertions(+), 296 deletions(-) create mode 100644 prdoc/pr_6728.prdoc create mode 100644 substrate/frame/revive/rpc/examples/js/abi/ErrorTester.json create mode 100644 substrate/frame/revive/rpc/examples/js/abi/ErrorTester.ts create mode 100644 substrate/frame/revive/rpc/examples/js/abi/EventExample.json create mode 100644 substrate/frame/revive/rpc/examples/js/abi/EventExample.ts create mode 100644 substrate/frame/revive/rpc/examples/js/abi/Flipper.json create mode 100644 substrate/frame/revive/rpc/examples/js/abi/Flipper.ts create mode 100644 substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.json create mode 100644 substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.ts create mode 100644 substrate/frame/revive/rpc/examples/js/abi/PiggyBank.json create mode 100644 substrate/frame/revive/rpc/examples/js/abi/RevertExample.ts delete mode 100644 substrate/frame/revive/rpc/examples/js/abi/event.ts create mode 100644 substrate/frame/revive/rpc/examples/js/contracts/Flipper.sol delete mode 100644 substrate/frame/revive/rpc/examples/js/contracts/Revert.sol create mode 100644 substrate/frame/revive/rpc/examples/js/evm/.gitkeep create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/ErrorTester.polkavm create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/EventExample.polkavm create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/Flipper.polkavm create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/FlipperCaller.polkavm create mode 100644 substrate/frame/revive/rpc/examples/js/pvm/PiggyBank.polkavm delete mode 100644 substrate/frame/revive/rpc/examples/js/pvm/errorTester.polkavm delete mode 100644 substrate/frame/revive/rpc/examples/js/pvm/event.polkavm delete mode 100644 substrate/frame/revive/rpc/examples/js/pvm/piggyBank.polkavm delete mode 100644 substrate/frame/revive/rpc/examples/js/pvm/revert.polkavm diff --git a/prdoc/pr_6728.prdoc b/prdoc/pr_6728.prdoc new file mode 100644 index 000000000000..68f61190d947 --- /dev/null +++ b/prdoc/pr_6728.prdoc @@ -0,0 +1,12 @@ +title: '[pallet-revive] eth-rpc add missing tests' +doc: +- audience: Runtime Dev + description: |- + Add tests for #6608 + + fix https://github.com/paritytech/contract-issues/issues/12 +crates: +- name: pallet-revive-eth-rpc + bump: minor +- name: pallet-revive + bump: minor diff --git a/substrate/frame/revive/rpc/Cargo.toml b/substrate/frame/revive/rpc/Cargo.toml index fe9cc82dd4d9..674abdd5b73e 100644 --- a/substrate/frame/revive/rpc/Cargo.toml +++ b/substrate/frame/revive/rpc/Cargo.toml @@ -76,6 +76,6 @@ example = ["hex-literal", "rlp", "secp256k1", "subxt-signer"] env_logger = { workspace = true } static_init = { workspace = true } hex-literal = { workspace = true } -pallet-revive-fixtures = { workspace = true } +pallet-revive-fixtures = { workspace = true, default-features = true } substrate-cli-test-utils = { workspace = true } subxt-signer = { workspace = true, features = ["unstable-eth"] } diff --git a/substrate/frame/revive/rpc/examples/js/abi/ErrorTester.json b/substrate/frame/revive/rpc/examples/js/abi/ErrorTester.json new file mode 100644 index 000000000000..2d8dccc771e8 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/ErrorTester.json @@ -0,0 +1,106 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "message", + "type": "string" + } + ], + "name": "CustomError", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "newState", + "type": "bool" + } + ], + "name": "setState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "state", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "triggerAssertError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerCustomError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerDivisionByZero", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerOutOfBoundsError", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerRequireError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerRevertError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "valueMatch", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +] \ No newline at end of file diff --git a/substrate/frame/revive/rpc/examples/js/abi/ErrorTester.ts b/substrate/frame/revive/rpc/examples/js/abi/ErrorTester.ts new file mode 100644 index 000000000000..f3776e498fd5 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/ErrorTester.ts @@ -0,0 +1,106 @@ +export const ErrorTesterAbi = [ + { + inputs: [ + { + internalType: "string", + name: "message", + type: "string", + }, + ], + name: "CustomError", + type: "error", + }, + { + inputs: [ + { + internalType: "bool", + name: "newState", + type: "bool", + }, + ], + name: "setState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "state", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "triggerAssertError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerCustomError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerDivisionByZero", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerOutOfBoundsError", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerRequireError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerRevertError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "valueMatch", + outputs: [], + stateMutability: "payable", + type: "function", + }, +] as const; diff --git a/substrate/frame/revive/rpc/examples/js/abi/EventExample.json b/substrate/frame/revive/rpc/examples/js/abi/EventExample.json new file mode 100644 index 000000000000..a64c920c4068 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/EventExample.json @@ -0,0 +1,34 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "message", + "type": "string" + } + ], + "name": "ExampleEvent", + "type": "event" + }, + { + "inputs": [], + "name": "triggerEvent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/substrate/frame/revive/rpc/examples/js/abi/EventExample.ts b/substrate/frame/revive/rpc/examples/js/abi/EventExample.ts new file mode 100644 index 000000000000..efb0d741b48f --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/EventExample.ts @@ -0,0 +1,34 @@ +export const EventExampleAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + { + indexed: false, + internalType: "string", + name: "message", + type: "string", + }, + ], + name: "ExampleEvent", + type: "event", + }, + { + inputs: [], + name: "triggerEvent", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; diff --git a/substrate/frame/revive/rpc/examples/js/abi/Flipper.json b/substrate/frame/revive/rpc/examples/js/abi/Flipper.json new file mode 100644 index 000000000000..4c1b163d2943 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/Flipper.json @@ -0,0 +1,35 @@ +[ + { + "inputs": [], + "name": "flip", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getValue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "value", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/substrate/frame/revive/rpc/examples/js/abi/Flipper.ts b/substrate/frame/revive/rpc/examples/js/abi/Flipper.ts new file mode 100644 index 000000000000..d7428beb6aa9 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/Flipper.ts @@ -0,0 +1,35 @@ +export const FlipperAbi = [ + { + inputs: [], + name: "flip", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "getValue", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "value", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const; diff --git a/substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.json b/substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.json new file mode 100644 index 000000000000..c4ed4228f47d --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.json @@ -0,0 +1,46 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_flipperAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "callFlip", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "callGetValue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "flipperAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.ts b/substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.ts new file mode 100644 index 000000000000..2d695886d960 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/FlipperCaller.ts @@ -0,0 +1,46 @@ +export const FlipperCallerAbi = [ + { + inputs: [ + { + internalType: "address", + name: "_flipperAddress", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "callFlip", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "callGetValue", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "flipperAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const; diff --git a/substrate/frame/revive/rpc/examples/js/abi/PiggyBank.json b/substrate/frame/revive/rpc/examples/js/abi/PiggyBank.json new file mode 100644 index 000000000000..e6655889e21a --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/PiggyBank.json @@ -0,0 +1,65 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "remainingBal", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/substrate/frame/revive/rpc/examples/js/abi/RevertExample.ts b/substrate/frame/revive/rpc/examples/js/abi/RevertExample.ts new file mode 100644 index 000000000000..ab483b1811c4 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/abi/RevertExample.ts @@ -0,0 +1,14 @@ +export const RevertExampleAbi = [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "doRevert", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const; diff --git a/substrate/frame/revive/rpc/examples/js/abi/errorTester.ts b/substrate/frame/revive/rpc/examples/js/abi/errorTester.ts index 93daf34e02b6..f3776e498fd5 100644 --- a/substrate/frame/revive/rpc/examples/js/abi/errorTester.ts +++ b/substrate/frame/revive/rpc/examples/js/abi/errorTester.ts @@ -1,106 +1,106 @@ -export const abi = [ - { - inputs: [ - { - internalType: 'string', - name: 'message', - type: 'string', - }, - ], - name: 'CustomError', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bool', - name: 'newState', - type: 'bool', - }, - ], - name: 'setState', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'state', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'triggerAssertError', - outputs: [], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [], - name: 'triggerCustomError', - outputs: [], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [], - name: 'triggerDivisionByZero', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [], - name: 'triggerOutOfBoundsError', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [], - name: 'triggerRequireError', - outputs: [], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [], - name: 'triggerRevertError', - outputs: [], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'valueMatch', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, -] as const +export const ErrorTesterAbi = [ + { + inputs: [ + { + internalType: "string", + name: "message", + type: "string", + }, + ], + name: "CustomError", + type: "error", + }, + { + inputs: [ + { + internalType: "bool", + name: "newState", + type: "bool", + }, + ], + name: "setState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "state", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "triggerAssertError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerCustomError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerDivisionByZero", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerOutOfBoundsError", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerRequireError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "triggerRevertError", + outputs: [], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "valueMatch", + outputs: [], + stateMutability: "payable", + type: "function", + }, +] as const; diff --git a/substrate/frame/revive/rpc/examples/js/abi/event.ts b/substrate/frame/revive/rpc/examples/js/abi/event.ts deleted file mode 100644 index c389e2daf1da..000000000000 --- a/substrate/frame/revive/rpc/examples/js/abi/event.ts +++ /dev/null @@ -1,34 +0,0 @@ -export const abi = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - indexed: false, - internalType: 'string', - name: 'message', - type: 'string', - }, - ], - name: 'ExampleEvent', - type: 'event', - }, - { - inputs: [], - name: 'triggerEvent', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, -] as const diff --git a/substrate/frame/revive/rpc/examples/js/abi/piggyBank.ts b/substrate/frame/revive/rpc/examples/js/abi/piggyBank.ts index 3d44cd998ad1..a6b8c1b0be56 100644 --- a/substrate/frame/revive/rpc/examples/js/abi/piggyBank.ts +++ b/substrate/frame/revive/rpc/examples/js/abi/piggyBank.ts @@ -1,65 +1,65 @@ -export const abi = [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'deposit', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'getDeposit', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'owner', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'withdrawAmount', - type: 'uint256', - }, - ], - name: 'withdraw', - outputs: [ - { - internalType: 'uint256', - name: 'remainingBal', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, -] as const +export const PiggyBankAbi = [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "deposit", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "getDeposit", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "withdrawAmount", + type: "uint256", + }, + ], + name: "withdraw", + outputs: [ + { + internalType: "uint256", + name: "remainingBal", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const; diff --git a/substrate/frame/revive/rpc/examples/js/bun.lockb b/substrate/frame/revive/rpc/examples/js/bun.lockb index 0ff3d54157db21a636e30076634343a24c812dca..46994bb147547bfb9b960b7630d1a6d274ee75dd 100755 GIT binary patch delta 9716 zcmeHNX;f6#vOcGo(FRl$8k&F@5rl4_nFSjVQ4tkUpo0j=&|ou9qA1dU;uI6b(nRCa zL}Q|um`F&BXq*xpaEdtGIN{Ul5J6FiLt>2js!sQz+p8;Uy|wQB_1D_vybRQ1%JPedF|LLTV@CPP{BmUp!*m&FjO3I`N~fp!FzuMO!t%4oN$(JH3*->S zI;riAH7yyMXe#}yN7mQ?DI1t-%K1hzwCR!za)Dunpyht3m#->N<*Q1|ka789%%`4A zM13lsZLYER5IOeLzd8&{QLes%q(Ac0n5GJcFl~!GmpsDf6-Qw%Yp;HUgF)lbiG(Z^ zq!kpZG8sl$nm$97m&xqFPTOGqC&+31mS}mImZxZW6mn|W4>@+XdZ3mIwfw22CjX|E zw`sV#dXF}vLCZftPJNuGIr(V$@9a9UP#yu;4KAw~=o~?u2}?Ha`pbAWV-$?u>jea!2IGT7Dachw8T? zr~GZmsi76f?UC0ZrxC`{Q&mHb8kJ;8Xv+Ea;-mcRA+nL)9eMQ>$YY`u8p*`zh~o>Sg)`EGcSSz*Yb z&e)H3H+dN@Vofincuo4oz4<-ZX;j2IgPUaUb~&g_LX8gN z)(nDe#=!zc0G%dsqj21oGUzf1W=lb38p`g32GdZ1i2-z)%Gt@_W){k>0u|Dy(16q% zI*`r)H}g=o0aQpkpaH2PbReA$ZoNX;jiBlkD!63?oxS9&4BUE$vZskZq)VYe7%DuBn>YlApXP^wMq_tyGB!1{#H|;Ox#r+)7GPG1DPK&P zK({EsY&)jHFl9_-!Uvf0z!Y{7JJ)EgsXq*7cmn1MIGsh93VcQ9YJaodm?_m}8gLaq zu`n~mOgUyU&}|$b^uR?#R*X2`ynDIBRgsw~W|E2kip>LzUScX7BzD2Vv3LSdM>LLj zn{bX8Ex_Dy&}A0fryZqGEH@-a5$15sXb5%INQ{TdBkN3C2bg_?sUWN| z0J=>Bgl8~CLxP7NV~uq=`vONHbPDBWb8yL14{-!~1qhmikYgbiuokctS%d|2B74sQ zhFZ!6$1NboQf_nt4~hwpZy9W4--kRTDZ58%>XBadNYQu=q;n{Z()faBnnp_Nkv8{8T_}y@^t|zG)JQXWq~;#!IWGw& z+CWZ!xzQ{pHq8zoJRNIbGMrJGRFc<>x01y>^u53*p|j)Jw0&?%A&eszSc zz2pK%Jd*6>f)ppnLAKEewj#Ui1f9qn2EtJLVQO6c41tb2oD6Pd;c#*faaxTyY+OE` zjNC&U-=_@rmdnRJaC+!1mqu?mn?sP(qt9`-(yrn3JsD;Ml`|-C&;N##A%BDbBE^ns zs*X#Ydx(?U!w}@=a0G1{T>RWaoXV+f${&TG=kGY_k4BKau?X6L;}G;9S91o(Ytqb{ zI2pjBfP0AJW@M&lk{l<)$=dXrIE{Ikw)}O@_5be_G&NtZ_;1SBw*NOCYF5_*Z4dt4 zT>bAbNK>>BL36tpLFpw3dWch+o;Pe6HT{U<9^$0(K{ZqX(}xP-1g0E7WEund)Pf&HY*&oX@ZOZdtLa>_&51WN)wi`(Tf|t-5(z^wrxoV{Gzv$Ho*k&it@zl=+Yz({@`|0v{@nM+X@=^dODcZ}8&xR%#UQ@U)y^(; zd&tZ>sdK#P&HI6i##t;ld13hctP?SDw^=Cguu(rf+7-QWP=C8R^Z716WEUK$n{Pa8 z_~W&=26R^ykH{3&%A`hiGQYWuyFx17G}9 zWzuMFA}$#-HS4eKt;UwY;2^P8|C6a)w=HM;h0@x#79uIQJd-&@V4yYEF# zt$7%oH!@=WefL8N#-G)#ulFnZ+^WLbwQu7bJ@1C-d*^Yj+v(P_w6>dr?MH+^I1;}$ z^`~ba`~3Vxf_&%Wz9uJH_x+G(6_=XOnfw6yl={aW9+DM@b6?p+9MN!uCnST?tz?`n&>j$>ynhTZ!0aO#nDM+V(5 zDNHuB2)})7(#7F!3svbS9V>Q;_3XOQuMhq)EIrYgxM#^ zezVoPXRh!3r`YWMf#H`7ZwIA3p0nv>@t@ypepIGfX7`owyYo@Af3FnOmFgKD${R&) zxHa_S2L}5ii|_c1$<6ufd|~0Gptx06pS6ydocNcYI-||}mhXwJ7w&94Ir^*kR;ypX zsY;5fcieFQ-HxDBC(U*xuZq+&?5=Nk@9BNNFW7Xb<#=6JXz}+QqwmP%cYI3j4s3X* z^^1bqou{r^Pyh2_P9LMvWjB6Q?aO)Q(iS2+vVK$g(7g}A#O%orWLK@-mLB?s(|$VD zy=~Bey5ac&Q5LJN%cKXs61o3Fc{k-dv%SNXUd%M89hv^~k%KDs{TUm(YlGwFnu_Ls zxi5I8@$;oF)t@(d=s7IWxBE!E;hUE7%Ex(rtN*xvbY<)}AFo#Lk$=BDLg9LP!R0lX zJC}4V-!Ev4tXfhM6!^$zLQ%imD7icH&$oYFS5clm@4o(;pdZ5gW4Pe*XWf3AUH2aS zYh+#SlmQpQDppPG-kB1y>13C&bm8vw6P^_xEMI!Uqu{;k!vqtbD@{KwPV)SH$$gh- z^-rD?YS!J+^O*lJK*kM&WuAE@ODtCJY708}n1;TY3S&;(WTSj{Fz_RSGQc;el}Qfzt*T~LQKM!r-hDx-2E!QF{kduhjFJpR$no7 z?&BoVGwiKzI6%5QJ0oLvzUNPI^$uO_Py7lx1y$F&UU(hN*}W^LU;UYm+K!5Asq+JNXJ7TKLtAhR7hjsfS&@! zga~17fm6#FaKNzjUPG7Jn*uyIgl5b(s$qj(nRnMQm|8CG14Ts zhIA?f4O6hmP>(bPI*_J9c(8(<25XR}K{wKLhze1#8PMpeU^8I@%1U^OGz(&fE7)vk zKsvpNm4D5$xzHGz3)AFB@Y=yp$X|;V;tygWTnn?ITr2)^RO*?Lr;_HBHibvnvT!P_ zx4>EmSHjWT6C=V{G#^5Sz$3!cC>%d~EYbAjrfG6R7M72+ z260$#qhIjXffZ$=^2nyZ$Wc~YRh|rD%@17(tH`!P}B)wy_ikOB-L!=`z z@S1Os!cSd{atWdoL0{5Ih^dJ2h~Wr1A{0S~?Ar*ux#2$X!;z0hj6p;pMj#>(BN35^ zafq=9nogPpT&|2If<`$Ef!AbovFu5=%yidIH}>4;9$lZ{Jry_fi;kjUvM>wWr}UxbX~9(=HFnz*?N#&0luhxL;-3%0-_i3I z+gRcw#XkmOr}+8MCpivTHGeBFU{k!LUQ+C$vTVAtq!gEJ(!kuhfTX)v;*a*EzR)~n zojv)E3%h#8(W!qpY?);)V7;Y&QksNmP@E)U^Wfbikv%PKT>91iKkgG>GWoMsr?mj~ zCHdIrY0J0mN$r{&`SEAihPTw0%v6AI>fhC`fbgjzwhod|>vbzt-co;!6^&NI)JS}( z-Jd#;{RH|Xi`cE;p6r7!jMQY2-!$}rdQx@!!kE~@Zn&20W6#IcHaI*PyMBM|SkAIcimU1@c&3Qhc8E&xVY^^%%6Qfl zj-`m~`N-Zf^UDFk{8^qfUf!I^Ja~!aZyHY@DQy;e@JV%NT_80zSg(&F))0P96^;L! zdd8aQ8XpWnA7wIW5Dp$6;N#;oOw7kuOBauM@$F}C zSL%BGNC-t~w*GwF^2(Kc>%Nff2{L4H{_%XkR{_2(`eGZZ=8!GE#`(8&B||J>FIMG4 zp$Bf(Z|P?<`gffIA1w7BcYMc&72nR*l_Xn2?{r%+A6?zpP?dAfbnt1N!aPd|OSkps z!?C7)WodO@qz7;;$ z^l`+<7G23^TX=z0`Plc08gXJ(`D0g|0v{cZyRvV?!bdfBx)L)Hj8oc*`FOg+>=^cD z<+*B|LZ}F;mA3wT0De))+9BY41J$e+S>o? zexvgR&jUQm41vuO;eDTdmdLzF`3xc&~?} zS;K^3MQJ6fvI@@X49J3pYz%NJK8Oou_{Lg{d$~(TFYog;tz#6gFH(zC_h8O9sksNrczlX zQO+t;7G$Cmsv^#NNk(CQzOtZ!W-sKkq!_Q*#|JcO|TDdzb| z13AC-oWL@@6b`OGG*%7_@9CLtkWljtxe|Iy`cTipiVBMIJrUTOf-I=17AL)ugZ24B zi43cF>nc$NRkl=FP%bG^7UiX7D7D6vWity)a-|t*k}Or8Qlloxn4YHMCfrLu1I_Cv zvA6U)lG-RLDJ(0L1cIHIQ9`9%s$S zlVoud=%AOzYI-RNo<-1@J;;k|;q_kk^g(|ps3$Zhy>ctCJhuYV0kFNm8BWz0Lt?Ga g0NJ1PJ8)B0wM^ zXob>@#zU=10YS$OSRd7(60HiN z!e0|++@3bvDamPBwJK97>4@E3K|vED0msp;QEHzs;XwVG6$naBR>Ne1stv9zrY|S zsa@)L7s3Qo90lG4+zX5awkYLAzbD4GVlhgaVs3Txb->uqRg3brl2_qE;xx^jR z1O5sPf{!4R&Lx~w4BkmSI+wN|`z)2-4@%ekO;DuXsZGQlvs1J_T~tty-X$KULA^`! zm4+gNonjsp2fM_b)C2wr4T8s$X{1Z6qhj!1QxEuiGzcC_rco|YLdD>Fsb`c+e_ks| zDVV|tIvYMq6B|fFqnx6OOa_IrdaM(L(oArowbOf$EIs_I8+N| zX^Brd=#wt_q!hS+fvndFDMyxG^GRViHQurkpY(uFy6BVaqgA~vKItT+Y_Baii(YAw zPulB~h9J$A^(KU>(kh?y8=rJhl{B-%DAMfIR$#X-r)YD!_Bfme8Q2P1Djz*d`x0^v+8>&(8DXZ9Sf^&bnR)>`%rpczX{N}yw07J| z5)&T{%v{1Y<+Cp*M(kt0JmhjrK~9Xg>Tq_whodOrE|VsMIDH#=teZjH zuSJqp0c7DvBX^h#V#8<2y?hr1l}?Ij$3~RqDYcAjevXp=A;ii^E0y}60NdrReu9qv z<9=}CN%hJE>T$=)$zSka&MV`~7V*kAfOx^0K%8#|abn~=r=N0Xw*QE&DI0+;`lIn% zJ9FIsx2D&Rd<6ctw&ql?VgG(>_6<%6(9t)!ZklQ}(EBsp!bAyH550?Am(?xIG>F_T zn}KHA+#;HG+dPzFH_)fZ#ZaobBjqd zfZUhJC8xW^6xxyQ5mRXpJb`Q(9x;t}gHNZk;4>(7wnyAd-QX6w06vp4ogQJO9&j67 z0k>1G%Oeu$5O@-O1)fZWb3DR9N5E&1$n=O5Dh5xbC&1H4e~U+?Q#p7B^@Go*&@2xg zHmMHCxkq=KLTgZl7(7jL35a!p-c0oMe#R5n%cLJJ)Y=dT)9g@+AZ6&-vB zsn6`k^r%|a*HO?WxCvz})@d!+tE0K2zPh{sK?jSBRHuujy1b^o6-%i=~i&He>{UYO_7ShS&=(yROIDAR=k^g;dCqATREAIRYuv^j#N+@C>?|c1phHh zGeK664P*x;f|5X!Nx#7y&7H%C^0R?0WQ*7WzSvjNFE?bh^S^2?XaUF#S_sMmEdu3( z*cXMM#US|ypadz?Mb zE5Ngw0h$h)21)?&Z8ZhN9*m>t>Z}RuKlYpIL$)%7oraXOmOiMSHkLniUJFck-fi9S znNF11Echi-dQCF@ye8759vbyyMYC3V2Giyyahs$eCW_CZ^+wti0 zD?i;f@BW80!e((;*zAoIT4xfibfh*>l+pXp-Kgj~PQDoRUeMQ_=-FmTVr8%HMw(t{ zGOM5D@1#wevHcC_eHyWyErh4aXeD}-wZtZ(x_NvP*2Rf?=pQKGNB1|H$WkAf%v%8) zu%r346<W;JFoxH{yKoo}u>D$mAh!TNqgZ#Dd| z|Li{hg$E_FsfrgD7P{F+p{&RK?Hqm#;J>iz0aX{hsBnPHtf-Gt=yWfHhmUK;iYIdqoWazwK_4z>AC&!u_Ur9M*H}b03c_PboWZYzTsBwtK-8t8fK6F!? z>@<0zYNTTNnFkvNHa@vRuCZINaWCtsZBs;)8Ud*6&p4bESbZ))VCpstcDgZ`ezz&Y zp@s}jeB6CFeEj^s`xVrnf@9$uPanGH=oWv?f?&FirfL-8fg{^D4C^MH_A97yid_MZ ztX~8B7aXBcjy6#w$Suzsf#eebTS+a4>bWMmUsENXJQOc>d%InmK+2HCXcA z&b8ULdxuW=Yt9AJn`o*=S5}R?rXL++{KBuG#$PD?Qv8Ol-d+Bhi6bd$b3~LHusLA1 zKKrK&t4sU}?vYfmIl`evcnss`UO4br%gcTRH3szC?8?#x*OYz!ny!&_0DY@Lqk%(X zqFXgi5Jsmr+oROj$aBVVVWoHVbOwkdi(NjPyBhvys|xb9a_ z!!3bLr`J@yc~#@Dxf(__XsX6%QZ8@J4;gdkfL}q4;Ox2Un|;s3hhFs86ou38w?ss# zA)j-ZlXRbF&3(zQus578qi;1vbkB~c;_WS;PxULPQKTgwym;u&&vr!mYrY64=hg^^ z8h47`k}p1PJJaD;@I|KnGGLo=?e%N^nj9njVrxW{94W#@vh~usKkf?qWFlXCHcKL| zZ-k1DZ;eR){&~a6v|BAUyCvlZ&TO*9?yw}`lpESi!5wRH;E|56#T#M{{<*2H%^KN; ze;Gcdx2Gh(AzDMOUsklvb<(qKX>?_qxi5O#5iLElZ*||<&QqfAv)z9PqvpG!s9;}U JU)=t~;-4>p@d^L{ diff --git a/substrate/frame/revive/rpc/examples/js/contracts/Flipper.sol b/substrate/frame/revive/rpc/examples/js/contracts/Flipper.sol new file mode 100644 index 000000000000..51aaafcae428 --- /dev/null +++ b/substrate/frame/revive/rpc/examples/js/contracts/Flipper.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// Flipper - Stores and toggles a boolean value +contract Flipper { + bool public value; + + function flip() external { + value = !value; + } + + function getValue() external view returns (bool) { + return value; + } +} + +// FlipperCaller - Interacts with the Flipper contract +contract FlipperCaller { + // Address of the Flipper contract + address public flipperAddress; + + // Constructor to initialize Flipper's address + constructor(address _flipperAddress) { + flipperAddress = _flipperAddress; + } + + function callFlip() external { + Flipper(flipperAddress).flip(); + } + + function callGetValue() external view returns (bool) { + return Flipper(flipperAddress).getValue(); + } +} + diff --git a/substrate/frame/revive/rpc/examples/js/contracts/Revert.sol b/substrate/frame/revive/rpc/examples/js/contracts/Revert.sol deleted file mode 100644 index 53f1f8994256..000000000000 --- a/substrate/frame/revive/rpc/examples/js/contracts/Revert.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract RevertExample { - constructor() { - } - - function doRevert() public { - revert("revert message"); - } -} diff --git a/substrate/frame/revive/rpc/examples/js/evm/.gitkeep b/substrate/frame/revive/rpc/examples/js/evm/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/substrate/frame/revive/rpc/examples/js/pvm/ErrorTester.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/ErrorTester.polkavm new file mode 100644 index 0000000000000000000000000000000000000000..ffdbbe2f9c4b52b7a37a159bc88e2bdac706c561 GIT binary patch literal 8919 zcmd5>4RjmTm7W=m^hTPI^(0I4^Q0t-I>8RxA8(ffCP}-FQK^)rIYw4PcBWoCA&Mm> z1d|_INjNlz0+EySY-|E?0;V|>636KeyZynCv<+>yq=oL%o^6*Nwyh7eXG7W2v|F;F z{CK|^Sx!O<1$uI}K7JbM&7C**eed4y-FsihvX61xf226~k0;z?ZQ^mRO)W((Lt(|*?)8O@o7S(}fLo;-ZrHSO#mcpX?o}%` zu5fy$h5J{m-Bjq_xPHaD4XX?5*B4fK!@}r`;`J-mt{pw?TUF>=d*f!`{Z}s*?&B)l zIQK>FU%6I(BY!9VMgB4VIiB;RJdNT?(eJ&*`=al?te_r5VAR&KPUL(IG zHz`@=-<9_Sp9}74_?u84{Stj&_zU5$hvmrkA{!c6^kDSI(Zw-cU8$~9f2w^`7mVi^ zAAe8$+W1ZJPsZ> zQZbf{geN2YyhudJM}=KIgmOZV=R{`+k1!zUOZo8i+DcEW=vnD$aXy+wPY+3o9^xZD zD*AoYr}4$`af`NEu@*~hF2>q0W=<7JnLS9xQg7HU>-HgPkLmVd$sSimB;^oMwv!OK zx&EfW_g^Pui(RJnp^QDY+&cQ#SbX_xk$%bsT&A0Fn4sNur4L>-OVgbl;kNNm2R3ouiLg zah?CGdw;~eKl}OT?-nOT(dVpV_6zv&f}dn}#P2pAYY1fx{o2k;q^`MV_^!F9&`zRF z@`5(WJIkP*;%)s5ZyP6hn@#fPEX3~`x*fylmK@Ff(6>7P^^03yHMf$&X1REDDshiu z-sA6l++RF2RoLt|HXeSgzRn*9sA+Evm{aBdY<{L=v({u&wRG!?oNSZ4<5SZ_Ff_?cYN)>J7<44 zPm1$jHRsEP38nbtRAQIU+!g3t6DTg6Dm)r6AC=>+eBX9bc$j>s(sU$Wkzra*C*u2( zbN2E16aM^GKk>&fxkZ3fdar})W%vk~0C&LBC_lR0(jPaO6;m~JP8{9LHp3;W$GgnTAwGo5#hyUjk_VUI6| zaqk-4H+oR{E>XTJDHW*<`ex^!HB}~O=UZ#pn^&H@sDr{yd|1FOBq~eHZju2<6g)M&baG-M_U<1Cw zmVmiMwgF*bt6bEQypPTvQfNvLE35#(t&kej%PE_ zxb0jA`GIWrf-b`pkR%oxSJy#W>$L=J*9Ha(})OQ1&_&`AFR&x4n4Mm?qJArl_Z368f zv@x^;XuHuy(5h(Lc#aqJ%l;i7^ue`M23?u6+xc0{UN2jOvtwbGp1eV?SaudlzvG$>>u5S2{?wm zcgC>q3J9xnFlQe%e{zP9I|4SAPAb-UnPgu9+ij3S*+=@0yli`%wK{_-okBZ_23`In znavCQk+u4h9QGT3eOi~aL9t)^XQoy6*#6O-@Yr$X5u%jq9@{%Jv15KK4nuUj^^ohW za9<|DDw}`%zl7Z9w>9``1TNC#XT}_6%x1=l8Z%U8#F!CfMk6yK z%m_1sG9$!{24)1Ap)f;cMt~U@L}CVEhL0IuW{Ax2e4S&4Foq9)T~pCcoZ*_D=sY3! zORr2#O*y-a4Ry>hNm;8n*4K0}e^AOlAu<1_xsdd_?Kt`W3w0hnS1LN@?a^anQr*9`!66Og?g(Bhu70^s86L%+8KeDU3b z??TD@62iWgr|7%!tMB{XjbH8cVcJe?@WJPQPsrWAw}=fcdmIuQeQsuu9Vz?(+Q*{;1C-d(m%#>+9V9PWj>`@4K1TH@tPeXr<8PYu*}P zwAo{sb9VR<@WnBI{Lt}b+n4PPk$WY8;iC(F_CJK|^u7fYi;h8}gjc|C7kf{?{?1u& zj`zr#x@Y zhV3cn|8JhN-V5Klcm(sd+3-Wq=zKOzZ~iSIm$-_aWkXQ(#Z&fevEd%!d^WuLho=bn zBs$*)8-o5~pu8xqE*%y`B}s2~HW`p&2)zv;yWl2KzKL#i_8RmC*3+Av-DU;7+1YMf zLZml48%~W6ew`=M zt%%m+#&J&gbsTYAEd(P=W%W3c{#pc3Yevy#dIqz5fZ-nJf z$9RkX403xPK?LhWpi8fNF+{%X=jv#7d=v`(eg@397x#VpO?WQ%hhGzN=r5Y){8MjE zbNPi(|K#gu-SRJk=9WRD^J#9`@P8BXx2~dRY3~0&===O@=hNKs7hWJ_1f6e#=D>2` zvh#yJQBKmWPArXZuK{<1;5MayhU2!@IBx4%j@vrJao|V3$Vgt4RyjKPsMQT!l-GED z5~h#DZj}=}B@q5Q2@FHtVjvAbS)=Y3pZEae|MOKRdnq=xnN57UIEMnGrJcYy z_)c<~WP5)7JR$pEvC(N8CphH8wvK1m1g9V&tAR4&RyLio=uHrG&4kw-c~o0QB#~QL z+?>p9@xJgp#8=~o=sS5rB~!i z*wUBFl?ZApa;4GId*n*g(sy%mC1&Y;az(ZDDt>5|z6}@2(kF27Tlxqt0ZSjlMYi+< zxF{A(L#_lZ{UKZ$Ed2y7Aqz$&S1cX&fFcf3V7Ve#Fj~3dvEb}-MYMFv%N4H$vzIGA z$I0aZ;uJsYzFxfQzX&;XW@Zzt*K|;ef76KKu`|Me>%pkTmpyp?p);k`NW)vPG^hfW zs?;`;rG2^+Kshee0t2&+4*W!=4Tg$Z+qA9Le4rxO`f^7`tDxj(8%0;9XGX?0`e0zT zwwqHnqfArfV9s`Y8#iszFitnrv5gVVm4lZ#a$_~Q183!I_7M6o(o>v*0%ZIIZc#gN zoSQan7^!QRHha1zccvzHvL-iqR?d!}LLWw=ys}kx_z~u9s~kUV;xN{uNf^BoUcrD6 zVU>@x(lw-fq=l}*_h!1rTRxJcYsB&qov!hek5IZsC?ApN8lINR`&(%_RNmi0%MIoI z&9odW?@!XQQr@rAvRvLzX*obkQhA?5OaAg;D=lf|!4_Il%Y)6d6e|xVX(?JB)M=@) zJV%4(qx_8%!xcg71ouXcsu6OCQOP9K&a}NOep8W;#KUX5C zCz0NMFsLVjx*pV{L7fJ5C8$e5y`JT-|1zXkoaQl}yHz=P{>%@N+lZgV@EHr|H%>s; zf5$JJ^BniUN~lhs=~P^q0~TFw#X2lClly9Jr)9J$B}q9leX3-!mT4j!0evS!(xrm% z70f4hofU8O(Jdc<5*jM{IPkHw=E8MOUFjmmL#UQFjpa&Bt2;-0{nE^i6mK;rBs<>L zbj(WV`D2o0I7Ez!WBzWpAhwCOV#3GWE$2EPy?M)XgsgL zoW&T687!u=n8so%i^W(h%3_Ty7Gbe4i%}K}u~-9(1zAjCF`2~zEaqo1iNy$u`B)4i ziY(?~F@eSSe)5eOMs0OB%{G+ZT{@-tI|%cJ$WM@92>or2v3T9I{{ivy1h$Ux8AfB`ywjPnJN2xWT+jO}d>#)^KG2GM0A%5~Dw{dHpg{}FLw{k0=2!})pH;XS)|cXVck%eP;% zR zd#W@%^Umxry}y}HN9H+C&rO}9O_m#~rXQ%9?P;^FAfECkBSRTS(itH=^Vfdfs~(_3 zW~N=d)6C|o!&jeotER<{+p6Z`NGg*~Uj|SCsQZRtJoa&nn_7~F+Gka)cI@F&gTr`P z4gj9*kF=So@ch&u4G*5vD^$~F&XL5JKxeR;Nks-T=^eFIs!hek%>~XM&gQb&;cBir z<}Tm#K=bED+~pdcUeyQMuW7Hr2jw#9+9>X4x_JpVly=@U{{o<@(IL#_TxmX?ip+N; zF^fS=5|07pT>$xq)oP|a9m%E!^B-{rZiX40yBg7X+cMEX{HO2F1j0kWClwib01v{3 z&qDG?zCSPydvHKW)tAi`8Zsk;>C{lhjC{oX95kWSym{IC&2#n5;@+?$<_Krq4?JgP zYp>jM!JDhOY$P=-W~&lzMN`99FX_BpdGNCArOteF?YEt4O4+-(VT^EXu6k~-KZytD V%})b=$2aO0=DrCNDJ{O0`#(LIA`$=q literal 0 HcmV?d00001 diff --git a/substrate/frame/revive/rpc/examples/js/pvm/EventExample.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/EventExample.polkavm new file mode 100644 index 0000000000000000000000000000000000000000..4b013b35852e668fd21ef7ce1dbd61936d7433bd GIT binary patch literal 4104 zcmcInZA=`;8Q$4jZgy|?VDI?Y@qpnV>ww)lAyyKTltyPtqXRbx1F_JI=wa~Xb{A|D z8^fKkDmNkJaIj*iC4&vEWhF9T)I@13gH2l6KSWNXT2-ayN2OS5ROLroS#ds`)-`?S zFi9h|{ZsXHJF_$M%scPLGw;kc?|nv+R8z|S5SD(`sjNs*U!?2dx!1;uR&O-=zV^uL zFB}iw+8O-GpX&;6;Y&N)Mz$XMNQwK!6j9{EL*RJ;p2y(n-q+ikIJ`g6cj$=QA5RP< z4)(hT`;PV>N$l&5A5QciJ$&#;qCf5)IB>LoUsrD;zJFi;zJYzcM-%b>!}|^%c`kAI zaAJQ>NIuo12wA6|^@Fh9Luvmj?OWti-+fOCpgi;tnnb@tw^5#4EHH z`p)`Z^Ih}3?|V$SpzO`Lle61z;1PUL{Zrtxz;695y~Fs>(1MQ#pAB{dThh75OaSdGIG#8 z8S&;L?ohqDu^C)v|>*dJSk)2p;N~E=xV)nMqio$%<5`FcJ>k3=bd$E2`g= zx36{LYDo?vNf9dgx_r%|h$+5K994YSkNu{i`AxrtoX`q0Ygl15 zE2?q|qad`U2qY+K#BZvQ zmghSx(qWk$mfC^k!KR!L_Xxja@>#;?R6cJ^s>UU3jNm+cd}F1+0a)o6_e_2%#%J64 zT$Il@&kW6s%uLSAi3wLUV^s5|BF3WXW+Kp&r|y;qVKu*LJOXo{3aB-bjMbomI~B0L zNeS^J5w6J%!*Cf-n%p63N(FyuO}@~&+sse@k%tutIY0=cXo?huAt!W!neD8wnH9yH z!cOqWhL#1ZS-2wqH-9L8@NirOU&l4^768}BbqGS`Sn-rnHig>8w93WGg|@_h=Pb%Mdw`+l`QS#%>BsNSxodE zGZzsnd;_tfS>zP1psx`2!3RM$)06-ND2{=qaTN#~*MPdrOQCoGcnYi<16EyPJ)Ma4 zwj*O%V@U@U53Vq$5A7XcZVc@`i}6)ZZr#|b8-K^Z8s6(5XEkcCs(gPRN(}4v?m%lM zz}OPx}G>e#E@|XyAUstsuV1r z%^D1>0pIw|>Z_k){8xWAR3h*@RZ7a9pro{#lFgKqP*N;{L^e@ED6uFhqNI?L0!s2J z2~!fH#H1vTl3YrHlo*uglmsZzC;>^B5mozBGj^|RYa{qY86l`pITvRg{WmxE00>a)Cy9|pq5Up0JSt~snh~lern}V zOQDvJS~9f|h0P7&5j21Fd$9DIIRp5Y8+3DkZX=jO47f006kcoK6|@(xohT2#n8TCR zNKX^yHtXq4%&pebl(|toT@04$=@JNwp56@GS5KERw^L7-F}Gb$o6J2e>FE%2`}A~} zxhJ5J&)k%rE@18~GzyuUfvSkP7of73I|-G_+#67V6W@R;z}yw6bmlHXWia(F9-h?WTx$i;6Tmm`*MQ%YuX08M+A9L?OOJQJ+p3Y&e3YA|3N*}}wjFLx0qFK)X zk9U8D@mU3Ibq7`MGz0m#6Lm8tcWc}!BJ#cHiMbgS_9!%A^SVolCDpuYE}G^~2{z8jGnZ%1&17btFy=7pse;TDL2&PZxWnNg zGO#h5jj>2e2V}XjQ|xqk60#mZ#rCQx`vl`wS>$415Oh453mtXP0Vi0hlQ}A~Q$Qj( z#UQ1_`DKr)t-vY9&hndr5Dd)wxrJxaXk6tjc?<;T2ZB9M#Jj6zcEYj29WpcOO@bvd>?EFy%nXXdKdm{| z3fz=io{z)#haA^cC=65FRR~;DjuAFwvg0aC!6jv@`(%WrtJ$%t4lBY^HOMvPK}D6t zN!x^+J<)p{u0tHILtI>kLMsTqP{hr>ZZoK|hl5%jgme(IgQy*9Q*7vYxM5`h^>;tQ zxLN>$Bm$1x6(l7=LV~0qNX#HHfHA`(rd%Ew#_bRiEU|^IAd?0JM*(wTXt;O0#0oU%&=NMtUenWt>0spSB%=@_46>#ZaAZc#$(xuqBUWk z3`gxo`=ni0FIwUs4vF9Bc+A#94K0P^_PE_xpUHeN4v>pgsQzNCVxnTy42^EggZ{>0 zH4+}r)Yrp1{3{yl(fSGy6ozU~wj7UD+#iH-d%}jn^+Mn#L?N&Z;qiZwx-LwVQpKJ# z6SIx=6M(9ys~^t51o&rS^%>B{4vl6ls}Gk~gtf?hbF#BfRD{Y~S|9{3f!DS*OoYE( WU$2eYyTak`gV?&KTN=vCrGEkjk_2@C literal 0 HcmV?d00001 diff --git a/substrate/frame/revive/rpc/examples/js/pvm/Flipper.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/Flipper.polkavm new file mode 100644 index 0000000000000000000000000000000000000000..7fb299e464dd75177e916f6631f6fa7dd7cf3ea9 GIT binary patch literal 1842 zcmb7EO>7%Q7@b{@cXk~&-gV;H%_KBV*!)TrQ2`OepNS0hQZ))DplDYs$7zf=A#FqA z#7PTMN?YPqJ+xMf5>>8}s#W5)hf;(ZS|NoKy&xe@91zN(2P6)lo~lq{zI75PJ@7N~ z8?U~Z`R1GV-b~Ls`w-eqP`PmgeHFp0D1rwBH&6kP0kwc#fKEUCA8{AC8{BtXl_&1G>sj;c#ckd} z?=kOL?@jM*Z+yD)u#8E-_bT=w#65ND`P7`q&(;UCYcD(p0Ust+$R{Giw@p=3I3*vS z!X%9N)GQ4A^;Lx&WzCc|GbEc-bVA{vvKE}=Fu|fA^M!sQB7O&lu)D&;XL+rgQ}(L^ zo=)r;@N~FcEB5r0F!m6E2r`xgSx`AgSvBQOGt^d@k^4zM;vIDjPGqLF`1`i1*{W=-qD}a0w^y--HET(>mNly= zT37vZqJN3_XGws3u)UM-#|=UbTf?%o6tkB5tYXBv+EX}Em@Ui|itd72lK-SMJRkP2 zh(ozBL;~VoJ`1}Evi}mSec30HzS zWKB+Q1PDf)1Nv}S!YBwsj)F?2`~aDuUy(_FLQV*AK+ATi)lWmd4|&Z06De2#niC=r zo{-!xAMl^303}*Z*Usbmd9L@g)UwiYy?4d$zwPV2E|n=H(x+U)Rj-hJFB>L%ioe|Z zW|<><-j06~4g~hRcK`A#=QuN{*$s2ZZa4$T0cH@d&LEd&^$fDKIb_x3ki}-uBSf#d zdEJVjgoNal9LhQTZ!391aZ8!ig>nw_}U1TN|~?9?;5 zlhG#_tz)#7QO0NuqZ*?sqm zY1On^%ss-k;XAD~*w7jh!Rr5!{as|stUGW279i~$(ETq`l%3%^WYZmw$}xks^iUU2 z?IfuBn2L`X%T`8hWy)3@Tj_VxfTG|lzP5ieiv_;3G%#BY7>~`NU>249Y4Ui1ChIe6 zdQ2^5s*z1+lwDEb5(%%>rYpiftP|2)`aiCCu)$Bp(}LW%2upw7uvASK5;Xi-Uo9&X3f5ymP-VFBUlyZwk*~wfk k7YjD#Uynu`8}oX;H`r*zp^RnOc(!d{X!p7HHXWls01Lvaxc~qF literal 0 HcmV?d00001 diff --git a/substrate/frame/revive/rpc/examples/js/pvm/FlipperCaller.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/FlipperCaller.polkavm new file mode 100644 index 0000000000000000000000000000000000000000..f112ca275df4ba33a26faa9c69efdd8d5292a98e GIT binary patch literal 5803 zcmcIoeQ+Dcb-z0tuy@!4u?G@|${s?2bntScMawfB%Uba4N! zM-Dt>?cZaR92j5yy}RInS48!kSK>IKz0jZ`_)Zl>6yXGG5?D-I zi@g0JPhLo^Z2rdE^_;D)nuMA`Vrr5dj0Duxz!)zgQSuPsi3}o~;Nv;b(d81x1={OU zcZY^uT_S9{)48;Xt_+HZF62QTBFY}(X?EM{r5h&c;>}aOYL~53*ywSt))B>c(Ya}TrFA*|imZH> zGwoRGv9#>8qy78?gnkU~eKZ2evcpHi zK1zMG!AFUYDn2UtD2y~5UG!BLJI~vrBH~5a==G?ef@S+WME^Ft`BOF=!>uxIlW@Bi zci`N(v+djr$t_Uuka7~?HXm+Ra7P{9=Fb(Ku;dmyJ;@wVoV+EFuA#q9)l1n{={kB-6ZLEO=Rw`q8L z=wodyn)X0>+{|VMx4y>>ZhZ^nXCSK}S3zC}SpvBPavo$6WDevsP?lh?azg$RCybot zMERzOdWGHDf8dyXmCKDsAO&IHfEsY};8w~HZY3ZR2*!1HLpZD0ZBebDezw}Qdzd(aAPD3@B7y(*{n zxO;x-VZ`sO)e=wSoYb?`3^3y~FynDxMquLLX@?nWHg8p7&Wu|W{wH1(J-}cU zIvbLmJ1-F25C*nueX40jY@XrMPsy!|tuLk*6-d$ai*kiUk$i&(?&DnL@saTey7!eI zTs{3A5#9UhA$I*5@4xqnzk2VXRo)B?3`Pg|!Dt^y0wl%@p&0K_ZK#iDbbx1#37+XO z-f`eM+5SkZkZOf-hh(7Hib?ik9~h4z>oB%2-VC2oj8k&|W!XM=6Y7w07&XoFqtg=5 zMg%=04n`r=Q3!PuLLKEm3Lv8(Hb@2pQY;Fo7KJp6t~zN%LG%nSG_8J^MxjyO3?*2| zhOa)RWuS^xt4-U*_Yk^AWcmO*_un%?x!|C&JOi6?2(bo6zZ4WrEhdZsQ>3yU(s2Y7 z2x2PBv;k|(!)T)XB%^&mxQ#%#Bu8}(>zY^BWL-nL=Fv5`u8F$l(ltTXc-@nq?IQW+ z{A?%5Z_dxQk^H9oY=q>)`B_TxP5D_u@_K$oBDqFlll)W{$%XP$og}B_r`kv^n4gM} zTtj|}l3aa$ijZ6&UzCWgk`XDt*hOrAezB9-b@|0MV*BzJBVc1f5=egIm|hZo zeN3Gcb5gCEW*cJ~1EQ`_16z-&X7enRapGEwY3IMagU~*q7Sq^z+5T$z$?{BjL3tS| zE0R*EMD;QPW~r2~&j}D!v$4$#cbZLIrXCT_IT0T7kUOVAT|{7^0V^x%v{|Q{b-GEX zVVySVRM%;vPN_~qI@NR<)MvbB?sj5?=Q@>8@bn4ToqEoC>uTEv1f*zz(k51h> z6?N)*K&L`Vr~GrA3A&&Lg<|FLTpa|oWf8eiwk&=Sl5 zGOZxMK|&P;q68V~A)ox|FA%c$N~!`ifR8-nQ_Jw|OT0_V_yA7S4qXB*BKW$Bu`zTL zK2T@iDdnNRg6}Y(o0>Gj`=SOfniRUWP{s^x2mEt4S>Tf3(wx(I&%bu9H8Wi+HR9R=rQc!>TH=-M3Sne#x% z%hS23h*S5A5tAld^gM*6&kW6RrdCC&09nw>LjYa}v|a_YE&*CE-9jruDS%Ct^gjFj z|3s+wCM5i?Vr1+VM)Ea`WIx16(@h5;O`SD#m?4PL?;i$bJSd~UfUL30dJZ_QS=Tn} z+9q8K>sphp>AKdaYe0n|UDI?esA~G>U7PgYsvu}-!h0{Gh-~c2hfMV9RO9A zzR!ZA6z~ZkzxRj#j?jZ^EKKob881nA*^5_h*VHcg@Unte>hP71X=)1szRcq#ye!}q z*KJzOB{yCc@rnmuK_6`+omR8p!j~KI62;3pUb$Vfy0i%|hw;j0eC1=B)q)3KR`C+S z%K^Mne>)q3c)0oSZ^9|LikH6U z-a=^e2mhOxz4g8@4t_U7ogR{U5T^gr`;efFb^#*-K>|NIlr)K23l3^RozOb`e?X?z zWDvU^=0b6O%$F-;u9_rb2C1o$)BzS~vtMd9Uc%OQJ;wKy{)>urpJLpH0uQX3 z^^(=^GWt2|kFkZt@E&aJard8hTi?LeOK#&Ok8uTCX9R1%U~R+JUwc|dTECngQ4~vP z{bG7M_T&95BpC-#cmf*}QvU_Xcov19$Hw#C{tMplAIi|A!SUGd{i4|bOVy(Hm8)+; zz+(XqPz)d&;aBu_wVlQ%V1mHFt0qiHUtsMA*m+nBks{_ zPNF_C0$;p`jPAb1{rQ9;cNh(+#FjhepD~gh-4prf#BoVgPn1Y>g2cK@rS#Kh4K)x5 zlqM3T^p<4FSpVxtP8rDn{1fkKuRe}D@6v&iVMMnidy=W>^T!RjbXItJ;iaJ^YYULA;cLb)4cfaZO#tCrk*^Xo>UMi7|{)kQ_V1(Kp_o~sB zmZQZYQ6D{1I_pgqjpUXs$ur%?1A$a2od6TpO@kP2Fml6vswd^Fk_L-9eKoZtlMT6HA;+ literal 0 HcmV?d00001 diff --git a/substrate/frame/revive/rpc/examples/js/pvm/PiggyBank.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/PiggyBank.polkavm new file mode 100644 index 0000000000000000000000000000000000000000..4423c605f746aa424937c84a10dfb9a4f7b6f8e5 GIT binary patch literal 6470 zcmbVQe{dUBe&1cM_pPLr^(1S5=t+rXvxyxjSI-Ss487(=&~Z|@bA>EGv#+Y11jVbh z3A!ZMvYne|xPaxr-6d)uPCy;gCd5u|rcB!-4)L^Uk12-GncNIFL;tE<%9P=bYuYPU z0}1K(t!;3e9>bl+-(BzS`|*9>_xXIj-`&gu-{QD?BAol<5%>2A@dB3+_dn-lcSJDu zj|xV>ZU(y(?CW3;f^7%ev2AdWS#fuNac}RQy^rkP)?X~`DnGh+cX98dyLa_Iv~BOU z-W`vWM^<0&DUBBQ6t@lbF5TP%T}ux?{OI0o+Xsto4|ZpHu%T^(j~09P?%uX*&(7lR z-NlC*gTm8)EV4o<+}pcz^2ql`pP*S!wg{@PDo8v8KOhy43WuraJ;}1-9Y=tOs`m|0eW) z=;KhZIopiFFNBNg!)kV*@}qboKPHx2cP}d%-O*O3mcY-Elsx7cqq6K8sbGH$`TgpeF$@cpXWr@qd^!J zjP8cu4t;w=m)Nkqp_3gt#D+c;7aNd-BrJL)EF}ax$X&DWB4??WIZJz&vsI3VfwP*3 z5~3WJuzdG5gk(XKVfgJ0ee95DhYTkSfwS&!zh&b-WOIV8FTk>_ek1$sf^HOaT+rnL z5{A1yLFyRv6sFS#ossEjWl~m7A!Qr|&=fE9$Gdsj-@)6Rv=pxomqz3Ds#A?C)3Rk7 z&TzawS(=C|N0HSp!)?nhY@Fo^8(##Q2Akse!p2GX=MY#GY(H1f$_1@b(CmWN$MJ$a z#R<-SP8jGDJ=a9kE$rw&!j*>O)Sl#M2?j1~d<*(r0-FcB!11&sTcs2&8CEG_*?Fr! zBiI*UkOUjR7l$$AwNCt|KCGRypydl%rl6$?8f?p&$yRp5`=hG}jZz2GQz<%~r!xt9 zI#VC3kJl&bGc2fQJ<5c~ITlxD`f_?`E%TZ~~J3Y(#)bHww~z zgF&dtg2yeiA5+_qD>C59(=7#;;Dt9|4Iq)@Z2&SadPFV+kL=)us}}AOEVWaxv<|^m z69PbI#nrGE#=DF}?~T9#V2KUA2$0#!kl8D+OAo-aeXRYfxiO{v+2}^GWhb9|R#Nu( za&yv&c{WC!*5>_rN8vQeW~-MOB}kFUOf4|M;Zh7 zR)2o%$J-l43Ffd!rO>*_7g{fay$iO$3;F`j(5YYMsj25wb-+Y`K+hsRgZn@T5-f4<2B z%bzU>xX=n*Xaz2`0?_p-&Rx)p95rS+8ky!Onc`M0=ntjOTaaSEaV_?oWIpHV>0h;= z(|mcFE$9y_?Z5&T7!_eK1m5ksH^dGRCR=5?2^LY_ z0}xybx$9W~0D>^if=vVX0C+$FAv(1Z#I+HCNLl(@Fm}q)FTp8c>GQm$U04S01-IXl zN&>%N<9FzgU375oT{xwvwg7o;DZOa_zKGE44VK1Sh2dnNUxiL5V2TDE^Ym1nM*6JC z6i;VTG-_MXX&w}hM$1<8MZSKlJ`71hIqI!fm4jZuxN|zrWN%ugk-Qa|1*c1PY&>-NhvNm5RXJuu^Q$NOH1_3+g zDM8L)*0APsKJWH^{V>2Uxokhg&JCPhe-adj1+K4t43`X|`H1EvnulnJ zXcEyHi6#=QfoKBJcp^E+yRg&Z9Ph-=dgpitcGfw^%yTOI&QK!JP88%<;K9eV~uvcJZua4*6g^iXE~Em#~&GpZN@m z-6C7jvU!WIXWZ9vmXDP@z=)O^K6i(b8&?8~!$Jh5b4Ta@Af#P`tu1IqLBj=2E=b*} zv2TO8Kobey9DoKNeB#&QpdCTK7V~R{Ukm#+?AH{(Ci^vLXR@Jw=bc|7bnz3xcIzrr z(V359TXg0PY&SUb7~6vLhKvV!7f84L<9{La!z%y}4}0g3f^6Ze zVud6Vfoj#QT3z9{B7N)y$tXvw`~#JM{0`z9CdQ_do&{M<6^m5+JIT+69v^Bb2D z`m2vWO+7?wA=-MPts`2DXi=gOqD6=XI;s;*BbrLIFwvTc79v`ZXqadLqBRlCPc&tf z*2-(-c8UYR9RbDtF-IgB*kM;hv%;#x;wVU+w`bT3JSmQP%~24KJm`e2@8=|(*xW#k zDn~=`0@=JDD(piX5GhvinH42lrs1-Ax2NZv!m6)PpE(MHTKqw#;uSDaekHDMo9`Gq+85Id{IscysJ^zub6i~N7;FofJW+i7Ok3)m~ zA5kM?kGGiPPyv9^S}ltU_N)(AQJ+VxGQ{sXtRcU7xLAv`4-MFDu1%6gsw0 zJd27G9?R&oB5`v9N_{0Z=dq$4<{avoM8#2`MH1#2+0s(QC#3ds?M_e0Yel=10gn|k z+ArpgLxuVSpm8epg2#Npn>#L3lAzJ9*vnohG;)(rXP2+8_uz+qrCf@}I+WL#8naquX1P|e&L#r#4?g7eP8T#?5>6e3 zVZZYs)hjSA$oh4q3L8CBKaa-@XRZtHYjNf}@xJxWTnFB_&Y6qjeKBXw!26=k9LD>I zb6&<{5j={SZj9+nH^wxk8)GWdjj=G(jj?8?8)G4+8>2xyA~W3>4KUppZDP7H>Sww! zsxaLc^)cNT^)lTU@!$%RjS<9TV?<)IG1ACnV?<=KG19Bb|`MAVTf0!7He82IVTAfMt3XKmoOX`APv|+P6=cduZKf=ox6}+^Df?3PNh^|2O0sfh z`OAex*rqRiys-3mKwd8hKY|_3J_vA=aQ3f%j*t&3HTbMx=^e!f5z$-XL|;$zbwrO5 zJxX*!^a#-nqU%K0h^`VnO!Q`=hlm~|IwpF6=uJfT6I~&?kLX^adx$O*9mbM~-bi$j z=nX^{hz>PiXZv)v)V{N4QW}y!4SKZ8oR!&*%mMs!bFvj-^|Teixo2d80&$ik+pZpA=2SBeoijOuDwIx8*^+a7q)EH5tL?uLx5Y-^6PE?JkDpA8kZ6<1ns6nD) zqC)#7qWX!d5Y2m5GXoDiIY%6p7kERDr1c5c<0nU>IE{<3IxVm79QnaPA32 z8UyH`K&ylyrrKhoTdh9O3+|nTyB$!g{&q_H5J+tiw0020wgi>!HYja(;v&=A-B91c zqsE<3;qHMFcNa)5Jmz;3DF-~Y$NQLCkwo#JtGHD!(7t%kYaWF7%0(9CxOLV#CtELL zYu2DRPt^?7Qg*Pf89p>aip#(E9>7b&*1x^SojhQAZZ^Z&)P{8JAb#GGTg@%WrHKK=_=kLw;srBN{13vycH)CiBvLq8$39Gx75sZ&1`dj)v6dgbf{XjlgS#i zXAjaFHl*44U^QDiVg`e(UA6jVHB~bYXS3Ores5N*ZtEJ{ht_w6m{-Bz;e*wb844cG zg(s4swotll!mLf7Fw<=}Cm&C>C6gj%t)9FmX--t#U%V}QIAzujq-wcr&D^@hOmEuo zd@`B5sjZe|-qgT_R+#j$YU=B4hnJgWz4z6!Tj42mS!#6M@o^&<=D zTST}6gWLl%C6hR~X;WKUa3aZK%6`dLa%O14Ox8}+*s80wBiUzGjo^;9$(`~*$5(y= zp$TtF*2Hwx9rf^uG=%1U)+iNfTjkgR*}afq-8%ibxT@7~y3H{UpSbP*`OMZoJ;7$^*pN)Eb|UAA iL&xw2*p1Ids&UZtz8Xy9It5z;Xi2(P5aCj5EBAlUKU0_h literal 0 HcmV?d00001 diff --git a/substrate/frame/revive/rpc/examples/js/pvm/errorTester.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/errorTester.polkavm deleted file mode 100644 index aebe24c4c0f597fb3d0171a9f527bc86d2d77b93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12890 zcmds73v?URnVvg$tb0cq$+9w*M$$m!Fl3xG(7>8vsJkmtQ>0*Wyw+^0a=c3tVr(ZN zq_$(rk3(r<;z!cfh?F=Xv?&QmoP;gqWE%o$PulL1@Yu8MS^5GBp}b$G910X@+U$2n zvh!##ER8g&lh0EKoX=-b0T3k{l?_RH5y>QvG-J3m&n^r8luG{my2mVRky}eo5E!`#k zm$Zb8$@j~@mEV#LT2^v)NvUTEyPj|4>(raQ8+^BETm2oShlBIVE)D&2s4H}H=)0kZ zLeGcjl&Mp`QZ9wh46lro8STa+h8F#7v^lya`b5khzbKxKf7iVHj62T=oO$rfOQ+_h z4o$sh>N8Vm;>wD*Dzek|PgBlHoOR(@4QKt)+JE*1(|>A5DsQWNu9D0+Z^ptI-7^Mf z+&1II8T~V#oVoc^cYLa$JJ1tUSgH3C#VbkV)590>AubP04Rsy)?1kv?Dr}16<&q@N z$mwB*?}nVhf|AS!066|@iX@jEp+S?D8#JuT<%v+)kx(a5n8H0l`L;0QlI$mvBHo}4 z#ynC+BGc(Cg-)lH;$ewLLOe|IFvLSwXqW{R$~?>yR8&vUbGa;+9i+h;T3$`VRdRU} zR2sqxODa6!3G&YzV=OEy9JHp>#gdH8zF|6DApUCNBP}Lb6(p<4kWPk8vQ{JO6f$6tL9X5F z)gDl_F;yF2+F4vYH?UH6J=R~Cn)lW}GuBH;vq3uQ$%-WD&62(p>2XL~9cix(RPxZE zbW94&Ftkw~nt`9{My^gXw7iNA+F}N(ix?NV7#9^W{?5>DR<$7-*jWURx!|!Pc$XpO zG$aQO7r_s>;0KD}hYd07AuVuE5xn08?=OPyGqnAJd_d))jpz&bL`TRc!1r-gGPJvV z=m=cSL-z^rTmyUvU0wv&8roi;U<_t(m}402e3dLQ#lNGxlrJYO;9O&1s5thpm}+Q1 zyxhgrL8HJ!?1&H`t?^Hc)p)rk$&C9HHd~?dXc;L01OEWvR54t$$#Wbcr_Phh3X&H* z>rbUjkzA2b7*SM33IQmWZTT||HWFH%B{b|1xqJbED2?xy{_4@fTM$04kU$z~^m-tZ zUJcUeRUo!r31aK@LSnr_cI~w7bJ9NhLVL`)P}P#m=~bzb^>WCteaK$q9Fj?-G2W$2 z?IrdAHR_xJ9}U-Q_cN!>r+uE$n4@8N1I+36DNr{^=LeEsS9qE4r-~v&uP|4M26DyC z>@_s(Yq#JiWU0%5NNNKrjit^_zkBm-KRS<`o4)hKTa>R*mi||KZ}G77aQqhQc3zr} z8vmHNLGf4A5PwBAS{2%Cv{`7CXck(6$dLpQY7v@Eh>;*9T17~#hLHFyLQIR0a5W*3 zN^)E|nweHPp&Y9MB$6dfqoeJsV^4g=;TF%$_oCtO;3ihr%rd=P-f;|4VC7hRC(-*k&#A!Aba8Di zi+2&dUFD0fQEF0gIn7WHNw%5+v&6!0^YgL^MUhOAL z^QjOBC+98o-pvZDkG=H{W7?mNuU=@%zH8qxy1TL1Y4W%CER(TVf5m3WUoncd9&H3| z9oisTKiUnF9JxVq#bQJv#tjmQu9rw`vqa+SBx3eUBs?mS$e{EdV(}kfSC(wi$quqx zBV!8L!(G-kg0;Mx%l*g9_1s#oW(HLG&@sM&TabX9ObsV~i0HkHx5?(+%(|OqIw{#5 zG}md`A(rW;^1frdonqJH`-wiH@@~!A?8$U_$PR;ynVQcRzl-S1$G`8fzVEXb)4Lhp z$3M5$ZgtkG_H6s1%t4>FM(C$~8HqN=HzuZTB+g|jw#?pU+Zl^#Gri6ZRlAxAa|ccC zRZG>M!&nIeX5RWXW8eGZNvvh*KSB-9QA*SMSL}YL3@Y_;s@s6~lc8?su-p9wo}4-G z2gYuD_e7p3QljJqc=E)viI0~X-&8*-+*n;&;KsD>w;21zJ126Z%vH9JQz&+E63&ul z(xQ=8g)HH6?@2efb-V_5a}%9vp>neH-l!wAavHL3;u18MGrX zx?Gwa>g`t8z%v|(3W4Sj^;sS}(k~W33>!d>?D@@XpAbp&48YCAC?BJnZ5sU9I zw0$hJyBLcj4?rNkgCUL$4De8wz(ByggN23##x6JD-YL8mjbsDOMT`~^goj!L#voU( zF|?Kfh7&kc#5n9?94=xYop3!LjnoHN5rexJyoiC6;fBH(b%D!@7%3McRm4En&|ko) z4P02nsCF@`ix^0GRu?dm0lSD%>0(qCF_1Q`@@So&4{A3eh*=H9tcYLDW=3KNUE@jf z9zlc{wdN>CNN0}0(^nIuE+mSORzMK-#_NUoizD_m9TTaPK+2jsIf*p_pn;=Edj=R| zrJnKJV%ANsF}CCPB$6U+^`t#XIOf$cnW4b~ArBG;;hwu>cQ!&PkH z60f$&b4t2&^6nu~G#Wojsy8GBQpMyU?Ph{$K_1Bic4a*hMP>3V)H_)k+wc$)O>GaS z!K|i;6c9m_NH1Fp>EJhCr?Dh8>u9)^>h(145F_=z>7fT{e?zk;c<$$Z$5`fdyn>9t zZK1pZ=gq^Mx~$gpLB1LTNJAWdtA?ZR0Pa4oU+E;FfiiqX0O$QG_8)? z@OD~enwGgngRUVQxBAeZ<+fsVcrw#G{A$UX%}6MTV3P*r$O0NtJi*zHL1K$3GN9-J z5^N#yWyGjAhnY1j)95Tr4tWSQsxvv67d|lU=xaPyAIDSQ%k@6QfR4UGq$ng_1@}zivvs&(+lQxaGsrVBYxDy?Vpi)9`5?J4 z5yZ&CZHs*>RyAIFO$e_sOV4>4T0Ft?55CISFJ41-O^nKh)``@+YA5=C_}WR9t6Uij3p|H@H2h>oV(3pq0`UOK=OB^*WMokgp zVgo@FEC!8c1KmZ89=8b6BQSPx8cC{s6G%>ACJ*frgl37p&@6#;KPNXRG*qYB29jUb zz#lignt{wGq!q}KVNF%ta!&!UNsJ^!-PQX# z?INM{kSDtf9?4%}BKI-SbhIFvhQ`qpGzo3;(8pi#D}+Fgqx}@^5wyc-52O7%+CdaC zWkW*g=a?KroD@HZs^vTqLQFK}1;j~+k79_K;)t0{#7u6SbW{=rEv!RZ>w7;ZLL&zx z8oo!O=3a@$?viM9k3^^JlxS$1MB`f|8I=*2_7+L;B|ut1d{Zb2)~mI*q?{SJ}zkm3Pw0rfklt**28*$XnwlJ5m!ynC_1S{V~lSqkzQ@eXjwWsd!Jp`9i}x&xxgLFF_goVbdQr{9)Z6 z4*J8IKg|7M#qXJy>isfw1TT1k&Vw%cZ(j6=6JSv2w67@K5<}1bmW%tn7mxc9%XO0l zJ&bl(ew9ld0-9sQSwUEC+1KmCp_xYGq6eBRyB|8122w{1ChKlh<6=c4&f ziydlx?gYyzV*39Z%lZ1VlUdHi_x@JQ?LVJA#jbsL%ee|e!8T7=&TFzRg{7xbhHPA_);3`}+nP#tzwZIj`$u;7AVNEUb{E=S zw4G>s(6*s%aU-{4^n@S|!4$$LUl_4mF@RcfsXOEBGw^bM)fme2%=^bsurer?c!J9g z9uaK&@26pt?3_pwJ3TnRJe>o!2;o??-6pj_$Gtd*APp9mH%Q5>8QIPoCHdWGZKeVaJ?S4WC#SfqQe=${; zJvEuB>M3>SHtngunyLEbk&{hT-<`h^t3QbDzfzF5(xotAs;;kd30x%zoM@^}4Dvdg z+ByoBs!SeSNOR&EN20Yo;b%@uYrDc1W6qugjw{`v^dqinEG9QMPDlC{8>*@$XR4c~_f zlS;$0NF>QOc&tt>vr)_3haywGTVw)GoqJ5oGWQ{2c6g3jt9>NY$nTab8}W2Us+)p_uiLy2a8_F#yWC8%3c{%gK|5e~8|ii*L8MZ?_cRE)<0k zy^WU?cDmr5MKH>isDTc!056smy`m%J6<`#dQ4ZcBs-%Ir#nJ|9D7XYNw+Kenahs@+ zAWNcSjdW+0?r`Y#dJ>*R_teqbQ*qjmOZW&?`4j=cj_ zOM7!>gQjg_{;8DqAJ_bG?vE=t%C}qM_7S9B;))0Aj1Z71j2{3S%VP^;eRpIlfxdSuFe}(V9Y!pmqT;p^64FI#IuhW^oCE44GuuAZvB9E=Vzv z9)tGkv@b}8G&0P|T7?W!%%g|XUWMkyIk!&w*{=odryqyEBOPRgLOMC-D{gY+f}~H! zeGVb3qKFkhSqf(iGmHBPS-pMy6k@!#k17~2E-qrAw!gK2k)4po2VIN@ix@a#K-H{= zPI`=y;}gQZ$$fiM@ofk@viNR!LYkMj;3Y*cq#0HA9?!(-1;iDz^A^DcaqT&t=+wFO zvy(48?PGSYtvS7#z0{uREcI$De9i%{z1FUAaA7Q-wfDNW2dKC`uvf)VhO+PM0U|?ehW_LYG|_p z+ew>I8mG-1+E1H>^`y-~SaaH}L#HV2*hL!Mi(`p~4W7h$Dd7%u{-cVDOuwN;*mpPQ zPuwDvxS)ub+G)=X{QQKZKQSu({1<{V&;Q!R7m5G*r+uxE_$M|=cewcbetq15ScGaag_>OD6ge)6Yc{AAR4WrdZm{3X-idV zCTL9P1ueI@xZkNvZ1!KDqHzNe35uJZ=lDbZ`%HBlFXUDTg zPY=Ir)&Mhbjm2w=eMP|z@g)I|P+a|60IgZEBsq>X3{&Hb<&-9lY{&L-4 z9`u)M{&Maw$EMGYcO7&!0`ebp6+t6W#TkWaaAytkmz1&xP`;flH;Jl>7<#*8W9Yro z#Lz37FmM9bcrp0Gj;mWh;JS{)wII^eo>&e-O^Lo2*sz4=^u(E@7`#H@-B z;PRF?Gw3A|gYUrYGPr7!@58~6Cv%@CvkS7BK-_P20-=)c!1+;0W>*P`SXh*`5}mVn z51zD*cEgr(iW^>?L1AuJ8nnkG!6YfK!F@TotagfoEXR}BDeZj(5s4?UOWOU2bVt9X z&b0J~)Y<9$aPT|fIlQ8Ogs1cCQSlSM`z-)At+Ysjk2Tj@EWyrrg7`F^YLyFyLp zNBXUFY7T$}kRA$cnv-`vwK&yUTWhJ&Ibxu>XQy{sGX#b^Zm`0#D$=2#_>|%EwZXx` zRNlJDMFG~tU-`6cRh)CcCc4CrhVw6@Jpo#t!$ z$ukvOpLZWZazIqjPnU~d?oJBc;*$uuTuuo_xSyLg70|I%3?SC)O*dTO&P)vSUZRO% z@h1cn61Q#r`usN0Beot5l)vi2#XqUMQb2CVZv$t!vPyh`4=EW#+-O+^VkdE0Ol4dF z1Oc%n7^LAQF|QEVihuR|NELSI_!M2?KV<_1+}#GOEIrcDFgGvuqoLSNn3|wc)Q5B) zR4z#bt#KCNdsV9TESDJGObNyoR*tb}s5j~OKc7(3i8NN&zYQxsMT$WYOoKT?}1i8fRf-*mjwgy>*{?hrx+#BHgDpx~@{`_lZX)SN_+EAl1o P|DsnIq4bp_3F&_TlmMih diff --git a/substrate/frame/revive/rpc/examples/js/pvm/event.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/event.polkavm deleted file mode 100644 index 859c1cdf5d3e97c7df8cbad6a0dc0cbd5f8d6388..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5186 zcma)AZ*UvOb-#Ce!0sLPzykylXA-qY=R%MQ9W$03(GJ@|Sd0zOtcC?J3a4QsN&<^N zLL{1m#UqL7C=Oi^q&gL0wxkq)@VN4b)OeD{)|iy!nKGTph?epplZo>wlPEKtrkP1= zJ58G=bOk7M>qHQXD^ea^f#W$Hzz0E}y*Er3hP#``u`)aB9l^(v^03v3E=2 z;Dc_s1sVyHKPF!wMZ#TSSGVg~*J0PYuAjMnDF{5kI# z@2|YyYiKvF8$UJn`1bog=Sxg^rwxTRXrEU!NrK1bpJWv#m-qT7Z-4F}c4!LSBWX;M z3N_E2H4!w>^?s{t{c(0;?YNW$5@$=i7hKS^f-F`x8?>&w@M$^2=a+ zE%DC7um95Z1XcInqx)g1hUDpOd2ZXsRy>~T^2^)of+_|z@DKJ#vhOxALZs0oO#!*F z)$hCQKMe|1nA?#5aJz{zN!CG9gi9o09+G_!Y$sg`X(t_`u|(4NecZ%Cc{h7`>#ihcq3K8zVSPqDi3 zH7uGT(WFE(D4GFDCRwwc#3We`-o`B@nNZ?6Js8r1rXCFFK|>F6J;?N+qSHezA7n%D zf&pKJN&x0Vu)yK00%a5C7{8|RcT~Qn@-pS0V4_{74fHQ@18S~mPoZlw02vdCgD@6> znIR~}U^)fk127Twb};{(v@Ll%O}@hXo%pJrXX+y+ud3KVvLSCzUE@hdWHt_#n(-KRZQqg}C3ueege97e`Hg#UnNbJ=kJshCi-CJ|sR@SOYr= zS=_l{Z>4T~UbyNni@}pjoil5Dh$kWt#Q*0*N_#cNC7CjhLc0}mNbx~U==~82_X=~F z5VIL#PCZ0?HRu`t^kD;4BnJ`-1w~aPKMG~vE5sNkjYFg5Nt3C05Xj*^Xb!bp zR`y5oMgP8woF1`LS-w=!oLX` z7^lc#kJ6`W2if%N-%xtuqmK{r5K$!4byIR1<_#n|fs*ETQRkVvbV9Bz)CqkXb!wsb z@HbGa?IUOj!5ahcW)!Za;A#xsj=)=kurb67TwoOu`;^K%9r)h?QFY#QLRH16Ulr%q zz`p-m*!aCb4w?!}yyZ4pyK(wge+#CG8ziu*NRK#({E#5gi)C2e-`tJac1I(!O^mlC z(zqd!rYn-%xGCL1e;q&gHKjk*6a~Sg3Hs9*GMlC$|7kK3p2m^zybH`P;@i96#PUKt zSTWu<#9~O+elS-^4`v$e!91nPt3dLFmdo2DS8O@InVMI3sc)Z&`{~~&9JCGTbj&0%m&h%Yo;- z(yJ7X6fHkB;n64K#G$Y;Z=$x93hW8oWc!VX_c zu50{lnzS{@3?-+qEwM1u%@9@{9^Eu`GoYJ>ZgSnkUWH_%I&09Lp>ntteIS_;xAAEU zeRu+=EI|f=AqL+yaJ-Plv8P%mPm$~aoyA5A1vzs@Is}<>63GN0a~2<%_~!5tg3K&F zaCv9&VeP=P`yc<4((k&_Js2N^i3k*jU@Qiu6wD03RP^4lRS&CGg#4IyrCuFeaE|Xn z{rJv1wS}OJ>~8EKfKd5P098C*RyUwJVpSMG_+kBU4yzBz8>@@sjyPTy*U*W@Nl#sT z&&o&Jo0;CMAQ^-!E$g@UmH-(cRS{ty zwqYa{R+3D?aL141L*d7hJu-R~UV#(C;q~MOrBloIqccS96RUGp7 z3Pw`P@}`K2YytAI)I7Q|0QrdXG6?xzd}*LFXgUgZh-716nm}t zO6K82H(6ki?jf@rj`b2O#YZCKOaO94QZXSHBb5-P|MK8kSm1T=K6u54%VEqI zLQL+1*Z!JVxep-s)x`3Bfam|=zgQF6SO_b_s-8*+p78$uyMM!NW>O42<% zUaPQwDC5!HW$cm&F3fjpg32+U;O5JdBbY?+^xVc%OCM1Bnv7%w;q1tRL$9jVt6Fje@!lmMQo(t; zp%4>^wBlj6JZw#|mQ?mN5}M%FgvXkt$s3-~Eaf+7a@vEDAh@hWsEpfc)>Y5hxT;-+EocPqxLZE$5{o3RyJEuQ*p7 z%+0bm1x!W_Gzm_4jk%4;{`V=3VpJh(jNOy)k?nEi^73A58QCey@J@6d{4=*(uDv2I z5$82soLPgmEy)`rBwKPDeLsGW()T4fxQRDd=lXiK>Be_4$d5g?_8MMezwtuJk5}1# z@~O|@b@u0d0ptPp{z3igc&#mWp8ADO8(%z_f^2};y?BWtb`RcjiG2XFt;FtztVQfD zJ=mcKEj@_Tf*fTa>m365Pb1ra^(bIH3ZfqMZQ_5m;7S#|tw;OOsW0L>e>bJ!3UziU zHuD@-yQu9po_-j0A9HkDk)J+)&mjuKgyuG4zxek%Yhw%V0eHddcYWnOA@48Y1Kh?y z@jdCaSxen#1ro7O#^ZmM=zMf-Dc!&Clkuw7*7xYF(Z||+RjX6=$>Lp&_gAeaI^$I< z?vKw|@#?IFZ`E^_8jm^eeg3M|rpBx1W>HuZbz0Ve7p=9!Tj#!qedpRNG_;zk&Q>p? z0uvL=G7!oyIYTTlh4|e0TQl1Jc2@Hx;<3J3=Q+!&SXNs+(N^tGzQ{ZOdTwrM7Ofb< z5!9**q4O@@+TwkFbV_(t?~C^@&c=4E<20!4`1^l-7goeN#QJtst+wjLi%ZsP_>0T& z>cyD<5fn0OZZT&0YCZFFa|y9S PI4Am)*gBU=#F+HI@tB`4 diff --git a/substrate/frame/revive/rpc/examples/js/pvm/piggyBank.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/piggyBank.polkavm deleted file mode 100644 index 1a45c15d53f68431b7e5c1dff297c768e1160e97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12334 zcmd5?eQ+G*dEa;6)$Y4@yQkH8wYzt>!8)<{B;zIyby5LND$GGnMtD@+K{TlnWFw=K zEQlh@(n%IGE^&}#I~^lCST=6zfNV=xZJc1hUzu@$scq~(NQX&DhcZfm0KsYaYU3eJ z-QT-+@>d<7GYOsE+_N9=`|SJqyubJNJi85d-zkt!&lmh3QG_4QmyQUv(wgl7o+3f` zML8r2nG3lIavS8!kY$j2mv(k?S>D~Yyyu>kJzwu$+P1v?fv#0O-OGDcbw6-V>(ZX3 z_uTvSuKo+}SGErEuqib$M6k*Zbw~FZ+Tx`HyYF9$~NWvT%^TDTyW5l-y8~DOs$1 zO_^ZNv%~63>Q@7Ofky&+0&i)i{zd&qWxp&l!$-r5XU#SbmVeRuroG9&Gjd&YL3AV* za+iGS@TcDWRP>q~uh}>|QW1?O<9n}-T=)K*%EVtK)+Dwhb|wxaq^j>$ovzwh{SVcR z{hL8Mt{4owN7XiuZtw9Re&hHksM?dZ0t z+lFpyy3KT3(v>A@8OgfjA%lFAjF@DdOV(>-gG7cLGR(At0qwY|O{&_EqFu}Qaf?!_ zJWa*6iY0_Bs~{coN!BCnRb<7y&=dftX8a-p>fjiD9 zN*f_<4q4eidTL2m6B(!{{V6h-A$`fv9!8c)_VvNggrn_e_S~R)$Tu#S&IF@bHCr=bt;;Q$cR!6AV_1 z$4S;i?WEn!n{BCbKks;7GkQTfBpZeF^ETMKRc_tri2oGU5C_M$p);a>2Jxmg>9{hadQ`mk{qCn;XND;E-)V{C>XE5^tsgc z_19mzjwq?WKC$!L4~eCz;Zs|mUnNp=kcM0I_!*+dPeVR}yazc2c^mQuWSRhK2?x{g zdxSXCghW0fBzlIB*eOEXHwdv#6Jozj&O>UOqE(%P)I$`#CEYGr>5v|i3>YLw1~t+v zkv=A_KjW=u?BSqz=&ZX!^;QJaV?i-@mhD%)e!&}Iv0h?!$}G#=W3qRQrCXQ_b7@o3 ztC_g_ER4X*DX|G+u4OEzLOsS1M+=f(`J`lv#4#R;)v(6-EE= z3vI>WwsLUq@0^JTFgSNU82xk;p|f%`;{!O215V?B(>UNX4mgbiPUC>n_zpp|cL@IY z>=lRubdBs2Nc6BkVp9Tf#|2{T7l=I}{GRc7S|s5?Qel!Ra=k{XB{C0N`WcvtHxyu# zOk8``-ORkrYI>b2zIc{xV;+WLA`m-D%+(4T2)G9o?;uV0QgXfFZqTqnrTeM)>{+&w zqVKT-#N4Q|e$Csiru$Sf$03!j7F1%ZiTRAewg_IA;yn{Ie<-tF`3ox&N@j(UxFK;O z{ajFMQ8QbDi7$~zPi$+&?5!m8B{lI-Vt4v+1&cj1q-s>rI(dbe)oQ6)U6LQ&=vRNE zDBnMGesq_}lHiuSdW~$jKf7jTL_bN3dl2UM|HIK+G`&AO{5+}~Gv7onyVu{3dp--J=o5qeYH>cr|^z+OG z>b@9APcjl46c0d|+dC$lxIN}}m5l_vZEAX0)lRV3Fji~MTn~d%J^a@*a}6dRYhp#d zft3^gsVE$>EQ~AcsE=gLw!9@o{RgtDF_1pq{a5aOEXp z8F37eI?W_%itJ&TMw|FN?pC~qRklSVF-;@}6WuB1O)2RSh1v}yoMoa2NMrjX5|KoL z(mau}TPZQS*k*}1Jq%mEQ;!AC#wBbV?q)pKL(LQrfJVA9{Q>qk^Qu&~iF!<=;jH_V zLTA-_Pa(Ip@p@`!GW|j7BwdDGUPuRm>>29a%ShA}iRFlFgXle{q=yya?UrbG(CcO--0WQ&Oy9w1 zq{(d$YA2M;01P=hyAL}=>+EefX3|^mNT;9D1ppydPo`bT1QhpLRXd<+F9bk-u~%ls zK)vt4N`Xr-_nHqCrRy}YT6D|REl0OZ-7<7b(=7(ZtIJDLtG@xG^_Azn|AC_1dRn(C z;5d|B_5q1`5!@^&Tc{^P617v3j7?p%j|gx~!Y^PiIfi}a zB=#8)>ex#{Xpq^R8mEUZ2JAMCdnRC2M-}dO*n{v)>^3Fum)I+OHh0b|v2&auBG>mx z>~=r*oJV5!z$4+gzCU7TeZDq44K5ET`oMnF^2ujJ)i;)Ietz8X$M_!X`h9bD%HqNo%7Xv<{Ta?cvyMv z3{MQ`6sa$&lp~RbqDnnjB}J9GNTjK#QYVQt7gcJ;(k!afN+Q{!N?Fbf;YogizogU8mCM0&g87MwbV|9-W`w#)y^kmH{OP-RA>z zR?>T3qp_Ow9Qm3GN*eYcRBeg%5F!PM#L-mh^p!r+jO}}_oQEJ{V`K;Rb`Qp&Zna*hlXF8nmaHhi1#hPEX$9;rkk9l(V5}BE}FA0vjrZ1mF(TeuYzWYQIdV^%5>?seKZs zB(;y>l%n>$8^AeZgJkXwoE-~{do(BMq; z>P&v&9ltD9TWt+b5~VnQ}*A9}k~`AJF1OTWr{O^dp5FPHrI zSLXp3tg>+>7zVKym|Nh>%s2bFFK0eMy;}q3q(30sE0UaYwr9Y`Nk_dlq>;8}?)zYCIj)Ab70mK6zH6wD zIldWV^T}(#v}yD(QB=9)tM7*T3q}s2k3A??Fkw)AzP-tfFjCpLefmw_ug|=jH_+5i z{M(9mNu-6fD|);Fvs6nM;G4in#7zoP4{3m8AWh_~=)kjvS4-^{B(xG5$-*_Sz&mI6~P2WUqz4saP9)cEe`a@eqTuN?}4X-rOHzJ$D3ktrgFhX zg-yiA@-yg5GqF$O1W5k~CqVjpeh2MSIDy5yjT08}8#sZ*Oye{-V>^on-{50>;vIqk z>P8$tNd_`xHKO^oq_=_Od;+uICoq`g>Z>3y9LopaAx;Y!zA6^eBpda=d7U@n_IE&d zuZZXU;4iI3!8}_8%!$=m6w14bLU~V7D9;sz^1T>FmO= zMq|`hZ_lgq*v2iFeX0=K$h`Y=-j|!+I=>C^=*En_-hI-~j=kmEYXezXOM04od(H6I zP`PAi7YpA9IN|*FGTSGO3|>O5*KzE@TPRR#PQZoGG3GP!&~Y9e2p{L!AkZMc$5m}a z3+*ptAMmpe6tWS901l1>@V+Vkbe*4FSIEXYr_IO?hH47gH~QH(7P9f)X%n*LP*owj z+Rv^oWFrzW%2ytrB`b?vp2mR8t=b+x(ZC$$G>!ZI9EislUx6RLdG#x>SvHzhP4iKI z;Y~iQk!H39^LUw=rA|s`?D_s3;+W)(fvxng0mNYCbe{~4%i03o0MM|DC4$~+EnTUl z@6!N|Y*6zCk>1J@lGh`rE1}%U+IU2t#}K>mo=LRV2sA9o##eTt)U^VQq8V!hVhkfH zv;h$!xUq`2PNb1~;xvP4P^T%KgL@0J&A96oZ#{gDoVSs4hIB4Stc`-ZksC8{HVf(Q zAX;JeN?xywkbyZCaK{vHOilNyW(VlfnBeVG%p6?f!MlgZtnGN=(P{2t=9tD`x$MHg zX3ZyL^HJG+SoQ`Pj^;jQ4k8+uGrPcHx=1YJbDjop9xoB(%qOA1(;{w*c^F=HlL@~G z8yj{_XOJ(lcK=QN7Dd6BH@q=JhvderY&5_7ns5Ja;Kd(tQjP5}{ycPp2yp0bo>>ZC z`?0TS@aM&W+1>z3Z(=#YTjReR!F=?qVJzWDCj8_y0t&=zA$K&9`eu@9Ah&0(ybNdv z@87s%8fy1VvAtl5@bJ)hSn3s5iFn0T!lPCV;`YD9TO77A;01!|t(d(GgS&cinym}4 zc^VCy)UEL5Y3#)S4`4VRjk?}CA-!E-D}pQtE{Q-0^H!+rM*rPdr|Q-O>8yEPjhKd) zTUSf1D%bZ#(|g5>nThWn!=EMfNfo@C(-$Fhyue3Z!g0G5mY@iKdMhP%yMl;~*9N<408yfm`RSyJcNsLA z#8RS018dO|k0p+zPY8*d69ehh__!mO*^4+$EsfM@n}XC{2<8oc0%2;5TVi`+eR>1p z|a-rh)CoLKoigYSjgB+=ghU?~Z9(KDKH?>|#In=;Ma&kw5~@l(OQQ11PAlGsq8U%M|S}pR9C$KnchtKX}cLr8*{} zvxR7F43SzFu~kHE`GyNT$Ls=Yuy%%gNPqA(9wg*}mA(p4ZVv0M=Fj-N-iy*&`0Fb8 zvep`Sm}~GJZixhhUqhw2={kIgSCOdZv;B1XKnZcZ#Bo0ByV8@g zHl?P&BWus8fLcCVx8l$UM}I0Slv)kRAr_ zaM*5qECN>JvS-1q8j++?afS$mNVI(BgrzO%S-G&Aar1j-ug zQoIw7^NvAj)Whgps6AoCcV3)=L5eTx_!gTiuN=R7c;hzSn5ytd(t}*^Ge#yJ!3b93 zVJ`VU3Qt~Gdf|FxEi~0p<8N@kXze&}%gisyhnoKl4Dd`b=gO-KLod!dfZs!@p)7sQbxA-|(=^M}^!zd(` ztSrAE?-p;_ZAiqB@|N>|oSP#rYSH=LptkW#OcYAI!+4@`IFnk`!7uX#%p5D~E|{d5 zCZKx134Wz<-Ye8yS2^O1^3H`(2l zKJ0vK_!Q@B%`aGfjfpEHR);I|h1P}Zc+w-|ymJ@)u>`-3)mKQnwD5~mefx=H%4eG5 zmowhTPjl6B}VbOo#UH%;%%dgJig-aH|qizZi7kwou9^W JpgkTJ{s(-6RoDOk diff --git a/substrate/frame/revive/rpc/examples/js/pvm/revert.polkavm b/substrate/frame/revive/rpc/examples/js/pvm/revert.polkavm deleted file mode 100644 index 7505c402f21b7f8a16914f1f067f94eebb9b3c96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2490 zcmbtVZ)_V$72h{A-I-nQI_r&NZ|v2@343u80z@Ucrn-P!%c6FYMv=2Z5h`i}ah+b% zQfxO#{|H5pyV&VTRK7#a9Uy_!JDTv};6Ua2=fj~Bkm?XfAU+`7ha&L_z9At6HEnof zn}!3OiiG8TJ3GHOzj-tBdvB&be@uZpn$q|ISAIUk-c?d8!(_(+d@Ou=@Hu_%{Dn%n zFuQP~RH$4iohuhACr+O|d!aJ>rG>(Yx!KC>;_SkO!ih?0_FVZ?p;Ri&9SD&sVPBqI zSg301T;cq}S1zixqft_|i^`Vrmhv0rG~6V=Ab%o%C++ly?3e7f?62%I>L1jD{G0qf z|A7C6Ya%4_7lW59#@qBGOji{6)cRpj6J)K+UV8BSA?(l@Z&!4oD5QTm9O3xRFEef_ zM64mO-)dJ#=mE7{+TqYhm~0DZ~VY$q_W~OokxZO9vV4rG3(P z(j=sDrE#PQGaBI*qg>^x#WdAY#|a6&ORZ7bF+wB5q$7os{rN`yhj5NM9Q_@UGlT`?vcY0|?Atd?$7fg$8{;OuxHKUFh4VzKRj2dQC zm{Df(Ng9HA7rt)6H=q`Vbr-H0@G^rn2dcujqZ{`%V^cHMxbZO|?RDP9zlO_ihNge# zG3S>7iVjq!;Cu=$&%l)|T=Jnb0p(1vPuNvuPYL!r#)h!_v8lZ#v>wN(YuG{O-QY;e z<8Z^{aLePeU!umxNYzntO;RBK2c@@e${vx)2KCBEa|%qmv{A zO)!{3uuIYvU9l`saoQw=n!>ZZM{TIQh9npVrZL4vkc3vKb%k~;(@2GMtSBg>f1OnL zZ@Y~Vs5q)i_0j04&QOZF6s4}AWOad()fH5$ZlG?H*OTl1bv^lhlKby-VZTdZpf{Is5YJNcadwrcz&;NNNpW<~CczoyH$P>}zVWE*`N^GiJy)LsMpG!VG22P{s_UNHitIYfpibf=(Y|$00reZU!PV5Y6sO zx5$mYC(`|~0?`pDxll&MhT)P0%W%bjMFvZPT;27q3h`2a+}(4}Xx^E?^hSUz?}>Lb z@1o+>M0^p#3#ynG?zZY}i|LcXz0QpypS~=}5BBhkyk#E03E@>CmNoRBUJ}L_k1s*E ztceZb;lIqoC5|QL6Z}Z?BqLvV$oZMa`zJXGOmPl8LsiR()22`CIrKUDAs^I1GXvci zVjq7D)+mrEpebN85XgezgFXQw6MR$Hr=*B6flh1on^K3TgoX+9f>bc=9QhBWu1k-t zhEi|JQ>4!D|C41kJ(z7JVXl#cImwST0MqDI%u)8V0`SolL^WOt7|#pihD;%PaFwU$PQRO^}Te{lZCU9g8x<6=NJb@ATC??L-W z@(_f*UsSEc z5XN<67owx0$g!H^Es*%{iVn_Dy!t^`6`*qvVhR6s+?qa!jrf~#k09n@!{lvZ=bK(&&S#&^)z_`>2fA0SbavItjipx=*-qE%Uhdc!ntI0W$<@7XEmvRl zyj[0] @@ -37,37 +37,60 @@ function evmCompile(sources: CompileInput) { console.log('Compiling contracts...') -const input = [ - { file: 'Event.sol', contract: 'EventExample', keypath: 'event' }, - { file: 'PiggyBank.sol', contract: 'PiggyBank', keypath: 'piggyBank' }, - { file: 'ErrorTester.sol', contract: 'ErrorTester', keypath: 'errorTester' }, -].filter(({ keypath }) => !filter || keypath.includes(filter)) +const rootDir = join(__dirname, '..') +const contractsDir = join(rootDir, 'contracts') +const abiDir = join(rootDir, 'abi') +const pvmDir = join(rootDir, 'pvm') +const evmDir = join(rootDir, 'evm') -for (const { keypath, contract, file } of input) { +const input = readdirSync(contractsDir) + .filter((f) => f.endsWith('.sol')) + .filter((f) => !filter || f.includes(filter)) + +for (const file of input) { + console.log(`🔨 Compiling ${file}...`) + const name = basename(file, '.sol') const input = { - [file]: { content: readFileSync(join('contracts', file), 'utf8') }, + [name]: { content: readFileSync(join(contractsDir, file), 'utf8') }, } - { - console.log(`Compile with solc ${file}`) - const out = JSON.parse(evmCompile(input)) - const entry = out.contracts[file][contract] - writeFileSync(join('evm', `${keypath}.bin`), Buffer.from(entry.evm.bytecode.object, 'hex')) - writeFileSync( - join('abi', `${keypath}.ts`), - await format(`export const abi = ${JSON.stringify(entry.abi, null, 2)} as const`, { - parser: 'typescript', - }) - ) + console.log('Compiling with revive...') + const reviveOut = await compile(input) + + for (const contracts of Object.values(reviveOut.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`📜 Add PVM contract ${name}`) + const abi = contract.abi + const abiName = `${name}Abi` + writeFileSync( + join(abiDir, `${name}.json`), + JSON.stringify(abi, null, 2) + ) + + writeFileSync( + join(abiDir, `${name}.ts`), + await format(`export const ${abiName} = ${JSON.stringify(abi, null, 2)} as const`, { + parser: 'typescript', + }) + ) + + writeFileSync( + join(pvmDir, `${name}.polkavm`), + Buffer.from(contract.evm.bytecode.object, 'hex') + ) + } } - { - console.log(`Compile with revive ${file}`) - const out = await compile(input) - const entry = out.contracts[file][contract] - writeFileSync( - join('pvm', `${keypath}.polkavm`), - Buffer.from(entry.evm.bytecode.object, 'hex') - ) + console.log(`Compile with solc ${file}`) + const evmOut = JSON.parse(evmCompile(input)) as typeof reviveOut + + for (const contracts of Object.values(evmOut.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`📜 Add EVM contract ${name}`) + writeFileSync( + join(evmDir, `${name}.bin`), + Buffer.from(contract.evm.bytecode.object, 'hex') + ) + } } } diff --git a/substrate/frame/revive/rpc/examples/js/src/geth-diff-setup.ts b/substrate/frame/revive/rpc/examples/js/src/geth-diff-setup.ts index 92b20473d165..3db2453f2475 100644 --- a/substrate/frame/revive/rpc/examples/js/src/geth-diff-setup.ts +++ b/substrate/frame/revive/rpc/examples/js/src/geth-diff-setup.ts @@ -1,5 +1,5 @@ import { spawn, spawnSync, Subprocess } from 'bun' -import { join, resolve } from 'path' +import { resolve } from 'path' import { readFileSync } from 'fs' import { createWalletClient, defineChain, Hex, http, publicActions } from 'viem' import { privateKeyToAccount } from 'viem/accounts' @@ -89,21 +89,34 @@ export async function createEnv(name: 'geth' | 'kitchensink') { export function waitForHealth(url: string) { return new Promise((resolve, reject) => { const start = Date.now() - const interval = setInterval(() => { - fetch(url) - .then((res) => { - if (res.status === 200) { - clearInterval(interval) - resolve() - } - }) - .catch(() => { - const elapsed = Date.now() - start - if (elapsed > 30_000) { - clearInterval(interval) - reject(new Error('hit timeout')) - } + const interval = setInterval(async () => { + try { + const res = await fetch(url, { + method: 'POST', + headers: { + 'content-type': 'application/json', + }, + body: JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_syncing', + params: [], + id: 1, + }), }) + + if (res.status !== 200) { + return + } + + clearInterval(interval) + resolve() + } catch (_err) { + const elapsed = Date.now() - start + if (elapsed > 30_000) { + clearInterval(interval) + reject(new Error('hit timeout')) + } + } }, 1000) }) } @@ -113,15 +126,17 @@ const polkadotSdkPath = resolve(__dirname, '../../../../../../..') if (!process.env.USE_LIVE_SERVERS) { procs.push( // Run geth on port 8546 - // - (() => { + await (async () => { killProcessOnPort(8546) - return spawn( + const proc = spawn( 'geth --http --http.api web3,eth,debug,personal,net --http.port 8546 --dev --verbosity 0'.split( ' ' ), { stdout: Bun.file('/tmp/geth.out.log'), stderr: Bun.file('/tmp/geth.err.log') } ) + + await waitForHealth('http://localhost:8546').catch() + return proc })(), //Run the substate node (() => { @@ -155,7 +170,7 @@ if (!process.env.USE_LIVE_SERVERS) { cwd: polkadotSdkPath, } ) - await waitForHealth('http://localhost:8545/health').catch() + await waitForHealth('http://localhost:8545').catch() return proc })() ) diff --git a/substrate/frame/revive/rpc/examples/js/src/geth-diff.test.ts b/substrate/frame/revive/rpc/examples/js/src/geth-diff.test.ts index 468e7860bb9a..37ebbc9ea3b3 100644 --- a/substrate/frame/revive/rpc/examples/js/src/geth-diff.test.ts +++ b/substrate/frame/revive/rpc/examples/js/src/geth-diff.test.ts @@ -1,7 +1,9 @@ import { jsonRpcErrors, procs, createEnv, getByteCode } from './geth-diff-setup.ts' import { afterAll, afterEach, beforeAll, describe, expect, test } from 'bun:test' import { encodeFunctionData, Hex, parseEther } from 'viem' -import { abi } from '../abi/errorTester' +import { ErrorTesterAbi } from '../abi/ErrorTester' +import { FlipperCallerAbi } from '../abi/FlipperCaller' +import { FlipperAbi } from '../abi/Flipper' afterEach(() => { jsonRpcErrors.length = 0 @@ -16,14 +18,42 @@ const envs = await Promise.all([createEnv('geth'), createEnv('kitchensink')]) for (const env of envs) { describe(env.serverWallet.chain.name, () => { let errorTesterAddr: Hex = '0x' + let flipperAddr: Hex = '0x' + let flipperCallerAddr: Hex = '0x' beforeAll(async () => { - const hash = await env.serverWallet.deployContract({ - abi, - bytecode: getByteCode('errorTester', env.evm), - }) - const deployReceipt = await env.serverWallet.waitForTransactionReceipt({ hash }) - if (!deployReceipt.contractAddress) throw new Error('Contract address should be set') - errorTesterAddr = deployReceipt.contractAddress + { + const hash = await env.serverWallet.deployContract({ + abi: ErrorTesterAbi, + bytecode: getByteCode('errorTester', env.evm), + }) + const deployReceipt = await env.serverWallet.waitForTransactionReceipt({ hash }) + if (!deployReceipt.contractAddress) + throw new Error('Contract address should be set') + errorTesterAddr = deployReceipt.contractAddress + } + + { + const hash = await env.serverWallet.deployContract({ + abi: FlipperAbi, + bytecode: getByteCode('flipper', env.evm), + }) + const deployReceipt = await env.serverWallet.waitForTransactionReceipt({ hash }) + if (!deployReceipt.contractAddress) + throw new Error('Contract address should be set') + flipperAddr = deployReceipt.contractAddress + } + + { + const hash = await env.serverWallet.deployContract({ + abi: FlipperCallerAbi, + args: [flipperAddr], + bytecode: getByteCode('flipperCaller', env.evm), + }) + const deployReceipt = await env.serverWallet.waitForTransactionReceipt({ hash }) + if (!deployReceipt.contractAddress) + throw new Error('Contract address should be set') + flipperCallerAddr = deployReceipt.contractAddress + } }) test('triggerAssertError', async () => { @@ -31,7 +61,7 @@ for (const env of envs) { try { await env.accountWallet.readContract({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'triggerAssertError', }) } catch (err) { @@ -49,7 +79,7 @@ for (const env of envs) { try { await env.accountWallet.readContract({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'triggerRevertError', }) } catch (err) { @@ -67,7 +97,7 @@ for (const env of envs) { try { await env.accountWallet.readContract({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'triggerDivisionByZero', }) } catch (err) { @@ -87,7 +117,7 @@ for (const env of envs) { try { await env.accountWallet.readContract({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'triggerOutOfBoundsError', }) } catch (err) { @@ -107,7 +137,7 @@ for (const env of envs) { try { await env.accountWallet.readContract({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'triggerCustomError', }) } catch (err) { @@ -125,7 +155,7 @@ for (const env of envs) { try { await env.accountWallet.simulateContract({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'valueMatch', value: parseEther('10'), args: [parseEther('10')], @@ -158,7 +188,25 @@ for (const env of envs) { try { await env.accountWallet.estimateContractGas({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, + functionName: 'valueMatch', + value: parseEther('10'), + args: [parseEther('10')], + }) + } catch (err) { + const lastJsonRpcError = jsonRpcErrors.pop() + expect(lastJsonRpcError?.code).toBe(-32000) + expect(lastJsonRpcError?.message).toInclude('insufficient funds') + expect(lastJsonRpcError?.data).toBeUndefined() + } + }) + + test('eth_estimate call caller (not enough funds)', async () => { + expect.assertions(3) + try { + await env.accountWallet.estimateContractGas({ + address: errorTesterAddr, + abi: ErrorTesterAbi, functionName: 'valueMatch', value: parseEther('10'), args: [parseEther('10')], @@ -176,7 +224,7 @@ for (const env of envs) { try { await env.serverWallet.estimateContractGas({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'valueMatch', value: parseEther('11'), args: [parseEther('10')], @@ -208,7 +256,7 @@ for (const env of envs) { await env.accountWallet.estimateContractGas({ address: errorTesterAddr, - abi, + abi: ErrorTesterAbi, functionName: 'setState', args: [true], }) @@ -225,7 +273,7 @@ for (const env of envs) { expect(balance).toBe(0n) const data = encodeFunctionData({ - abi, + abi: ErrorTesterAbi, functionName: 'setState', args: [true], }) @@ -241,5 +289,27 @@ for (const env of envs) { ], }) }) + + test.only('eth_estimate (no gas specified) child_call', async () => { + let balance = await env.serverWallet.getBalance(env.accountWallet.account) + expect(balance).toBe(0n) + + const data = encodeFunctionData({ + abi: FlipperCallerAbi, + functionName: 'callFlip', + }) + + await env.accountWallet.request({ + method: 'eth_estimateGas', + params: [ + { + data, + from: env.accountWallet.account.address, + to: flipperCallerAddr, + gas: `0x${Number(1000000).toString(16)}`, + }, + ], + }) + }) }) } diff --git a/substrate/frame/revive/rpc/src/tests.rs b/substrate/frame/revive/rpc/src/tests.rs index 7f2d4e683c31..43b600c33d78 100644 --- a/substrate/frame/revive/rpc/src/tests.rs +++ b/substrate/frame/revive/rpc/src/tests.rs @@ -218,38 +218,34 @@ async fn deploy_and_call() -> anyhow::Result<()> { Ok(()) } -/// TODO: enable ( https://github.com/paritytech/contract-issues/issues/12 ) -#[ignore] #[tokio::test] async fn revert_call() -> anyhow::Result<()> { let _lock = SHARED_RESOURCES.write(); let client = SharedResources::client().await; - let (bytecode, contract) = get_contract("revert")?; + let (bytecode, contract) = get_contract("ErrorTester")?; let receipt = TransactionBuilder::default() - .input(contract.constructor.clone().unwrap().encode_input(bytecode, &[]).unwrap()) + .input(bytecode) .send_and_wait_for_receipt(&client) .await?; let err = TransactionBuilder::default() .to(receipt.contract_address.unwrap()) - .input(contract.function("doRevert")?.encode_input(&[])?.to_vec()) + .input(contract.function("triggerRequireError")?.encode_input(&[])?.to_vec()) .send(&client) .await .unwrap_err(); let call_err = unwrap_call_err!(err.source().unwrap()); - assert_eq!(call_err.message(), "execution reverted: revert message"); + assert_eq!(call_err.message(), "execution reverted: This is a require error"); assert_eq!(call_err.code(), 3); Ok(()) } -/// TODO: enable ( https://github.com/paritytech/contract-issues/issues/12 ) -#[ignore] #[tokio::test] async fn event_logs() -> anyhow::Result<()> { let _lock = SHARED_RESOURCES.write(); let client = SharedResources::client().await; - let (bytecode, contract) = get_contract("event")?; + let (bytecode, contract) = get_contract("EventExample")?; let receipt = TransactionBuilder::default() .input(bytecode) .send_and_wait_for_receipt(&client) @@ -284,13 +280,11 @@ async fn invalid_transaction() -> anyhow::Result<()> { Ok(()) } -/// TODO: enable ( https://github.com/paritytech/contract-issues/issues/12 ) -#[ignore] #[tokio::test] async fn native_evm_ratio_works() -> anyhow::Result<()> { let _lock = SHARED_RESOURCES.write(); let client = SharedResources::client().await; - let (bytecode, contract) = get_contract("piggyBank")?; + let (bytecode, contract) = get_contract("PiggyBank")?; let contract_address = TransactionBuilder::default() .input(bytecode) .send_and_wait_for_receipt(&client) diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index a612e7760acb..58d4721b4e53 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -29,6 +29,7 @@ use crate::{ ChainExtension, Environment, Ext, RegisteredChainExtension, Result as ExtensionResult, RetVal, ReturnFlags, }, + evm::GenericTransaction, exec::Key, limits, primitives::CodeUploadReturnValue, @@ -38,8 +39,8 @@ use crate::{ wasm::Memory, weights::WeightInfo, AccountId32Mapper, BalanceOf, Code, CodeInfoOf, CollectEvents, Config, ContractInfo, - ContractInfoOf, DebugInfo, DeletionQueueCounter, DepositLimit, Error, HoldReason, Origin, - Pallet, PristineCode, H160, + ContractInfoOf, DebugInfo, DeletionQueueCounter, DepositLimit, Error, EthTransactError, + HoldReason, Origin, Pallet, PristineCode, H160, }; use crate::test_utils::builder::Contract; @@ -4655,3 +4656,100 @@ fn mapped_address_works() { assert_eq!(::Currency::total_balance(&EVE), 1_100); }); } + +#[test] +fn skip_transfer_works() { + let (code_caller, _) = compile_module("call").unwrap(); + let (code, _) = compile_module("set_empty_storage").unwrap(); + + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + ::Currency::set_balance(&ALICE, 1_000_000); + ::Currency::set_balance(&BOB, 0); + + // fails to instantiate when gas is specified. + assert_err!( + Pallet::::bare_eth_transact( + GenericTransaction { + from: Some(BOB_ADDR), + input: Some(code.clone().into()), + gas: Some(1u32.into()), + ..Default::default() + }, + Weight::MAX, + |_| 0u32 + ), + EthTransactError::Message(format!( + "insufficient funds for gas * price + value: address {BOB_ADDR:?} have 0 (supplied gas 1)" + )) + ); + + // works when no gas is specified. + assert_ok!(Pallet::::bare_eth_transact( + GenericTransaction { + from: Some(ALICE_ADDR), + input: Some(code.clone().into()), + ..Default::default() + }, + Weight::MAX, + |_| 0u32 + )); + + let Contract { addr, .. } = + builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_contract(); + + let Contract { addr: caller_addr, .. } = + builder::bare_instantiate(Code::Upload(code_caller)).build_and_unwrap_contract(); + + // fails to call when gas is specified. + assert_err!( + Pallet::::bare_eth_transact( + GenericTransaction { + from: Some(BOB_ADDR), + to: Some(addr), + gas: Some(1u32.into()), + ..Default::default() + }, + Weight::MAX, + |_| 0u32 + ), + EthTransactError::Message(format!( + "insufficient funds for gas * price + value: address {BOB_ADDR:?} have 0 (supplied gas 1)" + )) + ); + + // fails when calling from a contract when gas is specified. + assert_err!( + Pallet::::bare_eth_transact( + GenericTransaction { + from: Some(BOB_ADDR), + to: Some(caller_addr), + input: Some((0u32, &addr).encode().into()), + gas: Some(1u32.into()), + ..Default::default() + }, + Weight::MAX, + |_| 0u32 + ), + EthTransactError::Message(format!("insufficient funds for gas * price + value: address {BOB_ADDR:?} have 0 (supplied gas 1)")) + ); + + // works when no gas is specified. + assert_ok!(Pallet::::bare_eth_transact( + GenericTransaction { from: Some(BOB_ADDR), to: Some(addr), ..Default::default() }, + Weight::MAX, + |_| 0u32 + )); + + // works when calling from a contract when no gas is specified. + assert_ok!(Pallet::::bare_eth_transact( + GenericTransaction { + from: Some(BOB_ADDR), + to: Some(caller_addr), + input: Some((0u32, &addr).encode().into()), + ..Default::default() + }, + Weight::MAX, + |_| 0u32 + )); + }); +} From 9dcdf8133cbae2184caffd9070d18c1217ac5194 Mon Sep 17 00:00:00 2001 From: Ludovic_Domingues Date: Wed, 11 Dec 2024 02:52:29 +0100 Subject: [PATCH 39/51] Migration of polkadot-runtime-common auctions benchmarking to v2 (#6613) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Migrated polkadot-runtime-common auctions benchmarking to the new benchmarking syntax v2. This is part of #6202 --------- Co-authored-by: Giuseppe Re Co-authored-by: Bastian Köcher --- polkadot/runtime/common/src/auctions.rs | 120 ++++++++++++++++-------- 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index 78f20d918bab..3ac1ba2dc4e0 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -339,10 +339,10 @@ impl Auctioneer> for Pallet { let sample_length = T::SampleLength::get().max(One::one()); let sample = after_early_end / sample_length; let sub_sample = after_early_end % sample_length; - return AuctionStatus::EndingPeriod(sample, sub_sample) + return AuctionStatus::EndingPeriod(sample, sub_sample); } else { // This is safe because of the comparison operator above - return AuctionStatus::VrfDelay(after_early_end - ending_period) + return AuctionStatus::VrfDelay(after_early_end - ending_period); } } @@ -559,7 +559,7 @@ impl Pallet { #[allow(deprecated)] Winning::::remove_all(None); AuctionInfo::::kill(); - return Some((res, lease_period_index)) + return Some((res, lease_period_index)); } } } @@ -765,11 +765,11 @@ mod tests { let (current_lease_period, _) = Self::lease_period_index(now).ok_or(LeaseError::NoLeasePeriod)?; if period_begin < current_lease_period { - return Err(LeaseError::AlreadyEnded) + return Err(LeaseError::AlreadyEnded); } for period in period_begin..(period_begin + period_count) { if leases.contains_key(&(para, period)) { - return Err(LeaseError::AlreadyLeased) + return Err(LeaseError::AlreadyLeased); } leases.insert((para, period), LeaseData { leaser: *leaser, amount }); } @@ -1718,7 +1718,7 @@ mod benchmarking { use polkadot_runtime_parachains::paras; use sp_runtime::{traits::Bounded, SaturatedConversion}; - use frame_benchmarking::{account, benchmarks, whitelisted_caller, BenchmarkError}; + use frame_benchmarking::v2::*; fn assert_last_event(generic_event: ::RuntimeEvent) { let events = frame_system::Pallet::::events(); @@ -1772,25 +1772,37 @@ mod benchmarking { } } - benchmarks! { - where_clause { where T: pallet_babe::Config + paras::Config } + #[benchmarks( + where T: pallet_babe::Config + paras::Config, + )] + mod benchmarks { + use super::*; - new_auction { + #[benchmark] + fn new_auction() -> Result<(), BenchmarkError> { let duration = BlockNumberFor::::max_value(); let lease_period_index = LeasePeriodOf::::max_value(); - let origin = - T::InitiateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - }: _(origin, duration, lease_period_index) - verify { - assert_last_event::(Event::::AuctionStarted { - auction_index: AuctionCounter::::get(), - lease_period: LeasePeriodOf::::max_value(), - ending: BlockNumberFor::::max_value(), - }.into()); + let origin = T::InitiateOrigin::try_successful_origin() + .map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, duration, lease_period_index); + + assert_last_event::( + Event::::AuctionStarted { + auction_index: AuctionCounter::::get(), + lease_period: LeasePeriodOf::::max_value(), + ending: BlockNumberFor::::max_value(), + } + .into(), + ); + + Ok(()) } // Worst case scenario a new bid comes in which kicks out an existing bid for the same slot. - bid { + #[benchmark] + fn bid() -> Result<(), BenchmarkError> { // If there is an offset, we need to be on that block to be able to do lease things. let (_, offset) = T::Leaser::lease_period_length(); frame_system::Pallet::::set_block_number(offset + One::one()); @@ -1810,8 +1822,18 @@ mod benchmarking { CurrencyOf::::make_free_balance_be(&owner, BalanceOf::::max_value()); let worst_head_data = T::Registrar::worst_head_data(); let worst_validation_code = T::Registrar::worst_validation_code(); - T::Registrar::register(owner.clone(), para, worst_head_data.clone(), worst_validation_code.clone())?; - T::Registrar::register(owner, new_para, worst_head_data, worst_validation_code.clone())?; + T::Registrar::register( + owner.clone(), + para, + worst_head_data.clone(), + worst_validation_code.clone(), + )?; + T::Registrar::register( + owner, + new_para, + worst_head_data, + worst_validation_code.clone(), + )?; assert_ok!(paras::Pallet::::add_trusted_validation_code( frame_system::Origin::::Root.into(), worst_validation_code, @@ -1839,15 +1861,28 @@ mod benchmarking { CurrencyOf::::make_free_balance_be(&caller, BalanceOf::::max_value()); let bigger_amount = CurrencyOf::::minimum_balance().saturating_mul(10u32.into()); assert_eq!(CurrencyOf::::reserved_balance(&first_bidder), first_amount); - }: _(RawOrigin::Signed(caller.clone()), new_para, auction_index, first_slot, last_slot, bigger_amount) - verify { - // Confirms that we unreserved funds from a previous bidder, which is worst case scenario. + + #[extrinsic_call] + _( + RawOrigin::Signed(caller.clone()), + new_para, + auction_index, + first_slot, + last_slot, + bigger_amount, + ); + + // Confirms that we unreserved funds from a previous bidder, which is worst case + // scenario. assert_eq!(CurrencyOf::::reserved_balance(&caller), bigger_amount); + + Ok(()) } - // Worst case: 10 bidders taking all wining spots, and we need to calculate the winner for auction end. - // Entire winner map should be full and removed at the end of the benchmark. - on_initialize { + // Worst case: 10 bidders taking all wining spots, and we need to calculate the winner for + // auction end. Entire winner map should be full and removed at the end of the benchmark. + #[benchmark] + fn on_initialize() -> Result<(), BenchmarkError> { // If there is an offset, we need to be on that block to be able to do lease things. let (lease_length, offset) = T::Leaser::lease_period_length(); frame_system::Pallet::::set_block_number(offset + One::one()); @@ -1868,7 +1903,7 @@ mod benchmarking { let winning_data = Winning::::get(BlockNumberFor::::from(0u32)).unwrap(); // Make winning map full - for i in 0u32 .. (T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { + for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); } @@ -1882,20 +1917,29 @@ mod benchmarking { let authorities = pallet_babe::Pallet::::authorities(); // Check for non empty authority set since it otherwise emits a No-OP warning. if !authorities.is_empty() { - pallet_babe::Pallet::::enact_epoch_change(authorities.clone(), authorities, None); + pallet_babe::Pallet::::enact_epoch_change( + authorities.clone(), + authorities, + None, + ); } } - }: { - Auctions::::on_initialize(duration + now + T::EndingPeriod::get()); - } verify { + #[block] + { + Auctions::::on_initialize(duration + now + T::EndingPeriod::get()); + } + let auction_index = AuctionCounter::::get(); assert_last_event::(Event::::AuctionClosed { auction_index }.into()); assert!(Winning::::iter().count().is_zero()); + + Ok(()) } // Worst case: 10 bidders taking all wining spots, and winning data is full. - cancel_auction { + #[benchmark] + fn cancel_auction() -> Result<(), BenchmarkError> { // If there is an offset, we need to be on that block to be able to do lease things. let (lease_length, offset) = T::Leaser::lease_period_length(); frame_system::Pallet::::set_block_number(offset + One::one()); @@ -1903,7 +1947,6 @@ mod benchmarking { // Create a new auction let duration: BlockNumberFor = lease_length / 2u32.into(); let lease_period_index = LeasePeriodOf::::zero(); - let now = frame_system::Pallet::::block_number(); let origin = T::InitiateOrigin::try_successful_origin() .expect("InitiateOrigin has no successful origin required for the benchmark"); Auctions::::new_auction(origin, duration, lease_period_index)?; @@ -1916,13 +1959,16 @@ mod benchmarking { } // Make winning map full - for i in 0u32 .. (T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { + for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() { Winning::::insert(BlockNumberFor::::from(i), winning_data.clone()); } assert!(AuctionInfo::::get().is_some()); - }: _(RawOrigin::Root) - verify { + + #[extrinsic_call] + _(RawOrigin::Root); + assert!(AuctionInfo::::get().is_none()); + Ok(()) } impl_benchmark_test_suite!( From 85dd228d9a7d3d736e0dab7c0b084e3fc2c1b003 Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:21:05 +0200 Subject: [PATCH 40/51] Make approval-distribution aggression a bit more robust and less spammy (#6696) After finality started lagging on kusama around `2025-11-25 15:55:40` nodes started being overloaded with messages and some restarted with ``` Subsystem approval-distribution-subsystem appears unresponsive when sending a message of type polkadot_node_subsystem_types::messages::ApprovalDistributionMessage. origin=polkadot_service::relay_chain_selection::SelectRelayChainInner, sp_runtime::OpaqueExtrinsic>>, polkadot_overseer::Handle> ``` I think this happened because our aggression in the current form is way too spammy and create problems in situation where we already constructed blocks with a load of candidates to check which what happened around `#25933682` before and after. However aggression, does help in the nightmare scenario where the network is segmented and sparsely connected, so I tend to think we shouldn't completely remove it. The current configuration is: ``` l1_threshold: Some(16), l2_threshold: Some(28), resend_unfinalized_period: Some(8), ``` The way aggression works right now : 1. After L1 is triggered all nodes send all messages they created to all the other nodes and all messages they would have they already send according to the topology. 2. Because of resend_unfinalized_period for each block all messages at step 1) are sent every 8 blocks, so for example let's say we have blocks 1 to 24 unfinalized, then at block 25, all messages for block 1, 9 will be resent, and consequently at block 26, all messages for block 2, 10 will be resent, this becomes worse as more blocks are created if backing backpressure did not kick in yet. In total this logic makes that each node receive 3 * total_number_of messages_per_block 3. L2 aggression is way too spammy, when L2 aggression is enabled all nodes sends all messages of a block on GridXY, that means that all messages are received and sent by node at least 2*sqrt(num_validators), so on kusama would be 66 * NUM_MESSAGES_AT_FIRST_UNFINALIZED_BLOCK, so even with a reasonable number of messages like 10K, which you can have if you escalated because of no shows, you end-up sending and receiving ~660k messages at once, I think that's what makes the approval-distribution to appear unresponsive on some nodes. 4. Duplicate messages are received by the nodes which turn, mark the node as banned, which may create more no-shows. ## Proposed improvements: 1. Make L2 trigger way later 28 blocks, instead of 64, this should literally the last resort, until then we should try to let the approval-voting escalation mechanism to do its things and cover the no-shows. 2. On L1 aggression don't send messages for blocks too far from the first_unfinalized there is no point in sending the messages for block 20, if block 1 is still unfinalized. 3. On L1 aggression, send messages then back-off for 3 * resend_unfinalized_period to give time for everyone to clear up their queues. 4. If aggression is enabled accept duplicate messages from validators and don't punish them by reducting their reputation which, which may create no-shows. --------- Signed-off-by: Alexandru Gheorghe Co-authored-by: Andrei Sandu <54316454+sandreim@users.noreply.github.com> --- .../network/approval-distribution/src/lib.rs | 143 ++++++++++++++---- .../approval-distribution/src/tests.rs | 137 ++++++++++++++++- prdoc/pr_6696.prdoc | 15 ++ 3 files changed, 261 insertions(+), 34 deletions(-) create mode 100644 prdoc/pr_6696.prdoc diff --git a/polkadot/node/network/approval-distribution/src/lib.rs b/polkadot/node/network/approval-distribution/src/lib.rs index d6bbb0dca83c..cefb1d744992 100644 --- a/polkadot/node/network/approval-distribution/src/lib.rs +++ b/polkadot/node/network/approval-distribution/src/lib.rs @@ -316,7 +316,7 @@ impl Default for AggressionConfig { fn default() -> Self { AggressionConfig { l1_threshold: Some(16), - l2_threshold: Some(28), + l2_threshold: Some(64), resend_unfinalized_period: Some(8), } } @@ -512,6 +512,8 @@ struct BlockEntry { vrf_story: RelayVRFStory, /// The block slot. slot: Slot, + /// Backing off from re-sending messages to peers. + last_resent_at_block_number: Option, } impl BlockEntry { @@ -878,6 +880,7 @@ impl State { candidates_metadata: meta.candidates, vrf_story: meta.vrf_story, slot: meta.slot, + last_resent_at_block_number: None, }); self.topologies.inc_session_refs(meta.session); @@ -1317,6 +1320,33 @@ impl State { self.enable_aggression(network_sender, Resend::No, metrics).await; } + // When finality is lagging as a last resort nodes start sending the messages they have + // multiples times. This means it is safe to accept duplicate messages without punishing the + // peer and reduce the reputation and can end up banning the Peer, which in turn will create + // more no-shows. + fn accept_duplicates_from_validators( + blocks_by_number: &BTreeMap>, + topologies: &SessionGridTopologies, + aggression_config: &AggressionConfig, + entry: &BlockEntry, + peer: PeerId, + ) -> bool { + let topology = topologies.get_topology(entry.session); + let min_age = blocks_by_number.iter().next().map(|(num, _)| num); + let max_age = blocks_by_number.iter().rev().next().map(|(num, _)| num); + + // Return if we don't have at least 1 block. + let (min_age, max_age) = match (min_age, max_age) { + (Some(min), Some(max)) => (*min, *max), + _ => return false, + }; + + let age = max_age.saturating_sub(min_age); + + aggression_config.should_trigger_aggression(age) && + topology.map(|topology| topology.is_validator(&peer)).unwrap_or(false) + } + async fn import_and_circulate_assignment( &mut self, approval_voting_sender: &mut A, @@ -1381,20 +1411,29 @@ impl State { if peer_knowledge.contains(&message_subject, message_kind) { // wasn't included before if !peer_knowledge.received.insert(message_subject.clone(), message_kind) { - gum::debug!( - target: LOG_TARGET, - ?peer_id, - ?message_subject, - "Duplicate assignment", - ); - - modify_reputation( - &mut self.reputation, - network_sender, + if !Self::accept_duplicates_from_validators( + &self.blocks_by_number, + &self.topologies, + &self.aggression_config, + entry, peer_id, - COST_DUPLICATE_MESSAGE, - ) - .await; + ) { + gum::debug!( + target: LOG_TARGET, + ?peer_id, + ?message_subject, + "Duplicate assignment", + ); + + modify_reputation( + &mut self.reputation, + network_sender, + peer_id, + COST_DUPLICATE_MESSAGE, + ) + .await; + } + metrics.on_assignment_duplicate(); } else { gum::trace!( @@ -1710,6 +1749,9 @@ impl State { assignments_knowledge_key: &Vec<(MessageSubject, MessageKind)>, approval_knowledge_key: &(MessageSubject, MessageKind), entry: &mut BlockEntry, + blocks_by_number: &BTreeMap>, + topologies: &SessionGridTopologies, + aggression_config: &AggressionConfig, reputation: &mut ReputationAggregator, peer_id: PeerId, metrics: &Metrics, @@ -1738,20 +1780,27 @@ impl State { .received .insert(approval_knowledge_key.0.clone(), approval_knowledge_key.1) { - gum::trace!( - target: LOG_TARGET, - ?peer_id, - ?approval_knowledge_key, - "Duplicate approval", - ); - - modify_reputation( - reputation, - network_sender, + if !Self::accept_duplicates_from_validators( + blocks_by_number, + topologies, + aggression_config, + entry, peer_id, - COST_DUPLICATE_MESSAGE, - ) - .await; + ) { + gum::trace!( + target: LOG_TARGET, + ?peer_id, + ?approval_knowledge_key, + "Duplicate approval", + ); + modify_reputation( + reputation, + network_sender, + peer_id, + COST_DUPLICATE_MESSAGE, + ) + .await; + } metrics.on_approval_duplicate(); } return false @@ -1843,6 +1892,9 @@ impl State { &assignments_knowledge_keys, &approval_knwowledge_key, entry, + &self.blocks_by_number, + &self.topologies, + &self.aggression_config, &mut self.reputation, peer_id, metrics, @@ -2253,18 +2305,43 @@ impl State { &self.topologies, |block_entry| { let block_age = max_age - block_entry.number; + // We want to resend only for blocks of min_age, there is no point in + // resending for blocks newer than that, because we are just going to create load + // and not gain anything. + let diff_from_min_age = block_entry.number - min_age; + + // We want to back-off on resending for blocks that have been resent recently, to + // give time for nodes to process all the extra messages, if we still have not + // finalized we are going to resend again after unfinalized_period * 2 since the + // last resend. + let blocks_since_last_sent = block_entry + .last_resent_at_block_number + .map(|last_resent_at_block_number| max_age - last_resent_at_block_number); + + let can_resend_at_this_age = blocks_since_last_sent + .zip(config.resend_unfinalized_period) + .map(|(blocks_since_last_sent, unfinalized_period)| { + blocks_since_last_sent >= unfinalized_period * 2 + }) + .unwrap_or(true); if resend == Resend::Yes && - config - .resend_unfinalized_period - .as_ref() - .map_or(false, |p| block_age > 0 && block_age % p == 0) - { + config.resend_unfinalized_period.as_ref().map_or(false, |p| { + block_age > 0 && + block_age % p == 0 && diff_from_min_age == 0 && + can_resend_at_this_age + }) { // Retry sending to all peers. for (_, knowledge) in block_entry.known_by.iter_mut() { knowledge.sent = Knowledge::default(); } - + block_entry.last_resent_at_block_number = Some(max_age); + gum::debug!( + target: LOG_TARGET, + block_number = ?block_entry.number, + ?max_age, + "Aggression enabled with resend for block", + ); true } else { false diff --git a/polkadot/node/network/approval-distribution/src/tests.rs b/polkadot/node/network/approval-distribution/src/tests.rs index 063e71f2f528..323b2cb08fec 100644 --- a/polkadot/node/network/approval-distribution/src/tests.rs +++ b/polkadot/node/network/approval-distribution/src/tests.rs @@ -1030,6 +1030,141 @@ fn peer_sending_us_the_same_we_just_sent_them_is_ok() { ); } +#[test] +fn peer_sending_us_duplicates_while_aggression_enabled_is_ok() { + let parent_hash = Hash::repeat_byte(0xFF); + let hash = Hash::repeat_byte(0xAA); + + let peers = make_peers_and_authority_ids(8); + let peer_a = peers.first().unwrap().0; + + let _ = test_harness( + Arc::new(MockAssignmentCriteria { tranche: Ok(0) }), + Arc::new(SystemClock {}), + state_without_reputation_delay(), + |mut virtual_overseer| async move { + let overseer = &mut virtual_overseer; + let peer = &peer_a; + setup_peer_with_view(overseer, peer, view![], ValidationVersion::V3).await; + + let peers_with_optional_peer_id = peers + .iter() + .map(|(peer_id, authority)| (Some(*peer_id), authority.clone())) + .collect_vec(); + // Setup a topology where peer_a is neighbor to current node. + setup_gossip_topology( + overseer, + make_gossip_topology(1, &peers_with_optional_peer_id, &[0], &[2], 1), + ) + .await; + + // new block `hash` with 1 candidates + let meta = BlockApprovalMeta { + hash, + parent_hash, + number: 1, + candidates: vec![Default::default(); 1], + slot: 1.into(), + session: 1, + vrf_story: RelayVRFStory(Default::default()), + }; + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + // import an assignment related to `hash` locally + let validator_index = ValidatorIndex(0); + let candidate_indices: CandidateBitfield = + vec![0 as CandidateIndex].try_into().unwrap(); + let candidate_bitfields = vec![CoreIndex(0)].try_into().unwrap(); + let cert = fake_assignment_cert_v2(hash, validator_index, candidate_bitfields); + overseer_send( + overseer, + ApprovalDistributionMessage::DistributeAssignment( + cert.clone().into(), + candidate_indices.clone(), + ), + ) + .await; + + // update peer view to include the hash + overseer_send( + overseer, + ApprovalDistributionMessage::NetworkBridgeUpdate( + NetworkBridgeEvent::PeerViewChange(*peer, view![hash]), + ), + ) + .await; + + // we should send them the assignment + assert_matches!( + overseer_recv(overseer).await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V3(protocol_v3::ValidationProtocol::ApprovalDistribution( + protocol_v3::ApprovalDistributionMessage::Assignments(assignments) + )) + )) => { + assert_eq!(peers.len(), 1); + assert_eq!(assignments.len(), 1); + } + ); + + // but if someone else is sending it the same assignment + // the peer could send us it as well + let assignments = vec![(cert, candidate_indices)]; + let msg = protocol_v3::ApprovalDistributionMessage::Assignments(assignments); + send_message_from_peer_v3(overseer, peer, msg.clone()).await; + + assert!( + overseer.recv().timeout(TIMEOUT).await.is_none(), + "we should not punish the peer" + ); + + // send the assignments again + send_message_from_peer_v3(overseer, peer, msg.clone()).await; + + // now we should + expect_reputation_change(overseer, peer, COST_DUPLICATE_MESSAGE).await; + + // Peers will be continously punished for sending duplicates until approval-distribution + // aggression kicks, at which point they aren't anymore. + let mut parent_hash = hash; + for level in 0..16 { + // As long as the lag is bellow l1 aggression, punish peers for duplicates. + send_message_from_peer_v3(overseer, peer, msg.clone()).await; + expect_reputation_change(overseer, peer, COST_DUPLICATE_MESSAGE).await; + + let number = 1 + level + 1; // first block had number 1 + let hash = BlakeTwo256::hash_of(&(parent_hash, number)); + let meta = BlockApprovalMeta { + hash, + parent_hash, + number, + candidates: vec![], + slot: (level as u64).into(), + session: 1, + vrf_story: RelayVRFStory(Default::default()), + }; + + let msg = ApprovalDistributionMessage::ApprovalCheckingLagUpdate(level + 1); + overseer_send(overseer, msg).await; + + let msg = ApprovalDistributionMessage::NewBlocks(vec![meta]); + overseer_send(overseer, msg).await; + + parent_hash = hash; + } + + // send the assignments again, we should not punish the peer because aggression is + // enabled. + send_message_from_peer_v3(overseer, peer, msg).await; + + assert!(overseer.recv().timeout(TIMEOUT).await.is_none(), "no message should be sent"); + virtual_overseer + }, + ); +} + #[test] fn import_approval_happy_path_v1_v2_peers() { let peers = make_peers_and_authority_ids(15); @@ -3892,7 +4027,7 @@ fn resends_messages_periodically() { // Add blocks until resend is done. { let mut parent_hash = hash; - for level in 0..2 { + for level in 0..4 { number = number + 1; let hash = BlakeTwo256::hash_of(&(parent_hash, number)); let meta = BlockApprovalMeta { diff --git a/prdoc/pr_6696.prdoc b/prdoc/pr_6696.prdoc new file mode 100644 index 000000000000..c5c73f831886 --- /dev/null +++ b/prdoc/pr_6696.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Make approval-distribution aggression a bit more robust and less spammy + +doc: + - audience: Node Dev + description: | + The problem with the current implementation of approval-distribution aggression is that is too spammy, + and can overload the nodes, so make it less spammy by moving back the moment we trigger L2 aggression + and make resend enable only for the latest unfinalized block. + +crates: + - name: polkadot-approval-distribution + bump: minor From da2dd9b7737cb7c0dc9dc3dc74b384c719ea3306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 11 Dec 2024 12:34:12 +0100 Subject: [PATCH 41/51] snowbridge: Update alloy-core (#6808) I am planning to use `alloy_core` to implement precompile support in `pallet_revive`. I noticed that it is already used by snowbridge. In order to unify the dependencies I did the following: 1. Switch to the `alloy-core` umbrella crate so that we have less individual dependencies to update. 2. Bump the latest version and fixup the resulting compile errors. --- Cargo.lock | 247 ++++++++++++++++-- Cargo.toml | 3 +- .../pallets/inbound-queue/Cargo.toml | 6 +- .../pallets/inbound-queue/src/envelope.rs | 7 +- 4 files changed, 227 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 989430fdfe29..9b023a38cb2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,48 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "alloy-core" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618bd382f0bc2ac26a7e4bfae01c9b015ca8f21b37ca40059ae35a7e62b3dc6" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-primitives 0.8.15", + "alloy-rlp", + "alloy-sol-types 0.8.15", +] + +[[package]] +name = "alloy-dyn-abi" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41056bde53ae10ffbbf11618efbe1e0290859e5eab0fe9ef82ebdb62f12a866f" +dependencies = [ + "alloy-json-abi", + "alloy-primitives 0.8.15", + "alloy-sol-type-parser", + "alloy-sol-types 0.8.15", + "const-hex", + "itoa", + "serde", + "serde_json", + "winnow 0.6.18", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c357da577dfb56998d01f574d81ad7a1958d248740a7981b205d69d65a7da404" +dependencies = [ + "alloy-primitives 0.8.15", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + [[package]] name = "alloy-primitives" version = "0.4.2" @@ -145,6 +187,34 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "alloy-primitives" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6259a506ab13e1d658796c31e6e39d2e2ee89243bcc505ddc613b35732e0a430" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 1.0.0", + "foldhash", + "hashbrown 0.15.2", + "hex-literal", + "indexmap 2.7.0", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand", + "ruint", + "rustc-hash 2.0.0", + "serde", + "sha3 0.10.8", + "tiny-keccak", +] + [[package]] name = "alloy-rlp" version = "0.3.3" @@ -169,18 +239,88 @@ dependencies = [ "proc-macro2 1.0.86", "quote 1.0.37", "syn 2.0.87", - "syn-solidity", + "syn-solidity 0.4.2", "tiny-keccak", ] +[[package]] +name = "alloy-sol-macro" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d64f851d95619233f74b310f12bcf16e0cbc27ee3762b6115c14a84809280a" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.87", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bf7ed1574b699f48bf17caab4e6e54c6d12bc3c006ab33d58b1e227c1c3559f" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck 0.5.0", + "indexmap 2.7.0", + "proc-macro-error2", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.87", + "syn-solidity 0.8.15", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c02997ccef5f34f9c099277d4145f183b422938ed5322dc57a089fe9b9ad9ee" +dependencies = [ + "const-hex", + "dunce", + "heck 0.5.0", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.87", + "syn-solidity 0.8.15", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce13ff37285b0870d0a0746992a4ae48efaf34b766ae4c2640fa15e5305f8e73" +dependencies = [ + "serde", + "winnow 0.6.18", +] + [[package]] name = "alloy-sol-types" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98d7107bed88e8f09f0ddcc3335622d87bfb6821f3e0c7473329fb1cfad5e015" dependencies = [ - "alloy-primitives", - "alloy-sol-macro", + "alloy-primitives 0.4.2", + "alloy-sol-macro 0.4.2", + "const-hex", + "serde", +] + +[[package]] +name = "alloy-sol-types" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1174cafd6c6d810711b4e00383037bdb458efc4fe3dbafafa16567e0320c54d8" +dependencies = [ + "alloy-json-abi", + "alloy-primitives 0.8.15", + "alloy-sol-macro 0.8.15", "const-hex", "serde", ] @@ -3001,6 +3141,9 @@ name = "bytes" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +dependencies = [ + "serde", +] [[package]] name = "bzip2-sys" @@ -3759,9 +3902,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.10.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -6688,7 +6831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb42427514b063d97ce21d5199f36c0c307d981434a6be32582bc79fe5bd2303" dependencies = [ "expander", - "indexmap 2.2.3", + "indexmap 2.7.0", "proc-macro-crate 3.1.0", "proc-macro2 1.0.86", "quote 1.0.37", @@ -6879,6 +7022,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -8137,7 +8286,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.9", - "indexmap 2.2.3", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -8156,7 +8305,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.2.3", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -8227,6 +8376,16 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", + "serde", +] + [[package]] name = "hashlink" version = "0.8.4" @@ -8277,6 +8436,9 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "hex-conservative" @@ -8854,12 +9016,13 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", + "serde", ] [[package]] @@ -9359,6 +9522,16 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "keccak-hash" version = "0.11.0" @@ -10245,7 +10418,7 @@ dependencies = [ "futures-timer", "hex-literal", "hickory-resolver", - "indexmap 2.2.3", + "indexmap 2.7.0", "libc", "mockall 0.13.0", "multiaddr 0.17.1", @@ -11594,7 +11767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7b1d40dd8f367db3c65bec8d3dd47d4a604ee8874480738f93191bddab4e0e0" dependencies = [ "expander", - "indexmap 2.2.3", + "indexmap 2.7.0", "itertools 0.11.0", "petgraph", "proc-macro-crate 3.1.0", @@ -16797,7 +16970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.2.3", + "indexmap 2.7.0", ] [[package]] @@ -17126,7 +17299,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 2.2.3", + "indexmap 2.7.0", "parity-scale-codec", "polkadot-erasure-coding", "polkadot-node-network-protocol", @@ -19373,7 +19546,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 2.2.3", + "indexmap 2.7.0", "parity-scale-codec", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -20742,6 +20915,7 @@ dependencies = [ "libc", "rand_chacha", "rand_core 0.6.4", + "serde", ] [[package]] @@ -23581,7 +23755,7 @@ dependencies = [ "criterion", "futures", "futures-timer", - "indexmap 2.2.3", + "indexmap 2.7.0", "itertools 0.11.0", "linked-hash-map", "log", @@ -24155,7 +24329,7 @@ version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.7.0", "itoa", "memchr", "ryu", @@ -24189,7 +24363,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.7.0", "itoa", "ryu", "serde", @@ -24276,6 +24450,16 @@ dependencies = [ "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -24968,8 +25152,7 @@ dependencies = [ name = "snowbridge-pallet-inbound-queue" version = "0.2.0" dependencies = [ - "alloy-primitives", - "alloy-sol-types", + "alloy-core", "frame-benchmarking 28.0.0", "frame-support 28.0.0", "frame-system 28.0.0", @@ -24999,8 +25182,8 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2e6a9d00e60e3744e6b6f0c21fea6694b9c6401ac40e41340a96e561dcf1935" dependencies = [ - "alloy-primitives", - "alloy-sol-types", + "alloy-primitives 0.4.2", + "alloy-sol-types 0.4.2", "frame-benchmarking 38.0.0", "frame-support 38.0.0", "frame-system 38.0.0", @@ -29015,6 +29198,18 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "syn-solidity" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219389c1ebe89f8333df8bdfb871f6631c552ff399c23cac02480b6088aad8f0" +dependencies = [ + "paste", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.87", +] + [[package]] name = "sync_wrapper" version = "1.0.1" @@ -29672,7 +29867,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -29685,7 +29880,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.7.0", "toml_datetime", "winnow 0.5.15", ] @@ -29696,7 +29891,7 @@ version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ - "indexmap 2.2.3", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", diff --git a/Cargo.toml b/Cargo.toml index 383fc46c4e76..e76af28ecc31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -594,8 +594,7 @@ zero-prefixed-literal = { level = "allow", priority = 2 } # 00_1000_0 Inflector = { version = "0.11.4" } aes-gcm = { version = "0.10" } ahash = { version = "0.8.2" } -alloy-primitives = { version = "0.4.2", default-features = false } -alloy-sol-types = { version = "0.4.2", default-features = false } +alloy-core = { version = "0.8.15", default-features = false } always-assert = { version = "0.1" } anyhow = { version = "1.0.81", default-features = false } approx = { version = "0.5.1" } diff --git a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml index 1b08bb39b434..3ab633bfcd79 100644 --- a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml @@ -20,8 +20,7 @@ codec = { features = ["derive"], workspace = true } scale-info = { features = ["derive"], workspace = true } hex-literal = { optional = true, workspace = true, default-features = true } log = { workspace = true } -alloy-primitives = { features = ["rlp"], workspace = true } -alloy-sol-types = { workspace = true } +alloy-core = { workspace = true, features = ["sol-types"] } frame-benchmarking = { optional = true, workspace = true } frame-support = { workspace = true } @@ -49,8 +48,7 @@ hex-literal = { workspace = true, default-features = true } [features] default = ["std"] std = [ - "alloy-primitives/std", - "alloy-sol-types/std", + "alloy-core/std", "codec/std", "frame-benchmarking/std", "frame-support/std", diff --git a/bridges/snowbridge/pallets/inbound-queue/src/envelope.rs b/bridges/snowbridge/pallets/inbound-queue/src/envelope.rs index 31a8992442d8..d213c8aad648 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/envelope.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/envelope.rs @@ -5,8 +5,7 @@ use snowbridge_core::{inbound::Log, ChannelId}; use sp_core::{RuntimeDebug, H160, H256}; use sp_std::prelude::*; -use alloy_primitives::B256; -use alloy_sol_types::{sol, SolEvent}; +use alloy_core::{primitives::B256, sol, sol_types::SolEvent}; sol! { event OutboundMessageAccepted(bytes32 indexed channel_id, uint64 nonce, bytes32 indexed message_id, bytes payload); @@ -36,7 +35,7 @@ impl TryFrom<&Log> for Envelope { fn try_from(log: &Log) -> Result { let topics: Vec = log.topics.iter().map(|x| B256::from_slice(x.as_ref())).collect(); - let event = OutboundMessageAccepted::decode_log(topics, &log.data, true) + let event = OutboundMessageAccepted::decode_raw_log(topics, &log.data, true) .map_err(|_| EnvelopeDecodeError)?; Ok(Self { @@ -44,7 +43,7 @@ impl TryFrom<&Log> for Envelope { channel_id: ChannelId::from(event.channel_id.as_ref()), nonce: event.nonce, message_id: H256::from(event.message_id.as_ref()), - payload: event.payload, + payload: event.payload.into(), }) } } From 48c6574b1a32893e6a2113622d009cefda0a5f21 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Wed, 11 Dec 2024 11:39:41 -0300 Subject: [PATCH 42/51] Add aliasers to westend chains (#6814) `InitiateTransfer`, the new instruction introduced in XCMv5, allows preserving the origin after a cross-chain transfer via the usage of the `AliasOrigin` instruction. The receiving chain needs to be configured to allow such this instruction to have its intended effect and not just throw an error. In this PR, I add the alias rules specified in the [RFC for origin preservation](https://github.com/polkadot-fellows/RFCs/blob/main/text/0122-alias-origin-on-asset-transfers.md) to westend chains so we can test these scenarios in the testnet. The new scenarios include: - Sending a cross-chain transfer from one system chain to another and doing a Transact on the same message (1 hop) - Sending a reserve asset transfer from one chain to another going through asset hub and doing Transact on the same message (2 hops) The updated chains are: - Relay: added `AliasChildLocation` - Collectives: added `AliasChildLocation` and `AliasOriginRootUsingFilter` - People: added `AliasChildLocation` and `AliasOriginRootUsingFilter` - Coretime: added `AliasChildLocation` and `AliasOriginRootUsingFilter` AssetHub already has `AliasChildLocation` and doesn't need the other config item. BridgeHub is not intended to be used by end users so I didn't add any config item. Only added `AliasChildOrigin` to the relay since we intend for it to be used less. --------- Co-authored-by: GitHub Action Co-authored-by: command-bot <> --- .../collectives-westend/src/xcm_config.rs | 9 +- .../coretime/coretime-westend/src/lib.rs | 4 +- .../coretime-westend/src/weights/xcm/mod.rs | 3 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 169 ++++++++-------- .../coretime-westend/src/xcm_config.rs | 10 +- .../runtimes/people/people-westend/src/lib.rs | 4 +- .../people-westend/src/weights/xcm/mod.rs | 3 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 185 ++++++++++-------- .../people/people-westend/src/xcm_config.rs | 10 +- polkadot/runtime/westend/src/lib.rs | 5 +- .../runtime/westend/src/weights/xcm/mod.rs | 3 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 153 ++++++++------- polkadot/runtime/westend/src/xcm_config.rs | 22 ++- .../src/generic/benchmarking.rs | 2 +- prdoc/pr_6814.prdoc | 32 +++ 15 files changed, 353 insertions(+), 261 deletions(-) create mode 100644 prdoc/pr_6814.prdoc diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs index 56ef2e8ba02f..9eb9b85a3918 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs @@ -35,7 +35,8 @@ use polkadot_runtime_common::xcm_sender::ExponentialPrice; use westend_runtime_constants::xcm as xcm_constants; use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH}; use xcm_builder::{ - AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, + AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter, + AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin, FixedWeightBounds, FrameTransactionalProcessor, FungibleAdapter, @@ -191,6 +192,10 @@ pub type WaivedLocations = ( /// - DOT with the parent Relay Chain and sibling parachains. pub type TrustedTeleporters = ConcreteAssetFromSystem; +/// We allow locations to alias into their own child locations, as well as +/// AssetHub to alias into anything. +pub type Aliasers = (AliasChildLocation, AliasOriginRootUsingFilter); + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -227,7 +232,7 @@ impl xcm_executor::Config for XcmConfig { type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; + type Aliasers = Aliasers; type TransactionalProcessor = FrameTransactionalProcessor; type HrmpNewChannelOpenRequestHandler = (); type HrmpChannelAcceptedHandler = (); diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 39ea39f25a8b..67f7ad7afc6b 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -1126,7 +1126,9 @@ impl_runtime_apis! { } fn alias_origin() -> Result<(Location, Location), BenchmarkError> { - Err(BenchmarkError::Skip) + let origin = Location::new(1, [Parachain(1000)]); + let target = Location::new(1, [Parachain(1000), AccountId32 { id: [128u8; 32], network: None }]); + Ok((origin, target)) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs index 29466b3718c1..2f7529481543 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs @@ -261,8 +261,7 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { XcmGeneric::::clear_topic() } fn alias_origin(_: &Location) -> Weight { - // XCM Executor does not currently support alias origin operations - Weight::MAX + XcmGeneric::::alias_origin() } fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 6c6d3cf8c525..2d10ac16ea26 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-svzsllib-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `9340d096ec0f`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("coretime-westend-dev"), DB CACHE: 1024 // Executed Command: // target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 // --extrinsic=* +// --chain=coretime-westend-dev +// --pallet=pallet_xcm_benchmarks::generic +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm // --wasm-execution=compiled +// --steps=50 +// --repeat=20 // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_xcm_benchmarks::generic -// --chain=coretime-westend-dev -// --header=./cumulus/file_header.txt -// --template=./cumulus/templates/xcm-bench-template.hbs -// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/ +// --template=cumulus/templates/xcm-bench-template.hbs +// --no-storage-info +// --no-min-squares +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -64,8 +66,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 29_463_000 picoseconds. - Weight::from_parts(30_178_000, 3571) + // Minimum execution time: 30_717_000 picoseconds. + Weight::from_parts(31_651_000, 3571) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -73,15 +75,26 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 568_000 picoseconds. - Weight::from_parts(608_000, 0) + // Minimum execution time: 618_000 picoseconds. + Weight::from_parts(659_000, 0) } + // Storage: `System::Account` (r:1 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) pub fn pay_fees() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 3_504_000 picoseconds. + Weight::from_parts(3_757_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_530_000 picoseconds. - Weight::from_parts(1_585_000, 0) + // Minimum execution time: 643_000 picoseconds. + Weight::from_parts(702_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -89,58 +102,65 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 7_400_000 picoseconds. - Weight::from_parts(7_572_000, 3497) + // Minimum execution time: 7_799_000 picoseconds. + Weight::from_parts(8_037_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_951_000 picoseconds. - Weight::from_parts(7_173_000, 0) + // Minimum execution time: 6_910_000 picoseconds. + Weight::from_parts(7_086_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_245_000 picoseconds. - Weight::from_parts(1_342_000, 0) + // Minimum execution time: 1_257_000 picoseconds. + Weight::from_parts(1_384_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 613_000 picoseconds. - Weight::from_parts(657_000, 0) + // Minimum execution time: 634_000 picoseconds. + Weight::from_parts(687_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 613_000 picoseconds. - Weight::from_parts(656_000, 0) + // Minimum execution time: 604_000 picoseconds. + Weight::from_parts(672_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 570_000 picoseconds. - Weight::from_parts(608_000, 0) + // Minimum execution time: 593_000 picoseconds. + Weight::from_parts(643_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 557_000 picoseconds. - Weight::from_parts(607_000, 0) + // Minimum execution time: 630_000 picoseconds. + Weight::from_parts(694_000, 0) + } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 706_000 picoseconds. + Weight::from_parts(764_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 557_000 picoseconds. - Weight::from_parts(578_000, 0) + // Minimum execution time: 606_000 picoseconds. + Weight::from_parts(705_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -158,8 +178,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 26_179_000 picoseconds. - Weight::from_parts(27_089_000, 3571) + // Minimum execution time: 27_188_000 picoseconds. + Weight::from_parts(27_847_000, 3571) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -169,8 +189,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 10_724_000 picoseconds. - Weight::from_parts(10_896_000, 3555) + // Minimum execution time: 11_170_000 picoseconds. + Weight::from_parts(11_416_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -178,8 +198,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 567_000 picoseconds. - Weight::from_parts(623_000, 0) + // Minimum execution time: 590_000 picoseconds. + Weight::from_parts(653_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -197,8 +217,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 24_367_000 picoseconds. - Weight::from_parts(25_072_000, 3539) + // Minimum execution time: 25_196_000 picoseconds. + Weight::from_parts(25_641_000, 3539) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -208,44 +228,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_554_000 picoseconds. - Weight::from_parts(2_757_000, 0) + // Minimum execution time: 2_686_000 picoseconds. + Weight::from_parts(2_827_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 922_000 picoseconds. - Weight::from_parts(992_000, 0) + // Minimum execution time: 989_000 picoseconds. + Weight::from_parts(1_051_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 688_000 picoseconds. - Weight::from_parts(723_000, 0) + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(766_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 607_000 picoseconds. - Weight::from_parts(647_000, 0) + // Minimum execution time: 626_000 picoseconds. + Weight::from_parts(657_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 591_000 picoseconds. - Weight::from_parts(620_000, 0) + // Minimum execution time: 595_000 picoseconds. + Weight::from_parts(639_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 735_000 picoseconds. - Weight::from_parts(802_000, 0) + // Minimum execution time: 755_000 picoseconds. + Weight::from_parts(820_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -263,8 +283,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 29_923_000 picoseconds. - Weight::from_parts(30_770_000, 3571) + // Minimum execution time: 31_409_000 picoseconds. + Weight::from_parts(32_098_000, 3571) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -272,8 +292,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_884_000 picoseconds. - Weight::from_parts(3_088_000, 0) + // Minimum execution time: 3_258_000 picoseconds. + Weight::from_parts(3_448_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -291,8 +311,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 26_632_000 picoseconds. - Weight::from_parts(27_228_000, 3571) + // Minimum execution time: 27_200_000 picoseconds. + Weight::from_parts(28_299_000, 3571) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -300,49 +320,42 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 599_000 picoseconds. - Weight::from_parts(655_000, 0) + // Minimum execution time: 659_000 picoseconds. + Weight::from_parts(699_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 587_000 picoseconds. - Weight::from_parts(628_000, 0) + // Minimum execution time: 595_000 picoseconds. + Weight::from_parts(647_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 572_000 picoseconds. - Weight::from_parts(631_000, 0) + // Minimum execution time: 583_000 picoseconds. + Weight::from_parts(617_000, 0) } pub fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 570_000 picoseconds. - Weight::from_parts(615_000, 0) + // Minimum execution time: 595_000 picoseconds. + Weight::from_parts(633_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 624_000 picoseconds. - Weight::from_parts(659_000, 0) - } - pub fn asset_claimer() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 707_000 picoseconds. - Weight::from_parts(749_000, 0) + // Minimum execution time: 610_000 picoseconds. + Weight::from_parts(670_000, 0) } - pub fn execute_with_origin() -> Weight { + pub fn alias_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 713_000 picoseconds. - Weight::from_parts(776_000, 0) + // Minimum execution time: 630_000 picoseconds. + Weight::from_parts(700_000, 0) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs index 9f38975efae6..8a4879a1506e 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs @@ -39,7 +39,8 @@ use polkadot_runtime_common::xcm_sender::ExponentialPrice; use sp_runtime::traits::AccountIdConversion; use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH}; use xcm_builder::{ - AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, + AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter, + AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter, HashedDescription, IsConcrete, @@ -54,6 +55,7 @@ use xcm_executor::XcmExecutor; parameter_types! { pub const RootLocation: Location = Location::here(); pub const TokenRelayLocation: Location = Location::parent(); + pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]); pub const RelayNetwork: Option = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH)); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub UniversalLocation: InteriorLocation = @@ -191,6 +193,10 @@ pub type WaivedLocations = ( Equals, ); +/// We allow locations to alias into their own child locations, as well as +/// AssetHub to alias into anything. +pub type Aliasers = (AliasChildLocation, AliasOriginRootUsingFilter); + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -232,7 +238,7 @@ impl xcm_executor::Config for XcmConfig { type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; + type Aliasers = Aliasers; type TransactionalProcessor = FrameTransactionalProcessor; type HrmpNewChannelOpenRequestHandler = (); type HrmpChannelAcceptedHandler = (); diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 1b9a3b60a2c4..3265062a0441 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -1046,7 +1046,9 @@ impl_runtime_apis! { } fn alias_origin() -> Result<(Location, Location), BenchmarkError> { - Err(BenchmarkError::Skip) + let origin = Location::new(1, [Parachain(1000)]); + let target = Location::new(1, [Parachain(1000), AccountId32 { id: [128u8; 32], network: None }]); + Ok((origin, target)) } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs index 915a499cb77c..466da1eadd55 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs @@ -249,8 +249,7 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { XcmGeneric::::clear_topic() } fn alias_origin(_: &Location) -> Weight { - // XCM Executor does not currently support alias origin operations - Weight::MAX + XcmGeneric::::alias_origin() } fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index ad2cde22a075..3fa51a816b69 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-svzsllib-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `9340d096ec0f`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("people-westend-dev"), DB CACHE: 1024 // Executed Command: // target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 // --extrinsic=* +// --chain=people-westend-dev +// --pallet=pallet_xcm_benchmarks::generic +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/xcm // --wasm-execution=compiled +// --steps=50 +// --repeat=20 // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_xcm_benchmarks::generic -// --chain=people-westend-dev -// --header=./cumulus/file_header.txt -// --template=./cumulus/templates/xcm-bench-template.hbs -// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/ +// --template=cumulus/templates/xcm-bench-template.hbs +// --no-storage-info +// --no-min-squares +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -62,10 +64,10 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_holding() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 29_015_000 picoseconds. - Weight::from_parts(30_359_000, 3535) + // Measured: `107` + // Estimated: `3572` + // Minimum execution time: 31_309_000 picoseconds. + Weight::from_parts(31_924_000, 3572) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -73,15 +75,26 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 572_000 picoseconds. - Weight::from_parts(637_000, 0) + // Minimum execution time: 635_000 picoseconds. + Weight::from_parts(677_000, 0) } + // Storage: `System::Account` (r:1 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) pub fn pay_fees() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 3_457_000 picoseconds. + Weight::from_parts(3_656_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_550_000 picoseconds. - Weight::from_parts(1_604_000, 0) + // Minimum execution time: 644_000 picoseconds. + Weight::from_parts(695_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -89,58 +102,65 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 7_354_000 picoseconds. - Weight::from_parts(7_808_000, 3497) + // Minimum execution time: 7_701_000 picoseconds. + Weight::from_parts(8_120_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_716_000 picoseconds. - Weight::from_parts(7_067_000, 0) + // Minimum execution time: 6_945_000 picoseconds. + Weight::from_parts(7_187_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_280_000 picoseconds. - Weight::from_parts(1_355_000, 0) + // Minimum execution time: 1_352_000 picoseconds. + Weight::from_parts(1_428_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 587_000 picoseconds. - Weight::from_parts(645_000, 0) + // Minimum execution time: 603_000 picoseconds. + Weight::from_parts(648_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 629_000 picoseconds. - Weight::from_parts(662_000, 0) + // Minimum execution time: 621_000 picoseconds. + Weight::from_parts(661_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 590_000 picoseconds. - Weight::from_parts(639_000, 0) + // Minimum execution time: 591_000 picoseconds. + Weight::from_parts(655_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 651_000 picoseconds. - Weight::from_parts(688_000, 0) + // Minimum execution time: 666_000 picoseconds. + Weight::from_parts(736_000, 0) + } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 694_000 picoseconds. + Weight::from_parts(759_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 601_000 picoseconds. - Weight::from_parts(630_000, 0) + // Minimum execution time: 632_000 picoseconds. + Weight::from_parts(664_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -156,10 +176,10 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_error() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 25_650_000 picoseconds. - Weight::from_parts(26_440_000, 3535) + // Measured: `107` + // Estimated: `3572` + // Minimum execution time: 26_932_000 picoseconds. + Weight::from_parts(27_882_000, 3572) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -169,8 +189,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 10_492_000 picoseconds. - Weight::from_parts(10_875_000, 3555) + // Minimum execution time: 11_316_000 picoseconds. + Weight::from_parts(11_608_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -178,8 +198,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 597_000 picoseconds. - Weight::from_parts(647_000, 0) + // Minimum execution time: 564_000 picoseconds. + Weight::from_parts(614_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -197,8 +217,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 23_732_000 picoseconds. - Weight::from_parts(24_290_000, 3503) + // Minimum execution time: 24_373_000 picoseconds. + Weight::from_parts(25_068_000, 3503) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -208,44 +228,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_446_000 picoseconds. - Weight::from_parts(2_613_000, 0) + // Minimum execution time: 2_582_000 picoseconds. + Weight::from_parts(2_714_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 960_000 picoseconds. - Weight::from_parts(1_045_000, 0) + // Minimum execution time: 952_000 picoseconds. + Weight::from_parts(1_059_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 703_000 picoseconds. - Weight::from_parts(739_000, 0) + // Minimum execution time: 684_000 picoseconds. + Weight::from_parts(734_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 616_000 picoseconds. - Weight::from_parts(651_000, 0) + // Minimum execution time: 600_000 picoseconds. + Weight::from_parts(650_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 621_000 picoseconds. - Weight::from_parts(660_000, 0) + // Minimum execution time: 599_000 picoseconds. + Weight::from_parts(628_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 794_000 picoseconds. - Weight::from_parts(831_000, 0) + // Minimum execution time: 769_000 picoseconds. + Weight::from_parts(816_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -261,10 +281,10 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn query_pallet() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 29_527_000 picoseconds. - Weight::from_parts(30_614_000, 3535) + // Measured: `107` + // Estimated: `3572` + // Minimum execution time: 31_815_000 picoseconds. + Weight::from_parts(32_738_000, 3572) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -272,8 +292,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_189_000 picoseconds. - Weight::from_parts(3_296_000, 0) + // Minimum execution time: 3_462_000 picoseconds. + Weight::from_parts(3_563_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -289,10 +309,10 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_transact_status() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 25_965_000 picoseconds. - Weight::from_parts(26_468_000, 3535) + // Measured: `107` + // Estimated: `3572` + // Minimum execution time: 27_752_000 picoseconds. + Weight::from_parts(28_455_000, 3572) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -300,49 +320,42 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 618_000 picoseconds. - Weight::from_parts(659_000, 0) + // Minimum execution time: 605_000 picoseconds. + Weight::from_parts(687_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 593_000 picoseconds. - Weight::from_parts(618_000, 0) + // Minimum execution time: 610_000 picoseconds. + Weight::from_parts(646_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 603_000 picoseconds. - Weight::from_parts(634_000, 0) + // Minimum execution time: 579_000 picoseconds. + Weight::from_parts(636_000, 0) } pub fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 568_000 picoseconds. - Weight::from_parts(629_000, 0) + // Minimum execution time: 583_000 picoseconds. + Weight::from_parts(626_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 598_000 picoseconds. - Weight::from_parts(655_000, 0) - } - pub fn asset_claimer() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 707_000 picoseconds. - Weight::from_parts(749_000, 0) + // Minimum execution time: 616_000 picoseconds. + Weight::from_parts(679_000, 0) } - pub fn execute_with_origin() -> Weight { + pub fn alias_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 713_000 picoseconds. - Weight::from_parts(776_000, 0) + // Minimum execution time: 626_000 picoseconds. + Weight::from_parts(687_000, 0) } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 25256495ef91..7eaa43c05b20 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -36,7 +36,8 @@ use polkadot_parachain_primitives::primitives::Sibling; use sp_runtime::traits::AccountIdConversion; use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH}; use xcm_builder::{ - AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, + AccountId32Aliases, AliasChildLocation, AliasOriginRootUsingFilter, + AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, DescribeTerminus, EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter, @@ -51,6 +52,7 @@ use xcm_executor::XcmExecutor; parameter_types! { pub const RootLocation: Location = Location::here(); pub const RelayLocation: Location = Location::parent(); + pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]); pub const RelayNetwork: Option = Some(NetworkId::ByGenesis(WESTEND_GENESIS_HASH)); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub UniversalLocation: InteriorLocation = @@ -195,6 +197,10 @@ pub type WaivedLocations = ( LocalPlurality, ); +/// We allow locations to alias into their own child locations, as well as +/// AssetHub to alias into anything. +pub type Aliasers = (AliasChildLocation, AliasOriginRootUsingFilter); + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -236,7 +242,7 @@ impl xcm_executor::Config for XcmConfig { type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; + type Aliasers = Aliasers; type TransactionalProcessor = FrameTransactionalProcessor; type HrmpNewChannelOpenRequestHandler = (); type HrmpChannelAcceptedHandler = (); diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index f25ed33012a2..c540b3773286 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2801,8 +2801,9 @@ sp_api::impl_runtime_apis! { } fn alias_origin() -> Result<(Location, Location), BenchmarkError> { - // The XCM executor of Westend doesn't have a configured `Aliasers` - Err(BenchmarkError::Skip) + let origin = Location::new(0, [Parachain(1000)]); + let target = Location::new(0, [Parachain(1000), AccountId32 { id: [128u8; 32], network: None }]); + Ok((origin, target)) } } diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs index d2691c998d99..a5fb82a66837 100644 --- a/polkadot/runtime/westend/src/weights/xcm/mod.rs +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -299,8 +299,7 @@ impl XcmWeightInfo for WestendXcmWeight { XcmGeneric::::clear_topic() } fn alias_origin(_: &Location) -> Weight { - // XCM Executor does not currently support alias origin operations - Weight::MAX + XcmGeneric::::alias_origin() } fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() diff --git a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index dfc02fd20bc3..4e10e72356ab 100644 --- a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `aa8403b52523`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 // Executed Command: // target/production/polkadot // benchmark // pallet -// --steps=50 -// --repeat=20 // --extrinsic=* +// --chain=westend-dev +// --pallet=pallet_xcm_benchmarks::generic +// --header=/__w/polkadot-sdk/polkadot-sdk/polkadot/file_header.txt +// --output=./polkadot/runtime/westend/src/weights/xcm // --wasm-execution=compiled +// --steps=50 +// --repeat=20 // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_xcm_benchmarks::generic -// --chain=westend-dev -// --header=./polkadot/file_header.txt -// --template=./polkadot/xcm/pallet-xcm-benchmarks/template.hbs -// --output=./polkadot/runtime/westend/src/weights/xcm/ +// --template=polkadot/xcm/pallet-xcm-benchmarks/template.hbs +// --no-storage-info +// --no-min-squares +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -63,8 +65,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 69_051_000 picoseconds. - Weight::from_parts(71_282_000, 6196) + // Minimum execution time: 74_868_000 picoseconds. + Weight::from_parts(77_531_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -72,22 +74,22 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 660_000 picoseconds. - Weight::from_parts(695_000, 0) + // Minimum execution time: 688_000 picoseconds. + Weight::from_parts(733_000, 0) } pub(crate) fn pay_fees() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_096_000 picoseconds. - Weight::from_parts(3_313_000, 0) + // Minimum execution time: 3_491_000 picoseconds. + Weight::from_parts(3_667_000, 0) } pub(crate) fn asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 661_000 picoseconds. - Weight::from_parts(707_000, 0) + // Minimum execution time: 757_000 picoseconds. + Weight::from_parts(804_000, 0) } /// Storage: `XcmPallet::Queries` (r:1 w:0) /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -95,65 +97,65 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3465` - // Minimum execution time: 6_054_000 picoseconds. - Weight::from_parts(6_151_000, 3465) + // Minimum execution time: 6_322_000 picoseconds. + Weight::from_parts(6_565_000, 3465) .saturating_add(T::DbWeight::get().reads(1)) } pub(crate) fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_462_000 picoseconds. - Weight::from_parts(7_750_000, 0) + // Minimum execution time: 7_841_000 picoseconds. + Weight::from_parts(8_240_000, 0) } pub(crate) fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_378_000 picoseconds. - Weight::from_parts(1_454_000, 0) + // Minimum execution time: 1_327_000 picoseconds. + Weight::from_parts(1_460_000, 0) } pub(crate) fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 660_000 picoseconds. - Weight::from_parts(744_000, 0) + // Minimum execution time: 680_000 picoseconds. + Weight::from_parts(752_000, 0) } pub(crate) fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 713_000 picoseconds. - Weight::from_parts(755_000, 0) + // Minimum execution time: 712_000 picoseconds. + Weight::from_parts(764_000, 0) } pub(crate) fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 632_000 picoseconds. - Weight::from_parts(703_000, 0) + // Minimum execution time: 663_000 picoseconds. + Weight::from_parts(712_000, 0) } pub(crate) fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 712_000 picoseconds. - Weight::from_parts(771_000, 0) + // Minimum execution time: 756_000 picoseconds. + Weight::from_parts(801_000, 0) } pub(crate) fn execute_with_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 740_000 picoseconds. - Weight::from_parts(826_000, 0) + // Minimum execution time: 773_000 picoseconds. + Weight::from_parts(822_000, 0) } pub(crate) fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 653_000 picoseconds. - Weight::from_parts(707_000, 0) + // Minimum execution time: 669_000 picoseconds. + Weight::from_parts(750_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -169,8 +171,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 66_765_000 picoseconds. - Weight::from_parts(69_016_000, 6196) + // Minimum execution time: 73_173_000 picoseconds. + Weight::from_parts(75_569_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -180,8 +182,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `23` // Estimated: `3488` - // Minimum execution time: 9_545_000 picoseconds. - Weight::from_parts(9_853_000, 3488) + // Minimum execution time: 9_851_000 picoseconds. + Weight::from_parts(10_087_000, 3488) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -189,8 +191,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 676_000 picoseconds. - Weight::from_parts(723_000, 0) + // Minimum execution time: 673_000 picoseconds. + Weight::from_parts(744_000, 0) } /// Storage: `XcmPallet::VersionNotifyTargets` (r:1 w:1) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -206,8 +208,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `147` // Estimated: `3612` - // Minimum execution time: 31_324_000 picoseconds. - Weight::from_parts(32_023_000, 3612) + // Minimum execution time: 35_714_000 picoseconds. + Weight::from_parts(36_987_000, 3612) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -217,44 +219,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_058_000 picoseconds. - Weight::from_parts(3_199_000, 0) + // Minimum execution time: 3_128_000 picoseconds. + Weight::from_parts(3_364_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub(crate) fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 994_000 picoseconds. - Weight::from_parts(1_115_000, 0) + // Minimum execution time: 1_070_000 picoseconds. + Weight::from_parts(1_188_000, 0) } pub(crate) fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 763_000 picoseconds. - Weight::from_parts(824_000, 0) + // Minimum execution time: 764_000 picoseconds. + Weight::from_parts(863_000, 0) } pub(crate) fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 665_000 picoseconds. - Weight::from_parts(712_000, 0) + // Minimum execution time: 675_000 picoseconds. + Weight::from_parts(755_000, 0) } pub(crate) fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 627_000 picoseconds. - Weight::from_parts(695_000, 0) + // Minimum execution time: 666_000 picoseconds. + Weight::from_parts(745_000, 0) } pub(crate) fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 839_000 picoseconds. - Weight::from_parts(889_000, 0) + // Minimum execution time: 838_000 picoseconds. + Weight::from_parts(918_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -270,8 +272,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 75_853_000 picoseconds. - Weight::from_parts(77_515_000, 6196) + // Minimum execution time: 82_721_000 picoseconds. + Weight::from_parts(85_411_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -279,8 +281,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_183_000 picoseconds. - Weight::from_parts(8_378_000, 0) + // Minimum execution time: 8_138_000 picoseconds. + Weight::from_parts(8_344_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -296,8 +298,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 66_576_000 picoseconds. - Weight::from_parts(69_465_000, 6196) + // Minimum execution time: 73_617_000 picoseconds. + Weight::from_parts(76_999_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -305,35 +307,42 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 739_000 picoseconds. - Weight::from_parts(773_000, 0) + // Minimum execution time: 714_000 picoseconds. + Weight::from_parts(806_000, 0) } pub(crate) fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 648_000 picoseconds. - Weight::from_parts(693_000, 0) + // Minimum execution time: 676_000 picoseconds. + Weight::from_parts(720_000, 0) } pub(crate) fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 654_000 picoseconds. - Weight::from_parts(700_000, 0) + // Minimum execution time: 666_000 picoseconds. + Weight::from_parts(731_000, 0) } pub(crate) fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 646_000 picoseconds. - Weight::from_parts(702_000, 0) + // Minimum execution time: 662_000 picoseconds. + Weight::from_parts(696_000, 0) } pub(crate) fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 665_000 picoseconds. - Weight::from_parts(714_000, 0) + // Minimum execution time: 693_000 picoseconds. + Weight::from_parts(760_000, 0) + } + pub(crate) fn alias_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 705_000 picoseconds. + Weight::from_parts(746_000, 0) } } diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs index f8bb2676de3f..3f6a7304c8a9 100644 --- a/polkadot/runtime/westend/src/xcm_config.rs +++ b/polkadot/runtime/westend/src/xcm_config.rs @@ -38,13 +38,14 @@ use westend_runtime_constants::{ }; use xcm::latest::{prelude::*, WESTEND_GENESIS_HASH}; use xcm_builder::{ - AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, - AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, - ChildParachainConvertsVia, DescribeAllTerminal, DescribeFamily, FrameTransactionalProcessor, - FungibleAdapter, HashedDescription, IsChildSystemParachain, IsConcrete, MintLocation, - OriginToPluralityVoice, SendXcmFeeToAccount, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, - WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents, + AccountId32Aliases, AliasChildLocation, AllowExplicitUnpaidExecutionFrom, + AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, + ChildParachainAsNative, ChildParachainConvertsVia, DescribeAllTerminal, DescribeFamily, + FrameTransactionalProcessor, FungibleAdapter, HashedDescription, IsChildSystemParachain, + IsConcrete, MintLocation, OriginToPluralityVoice, SendXcmFeeToAccount, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, + XcmFeeManagerFromComponents, }; use xcm_executor::XcmExecutor; @@ -183,6 +184,11 @@ pub type Barrier = TrailingSetTopicAsId<( /// We only waive fees for system functions, which these locations represent. pub type WaivedLocations = (SystemParachains, Equals, LocalPlurality); +/// We let locations alias into child locations of their own. +/// This is a very simple aliasing rule, mimicking the behaviour of +/// the `DescendOrigin` instruction. +pub type Aliasers = AliasChildLocation; + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -216,7 +222,7 @@ impl xcm_executor::Config for XcmConfig { type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; + type Aliasers = Aliasers; type TransactionalProcessor = FrameTransactionalProcessor; type HrmpNewChannelOpenRequestHandler = (); type HrmpChannelAcceptedHandler = (); diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index 431c7a5f1371..84d4cba1dbe1 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -140,7 +140,7 @@ mod benchmarks { } #[benchmark] - fn set_asset_claimer() -> Result<(), BenchmarkError> { + fn asset_claimer() -> Result<(), BenchmarkError> { let mut executor = new_executor::(Default::default()); let (_, sender_location) = account_and_location::(1); diff --git a/prdoc/pr_6814.prdoc b/prdoc/pr_6814.prdoc new file mode 100644 index 000000000000..4edbf2f8ed28 --- /dev/null +++ b/prdoc/pr_6814.prdoc @@ -0,0 +1,32 @@ +title: Add aliasers to westend chains +doc: +- audience: Runtime Dev + description: |- + `InitiateTransfer`, the new instruction introduced in XCMv5, allows preserving the origin after a cross-chain transfer via the usage of the `AliasOrigin` instruction. The receiving chain needs to be configured to allow such this instruction to have its intended effect and not just throw an error. + + In this PR, I add the alias rules specified in the [RFC for origin preservation](https://github.com/polkadot-fellows/RFCs/blob/main/text/0122-alias-origin-on-asset-transfers.md) to westend chains so we can test these scenarios in the testnet. + + The new scenarios include: + - Sending a cross-chain transfer from one system chain to another and doing a Transact on the same message (1 hop) + - Sending a reserve asset transfer from one chain to another going through asset hub and doing Transact on the same message (2 hops) + + The updated chains are: + - Relay: added `AliasChildLocation` + - Collectives: added `AliasChildLocation` and `AliasOriginRootUsingFilter` + - People: added `AliasChildLocation` and `AliasOriginRootUsingFilter` + - Coretime: added `AliasChildLocation` and `AliasOriginRootUsingFilter` + + AssetHub already has `AliasChildLocation` and doesn't need the other config item. + BridgeHub is not intended to be used by end users so I didn't add any config item. + Only added `AliasChildOrigin` to the relay since we intend for it to be used less. +crates: +- name: westend-runtime + bump: patch +- name: collectives-westend-runtime + bump: patch +- name: people-westend-runtime + bump: patch +- name: coretime-westend-runtime + bump: patch +- name: pallet-xcm-benchmarks + bump: patch From f0b5c3e6c9f2dbef3df55a9ae19e9d4532fd6754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 11 Dec 2024 23:02:23 +0100 Subject: [PATCH 43/51] pallet-revive: Statically verify imports on code deployment (#6759) Previously, we failed at runtime if an unknown or unstable host function was called. This requires us to keep track of when a host function was added and when a code was deployed. We used the `api_version` to track at which API version each code was deployed. This made sure that when a new host function was added that old code won't have access to it. This is necessary as otherwise the behavior of a contract that made calls to this previously non existent host function would change from "trap" to "do something". In this PR we remove the API version. Instead, we statically verify on upload that no non-existent host function is ever used in the code. This will allow us to add new host function later without needing to keep track when they were added. This simplifies the code and also gives an immediate feedback if unknown host functions are used. --------- Co-authored-by: GitHub Action --- prdoc/pr_6759.prdoc | 16 +++ substrate/frame/revive/README.md | 2 +- .../fixtures/contracts/unknown_syscall.rs | 44 ++++++++ .../fixtures/contracts/unstable_interface.rs | 44 ++++++++ substrate/frame/revive/proc-macro/src/lib.rs | 72 ++++++------ .../revive/src/benchmarking/call_builder.rs | 10 +- substrate/frame/revive/src/lib.rs | 21 ---- substrate/frame/revive/src/limits.rs | 25 ++++- substrate/frame/revive/src/tests.rs | 32 ++++++ substrate/frame/revive/src/wasm/mod.rs | 42 ++----- substrate/frame/revive/src/wasm/runtime.rs | 105 +++++++++--------- 11 files changed, 261 insertions(+), 152 deletions(-) create mode 100644 prdoc/pr_6759.prdoc create mode 100644 substrate/frame/revive/fixtures/contracts/unknown_syscall.rs create mode 100644 substrate/frame/revive/fixtures/contracts/unstable_interface.rs diff --git a/prdoc/pr_6759.prdoc b/prdoc/pr_6759.prdoc new file mode 100644 index 000000000000..3dff12d740d4 --- /dev/null +++ b/prdoc/pr_6759.prdoc @@ -0,0 +1,16 @@ +title: 'pallet-revive: Statically verify imports on code deployment' +doc: +- audience: Runtime Dev + description: |- + Previously, we failed at runtime if an unknown or unstable host function was called. This requires us to keep track of when a host function was added and when a code was deployed. We used the `api_version` to track at which API version each code was deployed. This made sure that when a new host function was added that old code won't have access to it. This is necessary as otherwise the behavior of a contract that made calls to this previously non existent host function would change from "trap" to "do something". + + In this PR we remove the API version. Instead, we statically verify on upload that no non-existent host function is ever used in the code. This will allow us to add new host function later without needing to keep track when they were added. + + This simplifies the code and also gives an immediate feedback if unknown host functions are used. +crates: +- name: pallet-revive-proc-macro + bump: major +- name: pallet-revive + bump: major +- name: pallet-revive-fixtures + bump: major diff --git a/substrate/frame/revive/README.md b/substrate/frame/revive/README.md index 5352e636c252..575920dfaac7 100644 --- a/substrate/frame/revive/README.md +++ b/substrate/frame/revive/README.md @@ -92,7 +92,7 @@ Driven by the desire to have an iterative approach in developing new contract in concept of an unstable interface. Akin to the rust nightly compiler it allows us to add new interfaces but mark them as unstable so that contract languages can experiment with them and give feedback before we stabilize those. -In order to access interfaces which don't have a stable `#[api_version(x)]` in [`runtime.rs`](src/wasm/runtime.rs) +In order to access interfaces which don't have a stable `#[stable]` in [`runtime.rs`](src/wasm/runtime.rs) one need to set `pallet_revive::Config::UnsafeUnstableInterface` to `ConstU32`. **It should be obvious that any production runtime should never be compiled with this feature: In addition to be subject to change or removal those interfaces might not have proper weights associated with them and are therefore diff --git a/substrate/frame/revive/fixtures/contracts/unknown_syscall.rs b/substrate/frame/revive/fixtures/contracts/unknown_syscall.rs new file mode 100644 index 000000000000..93ea86754f55 --- /dev/null +++ b/substrate/frame/revive/fixtures/contracts/unknown_syscall.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#![no_std] +#![no_main] + +extern crate common; + +#[polkavm_derive::polkavm_import] +extern "C" { + pub fn __this_syscall_does_not_exist__(); +} + +// Export that is never called. We can put code here that should be in the binary +// but is never supposed to be run. +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call_never() { + // make sure it is not optimized away + unsafe { + __this_syscall_does_not_exist__(); + } +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() {} diff --git a/substrate/frame/revive/fixtures/contracts/unstable_interface.rs b/substrate/frame/revive/fixtures/contracts/unstable_interface.rs new file mode 100644 index 000000000000..d73ae041dc06 --- /dev/null +++ b/substrate/frame/revive/fixtures/contracts/unstable_interface.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#![no_std] +#![no_main] + +extern crate common; + +#[polkavm_derive::polkavm_import] +extern "C" { + pub fn set_code_hash(); +} + +// Export that is never called. We can put code here that should be in the binary +// but is never supposed to be run. +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call_never() { + // make sure it is not optimized away + unsafe { + set_code_hash(); + } +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() {} diff --git a/substrate/frame/revive/proc-macro/src/lib.rs b/substrate/frame/revive/proc-macro/src/lib.rs index 6814add128d9..ed1798e5b689 100644 --- a/substrate/frame/revive/proc-macro/src/lib.rs +++ b/substrate/frame/revive/proc-macro/src/lib.rs @@ -119,7 +119,7 @@ struct EnvDef { /// Parsed host function definition. struct HostFn { item: syn::ItemFn, - api_version: Option, + is_stable: bool, name: String, returns: HostFnReturn, cfg: Option, @@ -183,22 +183,21 @@ impl HostFn { }; // process attributes - let msg = "Only #[api_version()], #[cfg] and #[mutating] attributes are allowed."; + let msg = "Only #[stable], #[cfg] and #[mutating] attributes are allowed."; let span = item.span(); let mut attrs = item.attrs.clone(); attrs.retain(|a| !a.path().is_ident("doc")); - let mut api_version = None; + let mut is_stable = false; let mut mutating = false; let mut cfg = None; while let Some(attr) = attrs.pop() { let ident = attr.path().get_ident().ok_or(err(span, msg))?.to_string(); match ident.as_str() { - "api_version" => { - if api_version.is_some() { - return Err(err(span, "#[api_version] can only be specified once")) + "stable" => { + if is_stable { + return Err(err(span, "#[stable] can only be specified once")) } - api_version = - Some(attr.parse_args::().and_then(|lit| lit.base10_parse())?); + is_stable = true; }, "mutating" => { if mutating { @@ -313,7 +312,7 @@ impl HostFn { _ => Err(err(arg1.span(), &msg)), }?; - Ok(Self { item, api_version, name, returns, cfg }) + Ok(Self { item, is_stable, name, returns, cfg }) }, _ => Err(err(span, &msg)), } @@ -411,19 +410,23 @@ fn expand_env(def: &EnvDef) -> TokenStream2 { let impls = expand_functions(def); let bench_impls = expand_bench_functions(def); let docs = expand_func_doc(def); - let highest_api_version = - def.host_funcs.iter().filter_map(|f| f.api_version).max().unwrap_or_default(); + let stable_syscalls = expand_func_list(def, false); + let all_syscalls = expand_func_list(def, true); quote! { - #[cfg(test)] - pub const HIGHEST_API_VERSION: u16 = #highest_api_version; + pub fn list_syscalls(include_unstable: bool) -> &'static [&'static [u8]] { + if include_unstable { + #all_syscalls + } else { + #stable_syscalls + } + } impl<'a, E: Ext, M: PolkaVmInstance> Runtime<'a, E, M> { fn handle_ecall( &mut self, memory: &mut M, __syscall_symbol__: &[u8], - __available_api_version__: ApiVersion, ) -> Result, TrapReason> { #impls @@ -474,10 +477,6 @@ fn expand_functions(def: &EnvDef) -> TokenStream2 { let body = &f.item.block; let map_output = f.returns.map_output(); let output = &f.item.sig.output; - let api_version = match f.api_version { - Some(version) => quote! { Some(#version) }, - None => quote! { None }, - }; // wrapped host function body call with host function traces // see https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/contracts#host-function-tracing @@ -513,7 +512,7 @@ fn expand_functions(def: &EnvDef) -> TokenStream2 { quote! { #cfg - #syscall_symbol if __is_available__(#api_version) => { + #syscall_symbol => { // closure is needed so that "?" can infere the correct type (|| #output { #arg_decoder @@ -534,18 +533,6 @@ fn expand_functions(def: &EnvDef) -> TokenStream2 { // This is the overhead to call an empty syscall that always needs to be charged. self.charge_gas(crate::wasm::RuntimeCosts::HostFn).map_err(TrapReason::from)?; - // Not all APIs are available depending on configuration or when the code was deployed. - // This closure will be used by syscall specific code to perform this check. - let __is_available__ = |syscall_version: Option| { - match __available_api_version__ { - ApiVersion::UnsafeNewest => true, - ApiVersion::Versioned(max_available_version) => - syscall_version - .map(|required_version| max_available_version >= required_version) - .unwrap_or(false), - } - }; - // They will be mapped to variable names by the syscall specific code. let (__a0__, __a1__, __a2__, __a3__, __a4__, __a5__) = memory.read_input_regs(); @@ -607,10 +594,8 @@ fn expand_func_doc(def: &EnvDef) -> TokenStream2 { }); quote! { #( #docs )* } }; - let availability = if let Some(version) = func.api_version { - let info = format!( - "\n# Required API version\nThis API was added in version **{version}**.", - ); + let availability = if func.is_stable { + let info = "\n# Stable API\nThis API is stable and will never change."; quote! { #[doc = #info] } } else { let info = @@ -632,3 +617,20 @@ fn expand_func_doc(def: &EnvDef) -> TokenStream2 { #( #docs )* } } + +fn expand_func_list(def: &EnvDef, include_unstable: bool) -> TokenStream2 { + let docs = def.host_funcs.iter().filter(|f| include_unstable || f.is_stable).map(|f| { + let name = Literal::byte_string(f.name.as_bytes()); + quote! { + #name.as_slice() + } + }); + let len = docs.clone().count(); + + quote! { + { + static FUNCS: [&[u8]; #len] = [#(#docs),*]; + FUNCS.as_slice() + } + } +} diff --git a/substrate/frame/revive/src/benchmarking/call_builder.rs b/substrate/frame/revive/src/benchmarking/call_builder.rs index 8d3157541168..1177d47aadc3 100644 --- a/substrate/frame/revive/src/benchmarking/call_builder.rs +++ b/substrate/frame/revive/src/benchmarking/call_builder.rs @@ -21,7 +21,7 @@ use crate::{ exec::{ExportedFunction, Ext, Key, Stack}, storage::meter::Meter, transient_storage::MeterEntry, - wasm::{ApiVersion, PreparedCall, Runtime}, + wasm::{PreparedCall, Runtime}, BalanceOf, Config, DebugBuffer, Error, GasMeter, MomentOf, Origin, WasmBlob, Weight, }; use alloc::{vec, vec::Vec}; @@ -164,13 +164,7 @@ where module: WasmBlob, input: Vec, ) -> PreparedCall<'a, StackExt<'a, T>> { - module - .prepare_call( - Runtime::new(ext, input), - ExportedFunction::Call, - ApiVersion::UnsafeNewest, - ) - .unwrap() + module.prepare_call(Runtime::new(ext, input), ExportedFunction::Call).unwrap() } /// Add transient_storage diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index 1dee1da03bc4..b9a39e7ce4d3 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -115,19 +115,6 @@ const SENTINEL: u32 = u32::MAX; /// Example: `RUST_LOG=runtime::revive=debug my_code --dev` const LOG_TARGET: &str = "runtime::revive"; -/// This version determines which syscalls are available to contracts. -/// -/// Needs to be bumped every time a versioned syscall is added. -const API_VERSION: u16 = 0; - -#[test] -fn api_version_up_to_date() { - assert!( - API_VERSION == crate::wasm::HIGHEST_API_VERSION, - "A new versioned API has been added. The `API_VERSION` needs to be bumped." - ); -} - #[frame_support::pallet] pub mod pallet { use super::*; @@ -623,14 +610,6 @@ pub mod pallet { #[pallet::storage] pub(crate) type AddressSuffix = StorageMap<_, Identity, H160, [u8; 12]>; - #[pallet::extra_constants] - impl Pallet { - #[pallet::constant_name(ApiVersion)] - fn api_version() -> u16 { - API_VERSION - } - } - #[pallet::hooks] impl Hooks> for Pallet { fn on_idle(_block: BlockNumberFor, limit: Weight) -> Weight { diff --git a/substrate/frame/revive/src/limits.rs b/substrate/frame/revive/src/limits.rs index 5ce96f59c14d..2e112baae301 100644 --- a/substrate/frame/revive/src/limits.rs +++ b/substrate/frame/revive/src/limits.rs @@ -116,7 +116,10 @@ pub mod code { const BASIC_BLOCK_SIZE: u32 = 1000; /// Make sure that the various program parts are within the defined limits. - pub fn enforce(blob: Vec) -> Result { + pub fn enforce( + blob: Vec, + available_syscalls: &[&[u8]], + ) -> Result { fn round_page(n: u32) -> u64 { // performing the rounding in u64 in order to prevent overflow u64::from(n).next_multiple_of(PAGE_SIZE.into()) @@ -134,6 +137,26 @@ pub mod code { Err(Error::::CodeRejected)?; } + // Need to check that no non-existent syscalls are used. This allows us to add + // new syscalls later without affecting already deployed code. + for (idx, import) in program.imports().iter().enumerate() { + // We are being defensive in case an attacker is able to somehow include + // a lot of imports. This is important because we search the array of host + // functions for every import. + if idx == available_syscalls.len() { + log::debug!(target: LOG_TARGET, "Program contains too many imports."); + Err(Error::::CodeRejected)?; + } + let Some(import) = import else { + log::debug!(target: LOG_TARGET, "Program contains malformed import."); + return Err(Error::::CodeRejected.into()); + }; + if !available_syscalls.contains(&import.as_bytes()) { + log::debug!(target: LOG_TARGET, "Program references unknown syscall: {}", import); + Err(Error::::CodeRejected)?; + } + } + // This scans the whole program but we only do it once on code deployment. // It is safe to do unchecked math in u32 because the size of the program // was already checked above. diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index 58d4721b4e53..a000de1491fa 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -4753,3 +4753,35 @@ fn skip_transfer_works() { )); }); } + +#[test] +fn unknown_syscall_rejected() { + let (code, _) = compile_module("unknown_syscall").unwrap(); + + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + ::Currency::set_balance(&ALICE, 1_000_000); + + assert_err!( + builder::bare_instantiate(Code::Upload(code)).build().result, + >::CodeRejected, + ) + }); +} + +#[test] +fn unstable_interface_rejected() { + let (code, _) = compile_module("unstable_interface").unwrap(); + + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + ::Currency::set_balance(&ALICE, 1_000_000); + + Test::set_unstable_interface(false); + assert_err!( + builder::bare_instantiate(Code::Upload(code.clone())).build().result, + >::CodeRejected, + ); + + Test::set_unstable_interface(true); + assert_ok!(builder::bare_instantiate(Code::Upload(code)).build().result); + }); +} diff --git a/substrate/frame/revive/src/wasm/mod.rs b/substrate/frame/revive/src/wasm/mod.rs index 54fb02c866e1..e963895dafae 100644 --- a/substrate/frame/revive/src/wasm/mod.rs +++ b/substrate/frame/revive/src/wasm/mod.rs @@ -23,13 +23,10 @@ mod runtime; #[cfg(doc)] pub use crate::wasm::runtime::SyscallDoc; -#[cfg(test)] -pub use runtime::HIGHEST_API_VERSION; - #[cfg(feature = "runtime-benchmarks")] pub use crate::wasm::runtime::{ReturnData, TrapReason}; -pub use crate::wasm::runtime::{ApiVersion, Memory, Runtime, RuntimeCosts}; +pub use crate::wasm::runtime::{Memory, Runtime, RuntimeCosts}; use crate::{ address::AddressMapper, @@ -39,7 +36,7 @@ use crate::{ storage::meter::Diff, weights::WeightInfo, AccountIdOf, BadOrigin, BalanceOf, CodeInfoOf, CodeVec, Config, Error, Event, ExecError, - HoldReason, Pallet, PristineCode, Weight, API_VERSION, LOG_TARGET, + HoldReason, Pallet, PristineCode, Weight, LOG_TARGET, }; use alloc::vec::Vec; use codec::{Decode, Encode, MaxEncodedLen}; @@ -87,11 +84,6 @@ pub struct CodeInfo { refcount: u64, /// Length of the code in bytes. code_len: u32, - /// The API version that this contract operates under. - /// - /// This determines which host functions are available to the contract. This - /// prevents that new host functions become available to already deployed contracts. - api_version: u16, /// The behaviour version that this contract operates under. /// /// Whenever any observeable change (with the exception of weights) are made we need @@ -99,7 +91,7 @@ pub struct CodeInfo { /// exposing the old behaviour depending on the set behaviour version of the contract. /// /// As of right now this is a reserved field that is always set to 0. - behaviour_version: u16, + behaviour_version: u32, } impl ExportedFunction { @@ -130,9 +122,10 @@ where { /// We only check for size and nothing else when the code is uploaded. pub fn from_code(code: Vec, owner: AccountIdOf) -> Result { - // We do size checks when new code is deployed. This allows us to increase + // We do validation only when new code is deployed. This allows us to increase // the limits later without affecting already deployed code. - let code = limits::code::enforce::(code)?; + let available_syscalls = runtime::list_syscalls(T::UnsafeUnstableInterface::get()); + let code = limits::code::enforce::(code, available_syscalls)?; let code_len = code.len() as u32; let bytes_added = code_len.saturating_add(>::max_encoded_len() as u32); @@ -144,7 +137,6 @@ where deposit, refcount: 0, code_len, - api_version: API_VERSION, behaviour_version: Default::default(), }; let code_hash = H256(sp_io::hashing::keccak_256(&code)); @@ -230,7 +222,6 @@ impl CodeInfo { deposit: Default::default(), refcount: 0, code_len: 0, - api_version: API_VERSION, behaviour_version: Default::default(), } } @@ -260,7 +251,6 @@ pub struct PreparedCall<'a, E: Ext> { module: polkavm::Module, instance: polkavm::RawInstance, runtime: Runtime<'a, E, polkavm::RawInstance>, - api_version: ApiVersion, } impl<'a, E: Ext> PreparedCall<'a, E> @@ -271,12 +261,9 @@ where pub fn call(mut self) -> ExecResult { let exec_result = loop { let interrupt = self.instance.run(); - if let Some(exec_result) = self.runtime.handle_interrupt( - interrupt, - &self.module, - &mut self.instance, - self.api_version, - ) { + if let Some(exec_result) = + self.runtime.handle_interrupt(interrupt, &self.module, &mut self.instance) + { break exec_result } }; @@ -290,7 +277,6 @@ impl WasmBlob { self, mut runtime: Runtime, entry_point: ExportedFunction, - api_version: ApiVersion, ) -> Result, ExecError> { let mut config = polkavm::Config::default(); config.set_backend(Some(polkavm::BackendKind::Interpreter)); @@ -344,7 +330,7 @@ impl WasmBlob { instance.set_gas(gas_limit_polkavm); instance.prepare_call_untyped(entry_program_counter, &[]); - Ok(PreparedCall { module, instance, runtime, api_version }) + Ok(PreparedCall { module, instance, runtime }) } } @@ -365,13 +351,7 @@ where function: ExportedFunction, input_data: Vec, ) -> ExecResult { - let api_version = if ::UnsafeUnstableInterface::get() { - ApiVersion::UnsafeNewest - } else { - ApiVersion::Versioned(self.code_info.api_version) - }; - let prepared_call = - self.prepare_call(Runtime::new(ext, input_data), function, api_version)?; + let prepared_call = self.prepare_call(Runtime::new(ext, input_data), function)?; prepared_call.call() } diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs index 8fb7e5c27470..8d54b7fd0ddf 100644 --- a/substrate/frame/revive/src/wasm/runtime.rs +++ b/substrate/frame/revive/src/wasm/runtime.rs @@ -44,14 +44,6 @@ type CallOf = ::RuntimeCall; /// The maximum nesting depth a contract can use when encoding types. const MAX_DECODE_NESTING: u32 = 256; -#[derive(Clone, Copy)] -pub enum ApiVersion { - /// Expose all APIs even unversioned ones. Only used for testing and benchmarking. - UnsafeNewest, - /// Only expose API's up to and including the specified version. - Versioned(u16), -} - /// Abstraction over the memory access within syscalls. /// /// The reason for this abstraction is that we run syscalls on the host machine when @@ -551,7 +543,6 @@ impl<'a, E: Ext, M: PolkaVmInstance> Runtime<'a, E, M> { interrupt: Result, module: &polkavm::Module, instance: &mut M, - api_version: ApiVersion, ) -> Option { use polkavm::InterruptKind::*; @@ -571,7 +562,7 @@ impl<'a, E: Ext, M: PolkaVmInstance> Runtime<'a, E, M> { let Some(syscall_symbol) = module.imports().get(idx) else { return Some(Err(>::InvalidSyscall.into())); }; - match self.handle_ecall(instance, syscall_symbol.as_bytes(), api_version) { + match self.handle_ecall(instance, syscall_symbol.as_bytes()) { Ok(None) => None, Ok(Some(return_value)) => { instance.write_output(return_value); @@ -1127,14 +1118,18 @@ impl<'a, E: Ext, M: ?Sized + Memory> Runtime<'a, E, M> { #[define_env] pub mod env { /// Noop function used to benchmark the time it takes to execute an empty function. + /// + /// Marked as stable because it needs to be called from benchmarks even when the benchmarked + /// parachain has unstable functions disabled. #[cfg(feature = "runtime-benchmarks")] + #[stable] fn noop(&mut self, memory: &mut M) -> Result<(), TrapReason> { Ok(()) } /// Set the value at the given key in the contract storage. /// See [`pallet_revive_uapi::HostFn::set_storage_v2`] - #[api_version(0)] + #[stable] #[mutating] fn set_storage( &mut self, @@ -1150,7 +1145,7 @@ pub mod env { /// Clear the value at the given key in the contract storage. /// See [`pallet_revive_uapi::HostFn::clear_storage`] - #[api_version(0)] + #[stable] #[mutating] fn clear_storage( &mut self, @@ -1164,7 +1159,7 @@ pub mod env { /// Retrieve the value under the given key from storage. /// See [`pallet_revive_uapi::HostFn::get_storage`] - #[api_version(0)] + #[stable] fn get_storage( &mut self, memory: &mut M, @@ -1179,7 +1174,7 @@ pub mod env { /// Checks whether there is a value stored under the given key. /// See [`pallet_revive_uapi::HostFn::contains_storage`] - #[api_version(0)] + #[stable] fn contains_storage( &mut self, memory: &mut M, @@ -1192,7 +1187,7 @@ pub mod env { /// Retrieve and remove the value under the given key from storage. /// See [`pallet_revive_uapi::HostFn::take_storage`] - #[api_version(0)] + #[stable] #[mutating] fn take_storage( &mut self, @@ -1208,7 +1203,7 @@ pub mod env { /// Make a call to another contract. /// See [`pallet_revive_uapi::HostFn::call`]. - #[api_version(0)] + #[stable] fn call( &mut self, memory: &mut M, @@ -1239,7 +1234,7 @@ pub mod env { /// Execute code in the context (storage, caller, value) of the current contract. /// See [`pallet_revive_uapi::HostFn::delegate_call`]. - #[api_version(0)] + #[stable] fn delegate_call( &mut self, memory: &mut M, @@ -1269,7 +1264,7 @@ pub mod env { /// Instantiate a contract with the specified code hash. /// See [`pallet_revive_uapi::HostFn::instantiate`]. - #[api_version(0)] + #[stable] #[mutating] fn instantiate( &mut self, @@ -1303,7 +1298,7 @@ pub mod env { /// Remove the calling account and transfer remaining **free** balance. /// See [`pallet_revive_uapi::HostFn::terminate`]. - #[api_version(0)] + #[stable] #[mutating] fn terminate(&mut self, memory: &mut M, beneficiary_ptr: u32) -> Result<(), TrapReason> { self.terminate(memory, beneficiary_ptr) @@ -1311,7 +1306,7 @@ pub mod env { /// Stores the input passed by the caller into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::input`]. - #[api_version(0)] + #[stable] fn input(&mut self, memory: &mut M, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> { if let Some(input) = self.input_data.take() { self.write_sandbox_output(memory, out_ptr, out_len_ptr, &input, false, |len| { @@ -1326,7 +1321,7 @@ pub mod env { /// Cease contract execution and save a data buffer as a result of the execution. /// See [`pallet_revive_uapi::HostFn::return_value`]. - #[api_version(0)] + #[stable] fn seal_return( &mut self, memory: &mut M, @@ -1340,7 +1335,7 @@ pub mod env { /// Stores the address of the caller into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::caller`]. - #[api_version(0)] + #[stable] fn caller(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::Caller)?; let caller = ::AddressMapper::to_address(self.ext.caller().account_id()?); @@ -1355,7 +1350,7 @@ pub mod env { /// Stores the address of the call stack origin into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::origin`]. - #[api_version(0)] + #[stable] fn origin(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::Origin)?; let origin = ::AddressMapper::to_address(self.ext.origin().account_id()?); @@ -1370,7 +1365,7 @@ pub mod env { /// Checks whether a specified address belongs to a contract. /// See [`pallet_revive_uapi::HostFn::is_contract`]. - #[api_version(0)] + #[stable] fn is_contract(&mut self, memory: &mut M, account_ptr: u32) -> Result { self.charge_gas(RuntimeCosts::IsContract)?; let address = memory.read_h160(account_ptr)?; @@ -1379,7 +1374,7 @@ pub mod env { /// Retrieve the code hash for a specified contract address. /// See [`pallet_revive_uapi::HostFn::code_hash`]. - #[api_version(0)] + #[stable] fn code_hash(&mut self, memory: &mut M, addr_ptr: u32, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::CodeHash)?; let address = memory.read_h160(addr_ptr)?; @@ -1394,7 +1389,7 @@ pub mod env { /// Retrieve the code size for a given contract address. /// See [`pallet_revive_uapi::HostFn::code_size`]. - #[api_version(0)] + #[stable] fn code_size(&mut self, memory: &mut M, addr_ptr: u32, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::CodeSize)?; let address = memory.read_h160(addr_ptr)?; @@ -1409,7 +1404,7 @@ pub mod env { /// Retrieve the code hash of the currently executing contract. /// See [`pallet_revive_uapi::HostFn::own_code_hash`]. - #[api_version(0)] + #[stable] fn own_code_hash(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::OwnCodeHash)?; let code_hash = *self.ext.own_code_hash(); @@ -1424,7 +1419,7 @@ pub mod env { /// Checks whether the caller of the current contract is the origin of the whole call stack. /// See [`pallet_revive_uapi::HostFn::caller_is_origin`]. - #[api_version(0)] + #[stable] fn caller_is_origin(&mut self, _memory: &mut M) -> Result { self.charge_gas(RuntimeCosts::CallerIsOrigin)?; Ok(self.ext.caller_is_origin() as u32) @@ -1432,7 +1427,7 @@ pub mod env { /// Checks whether the caller of the current contract is root. /// See [`pallet_revive_uapi::HostFn::caller_is_root`]. - #[api_version(0)] + #[stable] fn caller_is_root(&mut self, _memory: &mut M) -> Result { self.charge_gas(RuntimeCosts::CallerIsRoot)?; Ok(self.ext.caller_is_root() as u32) @@ -1440,7 +1435,7 @@ pub mod env { /// Stores the address of the current contract into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::address`]. - #[api_version(0)] + #[stable] fn address(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::Address)?; let address = self.ext.address(); @@ -1455,7 +1450,7 @@ pub mod env { /// Stores the price for the specified amount of weight into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::weight_to_fee`]. - #[api_version(0)] + #[stable] fn weight_to_fee( &mut self, memory: &mut M, @@ -1476,7 +1471,7 @@ pub mod env { /// Stores the amount of weight left into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::weight_left`]. - #[api_version(0)] + #[stable] fn weight_left( &mut self, memory: &mut M, @@ -1497,7 +1492,7 @@ pub mod env { /// Stores the immutable data into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::get_immutable_data`]. - #[api_version(0)] + #[stable] fn get_immutable_data( &mut self, memory: &mut M, @@ -1513,7 +1508,7 @@ pub mod env { /// Attaches the supplied immutable data to the currently executing contract. /// See [`pallet_revive_uapi::HostFn::set_immutable_data`]. - #[api_version(0)] + #[stable] fn set_immutable_data(&mut self, memory: &mut M, ptr: u32, len: u32) -> Result<(), TrapReason> { if len > limits::IMMUTABLE_BYTES { return Err(Error::::OutOfBounds.into()); @@ -1527,7 +1522,7 @@ pub mod env { /// Stores the *free* balance of the current account into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::balance`]. - #[api_version(0)] + #[stable] fn balance(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::Balance)?; Ok(self.write_fixed_sandbox_output( @@ -1541,7 +1536,7 @@ pub mod env { /// Stores the *free* balance of the supplied address into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::balance`]. - #[api_version(0)] + #[stable] fn balance_of( &mut self, memory: &mut M, @@ -1561,7 +1556,7 @@ pub mod env { /// Returns the chain ID. /// See [`pallet_revive_uapi::HostFn::chain_id`]. - #[api_version(0)] + #[stable] fn chain_id(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { Ok(self.write_fixed_sandbox_output( memory, @@ -1574,7 +1569,7 @@ pub mod env { /// Stores the value transferred along with this call/instantiate into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::value_transferred`]. - #[api_version(0)] + #[stable] fn value_transferred(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::ValueTransferred)?; Ok(self.write_fixed_sandbox_output( @@ -1588,7 +1583,7 @@ pub mod env { /// Load the latest block timestamp into the supplied buffer /// See [`pallet_revive_uapi::HostFn::now`]. - #[api_version(0)] + #[stable] fn now(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::Now)?; Ok(self.write_fixed_sandbox_output( @@ -1602,7 +1597,7 @@ pub mod env { /// Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::minimum_balance`]. - #[api_version(0)] + #[stable] fn minimum_balance(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::MinimumBalance)?; Ok(self.write_fixed_sandbox_output( @@ -1616,7 +1611,7 @@ pub mod env { /// Deposit a contract event with the data buffer and optional list of topics. /// See [pallet_revive_uapi::HostFn::deposit_event] - #[api_version(0)] + #[stable] #[mutating] fn deposit_event( &mut self, @@ -1656,7 +1651,7 @@ pub mod env { /// Stores the current block number of the current contract into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::block_number`]. - #[api_version(0)] + #[stable] fn block_number(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::BlockNumber)?; Ok(self.write_fixed_sandbox_output( @@ -1670,7 +1665,7 @@ pub mod env { /// Stores the block hash at given block height into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::block_hash`]. - #[api_version(0)] + #[stable] fn block_hash( &mut self, memory: &mut M, @@ -1691,7 +1686,7 @@ pub mod env { /// Computes the SHA2 256-bit hash on the given input buffer. /// See [`pallet_revive_uapi::HostFn::hash_sha2_256`]. - #[api_version(0)] + #[stable] fn hash_sha2_256( &mut self, memory: &mut M, @@ -1707,7 +1702,7 @@ pub mod env { /// Computes the KECCAK 256-bit hash on the given input buffer. /// See [`pallet_revive_uapi::HostFn::hash_keccak_256`]. - #[api_version(0)] + #[stable] fn hash_keccak_256( &mut self, memory: &mut M, @@ -1723,7 +1718,7 @@ pub mod env { /// Computes the BLAKE2 256-bit hash on the given input buffer. /// See [`pallet_revive_uapi::HostFn::hash_blake2_256`]. - #[api_version(0)] + #[stable] fn hash_blake2_256( &mut self, memory: &mut M, @@ -1739,7 +1734,7 @@ pub mod env { /// Computes the BLAKE2 128-bit hash on the given input buffer. /// See [`pallet_revive_uapi::HostFn::hash_blake2_128`]. - #[api_version(0)] + #[stable] fn hash_blake2_128( &mut self, memory: &mut M, @@ -1785,7 +1780,7 @@ pub mod env { /// Emit a custom debug message. /// See [`pallet_revive_uapi::HostFn::debug_message`]. - #[api_version(0)] + #[stable] fn debug_message( &mut self, memory: &mut M, @@ -1903,7 +1898,7 @@ pub mod env { /// Recovers the ECDSA public key from the given message hash and signature. /// See [`pallet_revive_uapi::HostFn::ecdsa_recover`]. - #[api_version(0)] + #[stable] fn ecdsa_recover( &mut self, memory: &mut M, @@ -1934,7 +1929,7 @@ pub mod env { /// Verify a sr25519 signature /// See [`pallet_revive_uapi::HostFn::sr25519_verify`]. - #[api_version(0)] + #[stable] fn sr25519_verify( &mut self, memory: &mut M, @@ -1975,7 +1970,7 @@ pub mod env { /// Calculates Ethereum address from the ECDSA compressed public key and stores /// See [`pallet_revive_uapi::HostFn::ecdsa_to_eth_address`]. - #[api_version(0)] + #[stable] fn ecdsa_to_eth_address( &mut self, memory: &mut M, @@ -1997,7 +1992,7 @@ pub mod env { /// Adds a new delegate dependency to the contract. /// See [`pallet_revive_uapi::HostFn::lock_delegate_dependency`]. - #[api_version(0)] + #[stable] #[mutating] fn lock_delegate_dependency( &mut self, @@ -2012,7 +2007,7 @@ pub mod env { /// Removes the delegate dependency from the contract. /// see [`pallet_revive_uapi::HostFn::unlock_delegate_dependency`]. - #[api_version(0)] + #[stable] #[mutating] fn unlock_delegate_dependency( &mut self, @@ -2027,7 +2022,7 @@ pub mod env { /// Stores the length of the data returned by the last call into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::return_data_size`]. - #[api_version(0)] + #[stable] fn return_data_size(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { Ok(self.write_fixed_sandbox_output( memory, @@ -2040,7 +2035,7 @@ pub mod env { /// Stores data returned by the last call, starting from `offset`, into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::return_data`]. - #[api_version(0)] + #[stable] fn return_data_copy( &mut self, memory: &mut M, From 61518e0f808723beef9f4f63d1da9cc604c77530 Mon Sep 17 00:00:00 2001 From: Iulian Barbu <14218860+iulianbarbu@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:29:35 +0200 Subject: [PATCH 44/51] Update parity-publish to 0.10.3 (#6854) # Description Upgrades parity-publish with fixes for `Error: no dep` and panic triggered when running `plan` and there is a new unpublished member crate introduced in the workspace. ## Integration N/A ## Review Notes Context: https://github.com/paritytech/polkadot-sdk/pull/6450#issuecomment-2537108971 Signed-off-by: Iulian Barbu --- .github/workflows/check-semver.yml | 2 +- .github/workflows/publish-check-compile.yml | 2 +- .github/workflows/publish-check-crates.yml | 2 +- .github/workflows/publish-claim-crates.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-semver.yml b/.github/workflows/check-semver.yml index 11b386da21e9..16028c8de770 100644 --- a/.github/workflows/check-semver.yml +++ b/.github/workflows/check-semver.yml @@ -74,7 +74,7 @@ jobs: - name: install parity-publish # Set the target dir to cache the build. - run: CARGO_TARGET_DIR=./target/ cargo install parity-publish@0.10.2 --locked -q + run: CARGO_TARGET_DIR=./target/ cargo install parity-publish@0.10.3 --locked -q - name: check semver run: | diff --git a/.github/workflows/publish-check-compile.yml b/.github/workflows/publish-check-compile.yml index 83cd3ff8fa90..ada8635e314e 100644 --- a/.github/workflows/publish-check-compile.yml +++ b/.github/workflows/publish-check-compile.yml @@ -31,7 +31,7 @@ jobs: cache-on-failure: true - name: install parity-publish - run: cargo install parity-publish@0.10.2 --locked -q + run: cargo install parity-publish@0.10.3 --locked -q - name: parity-publish update plan run: parity-publish --color always plan --skip-check --prdoc prdoc/ diff --git a/.github/workflows/publish-check-crates.yml b/.github/workflows/publish-check-crates.yml index 1e5a8054e2c7..3150cb9dd405 100644 --- a/.github/workflows/publish-check-crates.yml +++ b/.github/workflows/publish-check-crates.yml @@ -24,7 +24,7 @@ jobs: cache-on-failure: true - name: install parity-publish - run: cargo install parity-publish@0.10.2 --locked -q + run: cargo install parity-publish@0.10.3 --locked -q - name: parity-publish check run: parity-publish --color always check --allow-unpublished diff --git a/.github/workflows/publish-claim-crates.yml b/.github/workflows/publish-claim-crates.yml index 845b57a61b96..a6efc8a5599e 100644 --- a/.github/workflows/publish-claim-crates.yml +++ b/.github/workflows/publish-claim-crates.yml @@ -18,7 +18,7 @@ jobs: cache-on-failure: true - name: install parity-publish - run: cargo install parity-publish@0.10.2 --locked -q + run: cargo install parity-publish@0.10.3 --locked -q - name: parity-publish claim env: From 389e221dcf65fc744d206f5293227959a228ba91 Mon Sep 17 00:00:00 2001 From: Cyrill Leutwiler Date: Thu, 12 Dec 2024 12:56:20 +0100 Subject: [PATCH 45/51] [pallet-revive] implement the call data load API (#6835) This PR implements the call data load API akin to [how it works on ethereum](https://www.evm.codes/?fork=cancun#35). There will also be a second PR to adjust the input function to resemble the call data copy opcode on EVM. --------- Signed-off-by: Cyrill Leutwiler Co-authored-by: command-bot <> --- prdoc/pr_6835.prdoc | 12 + .../fixtures/contracts/call_data_load.rs | 44 + .../frame/revive/src/benchmarking/mod.rs | 15 + substrate/frame/revive/src/tests.rs | 42 + substrate/frame/revive/src/wasm/runtime.rs | 34 + substrate/frame/revive/src/weights.rs | 881 +++++++++--------- substrate/frame/revive/uapi/src/host.rs | 15 + .../frame/revive/uapi/src/host/riscv64.rs | 5 + 8 files changed, 617 insertions(+), 431 deletions(-) create mode 100644 prdoc/pr_6835.prdoc create mode 100644 substrate/frame/revive/fixtures/contracts/call_data_load.rs diff --git a/prdoc/pr_6835.prdoc b/prdoc/pr_6835.prdoc new file mode 100644 index 000000000000..73d1a81e761c --- /dev/null +++ b/prdoc/pr_6835.prdoc @@ -0,0 +1,12 @@ +title: '[pallet-revive] implement the call data load API' +doc: +- audience: Runtime Dev + description: |- + This PR implements the call data load API akin to [how it works on ethereum](https://www.evm.codes/?fork=cancun#35). +crates: +- name: pallet-revive-fixtures + bump: minor +- name: pallet-revive + bump: minor +- name: pallet-revive-uapi + bump: minor diff --git a/substrate/frame/revive/fixtures/contracts/call_data_load.rs b/substrate/frame/revive/fixtures/contracts/call_data_load.rs new file mode 100644 index 000000000000..d3df9433f5d1 --- /dev/null +++ b/substrate/frame/revive/fixtures/contracts/call_data_load.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! This uses the call data load API to first the first input byte. +//! This single input byte is used as the offset for a second call +//! to the call data load API. +//! The output of the second API call is returned. + +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api, ReturnFlags}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + let mut buf = [0; 32]; + api::call_data_load(&mut buf, 0); + + let offset = buf[31] as u32; + let mut buf = [0; 32]; + api::call_data_load(&mut buf, offset); + + api::return_value(ReturnFlags::empty(), &buf); +} diff --git a/substrate/frame/revive/src/benchmarking/mod.rs b/substrate/frame/revive/src/benchmarking/mod.rs index ebdea8675824..94fac13d78e8 100644 --- a/substrate/frame/revive/src/benchmarking/mod.rs +++ b/substrate/frame/revive/src/benchmarking/mod.rs @@ -838,6 +838,21 @@ mod benchmarks { assert_eq!(U256::from_little_endian(&memory[..]), runtime.ext().get_weight_price(weight)); } + #[benchmark(pov_mode = Measured)] + fn seal_call_data_load() { + let mut setup = CallSetup::::default(); + let (mut ext, _) = setup.ext(); + let mut runtime = crate::wasm::Runtime::new(&mut ext, vec![42u8; 32]); + let mut memory = memory!(vec![0u8; 32],); + let result; + #[block] + { + result = runtime.bench_call_data_load(memory.as_mut_slice(), 0, 0); + } + assert_ok!(result); + assert_eq!(&memory[..], &vec![42u8; 32]); + } + #[benchmark(pov_mode = Measured)] fn seal_input(n: Linear<0, { limits::code::BLOB_BYTES - 4 }>) { let mut setup = CallSetup::::default(); diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index a000de1491fa..b3cd591e4d0c 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -4407,6 +4407,48 @@ fn chain_id_works() { }); } +#[test] +fn call_data_load_api_works() { + let (code, _) = compile_module("call_data_load").unwrap(); + + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { + let _ = ::Currency::set_balance(&ALICE, 1_000_000); + + // Create fixture: Constructor does nothing + let Contract { addr, .. } = + builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_contract(); + + // Call the contract: It reads a byte for the offset and then returns + // what call data load returned using this byte as the offset. + let input = (3u8, U256::max_value(), U256::max_value()).encode(); + let received = builder::bare_call(addr).data(input).build().result.unwrap(); + assert_eq!(received.flags, ReturnFlags::empty()); + assert_eq!(U256::from_little_endian(&received.data), U256::max_value()); + + // Edge case + let input = (2u8, U256::from(255).to_big_endian()).encode(); + let received = builder::bare_call(addr).data(input).build().result.unwrap(); + assert_eq!(received.flags, ReturnFlags::empty()); + assert_eq!(U256::from_little_endian(&received.data), U256::from(65280)); + + // Edge case + let received = builder::bare_call(addr).data(vec![1]).build().result.unwrap(); + assert_eq!(received.flags, ReturnFlags::empty()); + assert_eq!(U256::from_little_endian(&received.data), U256::zero()); + + // OOB case + let input = (42u8).encode(); + let received = builder::bare_call(addr).data(input).build().result.unwrap(); + assert_eq!(received.flags, ReturnFlags::empty()); + assert_eq!(U256::from_little_endian(&received.data), U256::zero()); + + // No calldata should return the zero value + let received = builder::bare_call(addr).build().result.unwrap(); + assert_eq!(received.flags, ReturnFlags::empty()); + assert_eq!(U256::from_little_endian(&received.data), U256::zero()); + }); +} + #[test] fn return_data_api_works() { let (code_return_data_api, _) = compile_module("return_data_api").unwrap(); diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs index 8d54b7fd0ddf..0d03771224b5 100644 --- a/substrate/frame/revive/src/wasm/runtime.rs +++ b/substrate/frame/revive/src/wasm/runtime.rs @@ -267,6 +267,8 @@ pub enum RuntimeCosts { CopyFromContract(u32), /// Weight charged for copying data to the sandbox. CopyToContract(u32), + /// Weight of calling `seal_call_data_load``. + CallDataLoad, /// Weight of calling `seal_caller`. Caller, /// Weight of calling `seal_origin`. @@ -429,6 +431,7 @@ impl Token for RuntimeCosts { HostFn => cost_args!(noop_host_fn, 1), CopyToContract(len) => T::WeightInfo::seal_input(len), CopyFromContract(len) => T::WeightInfo::seal_return(len), + CallDataLoad => T::WeightInfo::seal_call_data_load(), Caller => T::WeightInfo::seal_caller(), Origin => T::WeightInfo::seal_origin(), IsContract => T::WeightInfo::seal_is_contract(), @@ -1319,6 +1322,37 @@ pub mod env { } } + /// Stores the U256 value at given call input `offset` into the supplied buffer. + /// See [`pallet_revive_uapi::HostFn::call_data_load`]. + #[stable] + fn call_data_load( + &mut self, + memory: &mut M, + out_ptr: u32, + offset: u32, + ) -> Result<(), TrapReason> { + self.charge_gas(RuntimeCosts::CallDataLoad)?; + + let Some(input) = self.input_data.as_ref() else { + return Err(Error::::InputForwarded.into()); + }; + + let mut data = [0; 32]; + let start = offset as usize; + let data = if start >= input.len() { + data // Any index is valid to request; OOB offsets return zero. + } else { + let end = start.saturating_add(32).min(input.len()); + data[..end - start].copy_from_slice(&input[start..end]); + data.reverse(); + data // Solidity expects right-padded data + }; + + self.write_fixed_sandbox_output(memory, out_ptr, &data, false, already_charged)?; + + Ok(()) + } + /// Cease contract execution and save a data buffer as a result of the execution. /// See [`pallet_revive_uapi::HostFn::return_value`]. #[stable] diff --git a/substrate/frame/revive/src/weights.rs b/substrate/frame/revive/src/weights.rs index 96654432a5cc..e9178287f8f9 100644 --- a/substrate/frame/revive/src/weights.rs +++ b/substrate/frame/revive/src/weights.rs @@ -18,28 +18,28 @@ //! Autogenerated weights for `pallet_revive` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `9fd11f1b2ec3`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet +// --extrinsic=* // --chain=dev +// --pallet=pallet_revive +// --header=/__w/polkadot-sdk/polkadot-sdk/substrate/HEADER-APACHE2 +// --output=/__w/polkadot-sdk/polkadot-sdk/substrate/frame/revive/src/weights.rs +// --wasm-execution=compiled // --steps=50 // --repeat=20 -// --pallet=pallet_revive +// --heap-pages=4096 +// --template=substrate/.maintain/frame-weight-template.hbs // --no-storage-info -// --no-median-slopes // --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/revive/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --no-median-slopes #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -84,6 +84,7 @@ pub trait WeightInfo { fn seal_block_hash() -> Weight; fn seal_now() -> Weight; fn seal_weight_to_fee() -> Weight; + fn seal_call_data_load() -> Weight; fn seal_input(n: u32, ) -> Weight; fn seal_return(n: u32, ) -> Weight; fn seal_terminate(n: u32, ) -> Weight; @@ -133,8 +134,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `1594` - // Minimum execution time: 2_818_000 picoseconds. - Weight::from_parts(3_058_000, 1594) + // Minimum execution time: 2_874_000 picoseconds. + Weight::from_parts(3_131_000, 1594) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -144,10 +145,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `425 + k * (69 ±0)` // Estimated: `415 + k * (70 ±0)` - // Minimum execution time: 15_916_000 picoseconds. - Weight::from_parts(16_132_000, 415) - // Standard Error: 1_482 - .saturating_add(Weight::from_parts(1_185_583, 0).saturating_mul(k.into())) + // Minimum execution time: 16_079_000 picoseconds. + Weight::from_parts(5_747_743, 415) + // Standard Error: 1_130 + .saturating_add(Weight::from_parts(1_181_775, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -169,10 +170,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `c` is `[0, 262144]`. fn call_with_code_per_byte(_c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1502` - // Estimated: `7442` - // Minimum execution time: 88_115_000 picoseconds. - Weight::from_parts(92_075_651, 7442) + // Measured: `1536` + // Estimated: `7476` + // Minimum execution time: 94_513_000 picoseconds. + Weight::from_parts(99_111_938, 7476) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -194,14 +195,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 262144]`. fn instantiate_with_code(c: u32, i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `403` - // Estimated: `6326` - // Minimum execution time: 188_274_000 picoseconds. - Weight::from_parts(157_773_869, 6326) - // Standard Error: 11 - .saturating_add(Weight::from_parts(16, 0).saturating_mul(c.into())) - // Standard Error: 11 - .saturating_add(Weight::from_parts(4_464, 0).saturating_mul(i.into())) + // Measured: `416` + // Estimated: `6345` + // Minimum execution time: 195_917_000 picoseconds. + Weight::from_parts(175_835_928, 6345) + // Standard Error: 10 + .saturating_add(Weight::from_parts(10, 0).saturating_mul(c.into())) + // Standard Error: 10 + .saturating_add(Weight::from_parts(4_554, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -223,11 +224,11 @@ impl WeightInfo for SubstrateWeight { fn instantiate(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1296` - // Estimated: `4739` - // Minimum execution time: 158_616_000 picoseconds. - Weight::from_parts(134_329_076, 4739) - // Standard Error: 15 - .saturating_add(Weight::from_parts(4_358, 0).saturating_mul(i.into())) + // Estimated: `4753` + // Minimum execution time: 162_583_000 picoseconds. + Weight::from_parts(143_621_658, 4753) + // Standard Error: 16 + .saturating_add(Weight::from_parts(4_499, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -245,10 +246,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) fn call() -> Weight { // Proof Size summary in bytes: - // Measured: `1502` - // Estimated: `7442` - // Minimum execution time: 134_935_000 picoseconds. - Weight::from_parts(141_040_000, 7442) + // Measured: `1536` + // Estimated: `7476` + // Minimum execution time: 145_642_000 picoseconds. + Weight::from_parts(152_866_000, 7476) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -263,8 +264,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3574` - // Minimum execution time: 51_026_000 picoseconds. - Weight::from_parts(53_309_143, 3574) + // Minimum execution time: 51_664_000 picoseconds. + Weight::from_parts(53_863_257, 3574) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -278,8 +279,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `285` // Estimated: `3750` - // Minimum execution time: 44_338_000 picoseconds. - Weight::from_parts(45_398_000, 3750) + // Minimum execution time: 44_879_000 picoseconds. + Weight::from_parts(46_401_000, 3750) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -291,8 +292,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `529` // Estimated: `6469` - // Minimum execution time: 26_420_000 picoseconds. - Weight::from_parts(27_141_000, 6469) + // Minimum execution time: 27_833_000 picoseconds. + Weight::from_parts(29_013_000, 6469) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -304,8 +305,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3574` - // Minimum execution time: 39_735_000 picoseconds. - Weight::from_parts(41_260_000, 3574) + // Minimum execution time: 40_611_000 picoseconds. + Weight::from_parts(41_336_000, 3574) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -317,8 +318,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `56` // Estimated: `3521` - // Minimum execution time: 32_059_000 picoseconds. - Weight::from_parts(32_776_000, 3521) + // Minimum execution time: 32_576_000 picoseconds. + Weight::from_parts(33_300_000, 3521) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -330,8 +331,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 13_553_000 picoseconds. - Weight::from_parts(14_121_000, 3610) + // Minimum execution time: 13_978_000 picoseconds. + Weight::from_parts(14_573_000, 3610) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -339,24 +340,24 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_392_000 picoseconds. - Weight::from_parts(7_692_248, 0) - // Standard Error: 105 - .saturating_add(Weight::from_parts(180_036, 0).saturating_mul(r.into())) + // Minimum execution time: 6_877_000 picoseconds. + Weight::from_parts(8_471_206, 0) + // Standard Error: 226 + .saturating_add(Weight::from_parts(165_314, 0).saturating_mul(r.into())) } fn seal_caller() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 287_000 picoseconds. - Weight::from_parts(317_000, 0) + // Minimum execution time: 290_000 picoseconds. + Weight::from_parts(345_000, 0) } fn seal_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 235_000 picoseconds. - Weight::from_parts(288_000, 0) + // Minimum execution time: 243_000 picoseconds. + Weight::from_parts(303_000, 0) } /// Storage: `Revive::ContractInfoOf` (r:1 w:0) /// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`) @@ -364,8 +365,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `306` // Estimated: `3771` - // Minimum execution time: 10_101_000 picoseconds. - Weight::from_parts(10_420_000, 3771) + // Minimum execution time: 10_441_000 picoseconds. + Weight::from_parts(10_812_000, 3771) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Revive::ContractInfoOf` (r:1 w:0) @@ -374,16 +375,16 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `403` // Estimated: `3868` - // Minimum execution time: 11_422_000 picoseconds. - Weight::from_parts(11_829_000, 3868) + // Minimum execution time: 11_403_000 picoseconds. + Weight::from_parts(11_913_000, 3868) .saturating_add(T::DbWeight::get().reads(1_u64)) } fn seal_own_code_hash() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 247_000 picoseconds. - Weight::from_parts(282_000, 0) + // Minimum execution time: 259_000 picoseconds. + Weight::from_parts(306_000, 0) } /// Storage: `Revive::ContractInfoOf` (r:1 w:0) /// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`) @@ -393,44 +394,44 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `473` // Estimated: `3938` - // Minimum execution time: 14_856_000 picoseconds. - Weight::from_parts(15_528_000, 3938) + // Minimum execution time: 14_887_000 picoseconds. + Weight::from_parts(15_625_000, 3938) .saturating_add(T::DbWeight::get().reads(2_u64)) } fn seal_caller_is_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 303_000 picoseconds. - Weight::from_parts(361_000, 0) + // Minimum execution time: 315_000 picoseconds. + Weight::from_parts(389_000, 0) } fn seal_caller_is_root() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 253_000 picoseconds. - Weight::from_parts(287_000, 0) + // Minimum execution time: 294_000 picoseconds. + Weight::from_parts(322_000, 0) } fn seal_address() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 231_000 picoseconds. - Weight::from_parts(263_000, 0) + // Minimum execution time: 239_000 picoseconds. + Weight::from_parts(299_000, 0) } fn seal_weight_left() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` // Minimum execution time: 628_000 picoseconds. - Weight::from_parts(697_000, 0) + Weight::from_parts(703_000, 0) } fn seal_balance() -> Weight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `0` - // Minimum execution time: 4_531_000 picoseconds. - Weight::from_parts(4_726_000, 0) + // Minimum execution time: 4_816_000 picoseconds. + Weight::from_parts(5_078_000, 0) } /// Storage: `Revive::AddressSuffix` (r:1 w:0) /// Proof: `Revive::AddressSuffix` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `Measured`) @@ -440,8 +441,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `264` // Estimated: `3729` - // Minimum execution time: 8_787_000 picoseconds. - Weight::from_parts(9_175_000, 3729) + // Minimum execution time: 8_965_000 picoseconds. + Weight::from_parts(9_533_000, 3729) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: `Revive::ImmutableDataOf` (r:1 w:0) @@ -451,10 +452,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `238 + n * (1 ±0)` // Estimated: `3703 + n * (1 ±0)` - // Minimum execution time: 5_760_000 picoseconds. - Weight::from_parts(6_591_336, 3703) + // Minimum execution time: 6_174_000 picoseconds. + Weight::from_parts(6_755_842, 3703) // Standard Error: 4 - .saturating_add(Weight::from_parts(628, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(699, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -465,32 +466,32 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_971_000 picoseconds. - Weight::from_parts(2_206_252, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(529, 0).saturating_mul(n.into())) + // Minimum execution time: 1_977_000 picoseconds. + Weight::from_parts(2_175_653, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(633, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().writes(1_u64)) } fn seal_value_transferred() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 246_000 picoseconds. - Weight::from_parts(279_000, 0) + // Minimum execution time: 259_000 picoseconds. + Weight::from_parts(298_000, 0) } fn seal_minimum_balance() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 223_000 picoseconds. - Weight::from_parts(274_000, 0) + // Minimum execution time: 277_000 picoseconds. + Weight::from_parts(330_000, 0) } fn seal_block_number() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 213_000 picoseconds. - Weight::from_parts(270_000, 0) + // Minimum execution time: 260_000 picoseconds. + Weight::from_parts(295_000, 0) } /// Storage: `System::BlockHash` (r:1 w:0) /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `Measured`) @@ -498,43 +499,50 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `30` // Estimated: `3495` - // Minimum execution time: 3_502_000 picoseconds. - Weight::from_parts(3_777_000, 3495) + // Minimum execution time: 3_607_000 picoseconds. + Weight::from_parts(3_760_000, 3495) .saturating_add(T::DbWeight::get().reads(1_u64)) } fn seal_now() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 232_000 picoseconds. - Weight::from_parts(277_000, 0) + // Minimum execution time: 271_000 picoseconds. + Weight::from_parts(299_000, 0) } fn seal_weight_to_fee() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_293_000 picoseconds. - Weight::from_parts(1_426_000, 0) + // Minimum execution time: 1_320_000 picoseconds. + Weight::from_parts(1_406_000, 0) + } + fn seal_call_data_load() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 250_000 picoseconds. + Weight::from_parts(285_000, 0) } /// The range of component `n` is `[0, 262140]`. fn seal_input(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 449_000 picoseconds. - Weight::from_parts(446_268, 0) + // Minimum execution time: 411_000 picoseconds. + Weight::from_parts(514_738, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(113, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(148, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262140]`. fn seal_return(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 244_000 picoseconds. - Weight::from_parts(612_733, 0) + // Minimum execution time: 282_000 picoseconds. + Weight::from_parts(463_520, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(200, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(295, 0).saturating_mul(n.into())) } /// Storage: `Revive::AddressSuffix` (r:1 w:0) /// Proof: `Revive::AddressSuffix` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `Measured`) @@ -550,11 +558,11 @@ impl WeightInfo for SubstrateWeight { fn seal_terminate(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `324 + n * (88 ±0)` - // Estimated: `3789 + n * (2563 ±0)` - // Minimum execution time: 21_822_000 picoseconds. - Weight::from_parts(22_468_601, 3789) - // Standard Error: 7_303 - .saturating_add(Weight::from_parts(4_138_073, 0).saturating_mul(n.into())) + // Estimated: `3791 + n * (2563 ±0)` + // Minimum execution time: 22_960_000 picoseconds. + Weight::from_parts(23_432_764, 3791) + // Standard Error: 12_030 + .saturating_add(Weight::from_parts(4_292_055, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -567,22 +575,22 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_127_000 picoseconds. - Weight::from_parts(4_043_097, 0) - // Standard Error: 3_136 - .saturating_add(Weight::from_parts(209_603, 0).saturating_mul(t.into())) - // Standard Error: 28 - .saturating_add(Weight::from_parts(988, 0).saturating_mul(n.into())) + // Minimum execution time: 4_346_000 picoseconds. + Weight::from_parts(4_208_327, 0) + // Standard Error: 2_509 + .saturating_add(Weight::from_parts(194_145, 0).saturating_mul(t.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_084, 0).saturating_mul(n.into())) } /// The range of component `i` is `[0, 262144]`. fn seal_debug_message(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 276_000 picoseconds. - Weight::from_parts(1_111_301, 0) + // Minimum execution time: 360_000 picoseconds. + Weight::from_parts(374_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(706, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(816, 0).saturating_mul(i.into())) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -590,8 +598,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `744` // Estimated: `744` - // Minimum execution time: 7_869_000 picoseconds. - Weight::from_parts(8_190_000, 744) + // Minimum execution time: 8_066_000 picoseconds. + Weight::from_parts(8_425_000, 744) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -600,8 +608,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `10754` // Estimated: `10754` - // Minimum execution time: 42_793_000 picoseconds. - Weight::from_parts(43_861_000, 10754) + // Minimum execution time: 43_707_000 picoseconds. + Weight::from_parts(44_613_000, 10754) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -610,8 +618,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `744` // Estimated: `744` - // Minimum execution time: 8_753_000 picoseconds. - Weight::from_parts(9_235_000, 744) + // Minimum execution time: 9_101_000 picoseconds. + Weight::from_parts(9_425_000, 744) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -621,8 +629,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `10754` // Estimated: `10754` - // Minimum execution time: 44_446_000 picoseconds. - Weight::from_parts(45_586_000, 10754) + // Minimum execution time: 45_990_000 picoseconds. + Weight::from_parts(46_945_000, 10754) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -634,12 +642,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `248 + o * (1 ±0)` // Estimated: `247 + o * (1 ±0)` - // Minimum execution time: 9_214_000 picoseconds. - Weight::from_parts(9_888_060, 247) - // Standard Error: 41 - .saturating_add(Weight::from_parts(151, 0).saturating_mul(n.into())) - // Standard Error: 41 - .saturating_add(Weight::from_parts(315, 0).saturating_mul(o.into())) + // Minimum execution time: 9_229_000 picoseconds. + Weight::from_parts(10_039_961, 247) + // Standard Error: 39 + .saturating_add(Weight::from_parts(359, 0).saturating_mul(n.into())) + // Standard Error: 39 + .saturating_add(Weight::from_parts(424, 0).saturating_mul(o.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(o.into())) @@ -651,10 +659,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 8_647_000 picoseconds. - Weight::from_parts(9_553_009, 247) - // Standard Error: 48 - .saturating_add(Weight::from_parts(651, 0).saturating_mul(n.into())) + // Minimum execution time: 9_038_000 picoseconds. + Weight::from_parts(9_855_448, 247) + // Standard Error: 55 + .saturating_add(Weight::from_parts(544, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -666,10 +674,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 8_457_000 picoseconds. - Weight::from_parts(9_199_745, 247) - // Standard Error: 59 - .saturating_add(Weight::from_parts(1_562, 0).saturating_mul(n.into())) + // Minimum execution time: 8_533_000 picoseconds. + Weight::from_parts(9_485_405, 247) + // Standard Error: 60 + .saturating_add(Weight::from_parts(1_436, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -680,10 +688,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 8_025_000 picoseconds. - Weight::from_parts(8_700_911, 247) - // Standard Error: 49 - .saturating_add(Weight::from_parts(635, 0).saturating_mul(n.into())) + // Minimum execution time: 8_300_000 picoseconds. + Weight::from_parts(8_914_778, 247) + // Standard Error: 46 + .saturating_add(Weight::from_parts(774, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -694,10 +702,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 9_346_000 picoseconds. - Weight::from_parts(10_297_284, 247) - // Standard Error: 62 - .saturating_add(Weight::from_parts(1_396, 0).saturating_mul(n.into())) + // Minimum execution time: 9_384_000 picoseconds. + Weight::from_parts(10_500_656, 247) + // Standard Error: 64 + .saturating_add(Weight::from_parts(1_400, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -706,36 +714,36 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_428_000 picoseconds. - Weight::from_parts(1_517_000, 0) + // Minimum execution time: 1_478_000 picoseconds. + Weight::from_parts(1_625_000, 0) } fn set_transient_storage_full() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_868_000 picoseconds. - Weight::from_parts(1_942_000, 0) + // Minimum execution time: 1_842_000 picoseconds. + Weight::from_parts(1_969_000, 0) } fn get_transient_storage_empty() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_403_000 picoseconds. - Weight::from_parts(1_539_000, 0) + // Minimum execution time: 1_437_000 picoseconds. + Weight::from_parts(1_557_000, 0) } fn get_transient_storage_full() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_676_000 picoseconds. - Weight::from_parts(1_760_000, 0) + // Minimum execution time: 1_600_000 picoseconds. + Weight::from_parts(1_679_000, 0) } fn rollback_transient_storage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_119_000 picoseconds. - Weight::from_parts(1_205_000, 0) + // Minimum execution time: 1_114_000 picoseconds. + Weight::from_parts(1_191_000, 0) } /// The range of component `n` is `[0, 512]`. /// The range of component `o` is `[0, 512]`. @@ -743,50 +751,50 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_146_000 picoseconds. - Weight::from_parts(2_315_339, 0) - // Standard Error: 13 - .saturating_add(Weight::from_parts(327, 0).saturating_mul(n.into())) - // Standard Error: 13 - .saturating_add(Weight::from_parts(366, 0).saturating_mul(o.into())) + // Minimum execution time: 2_326_000 picoseconds. + Weight::from_parts(2_451_799, 0) + // Standard Error: 12 + .saturating_add(Weight::from_parts(391, 0).saturating_mul(n.into())) + // Standard Error: 12 + .saturating_add(Weight::from_parts(361, 0).saturating_mul(o.into())) } /// The range of component `n` is `[0, 512]`. fn seal_clear_transient_storage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_950_000 picoseconds. - Weight::from_parts(2_271_073, 0) - // Standard Error: 15 - .saturating_add(Weight::from_parts(373, 0).saturating_mul(n.into())) + // Minimum execution time: 1_951_000 picoseconds. + Weight::from_parts(2_353_245, 0) + // Standard Error: 16 + .saturating_add(Weight::from_parts(369, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 512]`. fn seal_get_transient_storage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_839_000 picoseconds. - Weight::from_parts(2_049_659, 0) + // Minimum execution time: 1_822_000 picoseconds. + Weight::from_parts(2_059_181, 0) // Standard Error: 14 - .saturating_add(Weight::from_parts(291, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(398, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 512]`. fn seal_contains_transient_storage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_716_000 picoseconds. - Weight::from_parts(1_893_932, 0) + // Minimum execution time: 1_697_000 picoseconds. + Weight::from_parts(1_905_887, 0) // Standard Error: 12 - .saturating_add(Weight::from_parts(172, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(215, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 512]`. fn seal_take_transient_storage(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_448_000 picoseconds. - Weight::from_parts(2_676_764, 0) + // Minimum execution time: 2_533_000 picoseconds. + Weight::from_parts(2_759_660, 0) } /// Storage: `Revive::AddressSuffix` (r:1 w:0) /// Proof: `Revive::AddressSuffix` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `Measured`) @@ -802,30 +810,32 @@ impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 262144]`. fn seal_call(t: u32, i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1294 + t * (242 ±0)` + // Measured: `1294 + t * (243 ±0)` // Estimated: `4759 + t * (2501 ±0)` - // Minimum execution time: 39_786_000 picoseconds. - Weight::from_parts(41_175_457, 4759) - // Standard Error: 45_251 - .saturating_add(Weight::from_parts(2_375_617, 0).saturating_mul(t.into())) + // Minimum execution time: 43_295_000 picoseconds. + Weight::from_parts(44_592_141, 4759) + // Standard Error: 60_598 + .saturating_add(Weight::from_parts(1_458_798, 0).saturating_mul(t.into())) // Standard Error: 0 - .saturating_add(Weight::from_parts(2, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(3, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2501).saturating_mul(t.into())) } + /// Storage: `Revive::ContractInfoOf` (r:1 w:0) + /// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`) /// Storage: `Revive::CodeInfoOf` (r:1 w:0) /// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`) /// Storage: `Revive::PristineCode` (r:1 w:0) /// Proof: `Revive::PristineCode` (`max_values`: None, `max_size`: Some(262180), added: 264655, mode: `Measured`) fn seal_delegate_call() -> Weight { // Proof Size summary in bytes: - // Measured: `1064` - // Estimated: `4529` - // Minimum execution time: 29_762_000 picoseconds. - Weight::from_parts(31_345_000, 4529) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `1237` + // Estimated: `4702` + // Minimum execution time: 37_787_000 picoseconds. + Weight::from_parts(38_510_000, 4702) + .saturating_add(T::DbWeight::get().reads(3_u64)) } /// Storage: `Revive::CodeInfoOf` (r:1 w:1) /// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`) @@ -838,12 +848,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 262144]`. fn seal_instantiate(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1310` - // Estimated: `4748` - // Minimum execution time: 117_791_000 picoseconds. - Weight::from_parts(105_413_907, 4748) - // Standard Error: 11 - .saturating_add(Weight::from_parts(4_038, 0).saturating_mul(i.into())) + // Measured: `1273` + // Estimated: `4736` + // Minimum execution time: 121_346_000 picoseconds. + Weight::from_parts(115_747_843, 4736) + // Standard Error: 10 + .saturating_add(Weight::from_parts(4_189, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -852,64 +862,64 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 638_000 picoseconds. - Weight::from_parts(4_703_710, 0) + // Minimum execution time: 696_000 picoseconds. + Weight::from_parts(3_319_775, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(1_349, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_500, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262144]`. fn seal_hash_keccak_256(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_085_000 picoseconds. - Weight::from_parts(3_630_716, 0) + // Minimum execution time: 1_070_000 picoseconds. + Weight::from_parts(4_463_019, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(3_567, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(3_689, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262144]`. fn seal_hash_blake2_256(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 643_000 picoseconds. - Weight::from_parts(3_733_026, 0) + // Minimum execution time: 617_000 picoseconds. + Weight::from_parts(3_175_243, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(1_492, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_617, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262144]`. fn seal_hash_blake2_128(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 653_000 picoseconds. - Weight::from_parts(4_627_285, 0) + // Minimum execution time: 616_000 picoseconds. + Weight::from_parts(3_420_409, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(1_478, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_623, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 261889]`. fn seal_sr25519_verify(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 45_786_000 picoseconds. - Weight::from_parts(36_383_470, 0) - // Standard Error: 10 - .saturating_add(Weight::from_parts(5_396, 0).saturating_mul(n.into())) + // Minimum execution time: 45_562_000 picoseconds. + Weight::from_parts(34_462_046, 0) + // Standard Error: 11 + .saturating_add(Weight::from_parts(5_259, 0).saturating_mul(n.into())) } fn seal_ecdsa_recover() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 48_140_000 picoseconds. - Weight::from_parts(49_720_000, 0) + // Minimum execution time: 49_472_000 picoseconds. + Weight::from_parts(50_517_000, 0) } fn seal_ecdsa_to_eth_address() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 12_565_000 picoseconds. - Weight::from_parts(12_704_000, 0) + // Minimum execution time: 12_716_000 picoseconds. + Weight::from_parts(12_812_000, 0) } /// Storage: `Revive::CodeInfoOf` (r:1 w:1) /// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`) @@ -917,8 +927,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `300` // Estimated: `3765` - // Minimum execution time: 17_208_000 picoseconds. - Weight::from_parts(18_307_000, 3765) + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_833_000, 3765) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -928,8 +938,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `338` // Estimated: `3803` - // Minimum execution time: 13_686_000 picoseconds. - Weight::from_parts(14_186_000, 3803) + // Minimum execution time: 14_523_000 picoseconds. + Weight::from_parts(14_812_000, 3803) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -939,8 +949,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `338` // Estimated: `3561` - // Minimum execution time: 12_381_000 picoseconds. - Weight::from_parts(13_208_000, 3561) + // Minimum execution time: 13_114_000 picoseconds. + Weight::from_parts(13_567_000, 3561) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -949,10 +959,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_118_000 picoseconds. - Weight::from_parts(9_813_514, 0) - // Standard Error: 40 - .saturating_add(Weight::from_parts(71_154, 0).saturating_mul(r.into())) + // Minimum execution time: 8_717_000 picoseconds. + Weight::from_parts(9_983_815, 0) + // Standard Error: 115 + .saturating_add(Weight::from_parts(72_253, 0).saturating_mul(r.into())) } } @@ -964,8 +974,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `1594` - // Minimum execution time: 2_818_000 picoseconds. - Weight::from_parts(3_058_000, 1594) + // Minimum execution time: 2_874_000 picoseconds. + Weight::from_parts(3_131_000, 1594) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -975,10 +985,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `425 + k * (69 ±0)` // Estimated: `415 + k * (70 ±0)` - // Minimum execution time: 15_916_000 picoseconds. - Weight::from_parts(16_132_000, 415) - // Standard Error: 1_482 - .saturating_add(Weight::from_parts(1_185_583, 0).saturating_mul(k.into())) + // Minimum execution time: 16_079_000 picoseconds. + Weight::from_parts(5_747_743, 415) + // Standard Error: 1_130 + .saturating_add(Weight::from_parts(1_181_775, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -1000,10 +1010,10 @@ impl WeightInfo for () { /// The range of component `c` is `[0, 262144]`. fn call_with_code_per_byte(_c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1502` - // Estimated: `7442` - // Minimum execution time: 88_115_000 picoseconds. - Weight::from_parts(92_075_651, 7442) + // Measured: `1536` + // Estimated: `7476` + // Minimum execution time: 94_513_000 picoseconds. + Weight::from_parts(99_111_938, 7476) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1025,14 +1035,14 @@ impl WeightInfo for () { /// The range of component `i` is `[0, 262144]`. fn instantiate_with_code(c: u32, i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `403` - // Estimated: `6326` - // Minimum execution time: 188_274_000 picoseconds. - Weight::from_parts(157_773_869, 6326) - // Standard Error: 11 - .saturating_add(Weight::from_parts(16, 0).saturating_mul(c.into())) - // Standard Error: 11 - .saturating_add(Weight::from_parts(4_464, 0).saturating_mul(i.into())) + // Measured: `416` + // Estimated: `6345` + // Minimum execution time: 195_917_000 picoseconds. + Weight::from_parts(175_835_928, 6345) + // Standard Error: 10 + .saturating_add(Weight::from_parts(10, 0).saturating_mul(c.into())) + // Standard Error: 10 + .saturating_add(Weight::from_parts(4_554, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1054,11 +1064,11 @@ impl WeightInfo for () { fn instantiate(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1296` - // Estimated: `4739` - // Minimum execution time: 158_616_000 picoseconds. - Weight::from_parts(134_329_076, 4739) - // Standard Error: 15 - .saturating_add(Weight::from_parts(4_358, 0).saturating_mul(i.into())) + // Estimated: `4753` + // Minimum execution time: 162_583_000 picoseconds. + Weight::from_parts(143_621_658, 4753) + // Standard Error: 16 + .saturating_add(Weight::from_parts(4_499, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -1076,10 +1086,10 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) fn call() -> Weight { // Proof Size summary in bytes: - // Measured: `1502` - // Estimated: `7442` - // Minimum execution time: 134_935_000 picoseconds. - Weight::from_parts(141_040_000, 7442) + // Measured: `1536` + // Estimated: `7476` + // Minimum execution time: 145_642_000 picoseconds. + Weight::from_parts(152_866_000, 7476) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1094,8 +1104,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3574` - // Minimum execution time: 51_026_000 picoseconds. - Weight::from_parts(53_309_143, 3574) + // Minimum execution time: 51_664_000 picoseconds. + Weight::from_parts(53_863_257, 3574) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1109,8 +1119,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `285` // Estimated: `3750` - // Minimum execution time: 44_338_000 picoseconds. - Weight::from_parts(45_398_000, 3750) + // Minimum execution time: 44_879_000 picoseconds. + Weight::from_parts(46_401_000, 3750) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1122,8 +1132,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `529` // Estimated: `6469` - // Minimum execution time: 26_420_000 picoseconds. - Weight::from_parts(27_141_000, 6469) + // Minimum execution time: 27_833_000 picoseconds. + Weight::from_parts(29_013_000, 6469) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1135,8 +1145,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3574` - // Minimum execution time: 39_735_000 picoseconds. - Weight::from_parts(41_260_000, 3574) + // Minimum execution time: 40_611_000 picoseconds. + Weight::from_parts(41_336_000, 3574) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1148,8 +1158,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `56` // Estimated: `3521` - // Minimum execution time: 32_059_000 picoseconds. - Weight::from_parts(32_776_000, 3521) + // Minimum execution time: 32_576_000 picoseconds. + Weight::from_parts(33_300_000, 3521) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1161,8 +1171,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 13_553_000 picoseconds. - Weight::from_parts(14_121_000, 3610) + // Minimum execution time: 13_978_000 picoseconds. + Weight::from_parts(14_573_000, 3610) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -1170,24 +1180,24 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_392_000 picoseconds. - Weight::from_parts(7_692_248, 0) - // Standard Error: 105 - .saturating_add(Weight::from_parts(180_036, 0).saturating_mul(r.into())) + // Minimum execution time: 6_877_000 picoseconds. + Weight::from_parts(8_471_206, 0) + // Standard Error: 226 + .saturating_add(Weight::from_parts(165_314, 0).saturating_mul(r.into())) } fn seal_caller() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 287_000 picoseconds. - Weight::from_parts(317_000, 0) + // Minimum execution time: 290_000 picoseconds. + Weight::from_parts(345_000, 0) } fn seal_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 235_000 picoseconds. - Weight::from_parts(288_000, 0) + // Minimum execution time: 243_000 picoseconds. + Weight::from_parts(303_000, 0) } /// Storage: `Revive::ContractInfoOf` (r:1 w:0) /// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`) @@ -1195,8 +1205,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `306` // Estimated: `3771` - // Minimum execution time: 10_101_000 picoseconds. - Weight::from_parts(10_420_000, 3771) + // Minimum execution time: 10_441_000 picoseconds. + Weight::from_parts(10_812_000, 3771) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Revive::ContractInfoOf` (r:1 w:0) @@ -1205,16 +1215,16 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `403` // Estimated: `3868` - // Minimum execution time: 11_422_000 picoseconds. - Weight::from_parts(11_829_000, 3868) + // Minimum execution time: 11_403_000 picoseconds. + Weight::from_parts(11_913_000, 3868) .saturating_add(RocksDbWeight::get().reads(1_u64)) } fn seal_own_code_hash() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 247_000 picoseconds. - Weight::from_parts(282_000, 0) + // Minimum execution time: 259_000 picoseconds. + Weight::from_parts(306_000, 0) } /// Storage: `Revive::ContractInfoOf` (r:1 w:0) /// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`) @@ -1224,44 +1234,44 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `473` // Estimated: `3938` - // Minimum execution time: 14_856_000 picoseconds. - Weight::from_parts(15_528_000, 3938) + // Minimum execution time: 14_887_000 picoseconds. + Weight::from_parts(15_625_000, 3938) .saturating_add(RocksDbWeight::get().reads(2_u64)) } fn seal_caller_is_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 303_000 picoseconds. - Weight::from_parts(361_000, 0) + // Minimum execution time: 315_000 picoseconds. + Weight::from_parts(389_000, 0) } fn seal_caller_is_root() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 253_000 picoseconds. - Weight::from_parts(287_000, 0) + // Minimum execution time: 294_000 picoseconds. + Weight::from_parts(322_000, 0) } fn seal_address() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 231_000 picoseconds. - Weight::from_parts(263_000, 0) + // Minimum execution time: 239_000 picoseconds. + Weight::from_parts(299_000, 0) } fn seal_weight_left() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` // Minimum execution time: 628_000 picoseconds. - Weight::from_parts(697_000, 0) + Weight::from_parts(703_000, 0) } fn seal_balance() -> Weight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `0` - // Minimum execution time: 4_531_000 picoseconds. - Weight::from_parts(4_726_000, 0) + // Minimum execution time: 4_816_000 picoseconds. + Weight::from_parts(5_078_000, 0) } /// Storage: `Revive::AddressSuffix` (r:1 w:0) /// Proof: `Revive::AddressSuffix` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `Measured`) @@ -1271,8 +1281,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `264` // Estimated: `3729` - // Minimum execution time: 8_787_000 picoseconds. - Weight::from_parts(9_175_000, 3729) + // Minimum execution time: 8_965_000 picoseconds. + Weight::from_parts(9_533_000, 3729) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: `Revive::ImmutableDataOf` (r:1 w:0) @@ -1282,10 +1292,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `238 + n * (1 ±0)` // Estimated: `3703 + n * (1 ±0)` - // Minimum execution time: 5_760_000 picoseconds. - Weight::from_parts(6_591_336, 3703) + // Minimum execution time: 6_174_000 picoseconds. + Weight::from_parts(6_755_842, 3703) // Standard Error: 4 - .saturating_add(Weight::from_parts(628, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(699, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1296,32 +1306,32 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_971_000 picoseconds. - Weight::from_parts(2_206_252, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(529, 0).saturating_mul(n.into())) + // Minimum execution time: 1_977_000 picoseconds. + Weight::from_parts(2_175_653, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(633, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } fn seal_value_transferred() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 246_000 picoseconds. - Weight::from_parts(279_000, 0) + // Minimum execution time: 259_000 picoseconds. + Weight::from_parts(298_000, 0) } fn seal_minimum_balance() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 223_000 picoseconds. - Weight::from_parts(274_000, 0) + // Minimum execution time: 277_000 picoseconds. + Weight::from_parts(330_000, 0) } fn seal_block_number() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 213_000 picoseconds. - Weight::from_parts(270_000, 0) + // Minimum execution time: 260_000 picoseconds. + Weight::from_parts(295_000, 0) } /// Storage: `System::BlockHash` (r:1 w:0) /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `Measured`) @@ -1329,43 +1339,50 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `30` // Estimated: `3495` - // Minimum execution time: 3_502_000 picoseconds. - Weight::from_parts(3_777_000, 3495) + // Minimum execution time: 3_607_000 picoseconds. + Weight::from_parts(3_760_000, 3495) .saturating_add(RocksDbWeight::get().reads(1_u64)) } fn seal_now() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 232_000 picoseconds. - Weight::from_parts(277_000, 0) + // Minimum execution time: 271_000 picoseconds. + Weight::from_parts(299_000, 0) } fn seal_weight_to_fee() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_293_000 picoseconds. - Weight::from_parts(1_426_000, 0) + // Minimum execution time: 1_320_000 picoseconds. + Weight::from_parts(1_406_000, 0) + } + fn seal_call_data_load() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 250_000 picoseconds. + Weight::from_parts(285_000, 0) } /// The range of component `n` is `[0, 262140]`. fn seal_input(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 449_000 picoseconds. - Weight::from_parts(446_268, 0) + // Minimum execution time: 411_000 picoseconds. + Weight::from_parts(514_738, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(113, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(148, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262140]`. fn seal_return(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 244_000 picoseconds. - Weight::from_parts(612_733, 0) + // Minimum execution time: 282_000 picoseconds. + Weight::from_parts(463_520, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(200, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(295, 0).saturating_mul(n.into())) } /// Storage: `Revive::AddressSuffix` (r:1 w:0) /// Proof: `Revive::AddressSuffix` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `Measured`) @@ -1381,11 +1398,11 @@ impl WeightInfo for () { fn seal_terminate(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `324 + n * (88 ±0)` - // Estimated: `3789 + n * (2563 ±0)` - // Minimum execution time: 21_822_000 picoseconds. - Weight::from_parts(22_468_601, 3789) - // Standard Error: 7_303 - .saturating_add(Weight::from_parts(4_138_073, 0).saturating_mul(n.into())) + // Estimated: `3791 + n * (2563 ±0)` + // Minimum execution time: 22_960_000 picoseconds. + Weight::from_parts(23_432_764, 3791) + // Standard Error: 12_030 + .saturating_add(Weight::from_parts(4_292_055, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -1398,22 +1415,22 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_127_000 picoseconds. - Weight::from_parts(4_043_097, 0) - // Standard Error: 3_136 - .saturating_add(Weight::from_parts(209_603, 0).saturating_mul(t.into())) - // Standard Error: 28 - .saturating_add(Weight::from_parts(988, 0).saturating_mul(n.into())) + // Minimum execution time: 4_346_000 picoseconds. + Weight::from_parts(4_208_327, 0) + // Standard Error: 2_509 + .saturating_add(Weight::from_parts(194_145, 0).saturating_mul(t.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_084, 0).saturating_mul(n.into())) } /// The range of component `i` is `[0, 262144]`. fn seal_debug_message(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 276_000 picoseconds. - Weight::from_parts(1_111_301, 0) + // Minimum execution time: 360_000 picoseconds. + Weight::from_parts(374_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(706, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(816, 0).saturating_mul(i.into())) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -1421,8 +1438,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `744` // Estimated: `744` - // Minimum execution time: 7_869_000 picoseconds. - Weight::from_parts(8_190_000, 744) + // Minimum execution time: 8_066_000 picoseconds. + Weight::from_parts(8_425_000, 744) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -1431,8 +1448,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `10754` // Estimated: `10754` - // Minimum execution time: 42_793_000 picoseconds. - Weight::from_parts(43_861_000, 10754) + // Minimum execution time: 43_707_000 picoseconds. + Weight::from_parts(44_613_000, 10754) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -1441,8 +1458,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `744` // Estimated: `744` - // Minimum execution time: 8_753_000 picoseconds. - Weight::from_parts(9_235_000, 744) + // Minimum execution time: 9_101_000 picoseconds. + Weight::from_parts(9_425_000, 744) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1452,8 +1469,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `10754` // Estimated: `10754` - // Minimum execution time: 44_446_000 picoseconds. - Weight::from_parts(45_586_000, 10754) + // Minimum execution time: 45_990_000 picoseconds. + Weight::from_parts(46_945_000, 10754) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1465,12 +1482,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + o * (1 ±0)` // Estimated: `247 + o * (1 ±0)` - // Minimum execution time: 9_214_000 picoseconds. - Weight::from_parts(9_888_060, 247) - // Standard Error: 41 - .saturating_add(Weight::from_parts(151, 0).saturating_mul(n.into())) - // Standard Error: 41 - .saturating_add(Weight::from_parts(315, 0).saturating_mul(o.into())) + // Minimum execution time: 9_229_000 picoseconds. + Weight::from_parts(10_039_961, 247) + // Standard Error: 39 + .saturating_add(Weight::from_parts(359, 0).saturating_mul(n.into())) + // Standard Error: 39 + .saturating_add(Weight::from_parts(424, 0).saturating_mul(o.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(o.into())) @@ -1482,10 +1499,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 8_647_000 picoseconds. - Weight::from_parts(9_553_009, 247) - // Standard Error: 48 - .saturating_add(Weight::from_parts(651, 0).saturating_mul(n.into())) + // Minimum execution time: 9_038_000 picoseconds. + Weight::from_parts(9_855_448, 247) + // Standard Error: 55 + .saturating_add(Weight::from_parts(544, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1497,10 +1514,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 8_457_000 picoseconds. - Weight::from_parts(9_199_745, 247) - // Standard Error: 59 - .saturating_add(Weight::from_parts(1_562, 0).saturating_mul(n.into())) + // Minimum execution time: 8_533_000 picoseconds. + Weight::from_parts(9_485_405, 247) + // Standard Error: 60 + .saturating_add(Weight::from_parts(1_436, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1511,10 +1528,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 8_025_000 picoseconds. - Weight::from_parts(8_700_911, 247) - // Standard Error: 49 - .saturating_add(Weight::from_parts(635, 0).saturating_mul(n.into())) + // Minimum execution time: 8_300_000 picoseconds. + Weight::from_parts(8_914_778, 247) + // Standard Error: 46 + .saturating_add(Weight::from_parts(774, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1525,10 +1542,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `247 + n * (1 ±0)` - // Minimum execution time: 9_346_000 picoseconds. - Weight::from_parts(10_297_284, 247) - // Standard Error: 62 - .saturating_add(Weight::from_parts(1_396, 0).saturating_mul(n.into())) + // Minimum execution time: 9_384_000 picoseconds. + Weight::from_parts(10_500_656, 247) + // Standard Error: 64 + .saturating_add(Weight::from_parts(1_400, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1537,36 +1554,36 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_428_000 picoseconds. - Weight::from_parts(1_517_000, 0) + // Minimum execution time: 1_478_000 picoseconds. + Weight::from_parts(1_625_000, 0) } fn set_transient_storage_full() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_868_000 picoseconds. - Weight::from_parts(1_942_000, 0) + // Minimum execution time: 1_842_000 picoseconds. + Weight::from_parts(1_969_000, 0) } fn get_transient_storage_empty() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_403_000 picoseconds. - Weight::from_parts(1_539_000, 0) + // Minimum execution time: 1_437_000 picoseconds. + Weight::from_parts(1_557_000, 0) } fn get_transient_storage_full() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_676_000 picoseconds. - Weight::from_parts(1_760_000, 0) + // Minimum execution time: 1_600_000 picoseconds. + Weight::from_parts(1_679_000, 0) } fn rollback_transient_storage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_119_000 picoseconds. - Weight::from_parts(1_205_000, 0) + // Minimum execution time: 1_114_000 picoseconds. + Weight::from_parts(1_191_000, 0) } /// The range of component `n` is `[0, 512]`. /// The range of component `o` is `[0, 512]`. @@ -1574,50 +1591,50 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_146_000 picoseconds. - Weight::from_parts(2_315_339, 0) - // Standard Error: 13 - .saturating_add(Weight::from_parts(327, 0).saturating_mul(n.into())) - // Standard Error: 13 - .saturating_add(Weight::from_parts(366, 0).saturating_mul(o.into())) + // Minimum execution time: 2_326_000 picoseconds. + Weight::from_parts(2_451_799, 0) + // Standard Error: 12 + .saturating_add(Weight::from_parts(391, 0).saturating_mul(n.into())) + // Standard Error: 12 + .saturating_add(Weight::from_parts(361, 0).saturating_mul(o.into())) } /// The range of component `n` is `[0, 512]`. fn seal_clear_transient_storage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_950_000 picoseconds. - Weight::from_parts(2_271_073, 0) - // Standard Error: 15 - .saturating_add(Weight::from_parts(373, 0).saturating_mul(n.into())) + // Minimum execution time: 1_951_000 picoseconds. + Weight::from_parts(2_353_245, 0) + // Standard Error: 16 + .saturating_add(Weight::from_parts(369, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 512]`. fn seal_get_transient_storage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_839_000 picoseconds. - Weight::from_parts(2_049_659, 0) + // Minimum execution time: 1_822_000 picoseconds. + Weight::from_parts(2_059_181, 0) // Standard Error: 14 - .saturating_add(Weight::from_parts(291, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(398, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 512]`. fn seal_contains_transient_storage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_716_000 picoseconds. - Weight::from_parts(1_893_932, 0) + // Minimum execution time: 1_697_000 picoseconds. + Weight::from_parts(1_905_887, 0) // Standard Error: 12 - .saturating_add(Weight::from_parts(172, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(215, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 512]`. fn seal_take_transient_storage(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_448_000 picoseconds. - Weight::from_parts(2_676_764, 0) + // Minimum execution time: 2_533_000 picoseconds. + Weight::from_parts(2_759_660, 0) } /// Storage: `Revive::AddressSuffix` (r:1 w:0) /// Proof: `Revive::AddressSuffix` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `Measured`) @@ -1633,30 +1650,32 @@ impl WeightInfo for () { /// The range of component `i` is `[0, 262144]`. fn seal_call(t: u32, i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1294 + t * (242 ±0)` + // Measured: `1294 + t * (243 ±0)` // Estimated: `4759 + t * (2501 ±0)` - // Minimum execution time: 39_786_000 picoseconds. - Weight::from_parts(41_175_457, 4759) - // Standard Error: 45_251 - .saturating_add(Weight::from_parts(2_375_617, 0).saturating_mul(t.into())) + // Minimum execution time: 43_295_000 picoseconds. + Weight::from_parts(44_592_141, 4759) + // Standard Error: 60_598 + .saturating_add(Weight::from_parts(1_458_798, 0).saturating_mul(t.into())) // Standard Error: 0 - .saturating_add(Weight::from_parts(2, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(3, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2501).saturating_mul(t.into())) } + /// Storage: `Revive::ContractInfoOf` (r:1 w:0) + /// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`) /// Storage: `Revive::CodeInfoOf` (r:1 w:0) /// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`) /// Storage: `Revive::PristineCode` (r:1 w:0) /// Proof: `Revive::PristineCode` (`max_values`: None, `max_size`: Some(262180), added: 264655, mode: `Measured`) fn seal_delegate_call() -> Weight { // Proof Size summary in bytes: - // Measured: `1064` - // Estimated: `4529` - // Minimum execution time: 29_762_000 picoseconds. - Weight::from_parts(31_345_000, 4529) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `1237` + // Estimated: `4702` + // Minimum execution time: 37_787_000 picoseconds. + Weight::from_parts(38_510_000, 4702) + .saturating_add(RocksDbWeight::get().reads(3_u64)) } /// Storage: `Revive::CodeInfoOf` (r:1 w:1) /// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`) @@ -1669,12 +1688,12 @@ impl WeightInfo for () { /// The range of component `i` is `[0, 262144]`. fn seal_instantiate(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1310` - // Estimated: `4748` - // Minimum execution time: 117_791_000 picoseconds. - Weight::from_parts(105_413_907, 4748) - // Standard Error: 11 - .saturating_add(Weight::from_parts(4_038, 0).saturating_mul(i.into())) + // Measured: `1273` + // Estimated: `4736` + // Minimum execution time: 121_346_000 picoseconds. + Weight::from_parts(115_747_843, 4736) + // Standard Error: 10 + .saturating_add(Weight::from_parts(4_189, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1683,64 +1702,64 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 638_000 picoseconds. - Weight::from_parts(4_703_710, 0) + // Minimum execution time: 696_000 picoseconds. + Weight::from_parts(3_319_775, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(1_349, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_500, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262144]`. fn seal_hash_keccak_256(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_085_000 picoseconds. - Weight::from_parts(3_630_716, 0) + // Minimum execution time: 1_070_000 picoseconds. + Weight::from_parts(4_463_019, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(3_567, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(3_689, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262144]`. fn seal_hash_blake2_256(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 643_000 picoseconds. - Weight::from_parts(3_733_026, 0) + // Minimum execution time: 617_000 picoseconds. + Weight::from_parts(3_175_243, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(1_492, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_617, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 262144]`. fn seal_hash_blake2_128(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 653_000 picoseconds. - Weight::from_parts(4_627_285, 0) + // Minimum execution time: 616_000 picoseconds. + Weight::from_parts(3_420_409, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(1_478, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_623, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 261889]`. fn seal_sr25519_verify(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 45_786_000 picoseconds. - Weight::from_parts(36_383_470, 0) - // Standard Error: 10 - .saturating_add(Weight::from_parts(5_396, 0).saturating_mul(n.into())) + // Minimum execution time: 45_562_000 picoseconds. + Weight::from_parts(34_462_046, 0) + // Standard Error: 11 + .saturating_add(Weight::from_parts(5_259, 0).saturating_mul(n.into())) } fn seal_ecdsa_recover() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 48_140_000 picoseconds. - Weight::from_parts(49_720_000, 0) + // Minimum execution time: 49_472_000 picoseconds. + Weight::from_parts(50_517_000, 0) } fn seal_ecdsa_to_eth_address() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 12_565_000 picoseconds. - Weight::from_parts(12_704_000, 0) + // Minimum execution time: 12_716_000 picoseconds. + Weight::from_parts(12_812_000, 0) } /// Storage: `Revive::CodeInfoOf` (r:1 w:1) /// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`) @@ -1748,8 +1767,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `300` // Estimated: `3765` - // Minimum execution time: 17_208_000 picoseconds. - Weight::from_parts(18_307_000, 3765) + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_833_000, 3765) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1759,8 +1778,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `338` // Estimated: `3803` - // Minimum execution time: 13_686_000 picoseconds. - Weight::from_parts(14_186_000, 3803) + // Minimum execution time: 14_523_000 picoseconds. + Weight::from_parts(14_812_000, 3803) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1770,8 +1789,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `338` // Estimated: `3561` - // Minimum execution time: 12_381_000 picoseconds. - Weight::from_parts(13_208_000, 3561) + // Minimum execution time: 13_114_000 picoseconds. + Weight::from_parts(13_567_000, 3561) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1780,9 +1799,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_118_000 picoseconds. - Weight::from_parts(9_813_514, 0) - // Standard Error: 40 - .saturating_add(Weight::from_parts(71_154, 0).saturating_mul(r.into())) + // Minimum execution time: 8_717_000 picoseconds. + Weight::from_parts(9_983_815, 0) + // Standard Error: 115 + .saturating_add(Weight::from_parts(72_253, 0).saturating_mul(r.into())) } } diff --git a/substrate/frame/revive/uapi/src/host.rs b/substrate/frame/revive/uapi/src/host.rs index 400a12879363..c6b9ef9d4fa2 100644 --- a/substrate/frame/revive/uapi/src/host.rs +++ b/substrate/frame/revive/uapi/src/host.rs @@ -436,6 +436,21 @@ pub trait HostFn: private::Sealed { /// - `output`: A reference to the output data buffer to write the input data. fn input(output: &mut &mut [u8]); + /// Stores the U256 value at given `offset` from the input passed by the caller + /// into the supplied buffer. + /// + /// # Note + /// - If `offset` is out of bounds, a value of zero will be returned. + /// - If `offset` is in bounds but there is not enough call data, the available data + /// is right-padded in order to fill a whole U256 value. + /// - The data written to `output` is a little endian U256 integer value. + /// + /// # Parameters + /// + /// - `output`: A reference to the fixed output data buffer to write the value. + /// - `offset`: The offset (index) into the call data. + fn call_data_load(output: &mut [u8; 32], offset: u32); + /// Instantiate a contract with the specified code hash. /// /// This function creates an account and executes the constructor defined in the code specified diff --git a/substrate/frame/revive/uapi/src/host/riscv64.rs b/substrate/frame/revive/uapi/src/host/riscv64.rs index b76320718a69..a208fef7055a 100644 --- a/substrate/frame/revive/uapi/src/host/riscv64.rs +++ b/substrate/frame/revive/uapi/src/host/riscv64.rs @@ -63,6 +63,7 @@ mod sys { pub fn instantiate(ptr: *const u8) -> ReturnCode; pub fn terminate(beneficiary_ptr: *const u8); pub fn input(out_ptr: *mut u8, out_len_ptr: *mut u32); + pub fn call_data_load(out_ptr: *mut u8, offset: u32); pub fn seal_return(flags: u32, data_ptr: *const u8, data_len: u32); pub fn caller(out_ptr: *mut u8); pub fn origin(out_ptr: *mut u8); @@ -449,6 +450,10 @@ impl HostFn for HostFnImpl { extract_from_slice(output, output_len as usize); } + fn call_data_load(out_ptr: &mut [u8; 32], offset: u32) { + unsafe { sys::call_data_load(out_ptr.as_mut_ptr(), offset) }; + } + fn return_value(flags: ReturnFlags, return_value: &[u8]) -> ! { unsafe { sys::seal_return(flags.bits(), return_value.as_ptr(), return_value.len() as u32) } panic!("seal_return does not return"); From 7cc5cdd0d98ae3466dc33b339197c169cf241fc0 Mon Sep 17 00:00:00 2001 From: Iulian Barbu <14218860+iulianbarbu@users.noreply.github.com> Date: Thu, 12 Dec 2024 15:18:22 +0200 Subject: [PATCH 46/51] omni-node: add metadata checks for runtime/parachain compatibility (#6450) # Description Get runtime's metadata, parse it and verify pallets list for a pallet named `ParachainSystem` (for now), and block number to be the same for both node and runtime. Ideally we'll add other pallets checks too, at least a small set of pallets we think right away as mandatory for parachain compatibility. Closes: #5565 ## Integration Runtime devs must be made aware that to be fully compatible with Omni Node, certain naming conventions should be respected when defining pallets (e.g we verify parachain-system pallet existence by searching for a pallet with `name` `ParachainSystem` in runtime's metadata). Not finding such a pallet will not influence the functionality yet, but by doing these checks we could provide useful feedback for runtimes that are clearly not implementing what's required for full parachain compatibility with Omni Node. ## Review Notes - [x] parachain system check - [x] check frame_system's metadata to ensure the block number in there is the same as the one in the node side - [x] add tests for the previous checking logic - [x] update omni node polkadot-sdk docs to make these conventions visible. - [ ] add more pallets checks? --------- Signed-off-by: Iulian Barbu Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> --- Cargo.lock | 29 ++ Cargo.toml | 3 + cumulus/polkadot-omni-node/lib/Cargo.toml | 16 +- .../lib/src/common/runtime.rs | 147 +++++++++- .../polkadot-omni-node/lib/src/common/spec.rs | 272 +++++++++--------- docs/sdk/src/reference_docs/omni_node.rs | 16 ++ prdoc/pr_6450.prdoc | 21 ++ substrate/client/runtime-utilities/Cargo.toml | 36 +++ .../client/runtime-utilities/src/error.rs | 35 +++ .../runtime-utilities/src/lib.rs} | 88 +++--- .../utils/frame/benchmarking-cli/Cargo.toml | 1 + .../utils/frame/benchmarking-cli/src/lib.rs | 1 - .../benchmarking-cli/src/overhead/command.rs | 28 +- .../benchmarking-cli/src/overhead/mod.rs | 1 - umbrella/Cargo.toml | 7 +- umbrella/src/lib.rs | 4 + 16 files changed, 510 insertions(+), 195 deletions(-) create mode 100644 prdoc/pr_6450.prdoc create mode 100644 substrate/client/runtime-utilities/Cargo.toml create mode 100644 substrate/client/runtime-utilities/src/error.rs rename substrate/{utils/frame/benchmarking-cli/src/overhead/runtime_utilities.rs => client/runtime-utilities/src/lib.rs} (60%) diff --git a/Cargo.lock b/Cargo.lock index 9b023a38cb2a..afd7507e7ab9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7172,6 +7172,7 @@ dependencies = [ "sc-client-db", "sc-executor 0.32.0", "sc-executor-common 0.29.0", + "sc-runtime-utilities", "sc-service", "sc-sysinfo", "serde", @@ -18095,6 +18096,7 @@ dependencies = [ "cumulus-primitives-aura 0.7.0", "cumulus-primitives-core 0.7.0", "cumulus-relay-chain-interface", + "cumulus-test-runtime", "docify", "frame-benchmarking 28.0.0", "frame-benchmarking-cli", @@ -18123,29 +18125,36 @@ dependencies = [ "sc-executor 0.32.0", "sc-network", "sc-rpc", + "sc-runtime-utilities", "sc-service", "sc-sysinfo", "sc-telemetry", "sc-tracing", "sc-transaction-pool", + "scale-info", "serde", "serde_json", "sp-api 26.0.0", "sp-block-builder 26.0.0", "sp-consensus-aura 0.32.0", "sp-core 28.0.0", + "sp-crypto-hashing 0.1.0", "sp-genesis-builder 0.8.0", "sp-inherents 26.0.0", + "sp-io 30.0.0", "sp-keystore 0.34.0", "sp-runtime 31.0.1", "sp-session 27.0.0", + "sp-storage 19.0.0", "sp-timestamp 26.0.0", "sp-transaction-pool 26.0.0", "sp-version 29.0.0", + "sp-wasm-interface 20.0.0", "sp-weights 27.0.0", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", "substrate-state-trie-migration-rpc", + "subxt-metadata", "tokio", "wait-timeout", ] @@ -18883,6 +18892,7 @@ dependencies = [ "sc-rpc-api", "sc-rpc-server", "sc-rpc-spec-v2", + "sc-runtime-utilities", "sc-service", "sc-state-db", "sc-statement-store", @@ -23505,6 +23515,25 @@ dependencies = [ "substrate-wasm-builder 17.0.0", ] +[[package]] +name = "sc-runtime-utilities" +version = "0.1.0" +dependencies = [ + "cumulus-primitives-proof-size-hostfunction 0.2.0", + "cumulus-test-runtime", + "parity-scale-codec", + "sc-executor 0.32.0", + "sc-executor-common 0.29.0", + "sp-core 28.0.0", + "sp-crypto-hashing 0.1.0", + "sp-io 30.0.0", + "sp-state-machine 0.35.0", + "sp-version 29.0.0", + "sp-wasm-interface 20.0.0", + "subxt", + "thiserror", +] + [[package]] name = "sc-service" version = "0.35.0" diff --git a/Cargo.toml b/Cargo.toml index e76af28ecc31..089ba3cef208 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -293,6 +293,7 @@ members = [ "substrate/client/rpc-api", "substrate/client/rpc-servers", "substrate/client/rpc-spec-v2", + "substrate/client/runtime-utilities", "substrate/client/service", "substrate/client/service/test", "substrate/client/state-db", @@ -1183,6 +1184,7 @@ sc-rpc-api = { path = "substrate/client/rpc-api", default-features = false } sc-rpc-server = { path = "substrate/client/rpc-servers", default-features = false } sc-rpc-spec-v2 = { path = "substrate/client/rpc-spec-v2", default-features = false } sc-runtime-test = { path = "substrate/client/executor/runtime-test" } +sc-runtime-utilities = { path = "substrate/client/runtime-utilities", default-features = true } sc-service = { path = "substrate/client/service", default-features = false } sc-service-test = { path = "substrate/client/service/test" } sc-state-db = { path = "substrate/client/state-db", default-features = false } @@ -1316,6 +1318,7 @@ substrate-test-runtime-transaction-pool = { path = "substrate/test-utils/runtime substrate-test-utils = { path = "substrate/test-utils" } substrate-wasm-builder = { path = "substrate/utils/wasm-builder", default-features = false } subxt = { version = "0.38", default-features = false } +subxt-metadata = { version = "0.38.0", default-features = false } subxt-signer = { version = "0.38" } syn = { version = "2.0.87" } sysinfo = { version = "0.30" } diff --git a/cumulus/polkadot-omni-node/lib/Cargo.toml b/cumulus/polkadot-omni-node/lib/Cargo.toml index cca4ac3b2b69..4d003a69456e 100644 --- a/cumulus/polkadot-omni-node/lib/Cargo.toml +++ b/cumulus/polkadot-omni-node/lib/Cargo.toml @@ -28,10 +28,13 @@ docify = { workspace = true } # Local jsonrpsee = { features = ["server"], workspace = true } parachains-common = { workspace = true, default-features = true } +scale-info = { workspace = true } +subxt-metadata = { workspace = true, default-features = true } # Substrate frame-benchmarking = { optional = true, workspace = true, default-features = true } frame-benchmarking-cli = { workspace = true, default-features = true } +sp-crypto-hashing = { workspace = true } sp-runtime = { workspace = true } sp-core = { workspace = true, default-features = true } sp-session = { workspace = true, default-features = true } @@ -57,12 +60,16 @@ sc-rpc = { workspace = true, default-features = true } sp-version = { workspace = true, default-features = true } sp-weights = { workspace = true, default-features = true } sc-tracing = { workspace = true, default-features = true } +sc-runtime-utilities = { workspace = true, default-features = true } +sp-storage = { workspace = true, default-features = true } frame-system-rpc-runtime-api = { workspace = true, default-features = true } pallet-transaction-payment = { workspace = true, default-features = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true, default-features = true } sp-inherents = { workspace = true, default-features = true } sp-api = { workspace = true, default-features = true } sp-consensus-aura = { workspace = true, default-features = true } +sp-io = { workspace = true, default-features = true } +sp-wasm-interface = { workspace = true, default-features = true } sc-consensus-manual-seal = { workspace = true, default-features = true } sc-sysinfo = { workspace = true, default-features = true } prometheus-endpoint = { workspace = true, default-features = true } @@ -93,15 +100,12 @@ assert_cmd = { workspace = true } nix = { features = ["signal"], workspace = true } tokio = { version = "1.32.0", features = ["macros", "parking_lot", "time"] } wait-timeout = { workspace = true } +cumulus-test-runtime = { workspace = true } [features] default = [] -rococo-native = [ - "polkadot-cli/rococo-native", -] -westend-native = [ - "polkadot-cli/westend-native", -] +rococo-native = ["polkadot-cli/rococo-native"] +westend-native = ["polkadot-cli/westend-native"] runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", "frame-benchmarking-cli/runtime-benchmarks", diff --git a/cumulus/polkadot-omni-node/lib/src/common/runtime.rs b/cumulus/polkadot-omni-node/lib/src/common/runtime.rs index 509d13b9d7a2..2a95f41495a6 100644 --- a/cumulus/polkadot-omni-node/lib/src/common/runtime.rs +++ b/cumulus/polkadot-omni-node/lib/src/common/runtime.rs @@ -16,7 +16,19 @@ //! Runtime parameters. +use codec::Decode; +use cumulus_client_service::ParachainHostFunctions; use sc_chain_spec::ChainSpec; +use sc_executor::WasmExecutor; +use sc_runtime_utilities::fetch_latest_metadata_from_code_blob; +use scale_info::{form::PortableForm, TypeDef, TypeDefPrimitive}; +use std::fmt::Display; +use subxt_metadata::{Metadata, StorageEntryType}; + +/// Expected parachain system pallet runtime type name. +pub const DEFAULT_PARACHAIN_SYSTEM_PALLET_NAME: &str = "ParachainSystem"; +/// Expected frame system pallet runtime type name. +pub const DEFAULT_FRAME_SYSTEM_PALLET_NAME: &str = "System"; /// The Aura ID used by the Aura consensus #[derive(PartialEq)] @@ -35,7 +47,7 @@ pub enum Consensus { } /// The choice of block number for the parachain omni-node. -#[derive(PartialEq)] +#[derive(PartialEq, Debug)] pub enum BlockNumber { /// u32 U32, @@ -43,6 +55,34 @@ pub enum BlockNumber { U64, } +impl Display for BlockNumber { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BlockNumber::U32 => write!(f, "u32"), + BlockNumber::U64 => write!(f, "u64"), + } + } +} + +impl Into for BlockNumber { + fn into(self) -> TypeDefPrimitive { + match self { + BlockNumber::U32 => TypeDefPrimitive::U32, + BlockNumber::U64 => TypeDefPrimitive::U64, + } + } +} + +impl BlockNumber { + fn from_type_def(type_def: &TypeDef) -> Option { + match type_def { + TypeDef::Primitive(TypeDefPrimitive::U32) => Some(BlockNumber::U32), + TypeDef::Primitive(TypeDefPrimitive::U64) => Some(BlockNumber::U64), + _ => None, + } + } +} + /// Helper enum listing the supported Runtime types #[derive(PartialEq)] pub enum Runtime { @@ -62,7 +102,108 @@ pub trait RuntimeResolver { pub struct DefaultRuntimeResolver; impl RuntimeResolver for DefaultRuntimeResolver { - fn runtime(&self, _chain_spec: &dyn ChainSpec) -> sc_cli::Result { - Ok(Runtime::Omni(BlockNumber::U32, Consensus::Aura(AuraConsensusId::Sr25519))) + fn runtime(&self, chain_spec: &dyn ChainSpec) -> sc_cli::Result { + let metadata_inspector = MetadataInspector::new(chain_spec)?; + let block_number = match metadata_inspector.block_number() { + Some(inner) => inner, + None => { + log::warn!( + r#"⚠️ There isn't a runtime type named `System`, corresponding to the `frame-system` + pallet (https://docs.rs/frame-system/latest/frame_system/). Please check Omni Node docs for runtime conventions: + https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html#runtime-conventions. + Note: We'll assume a block number size of `u32`."# + ); + BlockNumber::U32 + }, + }; + + if !metadata_inspector.pallet_exists(DEFAULT_PARACHAIN_SYSTEM_PALLET_NAME) { + log::warn!( + r#"⚠️ The parachain system pallet (https://docs.rs/crate/cumulus-pallet-parachain-system/latest) is + missing from the runtime’s metadata. Please check Omni Node docs for runtime conventions: + https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html#runtime-conventions."# + ); + } + + Ok(Runtime::Omni(block_number, Consensus::Aura(AuraConsensusId::Sr25519))) + } +} + +struct MetadataInspector(Metadata); + +impl MetadataInspector { + fn new(chain_spec: &dyn ChainSpec) -> Result { + MetadataInspector::fetch_metadata(chain_spec).map(MetadataInspector) + } + + fn pallet_exists(&self, name: &str) -> bool { + self.0.pallet_by_name(name).is_some() + } + + fn block_number(&self) -> Option { + let pallet_metadata = self.0.pallet_by_name(DEFAULT_FRAME_SYSTEM_PALLET_NAME); + pallet_metadata + .and_then(|inner| inner.storage()) + .and_then(|inner| inner.entry_by_name("Number")) + .and_then(|number_ty| match number_ty.entry_type() { + StorageEntryType::Plain(ty_id) => Some(ty_id), + _ => None, + }) + .and_then(|ty_id| self.0.types().resolve(*ty_id)) + .and_then(|portable_type| BlockNumber::from_type_def(&portable_type.type_def)) + } + + fn fetch_metadata(chain_spec: &dyn ChainSpec) -> Result { + let mut storage = chain_spec.build_storage()?; + let code_bytes = storage + .top + .remove(sp_storage::well_known_keys::CODE) + .ok_or("chain spec genesis does not contain code")?; + let opaque_metadata = fetch_latest_metadata_from_code_blob( + &WasmExecutor::::builder() + .with_allow_missing_host_functions(true) + .build(), + sp_runtime::Cow::Borrowed(code_bytes.as_slice()), + ) + .map_err(|err| err.to_string())?; + + Metadata::decode(&mut (*opaque_metadata).as_slice()).map_err(Into::into) + } +} + +#[cfg(test)] +mod tests { + use crate::runtime::{ + BlockNumber, MetadataInspector, DEFAULT_FRAME_SYSTEM_PALLET_NAME, + DEFAULT_PARACHAIN_SYSTEM_PALLET_NAME, + }; + use codec::Decode; + use cumulus_client_service::ParachainHostFunctions; + use sc_executor::WasmExecutor; + use sc_runtime_utilities::fetch_latest_metadata_from_code_blob; + + fn cumulus_test_runtime_metadata() -> subxt_metadata::Metadata { + let opaque_metadata = fetch_latest_metadata_from_code_blob( + &WasmExecutor::::builder() + .with_allow_missing_host_functions(true) + .build(), + sp_runtime::Cow::Borrowed(cumulus_test_runtime::WASM_BINARY.unwrap()), + ) + .unwrap(); + + subxt_metadata::Metadata::decode(&mut (*opaque_metadata).as_slice()).unwrap() + } + + #[test] + fn test_pallet_exists() { + let metadata_inspector = MetadataInspector(cumulus_test_runtime_metadata()); + assert!(metadata_inspector.pallet_exists(DEFAULT_PARACHAIN_SYSTEM_PALLET_NAME)); + assert!(metadata_inspector.pallet_exists(DEFAULT_FRAME_SYSTEM_PALLET_NAME)); + } + + #[test] + fn test_runtime_block_number() { + let metadata_inspector = MetadataInspector(cumulus_test_runtime_metadata()); + assert_eq!(metadata_inspector.block_number().unwrap(), BlockNumber::U32); } } diff --git a/cumulus/polkadot-omni-node/lib/src/common/spec.rs b/cumulus/polkadot-omni-node/lib/src/common/spec.rs index 259f89049c92..38f0e7d72881 100644 --- a/cumulus/polkadot-omni-node/lib/src/common/spec.rs +++ b/cumulus/polkadot-omni-node/lib/src/common/spec.rs @@ -208,151 +208,151 @@ pub(crate) trait NodeSpec: BaseNodeSpec { where Net: NetworkBackend, { - Box::pin( - async move { - let parachain_config = prepare_node_config(parachain_config); - - let params = Self::new_partial(¶chain_config)?; - let (block_import, mut telemetry, telemetry_worker_handle) = params.other; - - let client = params.client.clone(); - let backend = params.backend.clone(); - - let mut task_manager = params.task_manager; - let (relay_chain_interface, collator_key) = build_relay_chain_interface( - polkadot_config, - ¶chain_config, - telemetry_worker_handle, - &mut task_manager, - collator_options.clone(), - hwbench.clone(), - ) - .await - .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; - - let validator = parachain_config.role.is_authority(); - let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let transaction_pool = params.transaction_pool.clone(); - let import_queue_service = params.import_queue.service(); - let net_config = FullNetworkConfiguration::<_, _, Net>::new( - ¶chain_config.network, - prometheus_registry.clone(), - ); - - let (network, system_rpc_tx, tx_handler_controller, sync_service) = - build_network(BuildNetworkParams { - parachain_config: ¶chain_config, - net_config, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - para_id, - spawn_handle: task_manager.spawn_handle(), - relay_chain_interface: relay_chain_interface.clone(), - import_queue: params.import_queue, - sybil_resistance_level: Self::SYBIL_RESISTANCE, - }) - .await?; - - let rpc_builder = { - let client = client.clone(); - let transaction_pool = transaction_pool.clone(); - let backend_for_rpc = backend.clone(); - - Box::new(move |_| { - Self::BuildRpcExtensions::build_rpc_extensions( - client.clone(), - backend_for_rpc.clone(), - transaction_pool.clone(), - ) - }) - }; - - sc_service::spawn_tasks(sc_service::SpawnTasksParams { - rpc_builder, + let fut = async move { + let parachain_config = prepare_node_config(parachain_config); + + let params = Self::new_partial(¶chain_config)?; + let (block_import, mut telemetry, telemetry_worker_handle) = params.other; + let client = params.client.clone(); + let backend = params.backend.clone(); + let mut task_manager = params.task_manager; + let (relay_chain_interface, collator_key) = build_relay_chain_interface( + polkadot_config, + ¶chain_config, + telemetry_worker_handle, + &mut task_manager, + collator_options.clone(), + hwbench.clone(), + ) + .await + .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; + + let validator = parachain_config.role.is_authority(); + let prometheus_registry = parachain_config.prometheus_registry().cloned(); + let transaction_pool = params.transaction_pool.clone(); + let import_queue_service = params.import_queue.service(); + let net_config = FullNetworkConfiguration::<_, _, Net>::new( + ¶chain_config.network, + prometheus_registry.clone(), + ); + + let (network, system_rpc_tx, tx_handler_controller, sync_service) = + build_network(BuildNetworkParams { + parachain_config: ¶chain_config, + net_config, client: client.clone(), transaction_pool: transaction_pool.clone(), - task_manager: &mut task_manager, - config: parachain_config, - keystore: params.keystore_container.keystore(), - backend: backend.clone(), - network: network.clone(), - sync_service: sync_service.clone(), - system_rpc_tx, - tx_handler_controller, - telemetry: telemetry.as_mut(), - })?; - - if let Some(hwbench) = hwbench { - sc_sysinfo::print_hwbench(&hwbench); - if validator { - warn_if_slow_hardware(&hwbench); - } - - if let Some(ref mut telemetry) = telemetry { - let telemetry_handle = telemetry.handle(); - task_manager.spawn_handle().spawn( - "telemetry_hwbench", - None, - sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), - ); - } - } - - let announce_block = { - let sync_service = sync_service.clone(); - Arc::new(move |hash, data| sync_service.announce_block(hash, data)) - }; - - let relay_chain_slot_duration = Duration::from_secs(6); - - let overseer_handle = relay_chain_interface - .overseer_handle() - .map_err(|e| sc_service::Error::Application(Box::new(e)))?; - - start_relay_chain_tasks(StartRelayChainTasksParams { - client: client.clone(), - announce_block: announce_block.clone(), para_id, + spawn_handle: task_manager.spawn_handle(), relay_chain_interface: relay_chain_interface.clone(), - task_manager: &mut task_manager, - da_recovery_profile: if validator { - DARecoveryProfile::Collator - } else { - DARecoveryProfile::FullNode - }, - import_queue: import_queue_service, - relay_chain_slot_duration, - recovery_handle: Box::new(overseer_handle.clone()), - sync_service, - })?; - - if validator { - Self::StartConsensus::start_consensus( + import_queue: params.import_queue, + sybil_resistance_level: Self::SYBIL_RESISTANCE, + }) + .await?; + + let rpc_builder = { + let client = client.clone(); + let transaction_pool = transaction_pool.clone(); + let backend_for_rpc = backend.clone(); + + Box::new(move |_| { + Self::BuildRpcExtensions::build_rpc_extensions( client.clone(), - block_import, - prometheus_registry.as_ref(), - telemetry.as_ref().map(|t| t.handle()), - &task_manager, - relay_chain_interface.clone(), - transaction_pool, - params.keystore_container.keystore(), - relay_chain_slot_duration, - para_id, - collator_key.expect("Command line arguments do not allow this. qed"), - overseer_handle, - announce_block, - backend.clone(), - node_extra_args, - )?; + backend_for_rpc.clone(), + transaction_pool.clone(), + ) + }) + }; + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + rpc_builder, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + task_manager: &mut task_manager, + config: parachain_config, + keystore: params.keystore_container.keystore(), + backend: backend.clone(), + network: network.clone(), + sync_service: sync_service.clone(), + system_rpc_tx, + tx_handler_controller, + telemetry: telemetry.as_mut(), + })?; + + if let Some(hwbench) = hwbench { + sc_sysinfo::print_hwbench(&hwbench); + if validator { + warn_if_slow_hardware(&hwbench); } - Ok(task_manager) + if let Some(ref mut telemetry) = telemetry { + let telemetry_handle = telemetry.handle(); + task_manager.spawn_handle().spawn( + "telemetry_hwbench", + None, + sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), + ); + } } - .instrument(sc_tracing::tracing::info_span!( + + let announce_block = { + let sync_service = sync_service.clone(); + Arc::new(move |hash, data| sync_service.announce_block(hash, data)) + }; + + let relay_chain_slot_duration = Duration::from_secs(6); + + let overseer_handle = relay_chain_interface + .overseer_handle() + .map_err(|e| sc_service::Error::Application(Box::new(e)))?; + + start_relay_chain_tasks(StartRelayChainTasksParams { + client: client.clone(), + announce_block: announce_block.clone(), + para_id, + relay_chain_interface: relay_chain_interface.clone(), + task_manager: &mut task_manager, + da_recovery_profile: if validator { + DARecoveryProfile::Collator + } else { + DARecoveryProfile::FullNode + }, + import_queue: import_queue_service, + relay_chain_slot_duration, + recovery_handle: Box::new(overseer_handle.clone()), + sync_service, + })?; + + if validator { + Self::StartConsensus::start_consensus( + client.clone(), + block_import, + prometheus_registry.as_ref(), + telemetry.as_ref().map(|t| t.handle()), + &task_manager, + relay_chain_interface.clone(), + transaction_pool, + params.keystore_container.keystore(), + relay_chain_slot_duration, + para_id, + collator_key.expect("Command line arguments do not allow this. qed"), + overseer_handle, + announce_block, + backend.clone(), + node_extra_args, + )?; + } + + Ok(task_manager) + }; + + Box::pin(Instrument::instrument( + fut, + sc_tracing::tracing::info_span!( sc_tracing::logging::PREFIX_LOG_SPAN, - name = "Parachain", - )), - ) + name = "Parachain" + ), + )) } } diff --git a/docs/sdk/src/reference_docs/omni_node.rs b/docs/sdk/src/reference_docs/omni_node.rs index 44d63704a458..150755fb29a2 100644 --- a/docs/sdk/src/reference_docs/omni_node.rs +++ b/docs/sdk/src/reference_docs/omni_node.rs @@ -177,9 +177,25 @@ //! [This](https://github.com/paritytech/polkadot-sdk/issues/5565) future improvement to OmniNode //! aims to make such checks automatic. //! +//! ### Runtime conventions +//! +//! The Omni Node needs to make some assumptions about the runtime. During startup, the node fetches +//! the runtime metadata and asserts that the runtime represents a compatible parachain. +//! The checks are best effort and will generate warning level logs in the Omni Node log file on +//! failure. +//! +//! The list of checks may evolve in the future and for now only few rules are implemented: +//! * runtimes must define a type for [`cumulus-pallet-parachain-system`], which is recommended to +//! be named as `ParachainSystem`. +//! * runtimes must define a type for [`frame-system`] pallet, which is recommended to be named as +//! `System`. The configured [`block number`] here will be used by Omni Node to configure AURA +//! accordingly. //! //! [`templates`]: crate::polkadot_sdk::templates //! [`parachain-template`]: https://github.com/paritytech/polkadot-sdk-parachain-template //! [`--dev-block-time`]: polkadot_omni_node_lib::cli::Cli::dev_block_time //! [`polkadot-omni-node`]: https://crates.io/crates/polkadot-omni-node //! [`chain-spec-builder`]: https://crates.io/crates/staging-chain-spec-builder +//! [`cumulus-pallet-parachain-system`]: https://docs.rs/cumulus-pallet-parachain-system/latest/cumulus_pallet_parachain_system/ +//! [`frame-system`]: https://docs.rs/frame-system/latest/frame_system/ +//! [`block number`]: https://docs.rs/frame-system/latest/frame_system/pallet/storage_types/struct.Number.html diff --git a/prdoc/pr_6450.prdoc b/prdoc/pr_6450.prdoc new file mode 100644 index 000000000000..a9e927e45106 --- /dev/null +++ b/prdoc/pr_6450.prdoc @@ -0,0 +1,21 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Add omni-node checks for runtime parachain compatibility + +doc: + - audience: [ Node Dev, Runtime Dev ] + description: | + OmniNode parses runtime metadata and checks against the existence of `cumulus-pallet-parachain-system` + and `frame-system`, by filtering pallets by names: `ParachainSystem` and `System`. It also checks the + `frame-system` pallet storage `Number` type, and then uses it to configure AURA if `u32` or `u64`. + +crates: + - name: polkadot-omni-node-lib + bump: minor + - name: polkadot-sdk + bump: minor + - name: sc-runtime-utilities + bump: patch + - name: frame-benchmarking-cli + bump: major diff --git a/substrate/client/runtime-utilities/Cargo.toml b/substrate/client/runtime-utilities/Cargo.toml new file mode 100644 index 000000000000..5e026a5eff1a --- /dev/null +++ b/substrate/client/runtime-utilities/Cargo.toml @@ -0,0 +1,36 @@ +[package] +description = "Substrate client utilities for frame runtime functions calls." +name = "sc-runtime-utilities" +version = "0.1.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true +documentation = "https://docs.rs/sc-metadata" + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { workspace = true, default-features = true } + +sc-executor = { workspace = true, default-features = true } +sc-executor-common = { workspace = true, default-features = true } +sp-core = { workspace = true, default-features = true } +sp-crypto-hashing = { workspace = true, default-features = true } +sp-wasm-interface = { workspace = true, default-features = true } +sp-state-machine = { workspace = true, default-features = true } + + +thiserror = { workspace = true } + +[dev-dependencies] +cumulus-primitives-proof-size-hostfunction = { workspace = true, default-features = true } +cumulus-test-runtime = { workspace = true, default-features = true } +sp-version = { workspace = true, default-features = true } +sp-io = { workspace = true, default-features = true } +subxt = { workspace = true, features = ["native"] } diff --git a/substrate/client/runtime-utilities/src/error.rs b/substrate/client/runtime-utilities/src/error.rs new file mode 100644 index 000000000000..a0f1e45a5e57 --- /dev/null +++ b/substrate/client/runtime-utilities/src/error.rs @@ -0,0 +1,35 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +//! Errors types of runtime utilities. + +/// Generic result for the runtime utilities. +pub type Result = std::result::Result; + +/// Error type for the runtime utilities. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error("Scale codec error: {0}")] + ScaleCodec(#[from] codec::Error), + #[error("Opaque metadata not found")] + OpaqueMetadataNotFound, + #[error("Stable metadata version not found")] + StableMetadataVersionNotFound, + #[error("WASM executor error: {0}")] + Executor(#[from] sc_executor_common::error::Error), +} diff --git a/substrate/utils/frame/benchmarking-cli/src/overhead/runtime_utilities.rs b/substrate/client/runtime-utilities/src/lib.rs similarity index 60% rename from substrate/utils/frame/benchmarking-cli/src/overhead/runtime_utilities.rs rename to substrate/client/runtime-utilities/src/lib.rs index 3081197dc033..1ae3e2f1105a 100644 --- a/substrate/utils/frame/benchmarking-cli/src/overhead/runtime_utilities.rs +++ b/substrate/client/runtime-utilities/src/lib.rs @@ -1,21 +1,29 @@ // This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Substrate client runtime utilities. +//! +//! Provides convenient APIs to ease calling functions contained by a FRAME +//! runtime WASM blob. +#![warn(missing_docs)] use codec::{Decode, Encode}; +use error::{Error, Result}; use sc_executor::WasmExecutor; use sp_core::{ traits::{CallContext, CodeExecutor, FetchRuntimeCode, RuntimeCode}, @@ -25,41 +33,35 @@ use sp_state_machine::BasicExternalities; use sp_wasm_interface::HostFunctions; use std::borrow::Cow; +pub mod error; + /// Fetches the latest metadata from the given runtime blob. pub fn fetch_latest_metadata_from_code_blob( executor: &WasmExecutor, code_bytes: Cow<[u8]>, -) -> sc_cli::Result { +) -> Result { let runtime_caller = RuntimeCaller::new(executor, code_bytes); let version_result = runtime_caller.call("Metadata_metadata_versions", ()); - let opaque_metadata: OpaqueMetadata = match version_result { + match version_result { Ok(supported_versions) => { - let supported_versions = Vec::::decode(&mut supported_versions.as_slice()) - .map_err(|e| format!("Unable to decode version list: {e}"))?; - + let supported_versions = Vec::::decode(&mut supported_versions.as_slice())?; let latest_stable = supported_versions .into_iter() .filter(|v| *v != u32::MAX) .max() - .ok_or("No stable metadata versions supported".to_string())?; + .ok_or(Error::StableMetadataVersionNotFound)?; - let encoded = runtime_caller - .call("Metadata_metadata_at_version", latest_stable) - .map_err(|_| "Unable to fetch metadata from blob".to_string())?; + let encoded = runtime_caller.call("Metadata_metadata_at_version", latest_stable)?; Option::::decode(&mut encoded.as_slice())? - .ok_or_else(|| "Metadata not found".to_string())? + .ok_or(Error::OpaqueMetadataNotFound) }, Err(_) => { - let encoded = runtime_caller - .call("Metadata_metadata", ()) - .map_err(|_| "Unable to fetch metadata from blob".to_string())?; - Decode::decode(&mut encoded.as_slice())? + let encoded = runtime_caller.call("Metadata_metadata", ())?; + Decode::decode(&mut encoded.as_slice()).map_err(Into::into) }, - }; - - Ok(subxt::Metadata::decode(&mut (*opaque_metadata).as_slice())?) + } } struct BasicCodeFetcher<'a> { @@ -74,11 +76,11 @@ impl<'a> FetchRuntimeCode for BasicCodeFetcher<'a> { } impl<'a> BasicCodeFetcher<'a> { - pub fn new(code: Cow<'a, [u8]>) -> Self { + fn new(code: Cow<'a, [u8]>) -> Self { Self { hash: sp_crypto_hashing::blake2_256(&code).to_vec(), code } } - pub fn runtime_code(&'a self) -> RuntimeCode<'a> { + fn runtime_code(&'a self) -> RuntimeCode<'a> { RuntimeCode { code_fetcher: self as &'a dyn FetchRuntimeCode, heap_pages: None, @@ -88,17 +90,20 @@ impl<'a> BasicCodeFetcher<'a> { } /// Simple utility that is used to call into the runtime. -struct RuntimeCaller<'a, 'b, HF: HostFunctions> { +pub struct RuntimeCaller<'a, 'b, HF: HostFunctions> { executor: &'b WasmExecutor, code_fetcher: BasicCodeFetcher<'a>, } impl<'a, 'b, HF: HostFunctions> RuntimeCaller<'a, 'b, HF> { + /// Instantiate a new runtime caller. pub fn new(executor: &'b WasmExecutor, code_bytes: Cow<'a, [u8]>) -> Self { Self { executor, code_fetcher: BasicCodeFetcher::new(code_bytes) } } - fn call(&self, method: &str, data: impl Encode) -> sc_executor_common::error::Result> { + /// Calls a runtime function represented by a `method` name and `parity-scale-codec` + /// encodable arguments that will be passed to it. + pub fn call(&self, method: &str, data: impl Encode) -> Result> { let mut ext = BasicExternalities::default(); self.executor .call( @@ -109,24 +114,33 @@ impl<'a, 'b, HF: HostFunctions> RuntimeCaller<'a, 'b, HF> { CallContext::Offchain, ) .0 + .map_err(Into::into) } } #[cfg(test)] mod tests { - use crate::overhead::command::ParachainHostFunctions; use codec::Decode; use sc_executor::WasmExecutor; use sp_version::RuntimeVersion; + type ParachainHostFunctions = ( + cumulus_primitives_proof_size_hostfunction::storage_proof_size::HostFunctions, + sp_io::SubstrateHostFunctions, + ); + #[test] fn test_fetch_latest_metadata_from_blob_fetches_metadata() { let executor: WasmExecutor = WasmExecutor::builder().build(); let code_bytes = cumulus_test_runtime::WASM_BINARY .expect("To run this test, build the wasm binary of cumulus-test-runtime") .to_vec(); - let metadata = - super::fetch_latest_metadata_from_code_blob(&executor, code_bytes.into()).unwrap(); + let metadata = subxt::Metadata::decode( + &mut (*super::fetch_latest_metadata_from_code_blob(&executor, code_bytes.into()) + .unwrap()) + .as_slice(), + ) + .unwrap(); assert!(metadata.pallet_by_name("ParachainInfo").is_some()); } diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index 8a4a06b1b40a..6d86346ee180 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -44,6 +44,7 @@ sc-executor = { workspace = true, default-features = true } sc-executor-common = { workspace = true } sc-service = { workspace = true } sc-sysinfo = { workspace = true, default-features = true } +sc-runtime-utilities = { workspace = true, default-features = true } sp-api = { workspace = true, default-features = true } sp-blockchain = { workspace = true, default-features = true } sp-core = { workspace = true, default-features = true } diff --git a/substrate/utils/frame/benchmarking-cli/src/lib.rs b/substrate/utils/frame/benchmarking-cli/src/lib.rs index 1e8642e54d70..e1c3c5fe3706 100644 --- a/substrate/utils/frame/benchmarking-cli/src/lib.rs +++ b/substrate/utils/frame/benchmarking-cli/src/lib.rs @@ -30,7 +30,6 @@ pub use extrinsic::{ExtrinsicBuilder, ExtrinsicCmd, ExtrinsicFactory}; pub use machine::{MachineCmd, SUBSTRATE_REFERENCE_HARDWARE}; pub use overhead::{ remark_builder::{DynamicRemarkBuilder, SubstrateRemarkBuilder}, - runtime_utilities::fetch_latest_metadata_from_code_blob, OpaqueBlock, OverheadCmd, }; pub use pallet::PalletCmd; diff --git a/substrate/utils/frame/benchmarking-cli/src/overhead/command.rs b/substrate/utils/frame/benchmarking-cli/src/overhead/command.rs index 8102f14b4f4b..8df8ee5464f7 100644 --- a/substrate/utils/frame/benchmarking-cli/src/overhead/command.rs +++ b/substrate/utils/frame/benchmarking-cli/src/overhead/command.rs @@ -18,7 +18,6 @@ //! Contains the [`OverheadCmd`] as entry point for the CLI to execute //! the *overhead* benchmarks. -use super::runtime_utilities::*; use crate::{ extrinsic::{ bench::{Benchmark, BenchmarkParams as ExtrinsicBenchmarkParams}, @@ -37,7 +36,7 @@ use crate::{ }, }; use clap::{error::ErrorKind, Args, CommandFactory, Parser}; -use codec::Encode; +use codec::{Decode, Encode}; use cumulus_client_parachain_inherent::MockValidationDataInherentDataProvider; use fake_runtime_api::RuntimeApi as FakeRuntimeApi; use frame_support::Deserialize; @@ -50,6 +49,7 @@ use sc_cli::{CliConfiguration, Database, ImportParams, Result, SharedParams}; use sc_client_api::{execution_extensions::ExecutionExtensions, UsageProvider}; use sc_client_db::{BlocksPruning, DatabaseSettings}; use sc_executor::WasmExecutor; +use sc_runtime_utilities::fetch_latest_metadata_from_code_blob; use sc_service::{new_client, new_db_backend, BasePath, ClientConfig, TFullClient, TaskManager}; use serde::Serialize; use serde_json::{json, Value}; @@ -317,7 +317,7 @@ impl OverheadCmd { Some(self.params.genesis_builder_preset.clone()), ), self.params.para_id, - )) + )); }; Err("Neither a runtime nor a chain-spec were specified".to_string().into()) @@ -335,7 +335,7 @@ impl OverheadCmd { ErrorKind::MissingRequiredArgument, "Provide either a runtime via `--runtime` or a chain spec via `--chain`" .to_string(), - )) + )); } match self.params.genesis_builder { @@ -344,7 +344,7 @@ impl OverheadCmd { return Err(( ErrorKind::MissingRequiredArgument, "Provide a chain spec via `--chain`.".to_string(), - )) + )); }, _ => {}, }; @@ -400,8 +400,12 @@ impl OverheadCmd { .with_allow_missing_host_functions(true) .build(); - let metadata = - fetch_latest_metadata_from_code_blob(&executor, state_handler.get_code_bytes()?)?; + let opaque_metadata = + fetch_latest_metadata_from_code_blob(&executor, state_handler.get_code_bytes()?) + .map_err(|_| { + <&str as Into>::into("Unable to fetch latest stable metadata") + })?; + let metadata = subxt::Metadata::decode(&mut (*opaque_metadata).as_slice())?; // At this point we know what kind of chain we are dealing with. let chain_type = identify_chain(&metadata, para_id); @@ -682,6 +686,7 @@ mod tests { OverheadCmd, }; use clap::Parser; + use codec::Decode; use sc_executor::WasmExecutor; #[test] @@ -690,8 +695,9 @@ mod tests { let code_bytes = westend_runtime::WASM_BINARY .expect("To run this test, build the wasm binary of westend-runtime") .to_vec(); - let metadata = + let opaque_metadata = super::fetch_latest_metadata_from_code_blob(&executor, code_bytes.into()).unwrap(); + let metadata = subxt::Metadata::decode(&mut (*opaque_metadata).as_slice()).unwrap(); let chain_type = identify_chain(&metadata, None); assert_eq!(chain_type, ChainType::Relaychain); assert_eq!(chain_type.requires_proof_recording(), false); @@ -703,8 +709,9 @@ mod tests { let code_bytes = cumulus_test_runtime::WASM_BINARY .expect("To run this test, build the wasm binary of cumulus-test-runtime") .to_vec(); - let metadata = + let opaque_metadata = super::fetch_latest_metadata_from_code_blob(&executor, code_bytes.into()).unwrap(); + let metadata = subxt::Metadata::decode(&mut (*opaque_metadata).as_slice()).unwrap(); let chain_type = identify_chain(&metadata, Some(100)); assert_eq!(chain_type, ChainType::Parachain(100)); assert!(chain_type.requires_proof_recording()); @@ -717,8 +724,9 @@ mod tests { let code_bytes = substrate_test_runtime::WASM_BINARY .expect("To run this test, build the wasm binary of substrate-test-runtime") .to_vec(); - let metadata = + let opaque_metadata = super::fetch_latest_metadata_from_code_blob(&executor, code_bytes.into()).unwrap(); + let metadata = subxt::Metadata::decode(&mut (*opaque_metadata).as_slice()).unwrap(); let chain_type = identify_chain(&metadata, None); assert_eq!(chain_type, ChainType::Unknown); assert_eq!(chain_type.requires_proof_recording(), false); diff --git a/substrate/utils/frame/benchmarking-cli/src/overhead/mod.rs b/substrate/utils/frame/benchmarking-cli/src/overhead/mod.rs index 89c23d1fb6c1..de524d9ebc18 100644 --- a/substrate/utils/frame/benchmarking-cli/src/overhead/mod.rs +++ b/substrate/utils/frame/benchmarking-cli/src/overhead/mod.rs @@ -20,6 +20,5 @@ pub mod template; mod fake_runtime_api; pub mod remark_builder; -pub mod runtime_utilities; pub use command::{OpaqueBlock, OverheadCmd}; diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index 8ed9c3dcb02c..d5ef707d2b8f 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -604,7 +604,7 @@ runtime = [ "sp-wasm-interface", "sp-weights", ] -node = ["asset-test-utils", "bridge-hub-test-utils", "cumulus-client-cli", "cumulus-client-collator", "cumulus-client-consensus-aura", "cumulus-client-consensus-common", "cumulus-client-consensus-proposer", "cumulus-client-consensus-relay-chain", "cumulus-client-network", "cumulus-client-parachain-inherent", "cumulus-client-pov-recovery", "cumulus-client-service", "cumulus-relay-chain-inprocess-interface", "cumulus-relay-chain-interface", "cumulus-relay-chain-minimal-node", "cumulus-relay-chain-rpc-interface", "cumulus-test-relay-sproof-builder", "emulated-integration-tests-common", "fork-tree", "frame-benchmarking-cli", "frame-remote-externalities", "frame-support-procedural-tools", "generate-bags", "mmr-gadget", "mmr-rpc", "pallet-contracts-mock-network", "pallet-revive-eth-rpc", "pallet-revive-mock-network", "pallet-transaction-payment-rpc", "parachains-runtimes-test-utils", "polkadot-approval-distribution", "polkadot-availability-bitfield-distribution", "polkadot-availability-distribution", "polkadot-availability-recovery", "polkadot-cli", "polkadot-collator-protocol", "polkadot-dispute-distribution", "polkadot-erasure-coding", "polkadot-gossip-support", "polkadot-network-bridge", "polkadot-node-collation-generation", "polkadot-node-core-approval-voting", "polkadot-node-core-approval-voting-parallel", "polkadot-node-core-av-store", "polkadot-node-core-backing", "polkadot-node-core-bitfield-signing", "polkadot-node-core-candidate-validation", "polkadot-node-core-chain-api", "polkadot-node-core-chain-selection", "polkadot-node-core-dispute-coordinator", "polkadot-node-core-parachains-inherent", "polkadot-node-core-prospective-parachains", "polkadot-node-core-provisioner", "polkadot-node-core-pvf", "polkadot-node-core-pvf-checker", "polkadot-node-core-pvf-common", "polkadot-node-core-pvf-execute-worker", "polkadot-node-core-pvf-prepare-worker", "polkadot-node-core-runtime-api", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-types", "polkadot-node-subsystem-util", "polkadot-omni-node-lib", "polkadot-overseer", "polkadot-rpc", "polkadot-service", "polkadot-statement-distribution", "polkadot-statement-table", "sc-allocator", "sc-authority-discovery", "sc-basic-authorship", "sc-block-builder", "sc-chain-spec", "sc-cli", "sc-client-api", "sc-client-db", "sc-consensus", "sc-consensus-aura", "sc-consensus-babe", "sc-consensus-babe-rpc", "sc-consensus-beefy", "sc-consensus-beefy-rpc", "sc-consensus-epochs", "sc-consensus-grandpa", "sc-consensus-grandpa-rpc", "sc-consensus-manual-seal", "sc-consensus-pow", "sc-consensus-slots", "sc-executor", "sc-executor-common", "sc-executor-polkavm", "sc-executor-wasmtime", "sc-informant", "sc-keystore", "sc-mixnet", "sc-network", "sc-network-common", "sc-network-gossip", "sc-network-light", "sc-network-statement", "sc-network-sync", "sc-network-transactions", "sc-network-types", "sc-offchain", "sc-proposer-metrics", "sc-rpc", "sc-rpc-api", "sc-rpc-server", "sc-rpc-spec-v2", "sc-service", "sc-state-db", "sc-statement-store", "sc-storage-monitor", "sc-sync-state-rpc", "sc-sysinfo", "sc-telemetry", "sc-tracing", "sc-transaction-pool", "sc-transaction-pool-api", "sc-utils", "snowbridge-runtime-test-common", "sp-blockchain", "sp-consensus", "sp-core-hashing", "sp-core-hashing-proc-macro", "sp-database", "sp-maybe-compressed-blob", "sp-panic-handler", "sp-rpc", "staging-chain-spec-builder", "staging-node-inspect", "staging-tracking-allocator", "std", "subkey", "substrate-build-script-utils", "substrate-frame-rpc-support", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", "substrate-rpc-client", "substrate-state-trie-migration-rpc", "substrate-wasm-builder", "tracing-gum", "xcm-emulator", "xcm-simulator"] +node = ["asset-test-utils", "bridge-hub-test-utils", "cumulus-client-cli", "cumulus-client-collator", "cumulus-client-consensus-aura", "cumulus-client-consensus-common", "cumulus-client-consensus-proposer", "cumulus-client-consensus-relay-chain", "cumulus-client-network", "cumulus-client-parachain-inherent", "cumulus-client-pov-recovery", "cumulus-client-service", "cumulus-relay-chain-inprocess-interface", "cumulus-relay-chain-interface", "cumulus-relay-chain-minimal-node", "cumulus-relay-chain-rpc-interface", "cumulus-test-relay-sproof-builder", "emulated-integration-tests-common", "fork-tree", "frame-benchmarking-cli", "frame-remote-externalities", "frame-support-procedural-tools", "generate-bags", "mmr-gadget", "mmr-rpc", "pallet-contracts-mock-network", "pallet-revive-eth-rpc", "pallet-revive-mock-network", "pallet-transaction-payment-rpc", "parachains-runtimes-test-utils", "polkadot-approval-distribution", "polkadot-availability-bitfield-distribution", "polkadot-availability-distribution", "polkadot-availability-recovery", "polkadot-cli", "polkadot-collator-protocol", "polkadot-dispute-distribution", "polkadot-erasure-coding", "polkadot-gossip-support", "polkadot-network-bridge", "polkadot-node-collation-generation", "polkadot-node-core-approval-voting", "polkadot-node-core-approval-voting-parallel", "polkadot-node-core-av-store", "polkadot-node-core-backing", "polkadot-node-core-bitfield-signing", "polkadot-node-core-candidate-validation", "polkadot-node-core-chain-api", "polkadot-node-core-chain-selection", "polkadot-node-core-dispute-coordinator", "polkadot-node-core-parachains-inherent", "polkadot-node-core-prospective-parachains", "polkadot-node-core-provisioner", "polkadot-node-core-pvf", "polkadot-node-core-pvf-checker", "polkadot-node-core-pvf-common", "polkadot-node-core-pvf-execute-worker", "polkadot-node-core-pvf-prepare-worker", "polkadot-node-core-runtime-api", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-types", "polkadot-node-subsystem-util", "polkadot-omni-node-lib", "polkadot-overseer", "polkadot-rpc", "polkadot-service", "polkadot-statement-distribution", "polkadot-statement-table", "sc-allocator", "sc-authority-discovery", "sc-basic-authorship", "sc-block-builder", "sc-chain-spec", "sc-cli", "sc-client-api", "sc-client-db", "sc-consensus", "sc-consensus-aura", "sc-consensus-babe", "sc-consensus-babe-rpc", "sc-consensus-beefy", "sc-consensus-beefy-rpc", "sc-consensus-epochs", "sc-consensus-grandpa", "sc-consensus-grandpa-rpc", "sc-consensus-manual-seal", "sc-consensus-pow", "sc-consensus-slots", "sc-executor", "sc-executor-common", "sc-executor-polkavm", "sc-executor-wasmtime", "sc-informant", "sc-keystore", "sc-mixnet", "sc-network", "sc-network-common", "sc-network-gossip", "sc-network-light", "sc-network-statement", "sc-network-sync", "sc-network-transactions", "sc-network-types", "sc-offchain", "sc-proposer-metrics", "sc-rpc", "sc-rpc-api", "sc-rpc-server", "sc-rpc-spec-v2", "sc-runtime-utilities", "sc-service", "sc-state-db", "sc-statement-store", "sc-storage-monitor", "sc-sync-state-rpc", "sc-sysinfo", "sc-telemetry", "sc-tracing", "sc-transaction-pool", "sc-transaction-pool-api", "sc-utils", "snowbridge-runtime-test-common", "sp-blockchain", "sp-consensus", "sp-core-hashing", "sp-core-hashing-proc-macro", "sp-database", "sp-maybe-compressed-blob", "sp-panic-handler", "sp-rpc", "staging-chain-spec-builder", "staging-node-inspect", "staging-tracking-allocator", "std", "subkey", "substrate-build-script-utils", "substrate-frame-rpc-support", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", "substrate-rpc-client", "substrate-state-trie-migration-rpc", "substrate-wasm-builder", "tracing-gum", "xcm-emulator", "xcm-simulator"] tuples-96 = [ "frame-support-procedural?/tuples-96", "frame-support?/tuples-96", @@ -2327,6 +2327,11 @@ path = "../substrate/client/rpc-spec-v2" default-features = false optional = true +[dependencies.sc-runtime-utilities] +path = "../substrate/client/runtime-utilities" +default-features = false +optional = true + [dependencies.sc-service] path = "../substrate/client/service" default-features = false diff --git a/umbrella/src/lib.rs b/umbrella/src/lib.rs index 3712fb3343cf..7b3c869588f0 100644 --- a/umbrella/src/lib.rs +++ b/umbrella/src/lib.rs @@ -1119,6 +1119,10 @@ pub use sc_rpc_server; #[cfg(feature = "sc-rpc-spec-v2")] pub use sc_rpc_spec_v2; +/// Substrate client utilities for frame runtime functions calls. +#[cfg(feature = "sc-runtime-utilities")] +pub use sc_runtime_utilities; + /// Substrate service. Starts a thread that spins up the network, client, and extrinsic pool. /// Manages communication between them. #[cfg(feature = "sc-service")] From 50e5dd27dc905fbe71778b00f62aad3490e47de5 Mon Sep 17 00:00:00 2001 From: Kazunobu Ndong <33208377+ndkazu@users.noreply.github.com> Date: Thu, 12 Dec 2024 23:04:35 +0900 Subject: [PATCH 47/51] Remove collation-generation subsystem from validator nodes (#6832) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Issue #6476 Collation-generation is not needed for validators node, and should be removed. ## Implementation Use a `DummySubsystem` for `collation_generation` --------- Co-authored-by: Bastian Köcher Co-authored-by: command-bot <> Co-authored-by: Dmitry Markin Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> --- polkadot/node/service/src/overseer.rs | 9 +++++---- prdoc/pr_6832.prdoc | 13 +++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 prdoc/pr_6832.prdoc diff --git a/polkadot/node/service/src/overseer.rs b/polkadot/node/service/src/overseer.rs index 279b6ff80704..e4ea6efeaac2 100644 --- a/polkadot/node/service/src/overseer.rs +++ b/polkadot/node/service/src/overseer.rs @@ -210,7 +210,7 @@ pub fn validator_overseer_builder( AuthorityDiscoveryService, >, ChainApiSubsystem, - CollationGenerationSubsystem, + DummySubsystem, CollatorProtocolSubsystem, ApprovalDistributionSubsystem, ApprovalVotingSubsystem, @@ -237,6 +237,7 @@ where let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; let approval_voting_parallel_metrics: ApprovalVotingParallelMetrics = Metrics::register(registry)?; + let builder = Overseer::builder() .network_bridge_tx(NetworkBridgeTxSubsystem::new( network_service.clone(), @@ -295,7 +296,7 @@ where )) .pvf_checker(PvfCheckerSubsystem::new(keystore.clone(), Metrics::register(registry)?)) .chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?)) - .collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?)) + .collation_generation(DummySubsystem) .collator_protocol({ let side = match is_parachain_node { IsParachainNode::Collator(_) | IsParachainNode::FullNode => @@ -434,7 +435,7 @@ pub fn validator_with_parallel_overseer_builder( AuthorityDiscoveryService, >, ChainApiSubsystem, - CollationGenerationSubsystem, + DummySubsystem, CollatorProtocolSubsystem, DummySubsystem, DummySubsystem, @@ -519,7 +520,7 @@ where )) .pvf_checker(PvfCheckerSubsystem::new(keystore.clone(), Metrics::register(registry)?)) .chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?)) - .collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?)) + .collation_generation(DummySubsystem) .collator_protocol({ let side = match is_parachain_node { IsParachainNode::Collator(_) | IsParachainNode::FullNode => diff --git a/prdoc/pr_6832.prdoc b/prdoc/pr_6832.prdoc new file mode 100644 index 000000000000..bd0abbfba853 --- /dev/null +++ b/prdoc/pr_6832.prdoc @@ -0,0 +1,13 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Remove collation-generation subsystem from validator nodes" + +doc: + - audience: Node Dev + description: | + Collation-generation is only needed for Collators, and therefore not needed for validators + +crates: + - name: polkadot-service + bump: patch \ No newline at end of file From f8e5a8a131907df3ba2b33781ceab5c5dab68c67 Mon Sep 17 00:00:00 2001 From: davidk-pt Date: Thu, 12 Dec 2024 16:25:54 +0200 Subject: [PATCH 48/51] pallet-revive: disable host functions not in revive recompiler (#6844) Resolves https://github.com/paritytech/polkadot-sdk/issues/6720 List of used host functions in PolkaVM recompiler is here https://github.com/paritytech/revive/blob/main/crates/runtime-api/src/polkavm_imports.c#L65 --------- Co-authored-by: DavidK --- prdoc/pr_6844.prdoc | 8 ++++++++ substrate/frame/revive/src/wasm/runtime.rs | 19 ------------------- 2 files changed, 8 insertions(+), 19 deletions(-) create mode 100644 prdoc/pr_6844.prdoc diff --git a/prdoc/pr_6844.prdoc b/prdoc/pr_6844.prdoc new file mode 100644 index 000000000000..32901bf04df9 --- /dev/null +++ b/prdoc/pr_6844.prdoc @@ -0,0 +1,8 @@ +title: 'pallet-revive: disable host functions unused in solidity PolkaVM compiler' +doc: +- audience: Runtime Dev + description: Disables host functions in contracts that are not enabled + in solidity PolkaVM compiler to reduce surface of possible attack vectors. +crates: +- name: pallet-revive + bump: major diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs index 0d03771224b5..d8b856b0b766 100644 --- a/substrate/frame/revive/src/wasm/runtime.rs +++ b/substrate/frame/revive/src/wasm/runtime.rs @@ -1148,7 +1148,6 @@ pub mod env { /// Clear the value at the given key in the contract storage. /// See [`pallet_revive_uapi::HostFn::clear_storage`] - #[stable] #[mutating] fn clear_storage( &mut self, @@ -1177,7 +1176,6 @@ pub mod env { /// Checks whether there is a value stored under the given key. /// See [`pallet_revive_uapi::HostFn::contains_storage`] - #[stable] fn contains_storage( &mut self, memory: &mut M, @@ -1190,7 +1188,6 @@ pub mod env { /// Retrieve and remove the value under the given key from storage. /// See [`pallet_revive_uapi::HostFn::take_storage`] - #[stable] #[mutating] fn take_storage( &mut self, @@ -1301,7 +1298,6 @@ pub mod env { /// Remove the calling account and transfer remaining **free** balance. /// See [`pallet_revive_uapi::HostFn::terminate`]. - #[stable] #[mutating] fn terminate(&mut self, memory: &mut M, beneficiary_ptr: u32) -> Result<(), TrapReason> { self.terminate(memory, beneficiary_ptr) @@ -1399,7 +1395,6 @@ pub mod env { /// Checks whether a specified address belongs to a contract. /// See [`pallet_revive_uapi::HostFn::is_contract`]. - #[stable] fn is_contract(&mut self, memory: &mut M, account_ptr: u32) -> Result { self.charge_gas(RuntimeCosts::IsContract)?; let address = memory.read_h160(account_ptr)?; @@ -1438,7 +1433,6 @@ pub mod env { /// Retrieve the code hash of the currently executing contract. /// See [`pallet_revive_uapi::HostFn::own_code_hash`]. - #[stable] fn own_code_hash(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::OwnCodeHash)?; let code_hash = *self.ext.own_code_hash(); @@ -1453,7 +1447,6 @@ pub mod env { /// Checks whether the caller of the current contract is the origin of the whole call stack. /// See [`pallet_revive_uapi::HostFn::caller_is_origin`]. - #[stable] fn caller_is_origin(&mut self, _memory: &mut M) -> Result { self.charge_gas(RuntimeCosts::CallerIsOrigin)?; Ok(self.ext.caller_is_origin() as u32) @@ -1461,7 +1454,6 @@ pub mod env { /// Checks whether the caller of the current contract is root. /// See [`pallet_revive_uapi::HostFn::caller_is_root`]. - #[stable] fn caller_is_root(&mut self, _memory: &mut M) -> Result { self.charge_gas(RuntimeCosts::CallerIsRoot)?; Ok(self.ext.caller_is_root() as u32) @@ -1505,7 +1497,6 @@ pub mod env { /// Stores the amount of weight left into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::weight_left`]. - #[stable] fn weight_left( &mut self, memory: &mut M, @@ -1631,7 +1622,6 @@ pub mod env { /// Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer. /// See [`pallet_revive_uapi::HostFn::minimum_balance`]. - #[stable] fn minimum_balance(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> { self.charge_gas(RuntimeCosts::MinimumBalance)?; Ok(self.write_fixed_sandbox_output( @@ -1720,7 +1710,6 @@ pub mod env { /// Computes the SHA2 256-bit hash on the given input buffer. /// See [`pallet_revive_uapi::HostFn::hash_sha2_256`]. - #[stable] fn hash_sha2_256( &mut self, memory: &mut M, @@ -1752,7 +1741,6 @@ pub mod env { /// Computes the BLAKE2 256-bit hash on the given input buffer. /// See [`pallet_revive_uapi::HostFn::hash_blake2_256`]. - #[stable] fn hash_blake2_256( &mut self, memory: &mut M, @@ -1768,7 +1756,6 @@ pub mod env { /// Computes the BLAKE2 128-bit hash on the given input buffer. /// See [`pallet_revive_uapi::HostFn::hash_blake2_128`]. - #[stable] fn hash_blake2_128( &mut self, memory: &mut M, @@ -1814,7 +1801,6 @@ pub mod env { /// Emit a custom debug message. /// See [`pallet_revive_uapi::HostFn::debug_message`]. - #[stable] fn debug_message( &mut self, memory: &mut M, @@ -1932,7 +1918,6 @@ pub mod env { /// Recovers the ECDSA public key from the given message hash and signature. /// See [`pallet_revive_uapi::HostFn::ecdsa_recover`]. - #[stable] fn ecdsa_recover( &mut self, memory: &mut M, @@ -1963,7 +1948,6 @@ pub mod env { /// Verify a sr25519 signature /// See [`pallet_revive_uapi::HostFn::sr25519_verify`]. - #[stable] fn sr25519_verify( &mut self, memory: &mut M, @@ -2004,7 +1988,6 @@ pub mod env { /// Calculates Ethereum address from the ECDSA compressed public key and stores /// See [`pallet_revive_uapi::HostFn::ecdsa_to_eth_address`]. - #[stable] fn ecdsa_to_eth_address( &mut self, memory: &mut M, @@ -2026,7 +2009,6 @@ pub mod env { /// Adds a new delegate dependency to the contract. /// See [`pallet_revive_uapi::HostFn::lock_delegate_dependency`]. - #[stable] #[mutating] fn lock_delegate_dependency( &mut self, @@ -2041,7 +2023,6 @@ pub mod env { /// Removes the delegate dependency from the contract. /// see [`pallet_revive_uapi::HostFn::unlock_delegate_dependency`]. - #[stable] #[mutating] fn unlock_delegate_dependency( &mut self, From 5788ae8609e1e6947c588a5745d22d8777e47f4e Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:47:30 +0200 Subject: [PATCH 49/51] chore: Update litep2p to version 0.8.4 (#6860) ## [0.8.4] - 2024-12-12 This release aims to make the MDNS component more robust by fixing a bug that caused the MDNS service to fail to register opened substreams. Additionally, the release includes several improvements to the `identify` protocol, replacing `FuturesUnordered` with `FuturesStream` for better performance. ### Fixed - mdns/fix: Failed to register opened substream ([#301](https://github.com/paritytech/litep2p/pull/301)) ### Changed - identify: Replace FuturesUnordered with FuturesStream ([#302](https://github.com/paritytech/litep2p/pull/302)) - chore: Update hickory-resolver to version 0.24.2 ([#304](https://github.com/paritytech/litep2p/pull/304)) - ci: Ensure cargo-machete is working with rust version from CI ([#303](https://github.com/paritytech/litep2p/pull/303)) cc @paritytech/networking --------- Signed-off-by: Alexandru Vasile --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- prdoc/pr_6860.prdoc | 10 ++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 prdoc/pr_6860.prdoc diff --git a/Cargo.lock b/Cargo.lock index afd7507e7ab9..9eb9d3736a60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8488,9 +8488,9 @@ dependencies = [ [[package]] name = "hickory-resolver" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +checksum = "0a2e2aba9c389ce5267d31cf1e4dace82390ae276b0b364ea55630b1fa1b44b4" dependencies = [ "cfg-if", "futures-util", @@ -10406,9 +10406,9 @@ dependencies = [ [[package]] name = "litep2p" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e490b5a6d486711fd0284bd30e607a287343f2935a59a9192bd7109e85f443" +checksum = "2b0fef34af8847e816003bf7fdeac5ea50b9a7a88441ac927a6166b5e812ab79" dependencies = [ "async-trait", "bs58", diff --git a/Cargo.toml b/Cargo.toml index 089ba3cef208..98ab6551c802 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -848,7 +848,7 @@ linked-hash-map = { version = "0.5.4" } linked_hash_set = { version = "0.1.4" } linregress = { version = "0.5.1" } lite-json = { version = "0.2.0", default-features = false } -litep2p = { version = "0.8.3", features = ["websocket"] } +litep2p = { version = "0.8.4", features = ["websocket"] } log = { version = "0.4.22", default-features = false } macro_magic = { version = "0.5.1" } maplit = { version = "1.0.2" } diff --git a/prdoc/pr_6860.prdoc b/prdoc/pr_6860.prdoc new file mode 100644 index 000000000000..76b460ce52dd --- /dev/null +++ b/prdoc/pr_6860.prdoc @@ -0,0 +1,10 @@ +title: Update litep2p network backend to v0.8.4 + +doc: + - audience: [ Node Dev, Node Operator ] + description: | + This PR updates the Litep2p network backend to version 0.8.4 + +crates: + - name: sc-network + bump: patch From c10e25aaa8b8afd8665b53f0a0b02e4ea44caa77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 12 Dec 2024 17:50:23 +0100 Subject: [PATCH 50/51] dmp: Check that the para exist before delivering a message (#6604) Co-authored-by: GitHub Action Co-authored-by: Branislav Kontur Co-authored-by: command-bot <> --- Cargo.lock | 4 +- bridges/bin/runtime-common/Cargo.toml | 1 + .../modules/xcm-bridge-hub-router/Cargo.toml | 1 + bridges/modules/xcm-bridge-hub/Cargo.toml | 1 + .../pallets/inbound-queue/Cargo.toml | 1 + bridges/snowbridge/pallets/system/Cargo.toml | 1 + bridges/snowbridge/primitives/core/Cargo.toml | 1 + .../snowbridge/primitives/router/Cargo.toml | 1 + .../runtime/runtime-common/Cargo.toml | 1 + .../snowbridge/runtime/test-common/Cargo.toml | 1 + cumulus/pallets/dmp-queue/Cargo.toml | 1 + cumulus/pallets/parachain-system/Cargo.toml | 5 +- cumulus/pallets/parachain-system/src/lib.rs | 2 +- cumulus/pallets/xcmp-queue/Cargo.toml | 1 + cumulus/parachains/common/Cargo.toml | 1 + .../emulated/common/src/impls.rs | 2 + .../emulated/common/src/macros.rs | 3 + .../src/tests/hybrid_transfers.rs | 4 + .../src/tests/reserve_transfer.rs | 13 +++ .../asset-hub-rococo/src/tests/treasury.rs | 4 + .../src/tests/hybrid_transfers.rs | 4 + .../src/tests/reserve_transfer.rs | 13 +++ .../asset-hub-westend/src/tests/treasury.rs | 3 + .../bridge-hub-rococo/src/tests/send_xcm.rs | 4 + .../bridge-hub-westend/src/tests/send_xcm.rs | 4 + .../src/tests/fellowship_treasury.rs | 3 + .../src/tests/coretime_interface.rs | 5 + .../src/tests/coretime_interface.rs | 5 + .../people-westend/src/tests/governance.rs | 20 +++- .../assets/asset-hub-rococo/Cargo.toml | 1 + .../assets/asset-hub-westend/Cargo.toml | 1 + .../runtimes/assets/common/Cargo.toml | 1 + .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 1 + .../bridge-hubs/bridge-hub-westend/Cargo.toml | 1 + .../runtimes/bridge-hubs/common/Cargo.toml | 1 + .../collectives-westend/Cargo.toml | 1 + .../contracts/contracts-rococo/Cargo.toml | 1 + .../coretime/coretime-rococo/Cargo.toml | 1 + .../coretime/coretime-westend/Cargo.toml | 1 + .../glutton/glutton-westend/Cargo.toml | 1 + .../runtimes/people/people-rococo/Cargo.toml | 1 + .../runtimes/people/people-westend/Cargo.toml | 1 + .../runtimes/testing/penpal/Cargo.toml | 1 + .../testing/rococo-parachain/Cargo.toml | 1 + cumulus/polkadot-parachain/Cargo.toml | 1 + cumulus/primitives/core/Cargo.toml | 1 + cumulus/primitives/utility/Cargo.toml | 1 + polkadot/node/service/Cargo.toml | 1 + polkadot/parachain/src/primitives.rs | 5 + polkadot/runtime/common/Cargo.toml | 1 + .../runtime/common/src/identity_migrator.rs | 16 +++ .../runtime/common/src/paras_sudo_wrapper.rs | 3 + polkadot/runtime/common/src/xcm_sender.rs | 29 +++-- polkadot/runtime/parachains/Cargo.toml | 1 + .../parachains/src/coretime/benchmarking.rs | 2 + polkadot/runtime/parachains/src/dmp.rs | 37 ++++-- polkadot/runtime/parachains/src/dmp/tests.rs | 44 ++++++++ polkadot/runtime/parachains/src/lib.rs | 16 +++ polkadot/runtime/rococo/Cargo.toml | 1 + polkadot/runtime/rococo/src/impls.rs | 5 + polkadot/runtime/rococo/src/lib.rs | 6 +- polkadot/runtime/test-runtime/Cargo.toml | 1 + polkadot/runtime/westend/Cargo.toml | 1 + polkadot/runtime/westend/src/impls.rs | 5 + polkadot/runtime/westend/src/lib.rs | 6 +- polkadot/xcm/Cargo.toml | 4 + polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml | 1 + .../src/fungible/benchmarking.rs | 35 +++++- .../src/generic/benchmarking.rs | 6 + polkadot/xcm/pallet-xcm/Cargo.toml | 1 + polkadot/xcm/pallet-xcm/src/benchmarking.rs | 32 +++++- polkadot/xcm/src/v5/traits.rs | 11 ++ polkadot/xcm/xcm-builder/Cargo.toml | 1 + polkadot/xcm/xcm-builder/src/pay.rs | 11 +- polkadot/xcm/xcm-builder/src/routing.rs | 15 +++ polkadot/xcm/xcm-builder/src/tests/pay/pay.rs | 2 +- .../xcm/xcm-builder/src/universal_exports.rs | 16 +++ polkadot/xcm/xcm-executor/Cargo.toml | 1 + .../xcm-executor/integration-tests/Cargo.toml | 5 +- .../xcm-executor/integration-tests/src/lib.rs | 25 ++++- polkadot/xcm/xcm-runtime-apis/Cargo.toml | 1 + polkadot/xcm/xcm-simulator/example/Cargo.toml | 1 + polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml | 1 + prdoc/pr_6604.prdoc | 106 ++++++++++++++++++ substrate/frame/contracts/Cargo.toml | 1 + .../frame/contracts/mock-network/Cargo.toml | 1 + substrate/frame/revive/Cargo.toml | 1 + .../frame/revive/mock-network/Cargo.toml | 1 + umbrella/Cargo.toml | 1 + 89 files changed, 537 insertions(+), 51 deletions(-) create mode 100644 prdoc/pr_6604.prdoc diff --git a/Cargo.lock b/Cargo.lock index 9eb9d3736a60..f2379d4ee6de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4955,7 +4955,6 @@ dependencies = [ "pallet-message-queue 31.0.0", "parity-scale-codec", "polkadot-parachain-primitives 6.0.0", - "polkadot-runtime-common 7.0.0", "polkadot-runtime-parachains 7.0.0", "rand", "sc-client-api", @@ -31882,10 +31881,13 @@ name = "xcm-executor-integration-tests" version = "1.0.0" dependencies = [ "frame-support 28.0.0", + "frame-system 28.0.0", "futures", + "pallet-sudo 28.0.0", "pallet-transaction-payment 28.0.0", "pallet-xcm 7.0.0", "parity-scale-codec", + "polkadot-runtime-parachains 7.0.0", "polkadot-test-client", "polkadot-test-runtime", "polkadot-test-service", diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index 37b56140c289..49cd086fd3eb 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -99,6 +99,7 @@ runtime-benchmarks = [ "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "sp-trie", + "xcm/runtime-benchmarks", ] integrity-test = ["static_assertions"] test-helpers = ["bp-runtime/test-helpers", "sp-trie"] diff --git a/bridges/modules/xcm-bridge-hub-router/Cargo.toml b/bridges/modules/xcm-bridge-hub-router/Cargo.toml index 55824f6a7fe7..b0286938f36d 100644 --- a/bridges/modules/xcm-bridge-hub-router/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub-router/Cargo.toml @@ -56,6 +56,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/bridges/modules/xcm-bridge-hub/Cargo.toml b/bridges/modules/xcm-bridge-hub/Cargo.toml index 251dcfb45bcb..ef49b3396b5c 100644 --- a/bridges/modules/xcm-bridge-hub/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub/Cargo.toml @@ -77,6 +77,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml index 3ab633bfcd79..c0789940a9e8 100644 --- a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml @@ -81,6 +81,7 @@ runtime-benchmarks = [ "snowbridge-router-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/bridges/snowbridge/pallets/system/Cargo.toml b/bridges/snowbridge/pallets/system/Cargo.toml index f1e749afb997..d8e124d73d14 100644 --- a/bridges/snowbridge/pallets/system/Cargo.toml +++ b/bridges/snowbridge/pallets/system/Cargo.toml @@ -71,6 +71,7 @@ runtime-benchmarks = [ "snowbridge-pallet-outbound-queue/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/bridges/snowbridge/primitives/core/Cargo.toml b/bridges/snowbridge/primitives/core/Cargo.toml index fa37c795b2d1..af002a5a965c 100644 --- a/bridges/snowbridge/primitives/core/Cargo.toml +++ b/bridges/snowbridge/primitives/core/Cargo.toml @@ -64,4 +64,5 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/bridges/snowbridge/primitives/router/Cargo.toml b/bridges/snowbridge/primitives/router/Cargo.toml index ee8d481cec12..1f7f489c6b18 100644 --- a/bridges/snowbridge/primitives/router/Cargo.toml +++ b/bridges/snowbridge/primitives/router/Cargo.toml @@ -51,4 +51,5 @@ runtime-benchmarks = [ "snowbridge-core/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/bridges/snowbridge/runtime/runtime-common/Cargo.toml b/bridges/snowbridge/runtime/runtime-common/Cargo.toml index d47cb3cb7101..514a4c186696 100644 --- a/bridges/snowbridge/runtime/runtime-common/Cargo.toml +++ b/bridges/snowbridge/runtime/runtime-common/Cargo.toml @@ -43,4 +43,5 @@ runtime-benchmarks = [ "snowbridge-core/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/bridges/snowbridge/runtime/test-common/Cargo.toml b/bridges/snowbridge/runtime/test-common/Cargo.toml index 9f47f158ed4a..cc1ed1288ca0 100644 --- a/bridges/snowbridge/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/runtime/test-common/Cargo.toml @@ -92,5 +92,6 @@ runtime-benchmarks = [ "snowbridge-pallet-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] fast-runtime = [] diff --git a/cumulus/pallets/dmp-queue/Cargo.toml b/cumulus/pallets/dmp-queue/Cargo.toml index 936526290d93..ae85a108fe72 100644 --- a/cumulus/pallets/dmp-queue/Cargo.toml +++ b/cumulus/pallets/dmp-queue/Cargo.toml @@ -56,6 +56,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/pallets/parachain-system/Cargo.toml b/cumulus/pallets/parachain-system/Cargo.toml index 05498a474e42..c911f8531da2 100644 --- a/cumulus/pallets/parachain-system/Cargo.toml +++ b/cumulus/pallets/parachain-system/Cargo.toml @@ -38,7 +38,6 @@ sp-version = { workspace = true } # Polkadot polkadot-parachain-primitives = { features = ["wasm-api"], workspace = true } polkadot-runtime-parachains = { workspace = true } -polkadot-runtime-common = { optional = true, workspace = true } xcm = { workspace = true } xcm-builder = { workspace = true } @@ -84,7 +83,6 @@ std = [ "log/std", "pallet-message-queue/std", "polkadot-parachain-primitives/std", - "polkadot-runtime-common/std", "polkadot-runtime-parachains/std", "scale-info/std", "sp-core/std", @@ -109,17 +107,16 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", - "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "pallet-message-queue/try-runtime", - "polkadot-runtime-common?/try-runtime", "polkadot-runtime-parachains/try-runtime", "sp-runtime/try-runtime", ] diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs index 39fc8321a072..0fa759357f65 100644 --- a/cumulus/pallets/parachain-system/src/lib.rs +++ b/cumulus/pallets/parachain-system/src/lib.rs @@ -1636,7 +1636,7 @@ impl InspectMessageQueues for Pallet { } #[cfg(feature = "runtime-benchmarks")] -impl polkadot_runtime_common::xcm_sender::EnsureForParachain for Pallet { +impl polkadot_runtime_parachains::EnsureForParachain for Pallet { fn ensure(para_id: ParaId) { if let ChannelStatus::Closed = Self::get_channel_status(para_id) { Self::open_outbound_hrmp_channel_for_benchmarks_or_tests(para_id) diff --git a/cumulus/pallets/xcmp-queue/Cargo.toml b/cumulus/pallets/xcmp-queue/Cargo.toml index af70a3169d8e..432be3027e05 100644 --- a/cumulus/pallets/xcmp-queue/Cargo.toml +++ b/cumulus/pallets/xcmp-queue/Cargo.toml @@ -87,6 +87,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "cumulus-pallet-parachain-system/try-runtime", diff --git a/cumulus/parachains/common/Cargo.toml b/cumulus/parachains/common/Cargo.toml index 641693a6a01b..ae4d7fc1d115 100644 --- a/cumulus/parachains/common/Cargo.toml +++ b/cumulus/parachains/common/Cargo.toml @@ -92,4 +92,5 @@ runtime-benchmarks = [ "polkadot-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs index c0d42cf2758e..9dad323aa19c 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs @@ -370,6 +370,8 @@ macro_rules! impl_send_transact_helpers_for_relay_chain { let destination: $crate::impls::Location = ::child_location_of(recipient); let xcm = $crate::impls::xcm_transact_unpaid_execution(call, $crate::impls::OriginKind::Superuser); + $crate::impls::dmp::Pallet::<::Runtime>::make_parachain_reachable(recipient); + // Send XCM `Transact` $crate::impls::assert_ok!(]>::XcmPallet::send( root_origin, diff --git a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs index b776cafb2545..cd2b41e5198f 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs @@ -23,6 +23,7 @@ pub use pallet_message_queue; pub use pallet_xcm; // Polkadot +pub use polkadot_runtime_parachains::dmp::Pallet as Dmp; pub use xcm::{ prelude::{ AccountId32, All, Asset, AssetId, BuyExecution, DepositAsset, ExpectTransactStatus, @@ -156,6 +157,8 @@ macro_rules! test_relay_is_trusted_teleporter { // Send XCM message from Relay <$sender_relay>::execute_with(|| { + $crate::macros::Dmp::<<$sender_relay as $crate::macros::Chain>::Runtime>::make_parachain_reachable(<$receiver_para>::para_id()); + assert_ok!(<$sender_relay as [<$sender_relay Pallet>]>::XcmPallet::limited_teleport_assets( origin.clone(), bx!(para_destination.clone().into()), diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs index baec7d20f415..fb95c361f089 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use rococo_system_emulated_network::rococo_emulated_chain::rococo_runtime::Dmp; + use super::reserve_transfer::*; use crate::{ imports::*, @@ -777,6 +779,8 @@ fn transfer_native_asset_from_relay_to_para_through_asset_hub() { xcm: xcm_on_final_dest, }]); + Dmp::make_parachain_reachable(AssetHubRococo::para_id()); + // First leg is a teleport, from there a local-reserve-transfer to final dest ::XcmPallet::transfer_assets_using_type_and_then( t.signed_origin, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs index d642e877f002..407a581afeb9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs @@ -14,6 +14,7 @@ // limitations under the License. use crate::imports::*; +use rococo_system_emulated_network::rococo_emulated_chain::rococo_runtime::Dmp; use sp_core::{crypto::get_public_from_string_or_panic, sr25519}; fn relay_to_para_sender_assertions(t: RelayToParaTest) { @@ -487,6 +488,11 @@ pub fn para_to_para_through_hop_receiver_assertions(t: Test DispatchResult { + let Junction::Parachain(para_id) = *t.args.dest.chain_location().last().unwrap() else { + unimplemented!("Destination is not a parachain?") + }; + + Dmp::make_parachain_reachable(para_id); ::XcmPallet::limited_reserve_transfer_assets( t.signed_origin, bx!(t.args.dest.into()), @@ -546,6 +552,13 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn para_to_para_through_relay_limited_reserve_transfer_assets( t: ParaToParaThroughRelayTest, ) -> DispatchResult { + let Junction::Parachain(para_id) = *t.args.dest.chain_location().last().unwrap() else { + unimplemented!("Destination is not a parachain?") + }; + + Rococo::ext_wrapper(|| { + Dmp::make_parachain_reachable(para_id); + }); ::PolkadotXcm::limited_reserve_transfer_assets( t.signed_origin, bx!(t.args.dest.into()), diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs index 69111d38bcac..8648c8ce9311 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs @@ -29,6 +29,7 @@ use frame_support::{ use parachains_common::AccountId; use polkadot_runtime_common::impls::VersionedLocatableAsset; use rococo_runtime_constants::currency::GRAND; +use rococo_system_emulated_network::rococo_emulated_chain::rococo_runtime::Dmp; use xcm_executor::traits::ConvertLocation; // Fund Treasury account on Asset Hub from Treasury account on Relay Chain with ROCs. @@ -64,6 +65,7 @@ fn spend_roc_on_asset_hub() { treasury_balance * 2, )); + Dmp::make_parachain_reachable(1000); let native_asset = Location::here(); let asset_hub_location: Location = [Parachain(1000)].into(); let treasury_location: Location = (Parent, PalletInstance(18)).into(); @@ -199,6 +201,8 @@ fn create_and_claim_treasury_spend_in_usdt() { // create a conversion rate from `asset_kind` to the native currency. assert_ok!(AssetRate::create(root.clone(), Box::new(asset_kind.clone()), 2.into())); + Dmp::make_parachain_reachable(1000); + // create and approve a treasury spend. assert_ok!(Treasury::spend( root, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs index 0686bd71d085..91ebdda16828 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use westend_system_emulated_network::westend_emulated_chain::westend_runtime::Dmp; + use super::reserve_transfer::*; use crate::{ imports::*, @@ -778,6 +780,8 @@ fn transfer_native_asset_from_relay_to_penpal_through_asset_hub() { xcm: xcm_on_final_dest, }]); + Dmp::make_parachain_reachable(AssetHubWestend::para_id()); + // First leg is a teleport, from there a local-reserve-transfer to final dest ::XcmPallet::transfer_assets_using_type_and_then( t.signed_origin, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs index 707e8adc8a56..dc36fed42932 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs @@ -15,6 +15,7 @@ use crate::{create_pool_with_wnd_on, foreign_balance_on, imports::*}; use sp_core::{crypto::get_public_from_string_or_panic, sr25519}; +use westend_system_emulated_network::westend_emulated_chain::westend_runtime::Dmp; fn relay_to_para_sender_assertions(t: RelayToParaTest) { type RuntimeEvent = ::RuntimeEvent; @@ -487,6 +488,11 @@ pub fn para_to_para_through_hop_receiver_assertions(t: Test DispatchResult { + let Junction::Parachain(para_id) = *t.args.dest.chain_location().last().unwrap() else { + unimplemented!("Destination is not a parachain?") + }; + + Dmp::make_parachain_reachable(para_id); ::XcmPallet::limited_reserve_transfer_assets( t.signed_origin, bx!(t.args.dest.into()), @@ -533,6 +539,13 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn para_to_para_through_relay_limited_reserve_transfer_assets( t: ParaToParaThroughRelayTest, ) -> DispatchResult { + let Junction::Parachain(para_id) = *t.args.dest.chain_location().last().unwrap() else { + unimplemented!("Destination is not a parachain?") + }; + + Westend::ext_wrapper(|| { + Dmp::make_parachain_reachable(para_id); + }); ::PolkadotXcm::limited_reserve_transfer_assets( t.signed_origin, bx!(t.args.dest.into()), diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs index c303e6411d33..3b53557fc05c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs @@ -20,6 +20,7 @@ use emulated_integration_tests_common::{ }; use frame_support::traits::fungibles::{Inspect, Mutate}; use polkadot_runtime_common::impls::VersionedLocatableAsset; +use westend_system_emulated_network::westend_emulated_chain::westend_runtime::Dmp; use xcm_executor::traits::ConvertLocation; #[test] @@ -58,6 +59,8 @@ fn create_and_claim_treasury_spend() { // create a conversion rate from `asset_kind` to the native currency. assert_ok!(AssetRate::create(root.clone(), Box::new(asset_kind.clone()), 2.into())); + Dmp::make_parachain_reachable(1000); + // create and approve a treasury spend. assert_ok!(Treasury::spend( root, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs index 116ec4dc0e55..cfcb581238e6 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use rococo_system_emulated_network::rococo_emulated_chain::rococo_runtime::Dmp; + use crate::tests::*; #[test] @@ -38,6 +40,8 @@ fn send_xcm_from_rococo_relay_to_westend_asset_hub_should_fail_on_not_applicable // Rococo Global Consensus // Send XCM message from Relay Chain to Bridge Hub source Parachain Rococo::execute_with(|| { + Dmp::make_parachain_reachable(BridgeHubRococo::para_id()); + assert_ok!(::XcmPallet::send( sudo_origin, bx!(destination), diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs index acce60b4fa76..60f8af2242f9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use rococo_westend_system_emulated_network::westend_emulated_chain::westend_runtime::Dmp; + use crate::tests::*; #[test] @@ -38,6 +40,8 @@ fn send_xcm_from_westend_relay_to_rococo_asset_hub_should_fail_on_not_applicable // Westend Global Consensus // Send XCM message from Relay Chain to Bridge Hub source Parachain Westend::execute_with(|| { + Dmp::make_parachain_reachable(BridgeHubWestend::para_id()); + assert_ok!(::XcmPallet::send( sudo_origin, bx!(destination), diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs index 8418e3da3bba..ed7c9bafc607 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs @@ -20,6 +20,7 @@ use frame_support::{ }; use polkadot_runtime_common::impls::VersionedLocatableAsset; use westend_runtime_constants::currency::UNITS; +use westend_system_emulated_network::westend_emulated_chain::westend_runtime::Dmp; use xcm_executor::traits::ConvertLocation; // Fund Fellowship Treasury from Westend Treasury and spend from Fellowship Treasury. @@ -57,6 +58,8 @@ fn fellowship_treasury_spend() { treasury_balance * 2, )); + Dmp::make_parachain_reachable(1000); + let native_asset = Location::here(); let asset_hub_location: Location = [Parachain(1000)].into(); let treasury_location: Location = (Parent, PalletInstance(37)).into(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/coretime_interface.rs b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/coretime_interface.rs index 9915b1753ef6..554025e1ecfe 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/coretime_interface.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/coretime_interface.rs @@ -17,6 +17,7 @@ use crate::imports::*; use frame_support::traits::OnInitialize; use pallet_broker::{ConfigRecord, Configuration, CoreAssignment, CoreMask, ScheduleItem}; use rococo_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD; +use rococo_system_emulated_network::rococo_emulated_chain::rococo_runtime::Dmp; use sp_runtime::Perbill; #[test] @@ -34,6 +35,10 @@ fn transact_hardcoded_weights_are_sane() { type CoretimeEvent = ::RuntimeEvent; type RelayEvent = ::RuntimeEvent; + Rococo::execute_with(|| { + Dmp::make_parachain_reachable(CoretimeRococo::para_id()); + }); + // Reserve a workload, configure broker and start sales. CoretimeRococo::execute_with(|| { // Hooks don't run in emulated tests - workaround as we need `on_initialize` to tick things diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/coretime_interface.rs b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/coretime_interface.rs index 00530f80b958..900994b1afc1 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/coretime_interface.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/coretime_interface.rs @@ -18,6 +18,7 @@ use frame_support::traits::OnInitialize; use pallet_broker::{ConfigRecord, Configuration, CoreAssignment, CoreMask, ScheduleItem}; use sp_runtime::Perbill; use westend_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD; +use westend_system_emulated_network::westend_emulated_chain::westend_runtime::Dmp; #[test] fn transact_hardcoded_weights_are_sane() { @@ -34,6 +35,10 @@ fn transact_hardcoded_weights_are_sane() { type CoretimeEvent = ::RuntimeEvent; type RelayEvent = ::RuntimeEvent; + Westend::execute_with(|| { + Dmp::make_parachain_reachable(CoretimeWestend::para_id()); + }); + // Reserve a workload, configure broker and start sales. CoretimeWestend::execute_with(|| { // Hooks don't run in emulated tests - workaround as we need `on_initialize` to tick things diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs index 1ba787aaec52..ea438f80552e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/governance.rs @@ -20,7 +20,9 @@ use codec::Encode; use frame_support::sp_runtime::traits::Dispatchable; use parachains_common::AccountId; use people_westend_runtime::people::IdentityInfo; -use westend_runtime::governance::pallet_custom_origins::Origin::GeneralAdmin as GeneralAdminOrigin; +use westend_runtime::{ + governance::pallet_custom_origins::Origin::GeneralAdmin as GeneralAdminOrigin, Dmp, +}; use westend_system_emulated_network::people_westend_emulated_chain::people_westend_runtime; use pallet_identity::Data; @@ -39,6 +41,8 @@ fn relay_commands_add_registrar() { type PeopleCall = ::RuntimeCall; type PeopleRuntime = ::Runtime; + Dmp::make_parachain_reachable(1004); + let add_registrar_call = PeopleCall::Identity(pallet_identity::Call::::add_registrar { account: registrar.into(), @@ -102,6 +106,8 @@ fn relay_commands_add_registrar_wrong_origin() { type PeopleCall = ::RuntimeCall; type PeopleRuntime = ::Runtime; + Dmp::make_parachain_reachable(1004); + let add_registrar_call = PeopleCall::Identity(pallet_identity::Call::::add_registrar { account: registrar.into(), @@ -191,6 +197,8 @@ fn relay_commands_kill_identity() { type RuntimeEvent = ::RuntimeEvent; type PeopleRuntime = ::Runtime; + Dmp::make_parachain_reachable(1004); + let kill_identity_call = PeopleCall::Identity(pallet_identity::Call::::kill_identity { target: people_westend_runtime::MultiAddress::Id(PeopleWestend::account_id_of( @@ -253,6 +261,8 @@ fn relay_commands_kill_identity_wrong_origin() { type RuntimeEvent = ::RuntimeEvent; type PeopleRuntime = ::Runtime; + Dmp::make_parachain_reachable(1004); + let kill_identity_call = PeopleCall::Identity(pallet_identity::Call::::kill_identity { target: people_westend_runtime::MultiAddress::Id(PeopleWestend::account_id_of( @@ -303,6 +313,8 @@ fn relay_commands_add_remove_username_authority() { type PeopleCall = ::RuntimeCall; type PeopleRuntime = ::Runtime; + Dmp::make_parachain_reachable(1004); + let add_username_authority = PeopleCall::Identity(pallet_identity::Call::::add_username_authority { authority: people_westend_runtime::MultiAddress::Id(people_westend_alice.clone()), @@ -392,6 +404,8 @@ fn relay_commands_add_remove_username_authority() { type PeopleCall = ::RuntimeCall; type PeopleRuntime = ::Runtime; + Dmp::make_parachain_reachable(1004); + let remove_username_authority = PeopleCall::Identity(pallet_identity::Call::< PeopleRuntime, >::remove_username_authority { @@ -455,6 +469,8 @@ fn relay_commands_add_remove_username_authority_wrong_origin() { type PeopleCall = ::RuntimeCall; type PeopleRuntime = ::Runtime; + Dmp::make_parachain_reachable(1004); + let add_username_authority = PeopleCall::Identity(pallet_identity::Call::< PeopleRuntime, >::add_username_authority { @@ -503,6 +519,8 @@ fn relay_commands_add_remove_username_authority_wrong_origin() { suffix: b"suffix1".into(), }); + Dmp::make_parachain_reachable(1004); + let remove_authority_xcm_msg = RuntimeCall::XcmPallet(pallet_xcm::Call::::send { dest: bx!(VersionedLocation::from(Location::new(0, [Parachain(1004)]))), diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 949640dd4be6..81ebc7e09494 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -146,6 +146,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "cumulus-pallet-aura-ext/try-runtime", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml index 8e47146a06c3..7dd2a4ab4b51 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml @@ -150,6 +150,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "cumulus-pallet-aura-ext/try-runtime", diff --git a/cumulus/parachains/runtimes/assets/common/Cargo.toml b/cumulus/parachains/runtimes/assets/common/Cargo.toml index fa9efbca7a39..552afa4daa68 100644 --- a/cumulus/parachains/runtimes/assets/common/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/common/Cargo.toml @@ -66,4 +66,5 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index c0d6db5ad500..ff50223ef575 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -266,6 +266,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index f429a28a2e52..efdd0abbb8ee 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -263,6 +263,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml index 76a89bcb2e72..9eacb27639a3 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml @@ -41,4 +41,5 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml index dc4b73db69e3..2e35fe761c04 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml @@ -138,6 +138,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "cumulus-pallet-aura-ext/try-runtime", diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml index 1aeff5eb2e48..260c748819ae 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml @@ -173,6 +173,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml index ab621134b252..aa692c3c7e74 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml @@ -180,6 +180,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml index 44dfbf93c30e..226e1c817bb8 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml @@ -177,6 +177,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml b/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml index 9bbdb8d2ee08..f2922b710e24 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/Cargo.toml @@ -77,6 +77,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] std = [ "codec/std", diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml index 893133bf3c1a..4984f6314f87 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml @@ -176,6 +176,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml index 66b324b51af4..7822df585a58 100644 --- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml @@ -176,6 +176,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index 3a6b9d42f211..3bd1e5c6f436 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -175,6 +175,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml index 4713f4398eaa..035d0ac94be6 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml @@ -136,6 +136,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] # A feature that should be enabled when the runtime should be built for on-chain diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index f5ce040bb530..3bfb79610448 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -78,6 +78,7 @@ runtime-benchmarks = [ "people-rococo-runtime/runtime-benchmarks", "people-westend-runtime/runtime-benchmarks", "rococo-parachain-runtime/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "polkadot-omni-node-lib/try-runtime", diff --git a/cumulus/primitives/core/Cargo.toml b/cumulus/primitives/core/Cargo.toml index b5bfe4fbc889..307860897aec 100644 --- a/cumulus/primitives/core/Cargo.toml +++ b/cumulus/primitives/core/Cargo.toml @@ -43,4 +43,5 @@ runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/cumulus/primitives/utility/Cargo.toml b/cumulus/primitives/utility/Cargo.toml index 1444571edbe0..f26e34a29509 100644 --- a/cumulus/primitives/utility/Cargo.toml +++ b/cumulus/primitives/utility/Cargo.toml @@ -52,4 +52,5 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml index 7f58a56d5d16..c1e06dd830b5 100644 --- a/polkadot/node/service/Cargo.toml +++ b/polkadot/node/service/Cargo.toml @@ -210,6 +210,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "westend-runtime?/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-system/try-runtime", diff --git a/polkadot/parachain/src/primitives.rs b/polkadot/parachain/src/primitives.rs index c5757928c3fc..1f2f9e2e9cdc 100644 --- a/polkadot/parachain/src/primitives.rs +++ b/polkadot/parachain/src/primitives.rs @@ -57,6 +57,8 @@ impl HeadData { } } +impl codec::EncodeLike for alloc::vec::Vec {} + /// Parachain validation code. #[derive( PartialEq, @@ -154,6 +156,9 @@ pub struct BlockData(#[cfg_attr(feature = "std", serde(with = "bytes"))] pub Vec #[cfg_attr(feature = "std", derive(derive_more::Display))] pub struct Id(u32); +impl codec::EncodeLike for Id {} +impl codec::EncodeLike for u32 {} + impl TypeId for Id { const TYPE_ID: [u8; 4] = *b"para"; } diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index 1646db54455a..4b307b56bcbe 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -142,6 +142,7 @@ runtime-benchmarks = [ "sp-staking/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-election-provider-support/try-runtime", diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index 126c886280e6..e3835b692526 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -160,12 +160,22 @@ pub trait OnReapIdentity { /// - `bytes`: The byte size of `IdentityInfo`. /// - `subs`: The number of sub-accounts they had. fn on_reap_identity(who: &AccountId, bytes: u32, subs: u32) -> DispatchResult; + + /// Ensure that identity reaping will be succesful in benchmarking. + /// + /// Should setup the state in a way that the same call ot `[Self::on_reap_identity]` will be + /// successful. + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_identity_reaping(who: &AccountId, bytes: u32, subs: u32); } impl OnReapIdentity for () { fn on_reap_identity(_who: &AccountId, _bytes: u32, _subs: u32) -> DispatchResult { Ok(()) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_identity_reaping(_: &AccountId, _: u32, _: u32) {} } #[cfg(feature = "runtime-benchmarks")] @@ -219,6 +229,12 @@ mod benchmarks { } Identity::::set_subs(target_origin.clone(), subs.clone())?; + T::ReapIdentityHandler::ensure_successful_identity_reaping( + &target, + info.encoded_size() as u32, + subs.len() as u32, + ); + // add registrars and provide judgements let registrar_origin = T::RegistrarOrigin::try_successful_origin() .expect("RegistrarOrigin has no successful origin required for the benchmark"); diff --git a/polkadot/runtime/common/src/paras_sudo_wrapper.rs b/polkadot/runtime/common/src/paras_sudo_wrapper.rs index a93c209e9279..bd5984b3b63e 100644 --- a/polkadot/runtime/common/src/paras_sudo_wrapper.rs +++ b/polkadot/runtime/common/src/paras_sudo_wrapper.rs @@ -48,6 +48,8 @@ pub mod pallet { /// A DMP message couldn't be sent because it exceeds the maximum size allowed for a /// downward message. ExceedsMaxMessageSize, + /// A DMP message couldn't be sent because the destination is unreachable. + Unroutable, /// Could not schedule para cleanup. CouldntCleanup, /// Not a parathread (on-demand parachain). @@ -157,6 +159,7 @@ pub mod pallet { { dmp::QueueDownwardMessageError::ExceedsMaxMessageSize => Error::::ExceedsMaxMessageSize.into(), + dmp::QueueDownwardMessageError::Unroutable => Error::::Unroutable.into(), }) } diff --git a/polkadot/runtime/common/src/xcm_sender.rs b/polkadot/runtime/common/src/xcm_sender.rs index 7ff7f69faf14..32ea4fdd2f27 100644 --- a/polkadot/runtime/common/src/xcm_sender.rs +++ b/polkadot/runtime/common/src/xcm_sender.rs @@ -138,6 +138,13 @@ where .map(|()| hash) .map_err(|_| SendError::Transport(&"Error placing into DMP queue")) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(location: Option) { + if let Some((0, [Parachain(id)])) = location.as_ref().map(|l| l.unpack()) { + dmp::Pallet::::make_parachain_reachable(*id); + } + } } impl InspectMessageQueues for ChildParachainRouter { @@ -190,7 +197,7 @@ impl< ExistentialDeposit: Get>, PriceForDelivery: PriceForMessageDelivery, Parachain: Get, - ToParachainHelper: EnsureForParachain, + ToParachainHelper: polkadot_runtime_parachains::EnsureForParachain, > xcm_builder::EnsureDelivery for ToParachainDeliveryHelper< XcmConfig, @@ -219,6 +226,9 @@ impl< return (None, None) } + // allow more initialization for target parachain + ToParachainHelper::ensure(Parachain::get()); + let mut fees_mode = None; if !XcmConfig::FeeManager::is_waived(Some(origin_ref), fee_reason) { // if not waived, we need to set up accounts for paying and receiving fees @@ -238,9 +248,6 @@ impl< XcmConfig::AssetTransactor::deposit_asset(&fee, &origin_ref, None).unwrap(); } - // allow more initialization for target parachain - ToParachainHelper::ensure(Parachain::get()); - // expected worst case - direct withdraw fees_mode = Some(FeesMode { jit_withdraw: true }); } @@ -248,18 +255,6 @@ impl< } } -/// Ensure more initialization for `ParaId`. (e.g. open HRMP channels, ...) -#[cfg(feature = "runtime-benchmarks")] -pub trait EnsureForParachain { - fn ensure(para_id: ParaId); -} -#[cfg(feature = "runtime-benchmarks")] -impl EnsureForParachain for () { - fn ensure(_: ParaId) { - // doing nothing - } -} - #[cfg(test)] mod tests { use super::*; @@ -349,6 +344,8 @@ mod tests { c.max_downward_message_size = u32::MAX; }); + dmp::Pallet::::make_parachain_reachable(5555); + // Check that the good message is validated: assert_ok!(::validate( &mut Some(dest.into()), diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index b01778eeb424..b583e9c6cc50 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -140,6 +140,7 @@ runtime-benchmarks = [ "sp-std", "static_assertions", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support-test/try-runtime", diff --git a/polkadot/runtime/parachains/src/coretime/benchmarking.rs b/polkadot/runtime/parachains/src/coretime/benchmarking.rs index 6d593f1954ff..49e3d8a88c01 100644 --- a/polkadot/runtime/parachains/src/coretime/benchmarking.rs +++ b/polkadot/runtime/parachains/src/coretime/benchmarking.rs @@ -43,6 +43,8 @@ mod benchmarks { .unwrap(); on_demand::Revenue::::put(rev); + crate::paras::Heads::::insert(ParaId::from(T::BrokerId::get()), vec![1, 2, 3]); + ::Currency::make_free_balance_be( &>::account_id(), minimum_balance * (mhr * (mhr + 1)).into(), diff --git a/polkadot/runtime/parachains/src/dmp.rs b/polkadot/runtime/parachains/src/dmp.rs index 03580e11b8e9..3c9cf8004186 100644 --- a/polkadot/runtime/parachains/src/dmp.rs +++ b/polkadot/runtime/parachains/src/dmp.rs @@ -44,7 +44,7 @@ use crate::{ configuration::{self, HostConfiguration}, - initializer, FeeTracker, + initializer, paras, FeeTracker, }; use alloc::vec::Vec; use core::fmt; @@ -72,12 +72,15 @@ const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0 pub enum QueueDownwardMessageError { /// The message being sent exceeds the configured max message size. ExceedsMaxMessageSize, + /// The destination is unknown. + Unroutable, } impl From for SendError { fn from(err: QueueDownwardMessageError) -> Self { match err { QueueDownwardMessageError::ExceedsMaxMessageSize => SendError::ExceedsMaxMessageSize, + QueueDownwardMessageError::Unroutable => SendError::Unroutable, } } } @@ -116,7 +119,7 @@ pub mod pallet { pub struct Pallet(_); #[pallet::config] - pub trait Config: frame_system::Config + configuration::Config {} + pub trait Config: frame_system::Config + configuration::Config + paras::Config {} /// The downward messages addressed for a certain para. #[pallet::storage] @@ -200,6 +203,11 @@ impl Pallet { return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) } + // If the head exists, we assume the parachain is legit and exists. + if !paras::Heads::::contains_key(para) { + return Err(QueueDownwardMessageError::Unroutable) + } + Ok(()) } @@ -217,14 +225,7 @@ impl Pallet { msg: DownwardMessage, ) -> Result<(), QueueDownwardMessageError> { let serialized_len = msg.len() as u32; - if serialized_len > config.max_downward_message_size { - return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) - } - - // Hard limit on Queue size - if Self::dmq_length(para) > Self::dmq_max_length(config.max_downward_message_size) { - return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) - } + Self::can_queue_downward_message(config, ¶, &msg)?; let inbound = InboundDownwardMessage { msg, sent_at: frame_system::Pallet::::block_number() }; @@ -336,6 +337,15 @@ impl Pallet { ) -> Vec>> { DownwardMessageQueues::::get(&recipient) } + + /// Make the parachain reachable for downward messages. + /// + /// Only useable in benchmarks or tests. + #[cfg(any(feature = "runtime-benchmarks", feature = "std"))] + pub fn make_parachain_reachable(para: impl Into) { + let para = para.into(); + crate::paras::Heads::::insert(para, para.encode()); + } } impl FeeTracker for Pallet { @@ -359,3 +369,10 @@ impl FeeTracker for Pallet { }) } } + +#[cfg(feature = "runtime-benchmarks")] +impl crate::EnsureForParachain for Pallet { + fn ensure(para: ParaId) { + Self::make_parachain_reachable(para); + } +} diff --git a/polkadot/runtime/parachains/src/dmp/tests.rs b/polkadot/runtime/parachains/src/dmp/tests.rs index de1515958125..617c9488bd2a 100644 --- a/polkadot/runtime/parachains/src/dmp/tests.rs +++ b/polkadot/runtime/parachains/src/dmp/tests.rs @@ -61,6 +61,12 @@ fn queue_downward_message( Dmp::queue_downward_message(&configuration::ActiveConfig::::get(), para_id, msg) } +fn register_paras(paras: &[ParaId]) { + paras.iter().for_each(|p| { + Dmp::make_parachain_reachable(*p); + }); +} + #[test] fn clean_dmp_works() { let a = ParaId::from(1312); @@ -68,6 +74,8 @@ fn clean_dmp_works() { let c = ParaId::from(123); new_test_ext(default_genesis_config()).execute_with(|| { + register_paras(&[a, b, c]); + // enqueue downward messages to A, B and C. queue_downward_message(a, vec![1, 2, 3]).unwrap(); queue_downward_message(b, vec![4, 5, 6]).unwrap(); @@ -89,6 +97,8 @@ fn dmq_length_and_head_updated_properly() { let b = ParaId::from(228); new_test_ext(default_genesis_config()).execute_with(|| { + register_paras(&[a, b]); + assert_eq!(Dmp::dmq_length(a), 0); assert_eq!(Dmp::dmq_length(b), 0); @@ -101,11 +111,30 @@ fn dmq_length_and_head_updated_properly() { }); } +#[test] +fn dmq_fail_if_para_does_not_exist() { + let a = ParaId::from(1312); + + new_test_ext(default_genesis_config()).execute_with(|| { + assert_eq!(Dmp::dmq_length(a), 0); + + assert!(matches!( + queue_downward_message(a, vec![1, 2, 3]), + Err(QueueDownwardMessageError::Unroutable) + )); + + assert_eq!(Dmp::dmq_length(a), 0); + assert!(Dmp::dmq_mqc_head(a).is_zero()); + }); +} + #[test] fn dmp_mqc_head_fixture() { let a = ParaId::from(2000); new_test_ext(default_genesis_config()).execute_with(|| { + register_paras(&[a]); + run_to_block(2, None); assert!(Dmp::dmq_mqc_head(a).is_zero()); queue_downward_message(a, vec![1, 2, 3]).unwrap(); @@ -125,6 +154,8 @@ fn check_processed_downward_messages() { let a = ParaId::from(1312); new_test_ext(default_genesis_config()).execute_with(|| { + register_paras(&[a]); + let block_number = System::block_number(); // processed_downward_messages=0 is allowed when the DMQ is empty. @@ -150,6 +181,8 @@ fn check_processed_downward_messages_advancement_rule() { let a = ParaId::from(1312); new_test_ext(default_genesis_config()).execute_with(|| { + register_paras(&[a]); + let block_number = System::block_number(); run_to_block(block_number + 1, None); @@ -170,6 +203,8 @@ fn dmq_pruning() { let a = ParaId::from(1312); new_test_ext(default_genesis_config()).execute_with(|| { + register_paras(&[a]); + assert_eq!(Dmp::dmq_length(a), 0); queue_downward_message(a, vec![1, 2, 3]).unwrap(); @@ -194,6 +229,8 @@ fn queue_downward_message_critical() { genesis.configuration.config.max_downward_message_size = 7; new_test_ext(genesis).execute_with(|| { + register_paras(&[a]); + let smol = [0; 3].to_vec(); let big = [0; 8].to_vec(); @@ -215,6 +252,8 @@ fn verify_dmq_mqc_head_is_externally_accessible() { let a = ParaId::from(2020); new_test_ext(default_genesis_config()).execute_with(|| { + register_paras(&[a]); + let head = sp_io::storage::get(&well_known_keys::dmq_mqc_head(a)); assert_eq!(head, None); @@ -235,9 +274,12 @@ fn verify_dmq_mqc_head_is_externally_accessible() { #[test] fn verify_fee_increase_and_decrease() { let a = ParaId::from(123); + let mut genesis = default_genesis_config(); genesis.configuration.config.max_downward_message_size = 16777216; new_test_ext(genesis).execute_with(|| { + register_paras(&[a]); + let initial = InitialFactor::get(); assert_eq!(DeliveryFeeFactor::::get(a), initial); @@ -287,6 +329,8 @@ fn verify_fee_factor_reaches_high_value() { let mut genesis = default_genesis_config(); genesis.configuration.config.max_downward_message_size = 51200; new_test_ext(genesis).execute_with(|| { + register_paras(&[a]); + let max_messages = Dmp::dmq_max_length(ActiveConfig::::get().max_downward_message_size); let mut total_fee_factor = FixedU128::from_float(1.0); diff --git a/polkadot/runtime/parachains/src/lib.rs b/polkadot/runtime/parachains/src/lib.rs index 828c0b9bcef2..b1ff5419470e 100644 --- a/polkadot/runtime/parachains/src/lib.rs +++ b/polkadot/runtime/parachains/src/lib.rs @@ -114,3 +114,19 @@ pub fn schedule_code_upgrade( pub fn set_current_head(id: ParaId, new_head: HeadData) { paras::Pallet::::set_current_head(id, new_head) } + +/// Ensure more initialization for `ParaId` when benchmarking. (e.g. open HRMP channels, ...) +#[cfg(feature = "runtime-benchmarks")] +pub trait EnsureForParachain { + fn ensure(para_id: ParaId); +} + +#[cfg(feature = "runtime-benchmarks")] +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl EnsureForParachain for Tuple { + fn ensure(para: ParaId) { + for_tuples!( #( + Tuple::ensure(para); + )* ); + } +} diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index 764c53abbfcb..1fd32c5d0c32 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -277,6 +277,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-executive/try-runtime", diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 7d7e9fa9f06c..a5cb2eddfa0d 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -176,4 +176,9 @@ where )?; Ok(()) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_identity_reaping(_: &AccountId, _: u32, _: u32) { + crate::Dmp::make_parachain_reachable(1004); + } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index c832ace91c07..3304f89fc0cc 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -2471,14 +2471,14 @@ sp_api::impl_runtime_apis! { ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, AssetHubParaId, - (), + Dmp, >, polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper< XcmConfig, ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, RandomParaId, - (), + Dmp, > ); @@ -2537,7 +2537,7 @@ sp_api::impl_runtime_apis! { ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, AssetHubParaId, - (), + Dmp, >; fn valid_destination() -> Result { Ok(AssetHub::get()) diff --git a/polkadot/runtime/test-runtime/Cargo.toml b/polkadot/runtime/test-runtime/Cargo.toml index 90a0285cd17b..8b33bf9cebc6 100644 --- a/polkadot/runtime/test-runtime/Cargo.toml +++ b/polkadot/runtime/test-runtime/Cargo.toml @@ -154,4 +154,5 @@ runtime-benchmarks = [ "sp-staking/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index 584f5855b7a4..13e39b5aa317 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -298,6 +298,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-election-provider-support/try-runtime", diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 8cb597cbaa95..0e0d345a0ed4 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -176,4 +176,9 @@ where )?; Ok(()) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_identity_reaping(_: &AccountId, _: u32, _: u32) { + crate::Dmp::make_parachain_reachable(1004); + } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index c540b3773286..f9ef74fee29c 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2639,14 +2639,14 @@ sp_api::impl_runtime_apis! { ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, AssetHubParaId, - (), + Dmp, >, polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper< xcm_config::XcmConfig, ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, RandomParaId, - (), + Dmp, > ); @@ -2712,7 +2712,7 @@ sp_api::impl_runtime_apis! { ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, AssetHubParaId, - (), + Dmp, >; fn valid_destination() -> Result { Ok(AssetHub::get()) diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index 113e72c27ae1..7ac12dc1e377 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -51,3 +51,7 @@ json-schema = [ "dep:schemars", "sp-weights/json-schema", ] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] diff --git a/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml b/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml index fe2b78163223..d4131cc53ee6 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml +++ b/polkadot/xcm/pallet-xcm-benchmarks/Cargo.toml @@ -64,4 +64,5 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs index 303ff9493f71..4428076aa077 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs @@ -231,6 +231,13 @@ benchmarks_instance_pallet! { let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); assert!(T::TransactAsset::balance(&dest_account).is_zero()); + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + let (_, _) = T::DeliveryHelper::ensure_successful_delivery( + &Default::default(), + &dest_location, + FeeReason::ChargeFees, + ); + let mut executor = new_executor::(Default::default()); executor.set_holding(holding.into()); let instruction = Instruction::>::DepositAsset { @@ -257,6 +264,13 @@ benchmarks_instance_pallet! { let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); assert!(T::TransactAsset::balance(&dest_account).is_zero()); + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + let (_, _) = T::DeliveryHelper::ensure_successful_delivery( + &Default::default(), + &dest_location, + FeeReason::ChargeFees, + ); + let mut executor = new_executor::(Default::default()); executor.set_holding(holding.into()); let instruction = Instruction::>::DepositReserveAsset { @@ -281,12 +295,20 @@ benchmarks_instance_pallet! { // Checked account starts at zero assert!(T::CheckedAccount::get().map_or(true, |(c, _)| T::TransactAsset::balance(&c).is_zero())); + let dest_location = T::valid_destination()?; + + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + let (_, _) = T::DeliveryHelper::ensure_successful_delivery( + &Default::default(), + &dest_location, + FeeReason::ChargeFees, + ); let mut executor = new_executor::(Default::default()); executor.set_holding(holding.into()); let instruction = Instruction::>::InitiateTeleport { assets: asset.into(), - dest: T::valid_destination()?, + dest: dest_location, xcm: Xcm::new(), }; let xcm = Xcm(vec![instruction]); @@ -303,6 +325,15 @@ benchmarks_instance_pallet! { let (sender_account, sender_location) = account_and_location::(1); let asset = T::get_asset(); let mut holding = T::worst_case_holding(1); + let dest_location = T::valid_destination()?; + + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + let (_, _) = T::DeliveryHelper::ensure_successful_delivery( + &sender_location, + &dest_location, + FeeReason::ChargeFees, + ); + let sender_account_balance_before = T::TransactAsset::balance(&sender_account); // Add our asset to the holding. @@ -311,7 +342,7 @@ benchmarks_instance_pallet! { let mut executor = new_executor::(sender_location); executor.set_holding(holding.into()); let instruction = Instruction::>::InitiateTransfer { - destination: T::valid_destination()?, + destination: dest_location, // ReserveDeposit is the most expensive filter. remote_fees: Some(AssetTransferFilter::ReserveDeposit(asset.clone().into())), // It's more expensive if we reanchor the origin. diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index 84d4cba1dbe1..1c62bb5886d8 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -407,6 +407,9 @@ mod benchmarks { let mut executor = new_executor::(origin.clone()); let instruction = Instruction::SubscribeVersion { query_id, max_response_weight }; let xcm = Xcm(vec![instruction]); + + T::DeliveryHelper::ensure_successful_delivery(&origin, &origin, FeeReason::QueryPallet); + #[block] { executor.bench_process(xcm)?; @@ -422,6 +425,9 @@ mod benchmarks { use xcm_executor::traits::VersionChangeNotifier; // First we need to subscribe to notifications. let (origin, _) = T::transact_origin_and_runtime_call()?; + + T::DeliveryHelper::ensure_successful_delivery(&origin, &origin, FeeReason::QueryPallet); + let query_id = Default::default(); let max_response_weight = Default::default(); ::SubscriptionService::start( diff --git a/polkadot/xcm/pallet-xcm/Cargo.toml b/polkadot/xcm/pallet-xcm/Cargo.toml index e8cdd3b4931b..81fcea05cac2 100644 --- a/polkadot/xcm/pallet-xcm/Cargo.toml +++ b/polkadot/xcm/pallet-xcm/Cargo.toml @@ -70,6 +70,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index e493d4838f5c..dd3c58c5dc77 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -96,6 +96,13 @@ benchmarks! { )? .into(); let versioned_msg = VersionedXcm::from(msg); + + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + T::DeliveryHelper::ensure_successful_delivery( + &Default::default(), + &versioned_dest.clone().try_into().unwrap(), + FeeReason::ChargeFees, + ); }: _>(send_origin, Box::new(versioned_dest), Box::new(versioned_msg)) teleport_assets { @@ -164,7 +171,7 @@ benchmarks! { } // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) - let (_, _) = T::DeliveryHelper::ensure_successful_delivery( + T::DeliveryHelper::ensure_successful_delivery( &origin_location, &destination, FeeReason::ChargeFees, @@ -227,6 +234,13 @@ benchmarks! { let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); let versioned_assets: VersionedAssets = assets.into(); + + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + T::DeliveryHelper::ensure_successful_delivery( + &Default::default(), + &versioned_dest.clone().try_into().unwrap(), + FeeReason::ChargeFees, + ); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0, WeightLimit::Unlimited) verify { // run provided verification function @@ -259,6 +273,14 @@ benchmarks! { BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )? .into(); + + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + T::DeliveryHelper::ensure_successful_delivery( + &Default::default(), + &versioned_loc.clone().try_into().unwrap(), + FeeReason::ChargeFees, + ); + }: _(RawOrigin::Root, Box::new(versioned_loc)) force_unsubscribe_version_notify { @@ -266,6 +288,14 @@ benchmarks! { BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )?; let versioned_loc: VersionedLocation = loc.clone().into(); + + // Ensure that origin can send to destination (e.g. setup delivery fees, ensure router setup, ...) + T::DeliveryHelper::ensure_successful_delivery( + &Default::default(), + &versioned_loc.clone().try_into().unwrap(), + FeeReason::ChargeFees, + ); + let _ = crate::Pallet::::request_version_notify(loc); }: _(RawOrigin::Root, Box::new(versioned_loc)) diff --git a/polkadot/xcm/src/v5/traits.rs b/polkadot/xcm/src/v5/traits.rs index 71b67e97d5fe..79d328561428 100644 --- a/polkadot/xcm/src/v5/traits.rs +++ b/polkadot/xcm/src/v5/traits.rs @@ -460,6 +460,10 @@ pub trait SendXcm { /// Actually carry out the delivery operation for a previously validated message sending. fn deliver(ticket: Self::Ticket) -> result::Result; + + /// Ensure `[Self::delivery]` is successful for the given `location` when called in benchmarks. + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(_location: Option) {} } #[impl_trait_for_tuples::impl_for_tuples(30)] @@ -500,6 +504,13 @@ impl SendXcm for Tuple { )* ); Err(SendError::Unroutable) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(location: Option) { + for_tuples!( #( + return Tuple::ensure_successful_delivery(location.clone()); + )* ); + } } /// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps diff --git a/polkadot/xcm/xcm-builder/Cargo.toml b/polkadot/xcm/xcm-builder/Cargo.toml index 2819a0b0a555..e64ab1928132 100644 --- a/polkadot/xcm/xcm-builder/Cargo.toml +++ b/polkadot/xcm/xcm-builder/Cargo.toml @@ -59,6 +59,7 @@ runtime-benchmarks = [ "polkadot-test-runtime/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] std = [ "codec/std", diff --git a/polkadot/xcm/xcm-builder/src/pay.rs b/polkadot/xcm/xcm-builder/src/pay.rs index 978c6870cdaf..0093051290b7 100644 --- a/polkadot/xcm/xcm-builder/src/pay.rs +++ b/polkadot/xcm/xcm-builder/src/pay.rs @@ -70,8 +70,8 @@ impl< Router: SendXcm, Querier: QueryHandler, Timeout: Get, - Beneficiary: Clone, - AssetKind, + Beneficiary: Clone + core::fmt::Debug, + AssetKind: core::fmt::Debug, AssetKindToLocatableAsset: TryConvert, BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, Location>, > Pay @@ -144,10 +144,9 @@ impl< } #[cfg(feature = "runtime-benchmarks")] - fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) { - // We cannot generally guarantee this will go through successfully since we don't have any - // control over the XCM transport layers. We just assume that the benchmark environment - // will be sending it somewhere sensible. + fn ensure_successful(_: &Self::Beneficiary, asset_kind: Self::AssetKind, _: Self::Balance) { + let locatable = AssetKindToLocatableAsset::try_convert(asset_kind).unwrap(); + Router::ensure_successful_delivery(Some(locatable.location)); } #[cfg(feature = "runtime-benchmarks")] diff --git a/polkadot/xcm/xcm-builder/src/routing.rs b/polkadot/xcm/xcm-builder/src/routing.rs index fc2de89d2128..5b0d0a5f9835 100644 --- a/polkadot/xcm/xcm-builder/src/routing.rs +++ b/polkadot/xcm/xcm-builder/src/routing.rs @@ -60,6 +60,11 @@ impl SendXcm for WithUniqueTopic { Inner::deliver(ticket)?; Ok(unique_id) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(location: Option) { + Inner::ensure_successful_delivery(location); + } } impl InspectMessageQueues for WithUniqueTopic { fn clear_messages() { @@ -114,6 +119,11 @@ impl SendXcm for WithTopicSource) { + Inner::ensure_successful_delivery(location); + } } /// Trait for a type which ensures all requirements for successful delivery with XCM transport @@ -211,4 +221,9 @@ impl SendXcm for EnsureDecodableXcm { fn deliver(ticket: Self::Ticket) -> Result { Inner::deliver(ticket) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(location: Option) { + Inner::ensure_successful_delivery(location); + } } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs index 062faee2abd9..b4718edc6c98 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs @@ -22,7 +22,7 @@ use frame_support::{assert_ok, traits::tokens::Pay}; /// Type representing both a location and an asset that is held at that location. /// The id of the held asset is relative to the location where it is being held. -#[derive(Encode, Decode, Clone, PartialEq, Eq)] +#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)] pub struct AssetKind { destination: Location, asset_id: AssetId, diff --git a/polkadot/xcm/xcm-builder/src/universal_exports.rs b/polkadot/xcm/xcm-builder/src/universal_exports.rs index aae8438c78d2..6b3c3adf737d 100644 --- a/polkadot/xcm/xcm-builder/src/universal_exports.rs +++ b/polkadot/xcm/xcm-builder/src/universal_exports.rs @@ -95,6 +95,9 @@ impl> SendXcm fn deliver(ticket: Exporter::Ticket) -> Result { Exporter::deliver(ticket) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(_: Option) {} } pub trait ExporterFor { @@ -261,6 +264,11 @@ impl Result { Router::deliver(validation) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(location: Option) { + Router::ensure_successful_delivery(location); + } } /// Implementation of `SendXcm` which wraps the message inside an `ExportMessage` instruction @@ -361,6 +369,11 @@ impl Result { Router::deliver(ticket) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(location: Option) { + Router::ensure_successful_delivery(location); + } } impl InspectMessageQueues @@ -613,6 +626,9 @@ mod tests { fn deliver(_ticket: Self::Ticket) -> Result { Ok([0; 32]) } + + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful_delivery(_: Option) {} } impl> ExportXcm for OkFor { type Ticket = (); diff --git a/polkadot/xcm/xcm-executor/Cargo.toml b/polkadot/xcm/xcm-executor/Cargo.toml index 20ca40de5faa..eb558c0fcc19 100644 --- a/polkadot/xcm/xcm-executor/Cargo.toml +++ b/polkadot/xcm/xcm-executor/Cargo.toml @@ -32,6 +32,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "xcm/runtime-benchmarks", ] std = [ "codec/std", diff --git a/polkadot/xcm/xcm-executor/integration-tests/Cargo.toml b/polkadot/xcm/xcm-executor/integration-tests/Cargo.toml index 7e6bfe967b90..a89dd74a44fa 100644 --- a/polkadot/xcm/xcm-executor/integration-tests/Cargo.toml +++ b/polkadot/xcm/xcm-executor/integration-tests/Cargo.toml @@ -13,9 +13,12 @@ workspace = true [dependencies] codec = { workspace = true, default-features = true } frame-support = { workspace = true } +frame-system = { workspace = true, default-features = true } futures = { workspace = true } pallet-transaction-payment = { workspace = true, default-features = true } +pallet-sudo = { workspace = true, default-features = true } pallet-xcm = { workspace = true, default-features = true } +polkadot-runtime-parachains = { workspace = true, default-features = true } polkadot-test-client = { workspace = true } polkadot-test-runtime = { workspace = true } polkadot-test-service = { workspace = true } @@ -30,4 +33,4 @@ sp-core = { workspace = true, default-features = true } [features] default = ["std"] -std = ["frame-support/std", "sp-runtime/std", "xcm/std"] +std = ["frame-support/std", "frame-system/std", "pallet-sudo/std", "polkadot-runtime-parachains/std", "sp-runtime/std", "xcm/std"] diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs index 699a081e4f22..dfcc3fc4187f 100644 --- a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs +++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs @@ -375,6 +375,26 @@ fn deposit_reserve_asset_works_for_any_xcm_sender() { let mut block_builder = client.init_polkadot_block_builder(); + // Make the para available, so that `DMP` doesn't reject the XCM because the para is unknown. + let make_para_available = + construct_extrinsic( + &client, + polkadot_test_runtime::RuntimeCall::Sudo(pallet_sudo::Call::sudo { + call: Box::new(polkadot_test_runtime::RuntimeCall::System( + frame_system::Call::set_storage { + items: vec![( + polkadot_runtime_parachains::paras::Heads::< + polkadot_test_runtime::Runtime, + >::hashed_key_for(2000u32), + vec![1, 2, 3], + )], + }, + )), + }), + sp_keyring::Sr25519Keyring::Alice, + 0, + ); + // Simulate execution of an incoming XCM message at the reserve chain let execute = construct_extrinsic( &client, @@ -383,9 +403,12 @@ fn deposit_reserve_asset_works_for_any_xcm_sender() { max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), }), sp_keyring::Sr25519Keyring::Alice, - 0, + 1, ); + block_builder + .push_polkadot_extrinsic(make_para_available) + .expect("pushes extrinsic"); block_builder.push_polkadot_extrinsic(execute).expect("pushes extrinsic"); let block = block_builder.build().expect("Finalizes the block").block; diff --git a/polkadot/xcm/xcm-runtime-apis/Cargo.toml b/polkadot/xcm/xcm-runtime-apis/Cargo.toml index 9ccca76c321c..9ada69a1933b 100644 --- a/polkadot/xcm/xcm-runtime-apis/Cargo.toml +++ b/polkadot/xcm/xcm-runtime-apis/Cargo.toml @@ -60,4 +60,5 @@ runtime-benchmarks = [ "pallet-xcm/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/polkadot/xcm/xcm-simulator/example/Cargo.toml b/polkadot/xcm/xcm-simulator/example/Cargo.toml index 6fbe9243944a..43f36fc8991a 100644 --- a/polkadot/xcm/xcm-simulator/example/Cargo.toml +++ b/polkadot/xcm/xcm-simulator/example/Cargo.toml @@ -50,4 +50,5 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml b/polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml index 04f8ba115173..a2e36db95ba6 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml +++ b/polkadot/xcm/xcm-simulator/fuzzer/Cargo.toml @@ -59,6 +59,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] [[bin]] diff --git a/prdoc/pr_6604.prdoc b/prdoc/pr_6604.prdoc new file mode 100644 index 000000000000..dc198287ff67 --- /dev/null +++ b/prdoc/pr_6604.prdoc @@ -0,0 +1,106 @@ +title: 'dmp: Check that the para exist before delivering a message' +doc: +- audience: Runtime Dev + description: | + Ensure that a para exists before trying to deliver a message to it. + Besides that `ensure_successful_delivery` function is added to `SendXcm`. This function + should be used by benchmarks to ensure that the delivery of a Xcm will work in the benchmark. +crates: +- name: polkadot-runtime-parachains + bump: major +- name: polkadot-runtime-common + bump: major +- name: polkadot-parachain-primitives + bump: major +- name: rococo-runtime + bump: major +- name: westend-runtime + bump: major +- name: pallet-xcm-benchmarks + bump: major +- name: pallet-xcm + bump: major +- name: cumulus-pallet-parachain-system + bump: major +- name: staging-xcm + bump: major +- name: staging-xcm-builder + bump: major +- name: bridge-runtime-common + bump: major +- name: pallet-xcm-bridge-hub-router + bump: major +- name: pallet-xcm-bridge-hub + bump: major +- name: snowbridge-pallet-inbound-queue + bump: major +- name: snowbridge-pallet-system + bump: major +- name: snowbridge-core + bump: major +- name: snowbridge-router-primitives + bump: major +- name: snowbridge-runtime-common + bump: major +- name: snowbridge-runtime-test-common + bump: major +- name: cumulus-pallet-dmp-queue + bump: major +- name: cumulus-pallet-xcmp-queue + bump: major +- name: parachains-common + bump: major +- name: asset-hub-rococo-runtime + bump: major +- name: asset-hub-westend-runtime + bump: major +- name: assets-common + bump: major +- name: bridge-hub-rococo-runtime + bump: major +- name: bridge-hub-westend-runtime + bump: major +- name: bridge-hub-common + bump: major +- name: collectives-westend-runtime + bump: major +- name: contracts-rococo-runtime + bump: major +- name: coretime-rococo-runtime + bump: major +- name: coretime-westend-runtime + bump: major +- name: glutton-westend-runtime + bump: major +- name: people-rococo-runtime + bump: major +- name: people-westend-runtime + bump: major +- name: penpal-runtime + bump: major +- name: rococo-parachain-runtime + bump: major +- name: polkadot-parachain-bin + bump: major +- name: cumulus-primitives-core + bump: major +- name: cumulus-primitives-utility + bump: major +- name: polkadot-service + bump: major +- name: staging-xcm-executor + bump: major +- name: xcm-runtime-apis + bump: major +- name: xcm-simulator-example + bump: major +- name: pallet-contracts + bump: major +- name: pallet-contracts-mock-network + bump: major +- name: pallet-revive + bump: major +- name: pallet-revive-mock-network + bump: major +- name: polkadot-sdk + bump: major diff --git a/substrate/frame/contracts/Cargo.toml b/substrate/frame/contracts/Cargo.toml index 316ea6813048..96351752918a 100644 --- a/substrate/frame/contracts/Cargo.toml +++ b/substrate/frame/contracts/Cargo.toml @@ -119,6 +119,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "wasm-instrument", "xcm-builder/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/substrate/frame/contracts/mock-network/Cargo.toml b/substrate/frame/contracts/mock-network/Cargo.toml index d6e2d51ef452..66137bc8a0c6 100644 --- a/substrate/frame/contracts/mock-network/Cargo.toml +++ b/substrate/frame/contracts/mock-network/Cargo.toml @@ -87,4 +87,5 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] diff --git a/substrate/frame/revive/Cargo.toml b/substrate/frame/revive/Cargo.toml index 2e069bacf737..e61554f5cfa0 100644 --- a/substrate/frame/revive/Cargo.toml +++ b/substrate/frame/revive/Cargo.toml @@ -119,6 +119,7 @@ runtime-benchmarks = [ "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/substrate/frame/revive/mock-network/Cargo.toml b/substrate/frame/revive/mock-network/Cargo.toml index c5b18b3fa290..6208db45a91e 100644 --- a/substrate/frame/revive/mock-network/Cargo.toml +++ b/substrate/frame/revive/mock-network/Cargo.toml @@ -85,6 +85,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "xcm/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml index d5ef707d2b8f..68d71b4a5d5e 100644 --- a/umbrella/Cargo.toml +++ b/umbrella/Cargo.toml @@ -362,6 +362,7 @@ runtime-benchmarks = [ "staging-node-inspect?/runtime-benchmarks", "staging-xcm-builder?/runtime-benchmarks", "staging-xcm-executor?/runtime-benchmarks", + "staging-xcm?/runtime-benchmarks", "xcm-runtime-apis?/runtime-benchmarks", ] try-runtime = [ From 459b4a6521d35f3e84a036262e64fa547a5b1ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal=20Murray?= Date: Thu, 12 Dec 2024 21:23:25 +0100 Subject: [PATCH 51/51] [pallet-broker] Fix auto renew benchmarks (#6505) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the broker pallet auto-renew benchmarks which have been broken since #4424, yielding `Weightless` due to some prices being set too low, as reported in #6474. Upon further investigation it turned out that the auto-renew contribution to `rotate_sale` was always failing but the error was mapped. This is also fixed at the cost of a bit of setup overhead. Fixes #6474 TODO: - [x] Re-run weights --------- Co-authored-by: GitHub Action Co-authored-by: command-bot <> Co-authored-by: Bastian Köcher --- .../src/weights/pallet_broker.rs | 246 +++++---- .../src/weights/pallet_broker.rs | 250 ++++----- prdoc/pr_6505.prdoc | 14 + substrate/frame/broker/src/benchmarking.rs | 191 ++++--- substrate/frame/broker/src/weights.rs | 486 +++++++++--------- 5 files changed, 639 insertions(+), 548 deletions(-) create mode 100644 prdoc/pr_6505.prdoc diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs index 35708f22de20..5cb01f62cd26 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_broker` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-x5tnzzy-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-acd6uxux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -54,8 +54,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_024_000 picoseconds. - Weight::from_parts(2_121_000, 0) + // Minimum execution time: 2_250_000 picoseconds. + Weight::from_parts(2_419_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -65,8 +65,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `10888` // Estimated: `13506` - // Minimum execution time: 21_654_000 picoseconds. - Weight::from_parts(22_591_000, 0) + // Minimum execution time: 25_785_000 picoseconds. + Weight::from_parts(26_335_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -77,8 +77,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12090` // Estimated: `13506` - // Minimum execution time: 20_769_000 picoseconds. - Weight::from_parts(21_328_000, 0) + // Minimum execution time: 24_549_000 picoseconds. + Weight::from_parts(25_010_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -93,8 +93,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `466` // Estimated: `1951` - // Minimum execution time: 10_404_000 picoseconds. - Weight::from_parts(10_941_000, 0) + // Minimum execution time: 14_135_000 picoseconds. + Weight::from_parts(14_603_000, 0) .saturating_add(Weight::from_parts(0, 1951)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -121,6 +121,8 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(1002), added: 1497, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:0 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::Status` (r:0 w:1) @@ -132,31 +134,33 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12599` // Estimated: `15065 + n * (1 ±0)` - // Minimum execution time: 44_085_000 picoseconds. - Weight::from_parts(127_668_002, 0) + // Minimum execution time: 54_087_000 picoseconds. + Weight::from_parts(145_466_213, 0) .saturating_add(Weight::from_parts(0, 15065)) - // Standard Error: 2_231 - .saturating_add(Weight::from_parts(20_604, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(13)) - .saturating_add(T::DbWeight::get().writes(59)) + // Standard Error: 2_407 + .saturating_add(Weight::from_parts(20_971, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(60)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:1 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Broker::Regions` (r:0 w:1) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `332` + // Measured: `437` // Estimated: `3593` - // Minimum execution time: 45_100_000 picoseconds. - Weight::from_parts(46_263_000, 0) + // Minimum execution time: 58_341_000 picoseconds. + Weight::from_parts(59_505_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Broker::Configuration` (r:1 w:0) @@ -169,16 +173,18 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `553` + // Measured: `658` // Estimated: `4698` - // Minimum execution time: 65_944_000 picoseconds. - Weight::from_parts(68_666_000, 0) + // Minimum execution time: 92_983_000 picoseconds. + Weight::from_parts(99_237_000, 0) .saturating_add(Weight::from_parts(0, 4698)) - .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `Broker::Regions` (r:1 w:1) @@ -187,8 +193,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `358` // Estimated: `3551` - // Minimum execution time: 13_794_000 picoseconds. - Weight::from_parts(14_450_000, 0) + // Minimum execution time: 17_512_000 picoseconds. + Weight::from_parts(18_099_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -199,8 +205,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `358` // Estimated: `3551` - // Minimum execution time: 15_316_000 picoseconds. - Weight::from_parts(15_787_000, 0) + // Minimum execution time: 18_715_000 picoseconds. + Weight::from_parts(19_768_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -211,8 +217,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `358` // Estimated: `3551` - // Minimum execution time: 16_375_000 picoseconds. - Weight::from_parts(17_113_000, 0) + // Minimum execution time: 20_349_000 picoseconds. + Weight::from_parts(21_050_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(3)) @@ -229,8 +235,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `937` // Estimated: `4681` - // Minimum execution time: 25_952_000 picoseconds. - Weight::from_parts(27_198_000, 0) + // Minimum execution time: 31_876_000 picoseconds. + Weight::from_parts(33_536_000, 0) .saturating_add(Weight::from_parts(0, 4681)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -249,8 +255,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `1003` // Estimated: `5996` - // Minimum execution time: 31_790_000 picoseconds. - Weight::from_parts(32_920_000, 0) + // Minimum execution time: 39_500_000 picoseconds. + Weight::from_parts(40_666_000, 0) .saturating_add(Weight::from_parts(0, 5996)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(5)) @@ -264,13 +270,13 @@ impl pallet_broker::WeightInfo for WeightInfo { /// The range of component `m` is `[1, 3]`. fn claim_revenue(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `652` + // Measured: `671` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 56_286_000 picoseconds. - Weight::from_parts(56_946_240, 0) + // Minimum execution time: 65_843_000 picoseconds. + Weight::from_parts(65_768_512, 0) .saturating_add(Weight::from_parts(0, 6196)) - // Standard Error: 44_472 - .saturating_add(Weight::from_parts(1_684_838, 0).saturating_mul(m.into())) + // Standard Error: 40_994 + .saturating_add(Weight::from_parts(2_084_877, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5)) @@ -290,11 +296,11 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn purchase_credit() -> Weight { // Proof Size summary in bytes: - // Measured: `322` - // Estimated: `3787` - // Minimum execution time: 64_967_000 picoseconds. - Weight::from_parts(66_504_000, 0) - .saturating_add(Weight::from_parts(0, 3787)) + // Measured: `323` + // Estimated: `3788` + // Minimum execution time: 73_250_000 picoseconds. + Weight::from_parts(75_059_000, 0) + .saturating_add(Weight::from_parts(0, 3788)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -306,8 +312,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `466` // Estimated: `3551` - // Minimum execution time: 37_552_000 picoseconds. - Weight::from_parts(46_263_000, 0) + // Minimum execution time: 55_088_000 picoseconds. + Weight::from_parts(65_329_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -322,8 +328,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `463` // Estimated: `3533` - // Minimum execution time: 79_625_000 picoseconds. - Weight::from_parts(86_227_000, 0) + // Minimum execution time: 102_280_000 picoseconds. + Weight::from_parts(130_319_000, 0) .saturating_add(Weight::from_parts(0, 3533)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -338,10 +344,10 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `857` + // Measured: `979` // Estimated: `3593` - // Minimum execution time: 88_005_000 picoseconds. - Weight::from_parts(92_984_000, 0) + // Minimum execution time: 78_195_000 picoseconds. + Weight::from_parts(105_946_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -354,8 +360,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `957` // Estimated: `4698` - // Minimum execution time: 38_877_000 picoseconds. - Weight::from_parts(40_408_000, 0) + // Minimum execution time: 41_642_000 picoseconds. + Weight::from_parts(48_286_000, 0) .saturating_add(Weight::from_parts(0, 4698)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -371,15 +377,13 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 20_581_000 picoseconds. - Weight::from_parts(21_610_297, 0) + // Minimum execution time: 23_727_000 picoseconds. + Weight::from_parts(25_029_439, 0) .saturating_add(Weight::from_parts(0, 3539)) - // Standard Error: 119 - .saturating_add(Weight::from_parts(144, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -390,11 +394,11 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `266` // Estimated: `1487` - // Minimum execution time: 6_079_000 picoseconds. - Weight::from_parts(6_540_110, 0) + // Minimum execution time: 7_887_000 picoseconds. + Weight::from_parts(8_477_863, 0) .saturating_add(Weight::from_parts(0, 1487)) - // Standard Error: 14 - .saturating_add(Weight::from_parts(10, 0).saturating_mul(n.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(76, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -406,36 +410,50 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `442` + // Measured: `461` // Estimated: `6196` - // Minimum execution time: 42_947_000 picoseconds. - Weight::from_parts(43_767_000, 0) + // Minimum execution time: 52_505_000 picoseconds. + Weight::from_parts(53_392_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(4)) } + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) /// Storage: `Broker::Reservations` (r:1 w:0) /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(12021), added: 12516, mode: `MaxEncodedLen`) /// Storage: `Broker::Leases` (r:1 w:1) /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(401), added: 896, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(1002), added: 1497, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:100 w:200) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:101 w:101) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:0 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) - /// Storage: `Broker::Workplan` (r:0 w:60) + /// Storage: `Broker::Workplan` (r:0 w:1000) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn rotate_sale(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `12514` - // Estimated: `13506` - // Minimum execution time: 93_426_000 picoseconds. - Weight::from_parts(96_185_447, 0) - .saturating_add(Weight::from_parts(0, 13506)) - // Standard Error: 116 - .saturating_add(Weight::from_parts(4, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(65)) + // Measured: `32497` + // Estimated: `233641 + n * (198 ±9)` + // Minimum execution time: 28_834_000 picoseconds. + Weight::from_parts(2_467_159_777, 0) + .saturating_add(Weight::from_parts(0, 233641)) + // Standard Error: 149_483 + .saturating_add(Weight::from_parts(4_045_956, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(126)) + .saturating_add(T::DbWeight::get().writes(181)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 198).saturating_mul(n.into())) } /// Storage: `Broker::InstaPoolIo` (r:1 w:0) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) @@ -445,8 +463,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `42` // Estimated: `3493` - // Minimum execution time: 5_842_000 picoseconds. - Weight::from_parts(6_077_000, 0) + // Minimum execution time: 7_689_000 picoseconds. + Weight::from_parts(7_988_000, 0) .saturating_add(Weight::from_parts(0, 3493)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -469,8 +487,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `1321` // Estimated: `4786` - // Minimum execution time: 33_278_000 picoseconds. - Weight::from_parts(34_076_000, 0) + // Minimum execution time: 37_394_000 picoseconds. + Weight::from_parts(38_379_000, 0) .saturating_add(Weight::from_parts(0, 4786)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -489,8 +507,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 15_779_000 picoseconds. - Weight::from_parts(16_213_000, 0) + // Minimum execution time: 19_203_000 picoseconds. + Weight::from_parts(19_797_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -501,8 +519,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_774_000 picoseconds. - Weight::from_parts(1_873_000, 0) + // Minimum execution time: 2_129_000 picoseconds. + Weight::from_parts(2_266_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -512,8 +530,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_858_000 picoseconds. - Weight::from_parts(1_991_000, 0) + // Minimum execution time: 2_233_000 picoseconds. + Weight::from_parts(2_351_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -531,8 +549,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `408` // Estimated: `1893` - // Minimum execution time: 10_874_000 picoseconds. - Weight::from_parts(11_265_000, 0) + // Minimum execution time: 15_716_000 picoseconds. + Weight::from_parts(16_160_000, 0) .saturating_add(Weight::from_parts(0, 1893)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -543,8 +561,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `470` // Estimated: `1886` - // Minimum execution time: 6_525_000 picoseconds. - Weight::from_parts(6_769_000, 0) + // Minimum execution time: 8_887_000 picoseconds. + Weight::from_parts(9_178_000, 0) .saturating_add(Weight::from_parts(0, 1886)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -557,36 +575,36 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::AutoRenewals` (r:1 w:1) - /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(1002), added: 1497, mode: `MaxEncodedLen`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn enable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `914` - // Estimated: `4698` - // Minimum execution time: 51_938_000 picoseconds. - Weight::from_parts(55_025_000, 4698) - .saturating_add(T::DbWeight::get().reads(8_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Measured: `2829` + // Estimated: `6196` + // Minimum execution time: 130_799_000 picoseconds. + Weight::from_parts(139_893_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) } /// Storage: `Broker::AutoRenewals` (r:1 w:1) - /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(1002), added: 1497, mode: `MaxEncodedLen`) fn disable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `480` - // Estimated: `1516` - // Minimum execution time: 9_628_000 picoseconds. - Weight::from_parts(10_400_000, 1516) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } + // Measured: `1307` + // Estimated: `2487` + // Minimum execution time: 22_945_000 picoseconds. + Weight::from_parts(24_855_000, 0) + .saturating_add(Weight::from_parts(0, 2487)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) @@ -601,11 +619,11 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn on_new_timeslice() -> Weight { // Proof Size summary in bytes: - // Measured: `322` - // Estimated: `3787` - // Minimum execution time: 45_561_000 picoseconds. - Weight::from_parts(47_306_000, 0) - .saturating_add(Weight::from_parts(0, 3787)) + // Measured: `323` + // Estimated: `3788` + // Minimum execution time: 56_864_000 picoseconds. + Weight::from_parts(59_119_000, 0) + .saturating_add(Weight::from_parts(0, 3788)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs index 74b1c4e47029..ad71691b2174 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_broker` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-x5tnzzy-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-acd6uxux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -54,8 +54,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_899_000 picoseconds. - Weight::from_parts(2_051_000, 0) + // Minimum execution time: 2_274_000 picoseconds. + Weight::from_parts(2_421_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -65,8 +65,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `10888` // Estimated: `13506` - // Minimum execution time: 21_965_000 picoseconds. - Weight::from_parts(22_774_000, 0) + // Minimum execution time: 26_257_000 picoseconds. + Weight::from_parts(26_802_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -77,8 +77,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12090` // Estimated: `13506` - // Minimum execution time: 20_748_000 picoseconds. - Weight::from_parts(21_464_000, 0) + // Minimum execution time: 24_692_000 picoseconds. + Weight::from_parts(25_275_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -93,8 +93,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `146` // Estimated: `1631` - // Minimum execution time: 10_269_000 picoseconds. - Weight::from_parts(10_508_000, 0) + // Minimum execution time: 13_872_000 picoseconds. + Weight::from_parts(14_509_000, 0) .saturating_add(Weight::from_parts(0, 1631)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -121,6 +121,8 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(201), added: 696, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:0 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::Status` (r:0 w:1) @@ -132,32 +134,34 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12279` // Estimated: `14805 + n * (1 ±0)` - // Minimum execution time: 41_900_000 picoseconds. - Weight::from_parts(80_392_728, 0) + // Minimum execution time: 52_916_000 picoseconds. + Weight::from_parts(96_122_236, 0) .saturating_add(Weight::from_parts(0, 14805)) - // Standard Error: 870 - .saturating_add(Weight::from_parts(4_361, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(13)) - .saturating_add(T::DbWeight::get().writes(26)) + // Standard Error: 969 + .saturating_add(Weight::from_parts(5_732, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(27)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:1 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Broker::Regions` (r:0 w:1) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `332` + // Measured: `437` // Estimated: `3593` - // Minimum execution time: 40_911_000 picoseconds. - Weight::from_parts(43_102_000, 0) + // Minimum execution time: 56_955_000 picoseconds. + Weight::from_parts(59_005_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) @@ -169,16 +173,18 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `450` + // Measured: `658` // Estimated: `4698` - // Minimum execution time: 70_257_000 picoseconds. - Weight::from_parts(73_889_000, 0) + // Minimum execution time: 108_853_000 picoseconds. + Weight::from_parts(117_467_000, 0) .saturating_add(Weight::from_parts(0, 4698)) - .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Broker::Regions` (r:1 w:1) @@ -187,8 +193,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `358` // Estimated: `3551` - // Minimum execution time: 13_302_000 picoseconds. - Weight::from_parts(13_852_000, 0) + // Minimum execution time: 16_922_000 picoseconds. + Weight::from_parts(17_544_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -199,8 +205,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `358` // Estimated: `3551` - // Minimum execution time: 14_927_000 picoseconds. - Weight::from_parts(15_553_000, 0) + // Minimum execution time: 18_762_000 picoseconds. + Weight::from_parts(19_162_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -211,8 +217,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `358` // Estimated: `3551` - // Minimum execution time: 16_237_000 picoseconds. - Weight::from_parts(16_995_000, 0) + // Minimum execution time: 20_297_000 picoseconds. + Weight::from_parts(20_767_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(3)) @@ -229,8 +235,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `736` // Estimated: `4681` - // Minimum execution time: 24_621_000 picoseconds. - Weight::from_parts(25_165_000, 0) + // Minimum execution time: 31_347_000 picoseconds. + Weight::from_parts(32_259_000, 0) .saturating_add(Weight::from_parts(0, 4681)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -249,8 +255,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `802` // Estimated: `5996` - // Minimum execution time: 29_832_000 picoseconds. - Weight::from_parts(30_894_000, 0) + // Minimum execution time: 38_310_000 picoseconds. + Weight::from_parts(39_777_000, 0) .saturating_add(Weight::from_parts(0, 5996)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(5)) @@ -264,13 +270,13 @@ impl pallet_broker::WeightInfo for WeightInfo { /// The range of component `m` is `[1, 3]`. fn claim_revenue(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `652` + // Measured: `671` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 55_390_000 picoseconds. - Weight::from_parts(56_124_789, 0) + // Minimum execution time: 65_960_000 picoseconds. + Weight::from_parts(66_194_985, 0) .saturating_add(Weight::from_parts(0, 6196)) - // Standard Error: 41_724 - .saturating_add(Weight::from_parts(1_551_266, 0).saturating_mul(m.into())) + // Standard Error: 42_455 + .saturating_add(Weight::from_parts(1_808_497, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5)) @@ -290,11 +296,11 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn purchase_credit() -> Weight { // Proof Size summary in bytes: - // Measured: `320` - // Estimated: `3785` - // Minimum execution time: 59_759_000 picoseconds. - Weight::from_parts(61_310_000, 0) - .saturating_add(Weight::from_parts(0, 3785)) + // Measured: `321` + // Estimated: `3786` + // Minimum execution time: 69_918_000 picoseconds. + Weight::from_parts(72_853_000, 0) + .saturating_add(Weight::from_parts(0, 3786)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -306,8 +312,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `466` // Estimated: `3551` - // Minimum execution time: 37_007_000 picoseconds. - Weight::from_parts(51_927_000, 0) + // Minimum execution time: 44_775_000 picoseconds. + Weight::from_parts(58_978_000, 0) .saturating_add(Weight::from_parts(0, 3551)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -322,8 +328,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `463` // Estimated: `3533` - // Minimum execution time: 86_563_000 picoseconds. - Weight::from_parts(91_274_000, 0) + // Minimum execution time: 67_098_000 picoseconds. + Weight::from_parts(93_626_000, 0) .saturating_add(Weight::from_parts(0, 3533)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -338,10 +344,10 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `857` + // Measured: `979` // Estimated: `3593` - // Minimum execution time: 93_655_000 picoseconds. - Weight::from_parts(98_160_000, 0) + // Minimum execution time: 89_463_000 picoseconds. + Weight::from_parts(113_286_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -354,8 +360,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `556` // Estimated: `4698` - // Minimum execution time: 33_985_000 picoseconds. - Weight::from_parts(43_618_000, 0) + // Minimum execution time: 42_073_000 picoseconds. + Weight::from_parts(52_211_000, 0) .saturating_add(Weight::from_parts(0, 4698)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -371,30 +377,26 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 18_778_000 picoseconds. - Weight::from_parts(19_543_425, 0) + // Minimum execution time: 22_937_000 picoseconds. + Weight::from_parts(23_898_154, 0) .saturating_add(Weight::from_parts(0, 3539)) - // Standard Error: 41 - .saturating_add(Weight::from_parts(33, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Broker::CoreCountInbox` (r:1 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn process_core_count(n: u32, ) -> Weight { + fn process_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `266` // Estimated: `1487` - // Minimum execution time: 5_505_000 picoseconds. - Weight::from_parts(5_982_015, 0) + // Minimum execution time: 7_650_000 picoseconds. + Weight::from_parts(8_166_809, 0) .saturating_add(Weight::from_parts(0, 1487)) - // Standard Error: 13 - .saturating_add(Weight::from_parts(44, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -402,40 +404,54 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) /// Storage: `Broker::InstaPoolHistory` (r:1 w:1) /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `442` + // Measured: `461` // Estimated: `6196` - // Minimum execution time: 38_128_000 picoseconds. - Weight::from_parts(40_979_000, 0) + // Minimum execution time: 53_023_000 picoseconds. + Weight::from_parts(54_564_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) /// Storage: `Broker::Reservations` (r:1 w:0) /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(12021), added: 12516, mode: `MaxEncodedLen`) /// Storage: `Broker::Leases` (r:1 w:1) /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(81), added: 576, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(201), added: 696, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:20 w:40) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:21 w:20) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:0 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) - /// Storage: `Broker::Workplan` (r:0 w:20) + /// Storage: `Broker::Workplan` (r:0 w:1000) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn rotate_sale(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `12194` - // Estimated: `13506` - // Minimum execution time: 49_041_000 picoseconds. - Weight::from_parts(50_522_788, 0) - .saturating_add(Weight::from_parts(0, 13506)) - // Standard Error: 72 - .saturating_add(Weight::from_parts(78, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(25)) + // Measured: `16480` + // Estimated: `69404 + n * (8 ±1)` + // Minimum execution time: 29_313_000 picoseconds. + Weight::from_parts(746_062_644, 0) + .saturating_add(Weight::from_parts(0, 69404)) + // Standard Error: 22_496 + .saturating_add(Weight::from_parts(1_545_204, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(44)) + .saturating_add(T::DbWeight::get().writes(57)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(n.into())) } /// Storage: `Broker::InstaPoolIo` (r:1 w:0) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) @@ -445,8 +461,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `42` // Estimated: `3493` - // Minimum execution time: 5_903_000 picoseconds. - Weight::from_parts(6_202_000, 0) + // Minimum execution time: 7_625_000 picoseconds. + Weight::from_parts(7_910_000, 0) .saturating_add(Weight::from_parts(0, 3493)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -469,8 +485,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `1321` // Estimated: `4786` - // Minimum execution time: 31_412_000 picoseconds. - Weight::from_parts(31_964_000, 0) + // Minimum execution time: 36_572_000 picoseconds. + Weight::from_parts(37_316_000, 0) .saturating_add(Weight::from_parts(0, 4786)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -489,8 +505,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 14_098_000 picoseconds. - Weight::from_parts(14_554_000, 0) + // Minimum execution time: 18_362_000 picoseconds. + Weight::from_parts(18_653_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -501,8 +517,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_723_000 picoseconds. - Weight::from_parts(1_822_000, 0) + // Minimum execution time: 2_193_000 picoseconds. + Weight::from_parts(2_393_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -512,8 +528,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_865_000 picoseconds. - Weight::from_parts(1_983_000, 0) + // Minimum execution time: 2_344_000 picoseconds. + Weight::from_parts(2_486_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -531,8 +547,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `408` // Estimated: `1893` - // Minimum execution time: 10_387_000 picoseconds. - Weight::from_parts(10_819_000, 0) + // Minimum execution time: 15_443_000 picoseconds. + Weight::from_parts(15_753_000, 0) .saturating_add(Weight::from_parts(0, 1893)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(1)) @@ -543,8 +559,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `150` // Estimated: `1566` - // Minimum execution time: 5_996_000 picoseconds. - Weight::from_parts(6_278_000, 0) + // Minimum execution time: 8_637_000 picoseconds. + Weight::from_parts(8_883_000, 0) .saturating_add(Weight::from_parts(0, 1566)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -557,44 +573,44 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::AutoRenewals` (r:1 w:1) - /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(201), added: 696, mode: `MaxEncodedLen`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn enable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `914` - // Estimated: `4698` - // Minimum execution time: 51_938_000 picoseconds. - Weight::from_parts(55_025_000, 4698) - .saturating_add(T::DbWeight::get().reads(8_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Measured: `1451` + // Estimated: `6196` + // Minimum execution time: 120_585_000 picoseconds. + Weight::from_parts(148_755_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `Broker::AutoRenewals` (r:1 w:1) - /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(201), added: 696, mode: `MaxEncodedLen`) fn disable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `480` - // Estimated: `1516` - // Minimum execution time: 9_628_000 picoseconds. - Weight::from_parts(10_400_000, 1516) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } + // Measured: `506` + // Estimated: `1686` + // Minimum execution time: 18_235_000 picoseconds. + Weight::from_parts(19_113_000, 0) + .saturating_add(Weight::from_parts(0, 1686)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn on_new_timeslice() -> Weight { // Proof Size summary in bytes: - // Measured: `0` + // Measured: `103` // Estimated: `3593` - // Minimum execution time: 2_187_000 picoseconds. - Weight::from_parts(2_372_000, 0) + // Minimum execution time: 4_863_000 picoseconds. + Weight::from_parts(5_045_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) } diff --git a/prdoc/pr_6505.prdoc b/prdoc/pr_6505.prdoc new file mode 100644 index 000000000000..ae00dd17fed5 --- /dev/null +++ b/prdoc/pr_6505.prdoc @@ -0,0 +1,14 @@ +title: '[pallet-broker] Fix auto renew benchmarks' +doc: +- audience: Runtime Dev + description: |- + Fix the broker pallet auto-renew benchmarks which have been broken since #4424, yielding `Weightless` due to some prices being set too low, as reported in #6474. + + Upon further investigation it turned out that the auto-renew contribution to `rotate_sale` was always failing but the error was mapped. This is also fixed at the cost of a bit of setup overhead. +crates: +- name: pallet-broker + bump: patch +- name: coretime-rococo-runtime + bump: patch +- name: coretime-westend-runtime + bump: patch diff --git a/substrate/frame/broker/src/benchmarking.rs b/substrate/frame/broker/src/benchmarking.rs index 9ef9b1254435..044689b254c5 100644 --- a/substrate/frame/broker/src/benchmarking.rs +++ b/substrate/frame/broker/src/benchmarking.rs @@ -30,11 +30,11 @@ use frame_support::{ }, }; use frame_system::{Pallet as System, RawOrigin}; -use sp_arithmetic::{traits::Zero, Perbill}; +use sp_arithmetic::Perbill; use sp_core::Get; use sp_runtime::{ traits::{BlockNumberProvider, MaybeConvert}, - SaturatedConversion, Saturating, + Saturating, }; const SEED: u32 = 0; @@ -287,7 +287,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); Broker::::do_assign(region, None, 1001, Final) .map_err(|_| BenchmarkError::Weightless)?; @@ -316,7 +316,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); let recipient: T::AccountId = account("recipient", 0, SEED); @@ -349,7 +349,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); #[extrinsic_call] _(RawOrigin::Signed(caller), region, 2); @@ -381,7 +381,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); #[extrinsic_call] _(RawOrigin::Signed(caller), region, 0x00000_fffff_fffff_00000.into()); @@ -417,7 +417,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); #[extrinsic_call] _(RawOrigin::Signed(caller), region, 1000, Provisional); @@ -452,7 +452,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); let recipient: T::AccountId = account("recipient", 0, SEED); @@ -492,7 +492,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); let recipient: T::AccountId = account("recipient", 0, SEED); T::Currency::set_balance(&recipient.clone(), T::Currency::minimum_balance()); @@ -548,7 +548,7 @@ mod benches { T::Currency::set_balance(&Broker::::account_id(), T::Currency::minimum_balance()); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); let recipient: T::AccountId = account("recipient", 0, SEED); @@ -582,7 +582,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); advance_to::( (T::TimeslicePeriod::get() * (region_len * 4).into()).try_into().ok().unwrap(), @@ -616,7 +616,7 @@ mod benches { ); let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + .expect("Offer not high enough for configuration."); let recipient: T::AccountId = account("recipient", 0, SEED); @@ -786,80 +786,97 @@ mod benches { #[benchmark] fn rotate_sale(n: Linear<0, { MAX_CORE_COUNT.into() }>) -> Result<(), BenchmarkError> { - let core_count = n.try_into().unwrap(); let config = new_config_record::(); + Configuration::::put(config.clone()); - let now = RCBlockNumberProviderOf::::current_block_number(); - let end_price = 10_000_000u32.into(); - let commit_timeslice = Broker::::latest_timeslice_ready_to_commit(&config); - let sale = SaleInfoRecordOf:: { - sale_start: now, - leadin_length: Zero::zero(), - end_price, - sellout_price: None, - region_begin: commit_timeslice, - region_end: commit_timeslice.saturating_add(config.region_length), - first_core: 0, - ideal_cores_sold: 0, - cores_offered: 0, - cores_sold: 0, - }; - - let status = StatusRecord { - core_count, - private_pool_size: 0, - system_pool_size: 0, - last_committed_timeslice: commit_timeslice.saturating_sub(1), - last_timeslice: Broker::::current_timeslice(), - }; + // Ensure there is one buyable core then use the rest to max out reservations and leases, if + // possible for worst case. + + // First allocate up to MaxReservedCores for reservations + let n_reservations = T::MaxReservedCores::get().min(n.saturating_sub(1)); + setup_reservations::(n_reservations); + // Then allocate remaining cores to leases, up to MaxLeasedCores + let n_leases = + T::MaxLeasedCores::get().min(n.saturating_sub(1).saturating_sub(n_reservations)); + setup_leases::(n_leases, 1, 20); + + // Start sales so we can test the auto-renewals. + Broker::::do_start_sales( + 10_000_000u32.into(), + n.saturating_sub(n_reservations) + .saturating_sub(n_leases) + .try_into() + .expect("Upper limit of n is a u16."), + ) + .expect("Configuration was initialized before; qed"); + + // Advance to the fixed price period. + advance_to::(2); - // Assume Reservations to be filled for worst case - setup_reservations::(T::MaxReservedCores::get()); + // Assume max auto renewals for worst case. This is between 1 and the value of + // MaxAutoRenewals. + let n_renewable = T::MaxAutoRenewals::get() + .min(n.saturating_sub(n_leases).saturating_sub(n_reservations)); - // Assume Leases to be filled for worst case - setup_leases::(T::MaxLeasedCores::get(), 1, 10); + let timeslice_period: u32 = T::TimeslicePeriod::get().try_into().ok().unwrap(); + let sale = SaleInfo::::get().expect("Sale has started."); - // Assume max auto renewals for worst case. - (0..T::MaxAutoRenewals::get()).try_for_each(|indx| -> Result<(), BenchmarkError> { + (0..n_renewable.into()).try_for_each(|indx| -> Result<(), BenchmarkError> { let task = 1000 + indx; let caller: T::AccountId = T::SovereignAccountOf::maybe_convert(task) .expect("Failed to get sovereign account"); T::Currency::set_balance( &caller.clone(), - T::Currency::minimum_balance().saturating_add(100u32.into()), + T::Currency::minimum_balance().saturating_add(100_000_000u32.into()), ); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) + .expect("Offer not high enough for configuration."); Broker::::do_assign(region, None, task, Final) .map_err(|_| BenchmarkError::Weightless)?; - Broker::::do_enable_auto_renew(caller, region.core, task, None)?; + Broker::::do_enable_auto_renew(caller, region.core, task, Some(sale.region_end))?; Ok(()) })?; + // Advance to the block before the rotate_sale in which the auto-renewals will take place. + let rotate_block = timeslice_period.saturating_mul(config.region_length) - 2; + advance_to::(rotate_block - 1); + + // Advance one block and manually tick so we can isolate the `rotate_sale` call. + System::::set_block_number(rotate_block.into()); + RCBlockNumberProviderOf::::set_block_number(rotate_block.into()); + let mut status = Status::::get().expect("Sale has started."); + let sale = SaleInfo::::get().expect("Sale has started."); + Broker::::process_core_count(&mut status); + Broker::::process_revenue(); + status.last_committed_timeslice = config.region_length; + #[block] { Broker::::rotate_sale(sale.clone(), &config, &status); } - assert!(SaleInfo::::get().is_some()); - let sale_start = RCBlockNumberProviderOf::::current_block_number() + - config.interlude_length; - assert_last_event::( + // Get prices from the actual price adapter. + let new_prices = T::PriceAdapter::adapt_price(SalePerformance::from_sale(&sale)); + let new_sale = SaleInfo::::get().expect("Sale has started."); + let now = RCBlockNumberProviderOf::::current_block_number(); + let sale_start = config.interlude_length.saturating_add(rotate_block.into()); + + assert_has_event::( Event::SaleInitialized { sale_start, leadin_length: 1u32.into(), - start_price: 1_000_000_000u32.into(), - end_price: 10_000_000u32.into(), + start_price: Broker::::sale_price(&new_sale, now), + end_price: new_prices.end_price, region_begin: sale.region_begin + config.region_length, region_end: sale.region_end + config.region_length, ideal_cores_sold: 0, cores_offered: n - .saturating_sub(T::MaxReservedCores::get()) - .saturating_sub(T::MaxLeasedCores::get()) + .saturating_sub(n_reservations) + .saturating_sub(n_leases) .try_into() .unwrap(), } @@ -867,18 +884,18 @@ mod benches { ); // Make sure all cores got renewed: - (0..T::MaxAutoRenewals::get()).for_each(|indx| { + (0..n_renewable).for_each(|indx| { let task = 1000 + indx; let who = T::SovereignAccountOf::maybe_convert(task) .expect("Failed to get sovereign account"); assert_has_event::( Event::Renewed { who, - old_core: 10 + indx as u16, // first ten cores are allocated to leases. - core: 10 + indx as u16, - price: 10u32.saturated_into(), - begin: 7, - duration: 3, + old_core: n_reservations as u16 + n_leases as u16 + indx as u16, + core: n_reservations as u16 + n_leases as u16 + indx as u16, + price: 10_000_000u32.into(), + begin: new_sale.region_begin, + duration: config.region_length, workload: Schedule::truncate_from(vec![ScheduleItem { assignment: Task(task), mask: CoreMask::complete(), @@ -1018,56 +1035,62 @@ mod benches { #[benchmark] fn enable_auto_renew() -> Result<(), BenchmarkError> { - let _core = setup_and_start_sale::()?; + let _core_id = setup_and_start_sale::()?; advance_to::(2); + let sale = SaleInfo::::get().expect("Sale has already started."); // We assume max auto renewals for worst case. (0..T::MaxAutoRenewals::get() - 1).try_for_each(|indx| -> Result<(), BenchmarkError> { let task = 1000 + indx; let caller: T::AccountId = T::SovereignAccountOf::maybe_convert(task) .expect("Failed to get sovereign account"); + // Sovereign account needs sufficient funds to purchase and renew. T::Currency::set_balance( &caller.clone(), - T::Currency::minimum_balance().saturating_add(100u32.into()), + T::Currency::minimum_balance().saturating_add(100_000_000u32.into()), ); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) + .expect("Offer not high enough for configuration."); Broker::::do_assign(region, None, task, Final) .map_err(|_| BenchmarkError::Weightless)?; - Broker::::do_enable_auto_renew(caller, region.core, task, Some(7))?; + Broker::::do_enable_auto_renew(caller, region.core, task, Some(sale.region_end))?; Ok(()) })?; let caller: T::AccountId = T::SovereignAccountOf::maybe_convert(2001).expect("Failed to get sovereign account"); + // Sovereign account needs sufficient funds to purchase and renew. T::Currency::set_balance( &caller.clone(), - T::Currency::minimum_balance().saturating_add(100u32.into()), + T::Currency::minimum_balance().saturating_add(100_000_000u32.into()), ); // The region for which we benchmark enable auto renew. - let region = Broker::::do_purchase(caller.clone(), 10u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) + .expect("Offer not high enough for configuration."); Broker::::do_assign(region, None, 2001, Final) .map_err(|_| BenchmarkError::Weightless)?; // The most 'intensive' path is when we renew the core upon enabling auto-renewal. // Therefore, we advance to next bulk sale: - advance_to::(6); + let timeslice_period: u32 = T::TimeslicePeriod::get().try_into().ok().unwrap(); + let config = Configuration::::get().expect("Already configured."); + advance_to::(config.region_length * timeslice_period); #[extrinsic_call] _(RawOrigin::Signed(caller), region.core, 2001, None); assert_last_event::(Event::AutoRenewalEnabled { core: region.core, task: 2001 }.into()); // Make sure we indeed renewed: + let sale = SaleInfo::::get().expect("Sales have started."); assert!(PotentialRenewals::::get(PotentialRenewalId { core: region.core, - when: 10 // region end after renewal + when: sale.region_end, }) .is_some()); @@ -1076,37 +1099,41 @@ mod benches { #[benchmark] fn disable_auto_renew() -> Result<(), BenchmarkError> { - let _core = setup_and_start_sale::()?; + let core_id = setup_and_start_sale::()?; advance_to::(2); + let sale = SaleInfo::::get().expect("Sale has already started."); // We assume max auto renewals for worst case. - (0..T::MaxAutoRenewals::get() - 1).try_for_each(|indx| -> Result<(), BenchmarkError> { + (0..T::MaxAutoRenewals::get()).try_for_each(|indx| -> Result<(), BenchmarkError> { let task = 1000 + indx; let caller: T::AccountId = T::SovereignAccountOf::maybe_convert(task) .expect("Failed to get sovereign account"); T::Currency::set_balance( &caller.clone(), - T::Currency::minimum_balance().saturating_add(100u32.into()), + T::Currency::minimum_balance().saturating_add(10_000_000u32.into()), ); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()) - .map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) + .expect("Offer not high enough for configuration."); Broker::::do_assign(region, None, task, Final) .map_err(|_| BenchmarkError::Weightless)?; - Broker::::do_enable_auto_renew(caller, region.core, task, Some(7))?; + Broker::::do_enable_auto_renew(caller, region.core, task, Some(sale.region_end))?; Ok(()) })?; + let task = 1000; + let caller: T::AccountId = - T::SovereignAccountOf::maybe_convert(1000).expect("Failed to get sovereign account"); + T::SovereignAccountOf::maybe_convert(task).expect("Failed to get sovereign account"); + #[extrinsic_call] - _(RawOrigin::Signed(caller), _core, 1000); + _(RawOrigin::Signed(caller), core_id, task); - assert_last_event::(Event::AutoRenewalDisabled { core: _core, task: 1000 }.into()); + assert_last_event::(Event::AutoRenewalDisabled { core: core_id, task }.into()); Ok(()) } @@ -1120,11 +1147,11 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance( &caller.clone(), - T::Currency::minimum_balance().saturating_add(u32::MAX.into()), + T::Currency::minimum_balance().saturating_add(10_000_000u32.into()), ); - let _region = Broker::::do_purchase(caller.clone(), (u32::MAX / 2).into()) - .map_err(|_| BenchmarkError::Weightless)?; + let _region = Broker::::do_purchase(caller.clone(), 10_000_000u32.into()) + .expect("Offer not high enough for configuration."); let timeslice = Broker::::current_timeslice(); diff --git a/substrate/frame/broker/src/weights.rs b/substrate/frame/broker/src/weights.rs index 2f25fddc2050..894fed5a6a00 100644 --- a/substrate/frame/broker/src/weights.rs +++ b/substrate/frame/broker/src/weights.rs @@ -18,27 +18,25 @@ //! Autogenerated weights for `pallet_broker` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-05-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-12-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `sergej-B650-AORUS-ELITE-AX`, CPU: `AMD Ryzen 9 7900X3D 12-Core Processor` +//! HOSTNAME: `runner-acd6uxux-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/release/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_broker -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/broker/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_broker +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/broker/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -80,9 +78,9 @@ pub trait WeightInfo { fn notify_revenue() -> Weight; fn do_tick_base() -> Weight; fn swap_leases() -> Weight; - fn on_new_timeslice() -> Weight; fn enable_auto_renew() -> Weight; fn disable_auto_renew() -> Weight; + fn on_new_timeslice() -> Weight; } /// Weights for `pallet_broker` using the Substrate node and recommended hardware. @@ -94,8 +92,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_593_000 picoseconds. - Weight::from_parts(1_703_000, 0) + // Minimum execution time: 2_498_000 picoseconds. + Weight::from_parts(2_660_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -104,8 +102,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 12_864_000 picoseconds. - Weight::from_parts(13_174_000, 7496) + // Minimum execution time: 23_090_000 picoseconds. + Weight::from_parts(23_664_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -115,8 +113,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 12_284_000 picoseconds. - Weight::from_parts(13_566_000, 7496) + // Minimum execution time: 21_782_000 picoseconds. + Weight::from_parts(22_708_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -126,8 +124,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 6_743_000 picoseconds. - Weight::from_parts(7_094_000, 1526) + // Minimum execution time: 14_966_000 picoseconds. + Weight::from_parts(15_592_000, 1526) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -152,10 +150,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 21_120_000 picoseconds. - Weight::from_parts(40_929_422, 8499) - // Standard Error: 471 - .saturating_add(Weight::from_parts(1_004, 0).saturating_mul(n.into())) + // Minimum execution time: 31_757_000 picoseconds. + Weight::from_parts(57_977_268, 8499) + // Standard Error: 576 + .saturating_add(Weight::from_parts(3_102, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(16_u64)) } @@ -163,19 +161,15 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:1 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::Regions` (r:0 w:1) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `651` - // Estimated: `2136` - // Minimum execution time: 31_169_000 picoseconds. - Weight::from_parts(32_271_000, 2136) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `470` + // Estimated: `1542` + // Minimum execution time: 40_469_000 picoseconds. + Weight::from_parts(41_360_000, 1542) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Broker::Configuration` (r:1 w:0) @@ -186,19 +180,15 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::PotentialRenewals` (r:1 w:2) /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `769` + // Measured: `588` // Estimated: `4698` - // Minimum execution time: 44_945_000 picoseconds. - Weight::from_parts(47_119_000, 4698) - .saturating_add(T::DbWeight::get().reads(6_u64)) + // Minimum execution time: 60_724_000 picoseconds. + Weight::from_parts(63_445_000, 4698) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `Broker::Regions` (r:1 w:1) @@ -207,8 +197,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 11_562_000 picoseconds. - Weight::from_parts(11_943_000, 3551) + // Minimum execution time: 23_734_000 picoseconds. + Weight::from_parts(25_080_000, 3551) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -218,8 +208,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 13_075_000 picoseconds. - Weight::from_parts(13_616_000, 3551) + // Minimum execution time: 25_917_000 picoseconds. + Weight::from_parts(26_715_000, 3551) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -229,8 +219,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 13_695_000 picoseconds. - Weight::from_parts(14_658_000, 3551) + // Minimum execution time: 26_764_000 picoseconds. + Weight::from_parts(27_770_000, 3551) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -246,8 +236,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `741` // Estimated: `4681` - // Minimum execution time: 22_623_000 picoseconds. - Weight::from_parts(23_233_000, 4681) + // Minimum execution time: 37_617_000 picoseconds. + Weight::from_parts(39_333_000, 4681) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -265,8 +255,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `776` // Estimated: `5996` - // Minimum execution time: 26_901_000 picoseconds. - Weight::from_parts(27_472_000, 5996) + // Minimum execution time: 43_168_000 picoseconds. + Weight::from_parts(44_741_000, 5996) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -281,10 +271,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `878` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 51_778_000 picoseconds. - Weight::from_parts(53_726_731, 6196) - // Standard Error: 45_279 - .saturating_add(Weight::from_parts(677_769, 0).saturating_mul(m.into())) + // Minimum execution time: 75_317_000 picoseconds. + Weight::from_parts(76_792_860, 6196) + // Standard Error: 55_267 + .saturating_add(Weight::from_parts(1_878_133, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5_u64)) @@ -296,8 +286,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 31_790_000 picoseconds. - Weight::from_parts(32_601_000, 3593) + // Minimum execution time: 44_248_000 picoseconds. + Weight::from_parts(45_201_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -309,8 +299,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `604` // Estimated: `3551` - // Minimum execution time: 18_465_000 picoseconds. - Weight::from_parts(21_050_000, 3551) + // Minimum execution time: 39_853_000 picoseconds. + Weight::from_parts(44_136_000, 3551) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -324,8 +314,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 23_825_000 picoseconds. - Weight::from_parts(26_250_000, 3533) + // Minimum execution time: 46_452_000 picoseconds. + Weight::from_parts(52_780_000, 3533) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -339,10 +329,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `1014` + // Measured: `1117` // Estimated: `3593` - // Minimum execution time: 28_103_000 picoseconds. - Weight::from_parts(32_622_000, 3593) + // Minimum execution time: 64_905_000 picoseconds. + Weight::from_parts(72_914_000, 3593) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -354,8 +344,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `661` // Estimated: `4698` - // Minimum execution time: 16_751_000 picoseconds. - Weight::from_parts(17_373_000, 4698) + // Minimum execution time: 38_831_000 picoseconds. + Weight::from_parts(41_420_000, 4698) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -364,8 +354,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_705_000 picoseconds. - Weight::from_parts(2_991_768, 0) + // Minimum execution time: 4_595_000 picoseconds. + Weight::from_parts(4_964_606, 0) } /// Storage: `Broker::CoreCountInbox` (r:1 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -374,37 +364,58 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `404` // Estimated: `1487` - // Minimum execution time: 4_598_000 picoseconds. - Weight::from_parts(4_937_302, 1487) + // Minimum execution time: 8_640_000 picoseconds. + Weight::from_parts(9_153_332, 1487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) - /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Storage: `Broker::RevenueInbox` (r:1 w:1) + /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) /// Storage: `Broker::InstaPoolHistory` (r:1 w:1) /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `991` - // Estimated: `4456` - // Minimum execution time: 37_601_000 picoseconds. - Weight::from_parts(38_262_000, 4456) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Measured: `667` + // Estimated: `3593` + // Minimum execution time: 40_570_000 picoseconds. + Weight::from_parts(41_402_000, 3593) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + /// Storage: `Broker::InstaPoolIo` (r:3 w:3) + /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::Reservations` (r:1 w:0) + /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) + /// Storage: `Broker::Leases` (r:1 w:1) + /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:10 w:20) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:10 w:10) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Broker::SaleInfo` (r:0 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:0 w:1000) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn rotate_sale(_n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) + fn rotate_sale(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8548` + // Estimated: `38070` + // Minimum execution time: 29_370_000 picoseconds. + Weight::from_parts(334_030_189, 38070) + // Standard Error: 6_912 + .saturating_add(Weight::from_parts(1_268_750, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(26_u64)) + .saturating_add(T::DbWeight::get().writes(34_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) } /// Storage: `Broker::InstaPoolIo` (r:1 w:0) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) @@ -414,8 +425,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 5_391_000 picoseconds. - Weight::from_parts(5_630_000, 3493) + // Minimum execution time: 9_005_000 picoseconds. + Weight::from_parts(9_392_000, 3493) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -427,8 +438,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 10_249_000 picoseconds. - Weight::from_parts(10_529_000, 4681) + // Minimum execution time: 19_043_000 picoseconds. + Weight::from_parts(20_089_000, 4681) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -436,8 +447,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 120_000 picoseconds. - Weight::from_parts(140_000, 0) + // Minimum execution time: 149_000 picoseconds. + Weight::from_parts(183_000, 0) } /// Storage: `Broker::CoreCountInbox` (r:0 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -445,8 +456,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_402_000 picoseconds. - Weight::from_parts(1_513_000, 0) + // Minimum execution time: 2_248_000 picoseconds. + Weight::from_parts(2_425_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::RevenueInbox` (r:0 w:1) @@ -455,8 +466,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_902_000 picoseconds. - Weight::from_parts(2_116_000, 0) + // Minimum execution time: 2_413_000 picoseconds. + Weight::from_parts(2_640_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Status` (r:1 w:1) @@ -465,16 +476,16 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `Broker::CoreCountInbox` (r:1 w:0) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) - /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Storage: `Broker::RevenueInbox` (r:1 w:0) + /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `603` - // Estimated: `4068` - // Minimum execution time: 8_897_000 picoseconds. - Weight::from_parts(9_218_000, 4068) + // Measured: `441` + // Estimated: `1516` + // Minimum execution time: 17_083_000 picoseconds. + Weight::from_parts(18_077_000, 1516) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Leases` (r:1 w:1) /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) @@ -482,18 +493,11 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 4_678_000 picoseconds. - Weight::from_parts(4_920_000, 1526) + // Minimum execution time: 11_620_000 picoseconds. + Weight::from_parts(12_063_000, 1526) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - fn on_new_timeslice() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 229_000 picoseconds. - Weight::from_parts(268_000, 0) - } /// Storage: `Broker::SaleInfo` (r:1 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::PotentialRenewals` (r:1 w:2) @@ -504,34 +508,37 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::AutoRenewals` (r:1 w:1) /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn enable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `930` + // Measured: `1121` // Estimated: `4698` - // Minimum execution time: 51_597_000 picoseconds. - Weight::from_parts(52_609_000, 4698) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Minimum execution time: 85_270_000 picoseconds. + Weight::from_parts(90_457_000, 4698) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `Broker::AutoRenewals` (r:1 w:1) /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) fn disable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `484` + // Measured: `578` // Estimated: `1586` - // Minimum execution time: 8_907_000 picoseconds. - Weight::from_parts(9_167_000, 1586) + // Minimum execution time: 22_479_000 picoseconds. + Weight::from_parts(23_687_000, 1586) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + fn on_new_timeslice() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 245_000 picoseconds. + Weight::from_parts(290_000, 0) + } } // For backwards compatibility and tests. @@ -542,8 +549,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_593_000 picoseconds. - Weight::from_parts(1_703_000, 0) + // Minimum execution time: 2_498_000 picoseconds. + Weight::from_parts(2_660_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -552,8 +559,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 12_864_000 picoseconds. - Weight::from_parts(13_174_000, 7496) + // Minimum execution time: 23_090_000 picoseconds. + Weight::from_parts(23_664_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -563,8 +570,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 12_284_000 picoseconds. - Weight::from_parts(13_566_000, 7496) + // Minimum execution time: 21_782_000 picoseconds. + Weight::from_parts(22_708_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -574,8 +581,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 6_743_000 picoseconds. - Weight::from_parts(7_094_000, 1526) + // Minimum execution time: 14_966_000 picoseconds. + Weight::from_parts(15_592_000, 1526) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -600,10 +607,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 21_120_000 picoseconds. - Weight::from_parts(40_929_422, 8499) - // Standard Error: 471 - .saturating_add(Weight::from_parts(1_004, 0).saturating_mul(n.into())) + // Minimum execution time: 31_757_000 picoseconds. + Weight::from_parts(57_977_268, 8499) + // Standard Error: 576 + .saturating_add(Weight::from_parts(3_102, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(16_u64)) } @@ -611,19 +618,15 @@ impl WeightInfo for () { /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:1 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::Regions` (r:0 w:1) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `651` - // Estimated: `2136` - // Minimum execution time: 31_169_000 picoseconds. - Weight::from_parts(32_271_000, 2136) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `470` + // Estimated: `1542` + // Minimum execution time: 40_469_000 picoseconds. + Weight::from_parts(41_360_000, 1542) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Broker::Configuration` (r:1 w:0) @@ -634,19 +637,15 @@ impl WeightInfo for () { /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::PotentialRenewals` (r:1 w:2) /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `769` + // Measured: `588` // Estimated: `4698` - // Minimum execution time: 44_945_000 picoseconds. - Weight::from_parts(47_119_000, 4698) - .saturating_add(RocksDbWeight::get().reads(6_u64)) + // Minimum execution time: 60_724_000 picoseconds. + Weight::from_parts(63_445_000, 4698) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } /// Storage: `Broker::Regions` (r:1 w:1) @@ -655,8 +654,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 11_562_000 picoseconds. - Weight::from_parts(11_943_000, 3551) + // Minimum execution time: 23_734_000 picoseconds. + Weight::from_parts(25_080_000, 3551) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -666,8 +665,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 13_075_000 picoseconds. - Weight::from_parts(13_616_000, 3551) + // Minimum execution time: 25_917_000 picoseconds. + Weight::from_parts(26_715_000, 3551) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -677,8 +676,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 13_695_000 picoseconds. - Weight::from_parts(14_658_000, 3551) + // Minimum execution time: 26_764_000 picoseconds. + Weight::from_parts(27_770_000, 3551) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -694,8 +693,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `741` // Estimated: `4681` - // Minimum execution time: 22_623_000 picoseconds. - Weight::from_parts(23_233_000, 4681) + // Minimum execution time: 37_617_000 picoseconds. + Weight::from_parts(39_333_000, 4681) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -713,8 +712,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `776` // Estimated: `5996` - // Minimum execution time: 26_901_000 picoseconds. - Weight::from_parts(27_472_000, 5996) + // Minimum execution time: 43_168_000 picoseconds. + Weight::from_parts(44_741_000, 5996) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -729,10 +728,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `878` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 51_778_000 picoseconds. - Weight::from_parts(53_726_731, 6196) - // Standard Error: 45_279 - .saturating_add(Weight::from_parts(677_769, 0).saturating_mul(m.into())) + // Minimum execution time: 75_317_000 picoseconds. + Weight::from_parts(76_792_860, 6196) + // Standard Error: 55_267 + .saturating_add(Weight::from_parts(1_878_133, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(RocksDbWeight::get().writes(5_u64)) @@ -744,8 +743,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 31_790_000 picoseconds. - Weight::from_parts(32_601_000, 3593) + // Minimum execution time: 44_248_000 picoseconds. + Weight::from_parts(45_201_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -757,8 +756,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `604` // Estimated: `3551` - // Minimum execution time: 18_465_000 picoseconds. - Weight::from_parts(21_050_000, 3551) + // Minimum execution time: 39_853_000 picoseconds. + Weight::from_parts(44_136_000, 3551) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -772,8 +771,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 23_825_000 picoseconds. - Weight::from_parts(26_250_000, 3533) + // Minimum execution time: 46_452_000 picoseconds. + Weight::from_parts(52_780_000, 3533) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -787,10 +786,10 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `1014` + // Measured: `1117` // Estimated: `3593` - // Minimum execution time: 28_103_000 picoseconds. - Weight::from_parts(32_622_000, 3593) + // Minimum execution time: 64_905_000 picoseconds. + Weight::from_parts(72_914_000, 3593) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -802,8 +801,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `661` // Estimated: `4698` - // Minimum execution time: 16_751_000 picoseconds. - Weight::from_parts(17_373_000, 4698) + // Minimum execution time: 38_831_000 picoseconds. + Weight::from_parts(41_420_000, 4698) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -812,8 +811,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_705_000 picoseconds. - Weight::from_parts(2_991_768, 0) + // Minimum execution time: 4_595_000 picoseconds. + Weight::from_parts(4_964_606, 0) } /// Storage: `Broker::CoreCountInbox` (r:1 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -822,37 +821,58 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `404` // Estimated: `1487` - // Minimum execution time: 4_598_000 picoseconds. - Weight::from_parts(4_937_302, 1487) + // Minimum execution time: 8_640_000 picoseconds. + Weight::from_parts(9_153_332, 1487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) - /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Storage: `Broker::RevenueInbox` (r:1 w:1) + /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) /// Storage: `Broker::InstaPoolHistory` (r:1 w:1) /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `991` - // Estimated: `4456` - // Minimum execution time: 37_601_000 picoseconds. - Weight::from_parts(38_262_000, 4456) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Measured: `667` + // Estimated: `3593` + // Minimum execution time: 40_570_000 picoseconds. + Weight::from_parts(41_402_000, 3593) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } + /// Storage: `Broker::InstaPoolIo` (r:3 w:3) + /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::Reservations` (r:1 w:0) + /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) + /// Storage: `Broker::Leases` (r:1 w:1) + /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:10 w:20) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:10 w:10) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Broker::SaleInfo` (r:0 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:0 w:1000) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn rotate_sale(_n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) + fn rotate_sale(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `8548` + // Estimated: `38070` + // Minimum execution time: 29_370_000 picoseconds. + Weight::from_parts(334_030_189, 38070) + // Standard Error: 6_912 + .saturating_add(Weight::from_parts(1_268_750, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(26_u64)) + .saturating_add(RocksDbWeight::get().writes(34_u64)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) } /// Storage: `Broker::InstaPoolIo` (r:1 w:0) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) @@ -862,8 +882,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 5_391_000 picoseconds. - Weight::from_parts(5_630_000, 3493) + // Minimum execution time: 9_005_000 picoseconds. + Weight::from_parts(9_392_000, 3493) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -875,8 +895,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 10_249_000 picoseconds. - Weight::from_parts(10_529_000, 4681) + // Minimum execution time: 19_043_000 picoseconds. + Weight::from_parts(20_089_000, 4681) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -884,8 +904,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 120_000 picoseconds. - Weight::from_parts(140_000, 0) + // Minimum execution time: 149_000 picoseconds. + Weight::from_parts(183_000, 0) } /// Storage: `Broker::CoreCountInbox` (r:0 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -893,8 +913,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_402_000 picoseconds. - Weight::from_parts(1_513_000, 0) + // Minimum execution time: 2_248_000 picoseconds. + Weight::from_parts(2_425_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::RevenueInbox` (r:0 w:1) @@ -903,8 +923,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_902_000 picoseconds. - Weight::from_parts(2_116_000, 0) + // Minimum execution time: 2_413_000 picoseconds. + Weight::from_parts(2_640_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Status` (r:1 w:1) @@ -913,16 +933,16 @@ impl WeightInfo for () { /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `Broker::CoreCountInbox` (r:1 w:0) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) - /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Storage: `Broker::RevenueInbox` (r:1 w:0) + /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `603` - // Estimated: `4068` - // Minimum execution time: 8_897_000 picoseconds. - Weight::from_parts(9_218_000, 4068) + // Measured: `441` + // Estimated: `1516` + // Minimum execution time: 17_083_000 picoseconds. + Weight::from_parts(18_077_000, 1516) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Leases` (r:1 w:1) /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) @@ -930,18 +950,11 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 4_678_000 picoseconds. - Weight::from_parts(4_920_000, 1526) + // Minimum execution time: 11_620_000 picoseconds. + Weight::from_parts(12_063_000, 1526) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - fn on_new_timeslice() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 229_000 picoseconds. - Weight::from_parts(268_000, 0) - } /// Storage: `Broker::SaleInfo` (r:1 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::PotentialRenewals` (r:1 w:2) @@ -952,32 +965,35 @@ impl WeightInfo for () { /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::AutoRenewals` (r:1 w:1) /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) /// Storage: `Broker::Workplan` (r:0 w:1) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn enable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `930` + // Measured: `1121` // Estimated: `4698` - // Minimum execution time: 51_597_000 picoseconds. - Weight::from_parts(52_609_000, 4698) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Minimum execution time: 85_270_000 picoseconds. + Weight::from_parts(90_457_000, 4698) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `Broker::AutoRenewals` (r:1 w:1) /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) fn disable_auto_renew() -> Weight { // Proof Size summary in bytes: - // Measured: `484` + // Measured: `578` // Estimated: `1586` - // Minimum execution time: 8_907_000 picoseconds. - Weight::from_parts(9_167_000, 1586) + // Minimum execution time: 22_479_000 picoseconds. + Weight::from_parts(23_687_000, 1586) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } -} \ No newline at end of file + fn on_new_timeslice() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 245_000 picoseconds. + Weight::from_parts(290_000, 0) + } +}