mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 17:31:03 +00:00
[testnet] Add AssetHubRococo <-> AssetHubWestend asset bridging support (#1967)
## Summary Asset bridging support for AssetHub**Rococo** <-> AssetHub**Wococo** was added [here](https://github.com/paritytech/polkadot-sdk/pull/1215), so now we aim to bridge AssetHub**Rococo** and AssetHub**Westend**. (And perhaps retire AssetHubWococo and the Wococo chains). ## Solution **bridge-hub-westend-runtime** - added new runtime as a copy of `bridge-hub-rococo-runtime` - added support for bridging to `BridgeHubRococo` - added tests and benchmarks **bridge-hub-rococo-runtime** - added support for bridging to `BridgeHubWestend` - added tests and benchmarks - internal refactoring by splitting bridge configuration per network, e.g., `bridge_to_whatevernetwork_config.rs`. **asset-hub-rococo-runtime** - added support for asset bridging to `AssetHubWestend` (allows to receive only WNDs) - added new xcm router for `Westend` - added tests and benchmarks **asset-hub-westend-runtime** - added support for asset bridging to `AssetHubRococo` (allows to receive only ROCs) - added new xcm router for `Rococo` - added tests and benchmarks ## Deployment All changes will be deployed as a part of https://github.com/paritytech/polkadot-sdk/issues/1988. ## TODO - [x] benchmarks for all pallet instances - [x] integration tests - [x] local run scripts Relates to: https://github.com/paritytech/parity-bridges-common/issues/2602 Relates to: https://github.com/paritytech/polkadot-sdk/issues/1988 --------- Co-authored-by: command-bot <> Co-authored-by: Adrian Catangiu <adrian@parity.io> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
@@ -71,7 +71,7 @@ cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-fea
|
||||
cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false, features = ["parameterized-consensus-hook",] }
|
||||
cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false}
|
||||
cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false }
|
||||
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false }
|
||||
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] }
|
||||
cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false }
|
||||
cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false }
|
||||
pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false }
|
||||
@@ -79,10 +79,15 @@ parachain-info = { package = "staging-parachain-info", path = "../../../pallets/
|
||||
parachains-common = { path = "../../../common", default-features = false }
|
||||
assets-common = { path = "../common", default-features = false }
|
||||
|
||||
# Bridges
|
||||
pallet-xcm-bridge-hub-router = { path = "../../../../../bridges/modules/xcm-bridge-hub-router", default-features = false }
|
||||
bp-asset-hub-rococo = { path = "../../../../../bridges/primitives/chain-asset-hub-rococo", default-features = false }
|
||||
bp-asset-hub-westend = { path = "../../../../../bridges/primitives/chain-asset-hub-westend", default-features = false }
|
||||
bp-bridge-hub-westend = { path = "../../../../../bridges/primitives/chain-bridge-hub-westend", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.4.1"
|
||||
asset-test-utils = { path = "../test-utils" }
|
||||
sp-io = { path = "../../../../../substrate/primitives/io" }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { path = "../../../../../substrate/utils/wasm-builder", optional = true }
|
||||
@@ -112,6 +117,7 @@ runtime-benchmarks = [
|
||||
"pallet-uniques/runtime-benchmarks",
|
||||
"pallet-utility/runtime-benchmarks",
|
||||
"pallet-xcm-benchmarks/runtime-benchmarks",
|
||||
"pallet-xcm-bridge-hub-router/runtime-benchmarks",
|
||||
"pallet-xcm/runtime-benchmarks",
|
||||
"parachains-common/runtime-benchmarks",
|
||||
"polkadot-parachain-primitives/runtime-benchmarks",
|
||||
@@ -146,6 +152,7 @@ try-runtime = [
|
||||
"pallet-transaction-payment/try-runtime",
|
||||
"pallet-uniques/try-runtime",
|
||||
"pallet-utility/try-runtime",
|
||||
"pallet-xcm-bridge-hub-router/try-runtime",
|
||||
"pallet-xcm/try-runtime",
|
||||
"parachain-info/try-runtime",
|
||||
"polkadot-runtime-common/try-runtime",
|
||||
@@ -153,6 +160,9 @@ try-runtime = [
|
||||
]
|
||||
std = [
|
||||
"assets-common/std",
|
||||
"bp-asset-hub-rococo/std",
|
||||
"bp-asset-hub-westend/std",
|
||||
"bp-bridge-hub-westend/std",
|
||||
"codec/std",
|
||||
"cumulus-pallet-aura-ext/std",
|
||||
"cumulus-pallet-dmp-queue/std",
|
||||
@@ -189,6 +199,7 @@ std = [
|
||||
"pallet-uniques/std",
|
||||
"pallet-utility/std",
|
||||
"pallet-xcm-benchmarks?/std",
|
||||
"pallet-xcm-bridge-hub-router/std",
|
||||
"pallet-xcm/std",
|
||||
"parachain-info/std",
|
||||
"parachains-common/std",
|
||||
|
||||
@@ -43,7 +43,7 @@ use frame_support::{
|
||||
ord_parameter_types, parameter_types,
|
||||
traits::{
|
||||
tokens::nonfungibles_v2::Inspect, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32,
|
||||
ConstU64, ConstU8, InstanceFilter,
|
||||
ConstU64, ConstU8, Equals, InstanceFilter,
|
||||
},
|
||||
weights::{ConstantMultiplier, Weight},
|
||||
BoundedVec, PalletId,
|
||||
@@ -54,6 +54,7 @@ use frame_system::{
|
||||
};
|
||||
use pallet_asset_conversion_tx_payment::AssetConversionAdapter;
|
||||
use pallet_nfts::PalletFeatures;
|
||||
use pallet_xcm::EnsureXcm;
|
||||
pub use parachains_common as common;
|
||||
use parachains_common::{
|
||||
impls::DealWithFees,
|
||||
@@ -108,7 +109,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("westmint"),
|
||||
impl_name: create_runtime_str!("westmint"),
|
||||
authoring_version: 1,
|
||||
spec_version: 10000,
|
||||
spec_version: 1_003_000,
|
||||
impl_version: 0,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 13,
|
||||
@@ -794,6 +795,37 @@ impl pallet_nfts::Config for Runtime {
|
||||
type Helper = ();
|
||||
}
|
||||
|
||||
/// XCM router instance to BridgeHub with bridging capabilities for `Rococo` global
|
||||
/// consensus with dynamic fees and back-pressure.
|
||||
pub type ToRococoXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance1;
|
||||
impl pallet_xcm_bridge_hub_router::Config<ToRococoXcmRouterInstance> for Runtime {
|
||||
type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo<Runtime>;
|
||||
|
||||
type UniversalLocation = xcm_config::UniversalLocation;
|
||||
type BridgedNetworkId = xcm_config::bridging::to_rococo::RococoNetwork;
|
||||
type Bridges = xcm_config::bridging::NetworkExportTable;
|
||||
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
type BridgeHubOrigin = EnsureXcm<Equals<xcm_config::bridging::SiblingBridgeHub>>;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type BridgeHubOrigin = frame_support::traits::EitherOfDiverse<
|
||||
// for running benchmarks
|
||||
EnsureRoot<AccountId>,
|
||||
// for running tests with `--feature runtime-benchmarks`
|
||||
EnsureXcm<Equals<xcm_config::bridging::SiblingBridgeHub>>,
|
||||
>;
|
||||
|
||||
type ToBridgeHubSender = XcmpQueue;
|
||||
type WithBridgeHubChannel =
|
||||
cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider<
|
||||
xcm_config::bridging::SiblingBridgeHubParaId,
|
||||
Runtime,
|
||||
>;
|
||||
|
||||
type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee;
|
||||
type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId;
|
||||
}
|
||||
|
||||
// Create the runtime by composing the FRAME pallets that were previously configured.
|
||||
construct_runtime!(
|
||||
pub enum Runtime
|
||||
@@ -825,6 +857,8 @@ construct_runtime!(
|
||||
PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 31,
|
||||
CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 32,
|
||||
DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 33,
|
||||
// Bridge utilities.
|
||||
ToRococoXcmRouter: pallet_xcm_bridge_hub_router::<Instance1>::{Pallet, Storage, Call} = 34,
|
||||
|
||||
// Handy utilities.
|
||||
Utility: pallet_utility::{Pallet, Call, Event} = 40,
|
||||
@@ -946,6 +980,7 @@ mod benches {
|
||||
[pallet_timestamp, Timestamp]
|
||||
[pallet_collator_selection, CollatorSelection]
|
||||
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
||||
[pallet_xcm_bridge_hub_router, ToRococo]
|
||||
// XCM
|
||||
[pallet_xcm, PolkadotXcm]
|
||||
// NOTE: Make sure you point to the individual modules below.
|
||||
@@ -1231,6 +1266,7 @@ impl_runtime_apis! {
|
||||
use frame_support::traits::StorageInfoTrait;
|
||||
use frame_system_benchmarking::Pallet as SystemBench;
|
||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||
use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
|
||||
|
||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
||||
@@ -1246,6 +1282,8 @@ impl_runtime_apis! {
|
||||
type Foreign = pallet_assets::Pallet::<Runtime, ForeignAssetsInstance>;
|
||||
type Pool = pallet_assets::Pallet::<Runtime, PoolAssetsInstance>;
|
||||
|
||||
type ToRococo = XcmBridgeHubRouterBench<Runtime, ToRococoXcmRouterInstance>;
|
||||
|
||||
let mut list = Vec::<BenchmarkList>::new();
|
||||
list_benchmarks!(list, extra);
|
||||
|
||||
@@ -1274,6 +1312,25 @@ impl_runtime_apis! {
|
||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||
|
||||
use pallet_xcm_bridge_hub_router::benchmarking::{
|
||||
Pallet as XcmBridgeHubRouterBench,
|
||||
Config as XcmBridgeHubRouterConfig,
|
||||
};
|
||||
|
||||
impl XcmBridgeHubRouterConfig<ToRococoXcmRouterInstance> for Runtime {
|
||||
fn make_congested() {
|
||||
cumulus_pallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::<Runtime>(
|
||||
xcm_config::bridging::SiblingBridgeHubParaId::get().into()
|
||||
);
|
||||
}
|
||||
fn ensure_bridged_target_destination() -> MultiLocation {
|
||||
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
|
||||
xcm_config::bridging::SiblingBridgeHubParaId::get().into()
|
||||
);
|
||||
xcm_config::bridging::to_rococo::AssetHubRococo::get()
|
||||
}
|
||||
}
|
||||
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_config::{MaxAssetsIntoHolding, WestendLocation};
|
||||
use pallet_xcm_benchmarks::asset_instance_from;
|
||||
@@ -1329,7 +1386,13 @@ impl_runtime_apis! {
|
||||
MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) },
|
||||
));
|
||||
pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
|
||||
pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None;
|
||||
// AssetHubWestend trusts AssetHubRococo as reserve for ROCs
|
||||
pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some(
|
||||
(
|
||||
xcm_config::bridging::to_rococo::AssetHubRococo::get(),
|
||||
MultiAsset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
impl pallet_xcm_benchmarks::fungible::Config for Runtime {
|
||||
@@ -1360,7 +1423,10 @@ impl_runtime_apis! {
|
||||
}
|
||||
|
||||
fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> {
|
||||
Err(BenchmarkError::Skip)
|
||||
match xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() {
|
||||
Some(alias) => Ok(alias),
|
||||
None => Err(BenchmarkError::Skip)
|
||||
}
|
||||
}
|
||||
|
||||
fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> {
|
||||
@@ -1399,6 +1465,8 @@ impl_runtime_apis! {
|
||||
type Foreign = pallet_assets::Pallet::<Runtime, ForeignAssetsInstance>;
|
||||
type Pool = pallet_assets::Pallet::<Runtime, PoolAssetsInstance>;
|
||||
|
||||
type ToRococo = XcmBridgeHubRouterBench<Runtime, ToRococoXcmRouterInstance>;
|
||||
|
||||
let whitelist: Vec<TrackedStorageKey> = vec![
|
||||
// Block Number
|
||||
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
|
||||
|
||||
@@ -33,6 +33,7 @@ pub mod pallet_timestamp;
|
||||
pub mod pallet_uniques;
|
||||
pub mod pallet_utility;
|
||||
pub mod pallet_xcm;
|
||||
pub mod pallet_xcm_bridge_hub_router;
|
||||
pub mod paritydb_weights;
|
||||
pub mod rocksdb_weights;
|
||||
pub mod xcm;
|
||||
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// This file is part of Cumulus.
|
||||
|
||||
// Cumulus 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.
|
||||
|
||||
// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Autogenerated weights for `pallet_xcm_bridge_hub_router`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2023-10-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `runner-vmdtonbz-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:
|
||||
// target/production/polkadot-parachain
|
||||
// benchmark
|
||||
// pallet
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --extrinsic=*
|
||||
// --wasm-execution=compiled
|
||||
// --heap-pages=4096
|
||||
// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
|
||||
// --pallet=pallet_xcm_bridge_hub_router
|
||||
// --chain=asset-hub-westend-dev
|
||||
// --header=./cumulus/file_header.txt
|
||||
// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use frame_support::{traits::Get, weights::Weight};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// Weight functions for `pallet_xcm_bridge_hub_router`.
|
||||
pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo<T> {
|
||||
/// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0)
|
||||
/// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0)
|
||||
/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// 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: `193`
|
||||
// Estimated: `1678`
|
||||
// Minimum execution time: 8_157_000 picoseconds.
|
||||
Weight::from_parts(8_481_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 1678))
|
||||
.saturating_add(T::DbWeight::get().reads(3))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
/// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0)
|
||||
/// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0)
|
||||
/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
fn on_initialize_when_congested() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `111`
|
||||
// Estimated: `1596`
|
||||
// Minimum execution time: 3_319_000 picoseconds.
|
||||
Weight::from_parts(3_445_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 1596))
|
||||
.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: `117`
|
||||
// Estimated: `1502`
|
||||
// Minimum execution time: 10_396_000 picoseconds.
|
||||
Weight::from_parts(10_914_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 1502))
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
/// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
/// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
/// Storage: UNKNOWN KEY `0x0973fe64c85043ba1c965cbc38eb63c7` (r:1 w:0)
|
||||
/// Proof: UNKNOWN KEY `0x0973fe64c85043ba1c965cbc38eb63c7` (r:1 w:0)
|
||||
/// Storage: `ToRococoXcmRouter::Bridge` (r:1 w:1)
|
||||
/// Proof: `ToRococoXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`)
|
||||
/// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0)
|
||||
/// Proof: `XcmpQueue::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
/// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
/// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0)
|
||||
/// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `ParachainSystem::RelevantMessagingState` (r:1 w:0)
|
||||
/// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1)
|
||||
/// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0)
|
||||
/// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
/// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1)
|
||||
/// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
fn send_message() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `426`
|
||||
// Estimated: `3891`
|
||||
// Minimum execution time: 45_902_000 picoseconds.
|
||||
Weight::from_parts(46_887_000, 0)
|
||||
.saturating_add(Weight::from_parts(0, 3891))
|
||||
.saturating_add(T::DbWeight::get().reads(10))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ impl<Call> XcmWeightInfo<Call> for AssetHubWestendXcmWeight<Call> {
|
||||
XcmGeneric::<Runtime>::clear_transact_status()
|
||||
}
|
||||
fn universal_origin(_: &Junction) -> Weight {
|
||||
Weight::MAX
|
||||
XcmGeneric::<Runtime>::universal_origin()
|
||||
}
|
||||
fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight {
|
||||
Weight::MAX
|
||||
|
||||
+54
-41
@@ -17,9 +17,9 @@
|
||||
//! Autogenerated weights for `pallet_xcm_benchmarks::fungible`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2023-09-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2023-10-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `runner-nbnwcyh-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
|
||||
//! HOSTNAME: `runner-vmdtonbz-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:
|
||||
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `101`
|
||||
// Estimated: `3593`
|
||||
// Minimum execution time: 25_407_000 picoseconds.
|
||||
Weight::from_parts(25_949_000, 3593)
|
||||
// Minimum execution time: 20_295_000 picoseconds.
|
||||
Weight::from_parts(21_142_000, 3593)
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
@@ -65,15 +65,17 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `101`
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 51_335_000 picoseconds.
|
||||
Weight::from_parts(52_090_000, 6196)
|
||||
// Minimum execution time: 42_356_000 picoseconds.
|
||||
Weight::from_parts(43_552_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(2))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
}
|
||||
// Storage: `System::Account` (r:2 w:2)
|
||||
// Storage: `System::Account` (r:3 w:3)
|
||||
// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
@@ -87,48 +89,53 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
pub fn transfer_reserve_asset() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `246`
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 74_312_000 picoseconds.
|
||||
Weight::from_parts(76_725_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(8))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
// Storage: `Benchmark::Override` (r:0 w:0)
|
||||
// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
pub fn reserve_asset_deposited() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 18_446_744_073_709_551_000 picoseconds.
|
||||
Weight::from_parts(18_446_744_073_709_551_000, 0)
|
||||
// Estimated: `8799`
|
||||
// Minimum execution time: 85_553_000 picoseconds.
|
||||
Weight::from_parts(87_177_000, 8799)
|
||||
.saturating_add(T::DbWeight::get().reads(10))
|
||||
.saturating_add(T::DbWeight::get().writes(5))
|
||||
}
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
pub fn reserve_asset_deposited() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `1489`
|
||||
// Minimum execution time: 6_166_000 picoseconds.
|
||||
Weight::from_parts(6_352_000, 1489)
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
}
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `System::Account` (r:2 w:2)
|
||||
// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1)
|
||||
// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
pub fn initiate_reserve_withdraw() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 446_848_000 picoseconds.
|
||||
Weight::from_parts(466_251_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
// Measured: `246`
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 184_462_000 picoseconds.
|
||||
Weight::from_parts(189_593_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(9))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
pub fn receive_teleported_asset() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 3_602_000 picoseconds.
|
||||
Weight::from_parts(3_844_000, 0)
|
||||
// Minimum execution time: 3_018_000 picoseconds.
|
||||
Weight::from_parts(3_098_000, 0)
|
||||
}
|
||||
// Storage: `System::Account` (r:1 w:1)
|
||||
// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
@@ -136,15 +143,17 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `3593`
|
||||
// Minimum execution time: 25_480_000 picoseconds.
|
||||
Weight::from_parts(26_142_000, 3593)
|
||||
// Minimum execution time: 18_583_000 picoseconds.
|
||||
Weight::from_parts(19_057_000, 3593)
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
// 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: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
@@ -158,20 +167,24 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
pub fn deposit_reserve_asset() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 51_540_000 picoseconds.
|
||||
Weight::from_parts(53_744_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(7))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 56_666_000 picoseconds.
|
||||
Weight::from_parts(58_152_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(9))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SafeXcmVersion` (`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: `ParachainSystem::HostConfiguration` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1)
|
||||
@@ -180,9 +193,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 32_279_000 picoseconds.
|
||||
Weight::from_parts(33_176_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
// Minimum execution time: 44_197_000 picoseconds.
|
||||
Weight::from_parts(45_573_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(8))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
}
|
||||
}
|
||||
|
||||
+114
-88
@@ -17,28 +17,26 @@
|
||||
//! Autogenerated weights for `pallet_xcm_benchmarks::generic`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2023-10-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
|
||||
//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("asset-hub-westend-dev"), DB CACHE: 1024
|
||||
//! HOSTNAME: `runner-vmdtonbz-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:
|
||||
// ./target/production/polkadot-parachain
|
||||
// target/production/polkadot-parachain
|
||||
// benchmark
|
||||
// pallet
|
||||
// --template=./templates/xcm-bench-template.hbs
|
||||
// --chain=asset-hub-westend-dev
|
||||
// --wasm-execution=compiled
|
||||
// --pallet=pallet_xcm_benchmarks::generic
|
||||
// --no-storage-info
|
||||
// --no-median-slopes
|
||||
// --no-min-squares
|
||||
// --extrinsic=*
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --json
|
||||
// --header=./file_header.txt
|
||||
// --output=./parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs
|
||||
// --extrinsic=*
|
||||
// --wasm-execution=compiled
|
||||
// --heap-pages=4096
|
||||
// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
|
||||
// --pallet=pallet_xcm_benchmarks::generic
|
||||
// --chain=asset-hub-westend-dev
|
||||
// --header=./cumulus/file_header.txt
|
||||
// --template=./cumulus/templates/xcm-bench-template.hbs
|
||||
// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
@@ -52,31 +50,35 @@ pub struct WeightInfo<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `System::Account` (r:2 w:2)
|
||||
// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1)
|
||||
// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
pub fn report_holding() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 405_795_000 picoseconds.
|
||||
Weight::from_parts(421_225_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
// Measured: `246`
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 415_033_000 picoseconds.
|
||||
Weight::from_parts(429_573_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(9))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
pub fn buy_execution() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 4_021_000 picoseconds.
|
||||
Weight::from_parts(4_234_000, 0)
|
||||
// Minimum execution time: 3_193_000 picoseconds.
|
||||
Weight::from_parts(3_620_000, 0)
|
||||
}
|
||||
// Storage: `PolkadotXcm::Queries` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
@@ -84,79 +86,83 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `103`
|
||||
// Estimated: `3568`
|
||||
// Minimum execution time: 11_004_000 picoseconds.
|
||||
Weight::from_parts(11_217_000, 3568)
|
||||
// Minimum execution time: 8_045_000 picoseconds.
|
||||
Weight::from_parts(8_402_000, 3568)
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
}
|
||||
pub fn transact() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 12_888_000 picoseconds.
|
||||
Weight::from_parts(13_249_000, 0)
|
||||
// Minimum execution time: 9_827_000 picoseconds.
|
||||
Weight::from_parts(10_454_000, 0)
|
||||
}
|
||||
pub fn refund_surplus() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 4_504_000 picoseconds.
|
||||
Weight::from_parts(4_984_000, 0)
|
||||
// Minimum execution time: 3_330_000 picoseconds.
|
||||
Weight::from_parts(3_677_000, 0)
|
||||
}
|
||||
pub fn set_error_handler() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_733_000 picoseconds.
|
||||
Weight::from_parts(2_887_000, 0)
|
||||
// Minimum execution time: 1_947_000 picoseconds.
|
||||
Weight::from_parts(2_083_000, 0)
|
||||
}
|
||||
pub fn set_appendix() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_753_000 picoseconds.
|
||||
Weight::from_parts(2_844_000, 0)
|
||||
// Minimum execution time: 1_915_000 picoseconds.
|
||||
Weight::from_parts(1_993_000, 0)
|
||||
}
|
||||
pub fn clear_error() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_741_000 picoseconds.
|
||||
Weight::from_parts(2_826_000, 0)
|
||||
// Minimum execution time: 1_918_000 picoseconds.
|
||||
Weight::from_parts(2_048_000, 0)
|
||||
}
|
||||
pub fn descend_origin() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 3_417_000 picoseconds.
|
||||
Weight::from_parts(3_525_000, 0)
|
||||
// Minimum execution time: 2_683_000 picoseconds.
|
||||
Weight::from_parts(3_064_000, 0)
|
||||
}
|
||||
pub fn clear_origin() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_775_000 picoseconds.
|
||||
Weight::from_parts(2_853_000, 0)
|
||||
// Minimum execution time: 1_893_000 picoseconds.
|
||||
Weight::from_parts(2_159_000, 0)
|
||||
}
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `System::Account` (r:2 w:2)
|
||||
// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1)
|
||||
// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
pub fn report_error() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 27_035_000 picoseconds.
|
||||
Weight::from_parts(27_734_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
// Measured: `246`
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 53_116_000 picoseconds.
|
||||
Weight::from_parts(54_154_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(9))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
@@ -164,8 +170,8 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `160`
|
||||
// Estimated: `3625`
|
||||
// Minimum execution time: 15_728_000 picoseconds.
|
||||
Weight::from_parts(16_145_000, 3625)
|
||||
// Minimum execution time: 12_381_000 picoseconds.
|
||||
Weight::from_parts(12_693_000, 3625)
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
@@ -173,11 +179,13 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_630_000 picoseconds.
|
||||
Weight::from_parts(2_700_000, 0)
|
||||
// Minimum execution time: 1_933_000 picoseconds.
|
||||
Weight::from_parts(1_983_000, 0)
|
||||
}
|
||||
// Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
@@ -192,9 +200,9 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 29_996_000 picoseconds.
|
||||
Weight::from_parts(30_620_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
// Minimum execution time: 24_251_000 picoseconds.
|
||||
Weight::from_parts(24_890_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(7))
|
||||
.saturating_add(T::DbWeight::get().writes(3))
|
||||
}
|
||||
// Storage: `PolkadotXcm::VersionNotifyTargets` (r:0 w:1)
|
||||
@@ -203,127 +211,145 @@ impl<T: frame_system::Config> WeightInfo<T> {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 4_629_000 picoseconds.
|
||||
Weight::from_parts(4_861_000, 0)
|
||||
// Minimum execution time: 3_850_000 picoseconds.
|
||||
Weight::from_parts(4_082_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: 135_145_000 picoseconds.
|
||||
Weight::from_parts(142_115_000, 0)
|
||||
// Minimum execution time: 112_248_000 picoseconds.
|
||||
Weight::from_parts(124_454_000, 0)
|
||||
}
|
||||
pub fn expect_asset() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 11_948_000 picoseconds.
|
||||
Weight::from_parts(12_160_000, 0)
|
||||
// Minimum execution time: 11_457_000 picoseconds.
|
||||
Weight::from_parts(12_060_000, 0)
|
||||
}
|
||||
pub fn expect_origin() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_718_000 picoseconds.
|
||||
Weight::from_parts(2_794_000, 0)
|
||||
// Minimum execution time: 1_959_000 picoseconds.
|
||||
Weight::from_parts(2_076_000, 0)
|
||||
}
|
||||
pub fn expect_error() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_590_000 picoseconds.
|
||||
Weight::from_parts(2_674_000, 0)
|
||||
// Minimum execution time: 1_920_000 picoseconds.
|
||||
Weight::from_parts(1_994_000, 0)
|
||||
}
|
||||
pub fn expect_transact_status() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_858_000 picoseconds.
|
||||
Weight::from_parts(2_939_000, 0)
|
||||
// Minimum execution time: 2_149_000 picoseconds.
|
||||
Weight::from_parts(2_394_000, 0)
|
||||
}
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `System::Account` (r:2 w:2)
|
||||
// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1)
|
||||
// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
pub fn query_pallet() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 30_652_000 picoseconds.
|
||||
Weight::from_parts(31_552_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
// Measured: `246`
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 58_011_000 picoseconds.
|
||||
Weight::from_parts(59_306_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(9))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
pub fn expect_pallet() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 5_408_000 picoseconds.
|
||||
Weight::from_parts(5_597_000, 0)
|
||||
// Minimum execution time: 5_031_000 picoseconds.
|
||||
Weight::from_parts(5_243_000, 0)
|
||||
}
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1)
|
||||
// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0)
|
||||
// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `System::Account` (r:2 w:2)
|
||||
// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
|
||||
// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0)
|
||||
// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1)
|
||||
// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||
pub fn report_transact_status() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3610`
|
||||
// Minimum execution time: 27_144_000 picoseconds.
|
||||
Weight::from_parts(27_736_000, 3610)
|
||||
.saturating_add(T::DbWeight::get().reads(6))
|
||||
.saturating_add(T::DbWeight::get().writes(2))
|
||||
// Measured: `246`
|
||||
// Estimated: `6196`
|
||||
// Minimum execution time: 53_078_000 picoseconds.
|
||||
Weight::from_parts(54_345_000, 6196)
|
||||
.saturating_add(T::DbWeight::get().reads(9))
|
||||
.saturating_add(T::DbWeight::get().writes(4))
|
||||
}
|
||||
pub fn clear_transact_status() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_696_000 picoseconds.
|
||||
Weight::from_parts(2_802_000, 0)
|
||||
// Minimum execution time: 1_936_000 picoseconds.
|
||||
Weight::from_parts(2_002_000, 0)
|
||||
}
|
||||
pub fn set_topic() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_655_000 picoseconds.
|
||||
Weight::from_parts(2_720_000, 0)
|
||||
// Minimum execution time: 1_855_000 picoseconds.
|
||||
Weight::from_parts(1_950_000, 0)
|
||||
}
|
||||
pub fn clear_topic() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_599_000 picoseconds.
|
||||
Weight::from_parts(2_723_000, 0)
|
||||
// Minimum execution time: 1_882_000 picoseconds.
|
||||
Weight::from_parts(1_977_000, 0)
|
||||
}
|
||||
// Storage: `ParachainInfo::ParachainId` (r:1 w:0)
|
||||
// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
pub fn universal_origin() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `1489`
|
||||
// Minimum execution time: 3_912_000 picoseconds.
|
||||
Weight::from_parts(4_167_000, 1489)
|
||||
.saturating_add(T::DbWeight::get().reads(1))
|
||||
}
|
||||
pub fn set_fees_mode() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_630_000 picoseconds.
|
||||
Weight::from_parts(2_728_000, 0)
|
||||
// Minimum execution time: 1_911_000 picoseconds.
|
||||
Weight::from_parts(1_971_000, 0)
|
||||
}
|
||||
pub fn unpaid_execution() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `0`
|
||||
// Estimated: `0`
|
||||
// Minimum execution time: 2_797_000 picoseconds.
|
||||
Weight::from_parts(2_928_000, 0)
|
||||
// Minimum execution time: 1_990_000 picoseconds.
|
||||
Weight::from_parts(2_076_000, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
|
||||
use super::{
|
||||
AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee,
|
||||
FeeAssetId, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall,
|
||||
RuntimeEvent, RuntimeOrigin, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee,
|
||||
XcmpQueue,
|
||||
FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm,
|
||||
PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToRococoXcmRouter,
|
||||
TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
|
||||
};
|
||||
use crate::ForeignAssets;
|
||||
use assets_common::{
|
||||
local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation,
|
||||
matching::{FromSiblingParachain, IsForeignConcreteAsset},
|
||||
@@ -47,12 +46,13 @@ use xcm_builder::{
|
||||
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
|
||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter,
|
||||
DenyReserveTransferToRelayChain, DenyThenTry, DescribeFamily, DescribePalletTerminal,
|
||||
EnsureXcmOrigin, FungiblesAdapter, HashedDescription, IsConcrete, LocalMint, NoChecking,
|
||||
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
|
||||
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
|
||||
SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit,
|
||||
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
|
||||
XcmFeeManagerFromComponents, XcmFeeToAccount,
|
||||
EnsureXcmOrigin, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription,
|
||||
IsConcrete, LocalMint, NetworkExportTableItem, NoChecking, ParentAsSuperuser, ParentIsPreset,
|
||||
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
|
||||
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, StartsWith,
|
||||
StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
|
||||
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
|
||||
XcmFeeToAccount,
|
||||
};
|
||||
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};
|
||||
|
||||
@@ -90,6 +90,9 @@ pub type LocationToAccountId = (
|
||||
// Foreign chain account alias into local accounts according to a hash of their standard
|
||||
// description.
|
||||
HashedDescription<AccountId, DescribeFamily<DescribePalletTerminal>>,
|
||||
// Different global consensus parachain sovereign account.
|
||||
// (Used for over-bridge transfers and reserve processing)
|
||||
GlobalConsensusParachainConvertsFor<UniversalLocation, AccountId>,
|
||||
);
|
||||
|
||||
/// Means for transacting the native currency on this chain.
|
||||
@@ -256,6 +259,14 @@ impl Contains<RuntimeCall> for SafeCallFilter {
|
||||
}
|
||||
}
|
||||
|
||||
// Allow to change dedicated storage items (called by governance-like)
|
||||
match call {
|
||||
RuntimeCall::System(frame_system::Call::set_storage { items })
|
||||
if items.iter().all(|(k, _)| k.eq(&bridging::XcmBridgeHubRouterByteFee::key())) =>
|
||||
return true,
|
||||
_ => (),
|
||||
};
|
||||
|
||||
matches!(
|
||||
call,
|
||||
RuntimeCall::PolkadotXcm(pallet_xcm::Call::force_xcm_version { .. }) |
|
||||
@@ -445,7 +456,9 @@ impl Contains<RuntimeCall> for SafeCallFilter {
|
||||
pallet_uniques::Call::set_accept_ownership { .. } |
|
||||
pallet_uniques::Call::set_collection_max_supply { .. } |
|
||||
pallet_uniques::Call::set_price { .. } |
|
||||
pallet_uniques::Call::buy_item { .. },
|
||||
pallet_uniques::Call::buy_item { .. }
|
||||
) | RuntimeCall::ToRococoXcmRouter(
|
||||
pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. }
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -469,6 +482,7 @@ pub type Barrier = TrailingSetTopicAsId<
|
||||
AllowExplicitUnpaidExecutionFrom<(
|
||||
ParentOrParentsPlurality,
|
||||
Equals<RelayTreasuryLocation>,
|
||||
Equals<bridging::SiblingBridgeHub>,
|
||||
)>,
|
||||
// Subscriptions for version tracking are OK.
|
||||
AllowSubscriptionsFrom<Everything>,
|
||||
@@ -492,6 +506,15 @@ pub type AssetFeeAsExistentialDepositMultiplierFeeCharger = AssetFeeAsExistentia
|
||||
TrustBackedAssetsInstance,
|
||||
>;
|
||||
|
||||
/// Multiplier used for dedicated `TakeFirstAssetTrader` with `ForeignAssets` instance.
|
||||
pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger =
|
||||
AssetFeeAsExistentialDepositMultiplier<
|
||||
Runtime,
|
||||
WeightToFee,
|
||||
pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto, ForeignAssetsInstance>,
|
||||
ForeignAssetsInstance,
|
||||
>;
|
||||
|
||||
match_types! {
|
||||
pub type SystemParachains: impl Contains<MultiLocation> = {
|
||||
MultiLocation {
|
||||
@@ -526,10 +549,11 @@ impl xcm_executor::Config for XcmConfig {
|
||||
type XcmSender = XcmRouter;
|
||||
type AssetTransactor = AssetTransactors;
|
||||
type OriginConverter = XcmOriginToTransactDispatchOrigin;
|
||||
// Asset Hub Westend does not recognize a reserve location for any asset. This does not prevent
|
||||
// Asset Hub acting _as_ a reserve location for WND and assets created under `pallet-assets`.
|
||||
// For WND, users must use teleport where allowed (e.g. with the Relay Chain).
|
||||
type IsReserve = ();
|
||||
// Asset Hub trusts only particular, pre-configured bridged locations from a different consensus
|
||||
// as reserve locations (we trust the Bridge Hub to relay the message that a reserve is being
|
||||
// held). Asset Hub may _act_ as a reserve location for WND and assets created
|
||||
// under `pallet-assets`. Users must use teleport where allowed (e.g. WND with the Relay Chain).
|
||||
type IsReserve = (bridging::to_rococo::IsTrustedBridgedReserveLocationForConcreteAsset,);
|
||||
type IsTeleporter = TrustedTeleporters;
|
||||
type UniversalLocation = UniversalLocation;
|
||||
type Barrier = Barrier;
|
||||
@@ -553,6 +577,19 @@ impl xcm_executor::Config for XcmConfig {
|
||||
XcmAssetFeesReceiver,
|
||||
>,
|
||||
>,
|
||||
// This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated
|
||||
// `pallet_assets` instance - `ForeignAssets`.
|
||||
cumulus_primitives_utility::TakeFirstAssetTrader<
|
||||
AccountId,
|
||||
ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger,
|
||||
ForeignAssetsConvertedConcreteId,
|
||||
ForeignAssets,
|
||||
cumulus_primitives_utility::XcmFeesTo32ByteAccount<
|
||||
ForeignFungiblesTransactor,
|
||||
AccountId,
|
||||
XcmAssetFeesReceiver,
|
||||
>,
|
||||
>,
|
||||
);
|
||||
type ResponseHandler = PolkadotXcm;
|
||||
type AssetTrap = PolkadotXcm;
|
||||
@@ -567,7 +604,7 @@ impl xcm_executor::Config for XcmConfig {
|
||||
XcmFeeToAccount<Self::AssetTransactor, AccountId, TreasuryAccount>,
|
||||
>;
|
||||
type MessageExporter = ();
|
||||
type UniversalAliases = Nothing;
|
||||
type UniversalAliases = (bridging::to_rococo::UniversalAliases,);
|
||||
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
|
||||
type SafeCallFilter = SafeCallFilter;
|
||||
type Aliasers = Nothing;
|
||||
@@ -579,13 +616,21 @@ pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, R
|
||||
pub type PriceForParentDelivery =
|
||||
ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, ParachainSystem>;
|
||||
|
||||
/// The means for routing XCM messages which are not for local execution into the right message
|
||||
/// queues.
|
||||
pub type XcmRouter = WithUniqueTopic<(
|
||||
/// For routing XCM messages which do not cross local consensus boundary.
|
||||
type LocalXcmRouter = (
|
||||
// Two routers - use UMP to communicate with the relay chain:
|
||||
cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm, PriceForParentDelivery>,
|
||||
// ..and XCMP to communicate with the sibling chains.
|
||||
XcmpQueue,
|
||||
);
|
||||
|
||||
/// The means for routing XCM messages which are not for local execution into the right message
|
||||
/// queues.
|
||||
pub type XcmRouter = WithUniqueTopic<(
|
||||
LocalXcmRouter,
|
||||
// Router which wraps and sends xcm to BridgeHub to be delivered to the Rococo
|
||||
// GlobalConsensus
|
||||
ToRococoXcmRouter,
|
||||
)>;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
@@ -672,3 +717,124 @@ where
|
||||
sp_std::boxed::Box::new(Self::asset_id(asset_id))
|
||||
}
|
||||
}
|
||||
|
||||
/// All configuration related to bridging
|
||||
pub mod bridging {
|
||||
use super::*;
|
||||
use assets_common::matching;
|
||||
use sp_std::collections::btree_set::BTreeSet;
|
||||
|
||||
parameter_types! {
|
||||
pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID;
|
||||
pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get())));
|
||||
/// Router expects payment with this `AssetId`.
|
||||
/// (`AssetId` has to be aligned with `BridgeTable`)
|
||||
pub XcmBridgeHubRouterFeeAssetId: AssetId = WestendLocation::get().into();
|
||||
/// Price per byte - can be adjusted via governance `set_storage` call.
|
||||
pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get();
|
||||
|
||||
pub BridgeTable: sp_std::vec::Vec<NetworkExportTableItem> =
|
||||
sp_std::vec::Vec::new().into_iter()
|
||||
.chain(to_rococo::BridgeTable::get())
|
||||
.collect();
|
||||
}
|
||||
|
||||
pub type NetworkExportTable = xcm_builder::NetworkExportTable<BridgeTable>;
|
||||
|
||||
pub mod to_rococo {
|
||||
use super::*;
|
||||
|
||||
parameter_types! {
|
||||
pub SiblingBridgeHubWithBridgeHubRococoInstance: MultiLocation = MultiLocation::new(
|
||||
1,
|
||||
X2(
|
||||
Parachain(SiblingBridgeHubParaId::get()),
|
||||
PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)
|
||||
)
|
||||
);
|
||||
|
||||
pub const RococoNetwork: NetworkId = NetworkId::Rococo;
|
||||
pub AssetHubRococo: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(RococoNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID)));
|
||||
pub RocLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(RococoNetwork::get())));
|
||||
|
||||
pub RocFromAssetHubRococo: (MultiAssetFilter, MultiLocation) = (
|
||||
Wild(AllOf { fun: WildFungible, id: Concrete(RocLocation::get()) }),
|
||||
AssetHubRococo::get()
|
||||
);
|
||||
|
||||
/// Set up exporters configuration.
|
||||
/// `Option<MultiAsset>` represents static "base fee" which is used for total delivery fee calculation.
|
||||
pub BridgeTable: sp_std::vec::Vec<NetworkExportTableItem> = sp_std::vec![
|
||||
NetworkExportTableItem::new(
|
||||
RococoNetwork::get(),
|
||||
Some(sp_std::vec![
|
||||
AssetHubRococo::get().interior.split_global().expect("invalid configuration for AssetHubRococo").1,
|
||||
]),
|
||||
SiblingBridgeHub::get(),
|
||||
// base delivery fee to local `BridgeHub`
|
||||
Some((
|
||||
XcmBridgeHubRouterFeeAssetId::get(),
|
||||
bp_asset_hub_westend::BridgeHubWestendBaseFeeInWnds::get(),
|
||||
).into())
|
||||
)
|
||||
];
|
||||
|
||||
/// Universal aliases
|
||||
pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter(
|
||||
sp_std::vec![
|
||||
(SiblingBridgeHubWithBridgeHubRococoInstance::get(), GlobalConsensus(RococoNetwork::get()))
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
impl Contains<(MultiLocation, Junction)> for UniversalAliases {
|
||||
fn contains(alias: &(MultiLocation, Junction)) -> bool {
|
||||
UniversalAliases::get().contains(alias)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reserve locations filter for `xcm_executor::Config::IsReserve`.
|
||||
/// Locations from which the runtime accepts reserved assets.
|
||||
pub type IsTrustedBridgedReserveLocationForConcreteAsset =
|
||||
matching::IsTrustedBridgedReserveLocationForConcreteAsset<
|
||||
UniversalLocation,
|
||||
(
|
||||
// allow receive ROC from AssetHubRococo
|
||||
xcm_builder::Case<RocFromAssetHubRococo>,
|
||||
// and nothing else
|
||||
),
|
||||
>;
|
||||
|
||||
impl Contains<RuntimeCall> for ToRococoXcmRouter {
|
||||
fn contains(call: &RuntimeCall) -> bool {
|
||||
matches!(
|
||||
call,
|
||||
RuntimeCall::ToRococoXcmRouter(
|
||||
pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. }
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Benchmarks helper for bridging configuration.
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub struct BridgingBenchmarksHelper;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
impl BridgingBenchmarksHelper {
|
||||
pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> {
|
||||
let alias =
|
||||
to_rococo::UniversalAliases::get().into_iter().find_map(|(location, junction)| {
|
||||
match to_rococo::SiblingBridgeHubWithBridgeHubRococoInstance::get()
|
||||
.eq(&location)
|
||||
{
|
||||
true => Some((location, junction)),
|
||||
false => None,
|
||||
}
|
||||
});
|
||||
assert!(alias.is_some(), "we expect here BridgeHubWestend to Rococo mapping at least");
|
||||
Some(alias.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,20 +19,19 @@
|
||||
|
||||
use asset_hub_westend_runtime::{
|
||||
xcm_config::{
|
||||
AssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf,
|
||||
WestendLocation,
|
||||
self, bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount,
|
||||
ForeignCreatorsSovereignAccountOf, LocationToAccountId, TrustBackedAssetsPalletLocation,
|
||||
WestendLocation, XcmConfig,
|
||||
},
|
||||
AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall,
|
||||
RuntimeEvent,
|
||||
AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets,
|
||||
ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime,
|
||||
RuntimeCall, RuntimeEvent, SessionKeys, ToRococoXcmRouterInstance, TrustBackedAssetsInstance,
|
||||
XcmpQueue,
|
||||
};
|
||||
pub use asset_hub_westend_runtime::{
|
||||
xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig},
|
||||
AllowMultiAssetPools, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets,
|
||||
ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System,
|
||||
TrustBackedAssetsInstance,
|
||||
use asset_test_utils::{
|
||||
test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder,
|
||||
};
|
||||
use asset_test_utils::{CollatorSessionKeys, ExtBuilder, XcmReceivedFrom};
|
||||
use codec::{Decode, DecodeLimit, Encode};
|
||||
use codec::{Decode, Encode};
|
||||
use cumulus_primitives_utility::ChargeWeightInFungibles;
|
||||
use frame_support::{
|
||||
assert_noop, assert_ok,
|
||||
@@ -42,14 +41,10 @@ use frame_support::{
|
||||
use parachains_common::{
|
||||
westend::fee::WeightToFee, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance,
|
||||
};
|
||||
use sp_io;
|
||||
use sp_runtime::traits::MaybeEquivalence;
|
||||
use std::convert::Into;
|
||||
use xcm::{latest::prelude::*, VersionedXcm, MAX_XCM_DECODE_DEPTH};
|
||||
use xcm_executor::{
|
||||
traits::{Identity, JustTry, WeightTrader},
|
||||
XcmExecutor,
|
||||
};
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_executor::traits::{Identity, JustTry, WeightTrader};
|
||||
|
||||
const ALICE: [u8; 32] = [1u8; 32];
|
||||
const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32];
|
||||
@@ -59,14 +54,18 @@ type AssetIdForTrustBackedAssetsConvert =
|
||||
|
||||
type RuntimeHelper = asset_test_utils::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;
|
||||
|
||||
fn collator_session_keys() -> CollatorSessionKeys<Runtime> {
|
||||
CollatorSessionKeys::new(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) },
|
||||
fn collator_session_key(account: [u8; 32]) -> CollatorSessionKey<Runtime> {
|
||||
CollatorSessionKey::new(
|
||||
AccountId::from(account),
|
||||
AccountId::from(account),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(account)) },
|
||||
)
|
||||
}
|
||||
|
||||
fn collator_session_keys() -> CollatorSessionKeys<Runtime> {
|
||||
CollatorSessionKeys::default().add(collator_session_key(ALICE))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_asset_xcm_trader() {
|
||||
ExtBuilder::<Runtime>::default()
|
||||
@@ -253,7 +252,7 @@ fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() {
|
||||
// Set Alice as block author, who will receive fees
|
||||
RuntimeHelper::run_to_block(2, AccountId::from(ALICE));
|
||||
|
||||
// We are going to buy 5e9 weight
|
||||
// We are going to buy small amount
|
||||
let bought = Weight::from_parts(500_000_000u64, 0);
|
||||
|
||||
let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap();
|
||||
@@ -641,28 +640,178 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p
|
||||
})
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn plain_receive_teleported_asset_works() {
|
||||
ExtBuilder::<Runtime>::default()
|
||||
.with_collators(vec![AccountId::from(ALICE)])
|
||||
.with_session_keys(vec![(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) },
|
||||
)])
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
let data = hex_literal::hex!("02100204000100000b00a0724e18090a13000100000b00a0724e180901e20f5e480d010004000101001299557001f55815d3fcb53c74463acb0cf6d14d4639b340982c60877f384609").to_vec();
|
||||
let message_id = sp_io::hashing::blake2_256(&data);
|
||||
|
||||
let maybe_msg = VersionedXcm::<RuntimeCall>::decode_all_with_depth_limit(
|
||||
MAX_XCM_DECODE_DEPTH,
|
||||
&mut data.as_ref(),
|
||||
)
|
||||
.map(xcm::v3::Xcm::<RuntimeCall>::try_from).expect("failed").expect("failed");
|
||||
|
||||
let outcome =
|
||||
XcmExecutor::<XcmConfig>::execute_xcm(Parent, maybe_msg, message_id, RuntimeHelper::xcm_max_weight(XcmReceivedFrom::Parent));
|
||||
assert_eq!(outcome.ensure_complete(), Ok(()));
|
||||
})
|
||||
fn bridging_to_asset_hub_rococo() -> TestBridgingConfig {
|
||||
TestBridgingConfig {
|
||||
bridged_network: bridging::to_rococo::RococoNetwork::get(),
|
||||
local_bridge_hub_para_id: bridging::SiblingBridgeHubParaId::get(),
|
||||
local_bridge_hub_location: bridging::SiblingBridgeHub::get(),
|
||||
bridged_target_location: bridging::to_rococo::AssetHubRococo::get(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_rococo_works() {
|
||||
asset_test_utils::test_cases_over_bridge::limited_reserve_transfer_assets_for_native_asset_works::<
|
||||
Runtime,
|
||||
AllPalletsWithoutSystem,
|
||||
XcmConfig,
|
||||
ParachainSystem,
|
||||
XcmpQueue,
|
||||
LocationToAccountId,
|
||||
>(
|
||||
collator_session_keys(),
|
||||
ExistentialDeposit::get(),
|
||||
AccountId::from(ALICE),
|
||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
}),
|
||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
}),
|
||||
bridging_to_asset_hub_rococo,
|
||||
WeightLimit::Unlimited,
|
||||
Some(xcm_config::bridging::XcmBridgeHubRouterFeeAssetId::get()),
|
||||
Some(xcm_config::TreasuryAccount::get()),
|
||||
)
|
||||
}
|
||||
#[test]
|
||||
fn receive_reserve_asset_deposited_roc_from_asset_hub_rococo_works() {
|
||||
const BLOCK_AUTHOR_ACCOUNT: [u8; 32] = [13; 32];
|
||||
asset_test_utils::test_cases_over_bridge::receive_reserve_asset_deposited_from_different_consensus_works::<
|
||||
Runtime,
|
||||
AllPalletsWithoutSystem,
|
||||
XcmConfig,
|
||||
LocationToAccountId,
|
||||
ForeignAssetsInstance,
|
||||
>(
|
||||
collator_session_keys().add(collator_session_key(BLOCK_AUTHOR_ACCOUNT)),
|
||||
ExistentialDeposit::get(),
|
||||
AccountId::from([73; 32]),
|
||||
AccountId::from(BLOCK_AUTHOR_ACCOUNT),
|
||||
// receiving ROCs
|
||||
(MultiLocation { parents: 2, interior: X1(GlobalConsensus(Rococo)) }, 1000000000000, 1_000_000_000),
|
||||
bridging_to_asset_hub_rococo,
|
||||
(
|
||||
X1(PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)),
|
||||
GlobalConsensus(Rococo),
|
||||
X1(Parachain(1000))
|
||||
)
|
||||
)
|
||||
}
|
||||
#[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,
|
||||
|| {
|
||||
sp_std::vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
Transact {
|
||||
origin_kind: OriginKind::Xcm,
|
||||
require_weight_at_most:
|
||||
bp_asset_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(),
|
||||
call: bp_asset_hub_westend::Call::ToRococoXcmRouter(
|
||||
bp_asset_hub_westend::XcmBridgeHubRouterCall::report_bridge_status {
|
||||
bridge_id: Default::default(),
|
||||
is_congested: true,
|
||||
}
|
||||
)
|
||||
.encode()
|
||||
.into(),
|
||||
}
|
||||
]
|
||||
.into()
|
||||
},
|
||||
|| {
|
||||
sp_std::vec![
|
||||
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
|
||||
Transact {
|
||||
origin_kind: OriginKind::Xcm,
|
||||
require_weight_at_most:
|
||||
bp_asset_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(),
|
||||
call: bp_asset_hub_westend::Call::ToRococoXcmRouter(
|
||||
bp_asset_hub_westend::XcmBridgeHubRouterCall::report_bridge_status {
|
||||
bridge_id: Default::default(),
|
||||
is_congested: false,
|
||||
}
|
||||
)
|
||||
.encode()
|
||||
.into(),
|
||||
}
|
||||
]
|
||||
.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 = <Runtime as pallet_xcm_bridge_hub_router::Config<
|
||||
ToRococoXcmRouterInstance,
|
||||
>>::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::<
|
||||
Runtime,
|
||||
bridging::XcmBridgeHubRouterByteFee,
|
||||
Balance,
|
||||
>(
|
||||
collator_session_keys(),
|
||||
1000,
|
||||
Box::new(|call| RuntimeCall::System(call).encode()),
|
||||
|| {
|
||||
(
|
||||
bridging::XcmBridgeHubRouterByteFee::key().to_vec(),
|
||||
bridging::XcmBridgeHubRouterByteFee::get(),
|
||||
)
|
||||
},
|
||||
|old_value| {
|
||||
if let Some(new_value) = old_value.checked_add(1) {
|
||||
new_value
|
||||
} else {
|
||||
old_value.checked_sub(1).unwrap()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user