diff --git a/Cargo.lock b/Cargo.lock index 59f466715..a19e2f4ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1643,9 +1643,11 @@ dependencies = [ "fp-evm", "fp-rpc", "fp-self-contained", + "frame-benchmarking", "frame-executive", "frame-support", "frame-system", + "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", "hex-literal 0.3.4", @@ -1680,6 +1682,7 @@ dependencies = [ "pallet-tx-pause", "pallet-utility", "pallet-xcm", + "pallet-xcm-benchmarks", "parachain-info", "parity-scale-codec", "polkadot-parachain-primitives", @@ -1821,6 +1824,7 @@ dependencies = [ "pallet-tx-pause", "pallet-utility", "pallet-xcm", + "pallet-xcm-benchmarks", "parachain-info", "parity-scale-codec", "polkadot-parachain-primitives", @@ -2820,6 +2824,8 @@ dependencies = [ "hex-literal 0.3.4", "log", "nimbus-primitives", + "pallet-asset-rate", + "pallet-assets", "pallet-async-backing", "pallet-author-inherent", "pallet-author-noting", @@ -2831,6 +2837,7 @@ dependencies = [ "pallet-collator-assignment-runtime-api", "pallet-configuration", "pallet-data-preservers", + "pallet-foreign-asset-creator", "pallet-identity", "pallet-im-online", "pallet-inflation-rewards", @@ -2843,6 +2850,7 @@ dependencies = [ "pallet-proxy", "pallet-registrar", "pallet-registrar-runtime-api", + "pallet-relay-storage-roots", "pallet-root-testing", "pallet-services-payment", "pallet-session", @@ -2856,6 +2864,7 @@ dependencies = [ "pallet-xcm", "pallet-xcm-benchmarks", "parachain-info", + "parachains-common", "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-runtime-common", @@ -3974,6 +3983,7 @@ dependencies = [ "pallet-proxy", "pallet-registrar", "pallet-registrar-runtime-api", + "pallet-relay-storage-roots", "pallet-root-testing", "pallet-services-payment", "pallet-session", @@ -7626,6 +7636,8 @@ dependencies = [ "sp-runtime", "sp-std", "tp-traits", + "tracing", + "tracing-subscriber", ] [[package]] @@ -8016,6 +8028,25 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-foreign-asset-creator" +version = "0.1.0" +source = "git+https://github.com/moondance-labs/moonkit?branch=agustin-client-async-backing#cd873f110d04862b84f28e933903334c6202c159" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std", + "staging-xcm", +] + [[package]] name = "pallet-grandpa" version = "4.0.0-dev" @@ -8521,6 +8552,29 @@ dependencies = [ "tp-container-chain-genesis-data", ] +[[package]] +name = "pallet-relay-storage-roots" +version = "0.1.0" +source = "git+https://github.com/moondance-labs/moonkit?branch=agustin-client-async-backing#cd873f110d04862b84f28e933903334c6202c159" +dependencies = [ + "cumulus-pallet-parachain-system", + "cumulus-primitives-core", + "environmental", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex", + "log", + "nimbus-primitives", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-root-testing" version = "1.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index 02ba07ebe..1a5e945e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,8 +71,10 @@ pallet-evm-precompile-balances-erc20 = { git = "https://github.com/moondance-lab pallet-evm-precompile-batch = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } pallet-evm-precompile-call-permit = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } pallet-evm-precompile-xcm-utils = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } +pallet-foreign-asset-creator = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } pallet-maintenance-mode = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } pallet-migrations = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } +pallet-relay-storage-roots = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } xcm-primitives = { git = "https://github.com/moondance-labs/moonkit", branch = "agustin-client-async-backing", default-features = false } # Substrate (wasm) @@ -83,6 +85,8 @@ frame-system = { git = "https://github.com/moondance-labs/polkadot-sdk.git", bra frame-system-benchmarking = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } frame-system-rpc-runtime-api = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } frame-try-runtime = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } +pallet-asset-rate = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } +pallet-assets = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } pallet-balances = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } pallet-identity = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } pallet-im-online = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } @@ -193,6 +197,7 @@ cumulus-primitives-core = { git = "https://github.com/moondance-labs/polkadot-sd cumulus-primitives-timestamp = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } cumulus-primitives-utility = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } parachain-info = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } +parachains-common = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } # Cumulus (client) cumulus-client-cli = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "agustin-client-async-backing", default-features = false } @@ -266,6 +271,7 @@ tempfile = "3.1.0" thiserror = { version = "1.0.40" } tokio = { version = "1.32.0", default-features = false } tracing = { version = "0.1.37", default-features = false } +tracing-subscriber = { version = "0.2.25", default-features = false } url = "2.2.2" [patch.crates-io] diff --git a/container-chains/templates/frontier/runtime/Cargo.toml b/container-chains/templates/frontier/runtime/Cargo.toml index e65cdcf7c..5dea1e5ba 100644 --- a/container-chains/templates/frontier/runtime/Cargo.toml +++ b/container-chains/templates/frontier/runtime/Cargo.toml @@ -68,6 +68,7 @@ sp-version = { workspace = true } # Polkadot pallet-xcm = { workspace = true } +pallet-xcm-benchmarks = { workspace = true, optional = true } polkadot-parachain-primitives = { workspace = true } polkadot-runtime-common = { workspace = true } staging-xcm = { workspace = true } @@ -101,6 +102,10 @@ pallet-evm-precompile-simple = { workspace = true } pallet-hotfix-sufficients = { workspace = true } precompile-utils = { workspace = true } +# Benchmarking +frame-benchmarking = { workspace = true, optional = true } +frame-system-benchmarking = { workspace = true, optional = true } + [build-dependencies] substrate-wasm-builder = { workspace = true } @@ -120,8 +125,10 @@ std = [ "fp-evm/std", "fp-rpc/std", "fp-self-contained/std", + "frame-benchmarking?/std", "frame-executive/std", "frame-support/std", + "frame-system-benchmarking?/std", "frame-system-rpc-runtime-api/std", "frame-system/std", "frame-try-runtime/std", @@ -156,6 +163,7 @@ std = [ "pallet-transaction-payment/std", "pallet-tx-pause/std", "pallet-utility/std", + "pallet-xcm-benchmarks?/std", "pallet-xcm/std", "parachain-info/std", "parity-scale-codec/std", @@ -194,7 +202,9 @@ runtime-benchmarks = [ "cumulus-pallet-session-benchmarking/runtime-benchmarks", "cumulus-pallet-xcmp-queue/runtime-benchmarks", "cumulus-primitives-utility/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "hex-literal", "nimbus-primitives/runtime-benchmarks", @@ -211,12 +221,14 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", "pallet-tx-pause/runtime-benchmarks", "pallet-utility/runtime-benchmarks", + "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "staging-xcm-builder/runtime-benchmarks", "staging-xcm-executor/runtime-benchmarks", + "tp-consensus/runtime-benchmarks", "xcm-primitives/runtime-benchmarks", ] diff --git a/container-chains/templates/frontier/runtime/src/lib.rs b/container-chains/templates/frontier/runtime/src/lib.rs index 96e988067..7e02b497e 100644 --- a/container-chains/templates/frontier/runtime/src/lib.rs +++ b/container-chains/templates/frontier/runtime/src/lib.rs @@ -306,7 +306,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frontier-template"), impl_name: create_runtime_str!("frontier-template"), authoring_version: 1, - spec_version: 400, + spec_version: 500, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -797,6 +797,8 @@ impl pallet_cc_authorities_noting::Config for Runtime { type RelayChainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider; type AuthorityId = NimbusId; type WeightInfo = pallet_cc_authorities_noting::weights::SubstrateWeight; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = pallet_cc_authorities_noting::benchmarks::NimbusIdBenchmarkHelper; } // To match ethereum expectations @@ -962,6 +964,24 @@ construct_runtime!( } ); +#[cfg(feature = "runtime-benchmarks")] +mod benches { + frame_benchmarking::define_benchmarks!( + [frame_system, frame_system_benchmarking::Pallet::] + [pallet_timestamp, Timestamp] + [pallet_sudo, Sudo] + [pallet_proxy, Proxy] + [pallet_utility, Utility] + [pallet_tx_pause, TxPause] + [pallet_balances, Balances] + [pallet_cc_authorities_noting, AuthoritiesNoting] + [pallet_author_inherent, AuthorInherent] + [cumulus_pallet_xcmp_queue, XcmpQueue] + [pallet_xcm, PolkadotXcm] + [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] + ); +} + impl_runtime_apis! { impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { @@ -1108,6 +1128,144 @@ impl_runtime_apis! { } } + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata( + extra: bool, + ) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig, + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{BenchmarkBatch, Benchmarking, BenchmarkError}; + use sp_core::storage::TrackedStorageKey; + use staging_xcm::latest::prelude::*; + impl frame_system_benchmarking::Config for Runtime { + fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); + Ok(()) + } + + fn verify_set_code() { + System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); + } + } + + impl pallet_xcm_benchmarks::Config for Runtime { + type XcmConfig = xcm_config::XcmConfig; + type AccountIdConverter = xcm_config::LocationToAccountId; + type DeliveryHelper = (); + fn valid_destination() -> Result { + Ok(MultiLocation::parent()) + } + fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + // We only care for native asset until we support others + // TODO: refactor this case once other assets are supported + vec![MultiAsset{ + id: Concrete(MultiLocation::here()), + fun: Fungible(u128::MAX), + }].into() + } + } + + impl pallet_xcm_benchmarks::generic::Config for Runtime { + type TransactAsset = Balances; + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + (0u64, Response::Version(Default::default())) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + Ok((MultiLocation::parent(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + } + + fn subscribe_origin() -> Result { + Ok(MultiLocation::parent()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = MultiLocation::parent(); + let assets: MultiAssets = (Concrete(MultiLocation::parent()), 1_000u128).into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + Err(BenchmarkError::Skip) + } + } + + let whitelist: Vec = vec![ + // Block Number + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac") + .to_vec() + .into(), + // Total Issuance + hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80") + .to_vec() + .into(), + // Execution Phase + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a") + .to_vec() + .into(), + // Event Count + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850") + .to_vec() + .into(), + // System Events + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7") + .to_vec() + .into(), + // The transactional storage limit. + hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a") + .to_vec() + .into(), + + // ParachainInfo ParachainId + hex_literal::hex!( "0d715f2646c8f85767b5d2764bb2782604a74d81251e398fd8a0a4d55023bb3f") + .to_vec() + .into(), + ]; + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmarks!(params, batches); + + Ok(batches) + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { diff --git a/container-chains/templates/simple/runtime/Cargo.toml b/container-chains/templates/simple/runtime/Cargo.toml index 33bafb16f..2edc99d07 100644 --- a/container-chains/templates/simple/runtime/Cargo.toml +++ b/container-chains/templates/simple/runtime/Cargo.toml @@ -62,6 +62,7 @@ sp-version = { workspace = true } # Polkadot pallet-xcm = { workspace = true } +pallet-xcm-benchmarks = { workspace = true, optional = true } polkadot-parachain-primitives = { workspace = true } polkadot-runtime-common = { workspace = true } staging-xcm = { workspace = true } @@ -121,6 +122,7 @@ std = [ "pallet-transaction-payment/std", "pallet-tx-pause/std", "pallet-utility/std", + "pallet-xcm-benchmarks?/std", "pallet-xcm/std", "parachain-info/std", "parity-scale-codec/std", @@ -158,7 +160,6 @@ runtime-benchmarks = [ "cumulus-pallet-session-benchmarking/runtime-benchmarks", "cumulus-pallet-xcmp-queue/runtime-benchmarks", "cumulus-primitives-utility/runtime-benchmarks", - "frame-benchmarking", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", @@ -174,12 +175,14 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", "pallet-tx-pause/runtime-benchmarks", "pallet-utility/runtime-benchmarks", + "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "staging-xcm-builder/runtime-benchmarks", "staging-xcm-executor/runtime-benchmarks", + "tp-consensus/runtime-benchmarks", "xcm-primitives/runtime-benchmarks", ] diff --git a/container-chains/templates/simple/runtime/src/lib.rs b/container-chains/templates/simple/runtime/src/lib.rs index 42141a768..84e87a518 100644 --- a/container-chains/templates/simple/runtime/src/lib.rs +++ b/container-chains/templates/simple/runtime/src/lib.rs @@ -194,7 +194,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("container-chain-template"), impl_name: create_runtime_str!("container-chain-template"), authoring_version: 1, - spec_version: 400, + spec_version: 500, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -675,6 +675,8 @@ impl pallet_cc_authorities_noting::Config for Runtime { type RelayChainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider; type AuthorityId = NimbusId; type WeightInfo = pallet_cc_authorities_noting::weights::SubstrateWeight; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = pallet_cc_authorities_noting::benchmarks::NimbusIdBenchmarkHelper; } impl pallet_author_inherent::Config for Runtime { @@ -733,6 +735,24 @@ construct_runtime!( } ); +#[cfg(feature = "runtime-benchmarks")] +mod benches { + frame_benchmarking::define_benchmarks!( + [frame_system, frame_system_benchmarking::Pallet::] + [pallet_timestamp, Timestamp] + [pallet_sudo, Sudo] + [pallet_proxy, Proxy] + [pallet_utility, Utility] + [pallet_tx_pause, TxPause] + [pallet_balances, Balances] + [pallet_cc_authorities_noting, AuthoritiesNoting] + [pallet_author_inherent, AuthorInherent] + [cumulus_pallet_xcmp_queue, XcmpQueue] + [pallet_xcm, PolkadotXcm] + [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] + ); +} + impl_runtime_apis! { impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { @@ -831,35 +851,94 @@ impl_runtime_apis! { Vec, Vec, ) { - use frame_benchmarking::{list_benchmark, BenchmarkList, Benchmarking}; + use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; - use frame_system_benchmarking::Pallet as SystemBench; - use pallet_cc_authorities_noting::Pallet as PalletAuthoritiesNotingBench; let mut list = Vec::::new(); - - list_benchmark!(list, extra, frame_system, SystemBench::); - list_benchmark!( - list, - extra, - pallet_cc_authorities_noting, - PalletAuthoritiesNotingBench:: - ); + list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) } fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig, ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{add_benchmark, BenchmarkBatch, Benchmarking}; + use frame_benchmarking::{BenchmarkBatch, Benchmarking, BenchmarkError}; use sp_core::storage::TrackedStorageKey; + use staging_xcm::latest::prelude::*; + impl frame_system_benchmarking::Config for Runtime { + fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); + Ok(()) + } + + fn verify_set_code() { + System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); + } + } + + impl pallet_xcm_benchmarks::Config for Runtime { + type XcmConfig = xcm_config::XcmConfig; + type AccountIdConverter = xcm_config::LocationToAccountId; + type DeliveryHelper = (); + fn valid_destination() -> Result { + Ok(MultiLocation::parent()) + } + fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + // We only care for native asset until we support others + // TODO: refactor this case once other assets are supported + vec![MultiAsset{ + id: Concrete(MultiLocation::here()), + fun: Fungible(u128::MAX), + }].into() + } + } - use frame_system_benchmarking::Pallet as SystemBench; - impl frame_system_benchmarking::Config for Runtime {} - use pallet_cc_authorities_noting::Pallet as PalletAuthoritiesNotingBench; + impl pallet_xcm_benchmarks::generic::Config for Runtime { + type TransactAsset = Balances; + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + (0u64, Response::Version(Default::default())) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + Ok((MultiLocation::parent(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + } + + fn subscribe_origin() -> Result { + Ok(MultiLocation::parent()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = MultiLocation::parent(); + let assets: MultiAssets = (Concrete(MultiLocation::parent()), 1_000u128).into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + Err(BenchmarkError::Skip) + } + + fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + Err(BenchmarkError::Skip) + } + } let whitelist: Vec = vec![ // Block Number @@ -886,21 +965,18 @@ impl_runtime_apis! { hex_literal::hex!("3a7472616e73616374696f6e5f6c6576656c3a") .to_vec() .into(), + + // ParachainInfo ParachainId + hex_literal::hex!( "0d715f2646c8f85767b5d2764bb2782604a74d81251e398fd8a0a4d55023bb3f") + .to_vec() + .into(), ]; let mut batches = Vec::::new(); let params = (&config, &whitelist); - add_benchmark!(params, batches, frame_system, SystemBench::); - add_benchmark!( - params, - batches, - pallet_cc_authorities_noting, - PalletAuthoritiesNotingBench:: - ); - if batches.is_empty() { - return Err("Benchmark not found for this pallet.".into()); - } + add_benchmarks!(params, batches); + Ok(batches) } } diff --git a/docker/tanssi.Dockerfile b/docker/tanssi.Dockerfile index 6bb6ee513..8c6ddb645 100644 --- a/docker/tanssi.Dockerfile +++ b/docker/tanssi.Dockerfile @@ -4,7 +4,7 @@ FROM docker.io/library/ubuntu:20.04 AS builder -RUN apt-get update && apt-get install -y ca-certificates && update-ca-certificates +RUN apt-get update && apt-get install -y ca-certificates lsof && update-ca-certificates FROM debian:bookworm-slim LABEL maintainer "gorka@moondancelabs.com" @@ -37,4 +37,4 @@ EXPOSE 30333 30334 30335 9933 9944 9615 9935 9946 9617 VOLUME ["/data"] -ENTRYPOINT ["/tanssi/tanssi-node"] \ No newline at end of file +ENTRYPOINT ["/tanssi/tanssi-node"] diff --git a/node/src/chain_spec/dancebox.rs b/node/src/chain_spec/dancebox.rs index 808dcf882..fe48d3fb2 100644 --- a/node/src/chain_spec/dancebox.rs +++ b/node/src/chain_spec/dancebox.rs @@ -27,7 +27,7 @@ use { pallet_configuration::HostConfiguration, sc_service::ChainType, sp_core::sr25519, - sp_runtime::traits::Get, + sp_runtime::{traits::Get, Perbill}, tp_container_chain_genesis_data::{ json::container_chain_genesis_data_from_path, ContainerChainGenesisData, }, @@ -92,6 +92,9 @@ pub fn development_config( max_orchestrator_collators: 1u32, collators_per_container: 2u32, full_rotation_period: prod_or_fast!(24u32, 5u32), + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(80), }, ..Default::default() }, @@ -157,6 +160,9 @@ pub fn local_dancebox_config( max_orchestrator_collators: 5u32, collators_per_container: 2u32, full_rotation_period: prod_or_fast!(24u32, 5u32), + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(80), }, ..Default::default() }, diff --git a/node/src/chain_spec/flashbox.rs b/node/src/chain_spec/flashbox.rs index ca7fa0924..5a5b95b0f 100644 --- a/node/src/chain_spec/flashbox.rs +++ b/node/src/chain_spec/flashbox.rs @@ -27,7 +27,7 @@ use { pallet_configuration::HostConfiguration, sc_service::ChainType, sp_core::sr25519, - sp_runtime::traits::Get, + sp_runtime::{traits::Get, Perbill}, tp_container_chain_genesis_data::{ json::container_chain_genesis_data_from_path, ContainerChainGenesisData, }, @@ -92,6 +92,9 @@ pub fn development_config( max_orchestrator_collators: 1u32, collators_per_container: 2u32, full_rotation_period: 0, + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(80), }, ..Default::default() }, @@ -157,6 +160,9 @@ pub fn local_flashbox_config( max_orchestrator_collators: 5u32, collators_per_container: 2u32, full_rotation_period: 0, + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(80), }, ..Default::default() }, diff --git a/pallets/collator-assignment/Cargo.toml b/pallets/collator-assignment/Cargo.toml index 4c4fc9de7..f3d257a07 100644 --- a/pallets/collator-assignment/Cargo.toml +++ b/pallets/collator-assignment/Cargo.toml @@ -26,6 +26,8 @@ tp-traits = { workspace = true } [dev-dependencies] sp-io = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } [features] default = [ "std" ] @@ -46,6 +48,7 @@ std = [ "sp-runtime/std", "sp-std/std", "tp-traits/std", + "tracing/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/pallets/collator-assignment/src/assignment.rs b/pallets/collator-assignment/src/assignment.rs new file mode 100644 index 000000000..fb17885b6 --- /dev/null +++ b/pallets/collator-assignment/src/assignment.rs @@ -0,0 +1,436 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi 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. + +// Tanssi 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 Tanssi. If not, see + +use { + dp_collator_assignment::AssignedCollators, + sp_std::{ + cmp, + collections::{btree_map::BTreeMap, btree_set::BTreeSet}, + marker::PhantomData, + mem, vec, + vec::Vec, + }, + tp_traits::{ParaId, RemoveInvulnerables as RemoveInvulnerablesT}, +}; + +/// Helper methods to implement collator assignment algorithm +pub struct Assignment(PhantomData); + +impl Assignment +where + T: crate::Config, +{ + /// Recompute collator assignment from scratch. If the list of collators and the list of + /// container chains are shuffled, this returns a random assignment. + pub fn assign_collators_rotate_all( + collators: Vec, + orchestrator_chain: ChainNumCollators, + chains: Vec, + ) -> Result, AssignmentError> { + // This is just the "always_keep_old" algorithm but with an empty "old" + let old_assigned = Default::default(); + + Self::assign_collators_always_keep_old(collators, orchestrator_chain, chains, old_assigned) + } + + /// Assign new collators to missing container_chains. + /// Old collators always have preference to remain on the same chain. + /// If there are no missing collators, nothing is changed. + /// + /// `chains` should be shuffled or at least rotated on every session to ensure + /// a fair distribution, because the order of that list affects container chain priority: + /// the first chain on that list will be the first one to get new collators. + pub fn assign_collators_always_keep_old( + collators: Vec, + orchestrator_chain: ChainNumCollators, + mut chains: Vec, + mut old_assigned: AssignedCollators, + ) -> Result, AssignmentError> { + if collators.is_empty() { + return Err(AssignmentError::ZeroCollators); + } + // The rest of this function mostly treats orchestrator chain as another container chain, so move it into + // `old_assigned.container_chains` + let old_orchestrator_assigned = mem::take(&mut old_assigned.orchestrator_chain); + old_assigned + .container_chains + .insert(orchestrator_chain.para_id, old_orchestrator_assigned); + let mut old_assigned = old_assigned.container_chains; + // Orchestrator chain must be the first one in the list because it always has priority + chains.insert(0, orchestrator_chain); + let all_para_ids: Vec = chains.iter().map(|cc| cc.para_id).collect(); + let collators_set = BTreeSet::from_iter(collators.iter().cloned()); + let chains_with_collators = + Self::select_chains_with_collators(collators.len() as u32, &chains); + let chains_with_collators_set: BTreeSet = chains_with_collators + .iter() + .map(|(para_id, _num_collators)| *para_id) + .collect(); + Self::retain_valid_old_assigned( + &mut old_assigned, + &chains_with_collators_set, + &collators_set, + ); + + // Ensure the first `min_orchestrator_collators` of orchestrator chain are invulnerables + Self::prioritize_invulnerables(&collators, orchestrator_chain, &mut old_assigned); + + let new_assigned_chains = + Self::assign_full(collators, chains_with_collators, old_assigned)?; + let mut new_assigned = AssignedCollators::default(); + new_assigned.container_chains = new_assigned_chains; + + // Add container chains with 0 collators so that they are shown in UI + for para_id in all_para_ids { + new_assigned.container_chains.entry(para_id).or_default(); + } + + // The rest of this function mostly treats orchestrator chain as another container chain, remove it from + // container chains before returning the final assignment. + let orchestrator_assigned = new_assigned + .container_chains + .remove(&orchestrator_chain.para_id) + .unwrap(); + // Sanity check to avoid bricking orchestrator chain + if orchestrator_assigned.is_empty() { + return Err(AssignmentError::EmptyOrchestrator); + } + new_assigned.orchestrator_chain = orchestrator_assigned; + + Ok(new_assigned) + } + + /// Select which container chains will be assigned collators and how many collators, but do not specify which + /// collator goes to which chain. + /// + /// Each chain has a min and max number of collators. If the number of collators is not enough to reach the min, + /// no collators are assigned to that chain. + /// + /// If the available number of collators is: + /// * lower than the min of the first chain: we assign all the collators to the first chain. This is the + /// orchestrator chain and we always want it to have collators. + /// * lower than the sum of all the min: we cannot assign collators to all the chains. So remove chains until + /// we can. The order is important, the first chains will be assigned collators and the last ones will not. + /// * lower than the sum of all the max: we can assign the min value to all the chains, and have some leftover. + /// We use the same order to decide where this extra collators will go, by filling the max of the first chain, + /// then the max of the second chain, and so on. + /// * greater than the sum of all the max: all the chains will be assigned their max number of collators. + /// + /// # Params + /// + /// The first item of `chains` should be the orchestrator chain, because it will be the first one to be assigned + /// collators. + /// + /// # Returns + /// + /// A list of `(para_id, num_collators)`. + pub fn select_chains_with_collators( + num_collators: u32, + chains: &[ChainNumCollators], + ) -> Vec<(ParaId, u32)> { + if chains.is_empty() { + // Avoid panic if chains is empty + return vec![]; + } + // Let's count how many container chains we can support with the current number of collators + let mut available_collators = num_collators; + // Handle orchestrator chain in a special way, we always want to assign collators to it, even if we don't + // reach the min. + let min_orchestrator_collators = chains[0].min_collators; + available_collators = available_collators.saturating_sub(min_orchestrator_collators); + + let mut container_chains_with_collators = vec![chains[0]]; + // Skipping orchestrator chain because it was handled above + for cc in chains.iter().skip(1) { + if available_collators >= cc.min_collators { + available_collators -= cc.min_collators; + container_chains_with_collators.push(*cc); + } else if available_collators == 0 { + // Do not break if there are still some available collators. Even if they were not enough to reach the + // `min` of this chain, it is possible that one of the chains with less priority has a lower `min`, so + // that chain should be assigned collators. + break; + } + } + + let mut required_collators_min = 0; + for cc in &container_chains_with_collators { + required_collators_min += cc.min_collators; + } + + if num_collators < min_orchestrator_collators { + // Edge case: num collators less than min orchestrator collators: fill as much as we can + vec![(chains[0].para_id, num_collators)] + } else { + // After assigning the min to all the chains we have this remainder. The remainder will be assigned until + // all the chains reach the max value. + let mut required_collators_remainder = num_collators - required_collators_min; + let mut container_chains_variable = vec![]; + for cc in &container_chains_with_collators { + // Each chain will have `min + extra` collators, where extra is capped so `min + extra <= max`. + let extra = cmp::min( + required_collators_remainder, + cc.max_collators.saturating_sub(cc.min_collators), + ); + let num = cc.min_collators + extra; + required_collators_remainder -= extra; + container_chains_variable.push((cc.para_id, num)); + } + + container_chains_variable + } + } + + /// Same as `prioritize_invulnerables` but return the invulnerables instead of inserting them into `old_assigned`. + /// + /// Mutates `old_assigned` by removing invulnerables from their old chain, even if they will later be assigned to + /// the same chain. + pub fn remove_invulnerables( + collators: &[T::AccountId], + orchestrator_chain: ChainNumCollators, + old_assigned: &mut BTreeMap>, + ) -> Vec { + // TODO: clean this up, maybe change remove_invulnerables trait into something more ergonomic + let min_orchestrator_collators = orchestrator_chain.min_collators as usize; + let invulnerables_already_assigned = T::RemoveInvulnerables::remove_invulnerables( + &mut old_assigned + .get(&orchestrator_chain.para_id) + .cloned() + .unwrap_or_default(), + min_orchestrator_collators, + ); + let mut new_invulnerables = invulnerables_already_assigned; + if new_invulnerables.len() >= min_orchestrator_collators { + // We already had invulnerables, we will just move them to the front of the list if they weren't already + return new_invulnerables; + } + + // Not enough invulnerables currently assigned, get rest from new_collators + let mut new_collators = collators.to_vec(); + for (_id, cs) in old_assigned.iter() { + new_collators.retain(|c| !cs.contains(c)); + } + let num_missing_invulnerables = min_orchestrator_collators - new_invulnerables.len(); + let invulnerables_not_assigned = T::RemoveInvulnerables::remove_invulnerables( + &mut new_collators, + num_missing_invulnerables, + ); + new_invulnerables.extend(invulnerables_not_assigned); + + if new_invulnerables.len() >= min_orchestrator_collators { + // Got invulnerables from new_collators, and maybe some were already assigned + return new_invulnerables; + } + + // Still not enough invulnerables, try to get an invulnerable that is currently assigned somewhere else + let num_missing_invulnerables = min_orchestrator_collators - new_invulnerables.len(); + let mut collators = collators.to_vec(); + let new_invulnerables_set = BTreeSet::from_iter(new_invulnerables.iter().cloned()); + collators.retain(|c| { + // Remove collators already selected + !new_invulnerables_set.contains(c) + }); + let invulnerables_assigned_elsewhere = + T::RemoveInvulnerables::remove_invulnerables(&mut collators, num_missing_invulnerables); + + if invulnerables_assigned_elsewhere.is_empty() { + // If at this point we still do not have enough invulnerables, it means that there are no + // enough invulnerables, so no problem, but return the invulnerables + return new_invulnerables; + } + + new_invulnerables.extend(invulnerables_assigned_elsewhere.iter().cloned()); + + // In this case we must delete the old assignment of the invulnerables + let reassigned_invulnerables_set = BTreeSet::from_iter(invulnerables_assigned_elsewhere); + // old_assigned.remove_collators_in_set + for (_id, cs) in old_assigned.iter_mut() { + cs.retain(|c| !reassigned_invulnerables_set.contains(c)); + } + + new_invulnerables + } + + /// Ensure orchestrator chain has `min_orchestrator` invulnerables. If that's not possible, it tries to add as + /// many invulnerables as possible. + /// + /// Get invulnerables from: + /// * old_assigned in orchestrator + /// * new collators + /// * old_assigned elsewhere + /// + /// In that order. + /// + /// Mutates `old_assigned` because invulnerables will be inserted there, and if invulnerables were already + /// assigned to some other chain, they will be removed from that other chain as well. + /// + /// # Params + /// + /// * `old_assigned` must be a subset of `collators` + /// * `old_assigned` must not have duplicate collators. + /// + /// # Returns + /// + /// The number of invulnerables assigned to the orchestrator chain, capped to `min_collators`. + pub fn prioritize_invulnerables( + collators: &[T::AccountId], + orchestrator_chain: ChainNumCollators, + old_assigned: &mut BTreeMap>, + ) -> usize { + let new_invulnerables = + Self::remove_invulnerables(collators, orchestrator_chain, old_assigned); + + if !new_invulnerables.is_empty() { + Self::insert_invulnerables( + old_assigned.entry(orchestrator_chain.para_id).or_default(), + &new_invulnerables, + ); + } + + new_invulnerables.len() + } + + /// Assign collators assuming that the number of collators is greater than or equal to the required. + /// The order of both container chains and collators is important to ensure randomness when `old_assigned` is + /// empty. + /// + /// # Params + /// + /// * `old_assigned` does not need to be a subset of `collators`: collators are checked and removed. + /// * `old_assigned` does not need to be a subset of `chains`, unused para ids are removed. Collators + /// assigned to a para_id not present in `chains` may be reassigned to another para_id. + /// * `chains` `num_collators` can be 0. In that case an empty vec is returned for that para id. + /// * `old_assigned` must not have duplicate collators. + /// + /// # Returns + /// + /// The collator assigment, a map from `ParaId` to `Vec`. + /// + /// Or an error if the number of collators is not enough to fill all the chains, or if the required number + /// of collators overflows a `u32`. + pub fn assign_full( + collators: Vec, + chains: Vec<(ParaId, u32)>, + mut old_assigned: BTreeMap>, + ) -> Result>, AssignmentError> { + let mut required_collators = 0usize; + for (_para_id, num_collators) in chains.iter() { + let num_collators = + usize::try_from(*num_collators).map_err(|_| AssignmentError::NotEnoughCollators)?; + required_collators = required_collators + .checked_add(num_collators) + .ok_or(AssignmentError::NotEnoughCollators)?; + } + + // This check is necessary to ensure priority: if the number of collators is less than required, it is + // possible that the chain with the least priority could be assigned collators (since they are in + // old_assigned), while some chains with higher priority might have no collators. + if collators.len() < required_collators { + return Err(AssignmentError::NotEnoughCollators); + } + // We checked that the sum of all `num_collators` fits in `usize`, so we can safely use `as usize`. + + // Remove invalid collators and para ids from `old_assigned` + let para_ids_set = + BTreeSet::from_iter(chains.iter().map(|(para_id, _num_collators)| *para_id)); + let collators_set = BTreeSet::from_iter(collators.iter().cloned()); + Self::retain_valid_old_assigned(&mut old_assigned, ¶_ids_set, &collators_set); + + // Truncate num collators to required + for (para_id, num_collators) in chains.iter() { + let entry = old_assigned.entry(*para_id).or_default(); + entry.truncate(*num_collators as usize); + } + + let assigned_collators: BTreeSet = old_assigned + .iter() + .flat_map(|(_para_id, para_collators)| para_collators.iter().cloned()) + .collect(); + let mut new_collators = collators.into_iter().filter(|x| { + // Keep collators not already assigned + !assigned_collators.contains(x) + }); + + // Fill missing collators + for (para_id, num_collators) in chains.iter() { + let cs = old_assigned.entry(*para_id).or_default(); + + while cs.len() < *num_collators as usize { + // This error should never happen because we checked that `collators.len() >= required_collators` + let nc = new_collators + .next() + .ok_or(AssignmentError::NotEnoughCollators)?; + cs.push(nc); + } + } + + Ok(old_assigned) + } + + /// Insert invulnerables ensuring that they are always the first in the list. + /// The order of both lists is preserved. + /// `assigned` may already contain the invulnerables, in that case they are only moved to the front. + /// + /// Invulnerables need to be the first of the list because we may truncate the list of collators if the number of + /// collators changes, and in that case we want invulnerables to stay assigned there. + pub fn insert_invulnerables(assigned: &mut Vec, invulnerables: &[T::AccountId]) { + assigned.retain(|item| !invulnerables.contains(item)); + + let mut new_assigned = invulnerables.to_vec(); + new_assigned.extend(mem::take(assigned)); + + *assigned = new_assigned; + } + + /// Removes invalid entries from `old_assigned`: + /// + /// * para ids not in `chains_with_collators` + /// * collators not in `collators` + pub fn retain_valid_old_assigned( + old_assigned: &mut BTreeMap>, + chains_with_collators: &BTreeSet, + collators: &BTreeSet, + ) { + // old_assigned.remove_container_chains_not_in_set + old_assigned.retain(|id, _cs| chains_with_collators.contains(id)); + // old_assigned.remove_collators_not_in_set + for (_id, cs) in old_assigned.iter_mut() { + cs.retain(|c| collators.contains(c)); + } + } +} + +/// Errors than can happen during collator assignment +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum AssignmentError { + /// An empty list of collators was passed to `assign_collators_always_keep_old` + ZeroCollators, + /// The required number of collators for `assign_full` is greater than the provided number of collators. + /// Also includes possible overflows in number of collators. + NotEnoughCollators, + /// No collators were assigned to orchestrator chain + EmptyOrchestrator, +} + +/// A `ParaId` and a range of collators that need to be assigned to it. +/// This can be a container chain, a parathread, or the orchestrator chain. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct ChainNumCollators { + pub para_id: ParaId, + pub min_collators: u32, + // This will only be filled if all the other min have been reached + pub max_collators: u32, +} diff --git a/pallets/collator-assignment/src/lib.rs b/pallets/collator-assignment/src/lib.rs index eb10e53de..5df502dec 100644 --- a/pallets/collator-assignment/src/lib.rs +++ b/pallets/collator-assignment/src/lib.rs @@ -43,7 +43,10 @@ pub use pallet::*; use { - crate::weights::WeightInfo, + crate::{ + assignment::{Assignment, ChainNumCollators}, + weights::WeightInfo, + }, dp_collator_assignment::AssignedCollators, frame_support::pallet_prelude::*, frame_system::pallet_prelude::BlockNumberFor, @@ -60,6 +63,7 @@ use { }, }; +mod assignment; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; pub mod weights; @@ -164,6 +168,7 @@ pub mod pallet { // We get the containerChains that we will have at the target session let mut container_chain_ids = T::ContainerChains::session_container_chains(target_session_index); + let mut parathreads = T::ContainerChains::session_parathreads(target_session_index); let num_total_registered_paras = container_chain_ids.len() as u32; // Remove the containerChains that do not have enough credits for block production T::RemoveParaIdsWithNoCredits::remove_para_ids_with_no_credits( @@ -176,11 +181,47 @@ pub mod pallet { if random_seed != [0; 32] { let mut rng: ChaCha20Rng = SeedableRng::from_seed(random_seed); collators.shuffle(&mut rng); + // TODO: in the future, instead of shuffling the list of para ids, we need to use the priority fee to + // determine priority container_chain_ids.shuffle(&mut rng); + parathreads.shuffle(&mut rng); } // We read current assigned collators let old_assigned = Self::read_assigned_collators(); + let orchestrator_chain = ChainNumCollators { + para_id: T::SelfParaId::get(), + min_collators: T::HostConfiguration::min_collators_for_orchestrator( + target_session_index, + ), + max_collators: T::HostConfiguration::max_collators_for_orchestrator( + target_session_index, + ), + }; + // Initialize list of chains as `[container1, container2, parathread1, parathread2]`. + // The order means priority: the first chain in the list will be the first one to get assigned collators. + // Chains will not be assigned less than `min_collators`, except the orchestrator chain. + // First all chains will be assigned `min_collators`, and then the first one will be assigned up to `max`, + // then the second one, and so on. + let mut chains = vec![]; + let collators_per_container = + T::HostConfiguration::collators_per_container(target_session_index); + for para_id in &container_chain_ids { + chains.push(ChainNumCollators { + para_id: *para_id, + min_collators: collators_per_container, + max_collators: collators_per_container, + }); + } + let collators_per_parathread = + T::HostConfiguration::collators_per_parathread(target_session_index); + for para_id in ¶threads { + chains.push(ChainNumCollators { + para_id: *para_id, + min_collators: collators_per_parathread, + max_collators: collators_per_parathread, + }); + } // We assign new collators // we use the config scheduled at the target_session_index let new_assigned = @@ -197,15 +238,10 @@ pub mod pallet { target_session: target_session_index, }); - Self::assign_collators_rotate_all( + Assignment::::assign_collators_rotate_all( collators, - &container_chain_ids, - T::HostConfiguration::min_collators_for_orchestrator(target_session_index) - as usize, - T::HostConfiguration::max_collators_for_orchestrator(target_session_index) - as usize, - T::HostConfiguration::collators_per_container(target_session_index) - as usize, + orchestrator_chain, + chains, ) } else { log::info!( @@ -220,19 +256,26 @@ pub mod pallet { target_session: target_session_index, }); - Self::assign_collators_always_keep_old( + Assignment::::assign_collators_always_keep_old( collators, - &container_chain_ids, - T::HostConfiguration::min_collators_for_orchestrator(target_session_index) - as usize, - T::HostConfiguration::max_collators_for_orchestrator(target_session_index) - as usize, - T::HostConfiguration::collators_per_container(target_session_index) - as usize, + orchestrator_chain, + chains, old_assigned.clone(), ) }; + let new_assigned = match new_assigned { + Ok(x) => x, + Err(e) => { + log::error!( + "Error in collator assignment, will keep previous assignment. {:?}", + e + ); + + old_assigned.clone() + } + }; + let mut pending = PendingCollatorContainerChain::::get(); let old_assigned_changed = old_assigned != new_assigned; let mut pending_changed = false; @@ -267,128 +310,6 @@ pub mod pallet { } } - /// Recompute collator assignment from scratch. If the list of collators and the list of - /// container chains are shuffled, this returns a random assignment. - fn assign_collators_rotate_all( - collators: Vec, - container_chain_ids: &[ParaId], - min_num_orchestrator_chain: usize, - max_num_orchestrator_chain: usize, - num_each_container_chain: usize, - ) -> AssignedCollators { - // This is just the "always_keep_old" algorithm but with an empty "old" - let old_assigned = Default::default(); - - Self::assign_collators_always_keep_old( - collators, - container_chain_ids, - min_num_orchestrator_chain, - max_num_orchestrator_chain, - num_each_container_chain, - old_assigned, - ) - } - - /// Assign new collators to missing container_chains. - /// Old collators always have preference to remain on the same chain. - /// If there are no missing collators, nothing is changed. - /// - /// `container_chain_ids` should be shuffled or at least rotated on every session to ensure - /// a fair distribution, because the order of that list affects container chain priority: - /// the first container chain on that list will be the first one to get new collators. - fn assign_collators_always_keep_old( - collators: Vec, - container_chain_ids: &[ParaId], - min_num_orchestrator_chain: usize, - max_num_orchestrator_chain: usize, - num_each_container_chain: usize, - old_assigned: AssignedCollators, - ) -> AssignedCollators { - // TODO: the performance of this function is sad, could be improved by having sets of - // old_collators and new_collators instead of doing array.contains() every time. - let mut new_assigned = old_assigned; - new_assigned.remove_collators_not_in_list(&collators); - new_assigned.remove_container_chains_not_in_list(container_chain_ids); - let extra_orchestrator_collators = - new_assigned.remove_orchestrator_chain_excess_collators(min_num_orchestrator_chain); - // Only need to do this if the config params change - new_assigned.remove_container_chain_excess_collators(num_each_container_chain); - - // Collators that are not present in old_assigned - // This is used to keep track of which collators are old and which ones are new, to keep - // the old collators on the same chain if possible. - let mut new_collators = vec![]; - for c in collators { - if !new_assigned.find_collator(&c) && !extra_orchestrator_collators.contains(&c) { - new_collators.push(c); - } - } - - // Fill orchestrator chain collators up to min_num_orchestrator_chain - // Give priority to invulnerables - let num_missing_orchestrator_collators = - min_num_orchestrator_chain.saturating_sub(new_assigned.orchestrator_chain.len()); - let invulnerables_for_orchestrator = T::RemoveInvulnerables::remove_invulnerables( - &mut new_collators, - num_missing_orchestrator_collators, - ); - new_assigned.fill_orchestrator_chain_collators( - min_num_orchestrator_chain, - &mut invulnerables_for_orchestrator.into_iter(), - ); - // If there are no enough invulnerables, or if the invulnerables are currently assigned to other chains, - // fill orchestrator chain with regular collators - let mut new_collators = new_collators.into_iter(); - new_assigned - .fill_orchestrator_chain_collators(min_num_orchestrator_chain, &mut new_collators); - - // Fill container chain collators using new collators and also the extra - // collators that were previously assigned to the orchestrator chain, - // but give preference to new collators - let mut extra_orchestrator_collators = extra_orchestrator_collators.into_iter(); - let mut new_plus_extra_collators = new_collators - .by_ref() - .chain(&mut extra_orchestrator_collators); - - new_assigned.add_and_fill_new_container_chains_in_order( - num_each_container_chain, - container_chain_ids, - &mut new_plus_extra_collators, - ); - - // Fill orchestrator chain collators back up to max_num_orchestrator_chain, - // but give preference to collators that were already there - let mut extra_collators_plus_new = extra_orchestrator_collators - .by_ref() - .chain(&mut new_collators); - new_assigned.fill_orchestrator_chain_collators( - max_num_orchestrator_chain, - &mut extra_collators_plus_new, - ); - - // Reorganize container chain collators to fill the maximum number of container - // chains. For example, if num_each_container_chain == 2 and the number of collators - // in each container chain is - // [1, 1, 1, 1, 1] - // Then we can convert that into - // [2, 2, 0, 0, 0] - // and assign 1 extra collator to the orchestrator chain, if needed. - let incomplete_container_chains_collators = new_assigned - .reorganize_incomplete_container_chains_collators( - container_chain_ids, - num_each_container_chain, - ); - - // Assign collators from container chains that do not reach - // "num_each_container_chain" to orchestrator chain - new_assigned.fill_orchestrator_chain_collators( - max_num_orchestrator_chain, - &mut incomplete_container_chains_collators.into_iter(), - ); - - new_assigned - } - // Returns the assigned collators as read from storage. // If there is any item in PendingCollatorContainerChain, returns that element. // Otherwise, reads and returns the current CollatorContainerChain diff --git a/pallets/collator-assignment/src/mock.rs b/pallets/collator-assignment/src/mock.rs index f5c9e69ef..dbe4e095a 100644 --- a/pallets/collator-assignment/src/mock.rs +++ b/pallets/collator-assignment/src/mock.rs @@ -16,8 +16,8 @@ use { crate::{ - self as pallet_collator_assignment, GetRandomnessForNextBlock, - RotateCollatorsEveryNSessions, + self as pallet_collator_assignment, pallet::CollatorContainerChain, + GetRandomnessForNextBlock, RotateCollatorsEveryNSessions, }, frame_support::{ parameter_types, @@ -25,12 +25,14 @@ use { }, frame_system as system, parity_scale_codec::{Decode, Encode}, - sp_core::H256, + sp_core::{Get, H256}, sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }, + sp_std::collections::btree_map::BTreeMap, tp_traits::{ParaId, RemoveInvulnerables, RemoveParaIdsWithNoCredits}, + tracing_subscriber::{layer::SubscriberExt, FmtSubscriber}, }; type Block = frame_system::mocking::MockBlock; @@ -111,9 +113,13 @@ pub struct Mocks { pub min_orchestrator_chain_collators: u32, pub max_orchestrator_chain_collators: u32, pub collators_per_container: u32, + pub collators_per_parathread: u32, pub collators: Vec, pub container_chains: Vec, + pub parathreads: Vec, pub random_seed: [u8; 32], + // None means 5 + pub full_rotation_period: Option, } impl mock_data::Config for Test {} @@ -123,7 +129,7 @@ impl mock_data::Config for Test {} pub struct HostConfigurationGetter; parameter_types! { - pub const ParachainId: ParaId = ParaId::new(200); + pub const ParachainId: ParaId = ParaId::new(1000); } impl pallet_collator_assignment::GetHostConfiguration for HostConfigurationGetter { @@ -138,6 +144,10 @@ impl pallet_collator_assignment::GetHostConfiguration for HostConfiguration fn collators_per_container(_session_index: u32) -> u32 { MockData::mock().collators_per_container } + + fn collators_per_parathread(_session_index: u32) -> u32 { + MockData::mock().collators_per_parathread + } } pub struct CollatorsGetter; @@ -160,6 +170,15 @@ impl tp_traits::GetSessionContainerChains for ContainerChainsGetter { .collect() } + fn session_parathreads(_session_index: u32) -> Vec { + MockData::mock() + .parathreads + .iter() + .cloned() + .map(ParaId::from) + .collect() + } + #[cfg(feature = "runtime-benchmarks")] fn set_session_container_chains(_session_index: u32, para_ids: &[ParaId]) { MockData::mutate(|mocks| { @@ -184,13 +203,22 @@ parameter_types! { pub const CollatorRotationSessionPeriod: u32 = 5; } +pub struct MockCollatorRotationSessionPeriod; + +impl Get for MockCollatorRotationSessionPeriod { + fn get() -> u32 { + MockData::mock().full_rotation_period.unwrap_or(5) + } +} + impl pallet_collator_assignment::Config for Test { type RuntimeEvent = RuntimeEvent; type SessionIndex = u32; type HostConfiguration = HostConfigurationGetter; type ContainerChains = ContainerChainsGetter; type SelfParaId = ParachainId; - type ShouldRotateAllCollators = RotateCollatorsEveryNSessions; + type ShouldRotateAllCollators = + RotateCollatorsEveryNSessions; type GetRandomnessForNextBlock = MockGetRandomnessForNextBlock; type RemoveInvulnerables = RemoveAccountIdsAbove100; type RemoveParaIdsWithNoCredits = RemoveParaIdsAbove5000; @@ -199,10 +227,20 @@ impl pallet_collator_assignment::Config for Test { // Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { - system::GenesisConfig::::default() + let mut ext: sp_io::TestExternalities = system::GenesisConfig::::default() .build_storage() .unwrap() - .into() + .into(); + + ext.execute_with(|| { + MockData::mutate(|mocks| { + // Initialize collators with 1 collator to avoid error `ZeroCollators` in session 0 + mocks.collators = vec![100]; + mocks.min_orchestrator_chain_collators = 1; + }) + }); + + ext } pub trait GetCollators { @@ -264,3 +302,37 @@ impl RemoveParaIdsWithNoCredits for RemoveParaIdsAbove5000 { } } } + +/// Returns a map of collator to assigned para id +pub fn assigned_collators() -> BTreeMap { + let assigned_collators = CollatorContainerChain::::get(); + + let mut h = BTreeMap::new(); + + for (para_id, collators) in assigned_collators.container_chains.iter() { + for collator in collators.iter() { + h.insert(*collator, u32::from(*para_id)); + } + } + + for collator in assigned_collators.orchestrator_chain { + h.insert(collator, 1000); + } + + h +} + +/// Returns the default assignment for session 0 used in tests. Collator 100 is assigned to the orchestrator chain. +pub fn initial_collators() -> BTreeMap { + BTreeMap::from_iter(vec![(100, 1000)]) +} + +/// Executes code without printing any logs. Can be used in tests where we expect logs to be printed, to avoid clogging +/// up stderr. Only affects the current thread, if `f` spawns any threads or if logs come from another thread, they will +/// not be silenced. +pub fn silence_logs R, R>(f: F) -> R { + let no_logging_layer = tracing_subscriber::filter::LevelFilter::OFF; + let no_logging_subscriber = FmtSubscriber::builder().finish().with(no_logging_layer); + + tracing::subscriber::with_default(no_logging_subscriber, f) +} diff --git a/pallets/collator-assignment/src/tests.rs b/pallets/collator-assignment/src/tests.rs index 5706ad1e3..38bc00bcf 100644 --- a/pallets/collator-assignment/src/tests.rs +++ b/pallets/collator-assignment/src/tests.rs @@ -14,28 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see +use dp_collator_assignment::AssignedCollators; use { crate::{mock::*, CollatorContainerChain, Event, PendingCollatorContainerChain}, std::collections::BTreeMap, }; -fn assigned_collators() -> BTreeMap { - let assigned_collators = CollatorContainerChain::::get(); - - let mut h = BTreeMap::new(); - - for (para_id, collators) in assigned_collators.container_chains.iter() { - for collator in collators.iter() { - h.insert(*collator, u32::from(*para_id)); - } - } - - for collator in assigned_collators.orchestrator_chain { - h.insert(collator, 999); - } - - h -} +mod assign_full; +mod prioritize_invulnerables; +mod select_chains; #[test] fn assign_initial_collators() { @@ -44,6 +31,7 @@ fn assign_initial_collators() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; @@ -51,20 +39,20 @@ fn assign_initial_collators() { m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(6); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -81,6 +69,7 @@ fn assign_collators_after_one_leaves_container() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; @@ -88,20 +77,20 @@ fn assign_collators_after_one_leaves_container() { m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(6); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -120,11 +109,11 @@ fn assign_collators_after_one_leaves_container() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), //(6, 1001), (7, 1001), (8, 1002), @@ -143,6 +132,7 @@ fn assign_collators_after_one_leaves_orchestrator_chain() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; @@ -150,17 +140,17 @@ fn assign_collators_after_one_leaves_orchestrator_chain() { m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -177,17 +167,17 @@ fn assign_collators_after_one_leaves_orchestrator_chain() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - //(4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + //(4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), (9, 1002), // 10 is assigned in place of 4 - (10, 999), + (10, 1000), ]), ); }); @@ -200,23 +190,24 @@ fn assign_collators_if_config_orchestrator_chain_collators_increases() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -235,18 +226,18 @@ fn assign_collators_if_config_orchestrator_chain_collators_increases() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), (9, 1002), - (10, 999), - (11, 999), - (12, 999), + (10, 1000), + (11, 1000), + (12, 1000), ]), ); }); @@ -259,23 +250,24 @@ fn assign_collators_if_config_orchestrator_chain_collators_decreases() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -303,6 +295,7 @@ fn assign_collators_if_config_collators_per_container_increases() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; @@ -310,17 +303,17 @@ fn assign_collators_if_config_collators_per_container_increases() { m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -338,11 +331,11 @@ fn assign_collators_if_config_collators_per_container_increases() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -363,23 +356,24 @@ fn assign_collators_if_container_chain_is_removed() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -397,11 +391,11 @@ fn assign_collators_if_container_chain_is_removed() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), ]), @@ -416,23 +410,24 @@ fn assign_collators_if_container_chain_is_added() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -450,11 +445,11 @@ fn assign_collators_if_container_chain_is_added() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -473,36 +468,44 @@ fn assign_collators_after_decrease_num_collators() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 5; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; m.container_chains = vec![1001, 1002] }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); - assert_eq!( - assigned_collators(), - BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), - (6, 1001), - (7, 1001), - (8, 1002), - (9, 1002), - ]), - ); + let initial_assignment = BTreeMap::from_iter(vec![ + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), + (6, 1001), + (7, 1001), + (8, 1002), + (9, 1002), + ]); + assert_eq!(assigned_collators(), initial_assignment,); MockData::mutate(|m| { m.collators = vec![]; }); - run_to_block(21); - assert_eq!(assigned_collators(), BTreeMap::from_iter(vec![])); + // Disable logs in this test because it will print: + // Error in collator assignment, will keep previous assignment. ZeroCollators + // But only if this test runs after: + // test mock::__construct_runtime_integrity_test::runtime_integrity_tests ... ok + // Because that test enables logging + silence_logs(|| { + run_to_block(21); + }); + + // There are no collators but that would brick the chain, so we keep the old assignment + assert_eq!(assigned_collators(), initial_assignment); }); } @@ -513,18 +516,19 @@ fn assign_collators_stay_constant_if_new_collators_can_take_new_chains() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; m.container_chains = vec![]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), - BTreeMap::from_iter(vec![(1, 999), (2, 999), (3, 999), (4, 999), (5, 999),]), + BTreeMap::from_iter(vec![(1, 1000), (2, 1000), (3, 1000), (4, 1000), (5, 1000),]), ); MockData::mutate(|m| { @@ -535,11 +539,11 @@ fn assign_collators_stay_constant_if_new_collators_can_take_new_chains() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 999), - (4, 999), - (5, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), (6, 1001), (7, 1001), (8, 1002), @@ -556,18 +560,19 @@ fn assign_collators_move_extra_container_chain_to_orchestrator_chain_if_not_enou MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4]; m.container_chains = vec![]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), - BTreeMap::from_iter(vec![(1, 999), (2, 999), (3, 999), (4, 999),]), + BTreeMap::from_iter(vec![(1, 1000), (2, 1000), (3, 1000), (4, 1000),]), ); MockData::mutate(|m| { @@ -578,7 +583,7 @@ fn assign_collators_move_extra_container_chain_to_orchestrator_chain_if_not_enou assert_eq!( assigned_collators(), - BTreeMap::from_iter(vec![(1, 999), (2, 999), (5, 1001), (3, 1001), (4, 999),]), + BTreeMap::from_iter(vec![(1, 1000), (2, 1000), (3, 1000), (4, 1001), (5, 1001),]), ); }); } @@ -590,20 +595,21 @@ fn assign_collators_reorganize_container_chains_if_not_enough_collators() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; m.container_chains = vec![1001, 1002, 1003, 1004, 1005]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), + (1, 1000), + (2, 1000), (3, 1001), (4, 1001), (5, 1002), @@ -627,13 +633,13 @@ fn assign_collators_reorganize_container_chains_if_not_enough_collators() { assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 1005), - (5, 1004), - (7, 999), - (9, 1004), - (11, 1005) + (1, 1000), + (2, 1000), + (3, 1001), + (5, 1002), + (7, 1000), + (9, 1001), + (11, 1002) ]), ); }); @@ -646,30 +652,31 @@ fn assign_collators_set_zero_per_container() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; m.container_chains = vec![1001, 1002, 1003, 1004]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); assert_eq!( assigned_collators(), BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 1001), - (4, 1001), - (5, 1002), - (6, 1002), - (7, 1003), - (8, 1003), - (9, 1004), - (10, 1004), - (11, 999), - (12, 999) + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1001), + (6, 1001), + (7, 1002), + (8, 1002), + (9, 1003), + (10, 1003), + (11, 1004), + (12, 1004), ]), ); @@ -682,7 +689,7 @@ fn assign_collators_set_zero_per_container() { // There are 5 collators in total: 0x4 container chains, plus 5 in the orchestrator chain assert_eq!( assigned_collators(), - BTreeMap::from_iter(vec![(1, 999), (2, 999), (3, 999), (11, 999), (12, 999),]), + BTreeMap::from_iter(vec![(1, 1000), (2, 1000), (3, 1000), (4, 1000), (5, 1000),]), ); }); } @@ -694,28 +701,29 @@ fn assign_collators_rotation() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; m.container_chains = vec![1001, 1002, 1003, 1004]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); let initial_assignment = BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 1001), - (4, 1001), - (5, 1002), - (6, 1002), - (7, 1003), - (8, 1003), - (9, 1004), - (10, 1004), - (11, 999), - (12, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1001), + (6, 1001), + (7, 1002), + (8, 1002), + (9, 1003), + (10, 1003), + (11, 1004), + (12, 1004), ]); assert_eq!(assigned_collators(), initial_assignment,); @@ -743,18 +751,18 @@ fn assign_collators_rotation() { // Random assignment depends on the seed, shouldn't change unless the algorithm changes let shuffled_assignment = BTreeMap::from_iter(vec![ - (1, 1004), - (2, 999), - (3, 999), - (4, 1003), - (5, 1001), - (6, 1001), - (7, 999), - (8, 1002), - (9, 999), - (10, 1003), - (11, 1004), - (12, 1002), + (1, 1000), + (2, 1002), + (3, 1000), + (4, 1004), + (5, 1003), + (6, 1003), + (7, 1000), + (8, 1001), + (9, 1002), + (10, 1004), + (11, 1000), + (12, 1001), ]); assert_eq!(assigned_collators(), shuffled_assignment,); @@ -768,6 +776,7 @@ fn assign_collators_rotation_container_chains_are_shuffled() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; @@ -775,11 +784,11 @@ fn assign_collators_rotation_container_chains_are_shuffled() { m.collators = vec![1, 2, 3, 4]; m.container_chains = vec![1001, 1002]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); let initial_assignment = - BTreeMap::from_iter(vec![(1, 999), (2, 999), (3, 1001), (4, 1001)]); + BTreeMap::from_iter(vec![(1, 1000), (2, 1000), (3, 1001), (4, 1001)]); assert_eq!(assigned_collators(), initial_assignment,); @@ -793,7 +802,46 @@ fn assign_collators_rotation_container_chains_are_shuffled() { // Random assignment depends on the seed, shouldn't change unless the algorithm changes // Test that container chains are shuffled because 1001 does not have priority let shuffled_assignment = - BTreeMap::from_iter(vec![(1, 999), (2, 1002), (3, 999), (4, 1002)]); + BTreeMap::from_iter(vec![(1, 1000), (2, 1002), (3, 1000), (4, 1002)]); + + assert_eq!(assigned_collators(), shuffled_assignment,); + }); +} + +#[test] +fn assign_collators_rotation_parathreads_are_shuffled() { + new_test_ext().execute_with(|| { + run_to_block(1); + + MockData::mutate(|m| { + m.collators_per_container = 2; + m.collators_per_parathread = 2; + m.min_orchestrator_chain_collators = 2; + m.max_orchestrator_chain_collators = 5; + + // 4 collators so we can only assign to one parathread + m.collators = vec![1, 2, 3, 4]; + m.parathreads = vec![5001, 5002]; + }); + assert_eq!(assigned_collators(), initial_collators(),); + run_to_block(11); + + let initial_assignment = + BTreeMap::from_iter(vec![(1, 1000), (2, 1000), (3, 5001), (4, 5001)]); + + assert_eq!(assigned_collators(), initial_assignment,); + + MockData::mutate(|m| { + // Seed chosen manually to see the case where parathread 5002 is given priority + m.random_seed = [2; 32]; + }); + + run_to_block(26); + + // Random assignment depends on the seed, shouldn't change unless the algorithm changes + // Test that container chains are shuffled because 1001 does not have priority + let shuffled_assignment = + BTreeMap::from_iter(vec![(1, 1000), (2, 5002), (3, 1000), (4, 5002)]); assert_eq!(assigned_collators(), shuffled_assignment,); }); @@ -806,6 +854,7 @@ fn assign_collators_rotation_collators_are_shuffled() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; @@ -813,19 +862,19 @@ fn assign_collators_rotation_collators_are_shuffled() { m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; m.container_chains = vec![1001, 1002]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); let initial_assignment = BTreeMap::from_iter(vec![ - (1, 999), - (2, 999), - (3, 1001), - (4, 1001), - (5, 1002), - (6, 1002), - (7, 999), - (8, 999), - (9, 999), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1000), + (6, 1001), + (7, 1001), + (8, 1002), + (9, 1002), ]); assert_eq!(assigned_collators(), initial_assignment,); @@ -840,15 +889,15 @@ fn assign_collators_rotation_collators_are_shuffled() { // Test that collators are shuffled because collator 10 should be the last one to be assigned, // and here it is present let shuffled_assignment = BTreeMap::from_iter(vec![ - (1, 999), - (3, 1001), - (4, 1001), - (5, 1002), - (6, 999), - (7, 999), - (8, 999), - (9, 1002), - (10, 999), + (1, 1000), + (3, 1000), + (4, 1000), + (5, 1001), + (6, 1002), + (7, 1000), + (8, 1001), + (9, 1000), + (10, 1002), ]); assert_eq!(assigned_collators(), shuffled_assignment,); @@ -862,6 +911,7 @@ fn assign_collators_invulnerables_priority_orchestrator() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; @@ -870,22 +920,101 @@ fn assign_collators_invulnerables_priority_orchestrator() { m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]; m.container_chains = vec![1001, 1002]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); + run_to_block(11); + + let initial_assignment = BTreeMap::from_iter(vec![ + (100, 1000), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1000), + (5, 1001), + (6, 1001), + (7, 1002), + (8, 1002), + ]); + + assert_eq!(assigned_collators(), initial_assignment,); + }); +} + +#[test] +fn assign_collators_invulnerables_priority_orchestrator_reassigned() { + new_test_ext().execute_with(|| { + run_to_block(1); + + MockData::mutate(|m| { + m.collators_per_container = 2; + m.collators_per_parathread = 2; + m.min_orchestrator_chain_collators = 2; + m.max_orchestrator_chain_collators = 5; + // Disable rotation because this test is long + m.full_rotation_period = Some(0); + + // 10 collators but we only need 9, so 1 collator will not be assigned + // ids >= 100 are invulnerables so 2 of them will always be assigned to the orchestrator + m.collators = vec![1, 2, 3, 4, 5, 100, 101, 102, 103, 104]; + m.container_chains = vec![1001, 1002]; + }); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); let initial_assignment = BTreeMap::from_iter(vec![ - (100, 999), - (1, 999), - (2, 1001), - (3, 1001), - (4, 1002), - (5, 1002), - (6, 999), - (7, 999), - (8, 999), + (100, 1000), + (101, 1000), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1001), + (5, 1001), + (102, 1002), + (103, 1002), ]); assert_eq!(assigned_collators(), initial_assignment,); + + MockData::mutate(|m| { + // Remove invulnerable from orchestrator, the unassigned invulnerable will take its place + m.collators = vec![1, 2, 3, 4, 5, 101, 102, 103, 104]; + }); + + run_to_block(21); + + let assignment = BTreeMap::from_iter(vec![ + (104, 1000), + (101, 1000), + (1, 1000), + (2, 1000), + (3, 1000), + (4, 1001), + (5, 1001), + (102, 1002), + (103, 1002), + ]); + + assert_eq!(assigned_collators(), assignment,); + + MockData::mutate(|m| { + // Remove another invulnerable from orchestrator, there are no unassigned invulnerables so the ones in a + // container chain will move from the container chain to the orchestrator + m.collators = vec![1, 2, 3, 4, 5, 102, 103, 104]; + }); + + run_to_block(31); + + let assignment = BTreeMap::from_iter(vec![ + (104, 1000), + (102, 1000), + (1, 1000), + (2, 1000), + (3, 1002), + (4, 1001), + (5, 1001), + (103, 1002), + ]); + + assert_eq!(assigned_collators(), assignment,); }); } @@ -896,6 +1025,7 @@ fn assign_collators_all_invulnerables() { MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; @@ -903,19 +1033,19 @@ fn assign_collators_all_invulnerables() { m.collators = vec![101, 102, 103, 104, 105, 106, 107, 108, 109, 110]; m.container_chains = vec![1001, 1002]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); run_to_block(11); let initial_assignment = BTreeMap::from_iter(vec![ - (101, 999), - (102, 999), - (103, 1001), - (104, 1001), - (105, 1002), - (106, 1002), - (107, 999), - (108, 999), - (109, 999), + (101, 1000), + (102, 1000), + (103, 1000), + (104, 1000), + (105, 1000), + (106, 1001), + (107, 1001), + (108, 1002), + (109, 1002), ]); assert_eq!(assigned_collators(), initial_assignment,); @@ -924,19 +1054,20 @@ fn assign_collators_all_invulnerables() { #[test] fn rotation_events() { - // Ensure that the NewPendingAssignment is correct + // Ensure that the NewPendingAssignment event is correct new_test_ext().execute_with(|| { run_to_block(1); MockData::mutate(|m| { m.collators_per_container = 2; + m.collators_per_parathread = 2; m.min_orchestrator_chain_collators = 2; m.max_orchestrator_chain_collators = 5; m.collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; m.container_chains = vec![1001, 1002, 1003, 1004]; }); - assert_eq!(assigned_collators(), BTreeMap::new(),); + assert_eq!(assigned_collators(), initial_collators(),); // Block 1 should emit event, random seed was not set System::assert_last_event( @@ -1014,3 +1145,89 @@ fn rotation_events() { } }); } + +#[test] +fn assign_collators_remove_from_orchestator_when_all_assigned() { + new_test_ext().execute_with(|| { + run_to_block(1); + + MockData::mutate(|m| { + m.collators_per_container = 2; + m.collators_per_parathread = 2; + m.min_orchestrator_chain_collators = 2; + m.max_orchestrator_chain_collators = 2; + + m.collators = vec![1, 2]; + m.container_chains = vec![1001]; + }); + assert_eq!(assigned_collators(), initial_collators(),); + run_to_block(11); + + let initial_assignment = BTreeMap::from_iter(vec![(1, 1000), (2, 1000)]); + + assert_eq!(assigned_collators(), initial_assignment,); + + MockData::mutate(|m| { + m.collators = vec![1, 2, 3, 4]; + }); + + run_to_block(26); + + let assignment = BTreeMap::from_iter(vec![(1, 1000), (2, 1000), (3, 1001), (4, 1001)]); + assert_eq!(assigned_collators(), assignment,); + + MockData::mutate(|m| { + m.collators = vec![1, 3, 4]; + }); + + run_to_block(36); + + let assignment = BTreeMap::from_iter(vec![(1, 1000), (3, 1000)]); + + assert_eq!(assigned_collators(), assignment,); + + MockData::mutate(|m| { + m.collators = vec![3, 4]; + }); + + run_to_block(46); + + let assignment = BTreeMap::from_iter(vec![(3, 1000), (4, 1000)]); + + assert_eq!(assigned_collators(), assignment,); + }); +} + +#[test] +fn collator_assignment_includes_empty_chains() { + new_test_ext().execute_with(|| { + run_to_block(1); + + MockData::mutate(|m| { + m.collators_per_container = 2; + m.collators_per_parathread = 2; + m.min_orchestrator_chain_collators = 2; + m.max_orchestrator_chain_collators = 2; + + m.collators = vec![1, 2]; + m.container_chains = vec![2000, 2001, 2002]; + m.parathreads = vec![3000, 3001, 3002] + }); + assert_eq!(assigned_collators(), initial_collators(),); + run_to_block(11); + + let assigned_collators = CollatorContainerChain::::get(); + let expected = AssignedCollators { + orchestrator_chain: vec![1, 2], + container_chains: BTreeMap::from_iter(vec![ + (2000.into(), vec![]), + (2001.into(), vec![]), + (2002.into(), vec![]), + (3000.into(), vec![]), + (3001.into(), vec![]), + (3002.into(), vec![]), + ]), + }; + assert_eq!(assigned_collators, expected); + }); +} diff --git a/pallets/collator-assignment/src/tests/assign_full.rs b/pallets/collator-assignment/src/tests/assign_full.rs new file mode 100644 index 000000000..2ac36e2f3 --- /dev/null +++ b/pallets/collator-assignment/src/tests/assign_full.rs @@ -0,0 +1,90 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi 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. + +// Tanssi 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 Tanssi. If not, see + +use crate::assignment::AssignmentError; +use { + crate::{assignment::Assignment, tests::Test}, + sp_std::collections::btree_map::BTreeMap, +}; + +#[test] +fn assign_full_old_assigned_priority() { + // Collators in old_assigned will be selected before other collators + let collators = vec![1, 2, 3, 4, 5]; + let container_chains = vec![(1000.into(), 5)]; + let old_assigned = BTreeMap::from_iter(vec![(1000.into(), vec![3, 4])]); + + let new_assigned = + Assignment::::assign_full(collators, container_chains, old_assigned).unwrap(); + let expected = BTreeMap::from_iter(vec![(1000.into(), vec![3, 4, 1, 2, 5])]); + assert_eq!(new_assigned, expected); +} + +#[test] +fn assign_full_invalid_old_assigned_collators_removed() { + // If the collators in old_assigned are no longer collators, they are not assigned + let collators = vec![1, 2, 3, 4, 5]; + let container_chains = vec![(1000.into(), 5)]; + let old_assigned = BTreeMap::from_iter(vec![(1000.into(), vec![20, 21])]); + + let new_assigned = + Assignment::::assign_full(collators, container_chains, old_assigned).unwrap(); + let expected = BTreeMap::from_iter(vec![(1000.into(), vec![1, 2, 3, 4, 5])]); + assert_eq!(new_assigned, expected); +} + +#[test] +fn assign_full_invalid_chains_removed() { + // Mark all collators as already assigned to a chain that does not exist. Should treat them as not assigned. + let collators = vec![1, 2, 3, 4, 5]; + let container_chains = vec![(1000.into(), 5)]; + let old_assigned = BTreeMap::from_iter(vec![(1001.into(), vec![1, 2, 3, 4, 5])]); + + let new_assigned = + Assignment::::assign_full(collators, container_chains, old_assigned).unwrap(); + let expected = BTreeMap::from_iter(vec![(1000.into(), vec![1, 2, 3, 4, 5])]); + assert_eq!(new_assigned, expected); +} + +#[test] +fn assign_full_truncates_collators() { + // Need 2 collators for each chain, when old_assigned has more than 2. Should truncate old_assigned to 2. + let collators = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let container_chains = vec![(1000.into(), 2), (2000.into(), 2)]; + let old_assigned = BTreeMap::from_iter(vec![ + (1000.into(), vec![1, 2, 3, 4, 5]), + (2000.into(), vec![6, 7, 8, 9, 10]), + ]); + + let new_assigned = + Assignment::::assign_full(collators, container_chains, old_assigned).unwrap(); + let expected = BTreeMap::from_iter(vec![(1000.into(), vec![1, 2]), (2000.into(), vec![6, 7])]); + assert_eq!(new_assigned, expected); +} + +#[test] +fn assign_full_old_assigned_error_if_not_enough_collators() { + // Need 4 collators, only have 2, and all 2 were assigned to the second chain. If the function did not panic, we + // would have 0 collators assigned to the first chain, which is supposed to have priority. + let collators = vec![1, 2]; + let container_chains = vec![(1000.into(), 2), (2000.into(), 2)]; + let old_assigned = BTreeMap::from_iter(vec![(2000.into(), vec![1, 2])]); + let new_assigned = Assignment::::assign_full(collators, container_chains, old_assigned); + assert_eq!( + new_assigned.unwrap_err(), + AssignmentError::NotEnoughCollators + ); +} diff --git a/pallets/collator-assignment/src/tests/prioritize_invulnerables.rs b/pallets/collator-assignment/src/tests/prioritize_invulnerables.rs new file mode 100644 index 000000000..b9c57769b --- /dev/null +++ b/pallets/collator-assignment/src/tests/prioritize_invulnerables.rs @@ -0,0 +1,186 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi 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. + +// Tanssi 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 Tanssi. If not, see + +use { + crate::{ + assignment::{Assignment, ChainNumCollators}, + tests::Test, + }, + sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}, +}; + +#[test] +fn invulnerable_priority_0_collators() { + let collators = vec![]; + let orchestrator_chain = ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }; + let mut old_assigned = BTreeMap::new(); + + let num_invulnerables = Assignment::::prioritize_invulnerables( + &collators, + orchestrator_chain, + &mut old_assigned, + ); + + assert_eq!(num_invulnerables, 0); +} + +#[test] +fn invulnerable_priority_0_invulnerables() { + let collators = vec![1, 2, 3, 4, 5]; + let orchestrator_chain = ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }; + let mut old_assigned = BTreeMap::from_iter(vec![(1000.into(), vec![1, 2])]); + + let num_invulnerables = Assignment::::prioritize_invulnerables( + &collators, + orchestrator_chain, + &mut old_assigned, + ); + + assert_eq!(num_invulnerables, 0); +} + +#[test] +fn invulnerable_priority_1_invulnerable_orchestrator() { + let collators = vec![1, 2, 3, 4, 5, 101]; + let orchestrator_chain = ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }; + let mut old_assigned = BTreeMap::from_iter(vec![(1000.into(), vec![101])]); + + let num_invulnerables = Assignment::::prioritize_invulnerables( + &collators, + orchestrator_chain, + &mut old_assigned, + ); + + assert_eq!(num_invulnerables, 1); +} + +#[test] +fn invulnerable_priority_1_invulnerable_not_assigned() { + let collators = vec![1, 2, 3, 4, 5, 101]; + let orchestrator_chain = ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }; + let mut old_assigned = BTreeMap::new(); + + let num_invulnerables = Assignment::::prioritize_invulnerables( + &collators, + orchestrator_chain, + &mut old_assigned, + ); + + assert_eq!(num_invulnerables, 1); +} + +#[test] +fn invulnerable_priority_1_invulnerable_assigned_to_another_chain() { + let collators = vec![1, 2, 3, 4, 5, 101]; + let orchestrator_chain = ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }; + let mut old_assigned = + BTreeMap::from_iter(vec![(1000.into(), vec![]), (2000.into(), vec![101])]); + + let num_invulnerables = Assignment::::prioritize_invulnerables( + &collators, + orchestrator_chain, + &mut old_assigned, + ); + + assert_eq!(num_invulnerables, 1); +} + +#[test] +fn bug_same_invulnerable_selected_twice() { + let collators = vec![100]; + let orchestrator_chain = ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }; + let mut old_assigned = BTreeMap::from_iter(vec![(1000.into(), vec![100])]); + + let num_invulnerables = Assignment::::prioritize_invulnerables( + &collators, + orchestrator_chain, + &mut old_assigned, + ); + + assert_eq!(num_invulnerables, 1); +} + +#[test] +fn bug_not_using_assigned_invulnerables() { + // There are 3 invulnerables, 1 assigned to orchestrator and 2 assigned to a container chain. + // After `prioritize_invulnerables` the first one from the container should move to orchestrator + let collators = vec![1, 2, 3, 4, 5, 102, 103, 104]; + + let container_chains = vec![ + ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2000.into(), + min_collators: 2, + max_collators: 2, + }, + ChainNumCollators { + para_id: 2001.into(), + min_collators: 2, + max_collators: 2, + }, + ]; + let orchestrator_chain = container_chains[0]; + + let mut old_assigned = BTreeMap::from_iter(vec![ + (1000.into(), vec![101, 104, 1, 2, 3]), + (2000.into(), vec![4, 5]), + (2001.into(), vec![102, 103]), + ]); + + let chains_with_collators_set = + BTreeSet::from_iter(container_chains.iter().map(|cc| cc.para_id)); + let collators_set = BTreeSet::from_iter(collators.iter().cloned()); + Assignment::::retain_valid_old_assigned( + &mut old_assigned, + &chains_with_collators_set, + &collators_set, + ); + let num_invulnerables = Assignment::::prioritize_invulnerables( + &collators, + orchestrator_chain, + &mut old_assigned, + ); + + assert_eq!(num_invulnerables, 2); +} diff --git a/pallets/collator-assignment/src/tests/select_chains.rs b/pallets/collator-assignment/src/tests/select_chains.rs new file mode 100644 index 000000000..c524c0c86 --- /dev/null +++ b/pallets/collator-assignment/src/tests/select_chains.rs @@ -0,0 +1,176 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi 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. + +// Tanssi 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 Tanssi. If not, see + +use crate::{ + assignment::{Assignment, ChainNumCollators}, + tests::Test, +}; + +#[test] +fn select_chains_not_enough_to_reach_min_container() { + // 10 collators when the orchestrator needs 2 and the containers need 10 result in no containers having collators + let container_chains = vec![ + ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2000.into(), + min_collators: 10, + max_collators: 10, + }, + ChainNumCollators { + para_id: 2001.into(), + min_collators: 10, + max_collators: 10, + }, + ]; + let new_assigned = Assignment::::select_chains_with_collators(10, &container_chains); + assert_eq!(new_assigned, vec![(1000.into(), 5),]); +} + +#[test] +fn select_chains_not_enough_to_reach_min_orchestrator() { + // 1 collator when the orchestrator needs 2 results in 1 collators being assigned to orchestrator + let container_chains = vec![ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }]; + let new_assigned = Assignment::::select_chains_with_collators(1, &container_chains); + assert_eq!(new_assigned, vec![(1000.into(), 1),]); +} + +#[test] +fn select_chains_not_enough_for_all_min() { + // Need 6 collators to support 3 chains, only have 5. The last chain will be removed and the remaining collator + // will be assigned to orchestrator. + let container_chains = vec![ + ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2000.into(), + min_collators: 2, + max_collators: 2, + }, + ChainNumCollators { + para_id: 2001.into(), + min_collators: 2, + max_collators: 2, + }, + ]; + let new_assigned = Assignment::::select_chains_with_collators(5, &container_chains); + assert_eq!(new_assigned, vec![(1000.into(), 3), (2000.into(), 2),]); +} + +#[test] +fn select_chains_not_enough_for_all_max() { + // Need 6 collators to support 3 chains at min, but 15 collators to support them at max. + // The last chain will be removed and the remaining collator + let container_chains = vec![ + ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2001.into(), + min_collators: 2, + max_collators: 5, + }, + ]; + let new_assigned = Assignment::::select_chains_with_collators(7, &container_chains); + assert_eq!( + new_assigned, + vec![(1000.into(), 3), (2000.into(), 2), (2001.into(), 2),] + ); + let new_assigned = Assignment::::select_chains_with_collators(10, &container_chains); + assert_eq!( + new_assigned, + vec![(1000.into(), 5), (2000.into(), 3), (2001.into(), 2),] + ); + let new_assigned = Assignment::::select_chains_with_collators(13, &container_chains); + assert_eq!( + new_assigned, + vec![(1000.into(), 5), (2000.into(), 5), (2001.into(), 3),] + ); + let new_assigned = Assignment::::select_chains_with_collators(15, &container_chains); + assert_eq!( + new_assigned, + vec![(1000.into(), 5), (2000.into(), 5), (2001.into(), 5),] + ); +} + +#[test] +fn select_chains_more_than_max() { + // When the number of collators is greater than the sum of the max, all the chains are assigned max collators + let container_chains = vec![ + ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2001.into(), + min_collators: 2, + max_collators: 5, + }, + ]; + let new_assigned = Assignment::::select_chains_with_collators(20, &container_chains); + assert_eq!( + new_assigned, + vec![(1000.into(), 5), (2000.into(), 5), (2001.into(), 5),] + ); +} + +#[test] +fn select_chains_not_enough_to_reach_min_container_but_enough_for_parathread() { + // Chain 2000 has more priority than parathread 3000, but we do not have enough min collators so the container + // chain gets 0 collator and the parathread gets 1 + let container_chains = vec![ + ChainNumCollators { + para_id: 1000.into(), + min_collators: 2, + max_collators: 5, + }, + ChainNumCollators { + para_id: 2000.into(), + min_collators: 2, + max_collators: 2, + }, + ChainNumCollators { + para_id: 3000.into(), + min_collators: 1, + max_collators: 1, + }, + ]; + let new_assigned = Assignment::::select_chains_with_collators(3, &container_chains); + assert_eq!(new_assigned, vec![(1000.into(), 2), (3000.into(), 1)]); +} diff --git a/pallets/configuration/src/lib.rs b/pallets/configuration/src/lib.rs index ebc2465d6..0a7a035ca 100644 --- a/pallets/configuration/src/lib.rs +++ b/pallets/configuration/src/lib.rs @@ -46,7 +46,7 @@ use { frame_support::pallet_prelude::*, frame_system::pallet_prelude::*, serde::{Deserialize, Serialize}, - sp_runtime::{traits::AtLeast32BitUnsigned, RuntimeAppPublic, Saturating}, + sp_runtime::{traits::AtLeast32BitUnsigned, Perbill, RuntimeAppPublic, Saturating}, sp_std::prelude::*, tp_traits::GetSessionIndex, }; @@ -65,12 +65,26 @@ const LOG_TARGET: &str = "pallet_configuration"; Deserialize, )] pub struct HostConfiguration { + /// Maximum number of collators, in total, including orchestrator and containers pub max_collators: u32, + /// Minimum number of collators to be assigned to orchestrator chain pub min_orchestrator_collators: u32, + /// Maximum number of collators to be assigned to orchestrator chain after all the container chains have been + /// assigned collators. pub max_orchestrator_collators: u32, + /// How many collators to assign to one container chain pub collators_per_container: u32, - // If this value is 0 means that there is no rotation + /// Rotate all collators once every n sessions. If this value is 0 means that there is no rotation pub full_rotation_period: u32, + /// How many collators to assign to one parathread + // TODO: for now we only support 1 collator per parathread because using Aura for consensus conflicts with + // the idea of being able to create blocks every n slots: if there are 2 collators and we create blocks + // every 2 slots, 1 collator will create all the blocks. + pub collators_per_parathread: u32, + /// How many parathreads can be assigned to one collator + pub parathreads_per_collator: u32, + /// Ratio of collators that we expect to be assigned to container chains. Affects fees. + pub target_container_chain_fullness: Perbill, } impl Default for HostConfiguration { @@ -78,10 +92,12 @@ impl Default for HostConfiguration { Self { max_collators: 100u32, min_orchestrator_collators: 2u32, - // TODO: for zombienet testing max_orchestrator_collators: 5u32, collators_per_container: 2u32, full_rotation_period: 24u32, + collators_per_parathread: 1, + parathreads_per_collator: 1, + target_container_chain_fullness: Perbill::from_percent(80), } } } @@ -95,6 +111,8 @@ pub enum InconsistentError { MinOrchestratorCollatorsTooLow, /// `max_collators` must be at least 1 MaxCollatorsTooLow, + /// Tried to modify an unimplemented parameter + UnimplementedParameter, } impl HostConfiguration { @@ -113,6 +131,9 @@ impl HostConfiguration { if self.max_orchestrator_collators < self.min_orchestrator_collators { return Err(InconsistentError::MaxCollatorsLowerThanMinCollators); } + if self.collators_per_parathread != 1 || self.parathreads_per_collator != 1 { + return Err(InconsistentError::UnimplementedParameter); + } Ok(()) } @@ -273,6 +294,45 @@ pub mod pallet { }) } + #[pallet::call_index(5)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_collators_per_parathread(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.collators_per_parathread = new; + }) + } + + #[pallet::call_index(6)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_parathreads_per_collator(origin: OriginFor, new: u32) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.parathreads_per_collator = new; + }) + } + + #[pallet::call_index(7)] + #[pallet::weight(( + T::WeightInfo::set_config_with_u32(), + DispatchClass::Operational, + ))] + pub fn set_target_container_chain_fullness( + origin: OriginFor, + new: Perbill, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.target_container_chain_fullness = new; + }) + } + /// Setting this to true will disable consistency checks for the configuration setters. /// Use with caution. #[pallet::call_index(44)] @@ -478,6 +538,19 @@ pub mod pallet { config.collators_per_container } + fn collators_per_parathread(session_index: T::SessionIndex) -> u32 { + let (past_and_present, _) = Pallet::::pending_configs() + .into_iter() + .partition::, _>(|&(apply_at_session, _)| apply_at_session <= session_index); + + let config = if let Some(last) = past_and_present.last() { + last.1.clone() + } else { + Pallet::::config() + }; + config.collators_per_parathread + } + fn min_collators_for_orchestrator(session_index: T::SessionIndex) -> u32 { let (past_and_present, _) = Pallet::::pending_configs() .into_iter() diff --git a/pallets/configuration/src/tests.rs b/pallets/configuration/src/tests.rs index 54883d949..d5b4b4ac0 100644 --- a/pallets/configuration/src/tests.rs +++ b/pallets/configuration/src/tests.rs @@ -28,6 +28,7 @@ fn config_sets_values_from_genesis() { max_orchestrator_collators: 40, collators_per_container: 20, full_rotation_period: 24, + ..Default::default() }; new_test_ext_with_genesis(custom_config.clone()).execute_with(|| { run_to_block(1); @@ -43,6 +44,7 @@ fn config_sets_default_values() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }; new_test_ext().execute_with(|| { run_to_block(1); @@ -58,6 +60,7 @@ fn config_set_value() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .execute_with(|| { run_to_block(1); @@ -77,6 +80,7 @@ fn config_set_value() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() } )] ); @@ -105,6 +109,7 @@ fn config_set_full_rotation_period_to_zero_works() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .execute_with(|| { run_to_block(1); @@ -124,6 +129,7 @@ fn config_set_full_rotation_period_to_zero_works() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 0, + ..Default::default() } )] ); @@ -152,6 +158,7 @@ fn config_set_many_values_same_block() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .execute_with(|| { run_to_block(1); @@ -181,6 +188,7 @@ fn config_set_many_values_same_block() { max_orchestrator_collators: 20, collators_per_container: 10, full_rotation_period: 24, + ..Default::default() } )] ); @@ -207,6 +215,7 @@ fn config_set_many_values_different_blocks() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .execute_with(|| { run_to_block(1); @@ -238,6 +247,7 @@ fn config_set_many_values_different_blocks() { max_orchestrator_collators: 20, collators_per_container: 10, full_rotation_period: 24, + ..Default::default() } )] ); @@ -264,6 +274,7 @@ fn config_set_many_values_different_sessions() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .execute_with(|| { run_to_block(1); @@ -299,6 +310,7 @@ fn config_set_many_values_different_sessions() { max_orchestrator_collators: 20, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() } ), ( @@ -309,6 +321,7 @@ fn config_set_many_values_different_sessions() { max_orchestrator_collators: 20, collators_per_container: 10, full_rotation_period: 24, + ..Default::default() } ) ] @@ -336,6 +349,7 @@ fn config_cannot_set_invalid_values() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .execute_with(|| { run_to_block(1); diff --git a/pallets/registrar/src/lib.rs b/pallets/registrar/src/lib.rs index 3dc3d8b38..994cd4644 100644 --- a/pallets/registrar/src/lib.rs +++ b/pallets/registrar/src/lib.rs @@ -905,6 +905,11 @@ pub mod pallet { paras.into_iter().collect() } + fn session_parathreads(_session_index: T::SessionIndex) -> Vec { + // FIXME(parathreads) + vec![] + } + #[cfg(feature = "runtime-benchmarks")] fn set_session_container_chains( _session_index: T::SessionIndex, diff --git a/primitives/consensus/Cargo.toml b/primitives/consensus/Cargo.toml index 0e7393a2a..5226d895c 100644 --- a/primitives/consensus/Cargo.toml +++ b/primitives/consensus/Cargo.toml @@ -43,3 +43,10 @@ std = [ "sp-runtime/std", "sp-std/std", ] + +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "nimbus-primitives/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] diff --git a/primitives/consensus/src/lib.rs b/primitives/consensus/src/lib.rs index 9f60e5a83..de8ed4709 100644 --- a/primitives/consensus/src/lib.rs +++ b/primitives/consensus/src/lib.rs @@ -23,10 +23,13 @@ use { cumulus_primitives_core::ParaId, frame_support::traits::Get, parity_scale_codec::Codec, - sp_runtime::traits::Zero, + sp_runtime::{traits::Zero, DigestItem}, sp_std::{marker::PhantomData, vec::Vec}, }; +#[cfg(feature = "runtime-benchmarks")] +use {nimbus_primitives::NimbusSignature, sp_consensus_aura::digests::CompatibleDigestItem}; + sp_api::decl_runtime_apis! { /// API necessary for block authorship with Tanssi. pub trait TanssiAuthorityAssignmentApi { @@ -79,16 +82,25 @@ where fn slot() -> u32 { use sp_consensus_aura::{Slot, AURA_ENGINE_ID}; - let digests = frame_system::Pallet::::digest(); + let slot_from_digest = frame_system::Pallet::::digest() + .convert_first(|item: &DigestItem| item.pre_runtime_try_to::(&AURA_ENGINE_ID)); - let slot = digests - .convert_first(|item| item.pre_runtime_try_to::(&AURA_ENGINE_ID)) - //.unwrap_or_default(); - .expect("slot digest should exist"); + #[cfg(not(feature = "runtime-benchmarks"))] + let slot = slot_from_digest.expect("slot digest should exist"); + #[cfg(feature = "runtime-benchmarks")] + let slot = slot_from_digest.unwrap_or_default(); let slot: u64 = slot.into(); slot as u32 } + #[cfg(feature = "runtime-benchmarks")] + fn set_slot(slot: u32) { + let aura_digest_item = + >::aura_pre_digest( + (slot as u64).into(), + ); + frame_system::Pallet::::deposit_log(aura_digest_item); + } } #[cfg(test)] diff --git a/primitives/traits/src/lib.rs b/primitives/traits/src/lib.rs index 32aba7f6c..3b0537cee 100644 --- a/primitives/traits/src/lib.rs +++ b/primitives/traits/src/lib.rs @@ -76,6 +76,7 @@ pub trait GetCurrentContainerChains { /// session index. pub trait GetSessionContainerChains { fn session_container_chains(session_index: SessionIndex) -> Vec; + fn session_parathreads(session_index: SessionIndex) -> Vec; #[cfg(feature = "runtime-benchmarks")] fn set_session_container_chains(session_index: SessionIndex, container_chains: &[ParaId]); } @@ -93,6 +94,7 @@ pub trait GetHostConfiguration { fn min_collators_for_orchestrator(session_index: SessionIndex) -> u32; fn max_collators_for_orchestrator(session_index: SessionIndex) -> u32; fn collators_per_container(session_index: SessionIndex) -> u32; + fn collators_per_parathread(session_index: SessionIndex) -> u32; } /// Returns current session index. diff --git a/runtime/dancebox/Cargo.toml b/runtime/dancebox/Cargo.toml index fc447d5c3..73f8bfb49 100644 --- a/runtime/dancebox/Cargo.toml +++ b/runtime/dancebox/Cargo.toml @@ -33,12 +33,14 @@ pallet-pooled-staking = { workspace = true } pallet-proxy = { workspace = true } pallet-registrar = { workspace = true } pallet-registrar-runtime-api = { workspace = true } +pallet-relay-storage-roots = { workspace = true } pallet-services-payment = { workspace = true } # Moonkit nimbus-primitives = { workspace = true } pallet-async-backing = { workspace = true } pallet-author-inherent = { workspace = true } +pallet-foreign-asset-creator = { workspace = true } pallet-maintenance-mode = { workspace = true, features = [ "xcm-support" ] } pallet-migrations = { workspace = true } xcm-primitives = { workspace = true } @@ -48,6 +50,8 @@ frame-executive = { workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } frame-system-rpc-runtime-api = { workspace = true } +pallet-asset-rate = { workspace = true } +pallet-assets = { workspace = true } pallet-balances = { workspace = true } pallet-identity = { workspace = true } pallet-root-testing = { workspace = true } @@ -98,6 +102,7 @@ cumulus-primitives-timestamp = { workspace = true } cumulus-primitives-utility = { workspace = true } pallet-invulnerables = { workspace = true } parachain-info = { workspace = true } +parachains-common = { workspace = true } # Benchmarking frame-benchmarking = { workspace = true, optional = true } @@ -153,6 +158,8 @@ std = [ "frame-try-runtime/std", "log/std", "nimbus-primitives/std", + "pallet-asset-rate/std", + "pallet-assets/std", "pallet-async-backing/std", "pallet-author-inherent/std", "pallet-author-noting-runtime-api/std", @@ -164,6 +171,7 @@ std = [ "pallet-collator-assignment/std", "pallet-configuration/std", "pallet-data-preservers/std", + "pallet-foreign-asset-creator/std", "pallet-identity/std", "pallet-im-online/std", "pallet-inflation-rewards/std", @@ -176,6 +184,7 @@ std = [ "pallet-proxy/std", "pallet-registrar-runtime-api/std", "pallet-registrar/std", + "pallet-relay-storage-roots/std", "pallet-root-testing/std", "pallet-services-payment/std", "pallet-session/std", @@ -189,6 +198,7 @@ std = [ "pallet-xcm-benchmarks?/std", "pallet-xcm/std", "parachain-info/std", + "parachains-common/std", "parity-scale-codec/std", "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", @@ -243,12 +253,15 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "nimbus-primitives/runtime-benchmarks", + "pallet-asset-rate/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", "pallet-author-inherent/runtime-benchmarks", "pallet-author-noting/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collator-assignment/runtime-benchmarks", "pallet-configuration/runtime-benchmarks", "pallet-data-preservers/runtime-benchmarks", + "pallet-foreign-asset-creator/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", "pallet-inflation-rewards/runtime-benchmarks", @@ -258,6 +271,7 @@ runtime-benchmarks = [ "pallet-pooled-staking/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-registrar/runtime-benchmarks", + "pallet-relay-storage-roots/runtime-benchmarks", "pallet-services-payment/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", @@ -266,6 +280,7 @@ runtime-benchmarks = [ "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", + "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", @@ -273,6 +288,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "staging-xcm-builder/runtime-benchmarks", "staging-xcm-executor/runtime-benchmarks", + "tp-consensus/runtime-benchmarks", "tp-traits/runtime-benchmarks", "westend-runtime/runtime-benchmarks", "xcm-primitives/runtime-benchmarks", @@ -290,6 +306,10 @@ try-runtime = [ "frame-system/try-runtime", "frame-try-runtime/try-runtime", "nimbus-primitives/try-runtime", + "pallet-asset-rate/try-runtime", + "pallet-asset-rate/try-runtime", + "pallet-assets/try-runtime", + "pallet-assets/try-runtime", "pallet-author-inherent/try-runtime", "pallet-author-noting/try-runtime", "pallet-authority-assignment/try-runtime", @@ -298,6 +318,8 @@ try-runtime = [ "pallet-collator-assignment/try-runtime", "pallet-configuration/try-runtime", "pallet-data-preservers/try-runtime", + "pallet-foreign-asset-creator/try-runtime", + "pallet-foreign-asset-creator/try-runtime", "pallet-identity/try-runtime", "pallet-im-online/try-runtime", "pallet-inflation-rewards/try-runtime", @@ -309,6 +331,7 @@ try-runtime = [ "pallet-pooled-staking/try-runtime", "pallet-proxy/try-runtime", "pallet-registrar/try-runtime", + "pallet-relay-storage-roots/try-runtime", "pallet-root-testing/try-runtime", "pallet-services-payment/try-runtime", "pallet-session/try-runtime", diff --git a/runtime/dancebox/src/lib.rs b/runtime/dancebox/src/lib.rs index f6f832233..44ed54a5a 100644 --- a/runtime/dancebox/src/lib.rs +++ b/runtime/dancebox/src/lib.rs @@ -217,7 +217,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("dancebox"), impl_name: create_runtime_str!("dancebox"), authoring_version: 1, - spec_version: 400, + spec_version: 500, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -379,6 +379,12 @@ impl nimbus_primitives::CanAuthor for CanAuthor { expected_author == author } + #[cfg(feature = "runtime-benchmarks")] + fn get_authors(_slot: &u32) -> Vec { + AuthorityAssignment::collator_container_chain(Session::current_index()) + .expect("authorities should be set") + .orchestrator_chain + } } impl pallet_author_inherent::Config for Runtime { @@ -1194,6 +1200,16 @@ impl pallet_maintenance_mode::Config for Runtime { type MaintenanceExecutiveHooks = MaintenanceHooks; } +parameter_types! { + pub const MaxStorageRoots: u32 = 10; // 1 minute of relay blocks +} + +impl pallet_relay_storage_roots::Config for Runtime { + type RelaychainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider; + type MaxStorageRoots = MaxStorageRoots; + type WeightInfo = (); +} + impl pallet_root_testing::Config for Runtime {} parameter_types! { @@ -1418,6 +1434,12 @@ construct_runtime!( CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 51, DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 52, PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 53, + ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 54, + ForeignAssetsCreator: pallet_foreign_asset_creator::{Pallet, Call, Storage, Event} = 55, + AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 56, + + // More system support stuff + RelayStorageRoots: pallet_relay_storage_roots = 60, RootTesting: pallet_root_testing = 100, AsyncBacking: pallet_async_backing::{Pallet, Storage} = 110, @@ -1428,15 +1450,27 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, frame_system_benchmarking::Pallet::] - [pallet_author_noting, AuthorNoting] - [pallet_collator_assignment, CollatorAssignment] - [pallet_configuration, Configuration] + [pallet_timestamp, Timestamp] + [pallet_sudo, Sudo] + [pallet_proxy, Proxy] + [pallet_utility, Utility] + [pallet_tx_pause, TxPause] + [pallet_balances, Balances] + [pallet_identity, Identity] [pallet_registrar, Registrar] - [pallet_invulnerables, Invulnerables] - [pallet_pooled_staking, PooledStaking] + [pallet_configuration, Configuration] + [pallet_collator_assignment, CollatorAssignment] + [pallet_author_noting, AuthorNoting] [pallet_services_payment, ServicesPayment] + [pallet_foreign_asset_creator, ForeignAssetsCreator] [pallet_data_preservers, DataPreservers] + [pallet_invulnerables, Invulnerables] + [pallet_author_inherent, AuthorInherent] + [pallet_pooled_staking, PooledStaking] + [cumulus_pallet_xcmp_queue, XcmpQueue] + [pallet_xcm, PolkadotXcm] [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] + [pallet_relay_storage_roots, RelayStorageRoots] ); } @@ -1575,13 +1609,21 @@ impl_runtime_apis! { fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig, ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{BenchmarkBatch, Benchmarking}; + use frame_benchmarking::{BenchmarkBatch, Benchmarking, BenchmarkError}; use sp_core::storage::TrackedStorageKey; - impl frame_system_benchmarking::Config for Runtime {} + impl frame_system_benchmarking::Config for Runtime { + fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); + Ok(()) + } + + fn verify_set_code() { + System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); + } + } use staging_xcm::latest::prelude::*; - use frame_benchmarking::BenchmarkError; impl pallet_xcm_benchmarks::Config for Runtime { type XcmConfig = xcm_config::XcmConfig; diff --git a/runtime/dancebox/src/migrations.rs b/runtime/dancebox/src/migrations.rs index 60a2ef561..82dec71fb 100644 --- a/runtime/dancebox/src/migrations.rs +++ b/runtime/dancebox/src/migrations.rs @@ -46,11 +46,12 @@ use { sp_core::RuntimeDebug, scale_info::TypeInfo, )] -struct HostConfigurationV0 { +struct HostConfigurationV1 { pub max_collators: u32, pub min_orchestrator_collators: u32, pub max_orchestrator_collators: u32, pub collators_per_container: u32, + pub full_rotation_period: u32, } pub struct CollatorSelectionStorageValuePrefix; @@ -229,13 +230,13 @@ where } } -pub struct MigrateConfigurationFullRotationPeriod(pub PhantomData); -impl Migration for MigrateConfigurationFullRotationPeriod +pub struct MigrateConfigurationParathreads(pub PhantomData); +impl Migration for MigrateConfigurationParathreads where T: pallet_configuration::Config, { fn friendly_name(&self) -> &str { - "TM_MigrateConfigurationFullRotationPeriod" + "TM_MigrateConfigurationParathreads" } fn migrate(&self, _available_weight: Weight) -> Weight { @@ -245,9 +246,10 @@ where &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"); const CONFIGURATION_PENDING_CONFIGS_KEY: &[u8] = &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22d53b4123b2e186e07fb7bad5dda5f55c0"); + let default_config = HostConfiguration::default(); // Modify active config - let old_config: HostConfigurationV0 = + let old_config: HostConfigurationV1 = frame_support::storage::unhashed::get(CONFIGURATION_ACTIVE_CONFIG_KEY) .expect("configuration.activeConfig should have value"); let new_config = HostConfiguration { @@ -255,12 +257,15 @@ where min_orchestrator_collators: old_config.min_orchestrator_collators, max_orchestrator_collators: old_config.max_orchestrator_collators, collators_per_container: old_config.collators_per_container, - full_rotation_period: 0, + full_rotation_period: old_config.full_rotation_period, + collators_per_parathread: default_config.collators_per_parathread, + parathreads_per_collator: default_config.parathreads_per_collator, + target_container_chain_fullness: default_config.target_container_chain_fullness, }; frame_support::storage::unhashed::put(CONFIGURATION_ACTIVE_CONFIG_KEY, &new_config); // Modify pending configs, if any - let old_pending_configs: Vec<(u32, HostConfigurationV0)> = + let old_pending_configs: Vec<(u32, HostConfigurationV1)> = frame_support::storage::unhashed::get(CONFIGURATION_PENDING_CONFIGS_KEY) .unwrap_or_default(); let mut new_pending_configs: Vec<(u32, HostConfiguration)> = vec![]; @@ -271,7 +276,10 @@ where min_orchestrator_collators: old_config.min_orchestrator_collators, max_orchestrator_collators: old_config.max_orchestrator_collators, collators_per_container: old_config.collators_per_container, - full_rotation_period: 0, + full_rotation_period: old_config.full_rotation_period, + collators_per_parathread: default_config.collators_per_parathread, + parathreads_per_collator: default_config.parathreads_per_collator, + target_container_chain_fullness: default_config.target_container_chain_fullness, }; new_pending_configs.push((session_index, new_config)); } @@ -295,7 +303,7 @@ where let old_config_bytes = frame_support::storage::unhashed::get_raw(CONFIGURATION_ACTIVE_CONFIG_KEY) .expect("configuration.activeConfig should have value"); - assert_eq!(old_config_bytes.len(), 16); + assert_eq!(old_config_bytes.len(), 20); use parity_scale_codec::Encode; Ok((old_config_bytes).encode()) @@ -307,8 +315,20 @@ where &self, _number_of_invulnerables: Vec, ) -> Result<(), sp_runtime::DispatchError> { - let new_period = crate::Configuration::config().full_rotation_period; - assert_eq!(new_period, 24); + let new_config = crate::Configuration::config(); + let default_config = HostConfiguration::default(); + assert_eq!( + new_config.collators_per_parathread, + default_config.collators_per_parathread + ); + assert_eq!( + new_config.parathreads_per_collator, + default_config.collators_per_parathread + ); + assert_eq!( + new_config.target_container_chain_fullness, + default_config.target_container_chain_fullness + ); Ok(()) } @@ -565,6 +585,8 @@ where let migrate_services_payment = MigrateServicesPaymentAddCredits::(Default::default()); let migrate_boot_nodes = MigrateBootNodes::(Default::default()); + let migrate_config_parathread_params = + MigrateConfigurationParathreads::(Default::default()); let migrate_hold_reason_runtime_enum = MigrateHoldReasonRuntimeEnum::(Default::default()); @@ -582,6 +604,7 @@ where Box::new(migrate_services_payment), Box::new(migrate_hold_reason_runtime_enum), Box::new(migrate_boot_nodes), + Box::new(migrate_config_parathread_params), ] } } diff --git a/runtime/dancebox/src/xcm_config.rs b/runtime/dancebox/src/xcm_config.rs index 71153b810..e99e6e2f1 100644 --- a/runtime/dancebox/src/xcm_config.rs +++ b/runtime/dancebox/src/xcm_config.rs @@ -16,9 +16,9 @@ use { super::{ - weights::xcm::XcmWeight as XcmGenericWeights, AccountId, AllPalletsWithSystem, Balances, - ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, - RuntimeOrigin, WeightToFee, XcmpQueue, + weights::xcm::XcmWeight as XcmGenericWeights, AccountId, AllPalletsWithSystem, Balance, + Balances, ForeignAssetsCreator, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }, cumulus_primitives_core::ParaId, frame_support::{ @@ -33,10 +33,11 @@ use { staging_xcm::latest::prelude::*, staging_xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, - AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin, IsConcrete, - ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, - TakeWeightCredit, UsingComponents, WeightInfoBounds, WithComputedOrigin, + AllowTopLevelPaidExecutionFrom, ConvertedConcreteId, CurrencyAdapter, EnsureXcmOrigin, + IsConcrete, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, + SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds, + WithComputedOrigin, }, staging_xcm_executor::XcmExecutor, }; @@ -151,7 +152,7 @@ pub type XcmOriginToTransactDispatchOrigin = ( ); /// Means for transacting assets on this chain. -pub type AssetTransactors = CurrencyTransactor; +pub type AssetTransactors = (CurrencyTransactor, ForeignFungiblesTransactor); pub type XcmWeigher = WeightInfoBounds, RuntimeCall, MaxInstructions>; @@ -170,14 +171,24 @@ impl staging_xcm_executor::Config for XcmConfig { type XcmSender = XcmRouter; type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = (); + type IsReserve = NativeAssetReserve; type IsTeleporter = (); type UniversalLocation = UniversalLocation; type Barrier = XcmBarrier; type Weigher = XcmWeigher; // Local token trader only // TODO: update once we have a way to do fees - type Trader = UsingComponents; + type Trader = ( + UsingComponents, + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + AssetRateAsMultiplier, + // Use this currency when it is a fungible asset matching the given location or name: + (ConvertedConcreteId,), + ForeignAssets, + (), + >, + ); type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; type AssetClaims = PolkadotXcm; @@ -245,3 +256,184 @@ impl cumulus_pallet_dmp_queue::Config for Runtime { type XcmExecutor = XcmExecutor; type ExecuteOverweightOrigin = EnsureRoot; } + +parameter_types! { + // we just reuse the same deposits + pub const ForeignAssetsAssetDeposit: Balance = 0; + pub const ForeignAssetsAssetAccountDeposit: Balance = 0; + pub const ForeignAssetsApprovalDeposit: Balance = 0; + pub const ForeignAssetsAssetsStringLimit: u32 = 50; + pub const ForeignAssetsMetadataDepositBase: Balance = 0; + pub const ForeignAssetsMetadataDepositPerByte: Balance = 0; + pub CheckingAccount: AccountId = PolkadotXcm::check_account(); +} + +#[cfg(feature = "runtime-benchmarks")] +/// Simple conversion of `u32` into an `AssetId` for use in benchmarking. +pub struct ForeignAssetBenchmarkHelper; +#[cfg(feature = "runtime-benchmarks")] +impl pallet_assets::BenchmarkHelper for ForeignAssetBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> AssetId { + id.try_into() + .expect("number too large to create benchmarks") + } +} +#[cfg(feature = "runtime-benchmarks")] +impl pallet_asset_rate::AssetKindFactory for ForeignAssetBenchmarkHelper { + fn create_asset_kind(id: u32) -> AssetId { + id.try_into() + .expect("number too large to create benchmarks") + } +} + +pub type AssetId = u16; +pub type ForeignAssetsInstance = pallet_assets::Instance1; +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type AssetId = AssetId; + type AssetIdParameter = AssetId; + type Currency = Balances; + type CreateOrigin = frame_support::traits::NeverEnsureOrigin; + type ForceOrigin = EnsureRoot; + type AssetDeposit = ForeignAssetsAssetDeposit; + type MetadataDepositBase = ForeignAssetsMetadataDepositBase; + type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte; + type ApprovalDeposit = ForeignAssetsApprovalDeposit; + type StringLimit = ForeignAssetsAssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = pallet_assets::weights::SubstrateWeight; + type CallbackHandle = (); + type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit; + type RemoveItemsLimit = frame_support::traits::ConstU32<1000>; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = ForeignAssetBenchmarkHelper; +} + +impl pallet_foreign_asset_creator::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ForeignAsset = MultiLocation; + type ForeignAssetCreatorOrigin = EnsureRoot; + type ForeignAssetModifierOrigin = EnsureRoot; + type ForeignAssetDestroyerOrigin = EnsureRoot; + type Fungibles = ForeignAssets; + type WeightInfo = pallet_foreign_asset_creator::weights::SubstrateWeight; +} + +impl pallet_asset_rate::Config for Runtime { + type CreateOrigin = EnsureRoot; + type RemoveOrigin = EnsureRoot; + type UpdateOrigin = EnsureRoot; + type Currency = Balances; + type AssetKind = AssetId; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_asset_rate::weights::SubstrateWeight; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = ForeignAssetBenchmarkHelper; +} + +use crate::ForeignAssets; +use sp_runtime::{traits::CheckedDiv, FixedPointNumber}; +use staging_xcm_builder::FungiblesAdapter; +use staging_xcm_builder::NoChecking; +use staging_xcm_executor::traits::JustTry; + +/// Means for transacting foreign assets from different global consensus. +pub type ForeignFungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + ForeignAssets, + // Use this currency when it is a fungible asset matching the given location or name: + (ConvertedConcreteId,), + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont need to check teleports here. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + +/// Multiplier used for dedicated `TakeFirstAssetTrader` with `ForeignAssets` instance. +pub type AssetRateAsMultiplier = + parachains_common::xcm_config::AssetFeeAsExistentialDepositMultiplier< + Runtime, + WeightToFee, + CustomConverter, + ForeignAssetsInstance, + >; + +// TODO: move to https://github.com/paritytech/polkadot-sdk/pull/2903 once its merged +pub struct CustomConverter; +impl frame_support::traits::tokens::ConversionToAssetBalance + for CustomConverter +{ + type Error = (); + fn to_asset_balance(balance: Balance, asset_id: AssetId) -> Result { + let rate = pallet_asset_rate::ConversionRateToNative::::get(asset_id).ok_or(())?; + Ok(sp_runtime::FixedU128::from_u32(1) + .checked_div(&rate) + .ok_or(())? + .saturating_mul_int(balance)) + } +} + +// TODO: this should probably move to somewhere in the polkadot-sdk repo +pub struct NativeAssetReserve; +impl frame_support::traits::ContainsPair for NativeAssetReserve { + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + log::trace!(target: "xcm::contains", "NativeAssetReserve asset: {:?}, origin: {:?}", asset, origin); + let reserve = if let Concrete(location) = &asset.id { + if location.parents == 0 && !matches!(location.first_interior(), Some(Parachain(_))) { + Some(MultiLocation::here()) + } else { + location.chain_part() + } + } else { + None + }; + + if let Some(ref reserve) = reserve { + if reserve == origin { + return true; + } + } + false + } +} + +pub trait Parse { + /// Returns the "chain" location part. It could be parent, sibling + /// parachain, or child parachain. + fn chain_part(&self) -> Option; + /// Returns "non-chain" location part. + fn non_chain_part(&self) -> Option; +} + +impl Parse for MultiLocation { + fn chain_part(&self) -> Option { + match (self.parents, self.first_interior()) { + // sibling parachain + (1, Some(Parachain(id))) => Some(MultiLocation::new(1, X1(Parachain(*id)))), + // parent + (1, _) => Some(MultiLocation::parent()), + // children parachain + (0, Some(Parachain(id))) => Some(MultiLocation::new(0, X1(Parachain(*id)))), + _ => None, + } + } + + fn non_chain_part(&self) -> Option { + let mut junctions = *self.interior(); + while matches!(junctions.first(), Some(Parachain(_))) { + let _ = junctions.take_first(); + } + + if junctions != Here { + Some(MultiLocation::new(0, junctions)) + } else { + None + } + } +} diff --git a/runtime/dancebox/tests/common/mod.rs b/runtime/dancebox/tests/common/mod.rs index cbe489171..ce7379d9e 100644 --- a/runtime/dancebox/tests/common/mod.rs +++ b/runtime/dancebox/tests/common/mod.rs @@ -39,11 +39,11 @@ use { mod xcm; pub use dancebox_runtime::{ - AccountId, AuthorNoting, AuthorityAssignment, AuthorityMapping, Balance, Balances, - CollatorAssignment, Configuration, DataPreservers, InflationRewards, Initializer, - Invulnerables, MinimumSelfDelegation, ParachainInfo, PooledStaking, Proxy, ProxyType, - Registrar, RewardsPortion, Runtime, RuntimeCall, RuntimeEvent, ServicesPayment, Session, - System, + AccountId, AssetRate, AuthorNoting, AuthorityAssignment, AuthorityMapping, Balance, Balances, + CollatorAssignment, Configuration, DataPreservers, ForeignAssets, ForeignAssetsCreator, + InflationRewards, Initializer, Invulnerables, MinimumSelfDelegation, ParachainInfo, + PooledStaking, Proxy, ProxyType, Registrar, RewardsPortion, Runtime, RuntimeCall, RuntimeEvent, + ServicesPayment, Session, System, }; pub fn session_to_block(n: u32) -> u32 { diff --git a/runtime/dancebox/tests/common/xcm/mocknets.rs b/runtime/dancebox/tests/common/xcm/mocknets.rs index 5c803560d..a522920a0 100644 --- a/runtime/dancebox/tests/common/xcm/mocknets.rs +++ b/runtime/dancebox/tests/common/xcm/mocknets.rs @@ -94,6 +94,9 @@ decl_test_parachains! { Balances: dancebox_runtime::Balances, ParachainSystem: dancebox_runtime::ParachainSystem, PolkadotXcm: dancebox_runtime::PolkadotXcm, + ForeignAssets: dancebox_runtime::ForeignAssets, + AssetRate: dancebox_runtime::AssetRate, + ForeignAssetsCreator: dancebox_runtime::ForeignAssetsCreator, } }, pub struct FrontierTemplate { diff --git a/runtime/dancebox/tests/common/xcm/mod.rs b/runtime/dancebox/tests/common/xcm/mod.rs index 24a4c33e0..64cccedec 100644 --- a/runtime/dancebox/tests/common/xcm/mod.rs +++ b/runtime/dancebox/tests/common/xcm/mod.rs @@ -18,6 +18,8 @@ mod constants; mod foreign_signed_based_sovereign; mod foreign_sovereigns; mod mocknets; +mod token_derivative_reception_container; +mod token_derivative_reception_relay; mod transact; mod trap; diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_container.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_container.rs new file mode 100644 index 000000000..debc1b3ce --- /dev/null +++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_container.rs @@ -0,0 +1,139 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi 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. + +// Tanssi 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 Tanssi. If not, see + +use { + crate::common::xcm::{ + mocknets::{ + Dancebox, DanceboxPallet, DanceboxReceiver, SimpleTemplate, SimpleTemplatePallet, + SimpleTemplateSender, + }, + *, + }, + frame_support::{ + assert_ok, + traits::PalletInfoAccess, + weights::{Weight, WeightToFee}, + }, + sp_runtime::FixedU128, + staging_xcm::{latest::prelude::*, VersionedMultiLocation}, + xcm_emulator::Chain, +}; + +#[allow(unused_assignments)] +#[test] +fn receive_tokens_from_the_container_to_tanssi() { + // XcmPallet reserve transfer arguments + let alice_origin = + ::RuntimeOrigin::signed(SimpleTemplateSender::get()); + + // Parents 1 this time + let dancebox_dest: VersionedMultiLocation = MultiLocation { + parents: 1, + interior: X1(Parachain(2000u32)), + } + .into(); + + let dancebox_beneficiary: VersionedMultiLocation = MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: DanceboxReceiver::get().into(), + }), + } + .into(); + + let amount_to_send: crate::Balance = + container_chain_template_simple_runtime::ExistentialDeposit::get() * 1000; + + let simple_template_pallet_info_junction = PalletInstance( + <::Balances as PalletInfoAccess>::index() as u8, + ); + let assets: MultiAssets = (X1(simple_template_pallet_info_junction), amount_to_send).into(); + let fee_asset_item = 0; + let simple_template_token_asset_id = 1u16; + + // Register the asset first + Dancebox::execute_with(|| { + let root_origin = ::RuntimeOrigin::root(); + + assert_ok!( + ::ForeignAssetsCreator::create_foreign_asset( + root_origin.clone(), + MultiLocation { + parents: 1, + interior: X2(Parachain(2002), simple_template_pallet_info_junction) + }, + simple_template_token_asset_id, + DanceboxReceiver::get(), + true, + 1 + ) + ); + + assert_ok!(::AssetRate::create( + root_origin, + bx!(1), + FixedU128::from_u32(1) + )); + }); + + // Send XCM message from SimpleTemplate + SimpleTemplate::execute_with(|| { + assert_ok!( + ::PolkadotXcm::limited_reserve_transfer_assets( + alice_origin, + bx!(dancebox_dest), + bx!(dancebox_beneficiary), + bx!(assets.into()), + fee_asset_item, + WeightLimit::Unlimited, + ) + ); + }); + // We should have received the tokens + Dancebox::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + let mut outcome_weight = Weight::default(); + assert_expected_events!( + Dancebox, + vec![ + RuntimeEvent::XcmpQueue( + cumulus_pallet_xcmp_queue::Event::Success { + weight, + .. + }) => { + weight: { + outcome_weight = *weight; + weight.all_gte(Weight::from_parts(0, 0)) + }, + }, + ] + ); + type ForeignAssets = ::ForeignAssets; + + // We should have charged an amount of tokens that is identical to the weight spent + let native_balance = dancebox_runtime::WeightToFee::weight_to_fee(&outcome_weight); + + // Assert empty receiver received funds + assert_eq!( + >::balance( + simple_template_token_asset_id, + &DanceboxReceiver::get(), + ), + amount_to_send - native_balance + ); + }); +} diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay.rs new file mode 100644 index 000000000..ddce49633 --- /dev/null +++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay.rs @@ -0,0 +1,280 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi 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. + +// Tanssi 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 Tanssi. If not, see + +use { + crate::common::xcm::{ + mocknets::{ + Dancebox, DanceboxPallet, DanceboxReceiver, Westend, WestendPallet, WestendSender, + }, + *, + }, + frame_support::{ + assert_ok, + weights::{Weight, WeightToFee}, + }, + sp_runtime::FixedU128, + staging_xcm::{latest::prelude::*, VersionedMultiLocation}, + xcm_emulator::Chain, +}; + +#[allow(unused_assignments)] +#[test] +fn receive_tokens_from_the_relay_to_tanssi() { + // XcmPallet reserve transfer arguments + let alice_origin = ::RuntimeOrigin::signed(WestendSender::get()); + + let dancebox_dest: VersionedMultiLocation = MultiLocation { + parents: 0, + interior: X1(Parachain(2000u32)), + } + .into(); + + let dancebox_beneficiary: VersionedMultiLocation = MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: DanceboxReceiver::get().into(), + }), + } + .into(); + + let amount_to_send: crate::Balance = westend_runtime::ExistentialDeposit::get() * 1000; + + let assets: MultiAssets = (Here, amount_to_send).into(); + let fee_asset_item = 0; + let westend_token_asset_id = 1u16; + + // Register the asset first + Dancebox::execute_with(|| { + let root_origin = ::RuntimeOrigin::root(); + + assert_ok!( + ::ForeignAssetsCreator::create_foreign_asset( + root_origin.clone(), + MultiLocation::parent(), + westend_token_asset_id, + DanceboxReceiver::get(), + true, + 1 + ) + ); + + assert_ok!(::AssetRate::create( + root_origin, + bx!(1), + FixedU128::from_u32(1) + )); + }); + + // Send XCM message from Westend + Westend::execute_with(|| { + assert_ok!( + ::XcmPallet::limited_reserve_transfer_assets( + alice_origin, + bx!(dancebox_dest), + bx!(dancebox_beneficiary), + bx!(assets.into()), + fee_asset_item, + WeightLimit::Unlimited, + ) + ); + }); + // We should have received the tokens + Dancebox::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + let mut outcome_weight = Weight::default(); + assert_expected_events!( + Dancebox, + vec![ + RuntimeEvent::DmpQueue( + cumulus_pallet_dmp_queue::Event::ExecutedDownward { + outcome, .. + }) => { + outcome: { + outcome_weight = outcome.clone().weight_used(); + outcome.clone().ensure_complete().is_ok() + }, + }, + ] + ); + type ForeignAssets = ::ForeignAssets; + + // We should have charged an amount of tokens that is identical to the weight spent + let native_balance = dancebox_runtime::WeightToFee::weight_to_fee(&outcome_weight); + + // Assert empty receiver received funds + assert_eq!( + >::balance( + westend_token_asset_id, + &DanceboxReceiver::get(), + ), + amount_to_send - native_balance + ); + }); +} + +#[test] +fn cannot_receive_tokens_from_the_relay_if_no_rate_is_assigned() { + // XcmPallet reserve transfer arguments + let alice_origin = ::RuntimeOrigin::signed(WestendSender::get()); + + let dancebox_dest: VersionedMultiLocation = MultiLocation { + parents: 0, + interior: X1(Parachain(2000u32)), + } + .into(); + + let dancebox_beneficiary: VersionedMultiLocation = MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: DanceboxReceiver::get().into(), + }), + } + .into(); + + let amount_to_send: crate::Balance = westend_runtime::ExistentialDeposit::get() * 1000; + + let assets: MultiAssets = (Here, amount_to_send).into(); + let fee_asset_item = 0; + let westend_token_asset_id = 1u16; + + // Register the asset first + Dancebox::execute_with(|| { + let root_origin = ::RuntimeOrigin::root(); + + assert_ok!( + ::ForeignAssetsCreator::create_foreign_asset( + root_origin.clone(), + MultiLocation::parent(), + westend_token_asset_id, + DanceboxReceiver::get(), + true, + 1 + ) + ); + // we register the asset but we never rate it + }); + + // Send XCM message from Westend + Westend::execute_with(|| { + assert_ok!( + ::XcmPallet::limited_reserve_transfer_assets( + alice_origin, + bx!(dancebox_dest), + bx!(dancebox_beneficiary), + bx!(assets.into()), + fee_asset_item, + WeightLimit::Unlimited, + ) + ); + }); + // We should have received the tokens + Dancebox::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + assert_expected_events!( + Dancebox, + vec![ + RuntimeEvent::DmpQueue( + cumulus_pallet_dmp_queue::Event::ExecutedDownward { + outcome, .. + }) => { + outcome: { + outcome.clone().ensure_complete().is_err() + }, + }, + ] + ); + type ForeignAssets = ::ForeignAssets; + + // Assert receiver should not have received funds + assert_eq!( + >::balance( + westend_token_asset_id, + &DanceboxReceiver::get(), + ), + 0 + ); + }); +} + +#[test] +fn cannot_receive_tokens_from_the_relay_if_no_token_is_registered() { + // XcmPallet reserve transfer arguments + let alice_origin = ::RuntimeOrigin::signed(WestendSender::get()); + + let dancebox_dest: VersionedMultiLocation = MultiLocation { + parents: 0, + interior: X1(Parachain(2000u32)), + } + .into(); + + let dancebox_beneficiary: VersionedMultiLocation = MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: DanceboxReceiver::get().into(), + }), + } + .into(); + + let amount_to_send: crate::Balance = westend_runtime::ExistentialDeposit::get() * 1000; + + let assets: MultiAssets = (Here, amount_to_send).into(); + let fee_asset_item = 0; + let westend_token_asset_id = 1u16; + + // Send XCM message from Westend + Westend::execute_with(|| { + assert_ok!( + ::XcmPallet::limited_reserve_transfer_assets( + alice_origin, + bx!(dancebox_dest), + bx!(dancebox_beneficiary), + bx!(assets.into()), + fee_asset_item, + WeightLimit::Unlimited, + ) + ); + }); + // We should have received the tokens + Dancebox::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + assert_expected_events!( + Dancebox, + vec![ + RuntimeEvent::DmpQueue( + cumulus_pallet_dmp_queue::Event::ExecutedDownward { + outcome, .. + }) => { + outcome: { + outcome.clone().ensure_complete().is_err() + }, + }, + ] + ); + type ForeignAssets = ::ForeignAssets; + + // Assert receiver should not have received funds + assert_eq!( + >::balance( + westend_token_asset_id, + &DanceboxReceiver::get(), + ), + 0 + ); + }); +} diff --git a/runtime/dancebox/tests/integration_test.rs b/runtime/dancebox/tests/integration_test.rs index 398b1deee..4f340e3e2 100644 --- a/runtime/dancebox/tests/integration_test.rs +++ b/runtime/dancebox/tests/integration_test.rs @@ -16,14 +16,15 @@ #![cfg(test)] +use pallet_balances::Instance1; + use { common::*, cumulus_primitives_core::ParaId, dancebox_runtime::{ migrations::{ - CollatorSelectionInvulnerablesValue, MigrateBootNodes, - MigrateConfigurationFullRotationPeriod, MigrateInvulnerables, - MigrateServicesPaymentAddCredits, + CollatorSelectionInvulnerablesValue, MigrateBootNodes, MigrateConfigurationParathreads, + MigrateInvulnerables, MigrateServicesPaymentAddCredits, }, BlockProductionCost, RewardsCollatorCommission, }, @@ -47,9 +48,10 @@ use { sp_core::Get, sp_runtime::{ traits::{BadOrigin, BlakeTwo256, OpaqueKeys}, - DigestItem, + DigestItem, FixedU128, }, sp_std::vec, + staging_xcm::latest::prelude::*, test_relay_sproof_builder::{HeaderAs, ParaHeaderSproofBuilder, ParaHeaderSproofBuilderItem}, tp_consensus::runtime_decl_for_tanssi_authority_assignment_api::TanssiAuthorityAssignmentApiV1, }; @@ -107,6 +109,7 @@ fn default_config() -> pallet_configuration::HostConfiguration { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() } } @@ -616,6 +619,7 @@ fn test_authors_paras_inserted_a_posteriori_with_collators_already_assigned() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .build() .execute_with(|| { @@ -1293,12 +1297,9 @@ fn test_author_collation_aura_add_assigned_to_paras_runtime_api() { run_to_session(4u32); assert_eq!( Runtime::parachain_collators(100.into()), - Some(vec![ALICE.into()]) - ); - assert_eq!( - Runtime::parachain_collators(1001.into()), - Some(vec![CHARLIE.into(), DAVE.into()]) + Some(vec![ALICE.into(), CHARLIE.into()]) ); + assert_eq!(Runtime::parachain_collators(1001.into()), Some(vec![])); assert_eq!( Runtime::current_collator_parachain_assignment(BOB.into()), None @@ -3734,6 +3735,7 @@ fn test_pallet_session_limits_num_validators() { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .build() .execute_with(|| { @@ -3822,6 +3824,7 @@ fn test_pallet_session_limits_num_validators_from_staking() { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .build() .execute_with(|| { @@ -4041,6 +4044,7 @@ fn test_reward_to_staking_candidate() { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .build() .execute_with(|| { @@ -4155,6 +4159,7 @@ fn test_reward_to_invulnerable() { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .build() .execute_with(|| { @@ -4252,6 +4257,7 @@ fn test_reward_to_invulnerable_with_key_change() { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 24, + ..Default::default() }) .build() .execute_with(|| { @@ -4311,11 +4317,11 @@ fn test_migration_config_full_rotation_period() { &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22d53b4123b2e186e07fb7bad5dda5f55c0"); // Modify active config - frame_support::storage::unhashed::put_raw(CONFIGURATION_ACTIVE_CONFIG_KEY, &hex_literal::hex!("63000000020000000500000002000000")); + frame_support::storage::unhashed::put_raw(CONFIGURATION_ACTIVE_CONFIG_KEY, &hex_literal::hex!("6300000002000000050000000200000000000000")); // Modify pending configs - frame_support::storage::unhashed::put_raw(CONFIGURATION_PENDING_CONFIGS_KEY, &hex_literal::hex!("08b108000063000000020000000500000002000000b208000064000000020000000500000002000000")); + frame_support::storage::unhashed::put_raw(CONFIGURATION_PENDING_CONFIGS_KEY, &hex_literal::hex!("08b10800006300000002000000050000000200000000000000b20800006400000002000000050000000200000000000000")); - let migration = MigrateConfigurationFullRotationPeriod::(Default::default()); + let migration = MigrateConfigurationParathreads::(Default::default()); migration.migrate(Default::default()); let expected_active = pallet_configuration::HostConfiguration { @@ -4324,11 +4330,33 @@ fn test_migration_config_full_rotation_period() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 0, + ..Default::default() }; assert_eq!(Configuration::config(), expected_active); let expected_pending = vec![ - (2225, pallet_configuration::HostConfiguration { max_collators: 99, min_orchestrator_collators: 2, max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 0 }), (2226, pallet_configuration::HostConfiguration { max_collators: 100, min_orchestrator_collators: 2, max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 0 }) + ( + 2225, + pallet_configuration::HostConfiguration { + max_collators: 99, + min_orchestrator_collators: 2, + max_orchestrator_collators: 5, + collators_per_container: 2, + full_rotation_period: 0, + ..Default::default() + }, + ), + ( + 2226, + pallet_configuration::HostConfiguration { + max_collators: 100, + min_orchestrator_collators: 2, + max_orchestrator_collators: 5, + collators_per_container: 2, + full_rotation_period: 0, + ..Default::default() + }, + ), ]; assert_eq!(Configuration::pending_configs(), expected_pending); }); @@ -4805,3 +4833,158 @@ fn test_deregister_and_register_again_does_not_give_free_credits() { assert_eq!(credits, credits_before_2nd_register); }); } + +#[test] +fn test_sudo_can_register_foreign_assets_and_manager_change_paremeters() { + ExtBuilder::default() + .with_balances(vec![ + // Alice gets 10k extra tokens for her mapping deposit + (AccountId::from(ALICE), 210_000 * UNIT), + (AccountId::from(BOB), 100_000 * UNIT), + (AccountId::from(CHARLIE), 100_000 * UNIT), + (AccountId::from(DAVE), 100_000 * UNIT), + ]) + .with_collators(vec![ + (AccountId::from(ALICE), 210 * UNIT), + (AccountId::from(BOB), 100 * UNIT), + (AccountId::from(CHARLIE), 100 * UNIT), + (AccountId::from(DAVE), 100 * UNIT), + ]) + .with_config(default_config()) + .build() + .execute_with(|| { + + // We register the asset with Alice as manager + assert_ok!(ForeignAssetsCreator::create_foreign_asset(root_origin(), MultiLocation::parent(), 1, AccountId::from(ALICE), true, 1), ()); + assert_eq!(ForeignAssetsCreator::foreign_asset_for_id(1), Some(MultiLocation::parent())); + assert_eq!(ForeignAssetsCreator::asset_id_for_foreign(MultiLocation::parent()), Some(1)); + + // Alice now can change parameters like metadata from the asset + assert_ok!(ForeignAssets::set_metadata(origin_of(ALICE.into()), 1, b"xcDot".to_vec(), b"xcDot".to_vec(), 12)); + assert_eq!(>::name(1), b"xcDot".to_vec()); + assert_eq!(>::symbol(1), b"xcDot".to_vec()); + assert_eq!(>::decimals(1), 12); + + // Any other person cannot do this + assert_noop!( + ForeignAssets::set_metadata(origin_of(BOB.into()), 1, b"dummy".to_vec(), b"dummy".to_vec(), 12), + pallet_assets::Error::::NoPermission + ); + + // Alice now can mint + assert_ok!(ForeignAssets::mint(origin_of(ALICE.into()), 1, AccountId::from(BOB).into(), 1000)); + assert_eq!(>::total_issuance(1), 1000); + assert_eq!(>::balance(1, &AccountId::from(BOB)), 1000); + }); +} + +#[test] +fn test_assets_cannot_be_created_from_signed_origins() { + ExtBuilder::default() + .with_balances(vec![ + // Alice gets 10k extra tokens for her mapping deposit + (AccountId::from(ALICE), 210_000 * UNIT), + (AccountId::from(BOB), 100_000 * UNIT), + (AccountId::from(CHARLIE), 100_000 * UNIT), + (AccountId::from(DAVE), 100_000 * UNIT), + ]) + .with_collators(vec![ + (AccountId::from(ALICE), 210 * UNIT), + (AccountId::from(BOB), 100 * UNIT), + (AccountId::from(CHARLIE), 100 * UNIT), + (AccountId::from(DAVE), 100 * UNIT), + ]) + .with_config(default_config()) + .build() + .execute_with(|| { + // We try to register the asset with Alice as origin + // Any other person cannot do this + assert_noop!( + ForeignAssetsCreator::create_foreign_asset( + origin_of(ALICE.into()), + MultiLocation::parent(), + 1, + AccountId::from(ALICE), + true, + 1 + ), + BadOrigin + ); + + assert_noop!( + ForeignAssets::create(origin_of(ALICE.into()), 1, AccountId::from(ALICE).into(), 1), + BadOrigin + ); + }); +} + +#[test] +fn test_asset_rate_can_be_set_from_sudo_but_not_from_signed() { + ExtBuilder::default() + .with_balances(vec![ + // Alice gets 10k extra tokens for her mapping deposit + (AccountId::from(ALICE), 210_000 * UNIT), + (AccountId::from(BOB), 100_000 * UNIT), + (AccountId::from(CHARLIE), 100_000 * UNIT), + (AccountId::from(DAVE), 100_000 * UNIT), + ]) + .with_collators(vec![ + (AccountId::from(ALICE), 210 * UNIT), + (AccountId::from(BOB), 100 * UNIT), + (AccountId::from(CHARLIE), 100 * UNIT), + (AccountId::from(DAVE), 100 * UNIT), + ]) + .with_config(default_config()) + .build() + .execute_with(|| { + // We try to set the rate from non-sudo + assert_noop!( + AssetRate::create(origin_of(ALICE.into()), Box::new(1), FixedU128::from_u32(1)), + BadOrigin + ); + + // We try to set the rate from sudo + assert_ok!(AssetRate::create( + root_origin(), + Box::new(1), + FixedU128::from_u32(1) + )); + + assert_eq!( + pallet_asset_rate::ConversionRateToNative::::get(1), + Some(FixedU128::from_u32(1)) + ); + }); +} + +#[test] +fn test_division_by_0() { + ExtBuilder::default() + .with_balances(vec![ + // Alice gets 10k extra tokens for her mapping deposit + (AccountId::from(ALICE), 210_000 * UNIT), + (AccountId::from(BOB), 100_000 * UNIT), + (AccountId::from(CHARLIE), 100_000 * UNIT), + (AccountId::from(DAVE), 100_000 * UNIT), + ]) + .with_collators(vec![ + (AccountId::from(ALICE), 210 * UNIT), + (AccountId::from(BOB), 100 * UNIT), + (AccountId::from(CHARLIE), 100 * UNIT), + (AccountId::from(DAVE), 100 * UNIT), + ]) + .with_config(default_config()) + .build() + .execute_with(|| { + // We try to set 0 rate to make sure we dont overflow + assert_ok!(AssetRate::create( + root_origin(), + Box::new(1), + FixedU128::from_u32(0) + )); + + use frame_support::traits::tokens::ConversionToAssetBalance; + let balance = dancebox_runtime::xcm_config::CustomConverter::to_asset_balance(1, 1); + assert!(balance.is_err()); + }); +} diff --git a/runtime/flashbox/Cargo.toml b/runtime/flashbox/Cargo.toml index 15bcfa439..218c45d58 100644 --- a/runtime/flashbox/Cargo.toml +++ b/runtime/flashbox/Cargo.toml @@ -32,6 +32,7 @@ pallet-initializer = { workspace = true } pallet-proxy = { workspace = true } pallet-registrar = { workspace = true } pallet-registrar-runtime-api = { workspace = true } +pallet-relay-storage-roots = { workspace = true } pallet-services-payment = { workspace = true } # Moonkit @@ -151,6 +152,7 @@ std = [ "pallet-proxy/std", "pallet-registrar-runtime-api/std", "pallet-registrar/std", + "pallet-relay-storage-roots/std", "pallet-root-testing/std", "pallet-services-payment/std", "pallet-session/std", @@ -219,6 +221,7 @@ runtime-benchmarks = [ "pallet-migrations/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-registrar/runtime-benchmarks", + "pallet-relay-storage-roots/runtime-benchmarks", "pallet-services-payment/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", @@ -228,6 +231,7 @@ runtime-benchmarks = [ "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "tp-consensus/runtime-benchmarks", "tp-traits/runtime-benchmarks", ] @@ -255,6 +259,7 @@ try-runtime = [ "pallet-migrations/try-runtime", "pallet-proxy/try-runtime", "pallet-registrar/try-runtime", + "pallet-relay-storage-roots/try-runtime", "pallet-root-testing/try-runtime", "pallet-services-payment/try-runtime", "pallet-session/try-runtime", diff --git a/runtime/flashbox/src/lib.rs b/runtime/flashbox/src/lib.rs index 9ab931dd9..6d7e55455 100644 --- a/runtime/flashbox/src/lib.rs +++ b/runtime/flashbox/src/lib.rs @@ -92,6 +92,8 @@ pub use { sp_runtime::{MultiAddress, Perbill, Permill}, }; +const LOG_TARGET: &str = "runtime::tanssi"; + /// Block type as expected by this runtime. pub type Block = generic::Block; /// A Block signed with a Justification @@ -203,7 +205,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("flashbox"), impl_name: create_runtime_str!("flashbox"), authoring_version: 1, - spec_version: 400, + spec_version: 500, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -1018,6 +1020,16 @@ impl pallet_maintenance_mode::Config for Runtime { type MaintenanceExecutiveHooks = MaintenanceHooks; } +parameter_types! { + pub const MaxStorageRoots: u32 = 10; // 1 minute of relay blocks +} + +impl pallet_relay_storage_roots::Config for Runtime { + type RelaychainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider; + type MaxStorageRoots = MaxStorageRoots; + type WeightInfo = (); +} + impl pallet_root_testing::Config for Runtime {} parameter_types! { @@ -1159,6 +1171,9 @@ construct_runtime!( // InflationRewards must be after Session and AuthorInherent InflationRewards: pallet_inflation_rewards = 35, + // More system support stuff + RelayStorageRoots: pallet_relay_storage_roots = 60, + RootTesting: pallet_root_testing = 100, AsyncBacking: pallet_async_backing::{Pallet, Storage} = 110, } @@ -1168,13 +1183,22 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, frame_system_benchmarking::Pallet::] - [pallet_author_noting, AuthorNoting] - [pallet_collator_assignment, CollatorAssignment] - [pallet_configuration, Configuration] + [pallet_timestamp, Timestamp] + [pallet_sudo, Sudo] + [pallet_proxy, Proxy] + [pallet_utility, Utility] + [pallet_tx_pause, TxPause] + [pallet_balances, Balances] + [pallet_identity, Identity] [pallet_registrar, Registrar] - [pallet_invulnerables, Invulnerables] + [pallet_configuration, Configuration] + [pallet_collator_assignment, CollatorAssignment] + [pallet_author_noting, AuthorNoting] [pallet_services_payment, ServicesPayment] [pallet_data_preservers, DataPreservers] + [pallet_invulnerables, Invulnerables] + [pallet_author_inherent, AuthorInherent] + [pallet_relay_storage_roots, RelayStorageRoots] ); } @@ -1313,10 +1337,19 @@ impl_runtime_apis! { fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig, ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{BenchmarkBatch, Benchmarking}; + use frame_benchmarking::{BenchmarkBatch, Benchmarking, BenchmarkError}; use sp_core::storage::TrackedStorageKey; - impl frame_system_benchmarking::Config for Runtime {} + impl frame_system_benchmarking::Config for Runtime { + fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); + Ok(()) + } + + fn verify_set_code() { + System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); + } + } let whitelist: Vec = vec![ // Block Number diff --git a/runtime/flashbox/src/migrations.rs b/runtime/flashbox/src/migrations.rs index ba3850138..68079b911 100644 --- a/runtime/flashbox/src/migrations.rs +++ b/runtime/flashbox/src/migrations.rs @@ -20,16 +20,137 @@ //! the "Migration" trait declared in the pallet-migrations crate. use { - crate::{ParaId, Runtime, ServicesPayment}, + crate::{ParaId, Runtime, ServicesPayment, LOG_TARGET}, frame_support::{ pallet_prelude::ValueQuery, storage::types::StorageMap, weights::Weight, Blake2_128Concat, }, + pallet_configuration::{weights::WeightInfo as _, HostConfiguration}, pallet_migrations::{GetMigrations, Migration}, sp_core::Get, sp_runtime::BoundedVec, sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*}, }; +#[derive( + Clone, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + PartialEq, + sp_core::RuntimeDebug, + scale_info::TypeInfo, +)] +struct HostConfigurationV1 { + pub max_collators: u32, + pub min_orchestrator_collators: u32, + pub max_orchestrator_collators: u32, + pub collators_per_container: u32, + pub full_rotation_period: u32, +} + +pub struct MigrateConfigurationParathreads(pub PhantomData); +impl Migration for MigrateConfigurationParathreads +where + T: pallet_configuration::Config, +{ + fn friendly_name(&self) -> &str { + "TM_MigrateConfigurationParathreads" + } + + fn migrate(&self, _available_weight: Weight) -> Weight { + log::info!(target: LOG_TARGET, "migrate"); + + const CONFIGURATION_ACTIVE_CONFIG_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"); + const CONFIGURATION_PENDING_CONFIGS_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22d53b4123b2e186e07fb7bad5dda5f55c0"); + let default_config = HostConfiguration::default(); + + // Modify active config + let old_config: HostConfigurationV1 = + frame_support::storage::unhashed::get(CONFIGURATION_ACTIVE_CONFIG_KEY) + .expect("configuration.activeConfig should have value"); + let new_config = HostConfiguration { + max_collators: old_config.max_collators, + min_orchestrator_collators: old_config.min_orchestrator_collators, + max_orchestrator_collators: old_config.max_orchestrator_collators, + collators_per_container: old_config.collators_per_container, + full_rotation_period: old_config.full_rotation_period, + collators_per_parathread: default_config.collators_per_parathread, + parathreads_per_collator: default_config.parathreads_per_collator, + target_container_chain_fullness: default_config.target_container_chain_fullness, + }; + frame_support::storage::unhashed::put(CONFIGURATION_ACTIVE_CONFIG_KEY, &new_config); + + // Modify pending configs, if any + let old_pending_configs: Vec<(u32, HostConfigurationV1)> = + frame_support::storage::unhashed::get(CONFIGURATION_PENDING_CONFIGS_KEY) + .unwrap_or_default(); + let mut new_pending_configs: Vec<(u32, HostConfiguration)> = vec![]; + + for (session_index, old_config) in old_pending_configs { + let new_config = HostConfiguration { + max_collators: old_config.max_collators, + min_orchestrator_collators: old_config.min_orchestrator_collators, + max_orchestrator_collators: old_config.max_orchestrator_collators, + collators_per_container: old_config.collators_per_container, + full_rotation_period: old_config.full_rotation_period, + collators_per_parathread: default_config.collators_per_parathread, + parathreads_per_collator: default_config.parathreads_per_collator, + target_container_chain_fullness: default_config.target_container_chain_fullness, + }; + new_pending_configs.push((session_index, new_config)); + } + + if !new_pending_configs.is_empty() { + frame_support::storage::unhashed::put( + CONFIGURATION_PENDING_CONFIGS_KEY, + &new_pending_configs, + ); + } + + ::WeightInfo::set_config_with_u32() + } + + /// Run a standard pre-runtime test. This works the same way as in a normal runtime upgrade. + #[cfg(feature = "try-runtime")] + fn pre_upgrade(&self) -> Result, sp_runtime::DispatchError> { + const CONFIGURATION_ACTIVE_CONFIG_KEY: &[u8] = + &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385"); + + let old_config_bytes = + frame_support::storage::unhashed::get_raw(CONFIGURATION_ACTIVE_CONFIG_KEY) + .expect("configuration.activeConfig should have value"); + assert_eq!(old_config_bytes.len(), 20); + + use parity_scale_codec::Encode; + Ok((old_config_bytes).encode()) + } + + /// Run a standard post-runtime test. This works the same way as in a normal runtime upgrade. + #[cfg(feature = "try-runtime")] + fn post_upgrade( + &self, + _number_of_invulnerables: Vec, + ) -> Result<(), sp_runtime::DispatchError> { + let new_config = crate::Configuration::config(); + let default_config = HostConfiguration::default(); + assert_eq!( + new_config.collators_per_parathread, + default_config.collators_per_parathread + ); + assert_eq!( + new_config.parathreads_per_collator, + default_config.collators_per_parathread + ); + assert_eq!( + new_config.target_container_chain_fullness, + default_config.target_container_chain_fullness + ); + + Ok(()) + } +} + pub struct MigrateServicesPaymentAddCredits(pub PhantomData); impl Migration for MigrateServicesPaymentAddCredits where @@ -123,10 +244,13 @@ where let migrate_services_payment = MigrateServicesPaymentAddCredits::(Default::default()); let migrate_boot_nodes = MigrateBootNodes::(Default::default()); + let migrate_config_parathread_params = + MigrateConfigurationParathreads::(Default::default()); vec![ Box::new(migrate_services_payment), Box::new(migrate_boot_nodes), + Box::new(migrate_config_parathread_params), ] } } diff --git a/runtime/flashbox/tests/integration_test.rs b/runtime/flashbox/tests/integration_test.rs index 9a620751a..59dd94bb8 100644 --- a/runtime/flashbox/tests/integration_test.rs +++ b/runtime/flashbox/tests/integration_test.rs @@ -95,6 +95,7 @@ fn default_config() -> pallet_configuration::HostConfiguration { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 0, + ..Default::default() } } @@ -604,6 +605,7 @@ fn test_authors_paras_inserted_a_posteriori_with_collators_already_assigned() { max_orchestrator_collators: 5, collators_per_container: 2, full_rotation_period: 0, + ..Default::default() }) .build() .execute_with(|| { @@ -1281,12 +1283,9 @@ fn test_author_collation_aura_add_assigned_to_paras_runtime_api() { run_to_session(4u32); assert_eq!( Runtime::parachain_collators(100.into()), - Some(vec![ALICE.into()]) - ); - assert_eq!( - Runtime::parachain_collators(1001.into()), - Some(vec![CHARLIE.into(), DAVE.into()]) + Some(vec![ALICE.into(), CHARLIE.into()]) ); + assert_eq!(Runtime::parachain_collators(1001.into()), Some(vec![])); assert_eq!( Runtime::current_collator_parachain_assignment(BOB.into()), None @@ -2378,6 +2377,7 @@ fn test_reward_to_invulnerable() { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 0, + ..Default::default() }) .build() .execute_with(|| { @@ -2438,6 +2438,7 @@ fn test_reward_to_invulnerable_with_key_change() { max_orchestrator_collators: 2, collators_per_container: 2, full_rotation_period: 0, + ..Default::default() }) .build() .execute_with(|| { diff --git a/test/scripts/build-spec-warp-sync.sh b/test/scripts/build-spec-warp-sync.sh index ec4e70c49..0215a1942 100755 --- a/test/scripts/build-spec-warp-sync.sh +++ b/test/scripts/build-spec-warp-sync.sh @@ -8,4 +8,4 @@ cd $(dirname $0)/.. mkdir -p specs ../target/release/container-chain-template-simple-node build-spec --disable-default-bootnode --add-bootnode "/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" --parachain-id 2000 --raw > specs/warp-sync-template-container-2000.json -../target/release/tanssi-node build-spec --chain dancebox-local --parachain-id 1000 --add-container-chain specs/warp-sync-template-container-2000.json --invulnerable "Collator1000-01" --invulnerable "Collator1000-02" --invulnerable "Collator2000-01" --invulnerable "Collator2000-02" --invulnerable "Collator1000-03" > specs/warp-sync-tanssi-1000.json +../target/release/tanssi-node build-spec --chain dancebox-local --parachain-id 1000 --add-container-chain specs/warp-sync-template-container-2000.json --invulnerable "Collator1000-01" --invulnerable "Collator1000-02" --invulnerable "Collator1000-03" --invulnerable "Collator2000-01" --invulnerable "Collator2000-02" > specs/warp-sync-tanssi-1000.json diff --git a/test/scripts/build-spec.sh b/test/scripts/build-spec.sh index d95622194..b02ab2375 100755 --- a/test/scripts/build-spec.sh +++ b/test/scripts/build-spec.sh @@ -10,4 +10,4 @@ mkdir -p specs ../target/release/container-chain-template-simple-node build-spec --disable-default-bootnode --add-bootnode "/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" --parachain-id 2000 --raw > specs/template-container-2000.json ../target/release/container-chain-template-frontier-node build-spec --disable-default-bootnode --add-bootnode "/ip4/127.0.0.1/tcp/33050/ws/p2p/12D3KooWFGaw1rxB6MSuN3ucuBm7hMq5pBFJbEoqTyth4cG483Cc" --parachain-id 2001 --raw > specs/template-container-2001.json ../target/release/container-chain-template-simple-node build-spec --disable-default-bootnode --parachain-id 2002 --raw > specs/template-container-2002.json -../target/release/tanssi-node build-spec --chain dancebox-local --parachain-id 1000 --add-container-chain specs/template-container-2000.json --add-container-chain specs/template-container-2001.json --invulnerable "Collator1000-01" --invulnerable "Collator1000-02" --invulnerable "Collator2000-01" --invulnerable "Collator2000-02" --invulnerable "Collator2001-01" --invulnerable "Collator2001-02" --invulnerable "Collator2002-01" --invulnerable "Collator2002-02" > specs/tanssi-1000.json +../target/release/tanssi-node build-spec --chain dancebox-local --parachain-id 1000 --add-container-chain specs/template-container-2000.json --add-container-chain specs/template-container-2001.json --invulnerable "Collator1000-01" --invulnerable "Collator1000-02" --invulnerable "Collator2002-01" --invulnerable "Collator2002-02" --invulnerable "Collator2000-01" --invulnerable "Collator2000-02" --invulnerable "Collator2001-01" --invulnerable "Collator2001-02" > specs/tanssi-1000.json diff --git a/test/suites/common-tanssi/pallet-configuration/test-active-config-target-fullness.ts b/test/suites/common-tanssi/pallet-configuration/test-active-config-target-fullness.ts new file mode 100644 index 000000000..8d3ed96a2 --- /dev/null +++ b/test/suites/common-tanssi/pallet-configuration/test-active-config-target-fullness.ts @@ -0,0 +1,33 @@ +import { expect, beforeAll, describeSuite } from "@moonwall/cli"; +import { jumpSessions } from "../../../util/block"; + +describeSuite({ + id: "CT0406", + title: "Configuration - ActiveConfig - targetContainerChainFullness", + foundationMethods: "dev", + testCases: ({ context, it }) => { + beforeAll(async function () { + const config = await context.polkadotJs().query.configuration.activeConfig(); + expect(config["targetContainerChainFullness"].toString()).toBe("800000000"); + + const { result } = await context.createBlock( + context + .polkadotJs() + .tx.sudo.sudo(context.polkadotJs().tx.configuration.setTargetContainerChainFullness(500000000n)) + .signAsync(context.keyring.alice) + ); + expect(result!.successful, result!.error?.name).to.be.true; + + await jumpSessions(context, 2); + }); + + it({ + id: "T01", + title: "should set target fullness after 2 sessions", + test: async function () { + const config = await context.polkadotJs().query.configuration.activeConfig(); + expect(config["targetContainerChainFullness"].toString()).toBe("500000000"); + }, + }); + }, +}); diff --git a/test/suites/common-tanssi/relay-storage-roots/test_pallet_storage_roots.ts b/test/suites/common-tanssi/relay-storage-roots/test_pallet_storage_roots.ts new file mode 100644 index 000000000..546137572 --- /dev/null +++ b/test/suites/common-tanssi/relay-storage-roots/test_pallet_storage_roots.ts @@ -0,0 +1,45 @@ +import "@tanssi/api-augment"; +import { describeSuite, expect, beforeAll } from "@moonwall/cli"; +import { ApiPromise } from "@polkadot/api"; + +describeSuite({ + id: "CT0801", + title: "RelayStorageRoots pallet test suite", + foundationMethods: "dev", + + testCases: ({ it, context }) => { + let polkadotJs: ApiPromise; + + beforeAll(async () => { + polkadotJs = context.polkadotJs(); + }); + + it({ + id: "E01", + title: "Only 10 latest blocks are stored", + test: async function () { + // Relay block list starts empty + const relayBlocksEmpty = (await polkadotJs.query.relayStorageRoots.relayStorageRootKeys()).toJSON(); + expect(relayBlocksEmpty).to.deep.equal([]); + + // Create 30 blocks + for (let i = 0; i < 20; i++) { + await context.createBlock(); + } + + // Only latest 10 will be stored + // relay_block_number = tanssi_block_number * 2 + 1000 + const relayBlocks = (await polkadotJs.query.relayStorageRoots.relayStorageRootKeys()).toJSON(); + expect(relayBlocks).to.deep.equal([1020, 1022, 1024, 1026, 1028, 1030, 1032, 1034, 1036, 1038]); + + // The mapping only contains the keys that are in `relayStorageRootKeys` + const mappingKeys = (await polkadotJs.query.relayStorageRoots.relayStorageRoot.keys()).map((key) => { + // Convert "1,020" into 1020 + return parseInt(key.toHuman().toString().replace(",", "")); + }); + mappingKeys.sort(); + expect(relayBlocks).to.deep.equal(mappingKeys); + }, + }); + }, +}); diff --git a/test/suites/dev-tanssi/session-keys/test_remove_session_key_staking.ts b/test/suites/dev-tanssi/session-keys/test_remove_session_key_staking.ts index be36e8601..3b64c8970 100644 --- a/test/suites/dev-tanssi/session-keys/test_remove_session_key_staking.ts +++ b/test/suites/dev-tanssi/session-keys/test_remove_session_key_staking.ts @@ -3,7 +3,7 @@ import { describeSuite, expect, beforeAll } from "@moonwall/cli"; import { KeyringPair } from "@moonwall/util"; import { ApiPromise } from "@polkadot/api"; import { jumpSessions } from "../../../util/block"; -import { DANCE, STAKING_ACCOUNT } from "util/constants"; +import { DANCE } from "util/constants"; describeSuite({ id: "DT0202", @@ -13,10 +13,12 @@ describeSuite({ let polkadotJs: ApiPromise; let alice: KeyringPair; let bob: KeyringPair; + let charlie: KeyringPair; beforeAll(async () => { alice = context.keyring.alice; bob = context.keyring.bob; + charlie = context.keyring.charlie; polkadotJs = context.polkadotJs(); let aliceNonce = (await polkadotJs.rpc.system.accountNextIndex(alice.address)).toNumber(); @@ -25,16 +27,13 @@ describeSuite({ // We need to remove from invulnerables and add to staking // for that we need to remove Alice and Bob from invulnerables first - // Additionally, we need to pass to the staking account the minimum balance // We delegate with manual rewards to make sure the candidate does not update position - const existentialDeposit = polkadotJs.consts.balances.existentialDeposit; - + // We also need charlie to join staking because the settings for the dev environment are 1 collator for + // tanssi and 2 collators for containers, so we need 3 collators for bob to be assigned. await context.createBlock([ + // Remove all invulnerables, otherwise they have priority await polkadotJs.tx.sudo - .sudo(polkadotJs.tx.invulnerables.removeInvulnerable(alice.address)) - .signAsync(context.keyring.alice, { nonce: aliceNonce++ }), - await polkadotJs.tx.sudo - .sudo(polkadotJs.tx.invulnerables.removeInvulnerable(bob.address)) + .sudo(polkadotJs.tx.invulnerables.setInvulnerables([])) .signAsync(context.keyring.alice, { nonce: aliceNonce++ }), await polkadotJs.tx.pooledStaking .requestDelegate(alice.address, "ManualRewards", 10000n * DANCE) @@ -42,9 +41,9 @@ describeSuite({ await polkadotJs.tx.pooledStaking .requestDelegate(bob.address, "ManualRewards", 10000n * DANCE) .signAsync(context.keyring.bob, { nonce: bobNonce++ }), - await polkadotJs.tx.balances - .transferAllowDeath(STAKING_ACCOUNT, existentialDeposit) - .signAsync(context.keyring.bob, { nonce: bobNonce++ }), + await polkadotJs.tx.pooledStaking + .requestDelegate(charlie.address, "ManualRewards", 10000n * DANCE) + .signAsync(context.keyring.charlie, { nonce: 0 }), ]); // At least 2 sessions for the change to have effect await jumpSessions(context, 2); diff --git a/test/suites/dev-tanssi/staking/test_staking_rewards_balanced.ts b/test/suites/dev-tanssi/staking/test_staking_rewards_balanced.ts index ce2c1ac74..07d80f50b 100644 --- a/test/suites/dev-tanssi/staking/test_staking_rewards_balanced.ts +++ b/test/suites/dev-tanssi/staking/test_staking_rewards_balanced.ts @@ -9,7 +9,7 @@ import { filterRewardStakingDelegators, jumpSessions, } from "util/block"; -import { DANCE, STAKING_ACCOUNT } from "util/constants"; +import { DANCE } from "util/constants"; describeSuite({ id: "DT0302", @@ -32,15 +32,10 @@ describeSuite({ // we will make each of them delegate the other with 50% // Alice autocompounding, Bob will be manual - // Additionally, we need to pass to the staking account the minimum balance - const existentialDeposit = polkadotJs.consts.balances.existentialDeposit; - await context.createBlock([ + // Remove all invulnerables, otherwise they have priority await polkadotJs.tx.sudo - .sudo(polkadotJs.tx.invulnerables.removeInvulnerable(alice.address)) - .signAsync(context.keyring.alice, { nonce: aliceNonce++ }), - await polkadotJs.tx.sudo - .sudo(polkadotJs.tx.invulnerables.removeInvulnerable(bob.address)) + .sudo(polkadotJs.tx.invulnerables.setInvulnerables([])) .signAsync(context.keyring.alice, { nonce: aliceNonce++ }), await polkadotJs.tx.pooledStaking .requestDelegate(alice.address, "AutoCompounding", 10000n * DANCE) @@ -54,9 +49,6 @@ describeSuite({ await polkadotJs.tx.pooledStaking .requestDelegate(bob.address, "ManualRewards", 10000n * DANCE) .signAsync(context.keyring.bob, { nonce: bobNonce++ }), - await polkadotJs.tx.balances - .transferAllowDeath(STAKING_ACCOUNT, existentialDeposit) - .signAsync(context.keyring.bob, { nonce: bobNonce++ }), ]); // At least 2 sessions for the change to have effect await jumpSessions(context, 2); diff --git a/test/suites/dev-tanssi/staking/test_staking_rewards_non_balanced.ts b/test/suites/dev-tanssi/staking/test_staking_rewards_non_balanced.ts index b2b2174b3..7b57ee5c5 100644 --- a/test/suites/dev-tanssi/staking/test_staking_rewards_non_balanced.ts +++ b/test/suites/dev-tanssi/staking/test_staking_rewards_non_balanced.ts @@ -9,7 +9,7 @@ import { filterRewardStakingDelegators, jumpSessions, } from "util/block"; -import { DANCE, STAKING_ACCOUNT } from "util/constants"; +import { DANCE } from "util/constants"; describeSuite({ id: "DT0303", @@ -32,15 +32,10 @@ describeSuite({ // we will make each of them delegate the other with 50% // Alice autocompounding, Bob will be manual - // Additionally, we need to pass to the staking account the minimum balance - const existentialDeposit = polkadotJs.consts.balances.existentialDeposit; - await context.createBlock([ + // Remove all invulnerables, otherwise they have priority await polkadotJs.tx.sudo - .sudo(polkadotJs.tx.invulnerables.removeInvulnerable(alice.address)) - .signAsync(context.keyring.alice, { nonce: aliceNonce++ }), - await polkadotJs.tx.sudo - .sudo(polkadotJs.tx.invulnerables.removeInvulnerable(bob.address)) + .sudo(polkadotJs.tx.invulnerables.setInvulnerables([])) .signAsync(context.keyring.alice, { nonce: aliceNonce++ }), await polkadotJs.tx.pooledStaking .requestDelegate(alice.address, "AutoCompounding", 18000n * DANCE) @@ -54,9 +49,6 @@ describeSuite({ await polkadotJs.tx.pooledStaking .requestDelegate(bob.address, "ManualRewards", 2000n * DANCE) .signAsync(context.keyring.bob, { nonce: bobNonce++ }), - await polkadotJs.tx.balances - .transferAllowDeath(STAKING_ACCOUNT, existentialDeposit) - .signAsync(context.keyring.bob, { nonce: bobNonce++ }), ]); // At least 2 sessions for the change to have effect await jumpSessions(context, 2); diff --git a/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception.ts b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception.ts new file mode 100644 index 000000000..6ba3ad5cb --- /dev/null +++ b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception.ts @@ -0,0 +1,163 @@ +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair, alith } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { u8aToHex } from "@polkadot/util"; + +import { RawXcmMessage, XcmFragment, injectDmpMessageAndSeal } from "../../../util/xcm.ts"; +import { RELAY_SOURCE_LOCATION, RELAY_SOURCE_LOCATION_2 } from "../../../util/constants.ts"; + +describeSuite({ + id: "TX0101", + title: "Mock XCM - Succeeds receiving tokens DMP", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let polkadotJs: ApiPromise; + let transferredBalance; + let alice: KeyringPair; + let chain; + + beforeAll(async function () { + polkadotJs = context.polkadotJs(); + chain = polkadotJs.consts.system.version.specName.toString(); + // since in the future is likely that we are going to add this to containers, I leave it here + alice = + chain == "frontier-template" + ? alith + : new Keyring({ type: "sr25519" }).addFromUri("//Alice", { + name: "Alice default", + }); + + transferredBalance = 10_000_000_000_000n; + + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.utility.batch([ + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + RELAY_SOURCE_LOCATION, + 1, + alice.address, + true, + 1 + ), + polkadotJs.tx.assetRate.create( + 1, + // this defines how much the asset costs with respect to the + // new asset + // in this case, asset*2=native + // that means that we will charge 0.5 of the native balance + 2000000000000000000n + ), + ]) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + }); + + it({ + id: "T01", + title: "Should succeed receiving tokens", + test: async function () { + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + multilocation: { + parents: 1, + interior: { Here: null }, + }, + fungible: transferredBalance, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .clear_origin() + .buy_execution() + .deposit_asset() + .as_v3(); + + // Send an XCM and create block to execute it + await injectDmpMessageAndSeal(context, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has ALITH's to DOT tokens + const alice_dot_balance = (await context.polkadotJs().query.foreignAssets.account(1, alice.address)) + .unwrap() + .balance.toBigInt(); + expect(alice_dot_balance > 0n).to.be.true; + // we should expect to have received less than the amount transferred + expect(alice_dot_balance < transferredBalance).to.be.true; + }, + }); + + it({ + id: "T02", + title: "Should not succeed receiving tokens if asset rate is not defined", + test: async function () { + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + RELAY_SOURCE_LOCATION_2, + // id 2 + 2, + alice.address, + true, + 1 + ) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + // we change parents to 2 + multilocation: { + parents: 2, + interior: { Here: null }, + }, + fungible: 10000000000000n, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .clear_origin() + .buy_execution() + .deposit_asset() + .as_v3(); + + // Send an XCM and create block to execute it + await injectDmpMessageAndSeal(context, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has not ALITH's DOT_2 tokens + const alice_dot_2_balance = await context.polkadotJs().query.foreignAssets.account(2, alice.address); + expect(alice_dot_2_balance.isNone).to.be.true; + }, + }); + }, +}); diff --git a/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_appendix.ts b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_appendix.ts new file mode 100644 index 000000000..c2abbab22 --- /dev/null +++ b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_appendix.ts @@ -0,0 +1,107 @@ +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair, alith } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { u8aToHex } from "@polkadot/util"; + +import { RawXcmMessage, XcmFragment, injectDmpMessageAndSeal } from "../../../util/xcm.ts"; +import { RELAY_SOURCE_LOCATION } from "../../../util/constants.ts"; + +describeSuite({ + id: "TX0103", + title: "Mock XCM - downward transfer with always triggered appendix", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let polkadotJs: ApiPromise; + let transferredBalance; + let alice: KeyringPair; + let chain; + + beforeAll(async function () { + polkadotJs = context.polkadotJs(); + chain = polkadotJs.consts.system.version.specName.toString(); + // since in the future is likely that we are going to add this to containers, I leave it here + alice = + chain == "frontier-template" + ? alith + : new Keyring({ type: "sr25519" }).addFromUri("//Alice", { + name: "Alice default", + }); + + transferredBalance = 10_000_000_000_000n; + + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.utility.batch([ + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + RELAY_SOURCE_LOCATION, + 1, + alice.address, + true, + 1 + ), + polkadotJs.tx.assetRate.create( + 1, + // this defines how much the asset costs with respect to the + // new asset + // in this case, asset*2=native + // that means that we will charge 0.5 of the native balance + 2000000000000000000n + ), + ]) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + }); + + it({ + id: "T01", + title: "Should make sure Alice receives 10 dot with appendix and without error", + test: async function () { + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + multilocation: { + parents: 1, + interior: { Here: null }, + }, + fungible: transferredBalance, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .clear_origin() + .buy_execution() + // Set an appendix to be executed after the XCM message is executed. No matter if errors + .with(function () { + return this.set_appendix_with([this.deposit_asset_v3]); + }) + .as_v3(); + + // Send an XCM and create block to execute it + await injectDmpMessageAndSeal(context, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has Alice's DOT tokens + const alice_dot_balance = (await context.polkadotJs().query.foreignAssets.account(1, alice.address)) + .unwrap() + .balance.toBigInt(); + expect(alice_dot_balance > 0n).to.be.true; + // we should expect to have received less than the amount transferred + expect(alice_dot_balance < transferredBalance).to.be.true; + }, + }); + }, +}); diff --git a/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_appendix_2.ts b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_appendix_2.ts new file mode 100644 index 000000000..f5553dd4e --- /dev/null +++ b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_appendix_2.ts @@ -0,0 +1,108 @@ +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair, alith } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { u8aToHex } from "@polkadot/util"; + +import { RawXcmMessage, XcmFragment, injectDmpMessageAndSeal } from "../../../util/xcm.ts"; +import { RELAY_SOURCE_LOCATION } from "../../../util/constants.ts"; + +describeSuite({ + id: "TX0103", + title: "Mock XCM - downward transfer with always triggered appendix", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let polkadotJs: ApiPromise; + let transferredBalance; + let alice: KeyringPair; + let chain; + + beforeAll(async function () { + polkadotJs = context.polkadotJs(); + chain = polkadotJs.consts.system.version.specName.toString(); + // since in the future is likely that we are going to add this to containers, I leave it here + alice = + chain == "frontier-template" + ? alith + : new Keyring({ type: "sr25519" }).addFromUri("//Alice", { + name: "Alice default", + }); + + transferredBalance = 10_000_000_000_000n; + + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.utility.batch([ + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + RELAY_SOURCE_LOCATION, + 1, + alice.address, + true, + 1 + ), + polkadotJs.tx.assetRate.create( + 1, + // this defines how much the asset costs with respect to the + // new asset + // in this case, asset*2=native + // that means that we will charge 0.5 of the native balance + 2000000000000000000n + ), + ]) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + }); + + it({ + id: "T01", + title: "Should make sure Alice receives 10 dot with appendix and without error", + test: async function () { + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + multilocation: { + parents: 1, + interior: { Here: null }, + }, + fungible: transferredBalance, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .clear_origin() + .buy_execution() + // Set an appendix to be executed after the XCM message is executed. No matter if errors + .with(function () { + return this.set_appendix_with([this.deposit_asset_v3]); + }) + .trap() + .as_v3(); + + // Send an XCM and create block to execute it + await injectDmpMessageAndSeal(context, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has Alice's DOT tokens + const alice_dot_balance = (await context.polkadotJs().query.foreignAssets.account(1, alice.address)) + .unwrap() + .balance.toBigInt(); + expect(alice_dot_balance > 0n).to.be.true; + // we should expect to have received less than the amount transferred + expect(alice_dot_balance < transferredBalance).to.be.true; + }, + }); + }, +}); diff --git a/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_error_handler.ts b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_error_handler.ts new file mode 100644 index 000000000..eccefe49c --- /dev/null +++ b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_error_handler.ts @@ -0,0 +1,95 @@ +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair, alith } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { u8aToHex } from "@polkadot/util"; + +import { RawXcmMessage, XcmFragment, injectDmpMessageAndSeal } from "../../../util/xcm.ts"; +import { RELAY_SOURCE_LOCATION } from "../../../util/constants.ts"; + +describeSuite({ + id: "TX0104", + title: "Mock XCM - downward transfer with non-triggered error handler", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let polkadotJs: ApiPromise; + let transferredBalance; + let alice: KeyringPair; + let chain; + + beforeAll(async function () { + polkadotJs = context.polkadotJs(); + chain = polkadotJs.consts.system.version.specName.toString(); + // since in the future is likely that we are going to add this to containers, I leave it here + alice = + chain == "frontier-template" + ? alith + : new Keyring({ type: "sr25519" }).addFromUri("//Alice", { + name: "Alice default", + }); + + transferredBalance = 10_000_000_000_000n; + + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.utility.batch([ + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + RELAY_SOURCE_LOCATION, + 1, + alice.address, + true, + 1 + ), + ]) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + }); + + it({ + id: "T01", + title: "Should make sure that Alice does not receive 10 dot without error", + test: async function () { + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + multilocation: { + parents: 1, + interior: { Here: null }, + }, + fungible: transferredBalance, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .buy_execution() + + /// Buy execution does not error therefore error handler is not triggered + .with(function () { + return this.set_error_handler_with([this.deposit_asset_v3]); + }) + .as_v3(); + + // Send an XCM and create block to execute it + await injectDmpMessageAndSeal(context, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has not Alice's tokens + const alice_dot_balance = await context.polkadotJs().query.foreignAssets.account(1, alice.address); + expect(alice_dot_balance.isNone).to.be.true; + }, + }); + }, +}); diff --git a/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_error_handler_2.ts b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_error_handler_2.ts new file mode 100644 index 000000000..3d9b3e4d3 --- /dev/null +++ b/test/suites/dev-tanssi/xcm-token-reception/test_dmp_token_reception_error_handler_2.ts @@ -0,0 +1,107 @@ +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair, alith } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { u8aToHex } from "@polkadot/util"; + +import { RawXcmMessage, XcmFragment, injectDmpMessageAndSeal } from "../../../util/xcm.ts"; +import { RELAY_SOURCE_LOCATION } from "../../../util/constants.ts"; + +describeSuite({ + id: "TX0105", + title: "Mock XCM - downward transfer with triggered error handler", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let polkadotJs: ApiPromise; + let transferredBalance; + let alice: KeyringPair; + let chain; + + beforeAll(async function () { + polkadotJs = context.polkadotJs(); + chain = polkadotJs.consts.system.version.specName.toString(); + // since in the future is likely that we are going to add this to containers, I leave it here + alice = + chain == "frontier-template" + ? alith + : new Keyring({ type: "sr25519" }).addFromUri("//Alice", { + name: "Alice default", + }); + + transferredBalance = 10_000_000_000_000n; + + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.utility.batch([ + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + RELAY_SOURCE_LOCATION, + 1, + alice.address, + true, + 1 + ), + polkadotJs.tx.assetRate.create( + 1, + // this defines how much the asset costs with respect to the + // new asset + // in this case, asset*2=native + // that means that we will charge 0.5 of the native balance + 2000000000000000000n + ), + ]) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + }); + + it({ + id: "T01", + title: "Should make sure that Alith does receive 10 dot because there is error", + test: async function () { + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + multilocation: { + parents: 1, + interior: { Here: null }, + }, + fungible: transferredBalance, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .buy_execution() + // Trap makes it error, therefore the handler kicks in + .with(function () { + return this.set_error_handler_with([this.deposit_asset_v3]); + }) + .trap() + .as_v3(); + + // Send an XCM and create block to execute it + await injectDmpMessageAndSeal(context, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has Alice's DOT tokens + const alice_dot_balance = (await context.polkadotJs().query.foreignAssets.account(1, alice.address)) + .unwrap() + .balance.toBigInt(); + expect(alice_dot_balance > 0n).to.be.true; + // we should expect to have received less than the amount transferred + expect(alice_dot_balance < transferredBalance).to.be.true; + }, + }); + }, +}); diff --git a/test/suites/dev-tanssi/xcm-token-reception/test_hrmp_token_reception.ts b/test/suites/dev-tanssi/xcm-token-reception/test_hrmp_token_reception.ts new file mode 100644 index 000000000..8adbf6647 --- /dev/null +++ b/test/suites/dev-tanssi/xcm-token-reception/test_hrmp_token_reception.ts @@ -0,0 +1,106 @@ +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair, alith } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { u8aToHex } from "@polkadot/util"; + +import { RawXcmMessage, XcmFragment, injectHrmpMessageAndSeal } from "../../../util/xcm.ts"; +import { STATEMINT_LOCATION_EXAMPLE } from "../../../util/constants.ts"; + +describeSuite({ + id: "TX0102", + title: "Mock XCM - Succeeds receiving tokens through HRMP", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let polkadotJs: ApiPromise; + let transferredBalance; + let alice: KeyringPair; + let chain; + + beforeAll(async function () { + polkadotJs = context.polkadotJs(); + chain = polkadotJs.consts.system.version.specName.toString(); + // since in the future is likely that we are going to add this to containers, I leave it here + alice = + chain == "frontier-template" + ? alith + : new Keyring({ type: "sr25519" }).addFromUri("//Alice", { + name: "Alice default", + }); + + transferredBalance = 10_000_000_000_000n; + + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.utility.batch([ + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + STATEMINT_LOCATION_EXAMPLE, + 1, + alice.address, + true, + 1 + ), + polkadotJs.tx.assetRate.create( + 1, + // this defines how much the asset costs with respect to the + // new asset + // in this case, asset*2=native + // that means that we will charge 0.5 of the native balance + 2000000000000000000n + ), + ]) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + }); + + it({ + id: "T01", + title: "Should succeed receiving tokens", + test: async function () { + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + multilocation: { + parents: 1, + interior: { + X3: [{ Parachain: 1000 }, { PalletInstance: 50 }, { GeneralIndex: 0n }], + }, + }, + fungible: transferredBalance, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .clear_origin() + .buy_execution() + .deposit_asset() + .as_v3(); + + // Send an XCM and create block to execute it + await injectHrmpMessageAndSeal(context, 1000, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has Alice's tatemint tokens + const alice_statemint_balance = ( + await context.polkadotJs().query.foreignAssets.account(1, alice.address) + ) + .unwrap() + .balance.toBigInt(); + expect(alice_statemint_balance > 0n).to.be.true; + }, + }); + }, +}); diff --git a/test/suites/dev-tanssi/xcm-token-reception/test_hrmp_token_reception_2.ts b/test/suites/dev-tanssi/xcm-token-reception/test_hrmp_token_reception_2.ts new file mode 100644 index 000000000..6977ce7e5 --- /dev/null +++ b/test/suites/dev-tanssi/xcm-token-reception/test_hrmp_token_reception_2.ts @@ -0,0 +1,103 @@ +import { beforeAll, describeSuite, expect } from "@moonwall/cli"; +import { KeyringPair, alith } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { u8aToHex, hexToBigInt } from "@polkadot/util"; + +import { RawXcmMessage, XcmFragment, injectHrmpMessageAndSeal } from "../../../util/xcm.ts"; +import { STATEMINT_LOCATION_EXAMPLE } from "../../../util/constants.ts"; + +describeSuite({ + id: "TX0106", + title: "Mock XCM - Succeeds receiving tokens through HRMP", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let polkadotJs: ApiPromise; + let transferredBalance; + let alice: KeyringPair; + let chain; + + beforeAll(async function () { + polkadotJs = context.polkadotJs(); + chain = polkadotJs.consts.system.version.specName.toString(); + // since in the future is likely that we are going to add this to containers, I leave it here + alice = + chain == "frontier-template" + ? alith + : new Keyring({ type: "sr25519" }).addFromUri("//Alice", { + name: "Alice default", + }); + + transferredBalance = 10_000_000_000_000n; + + // We register the token + const txSigned = polkadotJs.tx.sudo.sudo( + polkadotJs.tx.utility.batch([ + polkadotJs.tx.foreignAssetsCreator.createForeignAsset( + STATEMINT_LOCATION_EXAMPLE, + 1, + alice.address, + true, + 1 + ), + polkadotJs.tx.assetRate.create( + 1, + // this will make sure we charge a minimum a fee + hexToBigInt("0xffffffffffffffffffffffffffffffff") + ), + ]) + ); + + await context.createBlock(await txSigned.signAsync(alice), { + allowFailures: false, + }); + }); + + it({ + id: "T01", + title: "Should succeed receiving tokens with 1 fee if sufficeintly large rate", + test: async function () { + // Send an XCM and create block to execute it + const xcmMessage = new XcmFragment({ + assets: [ + { + multilocation: { + parents: 1, + interior: { + X3: [{ Parachain: 1000 }, { PalletInstance: 50 }, { GeneralIndex: 0n }], + }, + }, + fungible: transferredBalance, + }, + ], + weight_limit: { + refTime: 4000000000n, + proofSize: 80000n, + } as any, + beneficiary: u8aToHex(alice.addressRaw), + }) + .reserve_asset_deposited() + .clear_origin() + .buy_execution() + .deposit_asset() + .as_v3(); + + // Send an XCM and create block to execute it + await injectHrmpMessageAndSeal(context, 1000, { + type: "XcmVersionedXcm", + payload: xcmMessage, + } as RawXcmMessage); + + // Create a block in which the XCM will be executed + await context.createBlock(); + + // Make sure the state has Alice's tatemint tokens + const alice_statemint_balance = ( + await context.polkadotJs().query.foreignAssets.account(1, alice.address) + ) + .unwrap() + .balance.toBigInt(); + expect(alice_statemint_balance).to.eq(transferredBalance - 1n); + }, + }); + }, +}); diff --git a/test/util/constants.ts b/test/util/constants.ts index 91df6c1bf..44b1fe4a1 100644 --- a/test/util/constants.ts +++ b/test/util/constants.ts @@ -1,3 +1,11 @@ export const PARACHAIN_BOND = "5EYCAe5cJkHcthonN7KrsVp11XYHMqtrFPimDd3Af755ET2D"; export const DANCE = 1_000_000_000_000n; export const STAKING_ACCOUNT = "5EYCAe5cHvXp3GAe94dYPGjLqQdn7cnYuENAn66SntQkNTAG"; +export const RELAY_SOURCE_LOCATION = { parents: 1, interior: "Here" }; +export const RELAY_SOURCE_LOCATION_2 = { parents: 2, interior: "Here" }; +export const STATEMINT_LOCATION_EXAMPLE = { + parents: 1, + interior: { + X3: [{ Parachain: 1000 }, { PalletInstance: 50 }, { GeneralIndex: 0n }], + }, +}; diff --git a/tools/benchmarking-template-simple.sh b/tools/benchmarking-template-simple.sh deleted file mode 100755 index 953cbdbde..000000000 --- a/tools/benchmarking-template-simple.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash - -# This script can be used for running moonbeam's benchmarks. -# -# The moonbeam binary is required to be compiled with --features=runtime-benchmarks -# in release mode. - -set -e - -BINARY="./target/release/container-chain-template-simple-node" -STEPS=50 -REPEAT=20 - -if [[ ! -f "${BINARY}" ]]; then - echo "binary '${BINARY}' does not exist." - echo "ensure that the container-chain-template-simple-node binary is compiled with '--features=runtime-benchmarks' and in release mode." - exit 1 -fi - -function help { - echo "USAGE:" - echo " ${0} [ ] [--check]" - echo "" - echo "EXAMPLES:" - echo " ${0} " "list all benchmarks and provide a selection to choose from" - echo " ${0} --check " "list all benchmarks and provide a selection to choose from, runs in 'check' mode (reduced steps and repetitions)" - echo " ${0} foo bar " "run a benchmark for pallet 'foo' and benchmark 'bar'" - echo " ${0} foo bar --check " "run a benchmark for pallet 'foo' and benchmark 'bar' in 'check' mode (reduced steps and repetitions)" - echo " ${0} foo bar --all " "run a benchmark for all pallets" - echo " ${0} foo bar --all --check " "run a benchmark for all pallets in 'check' mode (reduced steps and repetitions)" -} - -function choose_and_bench { - readarray -t options < <(${BINARY} benchmark pallet --list | sed 1d) - options+=('EXIT') - - select opt in "${options[@]}"; do - IFS=', ' read -ra parts <<< "${opt}" - [[ "${opt}" == 'EXIT' ]] && exit 0 - - bench "${parts[0]}" "${parts[1]}" "${1}" - break - done -} - -function bench { - OUTPUT=${4:-weights.rs} - echo "benchmarking '${1}::${2}' --check=${3}, writing results to '${OUTPUT}'" - - # Check enabled - if [[ "${3}" -eq 1 ]]; then - STEPS=16 - REPEAT=1 - fi - - WASMTIME_BACKTRACE_DETAILS=1 ${BINARY} benchmark pallet \ - --execution=wasm \ - --wasm-execution=compiled \ - --pallet "${1}" \ - --extrinsic "${2}" \ - --steps "${STEPS}" \ - --repeat "${REPEAT}" \ - --template=./benchmarking/frame-weight-template.hbs \ - --json-file raw.json \ - --output "${OUTPUT}" -} - -if [[ "${@}" =~ "--help" ]]; then - help -else - CHECK=0 - if [[ "${@}" =~ "--check" ]]; then - CHECK=1 - set -o noglob && set -- ${@/'--check'} && set +o noglob - fi - - ALL=0 - if [[ "${@}" =~ "--all" ]]; then - ALL=1 - fi - - if [[ "${ALL}" -eq 1 ]]; then - mkdir -p weights/ - bench '*' '*' "${CHECK}" "weights/" - elif [[ $# -ne 2 ]]; then - choose_and_bench "${CHECK}" - else - bench "${1}" "${2}" "${CHECK}" - fi -fi diff --git a/tools/benchmarking.sh b/tools/benchmarking.sh index 8b6c51ea3..ae7231dbb 100755 --- a/tools/benchmarking.sh +++ b/tools/benchmarking.sh @@ -1,13 +1,34 @@ #!/usr/bin/env bash -# This script can be used for running moonbeam's benchmarks. +# This script can be used for running tanssi's benchmarks. # -# The moonbeam binary is required to be compiled with --features=runtime-benchmarks +# The tanssi binary is required to be compiled with --features=runtime-benchmarks # in release mode. set -e -BINARY="./target/production/tanssi-node" +# By default we use the tanssi-node release binary +# However we can use any binary by running the benchmark tool with +# BINARY=./target/release/container-chain-template-simple-node ./tools/benchmarking.sh +if [[ -z "${BINARY}" ]]; then + BINARY="./target/release/tanssi-node" +else + BINARY="${BINARY}" +fi + +if [[ -z "${CHAIN}" ]]; then + CHAIN="dev" +else + CHAIN="${CHAIN}" +fi + +if [[ -z "${OUTPUT_PATH}" ]]; then + mkdir -p tmp + OUTPUT_PATH="tmp" +else + OUTPUT_PATH="${OUTPUT_PATH}" +fi + STEPS=50 REPEAT=20 @@ -32,7 +53,7 @@ function help { } function choose_and_bench { - readarray -t options < <(${BINARY} benchmark pallet --list | sed 1d) + readarray -t options < <(${BINARY} benchmark pallet --chain=${CHAIN} --list | sed 1d) options+=('EXIT') select opt in "${options[@]}"; do @@ -45,25 +66,51 @@ function choose_and_bench { } function bench { - OUTPUT=${4:-weights.rs} + OUTPUT="${OUTPUT_PATH}/${1}.rs" echo "benchmarking '${1}::${2}' --check=${3}, writing results to '${OUTPUT}'" - # Check enabled if [[ "${3}" -eq 1 ]]; then STEPS=16 REPEAT=1 fi - - WASMTIME_BACKTRACE_DETAILS=1 ${BINARY} benchmark pallet \ - --execution=wasm \ - --wasm-execution=compiled \ - --pallet "${1}" \ - --extrinsic "${2}" \ - --steps "${STEPS}" \ - --repeat "${REPEAT}" \ - --template=./benchmarking/frame-weight-template.hbs \ - --json-file raw.json \ - --output "${OUTPUT}" + echo "${1}" + if [[ ${1} == "*" ]] ; then + # Load all pallet names in an array. + ALL_PALLETS=($( + $BINARY benchmark pallet --list --chain="${CHAIN}" |\ + tail -n+2 |\ + cut -d',' -f1 |\ + sort |\ + uniq + )) + echo "[+] Benchmarking ${#ALL_PALLETS[@]} pallets" + for PALLET in "${ALL_PALLETS[@]}"; do + OUTPUT="${OUTPUT_PATH}/$PALLET.rs" + WASMTIME_BACKTRACE_DETAILS=1 ${BINARY} benchmark pallet \ + --execution=wasm \ + --wasm-execution=compiled \ + --pallet "$PALLET" \ + --extrinsic "*" \ + --chain="${CHAIN}" \ + --steps "${STEPS}" \ + --repeat "${REPEAT}" \ + --template=./benchmarking/frame-weight-template.hbs \ + --json-file raw.json \ + --output "${OUTPUT}" + done + else + WASMTIME_BACKTRACE_DETAILS=1 ${BINARY} benchmark pallet \ + --execution=wasm \ + --wasm-execution=compiled \ + --pallet "${1}" \ + --extrinsic "${2}" \ + --chain="${CHAIN}" \ + --steps "${STEPS}" \ + --repeat "${REPEAT}" \ + --template=./benchmarking/frame-weight-template.hbs \ + --json-file raw.json \ + --output "${OUTPUT}" + fi } if [[ "${@}" =~ "--help" ]]; then diff --git a/typescript-api/package.json b/typescript-api/package.json index 8eb6ca500..e0b47f318 100644 --- a/typescript-api/package.json +++ b/typescript-api/package.json @@ -1,6 +1,6 @@ { "name": "@tanssi/api-augment", - "version": "0.300.0", + "version": "0.400.0", "type": "module", "description": "Tanssi types augment for @polkadot/api", "author": "Moondance-labs", diff --git a/typescript-api/src/dancebox/interfaces/augment-api-consts.ts b/typescript-api/src/dancebox/interfaces/augment-api-consts.ts index 553fb0fe0..748e4c31c 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-consts.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-consts.ts @@ -41,6 +41,28 @@ declare module "@polkadot/api-base/types/consts" { /** Generic const */ [key: string]: Codec; }; + foreignAssets: { + /** The amount of funds that must be reserved when creating a new approval. */ + approvalDeposit: u128 & AugmentedConst; + /** The amount of funds that must be reserved for a non-provider asset account to be maintained. */ + assetAccountDeposit: u128 & AugmentedConst; + /** The basic amount of funds that must be reserved for an asset. */ + assetDeposit: u128 & AugmentedConst; + /** The basic amount of funds that must be reserved when adding metadata to your asset. */ + metadataDepositBase: u128 & AugmentedConst; + /** The additional funds that must be reserved for the number of bytes you store in your metadata. */ + metadataDepositPerByte: u128 & AugmentedConst; + /** + * Max number of items to destroy per `destroy_accounts` and `destroy_approvals` call. + * + * Must be configured to result in a weight that makes each call fit in a block. + */ + removeItemsLimit: u32 & AugmentedConst; + /** The maximum length of a name or symbol stored on-chain. */ + stringLimit: u32 & AugmentedConst; + /** Generic const */ + [key: string]: Codec; + }; identity: { /** The amount held on deposit for a registered identity */ basicDeposit: u128 & AugmentedConst; @@ -108,6 +130,16 @@ declare module "@polkadot/api-base/types/consts" { /** Generic const */ [key: string]: Codec; }; + relayStorageRoots: { + /** + * Limit the number of relay storage roots that will be stored. This limit applies to the number of items, not to + * their age. Decreasing the value of `MaxStorageRoots` is a breaking change and needs a migration to clean the + * `RelayStorageRoots` mapping. + */ + maxStorageRoots: u32 & AugmentedConst; + /** Generic const */ + [key: string]: Codec; + }; system: { /** Maximum number of block number to block hash mappings to keep (oldest pruned first). */ blockHashCount: u32 & AugmentedConst; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts index 9caf1d4d6..fb8199d96 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts @@ -11,6 +11,14 @@ export type __AugmentedError = AugmentedError declare module "@polkadot/api-base/types/errors" { interface AugmentedErrors { + assetRate: { + /** The given asset ID already has an assigned conversion rate and cannot be re-created. */ + AlreadyExists: AugmentedError; + /** The given asset ID is unknown. */ + UnknownAssetKind: AugmentedError; + /** Generic error */ + [key: string]: AugmentedError; + }; authorInherent: { /** Author already set in block. */ AuthorAlreadySet: AugmentedError; @@ -81,6 +89,63 @@ declare module "@polkadot/api-base/types/errors" { /** Generic error */ [key: string]: AugmentedError; }; + foreignAssets: { + /** The asset-account already exists. */ + AlreadyExists: AugmentedError; + /** The asset is not live, and likely being destroyed. */ + AssetNotLive: AugmentedError; + /** Invalid metadata given. */ + BadMetadata: AugmentedError; + /** Invalid witness data given. */ + BadWitness: AugmentedError; + /** Account balance must be greater than or equal to the transfer amount. */ + BalanceLow: AugmentedError; + /** Callback action resulted in error */ + CallbackFailed: AugmentedError; + /** The origin account is frozen. */ + Frozen: AugmentedError; + /** The asset status is not the expected status. */ + IncorrectStatus: AugmentedError; + /** The asset ID is already taken. */ + InUse: AugmentedError; + /** + * The asset is a live asset and is actively being used. Usually emit for operations such as `start_destroy` which + * require the asset to be in a destroying state. + */ + LiveAsset: AugmentedError; + /** Minimum balance should be non-zero. */ + MinBalanceZero: AugmentedError; + /** The account to alter does not exist. */ + NoAccount: AugmentedError; + /** The asset-account doesn't have an associated deposit. */ + NoDeposit: AugmentedError; + /** The signing account has no permission to do the operation. */ + NoPermission: AugmentedError; + /** The asset should be frozen before the given operation. */ + NotFrozen: AugmentedError; + /** No approval exists that would allow the transfer. */ + Unapproved: AugmentedError; + /** + * Unable to increment the consumer reference counters on the account. Either no provider reference exists to + * allow a non-zero balance of a non-self-sufficient asset, or one fewer then the maximum number of consumers has + * been reached. + */ + UnavailableConsumer: AugmentedError; + /** The given asset ID is unknown. */ + Unknown: AugmentedError; + /** The operation would result in funds being burned. */ + WouldBurn: AugmentedError; + /** The source account would not survive the transfer and it needs to stay alive. */ + WouldDie: AugmentedError; + /** Generic error */ + [key: string]: AugmentedError; + }; + foreignAssetsCreator: { + AssetAlreadyExists: AugmentedError; + AssetDoesNotExist: AugmentedError; + /** Generic error */ + [key: string]: AugmentedError; + }; identity: { /** Account ID is already named. */ AlreadyClaimed: AugmentedError; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-events.ts b/typescript-api/src/dancebox/interfaces/augment-api-events.ts index 2ae79ede9..50b0e88ed 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-events.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-events.ts @@ -30,6 +30,17 @@ export type __AugmentedEvent = AugmentedEvent declare module "@polkadot/api-base/types/events" { interface AugmentedEvents { + assetRate: { + AssetRateCreated: AugmentedEvent; + AssetRateRemoved: AugmentedEvent; + AssetRateUpdated: AugmentedEvent< + ApiType, + [assetKind: u16, old: u128, new_: u128], + { assetKind: u16; old: u128; new_: u128 } + >; + /** Generic event */ + [key: string]: AugmentedEvent; + }; authorNoting: { /** Latest author changed */ LatestAuthorChanged: AugmentedEvent< @@ -196,6 +207,146 @@ declare module "@polkadot/api-base/types/events" { /** Generic event */ [key: string]: AugmentedEvent; }; + foreignAssets: { + /** Accounts were destroyed for given asset. */ + AccountsDestroyed: AugmentedEvent< + ApiType, + [assetId: u16, accountsDestroyed: u32, accountsRemaining: u32], + { assetId: u16; accountsDestroyed: u32; accountsRemaining: u32 } + >; + /** An approval for account `delegate` was cancelled by `owner`. */ + ApprovalCancelled: AugmentedEvent< + ApiType, + [assetId: u16, owner: AccountId32, delegate: AccountId32], + { assetId: u16; owner: AccountId32; delegate: AccountId32 } + >; + /** Approvals were destroyed for given asset. */ + ApprovalsDestroyed: AugmentedEvent< + ApiType, + [assetId: u16, approvalsDestroyed: u32, approvalsRemaining: u32], + { assetId: u16; approvalsDestroyed: u32; approvalsRemaining: u32 } + >; + /** (Additional) funds have been approved for transfer to a destination account. */ + ApprovedTransfer: AugmentedEvent< + ApiType, + [assetId: u16, source: AccountId32, delegate: AccountId32, amount: u128], + { assetId: u16; source: AccountId32; delegate: AccountId32; amount: u128 } + >; + /** Some asset `asset_id` was frozen. */ + AssetFrozen: AugmentedEvent; + /** The min_balance of an asset has been updated by the asset owner. */ + AssetMinBalanceChanged: AugmentedEvent< + ApiType, + [assetId: u16, newMinBalance: u128], + { assetId: u16; newMinBalance: u128 } + >; + /** An asset has had its attributes changed by the `Force` origin. */ + AssetStatusChanged: AugmentedEvent; + /** Some asset `asset_id` was thawed. */ + AssetThawed: AugmentedEvent; + /** Some account `who` was blocked. */ + Blocked: AugmentedEvent; + /** Some assets were destroyed. */ + Burned: AugmentedEvent< + ApiType, + [assetId: u16, owner: AccountId32, balance: u128], + { assetId: u16; owner: AccountId32; balance: u128 } + >; + /** Some asset class was created. */ + Created: AugmentedEvent< + ApiType, + [assetId: u16, creator: AccountId32, owner: AccountId32], + { assetId: u16; creator: AccountId32; owner: AccountId32 } + >; + /** An asset class was destroyed. */ + Destroyed: AugmentedEvent; + /** An asset class is in the process of being destroyed. */ + DestructionStarted: AugmentedEvent; + /** Some asset class was force-created. */ + ForceCreated: AugmentedEvent< + ApiType, + [assetId: u16, owner: AccountId32], + { assetId: u16; owner: AccountId32 } + >; + /** Some account `who` was frozen. */ + Frozen: AugmentedEvent; + /** Some assets were issued. */ + Issued: AugmentedEvent< + ApiType, + [assetId: u16, owner: AccountId32, amount: u128], + { assetId: u16; owner: AccountId32; amount: u128 } + >; + /** Metadata has been cleared for an asset. */ + MetadataCleared: AugmentedEvent; + /** New metadata has been set for an asset. */ + MetadataSet: AugmentedEvent< + ApiType, + [assetId: u16, name: Bytes, symbol_: Bytes, decimals: u8, isFrozen: bool], + { assetId: u16; name: Bytes; symbol: Bytes; decimals: u8; isFrozen: bool } + >; + /** The owner changed. */ + OwnerChanged: AugmentedEvent< + ApiType, + [assetId: u16, owner: AccountId32], + { assetId: u16; owner: AccountId32 } + >; + /** The management team changed. */ + TeamChanged: AugmentedEvent< + ApiType, + [assetId: u16, issuer: AccountId32, admin: AccountId32, freezer: AccountId32], + { assetId: u16; issuer: AccountId32; admin: AccountId32; freezer: AccountId32 } + >; + /** Some account `who` was thawed. */ + Thawed: AugmentedEvent; + /** Some account `who` was created with a deposit from `depositor`. */ + Touched: AugmentedEvent< + ApiType, + [assetId: u16, who: AccountId32, depositor: AccountId32], + { assetId: u16; who: AccountId32; depositor: AccountId32 } + >; + /** Some assets were transferred. */ + Transferred: AugmentedEvent< + ApiType, + [assetId: u16, from: AccountId32, to: AccountId32, amount: u128], + { assetId: u16; from: AccountId32; to: AccountId32; amount: u128 } + >; + /** An `amount` was transferred in its entirety from `owner` to `destination` by the approved `delegate`. */ + TransferredApproved: AugmentedEvent< + ApiType, + [assetId: u16, owner: AccountId32, delegate: AccountId32, destination: AccountId32, amount: u128], + { assetId: u16; owner: AccountId32; delegate: AccountId32; destination: AccountId32; amount: u128 } + >; + /** Generic event */ + [key: string]: AugmentedEvent; + }; + foreignAssetsCreator: { + /** New asset with the asset manager is registered */ + ForeignAssetCreated: AugmentedEvent< + ApiType, + [assetId: u16, foreignAsset: StagingXcmV3MultiLocation], + { assetId: u16; foreignAsset: StagingXcmV3MultiLocation } + >; + /** Removed all information related to an assetId and destroyed asset */ + ForeignAssetDestroyed: AugmentedEvent< + ApiType, + [assetId: u16, foreignAsset: StagingXcmV3MultiLocation], + { assetId: u16; foreignAsset: StagingXcmV3MultiLocation } + >; + /** Removed all information related to an assetId */ + ForeignAssetRemoved: AugmentedEvent< + ApiType, + [assetId: u16, foreignAsset: StagingXcmV3MultiLocation], + { assetId: u16; foreignAsset: StagingXcmV3MultiLocation } + >; + /** Changed the xcm type mapping for a given asset id */ + ForeignAssetTypeChanged: AugmentedEvent< + ApiType, + [assetId: u16, newForeignAsset: StagingXcmV3MultiLocation], + { assetId: u16; newForeignAsset: StagingXcmV3MultiLocation } + >; + /** Generic event */ + [key: string]: AugmentedEvent; + }; identity: { /** A name was cleared, and the given balance returned. */ IdentityCleared: AugmentedEvent< diff --git a/typescript-api/src/dancebox/interfaces/augment-api-query.ts b/typescript-api/src/dancebox/interfaces/augment-api-query.ts index a75aebfae..190744dbb 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-query.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-query.ts @@ -43,6 +43,10 @@ import type { FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, NimbusPrimitivesNimbusCryptoPublic, + PalletAssetsApproval, + PalletAssetsAssetAccount, + PalletAssetsAssetDetails, + PalletAssetsAssetMetadata, PalletAuthorNotingContainerChainBlockInfo, PalletBalancesAccountData, PalletBalancesBalanceLock, @@ -71,6 +75,7 @@ import type { SpRuntimeDigest, SpTrieStorageProof, SpWeightsWeightV2Weight, + StagingXcmV3MultiLocation, TpContainerChainGenesisDataContainerChainGenesisData, XcmVersionedAssetId, XcmVersionedMultiLocation, @@ -82,6 +87,21 @@ export type __QueryableStorageEntry = QueryableStorage declare module "@polkadot/api-base/types/storage" { interface AugmentedQueries { + assetRate: { + /** + * Maps an asset to its fixed point representation in the native balance. + * + * E.g. `native_amount = asset_amount * ConversionRateToNative::::get(asset_kind)` + */ + conversionRateToNative: AugmentedQuery< + ApiType, + (arg: u16 | AnyNumber | Uint8Array) => Observable>, + [u16] + > & + QueryableStorageEntry; + /** Generic query */ + [key: string]: QueryableStorageEntry; + }; asyncBacking: { /** * First tuple element is the highest slot that has been seen in the history of this chain. Second tuple element @@ -299,6 +319,75 @@ declare module "@polkadot/api-base/types/storage" { /** Generic query */ [key: string]: QueryableStorageEntry; }; + foreignAssets: { + /** The holdings of a specific account for a specific asset. */ + account: AugmentedQuery< + ApiType, + ( + arg1: u16 | AnyNumber | Uint8Array, + arg2: AccountId32 | string | Uint8Array + ) => Observable>, + [u16, AccountId32] + > & + QueryableStorageEntry; + /** + * Approved balance transfers. First balance is the amount approved for transfer. Second is the amount of + * `T::Currency` reserved for storing this. First key is the asset ID, second key is the owner and third key is + * the delegate. + */ + approvals: AugmentedQuery< + ApiType, + ( + arg1: u16 | AnyNumber | Uint8Array, + arg2: AccountId32 | string | Uint8Array, + arg3: AccountId32 | string | Uint8Array + ) => Observable>, + [u16, AccountId32, AccountId32] + > & + QueryableStorageEntry; + /** Details of an asset. */ + asset: AugmentedQuery< + ApiType, + (arg: u16 | AnyNumber | Uint8Array) => Observable>, + [u16] + > & + QueryableStorageEntry; + /** Metadata of an asset. */ + metadata: AugmentedQuery< + ApiType, + (arg: u16 | AnyNumber | Uint8Array) => Observable, + [u16] + > & + QueryableStorageEntry; + /** Generic query */ + [key: string]: QueryableStorageEntry; + }; + foreignAssetsCreator: { + /** + * Mapping from an asset id to a Foreign asset type. This is mostly used when receiving transaction specifying an + * asset directly, like transferring an asset from this chain to another. + */ + assetIdToForeignAsset: AugmentedQuery< + ApiType, + (arg: u16 | AnyNumber | Uint8Array) => Observable>, + [u16] + > & + QueryableStorageEntry; + /** + * Reverse mapping of AssetIdToForeignAsset. Mapping from a foreign asset to an asset id. This is mostly used when + * receiving a multilocation XCM message to retrieve the corresponding asset in which tokens should me minted. + */ + foreignAssetToAssetId: AugmentedQuery< + ApiType, + ( + arg: StagingXcmV3MultiLocation | { parents?: any; interior?: any } | string | Uint8Array + ) => Observable>, + [StagingXcmV3MultiLocation] + > & + QueryableStorageEntry; + /** Generic query */ + [key: string]: QueryableStorageEntry; + }; identity: { /** * Information that is pertinent to identify the entity behind an account. @@ -806,6 +895,20 @@ declare module "@polkadot/api-base/types/storage" { /** Generic query */ [key: string]: QueryableStorageEntry; }; + relayStorageRoots: { + /** Map of relay block number to relay storage root */ + relayStorageRoot: AugmentedQuery< + ApiType, + (arg: u32 | AnyNumber | Uint8Array) => Observable>, + [u32] + > & + QueryableStorageEntry; + /** List of all the keys in `RelayStorageRoot`. Used to remove the oldest key without having to iterate over all of them. */ + relayStorageRootKeys: AugmentedQuery Observable>, []> & + QueryableStorageEntry; + /** Generic query */ + [key: string]: QueryableStorageEntry; + }; servicesPayment: { blockProductionCredits: AugmentedQuery< ApiType, diff --git a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts index 48eb73561..51dbe7124 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts @@ -12,7 +12,7 @@ import type { SubmittableExtrinsicFunction, } from "@polkadot/api-base/types"; import type { Data } from "@polkadot/types"; -import type { Bytes, Compact, Option, Vec, bool, u128, u16, u32, u64 } from "@polkadot/types-codec"; +import type { Bytes, Compact, Option, Vec, bool, u128, u16, u32, u64, u8 } from "@polkadot/types-codec"; import type { AnyNumber, IMethod, ITuple } from "@polkadot/types-codec/types"; import type { AccountId32, Call, H256, MultiAddress, Perbill } from "@polkadot/types/interfaces/runtime"; import type { @@ -43,6 +43,31 @@ export type __SubmittableExtrinsicFunction = Submittab declare module "@polkadot/api-base/types/submittable" { interface AugmentedSubmittables { + assetRate: { + /** See [`Pallet::create`]. */ + create: AugmentedSubmittable< + ( + assetKind: u16 | AnyNumber | Uint8Array, + rate: u128 | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, u128] + >; + /** See [`Pallet::remove`]. */ + remove: AugmentedSubmittable< + (assetKind: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::update`]. */ + update: AugmentedSubmittable< + ( + assetKind: u16 | AnyNumber | Uint8Array, + rate: u128 | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, u128] + >; + /** Generic tx */ + [key: string]: SubmittableExtrinsicFunction; + }; authorInherent: { /** See [`Pallet::kick_off_authorship_validation`]. */ kickOffAuthorshipValidation: AugmentedSubmittable<() => SubmittableExtrinsic, []>; @@ -211,6 +236,11 @@ declare module "@polkadot/api-base/types/submittable" { (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u32] >; + /** See [`Pallet::set_collators_per_parathread`]. */ + setCollatorsPerParathread: AugmentedSubmittable< + (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u32] + >; /** See [`Pallet::set_full_rotation_period`]. */ setFullRotationPeriod: AugmentedSubmittable< (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, @@ -231,6 +261,16 @@ declare module "@polkadot/api-base/types/submittable" { (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u32] >; + /** See [`Pallet::set_parathreads_per_collator`]. */ + setParathreadsPerCollator: AugmentedSubmittable< + (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u32] + >; + /** See [`Pallet::set_target_container_chain_fullness`]. */ + setTargetContainerChainFullness: AugmentedSubmittable< + (updated: Perbill | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [Perbill] + >; /** Generic tx */ [key: string]: SubmittableExtrinsicFunction; }; @@ -258,6 +298,508 @@ declare module "@polkadot/api-base/types/submittable" { /** Generic tx */ [key: string]: SubmittableExtrinsicFunction; }; + foreignAssets: { + /** See [`Pallet::approve_transfer`]. */ + approveTransfer: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + delegate: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + amount: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, Compact] + >; + /** See [`Pallet::block`]. */ + block: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + who: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress] + >; + /** See [`Pallet::burn`]. */ + burn: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + who: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + amount: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, Compact] + >; + /** See [`Pallet::cancel_approval`]. */ + cancelApproval: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + delegate: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress] + >; + /** See [`Pallet::clear_metadata`]. */ + clearMetadata: AugmentedSubmittable< + (id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::create`]. */ + create: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + admin: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + minBalance: u128 | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, u128] + >; + /** See [`Pallet::destroy_accounts`]. */ + destroyAccounts: AugmentedSubmittable< + (id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::destroy_approvals`]. */ + destroyApprovals: AugmentedSubmittable< + (id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::finish_destroy`]. */ + finishDestroy: AugmentedSubmittable< + (id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::force_asset_status`]. */ + forceAssetStatus: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + owner: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + issuer: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + admin: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + freezer: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + minBalance: Compact | AnyNumber | Uint8Array, + isSufficient: bool | boolean | Uint8Array, + isFrozen: bool | boolean | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, MultiAddress, MultiAddress, MultiAddress, Compact, bool, bool] + >; + /** See [`Pallet::force_cancel_approval`]. */ + forceCancelApproval: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + owner: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + delegate: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, MultiAddress] + >; + /** See [`Pallet::force_clear_metadata`]. */ + forceClearMetadata: AugmentedSubmittable< + (id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::force_create`]. */ + forceCreate: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + owner: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + isSufficient: bool | boolean | Uint8Array, + minBalance: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, bool, Compact] + >; + /** See [`Pallet::force_set_metadata`]. */ + forceSetMetadata: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + name: Bytes | string | Uint8Array, + symbol: Bytes | string | Uint8Array, + decimals: u8 | AnyNumber | Uint8Array, + isFrozen: bool | boolean | Uint8Array + ) => SubmittableExtrinsic, + [u16, Bytes, Bytes, u8, bool] + >; + /** See [`Pallet::force_transfer`]. */ + forceTransfer: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + source: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + dest: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + amount: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, MultiAddress, Compact] + >; + /** See [`Pallet::freeze`]. */ + freeze: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + who: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress] + >; + /** See [`Pallet::freeze_asset`]. */ + freezeAsset: AugmentedSubmittable< + (id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::mint`]. */ + mint: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + beneficiary: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + amount: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, Compact] + >; + /** See [`Pallet::refund`]. */ + refund: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + allowBurn: bool | boolean | Uint8Array + ) => SubmittableExtrinsic, + [u16, bool] + >; + /** See [`Pallet::refund_other`]. */ + refundOther: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + who: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress] + >; + /** See [`Pallet::set_metadata`]. */ + setMetadata: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + name: Bytes | string | Uint8Array, + symbol: Bytes | string | Uint8Array, + decimals: u8 | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, Bytes, Bytes, u8] + >; + /** See [`Pallet::set_min_balance`]. */ + setMinBalance: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + minBalance: u128 | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, u128] + >; + /** See [`Pallet::set_team`]. */ + setTeam: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + issuer: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + admin: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + freezer: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, MultiAddress, MultiAddress] + >; + /** See [`Pallet::start_destroy`]. */ + startDestroy: AugmentedSubmittable< + (id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::thaw`]. */ + thaw: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + who: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress] + >; + /** See [`Pallet::thaw_asset`]. */ + thawAsset: AugmentedSubmittable<(id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u16]>; + /** See [`Pallet::touch`]. */ + touch: AugmentedSubmittable<(id: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u16]>; + /** See [`Pallet::touch_other`]. */ + touchOther: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + who: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress] + >; + /** See [`Pallet::transfer`]. */ + transfer: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + target: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + amount: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, Compact] + >; + /** See [`Pallet::transfer_approved`]. */ + transferApproved: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + owner: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + destination: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + amount: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, MultiAddress, Compact] + >; + /** See [`Pallet::transfer_keep_alive`]. */ + transferKeepAlive: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + target: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array, + amount: Compact | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress, Compact] + >; + /** See [`Pallet::transfer_ownership`]. */ + transferOwnership: AugmentedSubmittable< + ( + id: u16 | AnyNumber | Uint8Array, + owner: + | MultiAddress + | { Id: any } + | { Index: any } + | { Raw: any } + | { Address32: any } + | { Address20: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u16, MultiAddress] + >; + /** Generic tx */ + [key: string]: SubmittableExtrinsicFunction; + }; + foreignAssetsCreator: { + /** See [`Pallet::change_existing_asset_type`]. */ + changeExistingAssetType: AugmentedSubmittable< + ( + assetId: u16 | AnyNumber | Uint8Array, + newForeignAsset: StagingXcmV3MultiLocation | { parents?: any; interior?: any } | string | Uint8Array + ) => SubmittableExtrinsic, + [u16, StagingXcmV3MultiLocation] + >; + /** See [`Pallet::create_foreign_asset`]. */ + createForeignAsset: AugmentedSubmittable< + ( + foreignAsset: StagingXcmV3MultiLocation | { parents?: any; interior?: any } | string | Uint8Array, + assetId: u16 | AnyNumber | Uint8Array, + admin: AccountId32 | string | Uint8Array, + isSufficient: bool | boolean | Uint8Array, + minBalance: u128 | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [StagingXcmV3MultiLocation, u16, AccountId32, bool, u128] + >; + /** See [`Pallet::destroy_foreign_asset`]. */ + destroyForeignAsset: AugmentedSubmittable< + (assetId: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** See [`Pallet::remove_existing_asset_type`]. */ + removeExistingAssetType: AugmentedSubmittable< + (assetId: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u16] + >; + /** Generic tx */ + [key: string]: SubmittableExtrinsicFunction; + }; identity: { /** See [`Pallet::add_registrar`]. */ addRegistrar: AugmentedSubmittable< diff --git a/typescript-api/src/dancebox/interfaces/lookup.ts b/typescript-api/src/dancebox/interfaces/lookup.ts index b36936e5e..b1d5a60aa 100644 --- a/typescript-api/src/dancebox/interfaces/lookup.ts +++ b/typescript-api/src/dancebox/interfaces/lookup.ts @@ -1382,7 +1382,162 @@ export default { V3: "StagingXcmV3MultiLocation", }, }, - /** Lookup122: frame_system::Phase */ + /** Lookup122: pallet_assets::pallet::Event */ + PalletAssetsEvent: { + _enum: { + Created: { + assetId: "u16", + creator: "AccountId32", + owner: "AccountId32", + }, + Issued: { + assetId: "u16", + owner: "AccountId32", + amount: "u128", + }, + Transferred: { + assetId: "u16", + from: "AccountId32", + to: "AccountId32", + amount: "u128", + }, + Burned: { + assetId: "u16", + owner: "AccountId32", + balance: "u128", + }, + TeamChanged: { + assetId: "u16", + issuer: "AccountId32", + admin: "AccountId32", + freezer: "AccountId32", + }, + OwnerChanged: { + assetId: "u16", + owner: "AccountId32", + }, + Frozen: { + assetId: "u16", + who: "AccountId32", + }, + Thawed: { + assetId: "u16", + who: "AccountId32", + }, + AssetFrozen: { + assetId: "u16", + }, + AssetThawed: { + assetId: "u16", + }, + AccountsDestroyed: { + assetId: "u16", + accountsDestroyed: "u32", + accountsRemaining: "u32", + }, + ApprovalsDestroyed: { + assetId: "u16", + approvalsDestroyed: "u32", + approvalsRemaining: "u32", + }, + DestructionStarted: { + assetId: "u16", + }, + Destroyed: { + assetId: "u16", + }, + ForceCreated: { + assetId: "u16", + owner: "AccountId32", + }, + MetadataSet: { + assetId: "u16", + name: "Bytes", + symbol: "Bytes", + decimals: "u8", + isFrozen: "bool", + }, + MetadataCleared: { + assetId: "u16", + }, + ApprovedTransfer: { + assetId: "u16", + source: "AccountId32", + delegate: "AccountId32", + amount: "u128", + }, + ApprovalCancelled: { + assetId: "u16", + owner: "AccountId32", + delegate: "AccountId32", + }, + TransferredApproved: { + assetId: "u16", + owner: "AccountId32", + delegate: "AccountId32", + destination: "AccountId32", + amount: "u128", + }, + AssetStatusChanged: { + assetId: "u16", + }, + AssetMinBalanceChanged: { + assetId: "u16", + newMinBalance: "u128", + }, + Touched: { + assetId: "u16", + who: "AccountId32", + depositor: "AccountId32", + }, + Blocked: { + assetId: "u16", + who: "AccountId32", + }, + }, + }, + /** Lookup123: pallet_foreign_asset_creator::pallet::Event */ + PalletForeignAssetCreatorEvent: { + _enum: { + ForeignAssetCreated: { + assetId: "u16", + foreignAsset: "StagingXcmV3MultiLocation", + }, + ForeignAssetTypeChanged: { + assetId: "u16", + newForeignAsset: "StagingXcmV3MultiLocation", + }, + ForeignAssetRemoved: { + assetId: "u16", + foreignAsset: "StagingXcmV3MultiLocation", + }, + ForeignAssetDestroyed: { + assetId: "u16", + foreignAsset: "StagingXcmV3MultiLocation", + }, + }, + }, + /** Lookup124: pallet_asset_rate::pallet::Event */ + PalletAssetRateEvent: { + _enum: { + AssetRateCreated: { + assetKind: "u16", + rate: "u128", + }, + AssetRateRemoved: { + assetKind: "u16", + }, + AssetRateUpdated: { + _alias: { + new_: "new", + }, + assetKind: "u16", + old: "u128", + new_: "u128", + }, + }, + }, + /** Lookup126: frame_system::Phase */ FrameSystemPhase: { _enum: { ApplyExtrinsic: "u32", @@ -1390,12 +1545,12 @@ export default { Initialization: "Null", }, }, - /** Lookup126: frame_system::LastRuntimeUpgradeInfo */ + /** Lookup130: frame_system::LastRuntimeUpgradeInfo */ FrameSystemLastRuntimeUpgradeInfo: { specVersion: "Compact", specName: "Text", }, - /** Lookup128: frame_system::pallet::Call */ + /** Lookup132: frame_system::pallet::Call */ FrameSystemCall: { _enum: { remark: { @@ -1428,41 +1583,41 @@ export default { }, }, }, - /** Lookup132: frame_system::limits::BlockWeights */ + /** Lookup136: frame_system::limits::BlockWeights */ FrameSystemLimitsBlockWeights: { baseBlock: "SpWeightsWeightV2Weight", maxBlock: "SpWeightsWeightV2Weight", perClass: "FrameSupportDispatchPerDispatchClassWeightsPerClass", }, - /** Lookup133: frame_support::dispatch::PerDispatchClass */ + /** Lookup137: frame_support::dispatch::PerDispatchClass */ FrameSupportDispatchPerDispatchClassWeightsPerClass: { normal: "FrameSystemLimitsWeightsPerClass", operational: "FrameSystemLimitsWeightsPerClass", mandatory: "FrameSystemLimitsWeightsPerClass", }, - /** Lookup134: frame_system::limits::WeightsPerClass */ + /** Lookup138: frame_system::limits::WeightsPerClass */ FrameSystemLimitsWeightsPerClass: { baseExtrinsic: "SpWeightsWeightV2Weight", maxExtrinsic: "Option", maxTotal: "Option", reserved: "Option", }, - /** Lookup136: frame_system::limits::BlockLength */ + /** Lookup140: frame_system::limits::BlockLength */ FrameSystemLimitsBlockLength: { max: "FrameSupportDispatchPerDispatchClassU32", }, - /** Lookup137: frame_support::dispatch::PerDispatchClass */ + /** Lookup141: frame_support::dispatch::PerDispatchClass */ FrameSupportDispatchPerDispatchClassU32: { normal: "u32", operational: "u32", mandatory: "u32", }, - /** Lookup138: sp_weights::RuntimeDbWeight */ + /** Lookup142: sp_weights::RuntimeDbWeight */ SpWeightsRuntimeDbWeight: { read: "u64", write: "u64", }, - /** Lookup139: sp_version::RuntimeVersion */ + /** Lookup143: sp_version::RuntimeVersion */ SpVersionRuntimeVersion: { specName: "Text", implName: "Text", @@ -1473,7 +1628,7 @@ export default { transactionVersion: "u32", stateVersion: "u8", }, - /** Lookup143: frame_system::pallet::Error */ + /** Lookup147: frame_system::pallet::Error */ FrameSystemError: { _enum: [ "InvalidSpecName", @@ -1484,49 +1639,49 @@ export default { "CallFiltered", ], }, - /** Lookup145: cumulus_pallet_parachain_system::unincluded_segment::Ancestor */ + /** Lookup149: cumulus_pallet_parachain_system::unincluded_segment::Ancestor */ CumulusPalletParachainSystemUnincludedSegmentAncestor: { usedBandwidth: "CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth", paraHeadHash: "Option", consumedGoAheadSignal: "Option", }, - /** Lookup146: cumulus_pallet_parachain_system::unincluded_segment::UsedBandwidth */ + /** Lookup150: cumulus_pallet_parachain_system::unincluded_segment::UsedBandwidth */ CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth: { umpMsgCount: "u32", umpTotalBytes: "u32", hrmpOutgoing: "BTreeMap", }, - /** Lookup148: cumulus_pallet_parachain_system::unincluded_segment::HrmpChannelUpdate */ + /** Lookup152: cumulus_pallet_parachain_system::unincluded_segment::HrmpChannelUpdate */ CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate: { msgCount: "u32", totalBytes: "u32", }, - /** Lookup153: polkadot_primitives::v6::UpgradeGoAhead */ + /** Lookup157: polkadot_primitives::v6::UpgradeGoAhead */ PolkadotPrimitivesV6UpgradeGoAhead: { _enum: ["Abort", "GoAhead"], }, - /** Lookup154: cumulus_pallet_parachain_system::unincluded_segment::SegmentTracker */ + /** Lookup158: cumulus_pallet_parachain_system::unincluded_segment::SegmentTracker */ CumulusPalletParachainSystemUnincludedSegmentSegmentTracker: { usedBandwidth: "CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth", hrmpWatermark: "Option", consumedGoAheadSignal: "Option", }, - /** Lookup155: polkadot_primitives::v6::PersistedValidationData */ + /** Lookup159: polkadot_primitives::v6::PersistedValidationData */ PolkadotPrimitivesV6PersistedValidationData: { parentHead: "Bytes", relayParentNumber: "u32", relayParentStorageRoot: "H256", maxPovSize: "u32", }, - /** Lookup158: polkadot_primitives::v6::UpgradeRestriction */ + /** Lookup162: polkadot_primitives::v6::UpgradeRestriction */ PolkadotPrimitivesV6UpgradeRestriction: { _enum: ["Present"], }, - /** Lookup159: sp_trie::storage_proof::StorageProof */ + /** Lookup163: sp_trie::storage_proof::StorageProof */ SpTrieStorageProof: { trieNodes: "BTreeSet", }, - /** Lookup161: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot */ + /** Lookup165: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot */ CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot: { dmqMqcHead: "H256", relayDispatchQueueRemainingCapacity: @@ -1534,12 +1689,12 @@ export default { ingressChannels: "Vec<(u32,PolkadotPrimitivesV6AbridgedHrmpChannel)>", egressChannels: "Vec<(u32,PolkadotPrimitivesV6AbridgedHrmpChannel)>", }, - /** Lookup162: cumulus_pallet_parachain_system::relay_state_snapshot::RelayDispatchQueueRemainingCapacity */ + /** Lookup166: cumulus_pallet_parachain_system::relay_state_snapshot::RelayDispatchQueueRemainingCapacity */ CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity: { remainingCount: "u32", remainingSize: "u32", }, - /** Lookup165: polkadot_primitives::v6::AbridgedHrmpChannel */ + /** Lookup169: polkadot_primitives::v6::AbridgedHrmpChannel */ PolkadotPrimitivesV6AbridgedHrmpChannel: { maxCapacity: "u32", maxTotalSize: "u32", @@ -1548,7 +1703,7 @@ export default { totalSize: "u32", mqcHead: "Option", }, - /** Lookup166: polkadot_primitives::v6::AbridgedHostConfiguration */ + /** Lookup170: polkadot_primitives::v6::AbridgedHostConfiguration */ PolkadotPrimitivesV6AbridgedHostConfiguration: { maxCodeSize: "u32", maxHeadDataSize: "u32", @@ -1561,22 +1716,22 @@ export default { validationUpgradeDelay: "u32", asyncBackingParams: "PolkadotPrimitivesV6AsyncBackingAsyncBackingParams", }, - /** Lookup167: polkadot_primitives::v6::async_backing::AsyncBackingParams */ + /** Lookup171: polkadot_primitives::v6::async_backing::AsyncBackingParams */ PolkadotPrimitivesV6AsyncBackingAsyncBackingParams: { maxCandidateDepth: "u32", allowedAncestryLen: "u32", }, - /** Lookup173: polkadot_core_primitives::OutboundHrmpMessage */ + /** Lookup177: polkadot_core_primitives::OutboundHrmpMessage */ PolkadotCorePrimitivesOutboundHrmpMessage: { recipient: "u32", data: "Bytes", }, - /** Lookup175: cumulus_pallet_parachain_system::CodeUpgradeAuthorization */ + /** Lookup178: cumulus_pallet_parachain_system::CodeUpgradeAuthorization */ CumulusPalletParachainSystemCodeUpgradeAuthorization: { codeHash: "H256", checkVersion: "bool", }, - /** Lookup176: cumulus_pallet_parachain_system::pallet::Call */ + /** Lookup179: cumulus_pallet_parachain_system::pallet::Call */ CumulusPalletParachainSystemCall: { _enum: { set_validation_data: { @@ -1594,24 +1749,24 @@ export default { }, }, }, - /** Lookup177: cumulus_primitives_parachain_inherent::ParachainInherentData */ + /** Lookup180: cumulus_primitives_parachain_inherent::ParachainInherentData */ CumulusPrimitivesParachainInherentParachainInherentData: { validationData: "PolkadotPrimitivesV6PersistedValidationData", relayChainState: "SpTrieStorageProof", downwardMessages: "Vec", horizontalMessages: "BTreeMap>", }, - /** Lookup179: polkadot_core_primitives::InboundDownwardMessage */ + /** Lookup182: polkadot_core_primitives::InboundDownwardMessage */ PolkadotCorePrimitivesInboundDownwardMessage: { sentAt: "u32", msg: "Bytes", }, - /** Lookup182: polkadot_core_primitives::InboundHrmpMessage */ + /** Lookup185: polkadot_core_primitives::InboundHrmpMessage */ PolkadotCorePrimitivesInboundHrmpMessage: { sentAt: "u32", data: "Bytes", }, - /** Lookup185: cumulus_pallet_parachain_system::pallet::Error */ + /** Lookup188: cumulus_pallet_parachain_system::pallet::Error */ CumulusPalletParachainSystemError: { _enum: [ "OverlappingUpgrades", @@ -1624,7 +1779,7 @@ export default { "Unauthorized", ], }, - /** Lookup186: pallet_timestamp::pallet::Call */ + /** Lookup189: pallet_timestamp::pallet::Call */ PalletTimestampCall: { _enum: { set: { @@ -1632,9 +1787,9 @@ export default { }, }, }, - /** Lookup187: parachain_info::pallet::Call */ + /** Lookup190: parachain_info::pallet::Call */ ParachainInfoCall: "Null", - /** Lookup188: pallet_sudo::pallet::Call */ + /** Lookup191: pallet_sudo::pallet::Call */ PalletSudoCall: { _enum: { sudo: { @@ -1656,7 +1811,7 @@ export default { }, }, }, - /** Lookup190: pallet_utility::pallet::Call */ + /** Lookup193: pallet_utility::pallet::Call */ PalletUtilityCall: { _enum: { batch: { @@ -1682,7 +1837,7 @@ export default { }, }, }, - /** Lookup192: dancebox_runtime::OriginCaller */ + /** Lookup195: dancebox_runtime::OriginCaller */ DanceboxRuntimeOriginCaller: { _enum: { system: "FrameSupportDispatchRawOrigin", @@ -1741,7 +1896,7 @@ export default { PolkadotXcm: "PalletXcmOrigin", }, }, - /** Lookup193: frame_support::dispatch::RawOrigin */ + /** Lookup196: frame_support::dispatch::RawOrigin */ FrameSupportDispatchRawOrigin: { _enum: { Root: "Null", @@ -1749,23 +1904,23 @@ export default { None: "Null", }, }, - /** Lookup194: cumulus_pallet_xcm::pallet::Origin */ + /** Lookup197: cumulus_pallet_xcm::pallet::Origin */ CumulusPalletXcmOrigin: { _enum: { Relay: "Null", SiblingParachain: "u32", }, }, - /** Lookup195: pallet_xcm::pallet::Origin */ + /** Lookup198: pallet_xcm::pallet::Origin */ PalletXcmOrigin: { _enum: { Xcm: "StagingXcmV3MultiLocation", Response: "StagingXcmV3MultiLocation", }, }, - /** Lookup196: sp_core::Void */ + /** Lookup199: sp_core::Void */ SpCoreVoid: "Null", - /** Lookup197: pallet_proxy::pallet::Call */ + /** Lookup200: pallet_proxy::pallet::Call */ PalletProxyCall: { _enum: { proxy: { @@ -1816,11 +1971,11 @@ export default { }, }, }, - /** Lookup201: pallet_maintenance_mode::pallet::Call */ + /** Lookup204: pallet_maintenance_mode::pallet::Call */ PalletMaintenanceModeCall: { _enum: ["enter_maintenance_mode", "resume_normal_operation"], }, - /** Lookup202: pallet_tx_pause::pallet::Call */ + /** Lookup205: pallet_tx_pause::pallet::Call */ PalletTxPauseCall: { _enum: { pause: { @@ -1831,7 +1986,7 @@ export default { }, }, }, - /** Lookup203: pallet_balances::pallet::Call */ + /** Lookup206: pallet_balances::pallet::Call */ PalletBalancesCall: { _enum: { transfer_allow_death: { @@ -1866,7 +2021,7 @@ export default { }, }, }, - /** Lookup204: pallet_identity::pallet::Call */ + /** Lookup207: pallet_identity::pallet::Call */ PalletIdentityCall: { _enum: { add_registrar: { @@ -1924,7 +2079,7 @@ export default { quit_sub: "Null", }, }, - /** Lookup205: pallet_identity::simple::IdentityInfo */ + /** Lookup208: pallet_identity::simple::IdentityInfo */ PalletIdentitySimpleIdentityInfo: { additional: "Vec<(Data,Data)>", display: "Data", @@ -1936,7 +2091,7 @@ export default { image: "Data", twitter: "Data", }, - /** Lookup241: pallet_identity::types::BitFlags */ + /** Lookup244: pallet_identity::types::BitFlags */ PalletIdentityBitFlags: { _bitLength: 64, Display: 0, @@ -1948,11 +2103,11 @@ export default { Image: 6, Twitter: 7, }, - /** Lookup242: pallet_identity::simple::IdentityField */ + /** Lookup245: pallet_identity::simple::IdentityField */ PalletIdentitySimpleIdentityField: { _enum: ["Display", "Legal", "Web", "Riot", "Email", "PgpFingerprint", "Image", "Twitter"], }, - /** Lookup243: pallet_identity::types::Judgement */ + /** Lookup246: pallet_identity::types::Judgement */ PalletIdentityJudgement: { _enum: { Unknown: "Null", @@ -1964,7 +2119,7 @@ export default { Erroneous: "Null", }, }, - /** Lookup244: pallet_registrar::pallet::Call */ + /** Lookup247: pallet_registrar::pallet::Call */ PalletRegistrarCall: { _enum: { register: { @@ -1986,7 +2141,7 @@ export default { }, }, }, - /** Lookup245: tp_container_chain_genesis_data::ContainerChainGenesisData */ + /** Lookup248: tp_container_chain_genesis_data::ContainerChainGenesisData */ TpContainerChainGenesisDataContainerChainGenesisData: { storage: "Vec", name: "Bytes", @@ -1995,23 +2150,23 @@ export default { extensions: "Bytes", properties: "TpContainerChainGenesisDataProperties", }, - /** Lookup247: tp_container_chain_genesis_data::ContainerChainGenesisDataItem */ + /** Lookup250: tp_container_chain_genesis_data::ContainerChainGenesisDataItem */ TpContainerChainGenesisDataContainerChainGenesisDataItem: { key: "Bytes", value: "Bytes", }, - /** Lookup249: tp_container_chain_genesis_data::Properties */ + /** Lookup252: tp_container_chain_genesis_data::Properties */ TpContainerChainGenesisDataProperties: { tokenMetadata: "TpContainerChainGenesisDataTokenMetadata", isEthereum: "bool", }, - /** Lookup250: tp_container_chain_genesis_data::TokenMetadata */ + /** Lookup253: tp_container_chain_genesis_data::TokenMetadata */ TpContainerChainGenesisDataTokenMetadata: { tokenSymbol: "Bytes", ss58Format: "u32", tokenDecimals: "u32", }, - /** Lookup252: pallet_configuration::pallet::Call */ + /** Lookup255: pallet_configuration::pallet::Call */ PalletConfigurationCall: { _enum: { set_max_collators: { @@ -2044,9 +2199,24 @@ export default { }, new_: "u32", }, - __Unused5: "Null", - __Unused6: "Null", - __Unused7: "Null", + set_collators_per_parathread: { + _alias: { + new_: "new", + }, + new_: "u32", + }, + set_parathreads_per_collator: { + _alias: { + new_: "new", + }, + new_: "u32", + }, + set_target_container_chain_fullness: { + _alias: { + new_: "new", + }, + new_: "Perbill", + }, __Unused8: "Null", __Unused9: "Null", __Unused10: "Null", @@ -2091,9 +2261,9 @@ export default { }, }, }, - /** Lookup253: pallet_collator_assignment::pallet::Call */ + /** Lookup257: pallet_collator_assignment::pallet::Call */ PalletCollatorAssignmentCall: "Null", - /** Lookup254: pallet_author_noting::pallet::Call */ + /** Lookup258: pallet_author_noting::pallet::Call */ PalletAuthorNotingCall: { _enum: { set_latest_author_data: { @@ -2109,13 +2279,13 @@ export default { }, }, }, - /** Lookup255: tp_author_noting_inherent::OwnParachainInherentData */ + /** Lookup259: tp_author_noting_inherent::OwnParachainInherentData */ TpAuthorNotingInherentOwnParachainInherentData: { relayStorageProof: "SpTrieStorageProof", }, - /** Lookup256: pallet_authority_assignment::pallet::Call */ + /** Lookup260: pallet_authority_assignment::pallet::Call */ PalletAuthorityAssignmentCall: "Null", - /** Lookup257: pallet_services_payment::pallet::Call */ + /** Lookup261: pallet_services_payment::pallet::Call */ PalletServicesPaymentCall: { _enum: { purchase_credits: { @@ -2133,7 +2303,7 @@ export default { }, }, }, - /** Lookup259: pallet_data_preservers::pallet::Call */ + /** Lookup263: pallet_data_preservers::pallet::Call */ PalletDataPreserversCall: { _enum: { set_boot_nodes: { @@ -2142,7 +2312,7 @@ export default { }, }, }, - /** Lookup263: pallet_invulnerables::pallet::Call */ + /** Lookup267: pallet_invulnerables::pallet::Call */ PalletInvulnerablesCall: { _enum: { set_invulnerables: { @@ -2159,7 +2329,7 @@ export default { }, }, }, - /** Lookup264: pallet_session::pallet::Call */ + /** Lookup268: pallet_session::pallet::Call */ PalletSessionCall: { _enum: { set_keys: { @@ -2172,19 +2342,19 @@ export default { purge_keys: "Null", }, }, - /** Lookup265: dancebox_runtime::SessionKeys */ + /** Lookup269: dancebox_runtime::SessionKeys */ DanceboxRuntimeSessionKeys: { nimbus: "NimbusPrimitivesNimbusCryptoPublic", }, - /** Lookup266: nimbus_primitives::nimbus_crypto::Public */ + /** Lookup270: nimbus_primitives::nimbus_crypto::Public */ NimbusPrimitivesNimbusCryptoPublic: "SpCoreSr25519Public", - /** Lookup267: sp_core::sr25519::Public */ + /** Lookup271: sp_core::sr25519::Public */ SpCoreSr25519Public: "[u8;32]", - /** Lookup268: pallet_author_inherent::pallet::Call */ + /** Lookup272: pallet_author_inherent::pallet::Call */ PalletAuthorInherentCall: { _enum: ["kick_off_authorship_validation"], }, - /** Lookup269: pallet_pooled_staking::pallet::Call */ + /** Lookup273: pallet_pooled_staking::pallet::Call */ PalletPooledStakingCall: { _enum: { rebalance_hold: { @@ -2218,16 +2388,16 @@ export default { }, }, }, - /** Lookup270: pallet_pooled_staking::pallet::AllTargetPool */ + /** Lookup274: pallet_pooled_staking::pallet::AllTargetPool */ PalletPooledStakingAllTargetPool: { _enum: ["Joining", "AutoCompounding", "ManualRewards", "Leaving"], }, - /** Lookup272: pallet_pooled_staking::pallet::PendingOperationQuery */ + /** Lookup276: pallet_pooled_staking::pallet::PendingOperationQuery */ PalletPooledStakingPendingOperationQuery: { delegator: "AccountId32", operation: "PalletPooledStakingPendingOperationKey", }, - /** Lookup273: pallet_pooled_staking::pallet::PendingOperationKey */ + /** Lookup277: pallet_pooled_staking::pallet::PendingOperationKey */ PalletPooledStakingPendingOperationKey: { _enum: { JoiningAutoCompounding: { @@ -2244,14 +2414,14 @@ export default { }, }, }, - /** Lookup274: pallet_pooled_staking::pallet::SharesOrStake */ + /** Lookup278: pallet_pooled_staking::pallet::SharesOrStake */ PalletPooledStakingSharesOrStake: { _enum: { Shares: "u128", Stake: "u128", }, }, - /** Lookup277: cumulus_pallet_xcmp_queue::pallet::Call */ + /** Lookup281: cumulus_pallet_xcmp_queue::pallet::Call */ CumulusPalletXcmpQueueCall: { _enum: { service_overweight: { @@ -2298,7 +2468,7 @@ export default { }, }, }, - /** Lookup278: cumulus_pallet_dmp_queue::pallet::Call */ + /** Lookup282: cumulus_pallet_dmp_queue::pallet::Call */ CumulusPalletDmpQueueCall: { _enum: { service_overweight: { @@ -2307,7 +2477,7 @@ export default { }, }, }, - /** Lookup279: pallet_xcm::pallet::Call */ + /** Lookup283: pallet_xcm::pallet::Call */ PalletXcmCall: { _enum: { send: { @@ -2362,7 +2532,7 @@ export default { }, }, }, - /** Lookup280: xcm::VersionedXcm */ + /** Lookup284: xcm::VersionedXcm */ XcmVersionedXcm: { _enum: { __Unused0: "Null", @@ -2371,9 +2541,9 @@ export default { V3: "XcmV3Xcm", }, }, - /** Lookup281: xcm::v2::Xcm */ + /** Lookup285: xcm::v2::Xcm */ XcmV2Xcm: "Vec", - /** Lookup283: xcm::v2::Instruction */ + /** Lookup287: xcm::v2::Instruction */ XcmV2Instruction: { _enum: { WithdrawAsset: "XcmV2MultiassetMultiAssets", @@ -2469,7 +2639,7 @@ export default { UnsubscribeVersion: "Null", }, }, - /** Lookup284: xcm::v2::Response */ + /** Lookup288: xcm::v2::Response */ XcmV2Response: { _enum: { Null: "Null", @@ -2478,7 +2648,7 @@ export default { Version: "u32", }, }, - /** Lookup287: xcm::v2::traits::Error */ + /** Lookup291: xcm::v2::traits::Error */ XcmV2TraitsError: { _enum: { Overflow: "Null", @@ -2509,14 +2679,14 @@ export default { WeightNotComputable: "Null", }, }, - /** Lookup288: xcm::v2::multiasset::MultiAssetFilter */ + /** Lookup292: xcm::v2::multiasset::MultiAssetFilter */ XcmV2MultiassetMultiAssetFilter: { _enum: { Definite: "XcmV2MultiassetMultiAssets", Wild: "XcmV2MultiassetWildMultiAsset", }, }, - /** Lookup289: xcm::v2::multiasset::WildMultiAsset */ + /** Lookup293: xcm::v2::multiasset::WildMultiAsset */ XcmV2MultiassetWildMultiAsset: { _enum: { All: "Null", @@ -2526,18 +2696,206 @@ export default { }, }, }, - /** Lookup290: xcm::v2::multiasset::WildFungibility */ + /** Lookup294: xcm::v2::multiasset::WildFungibility */ XcmV2MultiassetWildFungibility: { _enum: ["Fungible", "NonFungible"], }, - /** Lookup291: xcm::v2::WeightLimit */ + /** Lookup295: xcm::v2::WeightLimit */ XcmV2WeightLimit: { _enum: { Unlimited: "Null", Limited: "Compact", }, }, - /** Lookup300: pallet_root_testing::pallet::Call */ + /** Lookup304: pallet_assets::pallet::Call */ + PalletAssetsCall: { + _enum: { + create: { + id: "u16", + admin: "MultiAddress", + minBalance: "u128", + }, + force_create: { + id: "u16", + owner: "MultiAddress", + isSufficient: "bool", + minBalance: "Compact", + }, + start_destroy: { + id: "u16", + }, + destroy_accounts: { + id: "u16", + }, + destroy_approvals: { + id: "u16", + }, + finish_destroy: { + id: "u16", + }, + mint: { + id: "u16", + beneficiary: "MultiAddress", + amount: "Compact", + }, + burn: { + id: "u16", + who: "MultiAddress", + amount: "Compact", + }, + transfer: { + id: "u16", + target: "MultiAddress", + amount: "Compact", + }, + transfer_keep_alive: { + id: "u16", + target: "MultiAddress", + amount: "Compact", + }, + force_transfer: { + id: "u16", + source: "MultiAddress", + dest: "MultiAddress", + amount: "Compact", + }, + freeze: { + id: "u16", + who: "MultiAddress", + }, + thaw: { + id: "u16", + who: "MultiAddress", + }, + freeze_asset: { + id: "u16", + }, + thaw_asset: { + id: "u16", + }, + transfer_ownership: { + id: "u16", + owner: "MultiAddress", + }, + set_team: { + id: "u16", + issuer: "MultiAddress", + admin: "MultiAddress", + freezer: "MultiAddress", + }, + set_metadata: { + id: "u16", + name: "Bytes", + symbol: "Bytes", + decimals: "u8", + }, + clear_metadata: { + id: "u16", + }, + force_set_metadata: { + id: "u16", + name: "Bytes", + symbol: "Bytes", + decimals: "u8", + isFrozen: "bool", + }, + force_clear_metadata: { + id: "u16", + }, + force_asset_status: { + id: "u16", + owner: "MultiAddress", + issuer: "MultiAddress", + admin: "MultiAddress", + freezer: "MultiAddress", + minBalance: "Compact", + isSufficient: "bool", + isFrozen: "bool", + }, + approve_transfer: { + id: "u16", + delegate: "MultiAddress", + amount: "Compact", + }, + cancel_approval: { + id: "u16", + delegate: "MultiAddress", + }, + force_cancel_approval: { + id: "u16", + owner: "MultiAddress", + delegate: "MultiAddress", + }, + transfer_approved: { + id: "u16", + owner: "MultiAddress", + destination: "MultiAddress", + amount: "Compact", + }, + touch: { + id: "u16", + }, + refund: { + id: "u16", + allowBurn: "bool", + }, + set_min_balance: { + id: "u16", + minBalance: "u128", + }, + touch_other: { + id: "u16", + who: "MultiAddress", + }, + refund_other: { + id: "u16", + who: "MultiAddress", + }, + block: { + id: "u16", + who: "MultiAddress", + }, + }, + }, + /** Lookup305: pallet_foreign_asset_creator::pallet::Call */ + PalletForeignAssetCreatorCall: { + _enum: { + create_foreign_asset: { + foreignAsset: "StagingXcmV3MultiLocation", + assetId: "u16", + admin: "AccountId32", + isSufficient: "bool", + minBalance: "u128", + }, + change_existing_asset_type: { + assetId: "u16", + newForeignAsset: "StagingXcmV3MultiLocation", + }, + remove_existing_asset_type: { + assetId: "u16", + }, + destroy_foreign_asset: { + assetId: "u16", + }, + }, + }, + /** Lookup306: pallet_asset_rate::pallet::Call */ + PalletAssetRateCall: { + _enum: { + create: { + assetKind: "u16", + rate: "u128", + }, + update: { + assetKind: "u16", + rate: "u128", + }, + remove: { + assetKind: "u16", + }, + }, + }, + /** Lookup307: pallet_root_testing::pallet::Call */ PalletRootTestingCall: { _enum: { fill_block: { @@ -2545,27 +2903,27 @@ export default { }, }, }, - /** Lookup302: pallet_sudo::pallet::Error */ + /** Lookup308: pallet_sudo::pallet::Error */ PalletSudoError: { _enum: ["RequireSudo"], }, - /** Lookup303: pallet_utility::pallet::Error */ + /** Lookup309: pallet_utility::pallet::Error */ PalletUtilityError: { _enum: ["TooManyCalls"], }, - /** Lookup306: pallet_proxy::ProxyDefinition */ + /** Lookup312: pallet_proxy::ProxyDefinition */ PalletProxyProxyDefinition: { delegate: "AccountId32", proxyType: "DanceboxRuntimeProxyType", delay: "u32", }, - /** Lookup310: pallet_proxy::Announcement */ + /** Lookup316: pallet_proxy::Announcement */ PalletProxyAnnouncement: { real: "AccountId32", callHash: "H256", height: "u32", }, - /** Lookup312: pallet_proxy::pallet::Error */ + /** Lookup318: pallet_proxy::pallet::Error */ PalletProxyError: { _enum: [ "TooMany", @@ -2578,34 +2936,34 @@ export default { "NoSelfProxy", ], }, - /** Lookup313: pallet_migrations::pallet::Error */ + /** Lookup319: pallet_migrations::pallet::Error */ PalletMigrationsError: { _enum: ["PreimageMissing", "WrongUpperBound", "PreimageIsTooBig", "PreimageAlreadyExists"], }, - /** Lookup314: pallet_maintenance_mode::pallet::Error */ + /** Lookup320: pallet_maintenance_mode::pallet::Error */ PalletMaintenanceModeError: { _enum: ["AlreadyInMaintenanceMode", "NotInMaintenanceMode"], }, - /** Lookup315: pallet_tx_pause::pallet::Error */ + /** Lookup321: pallet_tx_pause::pallet::Error */ PalletTxPauseError: { _enum: ["IsPaused", "IsUnpaused", "Unpausable", "NotFound"], }, - /** Lookup317: pallet_balances::types::BalanceLock */ + /** Lookup323: pallet_balances::types::BalanceLock */ PalletBalancesBalanceLock: { id: "[u8;8]", amount: "u128", reasons: "PalletBalancesReasons", }, - /** Lookup318: pallet_balances::types::Reasons */ + /** Lookup324: pallet_balances::types::Reasons */ PalletBalancesReasons: { _enum: ["Fee", "Misc", "All"], }, - /** Lookup321: pallet_balances::types::ReserveData */ + /** Lookup327: pallet_balances::types::ReserveData */ PalletBalancesReserveData: { id: "[u8;8]", amount: "u128", }, - /** Lookup325: dancebox_runtime::RuntimeHoldReason */ + /** Lookup331: dancebox_runtime::RuntimeHoldReason */ DanceboxRuntimeRuntimeHoldReason: { _enum: { __Unused0: "Null", @@ -2645,16 +3003,16 @@ export default { PooledStaking: "PalletPooledStakingHoldReason", }, }, - /** Lookup326: pallet_pooled_staking::pallet::HoldReason */ + /** Lookup332: pallet_pooled_staking::pallet::HoldReason */ PalletPooledStakingHoldReason: { _enum: ["PooledStake"], }, - /** Lookup329: pallet_balances::types::IdAmount */ + /** Lookup335: pallet_balances::types::IdAmount */ PalletBalancesIdAmount: { id: "[u8;8]", amount: "u128", }, - /** Lookup331: pallet_balances::pallet::Error */ + /** Lookup337: pallet_balances::pallet::Error */ PalletBalancesError: { _enum: [ "VestingBalance", @@ -2669,18 +3027,18 @@ export default { "TooManyFreezes", ], }, - /** Lookup332: pallet_transaction_payment::Releases */ + /** Lookup338: pallet_transaction_payment::Releases */ PalletTransactionPaymentReleases: { _enum: ["V1Ancient", "V2"], }, - /** Lookup333: pallet_identity::types::Registration> */ + /** Lookup339: pallet_identity::types::Registration> */ PalletIdentityRegistration: { judgements: "Vec<(u32,PalletIdentityJudgement)>", deposit: "u128", info: "PalletIdentitySimpleIdentityInfo", }, /** - * Lookup341: pallet_identity::types::RegistrarInfo */ PalletIdentityRegistrarInfo: { @@ -2688,7 +3046,7 @@ export default { fee: "u128", fields: "PalletIdentityBitFlags", }, - /** Lookup343: pallet_identity::pallet::Error */ + /** Lookup349: pallet_identity::pallet::Error */ PalletIdentityError: { _enum: [ "TooManySubAccounts", @@ -2711,12 +3069,12 @@ export default { "JudgementPaymentFailed", ], }, - /** Lookup348: pallet_registrar::pallet::DepositInfo */ + /** Lookup354: pallet_registrar::pallet::DepositInfo */ PalletRegistrarDepositInfo: { creator: "AccountId32", deposit: "u128", }, - /** Lookup349: pallet_registrar::pallet::Error */ + /** Lookup355: pallet_registrar::pallet::Error */ PalletRegistrarError: { _enum: [ "ParaIdAlreadyRegistered", @@ -2730,29 +3088,32 @@ export default { "NotSufficientDeposit", ], }, - /** Lookup350: pallet_configuration::HostConfiguration */ + /** Lookup356: pallet_configuration::HostConfiguration */ PalletConfigurationHostConfiguration: { maxCollators: "u32", minOrchestratorCollators: "u32", maxOrchestratorCollators: "u32", collatorsPerContainer: "u32", fullRotationPeriod: "u32", + collatorsPerParathread: "u32", + parathreadsPerCollator: "u32", + targetContainerChainFullness: "Perbill", }, - /** Lookup353: pallet_configuration::pallet::Error */ + /** Lookup359: pallet_configuration::pallet::Error */ PalletConfigurationError: { _enum: ["InvalidNewValue"], }, - /** Lookup354: dp_collator_assignment::AssignedCollators */ + /** Lookup360: dp_collator_assignment::AssignedCollators */ DpCollatorAssignmentAssignedCollatorsAccountId32: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup359: pallet_author_noting::pallet::ContainerChainBlockInfo */ + /** Lookup365: pallet_author_noting::pallet::ContainerChainBlockInfo */ PalletAuthorNotingContainerChainBlockInfo: { blockNumber: "u32", author: "AccountId32", }, - /** Lookup360: pallet_author_noting::pallet::Error */ + /** Lookup366: pallet_author_noting::pallet::Error */ PalletAuthorNotingError: { _enum: [ "FailedReading", @@ -2764,39 +3125,39 @@ export default { "NonAuraDigest", ], }, - /** Lookup361: dp_collator_assignment::AssignedCollators */ + /** Lookup367: dp_collator_assignment::AssignedCollators */ DpCollatorAssignmentAssignedCollatorsPublic: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup366: pallet_services_payment::pallet::Error */ + /** Lookup372: pallet_services_payment::pallet::Error */ PalletServicesPaymentError: { _enum: ["InsufficientFundsToPurchaseCredits", "InsufficientCredits", "CreditPriceTooExpensive"], }, - /** Lookup367: pallet_data_preservers::pallet::Error */ + /** Lookup373: pallet_data_preservers::pallet::Error */ PalletDataPreserversError: { _enum: ["NoBootNodes"], }, - /** Lookup369: pallet_invulnerables::pallet::Error */ + /** Lookup375: pallet_invulnerables::pallet::Error */ PalletInvulnerablesError: { _enum: ["TooManyInvulnerables", "AlreadyInvulnerable", "NotInvulnerable"], }, - /** Lookup374: sp_core::crypto::KeyTypeId */ + /** Lookup380: sp_core::crypto::KeyTypeId */ SpCoreCryptoKeyTypeId: "[u8;4]", - /** Lookup375: pallet_session::pallet::Error */ + /** Lookup381: pallet_session::pallet::Error */ PalletSessionError: { _enum: ["InvalidProof", "NoAssociatedValidatorId", "DuplicatedKey", "NoKeys", "NoAccount"], }, - /** Lookup379: pallet_author_inherent::pallet::Error */ + /** Lookup385: pallet_author_inherent::pallet::Error */ PalletAuthorInherentError: { _enum: ["AuthorAlreadySet", "NoAccountId", "CannotBeAuthor"], }, - /** Lookup381: pallet_pooled_staking::candidate::EligibleCandidate */ + /** Lookup387: pallet_pooled_staking::candidate::EligibleCandidate */ PalletPooledStakingCandidateEligibleCandidate: { candidate: "AccountId32", stake: "u128", }, - /** Lookup384: pallet_pooled_staking::pallet::PoolsKey */ + /** Lookup390: pallet_pooled_staking::pallet::PoolsKey */ PalletPooledStakingPoolsKey: { _enum: { CandidateTotalStake: "Null", @@ -2838,7 +3199,7 @@ export default { }, }, }, - /** Lookup386: pallet_pooled_staking::pallet::Error */ + /** Lookup392: pallet_pooled_staking::pallet::Error */ PalletPooledStakingError: { _enum: { InvalidPalletSetting: "Null", @@ -2857,26 +3218,26 @@ export default { SwapResultsInZeroShares: "Null", }, }, - /** Lookup387: pallet_inflation_rewards::pallet::ChainsToRewardValue */ + /** Lookup393: pallet_inflation_rewards::pallet::ChainsToRewardValue */ PalletInflationRewardsChainsToRewardValue: { paraIds: "Vec", rewardsPerChain: "u128", }, - /** Lookup389: cumulus_pallet_xcmp_queue::InboundChannelDetails */ + /** Lookup395: cumulus_pallet_xcmp_queue::InboundChannelDetails */ CumulusPalletXcmpQueueInboundChannelDetails: { sender: "u32", state: "CumulusPalletXcmpQueueInboundState", messageMetadata: "Vec<(u32,PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat)>", }, - /** Lookup390: cumulus_pallet_xcmp_queue::InboundState */ + /** Lookup396: cumulus_pallet_xcmp_queue::InboundState */ CumulusPalletXcmpQueueInboundState: { _enum: ["Ok", "Suspended"], }, - /** Lookup393: polkadot_parachain_primitives::primitives::XcmpMessageFormat */ + /** Lookup399: polkadot_parachain_primitives::primitives::XcmpMessageFormat */ PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat: { _enum: ["ConcatenatedVersionedXcm", "ConcatenatedEncodedBlob", "Signals"], }, - /** Lookup396: cumulus_pallet_xcmp_queue::OutboundChannelDetails */ + /** Lookup402: cumulus_pallet_xcmp_queue::OutboundChannelDetails */ CumulusPalletXcmpQueueOutboundChannelDetails: { recipient: "u32", state: "CumulusPalletXcmpQueueOutboundState", @@ -2884,11 +3245,11 @@ export default { firstIndex: "u16", lastIndex: "u16", }, - /** Lookup397: cumulus_pallet_xcmp_queue::OutboundState */ + /** Lookup403: cumulus_pallet_xcmp_queue::OutboundState */ CumulusPalletXcmpQueueOutboundState: { _enum: ["Ok", "Suspended"], }, - /** Lookup399: cumulus_pallet_xcmp_queue::QueueConfigData */ + /** Lookup405: cumulus_pallet_xcmp_queue::QueueConfigData */ CumulusPalletXcmpQueueQueueConfigData: { suspendThreshold: "u32", dropThreshold: "u32", @@ -2897,27 +3258,27 @@ export default { weightRestrictDecay: "SpWeightsWeightV2Weight", xcmpMaxIndividualWeight: "SpWeightsWeightV2Weight", }, - /** Lookup401: cumulus_pallet_xcmp_queue::pallet::Error */ + /** Lookup407: cumulus_pallet_xcmp_queue::pallet::Error */ CumulusPalletXcmpQueueError: { _enum: ["FailedToSend", "BadXcmOrigin", "BadXcm", "BadOverweightIndex", "WeightOverLimit"], }, - /** Lookup402: cumulus_pallet_xcm::pallet::Error */ + /** Lookup408: cumulus_pallet_xcm::pallet::Error */ CumulusPalletXcmError: "Null", - /** Lookup403: cumulus_pallet_dmp_queue::ConfigData */ + /** Lookup409: cumulus_pallet_dmp_queue::ConfigData */ CumulusPalletDmpQueueConfigData: { maxIndividual: "SpWeightsWeightV2Weight", }, - /** Lookup404: cumulus_pallet_dmp_queue::PageIndexData */ + /** Lookup410: cumulus_pallet_dmp_queue::PageIndexData */ CumulusPalletDmpQueuePageIndexData: { beginUsed: "u32", endUsed: "u32", overweightCount: "u64", }, - /** Lookup407: cumulus_pallet_dmp_queue::pallet::Error */ + /** Lookup413: cumulus_pallet_dmp_queue::pallet::Error */ CumulusPalletDmpQueueError: { _enum: ["Unknown", "OverLimit"], }, - /** Lookup408: pallet_xcm::pallet::QueryStatus */ + /** Lookup414: pallet_xcm::pallet::QueryStatus */ PalletXcmQueryStatus: { _enum: { Pending: { @@ -2936,7 +3297,7 @@ export default { }, }, }, - /** Lookup412: xcm::VersionedResponse */ + /** Lookup418: xcm::VersionedResponse */ XcmVersionedResponse: { _enum: { __Unused0: "Null", @@ -2945,7 +3306,7 @@ export default { V3: "XcmV3Response", }, }, - /** Lookup418: pallet_xcm::pallet::VersionMigrationStage */ + /** Lookup424: pallet_xcm::pallet::VersionMigrationStage */ PalletXcmVersionMigrationStage: { _enum: { MigrateSupportedVersion: "Null", @@ -2954,7 +3315,7 @@ export default { MigrateAndNotifyOldTargets: "Null", }, }, - /** Lookup420: xcm::VersionedAssetId */ + /** Lookup426: xcm::VersionedAssetId */ XcmVersionedAssetId: { _enum: { __Unused0: "Null", @@ -2963,14 +3324,14 @@ export default { V3: "XcmV3MultiassetAssetId", }, }, - /** Lookup421: pallet_xcm::pallet::RemoteLockedFungibleRecord */ + /** Lookup427: pallet_xcm::pallet::RemoteLockedFungibleRecord */ PalletXcmRemoteLockedFungibleRecord: { amount: "u128", owner: "XcmVersionedMultiLocation", locker: "XcmVersionedMultiLocation", consumers: "Vec<(Null,u128)>", }, - /** Lookup428: pallet_xcm::pallet::Error */ + /** Lookup434: pallet_xcm::pallet::Error */ PalletXcmError: { _enum: [ "Unreachable", @@ -2995,7 +3356,93 @@ export default { "InUse", ], }, - /** Lookup432: sp_runtime::MultiSignature */ + /** Lookup435: pallet_assets::types::AssetDetails */ + PalletAssetsAssetDetails: { + owner: "AccountId32", + issuer: "AccountId32", + admin: "AccountId32", + freezer: "AccountId32", + supply: "u128", + deposit: "u128", + minBalance: "u128", + isSufficient: "bool", + accounts: "u32", + sufficients: "u32", + approvals: "u32", + status: "PalletAssetsAssetStatus", + }, + /** Lookup436: pallet_assets::types::AssetStatus */ + PalletAssetsAssetStatus: { + _enum: ["Live", "Frozen", "Destroying"], + }, + /** Lookup438: pallet_assets::types::AssetAccount */ + PalletAssetsAssetAccount: { + balance: "u128", + status: "PalletAssetsAccountStatus", + reason: "PalletAssetsExistenceReason", + extra: "Null", + }, + /** Lookup439: pallet_assets::types::AccountStatus */ + PalletAssetsAccountStatus: { + _enum: ["Liquid", "Frozen", "Blocked"], + }, + /** Lookup440: pallet_assets::types::ExistenceReason */ + PalletAssetsExistenceReason: { + _enum: { + Consumer: "Null", + Sufficient: "Null", + DepositHeld: "u128", + DepositRefunded: "Null", + DepositFrom: "(AccountId32,u128)", + }, + }, + /** Lookup442: pallet_assets::types::Approval */ + PalletAssetsApproval: { + amount: "u128", + deposit: "u128", + }, + /** Lookup443: pallet_assets::types::AssetMetadata> */ + PalletAssetsAssetMetadata: { + deposit: "u128", + name: "Bytes", + symbol: "Bytes", + decimals: "u8", + isFrozen: "bool", + }, + /** Lookup445: pallet_assets::pallet::Error */ + PalletAssetsError: { + _enum: [ + "BalanceLow", + "NoAccount", + "NoPermission", + "Unknown", + "Frozen", + "InUse", + "BadWitness", + "MinBalanceZero", + "UnavailableConsumer", + "BadMetadata", + "Unapproved", + "WouldDie", + "AlreadyExists", + "NoDeposit", + "WouldBurn", + "LiveAsset", + "AssetNotLive", + "IncorrectStatus", + "NotFrozen", + "CallbackFailed", + ], + }, + /** Lookup446: pallet_foreign_asset_creator::pallet::Error */ + PalletForeignAssetCreatorError: { + _enum: ["AssetAlreadyExists", "AssetDoesNotExist"], + }, + /** Lookup447: pallet_asset_rate::pallet::Error */ + PalletAssetRateError: { + _enum: ["UnknownAssetKind", "AlreadyExists"], + }, + /** Lookup452: sp_runtime::MultiSignature */ SpRuntimeMultiSignature: { _enum: { Ed25519: "SpCoreEd25519Signature", @@ -3003,26 +3450,26 @@ export default { Ecdsa: "SpCoreEcdsaSignature", }, }, - /** Lookup433: sp_core::ed25519::Signature */ + /** Lookup453: sp_core::ed25519::Signature */ SpCoreEd25519Signature: "[u8;64]", - /** Lookup435: sp_core::sr25519::Signature */ + /** Lookup455: sp_core::sr25519::Signature */ SpCoreSr25519Signature: "[u8;64]", - /** Lookup436: sp_core::ecdsa::Signature */ + /** Lookup456: sp_core::ecdsa::Signature */ SpCoreEcdsaSignature: "[u8;65]", - /** Lookup439: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ + /** Lookup459: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ FrameSystemExtensionsCheckNonZeroSender: "Null", - /** Lookup440: frame_system::extensions::check_spec_version::CheckSpecVersion */ + /** Lookup460: frame_system::extensions::check_spec_version::CheckSpecVersion */ FrameSystemExtensionsCheckSpecVersion: "Null", - /** Lookup441: frame_system::extensions::check_tx_version::CheckTxVersion */ + /** Lookup461: frame_system::extensions::check_tx_version::CheckTxVersion */ FrameSystemExtensionsCheckTxVersion: "Null", - /** Lookup442: frame_system::extensions::check_genesis::CheckGenesis */ + /** Lookup462: frame_system::extensions::check_genesis::CheckGenesis */ FrameSystemExtensionsCheckGenesis: "Null", - /** Lookup445: frame_system::extensions::check_nonce::CheckNonce */ + /** Lookup465: frame_system::extensions::check_nonce::CheckNonce */ FrameSystemExtensionsCheckNonce: "Compact", - /** Lookup446: frame_system::extensions::check_weight::CheckWeight */ + /** Lookup466: frame_system::extensions::check_weight::CheckWeight */ FrameSystemExtensionsCheckWeight: "Null", - /** Lookup447: pallet_transaction_payment::ChargeTransactionPayment */ + /** Lookup467: pallet_transaction_payment::ChargeTransactionPayment */ PalletTransactionPaymentChargeTransactionPayment: "Compact", - /** Lookup448: dancebox_runtime::Runtime */ + /** Lookup468: dancebox_runtime::Runtime */ DanceboxRuntimeRuntime: "Null", }; diff --git a/typescript-api/src/dancebox/interfaces/registry.ts b/typescript-api/src/dancebox/interfaces/registry.ts index 72acbb6f3..127b7c504 100644 --- a/typescript-api/src/dancebox/interfaces/registry.ts +++ b/typescript-api/src/dancebox/interfaces/registry.ts @@ -65,6 +65,19 @@ import type { FrameSystemLimitsWeightsPerClass, FrameSystemPhase, NimbusPrimitivesNimbusCryptoPublic, + PalletAssetRateCall, + PalletAssetRateError, + PalletAssetRateEvent, + PalletAssetsAccountStatus, + PalletAssetsApproval, + PalletAssetsAssetAccount, + PalletAssetsAssetDetails, + PalletAssetsAssetMetadata, + PalletAssetsAssetStatus, + PalletAssetsCall, + PalletAssetsError, + PalletAssetsEvent, + PalletAssetsExistenceReason, PalletAuthorInherentCall, PalletAuthorInherentError, PalletAuthorNotingCall, @@ -88,6 +101,9 @@ import type { PalletDataPreserversCall, PalletDataPreserversError, PalletDataPreserversEvent, + PalletForeignAssetCreatorCall, + PalletForeignAssetCreatorError, + PalletForeignAssetCreatorEvent, PalletIdentityBitFlags, PalletIdentityCall, PalletIdentityError, @@ -300,6 +316,19 @@ declare module "@polkadot/types/types/registry" { FrameSystemLimitsWeightsPerClass: FrameSystemLimitsWeightsPerClass; FrameSystemPhase: FrameSystemPhase; NimbusPrimitivesNimbusCryptoPublic: NimbusPrimitivesNimbusCryptoPublic; + PalletAssetRateCall: PalletAssetRateCall; + PalletAssetRateError: PalletAssetRateError; + PalletAssetRateEvent: PalletAssetRateEvent; + PalletAssetsAccountStatus: PalletAssetsAccountStatus; + PalletAssetsApproval: PalletAssetsApproval; + PalletAssetsAssetAccount: PalletAssetsAssetAccount; + PalletAssetsAssetDetails: PalletAssetsAssetDetails; + PalletAssetsAssetMetadata: PalletAssetsAssetMetadata; + PalletAssetsAssetStatus: PalletAssetsAssetStatus; + PalletAssetsCall: PalletAssetsCall; + PalletAssetsError: PalletAssetsError; + PalletAssetsEvent: PalletAssetsEvent; + PalletAssetsExistenceReason: PalletAssetsExistenceReason; PalletAuthorInherentCall: PalletAuthorInherentCall; PalletAuthorInherentError: PalletAuthorInherentError; PalletAuthorNotingCall: PalletAuthorNotingCall; @@ -323,6 +352,9 @@ declare module "@polkadot/types/types/registry" { PalletDataPreserversCall: PalletDataPreserversCall; PalletDataPreserversError: PalletDataPreserversError; PalletDataPreserversEvent: PalletDataPreserversEvent; + PalletForeignAssetCreatorCall: PalletForeignAssetCreatorCall; + PalletForeignAssetCreatorError: PalletForeignAssetCreatorError; + PalletForeignAssetCreatorEvent: PalletForeignAssetCreatorEvent; PalletIdentityBitFlags: PalletIdentityBitFlags; PalletIdentityCall: PalletIdentityCall; PalletIdentityError: PalletIdentityError; diff --git a/typescript-api/src/dancebox/interfaces/types-lookup.ts b/typescript-api/src/dancebox/interfaces/types-lookup.ts index 167fbbf21..ae95d81e7 100644 --- a/typescript-api/src/dancebox/interfaces/types-lookup.ts +++ b/typescript-api/src/dancebox/interfaces/types-lookup.ts @@ -2040,7 +2040,218 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3"; } - /** @name FrameSystemPhase (122) */ + /** @name PalletAssetsEvent (122) */ + interface PalletAssetsEvent extends Enum { + readonly isCreated: boolean; + readonly asCreated: { + readonly assetId: u16; + readonly creator: AccountId32; + readonly owner: AccountId32; + } & Struct; + readonly isIssued: boolean; + readonly asIssued: { + readonly assetId: u16; + readonly owner: AccountId32; + readonly amount: u128; + } & Struct; + readonly isTransferred: boolean; + readonly asTransferred: { + readonly assetId: u16; + readonly from: AccountId32; + readonly to: AccountId32; + readonly amount: u128; + } & Struct; + readonly isBurned: boolean; + readonly asBurned: { + readonly assetId: u16; + readonly owner: AccountId32; + readonly balance: u128; + } & Struct; + readonly isTeamChanged: boolean; + readonly asTeamChanged: { + readonly assetId: u16; + readonly issuer: AccountId32; + readonly admin: AccountId32; + readonly freezer: AccountId32; + } & Struct; + readonly isOwnerChanged: boolean; + readonly asOwnerChanged: { + readonly assetId: u16; + readonly owner: AccountId32; + } & Struct; + readonly isFrozen: boolean; + readonly asFrozen: { + readonly assetId: u16; + readonly who: AccountId32; + } & Struct; + readonly isThawed: boolean; + readonly asThawed: { + readonly assetId: u16; + readonly who: AccountId32; + } & Struct; + readonly isAssetFrozen: boolean; + readonly asAssetFrozen: { + readonly assetId: u16; + } & Struct; + readonly isAssetThawed: boolean; + readonly asAssetThawed: { + readonly assetId: u16; + } & Struct; + readonly isAccountsDestroyed: boolean; + readonly asAccountsDestroyed: { + readonly assetId: u16; + readonly accountsDestroyed: u32; + readonly accountsRemaining: u32; + } & Struct; + readonly isApprovalsDestroyed: boolean; + readonly asApprovalsDestroyed: { + readonly assetId: u16; + readonly approvalsDestroyed: u32; + readonly approvalsRemaining: u32; + } & Struct; + readonly isDestructionStarted: boolean; + readonly asDestructionStarted: { + readonly assetId: u16; + } & Struct; + readonly isDestroyed: boolean; + readonly asDestroyed: { + readonly assetId: u16; + } & Struct; + readonly isForceCreated: boolean; + readonly asForceCreated: { + readonly assetId: u16; + readonly owner: AccountId32; + } & Struct; + readonly isMetadataSet: boolean; + readonly asMetadataSet: { + readonly assetId: u16; + readonly name: Bytes; + readonly symbol: Bytes; + readonly decimals: u8; + readonly isFrozen: bool; + } & Struct; + readonly isMetadataCleared: boolean; + readonly asMetadataCleared: { + readonly assetId: u16; + } & Struct; + readonly isApprovedTransfer: boolean; + readonly asApprovedTransfer: { + readonly assetId: u16; + readonly source: AccountId32; + readonly delegate: AccountId32; + readonly amount: u128; + } & Struct; + readonly isApprovalCancelled: boolean; + readonly asApprovalCancelled: { + readonly assetId: u16; + readonly owner: AccountId32; + readonly delegate: AccountId32; + } & Struct; + readonly isTransferredApproved: boolean; + readonly asTransferredApproved: { + readonly assetId: u16; + readonly owner: AccountId32; + readonly delegate: AccountId32; + readonly destination: AccountId32; + readonly amount: u128; + } & Struct; + readonly isAssetStatusChanged: boolean; + readonly asAssetStatusChanged: { + readonly assetId: u16; + } & Struct; + readonly isAssetMinBalanceChanged: boolean; + readonly asAssetMinBalanceChanged: { + readonly assetId: u16; + readonly newMinBalance: u128; + } & Struct; + readonly isTouched: boolean; + readonly asTouched: { + readonly assetId: u16; + readonly who: AccountId32; + readonly depositor: AccountId32; + } & Struct; + readonly isBlocked: boolean; + readonly asBlocked: { + readonly assetId: u16; + readonly who: AccountId32; + } & Struct; + readonly type: + | "Created" + | "Issued" + | "Transferred" + | "Burned" + | "TeamChanged" + | "OwnerChanged" + | "Frozen" + | "Thawed" + | "AssetFrozen" + | "AssetThawed" + | "AccountsDestroyed" + | "ApprovalsDestroyed" + | "DestructionStarted" + | "Destroyed" + | "ForceCreated" + | "MetadataSet" + | "MetadataCleared" + | "ApprovedTransfer" + | "ApprovalCancelled" + | "TransferredApproved" + | "AssetStatusChanged" + | "AssetMinBalanceChanged" + | "Touched" + | "Blocked"; + } + + /** @name PalletForeignAssetCreatorEvent (123) */ + interface PalletForeignAssetCreatorEvent extends Enum { + readonly isForeignAssetCreated: boolean; + readonly asForeignAssetCreated: { + readonly assetId: u16; + readonly foreignAsset: StagingXcmV3MultiLocation; + } & Struct; + readonly isForeignAssetTypeChanged: boolean; + readonly asForeignAssetTypeChanged: { + readonly assetId: u16; + readonly newForeignAsset: StagingXcmV3MultiLocation; + } & Struct; + readonly isForeignAssetRemoved: boolean; + readonly asForeignAssetRemoved: { + readonly assetId: u16; + readonly foreignAsset: StagingXcmV3MultiLocation; + } & Struct; + readonly isForeignAssetDestroyed: boolean; + readonly asForeignAssetDestroyed: { + readonly assetId: u16; + readonly foreignAsset: StagingXcmV3MultiLocation; + } & Struct; + readonly type: + | "ForeignAssetCreated" + | "ForeignAssetTypeChanged" + | "ForeignAssetRemoved" + | "ForeignAssetDestroyed"; + } + + /** @name PalletAssetRateEvent (124) */ + interface PalletAssetRateEvent extends Enum { + readonly isAssetRateCreated: boolean; + readonly asAssetRateCreated: { + readonly assetKind: u16; + readonly rate: u128; + } & Struct; + readonly isAssetRateRemoved: boolean; + readonly asAssetRateRemoved: { + readonly assetKind: u16; + } & Struct; + readonly isAssetRateUpdated: boolean; + readonly asAssetRateUpdated: { + readonly assetKind: u16; + readonly old: u128; + readonly new_: u128; + } & Struct; + readonly type: "AssetRateCreated" | "AssetRateRemoved" | "AssetRateUpdated"; + } + + /** @name FrameSystemPhase (126) */ interface FrameSystemPhase extends Enum { readonly isApplyExtrinsic: boolean; readonly asApplyExtrinsic: u32; @@ -2049,13 +2260,13 @@ declare module "@polkadot/types/lookup" { readonly type: "ApplyExtrinsic" | "Finalization" | "Initialization"; } - /** @name FrameSystemLastRuntimeUpgradeInfo (126) */ + /** @name FrameSystemLastRuntimeUpgradeInfo (130) */ interface FrameSystemLastRuntimeUpgradeInfo extends Struct { readonly specVersion: Compact; readonly specName: Text; } - /** @name FrameSystemCall (128) */ + /** @name FrameSystemCall (132) */ interface FrameSystemCall extends Enum { readonly isRemark: boolean; readonly asRemark: { @@ -2101,21 +2312,21 @@ declare module "@polkadot/types/lookup" { | "RemarkWithEvent"; } - /** @name FrameSystemLimitsBlockWeights (132) */ + /** @name FrameSystemLimitsBlockWeights (136) */ interface FrameSystemLimitsBlockWeights extends Struct { readonly baseBlock: SpWeightsWeightV2Weight; readonly maxBlock: SpWeightsWeightV2Weight; readonly perClass: FrameSupportDispatchPerDispatchClassWeightsPerClass; } - /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (133) */ + /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (137) */ interface FrameSupportDispatchPerDispatchClassWeightsPerClass extends Struct { readonly normal: FrameSystemLimitsWeightsPerClass; readonly operational: FrameSystemLimitsWeightsPerClass; readonly mandatory: FrameSystemLimitsWeightsPerClass; } - /** @name FrameSystemLimitsWeightsPerClass (134) */ + /** @name FrameSystemLimitsWeightsPerClass (138) */ interface FrameSystemLimitsWeightsPerClass extends Struct { readonly baseExtrinsic: SpWeightsWeightV2Weight; readonly maxExtrinsic: Option; @@ -2123,25 +2334,25 @@ declare module "@polkadot/types/lookup" { readonly reserved: Option; } - /** @name FrameSystemLimitsBlockLength (136) */ + /** @name FrameSystemLimitsBlockLength (140) */ interface FrameSystemLimitsBlockLength extends Struct { readonly max: FrameSupportDispatchPerDispatchClassU32; } - /** @name FrameSupportDispatchPerDispatchClassU32 (137) */ + /** @name FrameSupportDispatchPerDispatchClassU32 (141) */ interface FrameSupportDispatchPerDispatchClassU32 extends Struct { readonly normal: u32; readonly operational: u32; readonly mandatory: u32; } - /** @name SpWeightsRuntimeDbWeight (138) */ + /** @name SpWeightsRuntimeDbWeight (142) */ interface SpWeightsRuntimeDbWeight extends Struct { readonly read: u64; readonly write: u64; } - /** @name SpVersionRuntimeVersion (139) */ + /** @name SpVersionRuntimeVersion (143) */ interface SpVersionRuntimeVersion extends Struct { readonly specName: Text; readonly implName: Text; @@ -2153,7 +2364,7 @@ declare module "@polkadot/types/lookup" { readonly stateVersion: u8; } - /** @name FrameSystemError (143) */ + /** @name FrameSystemError (147) */ interface FrameSystemError extends Enum { readonly isInvalidSpecName: boolean; readonly isSpecVersionNeedsToIncrease: boolean; @@ -2170,41 +2381,41 @@ declare module "@polkadot/types/lookup" { | "CallFiltered"; } - /** @name CumulusPalletParachainSystemUnincludedSegmentAncestor (145) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentAncestor (149) */ interface CumulusPalletParachainSystemUnincludedSegmentAncestor extends Struct { readonly usedBandwidth: CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth; readonly paraHeadHash: Option; readonly consumedGoAheadSignal: Option; } - /** @name CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth (146) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth (150) */ interface CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth extends Struct { readonly umpMsgCount: u32; readonly umpTotalBytes: u32; readonly hrmpOutgoing: BTreeMap; } - /** @name CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate (148) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate (152) */ interface CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate extends Struct { readonly msgCount: u32; readonly totalBytes: u32; } - /** @name PolkadotPrimitivesV6UpgradeGoAhead (153) */ + /** @name PolkadotPrimitivesV6UpgradeGoAhead (157) */ interface PolkadotPrimitivesV6UpgradeGoAhead extends Enum { readonly isAbort: boolean; readonly isGoAhead: boolean; readonly type: "Abort" | "GoAhead"; } - /** @name CumulusPalletParachainSystemUnincludedSegmentSegmentTracker (154) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentSegmentTracker (158) */ interface CumulusPalletParachainSystemUnincludedSegmentSegmentTracker extends Struct { readonly usedBandwidth: CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth; readonly hrmpWatermark: Option; readonly consumedGoAheadSignal: Option; } - /** @name PolkadotPrimitivesV6PersistedValidationData (155) */ + /** @name PolkadotPrimitivesV6PersistedValidationData (159) */ interface PolkadotPrimitivesV6PersistedValidationData extends Struct { readonly parentHead: Bytes; readonly relayParentNumber: u32; @@ -2212,18 +2423,18 @@ declare module "@polkadot/types/lookup" { readonly maxPovSize: u32; } - /** @name PolkadotPrimitivesV6UpgradeRestriction (158) */ + /** @name PolkadotPrimitivesV6UpgradeRestriction (162) */ interface PolkadotPrimitivesV6UpgradeRestriction extends Enum { readonly isPresent: boolean; readonly type: "Present"; } - /** @name SpTrieStorageProof (159) */ + /** @name SpTrieStorageProof (163) */ interface SpTrieStorageProof extends Struct { readonly trieNodes: BTreeSet; } - /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (161) */ + /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (165) */ interface CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot extends Struct { readonly dmqMqcHead: H256; readonly relayDispatchQueueRemainingCapacity: CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity; @@ -2231,13 +2442,13 @@ declare module "@polkadot/types/lookup" { readonly egressChannels: Vec>; } - /** @name CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity (162) */ + /** @name CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity (166) */ interface CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity extends Struct { readonly remainingCount: u32; readonly remainingSize: u32; } - /** @name PolkadotPrimitivesV6AbridgedHrmpChannel (165) */ + /** @name PolkadotPrimitivesV6AbridgedHrmpChannel (169) */ interface PolkadotPrimitivesV6AbridgedHrmpChannel extends Struct { readonly maxCapacity: u32; readonly maxTotalSize: u32; @@ -2247,7 +2458,7 @@ declare module "@polkadot/types/lookup" { readonly mqcHead: Option; } - /** @name PolkadotPrimitivesV6AbridgedHostConfiguration (166) */ + /** @name PolkadotPrimitivesV6AbridgedHostConfiguration (170) */ interface PolkadotPrimitivesV6AbridgedHostConfiguration extends Struct { readonly maxCodeSize: u32; readonly maxHeadDataSize: u32; @@ -2261,25 +2472,25 @@ declare module "@polkadot/types/lookup" { readonly asyncBackingParams: PolkadotPrimitivesV6AsyncBackingAsyncBackingParams; } - /** @name PolkadotPrimitivesV6AsyncBackingAsyncBackingParams (167) */ + /** @name PolkadotPrimitivesV6AsyncBackingAsyncBackingParams (171) */ interface PolkadotPrimitivesV6AsyncBackingAsyncBackingParams extends Struct { readonly maxCandidateDepth: u32; readonly allowedAncestryLen: u32; } - /** @name PolkadotCorePrimitivesOutboundHrmpMessage (173) */ + /** @name PolkadotCorePrimitivesOutboundHrmpMessage (177) */ interface PolkadotCorePrimitivesOutboundHrmpMessage extends Struct { readonly recipient: u32; readonly data: Bytes; } - /** @name CumulusPalletParachainSystemCodeUpgradeAuthorization (175) */ + /** @name CumulusPalletParachainSystemCodeUpgradeAuthorization (178) */ interface CumulusPalletParachainSystemCodeUpgradeAuthorization extends Struct { readonly codeHash: H256; readonly checkVersion: bool; } - /** @name CumulusPalletParachainSystemCall (176) */ + /** @name CumulusPalletParachainSystemCall (179) */ interface CumulusPalletParachainSystemCall extends Enum { readonly isSetValidationData: boolean; readonly asSetValidationData: { @@ -2301,7 +2512,7 @@ declare module "@polkadot/types/lookup" { readonly type: "SetValidationData" | "SudoSendUpwardMessage" | "AuthorizeUpgrade" | "EnactAuthorizedUpgrade"; } - /** @name CumulusPrimitivesParachainInherentParachainInherentData (177) */ + /** @name CumulusPrimitivesParachainInherentParachainInherentData (180) */ interface CumulusPrimitivesParachainInherentParachainInherentData extends Struct { readonly validationData: PolkadotPrimitivesV6PersistedValidationData; readonly relayChainState: SpTrieStorageProof; @@ -2309,19 +2520,19 @@ declare module "@polkadot/types/lookup" { readonly horizontalMessages: BTreeMap>; } - /** @name PolkadotCorePrimitivesInboundDownwardMessage (179) */ + /** @name PolkadotCorePrimitivesInboundDownwardMessage (182) */ interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct { readonly sentAt: u32; readonly msg: Bytes; } - /** @name PolkadotCorePrimitivesInboundHrmpMessage (182) */ + /** @name PolkadotCorePrimitivesInboundHrmpMessage (185) */ interface PolkadotCorePrimitivesInboundHrmpMessage extends Struct { readonly sentAt: u32; readonly data: Bytes; } - /** @name CumulusPalletParachainSystemError (185) */ + /** @name CumulusPalletParachainSystemError (188) */ interface CumulusPalletParachainSystemError extends Enum { readonly isOverlappingUpgrades: boolean; readonly isProhibitedByPolkadot: boolean; @@ -2342,7 +2553,7 @@ declare module "@polkadot/types/lookup" { | "Unauthorized"; } - /** @name PalletTimestampCall (186) */ + /** @name PalletTimestampCall (189) */ interface PalletTimestampCall extends Enum { readonly isSet: boolean; readonly asSet: { @@ -2351,10 +2562,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Set"; } - /** @name ParachainInfoCall (187) */ + /** @name ParachainInfoCall (190) */ type ParachainInfoCall = Null; - /** @name PalletSudoCall (188) */ + /** @name PalletSudoCall (191) */ interface PalletSudoCall extends Enum { readonly isSudo: boolean; readonly asSudo: { @@ -2377,7 +2588,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Sudo" | "SudoUncheckedWeight" | "SetKey" | "SudoAs"; } - /** @name PalletUtilityCall (190) */ + /** @name PalletUtilityCall (193) */ interface PalletUtilityCall extends Enum { readonly isBatch: boolean; readonly asBatch: { @@ -2409,7 +2620,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Batch" | "AsDerivative" | "BatchAll" | "DispatchAs" | "ForceBatch" | "WithWeight"; } - /** @name DanceboxRuntimeOriginCaller (192) */ + /** @name DanceboxRuntimeOriginCaller (195) */ interface DanceboxRuntimeOriginCaller extends Enum { readonly isSystem: boolean; readonly asSystem: FrameSupportDispatchRawOrigin; @@ -2421,7 +2632,7 @@ declare module "@polkadot/types/lookup" { readonly type: "System" | "Void" | "CumulusXcm" | "PolkadotXcm"; } - /** @name FrameSupportDispatchRawOrigin (193) */ + /** @name FrameSupportDispatchRawOrigin (196) */ interface FrameSupportDispatchRawOrigin extends Enum { readonly isRoot: boolean; readonly isSigned: boolean; @@ -2430,7 +2641,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Root" | "Signed" | "None"; } - /** @name CumulusPalletXcmOrigin (194) */ + /** @name CumulusPalletXcmOrigin (197) */ interface CumulusPalletXcmOrigin extends Enum { readonly isRelay: boolean; readonly isSiblingParachain: boolean; @@ -2438,7 +2649,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Relay" | "SiblingParachain"; } - /** @name PalletXcmOrigin (195) */ + /** @name PalletXcmOrigin (198) */ interface PalletXcmOrigin extends Enum { readonly isXcm: boolean; readonly asXcm: StagingXcmV3MultiLocation; @@ -2447,10 +2658,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Xcm" | "Response"; } - /** @name SpCoreVoid (196) */ + /** @name SpCoreVoid (199) */ type SpCoreVoid = Null; - /** @name PalletProxyCall (197) */ + /** @name PalletProxyCall (200) */ interface PalletProxyCall extends Enum { readonly isProxy: boolean; readonly asProxy: { @@ -2520,14 +2731,14 @@ declare module "@polkadot/types/lookup" { | "ProxyAnnounced"; } - /** @name PalletMaintenanceModeCall (201) */ + /** @name PalletMaintenanceModeCall (204) */ interface PalletMaintenanceModeCall extends Enum { readonly isEnterMaintenanceMode: boolean; readonly isResumeNormalOperation: boolean; readonly type: "EnterMaintenanceMode" | "ResumeNormalOperation"; } - /** @name PalletTxPauseCall (202) */ + /** @name PalletTxPauseCall (205) */ interface PalletTxPauseCall extends Enum { readonly isPause: boolean; readonly asPause: { @@ -2540,7 +2751,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Pause" | "Unpause"; } - /** @name PalletBalancesCall (203) */ + /** @name PalletBalancesCall (206) */ interface PalletBalancesCall extends Enum { readonly isTransferAllowDeath: boolean; readonly asTransferAllowDeath: { @@ -2587,7 +2798,7 @@ declare module "@polkadot/types/lookup" { | "ForceSetBalance"; } - /** @name PalletIdentityCall (204) */ + /** @name PalletIdentityCall (207) */ interface PalletIdentityCall extends Enum { readonly isAddRegistrar: boolean; readonly asAddRegistrar: { @@ -2670,7 +2881,7 @@ declare module "@polkadot/types/lookup" { | "QuitSub"; } - /** @name PalletIdentitySimpleIdentityInfo (205) */ + /** @name PalletIdentitySimpleIdentityInfo (208) */ interface PalletIdentitySimpleIdentityInfo extends Struct { readonly additional: Vec>; readonly display: Data; @@ -2683,7 +2894,7 @@ declare module "@polkadot/types/lookup" { readonly twitter: Data; } - /** @name PalletIdentityBitFlags (241) */ + /** @name PalletIdentityBitFlags (244) */ interface PalletIdentityBitFlags extends Set { readonly isDisplay: boolean; readonly isLegal: boolean; @@ -2695,7 +2906,7 @@ declare module "@polkadot/types/lookup" { readonly isTwitter: boolean; } - /** @name PalletIdentitySimpleIdentityField (242) */ + /** @name PalletIdentitySimpleIdentityField (245) */ interface PalletIdentitySimpleIdentityField extends Enum { readonly isDisplay: boolean; readonly isLegal: boolean; @@ -2708,7 +2919,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Display" | "Legal" | "Web" | "Riot" | "Email" | "PgpFingerprint" | "Image" | "Twitter"; } - /** @name PalletIdentityJudgement (243) */ + /** @name PalletIdentityJudgement (246) */ interface PalletIdentityJudgement extends Enum { readonly isUnknown: boolean; readonly isFeePaid: boolean; @@ -2721,7 +2932,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Unknown" | "FeePaid" | "Reasonable" | "KnownGood" | "OutOfDate" | "LowQuality" | "Erroneous"; } - /** @name PalletRegistrarCall (244) */ + /** @name PalletRegistrarCall (247) */ interface PalletRegistrarCall extends Enum { readonly isRegister: boolean; readonly asRegister: { @@ -2752,7 +2963,7 @@ declare module "@polkadot/types/lookup" { | "UnpauseContainerChain"; } - /** @name TpContainerChainGenesisDataContainerChainGenesisData (245) */ + /** @name TpContainerChainGenesisDataContainerChainGenesisData (248) */ interface TpContainerChainGenesisDataContainerChainGenesisData extends Struct { readonly storage: Vec; readonly name: Bytes; @@ -2762,26 +2973,26 @@ declare module "@polkadot/types/lookup" { readonly properties: TpContainerChainGenesisDataProperties; } - /** @name TpContainerChainGenesisDataContainerChainGenesisDataItem (247) */ + /** @name TpContainerChainGenesisDataContainerChainGenesisDataItem (250) */ interface TpContainerChainGenesisDataContainerChainGenesisDataItem extends Struct { readonly key: Bytes; readonly value: Bytes; } - /** @name TpContainerChainGenesisDataProperties (249) */ + /** @name TpContainerChainGenesisDataProperties (252) */ interface TpContainerChainGenesisDataProperties extends Struct { readonly tokenMetadata: TpContainerChainGenesisDataTokenMetadata; readonly isEthereum: bool; } - /** @name TpContainerChainGenesisDataTokenMetadata (250) */ + /** @name TpContainerChainGenesisDataTokenMetadata (253) */ interface TpContainerChainGenesisDataTokenMetadata extends Struct { readonly tokenSymbol: Bytes; readonly ss58Format: u32; readonly tokenDecimals: u32; } - /** @name PalletConfigurationCall (252) */ + /** @name PalletConfigurationCall (255) */ interface PalletConfigurationCall extends Enum { readonly isSetMaxCollators: boolean; readonly asSetMaxCollators: { @@ -2803,6 +3014,18 @@ declare module "@polkadot/types/lookup" { readonly asSetFullRotationPeriod: { readonly new_: u32; } & Struct; + readonly isSetCollatorsPerParathread: boolean; + readonly asSetCollatorsPerParathread: { + readonly new_: u32; + } & Struct; + readonly isSetParathreadsPerCollator: boolean; + readonly asSetParathreadsPerCollator: { + readonly new_: u32; + } & Struct; + readonly isSetTargetContainerChainFullness: boolean; + readonly asSetTargetContainerChainFullness: { + readonly new_: Perbill; + } & Struct; readonly isSetBypassConsistencyCheck: boolean; readonly asSetBypassConsistencyCheck: { readonly new_: bool; @@ -2813,13 +3036,16 @@ declare module "@polkadot/types/lookup" { | "SetMaxOrchestratorCollators" | "SetCollatorsPerContainer" | "SetFullRotationPeriod" + | "SetCollatorsPerParathread" + | "SetParathreadsPerCollator" + | "SetTargetContainerChainFullness" | "SetBypassConsistencyCheck"; } - /** @name PalletCollatorAssignmentCall (253) */ + /** @name PalletCollatorAssignmentCall (257) */ type PalletCollatorAssignmentCall = Null; - /** @name PalletAuthorNotingCall (254) */ + /** @name PalletAuthorNotingCall (258) */ interface PalletAuthorNotingCall extends Enum { readonly isSetLatestAuthorData: boolean; readonly asSetLatestAuthorData: { @@ -2838,15 +3064,15 @@ declare module "@polkadot/types/lookup" { readonly type: "SetLatestAuthorData" | "SetAuthor" | "KillAuthorData"; } - /** @name TpAuthorNotingInherentOwnParachainInherentData (255) */ + /** @name TpAuthorNotingInherentOwnParachainInherentData (259) */ interface TpAuthorNotingInherentOwnParachainInherentData extends Struct { readonly relayStorageProof: SpTrieStorageProof; } - /** @name PalletAuthorityAssignmentCall (256) */ + /** @name PalletAuthorityAssignmentCall (260) */ type PalletAuthorityAssignmentCall = Null; - /** @name PalletServicesPaymentCall (257) */ + /** @name PalletServicesPaymentCall (261) */ interface PalletServicesPaymentCall extends Enum { readonly isPurchaseCredits: boolean; readonly asPurchaseCredits: { @@ -2867,7 +3093,7 @@ declare module "@polkadot/types/lookup" { readonly type: "PurchaseCredits" | "SetCredits" | "SetGivenFreeCredits"; } - /** @name PalletDataPreserversCall (259) */ + /** @name PalletDataPreserversCall (263) */ interface PalletDataPreserversCall extends Enum { readonly isSetBootNodes: boolean; readonly asSetBootNodes: { @@ -2877,7 +3103,7 @@ declare module "@polkadot/types/lookup" { readonly type: "SetBootNodes"; } - /** @name PalletInvulnerablesCall (263) */ + /** @name PalletInvulnerablesCall (267) */ interface PalletInvulnerablesCall extends Enum { readonly isSetInvulnerables: boolean; readonly asSetInvulnerables: { @@ -2894,7 +3120,7 @@ declare module "@polkadot/types/lookup" { readonly type: "SetInvulnerables" | "AddInvulnerable" | "RemoveInvulnerable"; } - /** @name PalletSessionCall (264) */ + /** @name PalletSessionCall (268) */ interface PalletSessionCall extends Enum { readonly isSetKeys: boolean; readonly asSetKeys: { @@ -2905,24 +3131,24 @@ declare module "@polkadot/types/lookup" { readonly type: "SetKeys" | "PurgeKeys"; } - /** @name DanceboxRuntimeSessionKeys (265) */ + /** @name DanceboxRuntimeSessionKeys (269) */ interface DanceboxRuntimeSessionKeys extends Struct { readonly nimbus: NimbusPrimitivesNimbusCryptoPublic; } - /** @name NimbusPrimitivesNimbusCryptoPublic (266) */ + /** @name NimbusPrimitivesNimbusCryptoPublic (270) */ interface NimbusPrimitivesNimbusCryptoPublic extends SpCoreSr25519Public {} - /** @name SpCoreSr25519Public (267) */ + /** @name SpCoreSr25519Public (271) */ interface SpCoreSr25519Public extends U8aFixed {} - /** @name PalletAuthorInherentCall (268) */ + /** @name PalletAuthorInherentCall (272) */ interface PalletAuthorInherentCall extends Enum { readonly isKickOffAuthorshipValidation: boolean; readonly type: "KickOffAuthorshipValidation"; } - /** @name PalletPooledStakingCall (269) */ + /** @name PalletPooledStakingCall (273) */ interface PalletPooledStakingCall extends Enum { readonly isRebalanceHold: boolean; readonly asRebalanceHold: { @@ -2970,7 +3196,7 @@ declare module "@polkadot/types/lookup" { | "SwapPool"; } - /** @name PalletPooledStakingAllTargetPool (270) */ + /** @name PalletPooledStakingAllTargetPool (274) */ interface PalletPooledStakingAllTargetPool extends Enum { readonly isJoining: boolean; readonly isAutoCompounding: boolean; @@ -2979,13 +3205,13 @@ declare module "@polkadot/types/lookup" { readonly type: "Joining" | "AutoCompounding" | "ManualRewards" | "Leaving"; } - /** @name PalletPooledStakingPendingOperationQuery (272) */ + /** @name PalletPooledStakingPendingOperationQuery (276) */ interface PalletPooledStakingPendingOperationQuery extends Struct { readonly delegator: AccountId32; readonly operation: PalletPooledStakingPendingOperationKey; } - /** @name PalletPooledStakingPendingOperationKey (273) */ + /** @name PalletPooledStakingPendingOperationKey (277) */ interface PalletPooledStakingPendingOperationKey extends Enum { readonly isJoiningAutoCompounding: boolean; readonly asJoiningAutoCompounding: { @@ -3005,7 +3231,7 @@ declare module "@polkadot/types/lookup" { readonly type: "JoiningAutoCompounding" | "JoiningManualRewards" | "Leaving"; } - /** @name PalletPooledStakingSharesOrStake (274) */ + /** @name PalletPooledStakingSharesOrStake (278) */ interface PalletPooledStakingSharesOrStake extends Enum { readonly isShares: boolean; readonly asShares: u128; @@ -3014,7 +3240,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Shares" | "Stake"; } - /** @name CumulusPalletXcmpQueueCall (277) */ + /** @name CumulusPalletXcmpQueueCall (281) */ interface CumulusPalletXcmpQueueCall extends Enum { readonly isServiceOverweight: boolean; readonly asServiceOverweight: { @@ -3059,7 +3285,7 @@ declare module "@polkadot/types/lookup" { | "UpdateXcmpMaxIndividualWeight"; } - /** @name CumulusPalletDmpQueueCall (278) */ + /** @name CumulusPalletDmpQueueCall (282) */ interface CumulusPalletDmpQueueCall extends Enum { readonly isServiceOverweight: boolean; readonly asServiceOverweight: { @@ -3069,7 +3295,7 @@ declare module "@polkadot/types/lookup" { readonly type: "ServiceOverweight"; } - /** @name PalletXcmCall (279) */ + /** @name PalletXcmCall (283) */ interface PalletXcmCall extends Enum { readonly isSend: boolean; readonly asSend: { @@ -3146,7 +3372,7 @@ declare module "@polkadot/types/lookup" { | "ForceSuspension"; } - /** @name XcmVersionedXcm (280) */ + /** @name XcmVersionedXcm (284) */ interface XcmVersionedXcm extends Enum { readonly isV2: boolean; readonly asV2: XcmV2Xcm; @@ -3155,10 +3381,10 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3"; } - /** @name XcmV2Xcm (281) */ + /** @name XcmV2Xcm (285) */ interface XcmV2Xcm extends Vec {} - /** @name XcmV2Instruction (283) */ + /** @name XcmV2Instruction (287) */ interface XcmV2Instruction extends Enum { readonly isWithdrawAsset: boolean; readonly asWithdrawAsset: XcmV2MultiassetMultiAssets; @@ -3306,7 +3532,7 @@ declare module "@polkadot/types/lookup" { | "UnsubscribeVersion"; } - /** @name XcmV2Response (284) */ + /** @name XcmV2Response (288) */ interface XcmV2Response extends Enum { readonly isNull: boolean; readonly isAssets: boolean; @@ -3318,7 +3544,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Null" | "Assets" | "ExecutionResult" | "Version"; } - /** @name XcmV2TraitsError (287) */ + /** @name XcmV2TraitsError (291) */ interface XcmV2TraitsError extends Enum { readonly isOverflow: boolean; readonly isUnimplemented: boolean; @@ -3377,7 +3603,7 @@ declare module "@polkadot/types/lookup" { | "WeightNotComputable"; } - /** @name XcmV2MultiassetMultiAssetFilter (288) */ + /** @name XcmV2MultiassetMultiAssetFilter (292) */ interface XcmV2MultiassetMultiAssetFilter extends Enum { readonly isDefinite: boolean; readonly asDefinite: XcmV2MultiassetMultiAssets; @@ -3386,7 +3612,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Definite" | "Wild"; } - /** @name XcmV2MultiassetWildMultiAsset (289) */ + /** @name XcmV2MultiassetWildMultiAsset (293) */ interface XcmV2MultiassetWildMultiAsset extends Enum { readonly isAll: boolean; readonly isAllOf: boolean; @@ -3397,14 +3623,14 @@ declare module "@polkadot/types/lookup" { readonly type: "All" | "AllOf"; } - /** @name XcmV2MultiassetWildFungibility (290) */ + /** @name XcmV2MultiassetWildFungibility (294) */ interface XcmV2MultiassetWildFungibility extends Enum { readonly isFungible: boolean; readonly isNonFungible: boolean; readonly type: "Fungible" | "NonFungible"; } - /** @name XcmV2WeightLimit (291) */ + /** @name XcmV2WeightLimit (295) */ interface XcmV2WeightLimit extends Enum { readonly isUnlimited: boolean; readonly isLimited: boolean; @@ -3412,7 +3638,270 @@ declare module "@polkadot/types/lookup" { readonly type: "Unlimited" | "Limited"; } - /** @name PalletRootTestingCall (300) */ + /** @name PalletAssetsCall (304) */ + interface PalletAssetsCall extends Enum { + readonly isCreate: boolean; + readonly asCreate: { + readonly id: u16; + readonly admin: MultiAddress; + readonly minBalance: u128; + } & Struct; + readonly isForceCreate: boolean; + readonly asForceCreate: { + readonly id: u16; + readonly owner: MultiAddress; + readonly isSufficient: bool; + readonly minBalance: Compact; + } & Struct; + readonly isStartDestroy: boolean; + readonly asStartDestroy: { + readonly id: u16; + } & Struct; + readonly isDestroyAccounts: boolean; + readonly asDestroyAccounts: { + readonly id: u16; + } & Struct; + readonly isDestroyApprovals: boolean; + readonly asDestroyApprovals: { + readonly id: u16; + } & Struct; + readonly isFinishDestroy: boolean; + readonly asFinishDestroy: { + readonly id: u16; + } & Struct; + readonly isMint: boolean; + readonly asMint: { + readonly id: u16; + readonly beneficiary: MultiAddress; + readonly amount: Compact; + } & Struct; + readonly isBurn: boolean; + readonly asBurn: { + readonly id: u16; + readonly who: MultiAddress; + readonly amount: Compact; + } & Struct; + readonly isTransfer: boolean; + readonly asTransfer: { + readonly id: u16; + readonly target: MultiAddress; + readonly amount: Compact; + } & Struct; + readonly isTransferKeepAlive: boolean; + readonly asTransferKeepAlive: { + readonly id: u16; + readonly target: MultiAddress; + readonly amount: Compact; + } & Struct; + readonly isForceTransfer: boolean; + readonly asForceTransfer: { + readonly id: u16; + readonly source: MultiAddress; + readonly dest: MultiAddress; + readonly amount: Compact; + } & Struct; + readonly isFreeze: boolean; + readonly asFreeze: { + readonly id: u16; + readonly who: MultiAddress; + } & Struct; + readonly isThaw: boolean; + readonly asThaw: { + readonly id: u16; + readonly who: MultiAddress; + } & Struct; + readonly isFreezeAsset: boolean; + readonly asFreezeAsset: { + readonly id: u16; + } & Struct; + readonly isThawAsset: boolean; + readonly asThawAsset: { + readonly id: u16; + } & Struct; + readonly isTransferOwnership: boolean; + readonly asTransferOwnership: { + readonly id: u16; + readonly owner: MultiAddress; + } & Struct; + readonly isSetTeam: boolean; + readonly asSetTeam: { + readonly id: u16; + readonly issuer: MultiAddress; + readonly admin: MultiAddress; + readonly freezer: MultiAddress; + } & Struct; + readonly isSetMetadata: boolean; + readonly asSetMetadata: { + readonly id: u16; + readonly name: Bytes; + readonly symbol: Bytes; + readonly decimals: u8; + } & Struct; + readonly isClearMetadata: boolean; + readonly asClearMetadata: { + readonly id: u16; + } & Struct; + readonly isForceSetMetadata: boolean; + readonly asForceSetMetadata: { + readonly id: u16; + readonly name: Bytes; + readonly symbol: Bytes; + readonly decimals: u8; + readonly isFrozen: bool; + } & Struct; + readonly isForceClearMetadata: boolean; + readonly asForceClearMetadata: { + readonly id: u16; + } & Struct; + readonly isForceAssetStatus: boolean; + readonly asForceAssetStatus: { + readonly id: u16; + readonly owner: MultiAddress; + readonly issuer: MultiAddress; + readonly admin: MultiAddress; + readonly freezer: MultiAddress; + readonly minBalance: Compact; + readonly isSufficient: bool; + readonly isFrozen: bool; + } & Struct; + readonly isApproveTransfer: boolean; + readonly asApproveTransfer: { + readonly id: u16; + readonly delegate: MultiAddress; + readonly amount: Compact; + } & Struct; + readonly isCancelApproval: boolean; + readonly asCancelApproval: { + readonly id: u16; + readonly delegate: MultiAddress; + } & Struct; + readonly isForceCancelApproval: boolean; + readonly asForceCancelApproval: { + readonly id: u16; + readonly owner: MultiAddress; + readonly delegate: MultiAddress; + } & Struct; + readonly isTransferApproved: boolean; + readonly asTransferApproved: { + readonly id: u16; + readonly owner: MultiAddress; + readonly destination: MultiAddress; + readonly amount: Compact; + } & Struct; + readonly isTouch: boolean; + readonly asTouch: { + readonly id: u16; + } & Struct; + readonly isRefund: boolean; + readonly asRefund: { + readonly id: u16; + readonly allowBurn: bool; + } & Struct; + readonly isSetMinBalance: boolean; + readonly asSetMinBalance: { + readonly id: u16; + readonly minBalance: u128; + } & Struct; + readonly isTouchOther: boolean; + readonly asTouchOther: { + readonly id: u16; + readonly who: MultiAddress; + } & Struct; + readonly isRefundOther: boolean; + readonly asRefundOther: { + readonly id: u16; + readonly who: MultiAddress; + } & Struct; + readonly isBlock: boolean; + readonly asBlock: { + readonly id: u16; + readonly who: MultiAddress; + } & Struct; + readonly type: + | "Create" + | "ForceCreate" + | "StartDestroy" + | "DestroyAccounts" + | "DestroyApprovals" + | "FinishDestroy" + | "Mint" + | "Burn" + | "Transfer" + | "TransferKeepAlive" + | "ForceTransfer" + | "Freeze" + | "Thaw" + | "FreezeAsset" + | "ThawAsset" + | "TransferOwnership" + | "SetTeam" + | "SetMetadata" + | "ClearMetadata" + | "ForceSetMetadata" + | "ForceClearMetadata" + | "ForceAssetStatus" + | "ApproveTransfer" + | "CancelApproval" + | "ForceCancelApproval" + | "TransferApproved" + | "Touch" + | "Refund" + | "SetMinBalance" + | "TouchOther" + | "RefundOther" + | "Block"; + } + + /** @name PalletForeignAssetCreatorCall (305) */ + interface PalletForeignAssetCreatorCall extends Enum { + readonly isCreateForeignAsset: boolean; + readonly asCreateForeignAsset: { + readonly foreignAsset: StagingXcmV3MultiLocation; + readonly assetId: u16; + readonly admin: AccountId32; + readonly isSufficient: bool; + readonly minBalance: u128; + } & Struct; + readonly isChangeExistingAssetType: boolean; + readonly asChangeExistingAssetType: { + readonly assetId: u16; + readonly newForeignAsset: StagingXcmV3MultiLocation; + } & Struct; + readonly isRemoveExistingAssetType: boolean; + readonly asRemoveExistingAssetType: { + readonly assetId: u16; + } & Struct; + readonly isDestroyForeignAsset: boolean; + readonly asDestroyForeignAsset: { + readonly assetId: u16; + } & Struct; + readonly type: + | "CreateForeignAsset" + | "ChangeExistingAssetType" + | "RemoveExistingAssetType" + | "DestroyForeignAsset"; + } + + /** @name PalletAssetRateCall (306) */ + interface PalletAssetRateCall extends Enum { + readonly isCreate: boolean; + readonly asCreate: { + readonly assetKind: u16; + readonly rate: u128; + } & Struct; + readonly isUpdate: boolean; + readonly asUpdate: { + readonly assetKind: u16; + readonly rate: u128; + } & Struct; + readonly isRemove: boolean; + readonly asRemove: { + readonly assetKind: u16; + } & Struct; + readonly type: "Create" | "Update" | "Remove"; + } + + /** @name PalletRootTestingCall (307) */ interface PalletRootTestingCall extends Enum { readonly isFillBlock: boolean; readonly asFillBlock: { @@ -3421,33 +3910,33 @@ declare module "@polkadot/types/lookup" { readonly type: "FillBlock"; } - /** @name PalletSudoError (302) */ + /** @name PalletSudoError (308) */ interface PalletSudoError extends Enum { readonly isRequireSudo: boolean; readonly type: "RequireSudo"; } - /** @name PalletUtilityError (303) */ + /** @name PalletUtilityError (309) */ interface PalletUtilityError extends Enum { readonly isTooManyCalls: boolean; readonly type: "TooManyCalls"; } - /** @name PalletProxyProxyDefinition (306) */ + /** @name PalletProxyProxyDefinition (312) */ interface PalletProxyProxyDefinition extends Struct { readonly delegate: AccountId32; readonly proxyType: DanceboxRuntimeProxyType; readonly delay: u32; } - /** @name PalletProxyAnnouncement (310) */ + /** @name PalletProxyAnnouncement (316) */ interface PalletProxyAnnouncement extends Struct { readonly real: AccountId32; readonly callHash: H256; readonly height: u32; } - /** @name PalletProxyError (312) */ + /** @name PalletProxyError (318) */ interface PalletProxyError extends Enum { readonly isTooMany: boolean; readonly isNotFound: boolean; @@ -3468,7 +3957,7 @@ declare module "@polkadot/types/lookup" { | "NoSelfProxy"; } - /** @name PalletMigrationsError (313) */ + /** @name PalletMigrationsError (319) */ interface PalletMigrationsError extends Enum { readonly isPreimageMissing: boolean; readonly isWrongUpperBound: boolean; @@ -3477,14 +3966,14 @@ declare module "@polkadot/types/lookup" { readonly type: "PreimageMissing" | "WrongUpperBound" | "PreimageIsTooBig" | "PreimageAlreadyExists"; } - /** @name PalletMaintenanceModeError (314) */ + /** @name PalletMaintenanceModeError (320) */ interface PalletMaintenanceModeError extends Enum { readonly isAlreadyInMaintenanceMode: boolean; readonly isNotInMaintenanceMode: boolean; readonly type: "AlreadyInMaintenanceMode" | "NotInMaintenanceMode"; } - /** @name PalletTxPauseError (315) */ + /** @name PalletTxPauseError (321) */ interface PalletTxPauseError extends Enum { readonly isIsPaused: boolean; readonly isIsUnpaused: boolean; @@ -3493,14 +3982,14 @@ declare module "@polkadot/types/lookup" { readonly type: "IsPaused" | "IsUnpaused" | "Unpausable" | "NotFound"; } - /** @name PalletBalancesBalanceLock (317) */ + /** @name PalletBalancesBalanceLock (323) */ interface PalletBalancesBalanceLock extends Struct { readonly id: U8aFixed; readonly amount: u128; readonly reasons: PalletBalancesReasons; } - /** @name PalletBalancesReasons (318) */ + /** @name PalletBalancesReasons (324) */ interface PalletBalancesReasons extends Enum { readonly isFee: boolean; readonly isMisc: boolean; @@ -3508,32 +3997,32 @@ declare module "@polkadot/types/lookup" { readonly type: "Fee" | "Misc" | "All"; } - /** @name PalletBalancesReserveData (321) */ + /** @name PalletBalancesReserveData (327) */ interface PalletBalancesReserveData extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name DanceboxRuntimeRuntimeHoldReason (325) */ + /** @name DanceboxRuntimeRuntimeHoldReason (331) */ interface DanceboxRuntimeRuntimeHoldReason extends Enum { readonly isPooledStaking: boolean; readonly asPooledStaking: PalletPooledStakingHoldReason; readonly type: "PooledStaking"; } - /** @name PalletPooledStakingHoldReason (326) */ + /** @name PalletPooledStakingHoldReason (332) */ interface PalletPooledStakingHoldReason extends Enum { readonly isPooledStake: boolean; readonly type: "PooledStake"; } - /** @name PalletBalancesIdAmount (329) */ + /** @name PalletBalancesIdAmount (335) */ interface PalletBalancesIdAmount extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name PalletBalancesError (331) */ + /** @name PalletBalancesError (337) */ interface PalletBalancesError extends Enum { readonly isVestingBalance: boolean; readonly isLiquidityRestrictions: boolean; @@ -3558,28 +4047,28 @@ declare module "@polkadot/types/lookup" { | "TooManyFreezes"; } - /** @name PalletTransactionPaymentReleases (332) */ + /** @name PalletTransactionPaymentReleases (338) */ interface PalletTransactionPaymentReleases extends Enum { readonly isV1Ancient: boolean; readonly isV2: boolean; readonly type: "V1Ancient" | "V2"; } - /** @name PalletIdentityRegistration (333) */ + /** @name PalletIdentityRegistration (339) */ interface PalletIdentityRegistration extends Struct { readonly judgements: Vec>; readonly deposit: u128; readonly info: PalletIdentitySimpleIdentityInfo; } - /** @name PalletIdentityRegistrarInfo (341) */ + /** @name PalletIdentityRegistrarInfo (347) */ interface PalletIdentityRegistrarInfo extends Struct { readonly account: AccountId32; readonly fee: u128; readonly fields: PalletIdentityBitFlags; } - /** @name PalletIdentityError (343) */ + /** @name PalletIdentityError (349) */ interface PalletIdentityError extends Enum { readonly isTooManySubAccounts: boolean; readonly isNotFound: boolean; @@ -3620,13 +4109,13 @@ declare module "@polkadot/types/lookup" { | "JudgementPaymentFailed"; } - /** @name PalletRegistrarDepositInfo (348) */ + /** @name PalletRegistrarDepositInfo (354) */ interface PalletRegistrarDepositInfo extends Struct { readonly creator: AccountId32; readonly deposit: u128; } - /** @name PalletRegistrarError (349) */ + /** @name PalletRegistrarError (355) */ interface PalletRegistrarError extends Enum { readonly isParaIdAlreadyRegistered: boolean; readonly isParaIdNotRegistered: boolean; @@ -3649,34 +4138,37 @@ declare module "@polkadot/types/lookup" { | "NotSufficientDeposit"; } - /** @name PalletConfigurationHostConfiguration (350) */ + /** @name PalletConfigurationHostConfiguration (356) */ interface PalletConfigurationHostConfiguration extends Struct { readonly maxCollators: u32; readonly minOrchestratorCollators: u32; readonly maxOrchestratorCollators: u32; readonly collatorsPerContainer: u32; readonly fullRotationPeriod: u32; + readonly collatorsPerParathread: u32; + readonly parathreadsPerCollator: u32; + readonly targetContainerChainFullness: Perbill; } - /** @name PalletConfigurationError (353) */ + /** @name PalletConfigurationError (359) */ interface PalletConfigurationError extends Enum { readonly isInvalidNewValue: boolean; readonly type: "InvalidNewValue"; } - /** @name DpCollatorAssignmentAssignedCollatorsAccountId32 (354) */ + /** @name DpCollatorAssignmentAssignedCollatorsAccountId32 (360) */ interface DpCollatorAssignmentAssignedCollatorsAccountId32 extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name PalletAuthorNotingContainerChainBlockInfo (359) */ + /** @name PalletAuthorNotingContainerChainBlockInfo (365) */ interface PalletAuthorNotingContainerChainBlockInfo extends Struct { readonly blockNumber: u32; readonly author: AccountId32; } - /** @name PalletAuthorNotingError (360) */ + /** @name PalletAuthorNotingError (366) */ interface PalletAuthorNotingError extends Enum { readonly isFailedReading: boolean; readonly isFailedDecodingHeader: boolean; @@ -3695,13 +4187,13 @@ declare module "@polkadot/types/lookup" { | "NonAuraDigest"; } - /** @name DpCollatorAssignmentAssignedCollatorsPublic (361) */ + /** @name DpCollatorAssignmentAssignedCollatorsPublic (367) */ interface DpCollatorAssignmentAssignedCollatorsPublic extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name PalletServicesPaymentError (366) */ + /** @name PalletServicesPaymentError (372) */ interface PalletServicesPaymentError extends Enum { readonly isInsufficientFundsToPurchaseCredits: boolean; readonly isInsufficientCredits: boolean; @@ -3709,13 +4201,13 @@ declare module "@polkadot/types/lookup" { readonly type: "InsufficientFundsToPurchaseCredits" | "InsufficientCredits" | "CreditPriceTooExpensive"; } - /** @name PalletDataPreserversError (367) */ + /** @name PalletDataPreserversError (373) */ interface PalletDataPreserversError extends Enum { readonly isNoBootNodes: boolean; readonly type: "NoBootNodes"; } - /** @name PalletInvulnerablesError (369) */ + /** @name PalletInvulnerablesError (375) */ interface PalletInvulnerablesError extends Enum { readonly isTooManyInvulnerables: boolean; readonly isAlreadyInvulnerable: boolean; @@ -3723,10 +4215,10 @@ declare module "@polkadot/types/lookup" { readonly type: "TooManyInvulnerables" | "AlreadyInvulnerable" | "NotInvulnerable"; } - /** @name SpCoreCryptoKeyTypeId (374) */ + /** @name SpCoreCryptoKeyTypeId (380) */ interface SpCoreCryptoKeyTypeId extends U8aFixed {} - /** @name PalletSessionError (375) */ + /** @name PalletSessionError (381) */ interface PalletSessionError extends Enum { readonly isInvalidProof: boolean; readonly isNoAssociatedValidatorId: boolean; @@ -3736,7 +4228,7 @@ declare module "@polkadot/types/lookup" { readonly type: "InvalidProof" | "NoAssociatedValidatorId" | "DuplicatedKey" | "NoKeys" | "NoAccount"; } - /** @name PalletAuthorInherentError (379) */ + /** @name PalletAuthorInherentError (385) */ interface PalletAuthorInherentError extends Enum { readonly isAuthorAlreadySet: boolean; readonly isNoAccountId: boolean; @@ -3744,13 +4236,13 @@ declare module "@polkadot/types/lookup" { readonly type: "AuthorAlreadySet" | "NoAccountId" | "CannotBeAuthor"; } - /** @name PalletPooledStakingCandidateEligibleCandidate (381) */ + /** @name PalletPooledStakingCandidateEligibleCandidate (387) */ interface PalletPooledStakingCandidateEligibleCandidate extends Struct { readonly candidate: AccountId32; readonly stake: u128; } - /** @name PalletPooledStakingPoolsKey (384) */ + /** @name PalletPooledStakingPoolsKey (390) */ interface PalletPooledStakingPoolsKey extends Enum { readonly isCandidateTotalStake: boolean; readonly isJoiningShares: boolean; @@ -3820,7 +4312,7 @@ declare module "@polkadot/types/lookup" { | "LeavingSharesHeldStake"; } - /** @name PalletPooledStakingError (386) */ + /** @name PalletPooledStakingError (392) */ interface PalletPooledStakingError extends Enum { readonly isInvalidPalletSetting: boolean; readonly isDisabledFeature: boolean; @@ -3854,27 +4346,27 @@ declare module "@polkadot/types/lookup" { | "SwapResultsInZeroShares"; } - /** @name PalletInflationRewardsChainsToRewardValue (387) */ + /** @name PalletInflationRewardsChainsToRewardValue (393) */ interface PalletInflationRewardsChainsToRewardValue extends Struct { readonly paraIds: Vec; readonly rewardsPerChain: u128; } - /** @name CumulusPalletXcmpQueueInboundChannelDetails (389) */ + /** @name CumulusPalletXcmpQueueInboundChannelDetails (395) */ interface CumulusPalletXcmpQueueInboundChannelDetails extends Struct { readonly sender: u32; readonly state: CumulusPalletXcmpQueueInboundState; readonly messageMetadata: Vec>; } - /** @name CumulusPalletXcmpQueueInboundState (390) */ + /** @name CumulusPalletXcmpQueueInboundState (396) */ interface CumulusPalletXcmpQueueInboundState extends Enum { readonly isOk: boolean; readonly isSuspended: boolean; readonly type: "Ok" | "Suspended"; } - /** @name PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat (393) */ + /** @name PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat (399) */ interface PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat extends Enum { readonly isConcatenatedVersionedXcm: boolean; readonly isConcatenatedEncodedBlob: boolean; @@ -3882,7 +4374,7 @@ declare module "@polkadot/types/lookup" { readonly type: "ConcatenatedVersionedXcm" | "ConcatenatedEncodedBlob" | "Signals"; } - /** @name CumulusPalletXcmpQueueOutboundChannelDetails (396) */ + /** @name CumulusPalletXcmpQueueOutboundChannelDetails (402) */ interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct { readonly recipient: u32; readonly state: CumulusPalletXcmpQueueOutboundState; @@ -3891,14 +4383,14 @@ declare module "@polkadot/types/lookup" { readonly lastIndex: u16; } - /** @name CumulusPalletXcmpQueueOutboundState (397) */ + /** @name CumulusPalletXcmpQueueOutboundState (403) */ interface CumulusPalletXcmpQueueOutboundState extends Enum { readonly isOk: boolean; readonly isSuspended: boolean; readonly type: "Ok" | "Suspended"; } - /** @name CumulusPalletXcmpQueueQueueConfigData (399) */ + /** @name CumulusPalletXcmpQueueQueueConfigData (405) */ interface CumulusPalletXcmpQueueQueueConfigData extends Struct { readonly suspendThreshold: u32; readonly dropThreshold: u32; @@ -3908,7 +4400,7 @@ declare module "@polkadot/types/lookup" { readonly xcmpMaxIndividualWeight: SpWeightsWeightV2Weight; } - /** @name CumulusPalletXcmpQueueError (401) */ + /** @name CumulusPalletXcmpQueueError (407) */ interface CumulusPalletXcmpQueueError extends Enum { readonly isFailedToSend: boolean; readonly isBadXcmOrigin: boolean; @@ -3918,29 +4410,29 @@ declare module "@polkadot/types/lookup" { readonly type: "FailedToSend" | "BadXcmOrigin" | "BadXcm" | "BadOverweightIndex" | "WeightOverLimit"; } - /** @name CumulusPalletXcmError (402) */ + /** @name CumulusPalletXcmError (408) */ type CumulusPalletXcmError = Null; - /** @name CumulusPalletDmpQueueConfigData (403) */ + /** @name CumulusPalletDmpQueueConfigData (409) */ interface CumulusPalletDmpQueueConfigData extends Struct { readonly maxIndividual: SpWeightsWeightV2Weight; } - /** @name CumulusPalletDmpQueuePageIndexData (404) */ + /** @name CumulusPalletDmpQueuePageIndexData (410) */ interface CumulusPalletDmpQueuePageIndexData extends Struct { readonly beginUsed: u32; readonly endUsed: u32; readonly overweightCount: u64; } - /** @name CumulusPalletDmpQueueError (407) */ + /** @name CumulusPalletDmpQueueError (413) */ interface CumulusPalletDmpQueueError extends Enum { readonly isUnknown: boolean; readonly isOverLimit: boolean; readonly type: "Unknown" | "OverLimit"; } - /** @name PalletXcmQueryStatus (408) */ + /** @name PalletXcmQueryStatus (414) */ interface PalletXcmQueryStatus extends Enum { readonly isPending: boolean; readonly asPending: { @@ -3962,7 +4454,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Pending" | "VersionNotifier" | "Ready"; } - /** @name XcmVersionedResponse (412) */ + /** @name XcmVersionedResponse (418) */ interface XcmVersionedResponse extends Enum { readonly isV2: boolean; readonly asV2: XcmV2Response; @@ -3971,7 +4463,7 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3"; } - /** @name PalletXcmVersionMigrationStage (418) */ + /** @name PalletXcmVersionMigrationStage (424) */ interface PalletXcmVersionMigrationStage extends Enum { readonly isMigrateSupportedVersion: boolean; readonly isMigrateVersionNotifiers: boolean; @@ -3985,14 +4477,14 @@ declare module "@polkadot/types/lookup" { | "MigrateAndNotifyOldTargets"; } - /** @name XcmVersionedAssetId (420) */ + /** @name XcmVersionedAssetId (426) */ interface XcmVersionedAssetId extends Enum { readonly isV3: boolean; readonly asV3: XcmV3MultiassetAssetId; readonly type: "V3"; } - /** @name PalletXcmRemoteLockedFungibleRecord (421) */ + /** @name PalletXcmRemoteLockedFungibleRecord (427) */ interface PalletXcmRemoteLockedFungibleRecord extends Struct { readonly amount: u128; readonly owner: XcmVersionedMultiLocation; @@ -4000,7 +4492,7 @@ declare module "@polkadot/types/lookup" { readonly consumers: Vec>; } - /** @name PalletXcmError (428) */ + /** @name PalletXcmError (434) */ interface PalletXcmError extends Enum { readonly isUnreachable: boolean; readonly isSendFailure: boolean; @@ -4045,7 +4537,133 @@ declare module "@polkadot/types/lookup" { | "InUse"; } - /** @name SpRuntimeMultiSignature (432) */ + /** @name PalletAssetsAssetDetails (435) */ + interface PalletAssetsAssetDetails extends Struct { + readonly owner: AccountId32; + readonly issuer: AccountId32; + readonly admin: AccountId32; + readonly freezer: AccountId32; + readonly supply: u128; + readonly deposit: u128; + readonly minBalance: u128; + readonly isSufficient: bool; + readonly accounts: u32; + readonly sufficients: u32; + readonly approvals: u32; + readonly status: PalletAssetsAssetStatus; + } + + /** @name PalletAssetsAssetStatus (436) */ + interface PalletAssetsAssetStatus extends Enum { + readonly isLive: boolean; + readonly isFrozen: boolean; + readonly isDestroying: boolean; + readonly type: "Live" | "Frozen" | "Destroying"; + } + + /** @name PalletAssetsAssetAccount (438) */ + interface PalletAssetsAssetAccount extends Struct { + readonly balance: u128; + readonly status: PalletAssetsAccountStatus; + readonly reason: PalletAssetsExistenceReason; + readonly extra: Null; + } + + /** @name PalletAssetsAccountStatus (439) */ + interface PalletAssetsAccountStatus extends Enum { + readonly isLiquid: boolean; + readonly isFrozen: boolean; + readonly isBlocked: boolean; + readonly type: "Liquid" | "Frozen" | "Blocked"; + } + + /** @name PalletAssetsExistenceReason (440) */ + interface PalletAssetsExistenceReason extends Enum { + readonly isConsumer: boolean; + readonly isSufficient: boolean; + readonly isDepositHeld: boolean; + readonly asDepositHeld: u128; + readonly isDepositRefunded: boolean; + readonly isDepositFrom: boolean; + readonly asDepositFrom: ITuple<[AccountId32, u128]>; + readonly type: "Consumer" | "Sufficient" | "DepositHeld" | "DepositRefunded" | "DepositFrom"; + } + + /** @name PalletAssetsApproval (442) */ + interface PalletAssetsApproval extends Struct { + readonly amount: u128; + readonly deposit: u128; + } + + /** @name PalletAssetsAssetMetadata (443) */ + interface PalletAssetsAssetMetadata extends Struct { + readonly deposit: u128; + readonly name: Bytes; + readonly symbol: Bytes; + readonly decimals: u8; + readonly isFrozen: bool; + } + + /** @name PalletAssetsError (445) */ + interface PalletAssetsError extends Enum { + readonly isBalanceLow: boolean; + readonly isNoAccount: boolean; + readonly isNoPermission: boolean; + readonly isUnknown: boolean; + readonly isFrozen: boolean; + readonly isInUse: boolean; + readonly isBadWitness: boolean; + readonly isMinBalanceZero: boolean; + readonly isUnavailableConsumer: boolean; + readonly isBadMetadata: boolean; + readonly isUnapproved: boolean; + readonly isWouldDie: boolean; + readonly isAlreadyExists: boolean; + readonly isNoDeposit: boolean; + readonly isWouldBurn: boolean; + readonly isLiveAsset: boolean; + readonly isAssetNotLive: boolean; + readonly isIncorrectStatus: boolean; + readonly isNotFrozen: boolean; + readonly isCallbackFailed: boolean; + readonly type: + | "BalanceLow" + | "NoAccount" + | "NoPermission" + | "Unknown" + | "Frozen" + | "InUse" + | "BadWitness" + | "MinBalanceZero" + | "UnavailableConsumer" + | "BadMetadata" + | "Unapproved" + | "WouldDie" + | "AlreadyExists" + | "NoDeposit" + | "WouldBurn" + | "LiveAsset" + | "AssetNotLive" + | "IncorrectStatus" + | "NotFrozen" + | "CallbackFailed"; + } + + /** @name PalletForeignAssetCreatorError (446) */ + interface PalletForeignAssetCreatorError extends Enum { + readonly isAssetAlreadyExists: boolean; + readonly isAssetDoesNotExist: boolean; + readonly type: "AssetAlreadyExists" | "AssetDoesNotExist"; + } + + /** @name PalletAssetRateError (447) */ + interface PalletAssetRateError extends Enum { + readonly isUnknownAssetKind: boolean; + readonly isAlreadyExists: boolean; + readonly type: "UnknownAssetKind" | "AlreadyExists"; + } + + /** @name SpRuntimeMultiSignature (452) */ interface SpRuntimeMultiSignature extends Enum { readonly isEd25519: boolean; readonly asEd25519: SpCoreEd25519Signature; @@ -4056,36 +4674,36 @@ declare module "@polkadot/types/lookup" { readonly type: "Ed25519" | "Sr25519" | "Ecdsa"; } - /** @name SpCoreEd25519Signature (433) */ + /** @name SpCoreEd25519Signature (453) */ interface SpCoreEd25519Signature extends U8aFixed {} - /** @name SpCoreSr25519Signature (435) */ + /** @name SpCoreSr25519Signature (455) */ interface SpCoreSr25519Signature extends U8aFixed {} - /** @name SpCoreEcdsaSignature (436) */ + /** @name SpCoreEcdsaSignature (456) */ interface SpCoreEcdsaSignature extends U8aFixed {} - /** @name FrameSystemExtensionsCheckNonZeroSender (439) */ + /** @name FrameSystemExtensionsCheckNonZeroSender (459) */ type FrameSystemExtensionsCheckNonZeroSender = Null; - /** @name FrameSystemExtensionsCheckSpecVersion (440) */ + /** @name FrameSystemExtensionsCheckSpecVersion (460) */ type FrameSystemExtensionsCheckSpecVersion = Null; - /** @name FrameSystemExtensionsCheckTxVersion (441) */ + /** @name FrameSystemExtensionsCheckTxVersion (461) */ type FrameSystemExtensionsCheckTxVersion = Null; - /** @name FrameSystemExtensionsCheckGenesis (442) */ + /** @name FrameSystemExtensionsCheckGenesis (462) */ type FrameSystemExtensionsCheckGenesis = Null; - /** @name FrameSystemExtensionsCheckNonce (445) */ + /** @name FrameSystemExtensionsCheckNonce (465) */ interface FrameSystemExtensionsCheckNonce extends Compact {} - /** @name FrameSystemExtensionsCheckWeight (446) */ + /** @name FrameSystemExtensionsCheckWeight (466) */ type FrameSystemExtensionsCheckWeight = Null; - /** @name PalletTransactionPaymentChargeTransactionPayment (447) */ + /** @name PalletTransactionPaymentChargeTransactionPayment (467) */ interface PalletTransactionPaymentChargeTransactionPayment extends Compact {} - /** @name DanceboxRuntimeRuntime (448) */ + /** @name DanceboxRuntimeRuntime (468) */ type DanceboxRuntimeRuntime = Null; } // declare module diff --git a/typescript-api/src/flashbox/interfaces/augment-api-consts.ts b/typescript-api/src/flashbox/interfaces/augment-api-consts.ts index 553fb0fe0..317586e2e 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-consts.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-consts.ts @@ -108,6 +108,16 @@ declare module "@polkadot/api-base/types/consts" { /** Generic const */ [key: string]: Codec; }; + relayStorageRoots: { + /** + * Limit the number of relay storage roots that will be stored. This limit applies to the number of items, not to + * their age. Decreasing the value of `MaxStorageRoots` is a breaking change and needs a migration to clean the + * `RelayStorageRoots` mapping. + */ + maxStorageRoots: u32 & AugmentedConst; + /** Generic const */ + [key: string]: Codec; + }; system: { /** Maximum number of block number to block hash mappings to keep (oldest pruned first). */ blockHashCount: u32 & AugmentedConst; diff --git a/typescript-api/src/flashbox/interfaces/augment-api-query.ts b/typescript-api/src/flashbox/interfaces/augment-api-query.ts index 3c2940781..7b5a3e77c 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-query.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-query.ts @@ -595,6 +595,20 @@ declare module "@polkadot/api-base/types/storage" { /** Generic query */ [key: string]: QueryableStorageEntry; }; + relayStorageRoots: { + /** Map of relay block number to relay storage root */ + relayStorageRoot: AugmentedQuery< + ApiType, + (arg: u32 | AnyNumber | Uint8Array) => Observable>, + [u32] + > & + QueryableStorageEntry; + /** List of all the keys in `RelayStorageRoot`. Used to remove the oldest key without having to iterate over all of them. */ + relayStorageRootKeys: AugmentedQuery Observable>, []> & + QueryableStorageEntry; + /** Generic query */ + [key: string]: QueryableStorageEntry; + }; servicesPayment: { blockProductionCredits: AugmentedQuery< ApiType, diff --git a/typescript-api/src/flashbox/interfaces/augment-api-tx.ts b/typescript-api/src/flashbox/interfaces/augment-api-tx.ts index d98192a83..6bfd8322b 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-tx.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-tx.ts @@ -202,6 +202,11 @@ declare module "@polkadot/api-base/types/submittable" { (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u32] >; + /** See [`Pallet::set_collators_per_parathread`]. */ + setCollatorsPerParathread: AugmentedSubmittable< + (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u32] + >; /** See [`Pallet::set_full_rotation_period`]. */ setFullRotationPeriod: AugmentedSubmittable< (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, @@ -222,6 +227,16 @@ declare module "@polkadot/api-base/types/submittable" { (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u32] >; + /** See [`Pallet::set_parathreads_per_collator`]. */ + setParathreadsPerCollator: AugmentedSubmittable< + (updated: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u32] + >; + /** See [`Pallet::set_target_container_chain_fullness`]. */ + setTargetContainerChainFullness: AugmentedSubmittable< + (updated: Perbill | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [Perbill] + >; /** Generic tx */ [key: string]: SubmittableExtrinsicFunction; }; diff --git a/typescript-api/src/flashbox/interfaces/lookup.ts b/typescript-api/src/flashbox/interfaces/lookup.ts index c4a67db8d..da1643a02 100644 --- a/typescript-api/src/flashbox/interfaces/lookup.ts +++ b/typescript-api/src/flashbox/interfaces/lookup.ts @@ -1132,9 +1132,24 @@ export default { }, new_: "u32", }, - __Unused5: "Null", - __Unused6: "Null", - __Unused7: "Null", + set_collators_per_parathread: { + _alias: { + new_: "new", + }, + new_: "u32", + }, + set_parathreads_per_collator: { + _alias: { + new_: "new", + }, + new_: "u32", + }, + set_target_container_chain_fullness: { + _alias: { + new_: "new", + }, + new_: "Perbill", + }, __Unused8: "Null", __Unused9: "Null", __Unused10: "Null", @@ -1179,9 +1194,9 @@ export default { }, }, }, - /** Lookup195: pallet_collator_assignment::pallet::Call */ + /** Lookup196: pallet_collator_assignment::pallet::Call */ PalletCollatorAssignmentCall: "Null", - /** Lookup196: pallet_author_noting::pallet::Call */ + /** Lookup197: pallet_author_noting::pallet::Call */ PalletAuthorNotingCall: { _enum: { set_latest_author_data: { @@ -1197,13 +1212,13 @@ export default { }, }, }, - /** Lookup197: tp_author_noting_inherent::OwnParachainInherentData */ + /** Lookup198: tp_author_noting_inherent::OwnParachainInherentData */ TpAuthorNotingInherentOwnParachainInherentData: { relayStorageProof: "SpTrieStorageProof", }, - /** Lookup198: pallet_authority_assignment::pallet::Call */ + /** Lookup199: pallet_authority_assignment::pallet::Call */ PalletAuthorityAssignmentCall: "Null", - /** Lookup199: pallet_services_payment::pallet::Call */ + /** Lookup200: pallet_services_payment::pallet::Call */ PalletServicesPaymentCall: { _enum: { purchase_credits: { @@ -1221,7 +1236,7 @@ export default { }, }, }, - /** Lookup201: pallet_data_preservers::pallet::Call */ + /** Lookup202: pallet_data_preservers::pallet::Call */ PalletDataPreserversCall: { _enum: { set_boot_nodes: { @@ -1230,7 +1245,7 @@ export default { }, }, }, - /** Lookup205: pallet_invulnerables::pallet::Call */ + /** Lookup206: pallet_invulnerables::pallet::Call */ PalletInvulnerablesCall: { _enum: { set_invulnerables: { @@ -1247,7 +1262,7 @@ export default { }, }, }, - /** Lookup206: pallet_session::pallet::Call */ + /** Lookup207: pallet_session::pallet::Call */ PalletSessionCall: { _enum: { set_keys: { @@ -1260,19 +1275,19 @@ export default { purge_keys: "Null", }, }, - /** Lookup207: flashbox_runtime::SessionKeys */ + /** Lookup208: flashbox_runtime::SessionKeys */ FlashboxRuntimeSessionKeys: { nimbus: "NimbusPrimitivesNimbusCryptoPublic", }, - /** Lookup208: nimbus_primitives::nimbus_crypto::Public */ + /** Lookup209: nimbus_primitives::nimbus_crypto::Public */ NimbusPrimitivesNimbusCryptoPublic: "SpCoreSr25519Public", - /** Lookup209: sp_core::sr25519::Public */ + /** Lookup210: sp_core::sr25519::Public */ SpCoreSr25519Public: "[u8;32]", - /** Lookup210: pallet_author_inherent::pallet::Call */ + /** Lookup211: pallet_author_inherent::pallet::Call */ PalletAuthorInherentCall: { _enum: ["kick_off_authorship_validation"], }, - /** Lookup211: pallet_root_testing::pallet::Call */ + /** Lookup212: pallet_root_testing::pallet::Call */ PalletRootTestingCall: { _enum: { fill_block: { @@ -1430,6 +1445,9 @@ export default { maxOrchestratorCollators: "u32", collatorsPerContainer: "u32", fullRotationPeriod: "u32", + collatorsPerParathread: "u32", + parathreadsPerCollator: "u32", + targetContainerChainFullness: "Perbill", }, /** Lookup263: pallet_configuration::pallet::Error */ PalletConfigurationError: { @@ -1489,7 +1507,7 @@ export default { paraIds: "Vec", rewardsPerChain: "u128", }, - /** Lookup294: sp_runtime::MultiSignature */ + /** Lookup295: sp_runtime::MultiSignature */ SpRuntimeMultiSignature: { _enum: { Ed25519: "SpCoreEd25519Signature", @@ -1497,26 +1515,26 @@ export default { Ecdsa: "SpCoreEcdsaSignature", }, }, - /** Lookup295: sp_core::ed25519::Signature */ + /** Lookup296: sp_core::ed25519::Signature */ SpCoreEd25519Signature: "[u8;64]", - /** Lookup297: sp_core::sr25519::Signature */ + /** Lookup298: sp_core::sr25519::Signature */ SpCoreSr25519Signature: "[u8;64]", - /** Lookup298: sp_core::ecdsa::Signature */ + /** Lookup299: sp_core::ecdsa::Signature */ SpCoreEcdsaSignature: "[u8;65]", - /** Lookup301: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ + /** Lookup302: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ FrameSystemExtensionsCheckNonZeroSender: "Null", - /** Lookup302: frame_system::extensions::check_spec_version::CheckSpecVersion */ + /** Lookup303: frame_system::extensions::check_spec_version::CheckSpecVersion */ FrameSystemExtensionsCheckSpecVersion: "Null", - /** Lookup303: frame_system::extensions::check_tx_version::CheckTxVersion */ + /** Lookup304: frame_system::extensions::check_tx_version::CheckTxVersion */ FrameSystemExtensionsCheckTxVersion: "Null", - /** Lookup304: frame_system::extensions::check_genesis::CheckGenesis */ + /** Lookup305: frame_system::extensions::check_genesis::CheckGenesis */ FrameSystemExtensionsCheckGenesis: "Null", - /** Lookup307: frame_system::extensions::check_nonce::CheckNonce */ + /** Lookup308: frame_system::extensions::check_nonce::CheckNonce */ FrameSystemExtensionsCheckNonce: "Compact", - /** Lookup308: frame_system::extensions::check_weight::CheckWeight */ + /** Lookup309: frame_system::extensions::check_weight::CheckWeight */ FrameSystemExtensionsCheckWeight: "Null", - /** Lookup309: pallet_transaction_payment::ChargeTransactionPayment */ + /** Lookup310: pallet_transaction_payment::ChargeTransactionPayment */ PalletTransactionPaymentChargeTransactionPayment: "Compact", - /** Lookup310: flashbox_runtime::Runtime */ + /** Lookup311: flashbox_runtime::Runtime */ FlashboxRuntimeRuntime: "Null", }; diff --git a/typescript-api/src/flashbox/interfaces/types-lookup.ts b/typescript-api/src/flashbox/interfaces/types-lookup.ts index ecb7c546f..d4a8e0869 100644 --- a/typescript-api/src/flashbox/interfaces/types-lookup.ts +++ b/typescript-api/src/flashbox/interfaces/types-lookup.ts @@ -1519,6 +1519,18 @@ declare module "@polkadot/types/lookup" { readonly asSetFullRotationPeriod: { readonly new_: u32; } & Struct; + readonly isSetCollatorsPerParathread: boolean; + readonly asSetCollatorsPerParathread: { + readonly new_: u32; + } & Struct; + readonly isSetParathreadsPerCollator: boolean; + readonly asSetParathreadsPerCollator: { + readonly new_: u32; + } & Struct; + readonly isSetTargetContainerChainFullness: boolean; + readonly asSetTargetContainerChainFullness: { + readonly new_: Perbill; + } & Struct; readonly isSetBypassConsistencyCheck: boolean; readonly asSetBypassConsistencyCheck: { readonly new_: bool; @@ -1529,13 +1541,16 @@ declare module "@polkadot/types/lookup" { | "SetMaxOrchestratorCollators" | "SetCollatorsPerContainer" | "SetFullRotationPeriod" + | "SetCollatorsPerParathread" + | "SetParathreadsPerCollator" + | "SetTargetContainerChainFullness" | "SetBypassConsistencyCheck"; } - /** @name PalletCollatorAssignmentCall (195) */ + /** @name PalletCollatorAssignmentCall (196) */ type PalletCollatorAssignmentCall = Null; - /** @name PalletAuthorNotingCall (196) */ + /** @name PalletAuthorNotingCall (197) */ interface PalletAuthorNotingCall extends Enum { readonly isSetLatestAuthorData: boolean; readonly asSetLatestAuthorData: { @@ -1554,15 +1569,15 @@ declare module "@polkadot/types/lookup" { readonly type: "SetLatestAuthorData" | "SetAuthor" | "KillAuthorData"; } - /** @name TpAuthorNotingInherentOwnParachainInherentData (197) */ + /** @name TpAuthorNotingInherentOwnParachainInherentData (198) */ interface TpAuthorNotingInherentOwnParachainInherentData extends Struct { readonly relayStorageProof: SpTrieStorageProof; } - /** @name PalletAuthorityAssignmentCall (198) */ + /** @name PalletAuthorityAssignmentCall (199) */ type PalletAuthorityAssignmentCall = Null; - /** @name PalletServicesPaymentCall (199) */ + /** @name PalletServicesPaymentCall (200) */ interface PalletServicesPaymentCall extends Enum { readonly isPurchaseCredits: boolean; readonly asPurchaseCredits: { @@ -1583,7 +1598,7 @@ declare module "@polkadot/types/lookup" { readonly type: "PurchaseCredits" | "SetCredits" | "SetGivenFreeCredits"; } - /** @name PalletDataPreserversCall (201) */ + /** @name PalletDataPreserversCall (202) */ interface PalletDataPreserversCall extends Enum { readonly isSetBootNodes: boolean; readonly asSetBootNodes: { @@ -1593,7 +1608,7 @@ declare module "@polkadot/types/lookup" { readonly type: "SetBootNodes"; } - /** @name PalletInvulnerablesCall (205) */ + /** @name PalletInvulnerablesCall (206) */ interface PalletInvulnerablesCall extends Enum { readonly isSetInvulnerables: boolean; readonly asSetInvulnerables: { @@ -1610,7 +1625,7 @@ declare module "@polkadot/types/lookup" { readonly type: "SetInvulnerables" | "AddInvulnerable" | "RemoveInvulnerable"; } - /** @name PalletSessionCall (206) */ + /** @name PalletSessionCall (207) */ interface PalletSessionCall extends Enum { readonly isSetKeys: boolean; readonly asSetKeys: { @@ -1621,24 +1636,24 @@ declare module "@polkadot/types/lookup" { readonly type: "SetKeys" | "PurgeKeys"; } - /** @name FlashboxRuntimeSessionKeys (207) */ + /** @name FlashboxRuntimeSessionKeys (208) */ interface FlashboxRuntimeSessionKeys extends Struct { readonly nimbus: NimbusPrimitivesNimbusCryptoPublic; } - /** @name NimbusPrimitivesNimbusCryptoPublic (208) */ + /** @name NimbusPrimitivesNimbusCryptoPublic (209) */ interface NimbusPrimitivesNimbusCryptoPublic extends SpCoreSr25519Public {} - /** @name SpCoreSr25519Public (209) */ + /** @name SpCoreSr25519Public (210) */ interface SpCoreSr25519Public extends U8aFixed {} - /** @name PalletAuthorInherentCall (210) */ + /** @name PalletAuthorInherentCall (211) */ interface PalletAuthorInherentCall extends Enum { readonly isKickOffAuthorshipValidation: boolean; readonly type: "KickOffAuthorshipValidation"; } - /** @name PalletRootTestingCall (211) */ + /** @name PalletRootTestingCall (212) */ interface PalletRootTestingCall extends Enum { readonly isFillBlock: boolean; readonly asFillBlock: { @@ -1872,6 +1887,9 @@ declare module "@polkadot/types/lookup" { readonly maxOrchestratorCollators: u32; readonly collatorsPerContainer: u32; readonly fullRotationPeriod: u32; + readonly collatorsPerParathread: u32; + readonly parathreadsPerCollator: u32; + readonly targetContainerChainFullness: Perbill; } /** @name PalletConfigurationError (263) */ @@ -1966,7 +1984,7 @@ declare module "@polkadot/types/lookup" { readonly rewardsPerChain: u128; } - /** @name SpRuntimeMultiSignature (294) */ + /** @name SpRuntimeMultiSignature (295) */ interface SpRuntimeMultiSignature extends Enum { readonly isEd25519: boolean; readonly asEd25519: SpCoreEd25519Signature; @@ -1977,36 +1995,36 @@ declare module "@polkadot/types/lookup" { readonly type: "Ed25519" | "Sr25519" | "Ecdsa"; } - /** @name SpCoreEd25519Signature (295) */ + /** @name SpCoreEd25519Signature (296) */ interface SpCoreEd25519Signature extends U8aFixed {} - /** @name SpCoreSr25519Signature (297) */ + /** @name SpCoreSr25519Signature (298) */ interface SpCoreSr25519Signature extends U8aFixed {} - /** @name SpCoreEcdsaSignature (298) */ + /** @name SpCoreEcdsaSignature (299) */ interface SpCoreEcdsaSignature extends U8aFixed {} - /** @name FrameSystemExtensionsCheckNonZeroSender (301) */ + /** @name FrameSystemExtensionsCheckNonZeroSender (302) */ type FrameSystemExtensionsCheckNonZeroSender = Null; - /** @name FrameSystemExtensionsCheckSpecVersion (302) */ + /** @name FrameSystemExtensionsCheckSpecVersion (303) */ type FrameSystemExtensionsCheckSpecVersion = Null; - /** @name FrameSystemExtensionsCheckTxVersion (303) */ + /** @name FrameSystemExtensionsCheckTxVersion (304) */ type FrameSystemExtensionsCheckTxVersion = Null; - /** @name FrameSystemExtensionsCheckGenesis (304) */ + /** @name FrameSystemExtensionsCheckGenesis (305) */ type FrameSystemExtensionsCheckGenesis = Null; - /** @name FrameSystemExtensionsCheckNonce (307) */ + /** @name FrameSystemExtensionsCheckNonce (308) */ interface FrameSystemExtensionsCheckNonce extends Compact {} - /** @name FrameSystemExtensionsCheckWeight (308) */ + /** @name FrameSystemExtensionsCheckWeight (309) */ type FrameSystemExtensionsCheckWeight = Null; - /** @name PalletTransactionPaymentChargeTransactionPayment (309) */ + /** @name PalletTransactionPaymentChargeTransactionPayment (310) */ interface PalletTransactionPaymentChargeTransactionPayment extends Compact {} - /** @name FlashboxRuntimeRuntime (310) */ + /** @name FlashboxRuntimeRuntime (311) */ type FlashboxRuntimeRuntime = Null; } // declare module