diff --git a/Cargo.lock b/Cargo.lock index e4ee5fa7a..2a930face 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2855,6 +2855,7 @@ dependencies = [ "pallet-registrar", "pallet-registrar-runtime-api", "pallet-root-testing", + "pallet-services-payment", "pallet-session", "pallet-staking", "pallet-sudo", @@ -8335,6 +8336,7 @@ name = "pallet-services-payment" version = "0.1.0" dependencies = [ "cumulus-primitives-core", + "frame-benchmarking", "frame-support", "frame-system", "log", @@ -8345,6 +8347,8 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", + "sp-std", + "tp-traits", ] [[package]] @@ -15213,6 +15217,7 @@ version = "0.1.0" dependencies = [ "cumulus-primitives-core", "frame-support", + "impl-trait-for-tuples", "sp-std", ] diff --git a/Cargo.toml b/Cargo.toml index 7afb36e84..0046bb991 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ pallet-invulnerables = { path = "pallets/invulnerables", default-features = fals pallet-pooled-staking = { path = "pallets/pooled-staking", default-features = false } pallet-registrar = { path = "pallets/registrar", default-features = false } pallet-registrar-runtime-api = { path = "pallets/registrar/rpc/runtime-api", default-features = false } +pallet-services-payment = { path = "pallets/services-payment", default-features = false } ccp-authorities-noting-inherent = { path = "container-chains/primitives/authorities-noting-inherent", default-features = false } ccp-xcm = { path = "container-chains/primitives/xcm", default-features = false } @@ -226,6 +227,7 @@ log = { version = "0.4.17", default-features = false } serde = { version = "1.0.152", default-features = false } smallvec = "1.10.0" rand_chacha = { version = "0.3.1", default-features = false } +impl-trait-for-tuples = "0.2.2" # General (client) async-io = "1.3" diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index b9cdbaead..0bbc684f4 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -18,7 +18,7 @@ use { cumulus_primitives_core::ParaId, dancebox_runtime::{ prod_or_fast, AccountId, MaintenanceModeConfig, MigrationsConfig, PolkadotXcmConfig, - RegistrarConfig, Signature, SudoConfig, + RegistrarConfig, ServicesPaymentConfig, Signature, SudoConfig, }, nimbus_primitives::NimbusId, pallet_configuration::HostConfiguration, @@ -293,6 +293,27 @@ fn testnet_genesis( mock_container_chains: &[ParaId], configuration: pallet_configuration::GenesisConfig, ) -> dancebox_runtime::RuntimeGenesisConfig { + let para_ids: Vec<_> = container_chains + .iter() + .map(|x| { + container_chain_genesis_data_from_path(x).unwrap_or_else(|e| { + panic!( + "Failed to build genesis data for container chain {:?}: {}", + x, e + ) + }) + }) + .chain( + mock_container_chains + .iter() + .map(|x| (*x, mock_container_chain_genesis_data(*x), vec![])), + ) + .collect(); + // Assign 1000 block credits to all container chains registered in genesis + let para_id_credits: Vec<_> = para_ids + .iter() + .map(|(para_id, _genesis_data, _boot_nodes)| (*para_id, 1000)) + .collect(); let accounts_with_ed = vec![ dancebox_runtime::StakingAccount::get(), dancebox_runtime::ParachainBondAccount::get(), @@ -339,24 +360,8 @@ fn testnet_genesis( }, parachain_system: Default::default(), configuration, - registrar: RegistrarConfig { - para_ids: container_chains - .iter() - .map(|x| { - container_chain_genesis_data_from_path(x).unwrap_or_else(|e| { - panic!( - "Failed to build genesis data for container chain {:?}: {}", - x, e - ) - }) - }) - .chain( - mock_container_chains - .iter() - .map(|x| (*x, mock_container_chain_genesis_data(*x), vec![])), - ) - .collect(), - }, + registrar: RegistrarConfig { para_ids }, + services_payment: ServicesPaymentConfig { para_id_credits }, sudo: SudoConfig { key: Some(root_key), }, diff --git a/pallets/collator-assignment/src/benchmarking.rs b/pallets/collator-assignment/src/benchmarking.rs index 851fbdfd3..b4567fd35 100644 --- a/pallets/collator-assignment/src/benchmarking.rs +++ b/pallets/collator-assignment/src/benchmarking.rs @@ -72,6 +72,7 @@ mod benchmarks { let container_chains: Vec<_> = (0..y).map(|para_id| ParaId::from(para_id)).collect(); let session_index = 0u32.into(); T::ContainerChains::set_session_container_chains(session_index, &container_chains); + T::RemoveParaIdsWithNoCredits::make_valid_para_ids(&container_chains); // Assign random collators to test worst case: when collators need to be checked against existing collators // In this case all of the old collators don't exist anymore diff --git a/pallets/collator-assignment/src/lib.rs b/pallets/collator-assignment/src/lib.rs index 5ec6480b0..b76836be9 100644 --- a/pallets/collator-assignment/src/lib.rs +++ b/pallets/collator-assignment/src/lib.rs @@ -56,7 +56,7 @@ use { tp_collator_assignment::AssignedCollators, tp_traits::{ GetContainerChainAuthor, GetHostConfiguration, GetSessionContainerChains, ParaId, - RemoveInvulnerables, ShouldRotateAllCollators, Slot, + RemoveInvulnerables, RemoveParaIdsWithNoCredits, ShouldRotateAllCollators, Slot, }, }; @@ -97,6 +97,7 @@ pub mod pallet { type ShouldRotateAllCollators: ShouldRotateAllCollators; type GetRandomnessForNextBlock: GetRandomnessForNextBlock>; type RemoveInvulnerables: RemoveInvulnerables; + type RemoveParaIdsWithNoCredits: RemoveParaIdsWithNoCredits; /// The weight information of this pallet. type WeightInfo: WeightInfo; } @@ -145,6 +146,8 @@ pub mod pallet { pub active_assignment: AssignedCollators, /// Next session active assignment. pub next_assignment: AssignedCollators, + /// Total number of registered parachains before filtering them out, used as a weight hint + pub num_total_registered_paras: u32, } impl Pallet { @@ -161,6 +164,11 @@ 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 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( + &mut container_chain_ids, + ); // If the random_seed is all zeros, we don't shuffle the list of collators nor the list // of container chains. @@ -248,12 +256,14 @@ pub mod pallet { return SessionChangeOutcome { active_assignment: new_assigned.clone(), next_assignment: new_assigned, + num_total_registered_paras, }; } SessionChangeOutcome { active_assignment: old_assigned, next_assignment: new_assigned, + num_total_registered_paras, } } @@ -400,10 +410,10 @@ pub mod pallet { let random_seed = Randomness::::take(); let num_collators = collators.len(); let assigned_collators = Self::assign_collators(session_index, random_seed, collators); - let num_parachains = assigned_collators.next_assignment.container_chains.len(); + let num_total_registered_paras = assigned_collators.num_total_registered_paras; frame_system::Pallet::::register_extra_weight_unchecked( - T::WeightInfo::new_session(num_collators as u32, num_parachains as u32), + T::WeightInfo::new_session(num_collators as u32, num_total_registered_paras), DispatchClass::Mandatory, ); diff --git a/pallets/collator-assignment/src/mock.rs b/pallets/collator-assignment/src/mock.rs index a80d4a837..b81f4d058 100644 --- a/pallets/collator-assignment/src/mock.rs +++ b/pallets/collator-assignment/src/mock.rs @@ -30,7 +30,7 @@ use { traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }, - tp_traits::{ParaId, RemoveInvulnerables}, + tp_traits::{ParaId, RemoveInvulnerables, RemoveParaIdsWithNoCredits}, }; type Block = frame_system::mocking::MockBlock; @@ -193,6 +193,7 @@ impl pallet_collator_assignment::Config for Test { type ShouldRotateAllCollators = RotateCollatorsEveryNSessions; type GetRandomnessForNextBlock = MockGetRandomnessForNextBlock; type RemoveInvulnerables = RemoveAccountIdsAbove100; + type RemoveParaIdsWithNoCredits = RemoveParaIdsAbove5000; type WeightInfo = (); } @@ -247,3 +248,19 @@ impl RemoveInvulnerables for RemoveAccountIdsAbove100 { invulnerables } } + +/// Any ParaId >= 5000 will be considered to not have enough credits +pub struct RemoveParaIdsAbove5000; + +impl RemoveParaIdsWithNoCredits for RemoveParaIdsAbove5000 { + fn remove_para_ids_with_no_credits(para_ids: &mut Vec) { + para_ids.retain(|para_id| *para_id <= ParaId::from(5000)); + } + + #[cfg(feature = "runtime-benchmarks")] + fn make_valid_para_ids(para_ids: &[ParaId]) { + for para_id in para_ids { + assert!(para_id > 5000.into(), "{}", para_id); + } + } +} diff --git a/pallets/collator-assignment/src/weights.rs b/pallets/collator-assignment/src/weights.rs index a7e19911e..147d12122 100644 --- a/pallets/collator-assignment/src/weights.rs +++ b/pallets/collator-assignment/src/weights.rs @@ -18,10 +18,10 @@ //! Autogenerated weights for pallet_collator_assignment //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-09-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-11-13, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `tomasz-XPS-15-9520`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 // Executed Command: // ./target/release/tanssi-node @@ -32,7 +32,7 @@ // --pallet // pallet_collator_assignment // --extrinsic -// new_session +// * // --steps // 50 // --repeat @@ -58,64 +58,82 @@ pub trait WeightInfo { /// Weights for pallet_collator_assignment using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Registrar PendingParaIds (r:1 w:0) - /// Proof Skipped: Registrar PendingParaIds (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Registrar RegisteredParaIds (r:1 w:0) - /// Proof Skipped: Registrar RegisteredParaIds (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: CollatorAssignment PendingCollatorContainerChain (r:1 w:1) - /// Proof Skipped: CollatorAssignment PendingCollatorContainerChain (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration PendingConfigs (r:1 w:0) - /// Proof Skipped: Configuration PendingConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: CollatorAssignment CollatorContainerChain (r:0 w:1) - /// Proof Skipped: CollatorAssignment CollatorContainerChain (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `CollatorAssignment::Randomness` (r:1 w:1) + /// Proof: `CollatorAssignment::Randomness` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::PendingParaIds` (r:1 w:0) + /// Proof: `Registrar::PendingParaIds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::RegisteredParaIds` (r:1 w:0) + /// Proof: `Registrar::RegisteredParaIds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ServicesPayment::BlockProductionCredits` (r:20 w:0) + /// Proof: `ServicesPayment::BlockProductionCredits` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + /// Storage: `CollatorAssignment::PendingCollatorContainerChain` (r:1 w:1) + /// Proof: `CollatorAssignment::PendingCollatorContainerChain` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::ActiveConfig` (r:1 w:0) + /// Proof: `Configuration::ActiveConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::PendingConfigs` (r:1 w:0) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Invulnerables::Invulnerables` (r:1 w:0) + /// Proof: `Invulnerables::Invulnerables` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + /// Storage: `CollatorAssignment::CollatorContainerChain` (r:0 w:1) + /// Proof: `CollatorAssignment::CollatorContainerChain` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 20]`. fn new_session(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `427 + y * (4 ±0)` - // Estimated: `1913 + y * (4 ±0)` - // Minimum execution time: 25_688_000 picoseconds. - Weight::from_parts(19_486_973, 1913) - // Standard Error: 874 - .saturating_add(Weight::from_parts(39_428, 0).saturating_mul(x.into())) - // Standard Error: 8_900 - .saturating_add(Weight::from_parts(706_995, 0).saturating_mul(y.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - .saturating_add(Weight::from_parts(0, 4).saturating_mul(y.into())) + // Measured: `766 + y * (32 ±0)` + // Estimated: `4687 + y * (2499 ±0)` + // Minimum execution time: 56_626_000 picoseconds. + Weight::from_parts(41_872_969, 4687) + // Standard Error: 1_156 + .saturating_add(Weight::from_parts(76_061, 0).saturating_mul(x.into())) + // Standard Error: 11_776 + .saturating_add(Weight::from_parts(2_758_758, 0).saturating_mul(y.into())) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(y.into()))) + .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(Weight::from_parts(0, 2499).saturating_mul(y.into())) } } // For backwards compatibility and tests impl WeightInfo for () { - /// Storage: Registrar PendingParaIds (r:1 w:0) - /// Proof Skipped: Registrar PendingParaIds (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Registrar RegisteredParaIds (r:1 w:0) - /// Proof Skipped: Registrar RegisteredParaIds (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: CollatorAssignment PendingCollatorContainerChain (r:1 w:1) - /// Proof Skipped: CollatorAssignment PendingCollatorContainerChain (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration PendingConfigs (r:1 w:0) - /// Proof Skipped: Configuration PendingConfigs (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: CollatorAssignment CollatorContainerChain (r:0 w:1) - /// Proof Skipped: CollatorAssignment CollatorContainerChain (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `CollatorAssignment::Randomness` (r:1 w:1) + /// Proof: `CollatorAssignment::Randomness` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::PendingParaIds` (r:1 w:0) + /// Proof: `Registrar::PendingParaIds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::RegisteredParaIds` (r:1 w:0) + /// Proof: `Registrar::RegisteredParaIds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ServicesPayment::BlockProductionCredits` (r:20 w:0) + /// Proof: `ServicesPayment::BlockProductionCredits` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + /// Storage: `CollatorAssignment::PendingCollatorContainerChain` (r:1 w:1) + /// Proof: `CollatorAssignment::PendingCollatorContainerChain` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::ActiveConfig` (r:1 w:0) + /// Proof: `Configuration::ActiveConfig` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::PendingConfigs` (r:1 w:0) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Invulnerables::Invulnerables` (r:1 w:0) + /// Proof: `Invulnerables::Invulnerables` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + /// Storage: `CollatorAssignment::CollatorContainerChain` (r:0 w:1) + /// Proof: `CollatorAssignment::CollatorContainerChain` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 20]`. fn new_session(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `427 + y * (4 ±0)` - // Estimated: `1913 + y * (4 ±0)` - // Minimum execution time: 25_688_000 picoseconds. - Weight::from_parts(19_486_973, 1913) - // Standard Error: 874 - .saturating_add(Weight::from_parts(39_428, 0).saturating_mul(x.into())) - // Standard Error: 8_900 - .saturating_add(Weight::from_parts(706_995, 0).saturating_mul(y.into())) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - .saturating_add(Weight::from_parts(0, 4).saturating_mul(y.into())) + // Measured: `766 + y * (32 ±0)` + // Estimated: `4687 + y * (2499 ±0)` + // Minimum execution time: 56_626_000 picoseconds. + Weight::from_parts(41_872_969, 4687) + // Standard Error: 1_156 + .saturating_add(Weight::from_parts(76_061, 0).saturating_mul(x.into())) + // Standard Error: 11_776 + .saturating_add(Weight::from_parts(2_758_758, 0).saturating_mul(y.into())) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(y.into()))) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(Weight::from_parts(0, 2499).saturating_mul(y.into())) } } diff --git a/pallets/services-payment/Cargo.toml b/pallets/services-payment/Cargo.toml index c431faa49..1e4c3870b 100644 --- a/pallets/services-payment/Cargo.toml +++ b/pallets/services-payment/Cargo.toml @@ -9,16 +9,17 @@ version = "0.1.0" [package.metadata.docs.rs] targets = [ "x86_64-unknown-linux-gnu" ] [dependencies] +frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } log = { workspace = true } parity-scale-codec = { workspace = true, features = [ "derive", "max-encoded-len" ] } scale-info = { workspace = true } serde = { workspace = true, optional = true, features = [ "derive" ] } - sp-runtime = { workspace = true } - cumulus-primitives-core = { workspace = true } +tp-traits = { workspace = true } +sp-std = { workspace = true } [dev-dependencies] pallet-balances = { workspace = true } @@ -29,10 +30,13 @@ sp-io = { workspace = true } default = [ "std" ] std = [ "cumulus-primitives-core/std", + "frame-benchmarking/std", "frame-support/std", "frame-system/std", "pallet-balances/std", "scale-info/std", "sp-runtime/std", + "sp-std/std", ] try-runtime = [ "frame-support/try-runtime" ] +runtime-benchmarks = [ "frame-benchmarking", "tp-traits/runtime-benchmarks" ] \ No newline at end of file diff --git a/pallets/services-payment/src/benchmarks.rs b/pallets/services-payment/src/benchmarks.rs new file mode 100644 index 000000000..4edae2d78 --- /dev/null +++ b/pallets/services-payment/src/benchmarks.rs @@ -0,0 +1,102 @@ +// 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 + +#![cfg(feature = "runtime-benchmarks")] + +//! Benchmarking +use { + crate::{BalanceOf, BlockNumberFor, Call, Config, Pallet}, + frame_benchmarking::{account, v2::*}, + frame_support::{assert_ok, traits::Currency}, + frame_system::RawOrigin, + sp_std::prelude::*, +}; + +const SEED: u32 = 0; + +fn create_funded_user( + string: &'static str, + n: u32, + balance_factor: u32, +) -> T::AccountId { + let user = account(string, n, SEED); + let balance = ::minimum_balance() * balance_factor.into(); + let _ = ::make_free_balance_be(&user, balance); + user +} + +#[benchmarks(where BalanceOf: From>)] +mod benchmarks { + use super::*; + + #[benchmark] + fn purchase_credits() { + let caller = create_funded_user::("caller", 1, 100); + let para_id = 1001u32.into(); + let credits = 1000u32.into(); + + // Before call: 0 credits + assert_eq!( + crate::BlockProductionCredits::::get(¶_id).unwrap_or_default(), + 0u32.into() + ); + + #[extrinsic_call] + Pallet::::purchase_credits( + RawOrigin::Signed(caller), + para_id, + credits, + Some(u32::MAX.into()), + ); + + // verification code + assert_eq!( + crate::BlockProductionCredits::::get(¶_id).unwrap_or_default(), + credits + ); + } + + #[benchmark] + fn set_credits() { + let caller = create_funded_user::("caller", 1, 100); + let para_id = 1001u32.into(); + let credits = 1000u32.into(); + + assert_ok!(Pallet::::purchase_credits( + RawOrigin::Signed(caller).into(), + para_id, + credits, + Some(u32::MAX.into()), + )); + + // Before call: 1000 credits + assert_eq!( + crate::BlockProductionCredits::::get(¶_id).unwrap_or_default(), + 1000u32.into() + ); + + #[extrinsic_call] + Pallet::::set_credits(RawOrigin::Root, para_id, 1u32.into()); + + // After call: 1 credit + assert_eq!( + crate::BlockProductionCredits::::get(¶_id).unwrap_or_default(), + 1u32.into() + ); + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/services-payment/src/lib.rs b/pallets/services-payment/src/lib.rs index d00489211..cd603796c 100644 --- a/pallets/services-payment/src/lib.rs +++ b/pallets/services-payment/src/lib.rs @@ -36,24 +36,30 @@ #![cfg_attr(not(feature = "std"), no_std)] use { + crate::weights::WeightInfo, cumulus_primitives_core::ParaId, frame_support::{ pallet_prelude::*, sp_runtime::{traits::Zero, Saturating}, - traits::Currency, + traits::{tokens::ExistenceRequirement, Currency, WithdrawReasons}, }, frame_system::pallet_prelude::*, + scale_info::prelude::vec::Vec, + tp_traits::{AuthorNotingHook, BlockNumber}, }; +#[cfg(any(test, feature = "runtime-benchmarks"))] +mod benchmarks; #[cfg(test)] mod mock; #[cfg(test)] mod tests; +pub mod weights; pub use pallet::*; -#[frame_support::pallet(dev_mode)] +#[frame_support::pallet] pub mod pallet { use super::*; @@ -69,6 +75,8 @@ pub mod pallet { type ProvideBlockProductionCost: ProvideBlockProductionCost; /// The maximum number of credits that can be accumulated type MaxCreditsStored: Get>; + + type WeightInfo: WeightInfo; } #[pallet::error] @@ -95,6 +103,10 @@ pub mod pallet { para_id: ParaId, credits_remaining: BlockNumberFor, }, + CreditsSet { + para_id: ParaId, + credits: BlockNumberFor, + }, } #[pallet::storage] @@ -108,7 +120,7 @@ pub mod pallet { BalanceOf: From>, { #[pallet::call_index(0)] - #[pallet::weight(0)] // TODO + #[pallet::weight(T::WeightInfo::purchase_credits())] pub fn purchase_credits( origin: OriginFor, para_id: ParaId, @@ -154,6 +166,28 @@ pub mod pallet { Ok(().into()) } + + /// Set the number of block production credits for this para_id without paying for them. + /// Can only be called by root. + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::set_credits())] + pub fn set_credits( + origin: OriginFor, + para_id: ParaId, + credits: BlockNumberFor, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + if credits.is_zero() { + BlockProductionCredits::::remove(para_id); + } else { + BlockProductionCredits::::insert(para_id, credits); + } + + Self::deposit_event(Event::::CreditsSet { para_id, credits }); + + Ok(().into()) + } } impl Pallet { @@ -181,21 +215,24 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { - _phantom: PhantomData, + pub para_id_credits: Vec<(ParaId, BlockNumberFor)>, } - #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { Self { - _phantom: Default::default(), + para_id_credits: Default::default(), } } } #[pallet::genesis_build] impl BuildGenesisConfig for GenesisConfig { - fn build(&self) {} + fn build(&self) { + for (para_id, credits) in &self.para_id_credits { + BlockProductionCredits::::insert(para_id, credits); + } + } } } @@ -214,8 +251,57 @@ pub trait OnChargeForBlockCredit { ) -> Result<(), Error>; } +pub struct ChargeForBlockCredit(PhantomData); +impl OnChargeForBlockCredit for ChargeForBlockCredit { + fn charge_credits( + payer: &T::AccountId, + _para_id: &ParaId, + _credits: BlockNumberFor, + fee: BalanceOf, + ) -> Result<(), crate::Error> { + use frame_support::traits::tokens::imbalance::Imbalance; + + let result = T::Currency::withdraw( + payer, + fee, + WithdrawReasons::FEE, + ExistenceRequirement::AllowDeath, + ); + let imbalance = result.map_err(|_| crate::Error::InsufficientFundsToPurchaseCredits)?; + + if imbalance.peek() != fee { + panic!("withdrawn balance incorrect"); + } + + Ok(()) + } +} + /// Returns the cost for a given block credit at the current time. This can be a complex operation, /// so it also returns the weight it consumes. (TODO: or just rely on benchmarking) pub trait ProvideBlockProductionCost { fn block_cost(para_id: &ParaId) -> (BalanceOf, Weight); } + +impl AuthorNotingHook for Pallet { + // This hook is called when pallet_author_noting sees that the block number of a container chain has increased. + // Currently we always charge 1 credit, even if a container chain produced more that 1 block in between tanssi + // blocks. + fn on_container_author_noted( + _author: &T::AccountId, + _block_number: BlockNumber, + para_id: ParaId, + ) -> Weight { + let total_weight = T::DbWeight::get().reads_writes(1, 1); + + if let Err(e) = Pallet::::burn_credit_for_para(¶_id) { + log::warn!( + "Failed to burn credits for container chain {}: {:?}", + u32::from(para_id), + e + ); + } + + total_weight + } +} diff --git a/pallets/services-payment/src/mock.rs b/pallets/services-payment/src/mock.rs index 8bfbfe2be..4af7c4080 100644 --- a/pallets/services-payment/src/mock.rs +++ b/pallets/services-payment/src/mock.rs @@ -28,15 +28,13 @@ //! Using those two requirements we can select who the author was based on the collators assigned //! to that containerChain, by simply assigning the slot position. -use frame_support::traits::{Currency, WithdrawReasons}; - use { - crate::{self as payment_services_pallet, OnChargeForBlockCredit, ProvideBlockProductionCost}, + crate::{self as pallet_services_payment, ChargeForBlockCredit, ProvideBlockProductionCost}, cumulus_primitives_core::ParaId, frame_support::{ pallet_prelude::*, parameter_types, - traits::{tokens::ExistenceRequirement, ConstU32, ConstU64, Everything}, + traits::{ConstU32, ConstU64, Everything}, }, sp_core::H256, sp_runtime::{ @@ -54,7 +52,7 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - PaymentServices: payment_services_pallet::{Pallet, Call, Config, Storage, Event} + PaymentServices: pallet_services_payment::{Pallet, Call, Config, Storage, Event} } ); @@ -108,39 +106,13 @@ parameter_types! { pub const MaxCreditsStored: u64 = 5; } -impl payment_services_pallet::Config for Test { +impl pallet_services_payment::Config for Test { type RuntimeEvent = RuntimeEvent; type OnChargeForBlockCredit = ChargeForBlockCredit; type Currency = Balances; type ProvideBlockProductionCost = BlockProductionCost; type MaxCreditsStored = MaxCreditsStored; -} - -pub struct ChargeForBlockCredit(PhantomData); -impl OnChargeForBlockCredit for ChargeForBlockCredit { - fn charge_credits( - payer: &u64, - _para_id: &ParaId, - _credits: u64, - fee: u128, - ) -> Result<(), payment_services_pallet::Error> { - use frame_support::traits::tokens::imbalance::Imbalance; - - let result = Balances::withdraw( - payer, - fee, - WithdrawReasons::FEE, - ExistenceRequirement::AllowDeath, - ); - let imbalance = result - .map_err(|_| payment_services_pallet::Error::InsufficientFundsToPurchaseCredits)?; - - if imbalance.peek() != fee { - panic!("withdrawn balance incorrect"); - } - - Ok(()) - } + type WeightInfo = (); } pub(crate) const FIXED_BLOCK_PRODUCTION_COST: u128 = 100; @@ -178,7 +150,7 @@ impl ExtBuilder { } } -pub(crate) fn events() -> Vec> { +pub(crate) fn events() -> Vec> { System::events() .into_iter() .map(|r| r.event) diff --git a/pallets/services-payment/src/tests.rs b/pallets/services-payment/src/tests.rs index 7fe95be52..4167e3bf8 100644 --- a/pallets/services-payment/src/tests.rs +++ b/pallets/services-payment/src/tests.rs @@ -29,8 +29,10 @@ //! to that containerChain, by simply assigning the slot position. use { - crate::{mock::*, pallet as payment_services_pallet, BlockProductionCredits}, + crate::{mock::*, pallet as pallet_services_payment, BlockProductionCredits}, + cumulus_primitives_core::ParaId, frame_support::{assert_err, assert_ok}, + sp_runtime::DispatchError, }; const ALICE: u64 = 1; @@ -52,7 +54,7 @@ fn purchase_credits_works() { assert_eq!( events(), - vec![payment_services_pallet::Event::CreditsPurchased { + vec![pallet_services_payment::Event::CreditsPurchased { para_id: 1.into(), payer: ALICE, fee: 500, @@ -98,14 +100,14 @@ fn purchase_credits_purchases_zero_when_max_already_stored() { assert_eq!( events(), vec![ - payment_services_pallet::Event::CreditsPurchased { + pallet_services_payment::Event::CreditsPurchased { para_id, payer: ALICE, fee: 500, credits_purchased: MaxCreditsStored::get(), credits_remaining: MaxCreditsStored::get(), }, - payment_services_pallet::Event::CreditsPurchased { + pallet_services_payment::Event::CreditsPurchased { para_id, payer: ALICE, fee: 0, @@ -156,14 +158,14 @@ fn purchase_credits_purchases_max_possible_when_cant_purchase_all_requested() { assert_eq!( events(), vec![ - payment_services_pallet::Event::CreditsPurchased { + pallet_services_payment::Event::CreditsPurchased { para_id, payer: ALICE, fee: 100, credits_purchased: amount_purchased, credits_remaining: amount_purchased, }, - payment_services_pallet::Event::CreditsPurchased { + pallet_services_payment::Event::CreditsPurchased { para_id, payer: ALICE, fee: 400, @@ -181,7 +183,7 @@ fn purchase_credits_fails_with_insufficient_balance() { // really what we're testing is that purchase_credits fails when OnChargeForBlockCredits does assert_err!( PaymentServices::purchase_credits(RuntimeOrigin::signed(ALICE), 1.into(), 1, None), - payment_services_pallet::Error::::InsufficientFundsToPurchaseCredits, + pallet_services_payment::Error::::InsufficientFundsToPurchaseCredits, ); }); } @@ -191,7 +193,7 @@ fn burn_credit_fails_with_no_credits() { ExtBuilder::default().build().execute_with(|| { assert_err!( PaymentServices::burn_credit_for_para(&1u32.into()), - payment_services_pallet::Error::::InsufficientCredits, + pallet_services_payment::Error::::InsufficientCredits, ); }); } @@ -218,7 +220,7 @@ fn burn_credit_works() { // now should fail assert_err!( PaymentServices::burn_credit_for_para(¶_id), - payment_services_pallet::Error::::InsufficientCredits, + pallet_services_payment::Error::::InsufficientCredits, ); }); } @@ -241,7 +243,7 @@ fn burn_credit_fails_for_wrong_para() { let wrong_para_id = 2.into(); assert_err!( PaymentServices::burn_credit_for_para(&wrong_para_id), - payment_services_pallet::Error::::InsufficientCredits, + pallet_services_payment::Error::::InsufficientCredits, ); }); } @@ -274,7 +276,7 @@ fn buy_credits_too_expensive_fails() { 1u64, Some(FIXED_BLOCK_PRODUCTION_COST - 1), ), - payment_services_pallet::Error::::CreditPriceTooExpensive, + pallet_services_payment::Error::::CreditPriceTooExpensive, ); }); } @@ -308,3 +310,51 @@ fn buy_credits_limit_exceeds_price_works() { ),); }); } + +#[test] +fn set_credits_bad_origin() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + assert_err!( + PaymentServices::set_credits(RuntimeOrigin::signed(ALICE), 1.into(), 1u64,), + DispatchError::BadOrigin + ) + }); +} + +#[test] +fn set_credits_above_max_works() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + assert_ok!(PaymentServices::set_credits( + RuntimeOrigin::root(), + 1.into(), + MaxCreditsStored::get() * 2, + )); + + assert_eq!( + >::get(ParaId::from(1)), + Some(MaxCreditsStored::get() * 2) + ); + }); +} + +#[test] +fn set_credits_to_zero_kills_storage() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + assert_ok!(PaymentServices::set_credits( + RuntimeOrigin::root(), + 1.into(), + 0u64, + )); + + assert_eq!(>::get(ParaId::from(1)), None,); + }); +} diff --git a/pallets/services-payment/src/weights.rs b/pallets/services-payment/src/weights.rs new file mode 100644 index 000000000..aa0db2883 --- /dev/null +++ b/pallets/services-payment/src/weights.rs @@ -0,0 +1,112 @@ +// 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 + + +//! Autogenerated weights for pallet_services_payment +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-13, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `tomasz-XPS-15-9520`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// ./target/release/tanssi-node +// benchmark +// pallet +// --execution=wasm +// --wasm-execution=compiled +// --pallet +// pallet_services_payment +// --extrinsic +// * +// --steps +// 50 +// --repeat +// 20 +// --template=./benchmarking/frame-weight-template.hbs +// --json-file +// raw.json +// --output +// weights.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_services_payment. +pub trait WeightInfo { + fn purchase_credits() -> Weight; + fn set_credits() -> Weight; +} + +/// Weights for pallet_services_payment using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `ServicesPayment::BlockProductionCredits` (r:1 w:1) + /// Proof: `ServicesPayment::BlockProductionCredits` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn purchase_credits() -> Weight { + // Proof Size summary in bytes: + // Measured: `187` + // Estimated: `3593` + // Minimum execution time: 23_134_000 picoseconds. + Weight::from_parts(23_980_000, 3593) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `ServicesPayment::BlockProductionCredits` (r:0 w:1) + /// Proof: `ServicesPayment::BlockProductionCredits` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + fn set_credits() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_098_000 picoseconds. + Weight::from_parts(7_268_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: `ServicesPayment::BlockProductionCredits` (r:1 w:1) + /// Proof: `ServicesPayment::BlockProductionCredits` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn purchase_credits() -> Weight { + // Proof Size summary in bytes: + // Measured: `187` + // Estimated: `3593` + // Minimum execution time: 23_134_000 picoseconds. + Weight::from_parts(23_980_000, 3593) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `ServicesPayment::BlockProductionCredits` (r:0 w:1) + /// Proof: `ServicesPayment::BlockProductionCredits` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + fn set_credits() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_098_000 picoseconds. + Weight::from_parts(7_268_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/primitives/traits/Cargo.toml b/primitives/traits/Cargo.toml index deb38c889..7ca06cac7 100644 --- a/primitives/traits/Cargo.toml +++ b/primitives/traits/Cargo.toml @@ -7,6 +7,7 @@ license = "GPL-3.0-only" version = "0.1.0" [dependencies] +impl-trait-for-tuples = { workspace = true } frame-support = { workspace = true } sp-std = { workspace = true } diff --git a/primitives/traits/src/lib.rs b/primitives/traits/src/lib.rs index 6f370701e..32aba7f6c 100644 --- a/primitives/traits/src/lib.rs +++ b/primitives/traits/src/lib.rs @@ -43,9 +43,12 @@ pub trait AuthorNotingHook { ) -> Weight; } -impl AuthorNotingHook for () { - fn on_container_author_noted(_: &AccountId, _: BlockNumber, _: ParaId) -> Weight { - Weight::zero() +#[impl_trait_for_tuples::impl_for_tuples(5)] +impl AuthorNotingHook for Tuple { + fn on_container_author_noted(a: &AccountId, b: BlockNumber, p: ParaId) -> Weight { + let mut weight: Weight = Default::default(); + for_tuples!( #( weight.saturating_accrue(Tuple::on_container_author_noted(a, b, p)); )* ); + weight } } @@ -110,3 +113,15 @@ pub trait RemoveInvulnerables { num_invulnerables: usize, ) -> Vec; } + +/// Helper trait for pallet_collator_assignment to be able to not assign collators to container chains with no credits +/// in pallet_services_payment +pub trait RemoveParaIdsWithNoCredits { + /// Remove para ids with not enough credits. The resulting order will affect priority: the first para id in the list + /// will be the first one to get collators. + fn remove_para_ids_with_no_credits(para_ids: &mut Vec); + + /// Make those para ids valid by giving them enough credits, for benchmarking. + #[cfg(feature = "runtime-benchmarks")] + fn make_valid_para_ids(para_ids: &[ParaId]); +} diff --git a/runtime/dancebox/Cargo.toml b/runtime/dancebox/Cargo.toml index 085d46251..603a4dca5 100644 --- a/runtime/dancebox/Cargo.toml +++ b/runtime/dancebox/Cargo.toml @@ -31,6 +31,7 @@ pallet-pooled-staking = { workspace = true } pallet-proxy = { workspace = true } pallet-registrar = { workspace = true } pallet-registrar-runtime-api = { workspace = true } +pallet-services-payment = { workspace = true } tp-core = { workspace = true } # Moonkit @@ -154,6 +155,7 @@ std = [ "pallet-registrar-runtime-api/std", "pallet-registrar/std", "pallet-session/std", + "pallet-services-payment/std", "pallet-sudo/std", "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", @@ -202,6 +204,7 @@ runtime-benchmarks = [ "pallet-invulnerables/runtime-benchmarks", "pallet-pooled-staking/runtime-benchmarks", "pallet-registrar/runtime-benchmarks", + "pallet-services-payment/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", @@ -235,6 +238,7 @@ try-runtime = [ "pallet-pooled-staking/try-runtime", "pallet-proxy/try-runtime", "pallet-registrar/try-runtime", + "pallet-services-payment/try-runtime", "pallet-root-testing/try-runtime", "pallet-session/try-runtime", "pallet-sudo/try-runtime", diff --git a/runtime/dancebox/src/lib.rs b/runtime/dancebox/src/lib.rs index b7191ca0c..7074b076e 100644 --- a/runtime/dancebox/src/lib.rs +++ b/runtime/dancebox/src/lib.rs @@ -29,7 +29,6 @@ use sp_version::NativeVersion; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -use tp_traits::RemoveInvulnerables; pub mod migrations; pub mod weights; @@ -72,6 +71,7 @@ use { pallet_invulnerables::InvulnerableRewardDistribution, pallet_pooled_staking::traits::{IsCandidateEligible, Timer}, pallet_registrar_runtime_api::ContainerChainGenesisData, + pallet_services_payment::{ChargeForBlockCredit, ProvideBlockProductionCost}, pallet_session::{SessionManager, ShouldEndSession}, pallet_transaction_payment::{ConstFeeMultiplier, CurrencyAdapter, Multiplier}, polkadot_runtime_common::BlockHashCount, @@ -89,7 +89,7 @@ use { }, sp_std::{marker::PhantomData, prelude::*}, sp_version::RuntimeVersion, - tp_traits::GetSessionContainerChains, + tp_traits::{GetSessionContainerChains, RemoveInvulnerables, RemoveParaIdsWithNoCredits}, }; pub use { sp_runtime::{MultiAddress, Perbill, Permill}, @@ -686,6 +686,40 @@ impl RemoveInvulnerables for RemoveInvulnerablesImpl { } } +pub struct RemoveParaIdsWithNoCreditsImpl; + +impl RemoveParaIdsWithNoCredits for RemoveParaIdsWithNoCreditsImpl { + fn remove_para_ids_with_no_credits(para_ids: &mut Vec) { + let blocks_per_session = Period::get(); + let credits_for_2_sessions = 2 * blocks_per_session; + para_ids.retain(|para_id| { + // Check if the container chain has enough credits for producing blocks for 2 sessions + let credits = pallet_services_payment::BlockProductionCredits::::get(para_id) + .unwrap_or_default(); + + credits >= credits_for_2_sessions + }); + } + + /// Make those para ids valid by giving them enough credits, for benchmarking. + #[cfg(feature = "runtime-benchmarks")] + fn make_valid_para_ids(para_ids: &[ParaId]) { + use frame_support::assert_ok; + + let blocks_per_session = Period::get(); + // Enough credits to run any benchmark + let credits = 20 * blocks_per_session; + + for para_id in para_ids { + assert_ok!(ServicesPayment::set_credits( + RuntimeOrigin::root(), + *para_id, + credits, + )); + } + } +} + impl pallet_collator_assignment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type HostConfiguration = Configuration; @@ -696,6 +730,7 @@ impl pallet_collator_assignment::Config for Runtime { RotateCollatorsEveryNSessions; type GetRandomnessForNextBlock = BabeGetRandomnessForNextBlock; type RemoveInvulnerables = RemoveInvulnerablesImpl; + type RemoveParaIdsWithNoCredits = RemoveParaIdsWithNoCreditsImpl; type WeightInfo = pallet_collator_assignment::weights::SubstrateWeight; } @@ -704,13 +739,40 @@ impl pallet_authority_assignment::Config for Runtime { type AuthorityId = NimbusId; } +pub const FIXED_BLOCK_PRODUCTION_COST: u128 = 1 * currency::MICRODANCE; + +pub struct BlockProductionCost(PhantomData); +impl ProvideBlockProductionCost for BlockProductionCost { + fn block_cost(_para_id: &ParaId) -> (u128, Weight) { + (FIXED_BLOCK_PRODUCTION_COST, Weight::zero()) + } +} + +parameter_types! { + // 60 days worth of blocks + pub const MaxCreditsStored: BlockNumber = 60 * DAYS; +} + +impl pallet_services_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + /// Handler for fees + type OnChargeForBlockCredit = ChargeForBlockCredit; + /// Currency type for fee payment + type Currency = Balances; + /// Provider of a block cost which can adjust from block to block + type ProvideBlockProductionCost = BlockProductionCost; + /// The maximum number of credits that can be accumulated + type MaxCreditsStored = MaxCreditsStored; + type WeightInfo = pallet_services_payment::weights::SubstrateWeight; +} + impl pallet_author_noting::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ContainerChains = Registrar; type SelfParaId = parachain_info::Pallet; type ContainerChainAuthor = CollatorAssignment; type RelayChainStateProvider = cumulus_pallet_parachain_system::RelaychainDataProvider; - type AuthorNotingHook = InflationRewards; + type AuthorNotingHook = (InflationRewards, ServicesPayment); type WeightInfo = pallet_author_noting::weights::SubstrateWeight; } @@ -1197,6 +1259,7 @@ construct_runtime!( Initializer: pallet_initializer = 23, AuthorNoting: pallet_author_noting = 24, AuthorityAssignment: pallet_authority_assignment = 25, + ServicesPayment: pallet_services_payment = 26, // Collator support. The order of these 6 are important and shall not change. Invulnerables: pallet_invulnerables = 30, @@ -1227,6 +1290,7 @@ mod benches { [pallet_registrar, Registrar] [pallet_invulnerables, Invulnerables] [pallet_pooled_staking, PooledStaking] + [pallet_services_payment, ServicesPayment] [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] ); } diff --git a/runtime/dancebox/src/migrations.rs b/runtime/dancebox/src/migrations.rs index 81b4d13df..badac5857 100644 --- a/runtime/dancebox/src/migrations.rs +++ b/runtime/dancebox/src/migrations.rs @@ -31,7 +31,7 @@ use { pallet_migrations::{GetMigrations, Migration}, sp_core::Get, sp_runtime::BoundedVec, - sp_std::{marker::PhantomData, prelude::*}, + sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*}, }; #[derive( @@ -338,6 +338,43 @@ where } } +pub struct MigrateServicesPaymentAddCredits(pub PhantomData); +impl Migration for MigrateServicesPaymentAddCredits +where + T: cumulus_pallet_xcmp_queue::Config, +{ + fn friendly_name(&self) -> &str { + "TM_MigrateServicesPaymentAddCredits" + } + + fn migrate(&self, _available_weight: Weight) -> Weight { + // For each parachain in pallet_registrar (active, pending or pending_verification), + // insert `MaxCreditsStored` to pallet_services_payment + let mut para_ids = BTreeSet::new(); + let active = pallet_registrar::RegisteredParaIds::::get(); + let pending = pallet_registrar::PendingParaIds::::get(); + let pending_verification = pallet_registrar::PendingVerification::::get(); + + para_ids.extend(active); + para_ids.extend(pending.into_iter().flat_map(|(_session, active)| active)); + para_ids.extend(pending_verification); + + let max_credits = crate::MaxCreditsStored::get(); + let reads = 3; + let writes = para_ids.len() as u64; + + for para_id in para_ids { + pallet_services_payment::BlockProductionCredits::::insert( + para_id, + max_credits, + ); + } + + let db_weights = T::DbWeight::get(); + db_weights.reads_writes(reads, writes) + } +} + pub struct DanceboxMigrations(PhantomData); impl GetMigrations for DanceboxMigrations @@ -356,6 +393,8 @@ where let migrate_config = MigrateConfigurationFullRotationPeriod::(Default::default()); let migrate_xcm = PolkadotXcmMigration::(Default::default()); let migrate_xcmp_queue = XcmpQueueMigration::(Default::default()); + let migrate_services_payment = + MigrateServicesPaymentAddCredits::(Default::default()); vec![ Box::new(migrate_invulnerables), @@ -363,6 +402,7 @@ where Box::new(migrate_config), Box::new(migrate_xcm), Box::new(migrate_xcmp_queue), + Box::new(migrate_services_payment), ] } } diff --git a/runtime/dancebox/tests/common/mod.rs b/runtime/dancebox/tests/common/mod.rs index 7fb40a8a4..3eeb34731 100644 --- a/runtime/dancebox/tests/common/mod.rs +++ b/runtime/dancebox/tests/common/mod.rs @@ -17,10 +17,7 @@ use { cumulus_primitives_core::{ParaId, PersistedValidationData}, cumulus_primitives_parachain_inherent::ParachainInherentData, - dancebox_runtime::{ - AuthorInherent, AuthorityAssignment, CollatorAssignment, InflationRewards, - MaxLengthTokenSymbol, - }, + dancebox_runtime::{AuthorInherent, MaxLengthTokenSymbol}, frame_support::{ assert_ok, traits::{OnFinalize, OnInitialize}, @@ -41,8 +38,10 @@ use { mod xcm; pub use dancebox_runtime::{ - AccountId, Balance, Balances, Initializer, ParachainInfo, Registrar, Runtime, RuntimeCall, - RuntimeEvent, Session, System, + AccountId, AuthorNoting, AuthorityAssignment, AuthorityMapping, Balance, Balances, + CollatorAssignment, Configuration, InflationRewards, Initializer, Invulnerables, + MinimumSelfDelegation, ParachainInfo, PooledStaking, Proxy, ProxyType, Registrar, + RewardsPortion, Runtime, RuntimeCall, RuntimeEvent, ServicesPayment, Session, System, }; pub fn session_to_block(n: u32) -> u32 { @@ -201,11 +200,12 @@ pub struct ExtBuilder { balances: Vec<(AccountId, Balance)>, // [collator, amount] collators: Vec<(AccountId, Balance)>, - // list of registered para ids + // list of registered para ids: para_id, genesis_data, boot_nodes, block_credits para_ids: Vec<( u32, ContainerChainGenesisData, Vec>, + u32, )>, // configuration to apply config: pallet_configuration::HostConfiguration, @@ -230,6 +230,7 @@ impl ExtBuilder { u32, ContainerChainGenesisData, Vec>, + u32, )>, ) -> Self { self.para_ids = para_ids; @@ -268,8 +269,9 @@ impl ExtBuilder { pallet_registrar::GenesisConfig:: { para_ids: self .para_ids - .into_iter() - .map(|(para_id, genesis_data, boot_nodes)| { + .iter() + .cloned() + .map(|(para_id, genesis_data, boot_nodes, _block_credits)| { (para_id.into(), genesis_data, boot_nodes) }) .collect(), @@ -277,6 +279,18 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); + pallet_services_payment::GenesisConfig:: { + para_id_credits: self + .para_ids + .into_iter() + .map(|(para_id, _genesis_data, _boot_nodes, block_credits)| { + (para_id.into(), block_credits) + }) + .collect(), + } + .assimilate_storage(&mut t) + .unwrap(); + pallet_configuration::GenesisConfig:: { config: self.config, ..Default::default() @@ -391,6 +405,12 @@ pub fn set_author_noting_inherent_data(builder: ParaHeaderSproofBuilder) { }, ); + // But we also need to store the new proof submitted + frame_support::storage::unhashed::put( + &frame_support::storage::storage_prefix(b"ParachainSystem", b"RelayStateProof"), + &relay_storage_proof, + ); + assert_ok!(RuntimeCall::AuthorNoting( pallet_author_noting::Call::::set_latest_author_data { data: tp_author_noting_inherent::OwnParachainInherentData { diff --git a/runtime/dancebox/tests/integration_test.rs b/runtime/dancebox/tests/integration_test.rs index afb002a74..fe3fcd941 100644 --- a/runtime/dancebox/tests/integration_test.rs +++ b/runtime/dancebox/tests/integration_test.rs @@ -22,11 +22,9 @@ use { dancebox_runtime::{ migrations::{ CollatorSelectionInvulnerablesValue, MigrateConfigurationFullRotationPeriod, - MigrateInvulnerables, + MigrateInvulnerables, MigrateServicesPaymentAddCredits, }, - AuthorNoting, AuthorityAssignment, AuthorityMapping, CollatorAssignment, Configuration, - Invulnerables, MinimumSelfDelegation, PooledStaking, Proxy, ProxyType, - RewardsCollatorCommission, RewardsPortion, + BlockProductionCost, RewardsCollatorCommission, }, frame_support::{assert_noop, assert_ok, BoundedVec}, nimbus_primitives::NIMBUS_KEY_ID, @@ -41,6 +39,7 @@ use { pallet_registrar_runtime_api::{ runtime_decl_for_registrar_api::RegistrarApi, ContainerChainGenesisData, }, + pallet_services_payment::ProvideBlockProductionCost, parity_scale_codec::Encode, sp_consensus_aura::AURA_ENGINE_ID, sp_core::Get, @@ -88,8 +87,8 @@ fn genesis_para_registrar() { (AccountId::from(BOB), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .build() .execute_with(|| { @@ -119,8 +118,8 @@ fn genesis_para_registrar_deregister() { (AccountId::from(BOB), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_collators(vec![ (AccountId::from(ALICE), 210 * UNIT), @@ -168,8 +167,8 @@ fn genesis_para_registrar_runtime_api() { (AccountId::from(BOB), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_collators(vec![ (AccountId::from(ALICE), 210 * UNIT), @@ -219,8 +218,8 @@ fn genesis_para_registrar_container_chain_genesis_data_runtime_api() { (AccountId::from(BOB), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, genesis_data_1001.clone(), vec![]), - (1002, genesis_data_1002.clone(), vec![]), + (1001, genesis_data_1001.clone(), vec![], u32::MAX), + (1002, genesis_data_1002.clone(), vec![], u32::MAX), ]) .with_collators(vec![ (AccountId::from(ALICE), 210 * UNIT), @@ -295,8 +294,8 @@ fn test_author_collation_aura() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -330,8 +329,8 @@ fn test_author_collation_aura_change_of_authorities_on_session() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -402,8 +401,8 @@ fn test_author_collation_aura_add_assigned_to_paras() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -544,6 +543,12 @@ fn test_authors_paras_inserted_a_posteriori() { Registrar::mark_valid_for_collating(root_origin(), 1001.into()), () ); + assert_ok!(ServicesPayment::purchase_credits( + origin_of(ALICE.into()), + 1001.into(), + 100_000, + None, + )); assert_ok!( Registrar::register(origin_of(ALICE.into()), 1002.into(), empty_genesis_data()), () @@ -552,6 +557,12 @@ fn test_authors_paras_inserted_a_posteriori() { Registrar::mark_valid_for_collating(root_origin(), 1002.into()), () ); + assert_ok!(ServicesPayment::purchase_credits( + origin_of(ALICE.into()), + 1002.into(), + 100_000, + None, + )); // Assignment should happen after 2 sessions run_to_session(1u32); @@ -559,7 +570,7 @@ fn test_authors_paras_inserted_a_posteriori() { assert!(assignment.container_chains.is_empty()); run_to_session(2u32); - // Charlie and Dave should be assigne dot para 1001 + // Charlie and Dave should be assigned to para 1001 let assignment = CollatorAssignment::collator_container_chain(); assert_eq!( assignment.container_chains[&1001u32.into()], @@ -614,6 +625,12 @@ fn test_authors_paras_inserted_a_posteriori_with_collators_already_assigned() { Registrar::mark_valid_for_collating(root_origin(), 1001.into()), () ); + assert_ok!(ServicesPayment::purchase_credits( + origin_of(ALICE.into()), + 1001.into(), + 100_000, + None, + )); // Assignment should happen after 2 sessions run_to_session(1u32); @@ -634,6 +651,237 @@ fn test_authors_paras_inserted_a_posteriori_with_collators_already_assigned() { }); } +#[test] +fn test_paras_registered_but_zero_credits() { + 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(|| { + run_to_block(2); + // Assert current slot gets updated + assert_eq!(current_slot(), 1u64); + assert!(current_author() == AccountId::from(BOB)); + + // Alice and Bob collate in our chain + let alice_id = get_aura_id_from_seed(&AccountId::from(ALICE).to_string()); + let bob_id = get_aura_id_from_seed(&AccountId::from(BOB).to_string()); + + assert_eq!(authorities(), vec![alice_id, bob_id]); + + assert_ok!( + Registrar::register(origin_of(ALICE.into()), 1001.into(), empty_genesis_data()), + () + ); + assert_ok!( + Registrar::mark_valid_for_collating(root_origin(), 1001.into()), + () + ); + + // Assignment should happen after 2 sessions + run_to_session(1u32); + let assignment = CollatorAssignment::collator_container_chain(); + assert!(assignment.container_chains.is_empty()); + run_to_session(2u32); + + // Nobody should be assigned to para 1001 + let assignment = CollatorAssignment::collator_container_chain(); + assert_eq!(assignment.container_chains.get(&1001u32.into()), None,); + }); +} + +#[test] +fn test_paras_registered_but_not_enough_credits() { + 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(|| { + run_to_block(2); + // Assert current slot gets updated + assert_eq!(current_slot(), 1u64); + assert!(current_author() == AccountId::from(BOB)); + + // Alice and Bob collate in our chain + let alice_id = get_aura_id_from_seed(&AccountId::from(ALICE).to_string()); + let bob_id = get_aura_id_from_seed(&AccountId::from(BOB).to_string()); + + assert_eq!(authorities(), vec![alice_id, bob_id]); + + assert_ok!( + Registrar::register(origin_of(ALICE.into()), 1001.into(), empty_genesis_data()), + () + ); + assert_ok!( + Registrar::mark_valid_for_collating(root_origin(), 1001.into()), + () + ); + // Purchase 1 credit less that what is needed + let credits_1001 = dancebox_runtime::Period::get() * 2 - 1; + assert_ok!(ServicesPayment::purchase_credits( + origin_of(ALICE.into()), + 1001.into(), + credits_1001, + None, + )); + + // Assignment should happen after 2 sessions + run_to_session(1u32); + let assignment = CollatorAssignment::collator_container_chain(); + assert!(assignment.container_chains.is_empty()); + run_to_session(2u32); + // Nobody should be assigned to para 1001 + let assignment = CollatorAssignment::collator_container_chain(); + assert_eq!(assignment.container_chains.get(&1001u32.into()), None,); + + // Now purchase the missing block credit + assert_ok!(ServicesPayment::purchase_credits( + origin_of(ALICE.into()), + 1001.into(), + 1, + None, + )); + + run_to_session(4u32); + // Charlie and Dave should be assigned to para 1001 + let assignment = CollatorAssignment::collator_container_chain(); + assert_eq!( + assignment.container_chains[&1001u32.into()], + vec![CHARLIE.into(), DAVE.into()] + ); + }); +} + +#[test] +fn test_paras_registered_but_only_credits_for_1_session() { + 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(|| { + run_to_block(2); + // Assert current slot gets updated + assert_eq!(current_slot(), 1u64); + assert!(current_author() == AccountId::from(BOB)); + + // Alice and Bob collate in our chain + let alice_id = get_aura_id_from_seed(&AccountId::from(ALICE).to_string()); + let bob_id = get_aura_id_from_seed(&AccountId::from(BOB).to_string()); + + assert_eq!(authorities(), vec![alice_id, bob_id]); + + assert_ok!( + Registrar::register(origin_of(ALICE.into()), 1001.into(), empty_genesis_data()), + () + ); + assert_ok!( + Registrar::mark_valid_for_collating(root_origin(), 1001.into()), + () + ); + // Purchase only enough credits for 1 session + let credits_1001 = dancebox_runtime::Period::get() * 2; + assert_ok!(ServicesPayment::purchase_credits( + origin_of(ALICE.into()), + 1001.into(), + credits_1001, + None, + )); + + // Assignment should happen after 2 sessions + run_to_session(1u32); + let assignment = CollatorAssignment::collator_container_chain(); + assert!(assignment.container_chains.is_empty()); + run_to_session(2u32); + // Charlie and Dave should be assigned to para 1001 + let assignment = CollatorAssignment::collator_container_chain(); + assert_eq!( + assignment.container_chains[&1001u32.into()], + vec![CHARLIE.into(), DAVE.into()] + ); + + // No credits are consumed if the container chain is not producing blocks + run_block(); + let credits = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1001), + ) + .unwrap_or_default(); + assert_eq!(credits, credits_1001); + + // Simulate block inclusion from container chain 1001 + let mut sproof = ParaHeaderSproofBuilder::default(); + let slot: u64 = 5; + let mut s = ParaHeaderSproofBuilderItem::default(); + s.para_id = 1001.into(); + s.author_id = HeaderAs::NonEncoded(sp_runtime::generic::Header:: { + parent_hash: Default::default(), + number: 1, + state_root: Default::default(), + extrinsics_root: Default::default(), + digest: sp_runtime::generic::Digest { + logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())], + }, + }); + sproof.items.push(s); + set_author_noting_inherent_data(sproof); + + run_block(); + let credits = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1001), + ) + .unwrap_or_default(); + assert_eq!(credits, credits_1001 - 1); + + run_to_session(4u32); + // Nobody should be assigned to para 1001 + let assignment = CollatorAssignment::collator_container_chain(); + assert_eq!(assignment.container_chains.get(&1001u32.into()), None,); + + // The container chain only produced one block, so it only consumed one block credit. + // (it could have produced more blocks, but at most it would have consumed `Period::get()` credits) + let credits = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1001), + ) + .unwrap_or_default(); + assert_eq!(credits, credits_1001 - 1); + }); +} + #[test] fn test_parachains_deregister_collators_re_assigned() { ExtBuilder::default() @@ -651,8 +899,8 @@ fn test_parachains_deregister_collators_re_assigned() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -714,8 +962,8 @@ fn test_parachains_deregister_collators_config_change_reassigned() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -781,8 +1029,8 @@ fn test_orchestrator_collators_with_non_sufficient_collators() { ]) .with_collators(vec![(AccountId::from(ALICE), 210 * UNIT)]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -868,8 +1116,8 @@ fn test_author_collation_aura_add_assigned_to_paras_runtime_api() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -1032,8 +1280,8 @@ fn test_consensus_runtime_api() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -1127,8 +1375,8 @@ fn test_consensus_runtime_api_session_changes() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -1243,8 +1491,8 @@ fn test_consensus_runtime_api_next_session() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -1455,8 +1703,8 @@ fn test_author_noting_not_self_para() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .build() .execute_with(|| { @@ -1513,8 +1761,8 @@ fn test_author_noting_set_author_and_kill_author_data() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .build() .execute_with(|| { @@ -1558,8 +1806,8 @@ fn test_author_noting_set_author_and_kill_author_data_bad_origin() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .build() .execute_with(|| { @@ -1599,8 +1847,8 @@ fn test_author_noting_runtime_api() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .build() .execute_with(|| { @@ -1663,8 +1911,8 @@ fn test_collator_assignment_rotation() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .build() .execute_with(|| { @@ -1723,8 +1971,8 @@ fn test_session_keys_with_authority_mapping() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -1808,8 +2056,8 @@ fn test_session_keys_with_authority_assignment() { (AccountId::from(BOB), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2099,8 +2347,8 @@ fn test_staking_no_candidates_in_genesis() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2131,8 +2379,8 @@ fn test_staking_join() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2184,8 +2432,8 @@ fn test_staking_join_no_keys_registered() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2240,8 +2488,8 @@ fn test_staking_register_keys_after_joining() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2329,8 +2577,8 @@ fn test_staking_join_bad_origin() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2367,8 +2615,8 @@ fn test_staking_join_below_self_delegation_min() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2440,8 +2688,8 @@ fn test_staking_join_no_self_delegation() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2480,8 +2728,8 @@ fn test_staking_join_before_self_delegation() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2551,8 +2799,8 @@ fn test_staking_join_twice_in_same_block() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2621,8 +2869,8 @@ fn test_staking_join_execute_before_time() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2697,8 +2945,8 @@ fn test_staking_join_execute_any_origin() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2757,8 +3005,8 @@ fn test_staking_join_execute_bad_origin() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -2826,8 +3074,8 @@ fn setup_staking_join_and_execute(ops: Vec, f: impl FnOnce() -> R) { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -3263,8 +3511,8 @@ fn test_pallet_session_takes_validators_from_invulnerables_and_staking() { (AccountId::from(CHARLIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -3354,8 +3602,8 @@ fn test_pallet_session_limits_num_validators() { (AccountId::from(CHARLIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(pallet_configuration::HostConfiguration { max_collators: 2, @@ -3442,8 +3690,8 @@ fn test_pallet_session_limits_num_validators_from_staking() { ]) .with_collators(vec![(AccountId::from(ALICE), 210 * UNIT)]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(pallet_configuration::HostConfiguration { max_collators: 2, @@ -3604,8 +3852,8 @@ fn test_reward_to_staking_candidate() { ]) .with_collators(vec![(AccountId::from(ALICE), 210 * UNIT)]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(pallet_configuration::HostConfiguration { max_collators: 100, @@ -3718,8 +3966,8 @@ fn test_reward_to_invulnerable() { (AccountId::from(CHARLIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(pallet_configuration::HostConfiguration { max_collators: 100, @@ -3815,8 +4063,8 @@ fn test_reward_to_invulnerable_with_key_change() { ]) .with_collators(vec![(AccountId::from(ALICE), 210 * UNIT)]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(pallet_configuration::HostConfiguration { max_collators: 100, @@ -3906,6 +4154,65 @@ fn test_migration_config_full_rotation_period() { }); } +#[test] +fn test_migration_services_payment() { + 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), + ]) + .with_collators(vec![ + (AccountId::from(ALICE), 210 * UNIT), + (AccountId::from(BOB), 100 * UNIT), + ]) + .with_config(default_config()) + .build() + .execute_with(|| { + // Register a new parachain with no credits + assert_ok!( + Registrar::register(origin_of(ALICE.into()), 1001.into(), empty_genesis_data()), + () + ); + assert_ok!( + Registrar::mark_valid_for_collating(root_origin(), 1001.into()), + () + ); + // Register another parachain with no credits, do not mark this as valid for collation + assert_ok!( + Registrar::register(origin_of(ALICE.into()), 1002.into(), empty_genesis_data()), + () + ); + + let credits_1001 = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1001), + ) + .unwrap_or_default(); + assert_eq!(credits_1001, 0); + let credits_1002 = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1002), + ) + .unwrap_or_default(); + assert_eq!(credits_1002, 0); + + // Apply migration + let migration = MigrateServicesPaymentAddCredits::(Default::default()); + migration.migrate(Default::default()); + + // Both parachains have been given credits + let credits_1001 = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1001), + ) + .unwrap_or_default(); + assert_ne!(credits_1001, 0); + let credits_1002 = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1002), + ) + .unwrap_or_default(); + assert_ne!(credits_1002, 0); + }); +} + #[test] fn test_collator_assignment_gives_priority_to_invulnerables() { // Set max_collators = 2, take 1 invulnerable and the rest from staking @@ -3922,8 +4229,8 @@ fn test_collator_assignment_gives_priority_to_invulnerables() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![]), - (1002, empty_genesis_data(), vec![]), + (1001, empty_genesis_data(), vec![], u32::MAX), + (1002, empty_genesis_data(), vec![], u32::MAX), ]) .with_config(default_config()) .build() @@ -4020,3 +4327,47 @@ fn test_collator_assignment_gives_priority_to_invulnerables() { ); }); } + +#[test] +fn test_can_buy_credits_before_registering_para() { + 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(|| { + run_to_block(2); + + // Try to buy the maximum amount of credits + let balance_before = System::account(AccountId::from(ALICE)).data.free; + assert_ok!(ServicesPayment::purchase_credits( + origin_of(ALICE.into()), + 1001.into(), + u32::MAX, + None, + )); + let balance_after = System::account(AccountId::from(ALICE)).data.free; + + // But only up to MaxCreditsStored have actually been purchased + let credits = pallet_services_payment::BlockProductionCredits::::get( + &ParaId::from(1001), + ) + .unwrap_or_default(); + assert_eq!(credits, dancebox_runtime::MaxCreditsStored::get()); + + let expected_cost = BlockProductionCost::::block_cost(&ParaId::from(1001)).0 + * u128::from(dancebox_runtime::MaxCreditsStored::get()); + assert_eq!(balance_before - balance_after, expected_cost); + }); +} diff --git a/test/suites/dev-tanssi/services-payment/test_services_payment.ts b/test/suites/dev-tanssi/services-payment/test_services_payment.ts new file mode 100644 index 000000000..7cd1d9ce7 --- /dev/null +++ b/test/suites/dev-tanssi/services-payment/test_services_payment.ts @@ -0,0 +1,234 @@ +import "@tanssi/api-augment"; +import { describeSuite, expect, beforeAll } from "@moonwall/cli"; +import { ApiPromise } from "@polkadot/api"; +import { generateKeyringPair, KeyringPair } from "@moonwall/util"; +import { jumpSessions } from "util/block"; + +describeSuite({ + id: "SP0801", + title: "Services payment test suite", + foundationMethods: "dev", + testCases: ({ it, context }) => { + let polkadotJs: ApiPromise; + let alice: KeyringPair; + const blocksPerSession = 5n; + + beforeAll(async () => { + polkadotJs = context.polkadotJs(); + alice = context.keyring.alice; + }); + it({ + id: "E01", + title: "Genesis container chains have credits and collators", + test: async function () { + await context.createBlock(); + const parasRegistered = await polkadotJs.query.registrar.registeredParaIds(); + + for (const paraId of parasRegistered.toJSON()) { + // Should have credits + const credits = await polkadotJs.query.servicesPayment.blockProductionCredits(paraId); + expect( + credits.toJSON(), + `Container chain ${paraId} does not have enough credits at genesis` + ).toBeGreaterThanOrEqual(2n * blocksPerSession); + + // Should have assigned collators + const collators = await polkadotJs.query.collatorAssignment.collatorContainerChain(); + // Container chain 2001 does not have any collators, this will result in only 1 container chain + // producing blocks at a time. So if both container chains have 1000 credits, container 2000 + // will produce blocks 0-999, and container 2001 will produce blocks 1000-1999. + if (paraId == 2000) { + expect( + collators.toJSON().containerChains[paraId].length, + `Container chain ${paraId} has 0 collators` + ).toBeGreaterThan(0); + } + } + }, + }); + + it({ + id: "E02", + title: "Creating a container chain block costs credits", + test: async function () { + // Read num credits of para 2000, then create that many blocks. Check that authorNoting.blockNum does not increase anymore + // and collatorAssignment does not have collators + + const paraId = 2000n; + + // Create a block, the block number should increase, and the number of credits should decrease + const credits1 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + const containerBlockNum1 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + await context.createBlock(); + const credits2 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + const containerBlockNum2 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + expect(containerBlockNum1, "container chain 2000 did not create a block").toBeLessThan( + containerBlockNum2 + ); + expect(credits1, "container chain 2000 created a block without burning any credits").toBeGreaterThan( + credits2 + ); + }, + }); + + it({ + id: "E03", + title: "Collators are unassigned when a container chain does not have enough credits", + test: async function () { + // Create blocks until authorNoting.blockNum does not increase anymore. + // Check that collatorAssignment does not have collators and num credits is less than 2 sessions. + + const paraId = 2000n; + + // Create blocks until the block number stops increasing + let containerBlockNum3 = -1; + let containerBlockNum4 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + while (containerBlockNum3 != containerBlockNum4) { + await context.createBlock(); + containerBlockNum3 = containerBlockNum4; + containerBlockNum4 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + } + + // Now the container chain should have less than 2 sessions worth of credits + const credits = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + expect( + credits, + "Container chain 2000 has stopped producing blocks, so it should not have enough credits" + ).toBeLessThan(2n * blocksPerSession); + + const collators = await polkadotJs.query.collatorAssignment.collatorContainerChain(); + expect( + collators.toJSON().containerChains[paraId], + `Container chain ${paraId} should have 0 collators` + ).toBeUndefined(); + }, + }); + + it({ + id: "E04", + title: "Root can remove credits", + test: async function () { + // Remove all the credits of container chain 2001, which should have assigned collators now + // This checks that the node does not panic when we try to subtract credits from 0 (saturating_sub) + + const paraId = 2001n; + const credits = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + expect(credits, "Container chain 2001 does not have enough credits").toBeGreaterThanOrEqual( + 2n * blocksPerSession + ); + + // Should have assigned collators + const collators = await polkadotJs.query.collatorAssignment.collatorContainerChain(); + expect( + collators.toJSON().containerChains[paraId].length, + `Container chain ${paraId} has 0 collators` + ).toBeGreaterThan(0); + + // Create a block, the block number should increase, and the number of credits should decrease + const credits1 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + const containerBlockNum1 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + await context.createBlock(); + const credits2 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + const containerBlockNum2 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + expect(containerBlockNum1, "container chain 2001 did not create a block").toBeLessThan( + containerBlockNum2 + ); + expect(credits1, "container chain 2001 created a block without burning any credits").toBeGreaterThan( + credits2 + ); + + // Set credits to 0 + const tx = polkadotJs.tx.servicesPayment.setCredits(paraId, 0n); + await context.createBlock([await polkadotJs.tx.sudo.sudo(tx).signAsync(alice)]); + + const credits3 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON() || 0; + expect(credits3).toBe(0); + // Can still create blocks + const containerBlockNum3 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + await context.createBlock(); + const credits4 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON() || 0; + const containerBlockNum4 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + expect( + containerBlockNum3, + "container chain 2001 did not create a block after root set credits to 0" + ).toBeLessThan(containerBlockNum4); + // But credits cannot be lower than 0 + expect(credits4, "container chain 2001 has negative credits").toBe(0); + }, + }); + + it({ + id: "E05", + title: "Can buy additional credits", + test: async function () { + // As alice, buy credits for para 2000. Check that it is assigned collators again + const paraId = 2000n; + + // Create blocks until no collators are assigned to any container chain + for (;;) { + await context.createBlock(); + const collators = await polkadotJs.query.collatorAssignment.collatorContainerChain(); + if (Object.keys(collators.toJSON().containerChains).length == 0) { + break; + } + } + + // Use random account instead of alice because alice is getting block rewards + const randomAccount = generateKeyringPair("sr25519"); + const value = 100_000_000_000n; + await context.createBlock([ + await polkadotJs.tx.balances.transfer(randomAccount.address, value).signAsync(alice), + ]); + + // Now, buy some credits for container chain 2000 + const balanceBefore = ( + await polkadotJs.query.system.account(randomAccount.address) + ).data.free.toBigInt(); + const credits1 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + const purchasedCredits = 100n * blocksPerSession; + + const tx = polkadotJs.tx.servicesPayment.purchaseCredits(paraId, purchasedCredits, null); + await context.createBlock([await tx.signAsync(randomAccount)]); + + const balanceAfter = ( + await polkadotJs.query.system.account(randomAccount.address) + ).data.free.toBigInt(); + expect(balanceAfter).toBeLessThan(balanceBefore); + const credits2 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + expect(BigInt(credits2)).toBe(BigInt(credits1) + purchasedCredits); + + // Check that after 2 sessions, container chain 2000 has collators and is producing blocks + await jumpSessions(context, 2); + + const collators = await polkadotJs.query.collatorAssignment.collatorContainerChain(); + expect( + collators.toJSON().containerChains[paraId].length, + `Container chain ${paraId} has 0 collators` + ).toBeGreaterThan(0); + + // Create a block, the block number should increase, and the number of credits should decrease + const credits3 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + const containerBlockNum3 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + await context.createBlock(); + const credits4 = (await polkadotJs.query.servicesPayment.blockProductionCredits(paraId)).toJSON(); + const containerBlockNum4 = await (await polkadotJs.query.authorNoting.latestAuthor(paraId)).toJSON() + .blockNumber; + expect(containerBlockNum3, "container chain 2000 did not create a block").toBeLessThan( + containerBlockNum4 + ); + expect(credits3, "container chain 2000 created a block without burning any credits").toBeGreaterThan( + credits4 + ); + }, + }); + }, +}); diff --git a/test/suites/para/test_tanssi_containers.ts b/test/suites/para/test_tanssi_containers.ts index 86508659f..1ed0172b1 100644 --- a/test/suites/para/test_tanssi_containers.ts +++ b/test/suites/para/test_tanssi_containers.ts @@ -238,15 +238,17 @@ describeSuite({ const chainSpec2002 = JSON.parse(spec2002); const containerChainGenesisData = chainSpecToContainerChainGenesisData(paraApi, chainSpec2002); - const tx = paraApi.tx.registrar.register(2002, containerChainGenesisData); - await signAndSendAndInclude(tx, alice); + const tx1 = paraApi.tx.registrar.register(2002, containerChainGenesisData); + const tx2 = paraApi.tx.servicesPayment.purchaseCredits(2002, 100000, null); + const tx12 = paraApi.tx.utility.batchAll([tx1, tx2]); + await signAndSendAndInclude(tx12, alice); const bootNodes = [ "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", ]; - const tx2 = paraApi.tx.registrar.setBootNodes(2002, bootNodes); - const tx3 = paraApi.tx.registrar.markValidForCollating(2002); - const tx2tx3 = paraApi.tx.utility.batchAll([tx2, tx3]); - await signAndSendAndInclude(paraApi.tx.sudo.sudo(tx2tx3), alice); + const tx3 = paraApi.tx.registrar.setBootNodes(2002, bootNodes); + const tx4 = paraApi.tx.registrar.markValidForCollating(2002); + const tx34 = paraApi.tx.utility.batchAll([tx3, tx4]); + await signAndSendAndInclude(paraApi.tx.sudo.sudo(tx34), alice); // Check that pending para ids contains 2002 const registered2 = await paraApi.query.registrar.pendingParaIds(); const registered3 = await paraApi.query.registrar.registeredParaIds(); diff --git a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts index a6ef33b43..fd651329d 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts @@ -228,6 +228,13 @@ declare module "@polkadot/api-base/types/errors" { /** Generic error */ [key: string]: AugmentedError; }; + servicesPayment: { + CreditPriceTooExpensive: AugmentedError; + InsufficientCredits: AugmentedError; + InsufficientFundsToPurchaseCredits: AugmentedError; + /** Generic error */ + [key: string]: AugmentedError; + }; session: { /** Registered duplicate key. */ DuplicatedKey: AugmentedError; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-events.ts b/typescript-api/src/dancebox/interfaces/augment-api-events.ts index 94ea7110d..df95bb034 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-events.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-events.ts @@ -719,6 +719,21 @@ declare module "@polkadot/api-base/types/events" { /** Generic event */ [key: string]: AugmentedEvent; }; + servicesPayment: { + CreditBurned: AugmentedEvent< + ApiType, + [paraId: u32, creditsRemaining: u32], + { paraId: u32; creditsRemaining: u32 } + >; + CreditsPurchased: AugmentedEvent< + ApiType, + [paraId: u32, payer: AccountId32, fee: u128, creditsPurchased: u32, creditsRemaining: u32], + { paraId: u32; payer: AccountId32; fee: u128; creditsPurchased: u32; creditsRemaining: u32 } + >; + CreditsSet: AugmentedEvent; + /** Generic event */ + [key: string]: AugmentedEvent; + }; session: { /** New session has happened. Note that the argument is the session index, not the block number as the type might suggest. */ NewSession: AugmentedEvent; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-query.ts b/typescript-api/src/dancebox/interfaces/augment-api-query.ts index 01ed0de14..0c15a1cbf 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-query.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-query.ts @@ -720,6 +720,16 @@ declare module "@polkadot/api-base/types/storage" { /** Generic query */ [key: string]: QueryableStorageEntry; }; + servicesPayment: { + blockProductionCredits: AugmentedQuery< + ApiType, + (arg: u32 | AnyNumber | Uint8Array) => Observable>, + [u32] + > & + QueryableStorageEntry; + /** Generic query */ + [key: string]: QueryableStorageEntry; + }; session: { /** Current index of the session. */ currentIndex: AugmentedQuery Observable, []> & QueryableStorageEntry; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts index 33b4de79a..efb90cbae 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts @@ -805,6 +805,27 @@ declare module "@polkadot/api-base/types/submittable" { /** Generic tx */ [key: string]: SubmittableExtrinsicFunction; }; + servicesPayment: { + /** See [`Pallet::purchase_credits`]. */ + purchaseCredits: AugmentedSubmittable< + ( + paraId: u32 | AnyNumber | Uint8Array, + credits: u32 | AnyNumber | Uint8Array, + maxPricePerCredit: Option | null | Uint8Array | u128 | AnyNumber + ) => SubmittableExtrinsic, + [u32, u32, Option] + >; + /** See [`Pallet::set_credits`]. */ + setCredits: AugmentedSubmittable< + ( + paraId: u32 | AnyNumber | Uint8Array, + credits: u32 | AnyNumber | Uint8Array + ) => SubmittableExtrinsic, + [u32, u32] + >; + /** Generic tx */ + [key: string]: SubmittableExtrinsicFunction; + }; session: { /** See [`Pallet::purge_keys`]. */ purgeKeys: AugmentedSubmittable<() => SubmittableExtrinsic, []>; diff --git a/typescript-api/src/dancebox/interfaces/lookup.ts b/typescript-api/src/dancebox/interfaces/lookup.ts index e80dd63ee..69a58bdc7 100644 --- a/typescript-api/src/dancebox/interfaces/lookup.ts +++ b/typescript-api/src/dancebox/interfaces/lookup.ts @@ -412,7 +412,27 @@ export default { }, }, }, - /** Lookup50: pallet_invulnerables::pallet::Event */ + /** Lookup50: pallet_services_payment::pallet::Event */ + PalletServicesPaymentEvent: { + _enum: { + CreditsPurchased: { + paraId: "u32", + payer: "AccountId32", + fee: "u128", + creditsPurchased: "u32", + creditsRemaining: "u32", + }, + CreditBurned: { + paraId: "u32", + creditsRemaining: "u32", + }, + CreditsSet: { + paraId: "u32", + credits: "u32", + }, + }, + }, + /** Lookup51: pallet_invulnerables::pallet::Event */ PalletInvulnerablesEvent: { _enum: { NewInvulnerables: { @@ -429,7 +449,7 @@ export default { }, }, }, - /** Lookup52: pallet_session::pallet::Event */ + /** Lookup53: pallet_session::pallet::Event */ PalletSessionEvent: { _enum: { NewSession: { @@ -437,7 +457,7 @@ export default { }, }, }, - /** Lookup53: pallet_pooled_staking::pallet::Event */ + /** Lookup54: pallet_pooled_staking::pallet::Event */ PalletPooledStakingEvent: { _enum: { UpdatedCandidatePosition: { @@ -532,11 +552,11 @@ export default { }, }, }, - /** Lookup55: pallet_pooled_staking::pallet::TargetPool */ + /** Lookup56: pallet_pooled_staking::pallet::TargetPool */ PalletPooledStakingTargetPool: { _enum: ["AutoCompounding", "ManualRewards"], }, - /** Lookup56: pallet_inflation_rewards::pallet::Event */ + /** Lookup57: pallet_inflation_rewards::pallet::Event */ PalletInflationRewardsEvent: { _enum: { RewardedOrchestrator: { @@ -550,7 +570,7 @@ export default { }, }, }, - /** Lookup57: cumulus_pallet_xcmp_queue::pallet::Event */ + /** Lookup58: cumulus_pallet_xcmp_queue::pallet::Event */ CumulusPalletXcmpQueueEvent: { _enum: { Success: { @@ -585,7 +605,7 @@ export default { }, }, }, - /** Lookup58: staging_xcm::v3::traits::Error */ + /** Lookup59: staging_xcm::v3::traits::Error */ StagingXcmV3TraitsError: { _enum: { Overflow: "Null", @@ -630,7 +650,7 @@ export default { ExceedsStackLimit: "Null", }, }, - /** Lookup59: cumulus_pallet_xcm::pallet::Event */ + /** Lookup60: cumulus_pallet_xcm::pallet::Event */ CumulusPalletXcmEvent: { _enum: { InvalidFormat: "[u8;32]", @@ -638,7 +658,7 @@ export default { ExecutedDownward: "([u8;32],StagingXcmV3TraitsOutcome)", }, }, - /** Lookup60: staging_xcm::v3::traits::Outcome */ + /** Lookup61: staging_xcm::v3::traits::Outcome */ StagingXcmV3TraitsOutcome: { _enum: { Complete: "SpWeightsWeightV2Weight", @@ -646,7 +666,7 @@ export default { Error: "StagingXcmV3TraitsError", }, }, - /** Lookup61: cumulus_pallet_dmp_queue::pallet::Event */ + /** Lookup62: cumulus_pallet_dmp_queue::pallet::Event */ CumulusPalletDmpQueueEvent: { _enum: { InvalidFormat: { @@ -681,7 +701,7 @@ export default { }, }, }, - /** Lookup62: pallet_xcm::pallet::Event */ + /** Lookup63: pallet_xcm::pallet::Event */ PalletXcmEvent: { _enum: { Attempted: { @@ -801,12 +821,12 @@ export default { }, }, }, - /** Lookup63: staging_xcm::v3::multilocation::MultiLocation */ + /** Lookup64: staging_xcm::v3::multilocation::MultiLocation */ StagingXcmV3MultiLocation: { parents: "u8", interior: "StagingXcmV3Junctions", }, - /** Lookup64: staging_xcm::v3::junctions::Junctions */ + /** Lookup65: staging_xcm::v3::junctions::Junctions */ StagingXcmV3Junctions: { _enum: { Here: "Null", @@ -820,7 +840,7 @@ export default { X8: "(StagingXcmV3Junction,StagingXcmV3Junction,StagingXcmV3Junction,StagingXcmV3Junction,StagingXcmV3Junction,StagingXcmV3Junction,StagingXcmV3Junction,StagingXcmV3Junction)", }, }, - /** Lookup65: staging_xcm::v3::junction::Junction */ + /** Lookup66: staging_xcm::v3::junction::Junction */ StagingXcmV3Junction: { _enum: { Parachain: "Compact", @@ -850,7 +870,7 @@ export default { GlobalConsensus: "StagingXcmV3JunctionNetworkId", }, }, - /** Lookup68: staging_xcm::v3::junction::NetworkId */ + /** Lookup69: staging_xcm::v3::junction::NetworkId */ StagingXcmV3JunctionNetworkId: { _enum: { ByGenesis: "[u8;32]", @@ -870,7 +890,7 @@ export default { BitcoinCash: "Null", }, }, - /** Lookup71: staging_xcm::v3::junction::BodyId */ + /** Lookup72: staging_xcm::v3::junction::BodyId */ StagingXcmV3JunctionBodyId: { _enum: { Unit: "Null", @@ -885,7 +905,7 @@ export default { Treasury: "Null", }, }, - /** Lookup72: staging_xcm::v3::junction::BodyPart */ + /** Lookup73: staging_xcm::v3::junction::BodyPart */ StagingXcmV3JunctionBodyPart: { _enum: { Voice: "Null", @@ -906,9 +926,9 @@ export default { }, }, }, - /** Lookup73: staging_xcm::v3::Xcm */ + /** Lookup74: staging_xcm::v3::Xcm */ StagingXcmV3Xcm: "Vec", - /** Lookup75: staging_xcm::v3::Instruction */ + /** Lookup76: staging_xcm::v3::Instruction */ StagingXcmV3Instruction: { _enum: { WithdrawAsset: "StagingXcmV3MultiassetMultiAssets", @@ -1048,28 +1068,28 @@ export default { }, }, }, - /** Lookup76: staging_xcm::v3::multiasset::MultiAssets */ + /** Lookup77: staging_xcm::v3::multiasset::MultiAssets */ StagingXcmV3MultiassetMultiAssets: "Vec", - /** Lookup78: staging_xcm::v3::multiasset::MultiAsset */ + /** Lookup79: staging_xcm::v3::multiasset::MultiAsset */ StagingXcmV3MultiAsset: { id: "StagingXcmV3MultiassetAssetId", fun: "StagingXcmV3MultiassetFungibility", }, - /** Lookup79: staging_xcm::v3::multiasset::AssetId */ + /** Lookup80: staging_xcm::v3::multiasset::AssetId */ StagingXcmV3MultiassetAssetId: { _enum: { Concrete: "StagingXcmV3MultiLocation", Abstract: "[u8;32]", }, }, - /** Lookup80: staging_xcm::v3::multiasset::Fungibility */ + /** Lookup81: staging_xcm::v3::multiasset::Fungibility */ StagingXcmV3MultiassetFungibility: { _enum: { Fungible: "Compact", NonFungible: "StagingXcmV3MultiassetAssetInstance", }, }, - /** Lookup81: staging_xcm::v3::multiasset::AssetInstance */ + /** Lookup82: staging_xcm::v3::multiasset::AssetInstance */ StagingXcmV3MultiassetAssetInstance: { _enum: { Undefined: "Null", @@ -1080,7 +1100,7 @@ export default { Array32: "[u8;32]", }, }, - /** Lookup84: staging_xcm::v3::Response */ + /** Lookup85: staging_xcm::v3::Response */ StagingXcmV3Response: { _enum: { Null: "Null", @@ -1091,7 +1111,7 @@ export default { DispatchResult: "StagingXcmV3MaybeErrorCode", }, }, - /** Lookup88: staging_xcm::v3::PalletInfo */ + /** Lookup89: staging_xcm::v3::PalletInfo */ StagingXcmV3PalletInfo: { index: "Compact", name: "Bytes", @@ -1100,7 +1120,7 @@ export default { minor: "Compact", patch: "Compact", }, - /** Lookup91: staging_xcm::v3::MaybeErrorCode */ + /** Lookup92: staging_xcm::v3::MaybeErrorCode */ StagingXcmV3MaybeErrorCode: { _enum: { Success: "Null", @@ -1108,28 +1128,28 @@ export default { TruncatedError: "Bytes", }, }, - /** Lookup94: staging_xcm::v2::OriginKind */ + /** Lookup95: staging_xcm::v2::OriginKind */ StagingXcmV2OriginKind: { _enum: ["Native", "SovereignAccount", "Superuser", "Xcm"], }, - /** Lookup95: staging_xcm::double_encoded::DoubleEncoded */ + /** Lookup96: staging_xcm::double_encoded::DoubleEncoded */ StagingXcmDoubleEncoded: { encoded: "Bytes", }, - /** Lookup96: staging_xcm::v3::QueryResponseInfo */ + /** Lookup97: staging_xcm::v3::QueryResponseInfo */ StagingXcmV3QueryResponseInfo: { destination: "StagingXcmV3MultiLocation", queryId: "Compact", maxWeight: "SpWeightsWeightV2Weight", }, - /** Lookup97: staging_xcm::v3::multiasset::MultiAssetFilter */ + /** Lookup98: staging_xcm::v3::multiasset::MultiAssetFilter */ StagingXcmV3MultiassetMultiAssetFilter: { _enum: { Definite: "StagingXcmV3MultiassetMultiAssets", Wild: "StagingXcmV3MultiassetWildMultiAsset", }, }, - /** Lookup98: staging_xcm::v3::multiasset::WildMultiAsset */ + /** Lookup99: staging_xcm::v3::multiasset::WildMultiAsset */ StagingXcmV3MultiassetWildMultiAsset: { _enum: { All: "Null", @@ -1145,18 +1165,18 @@ export default { }, }, }, - /** Lookup99: staging_xcm::v3::multiasset::WildFungibility */ + /** Lookup100: staging_xcm::v3::multiasset::WildFungibility */ StagingXcmV3MultiassetWildFungibility: { _enum: ["Fungible", "NonFungible"], }, - /** Lookup100: staging_xcm::v3::WeightLimit */ + /** Lookup101: staging_xcm::v3::WeightLimit */ StagingXcmV3WeightLimit: { _enum: { Unlimited: "Null", Limited: "SpWeightsWeightV2Weight", }, }, - /** Lookup101: staging_xcm::VersionedMultiAssets */ + /** Lookup102: staging_xcm::VersionedMultiAssets */ StagingXcmVersionedMultiAssets: { _enum: { __Unused0: "Null", @@ -1165,26 +1185,26 @@ export default { V3: "StagingXcmV3MultiassetMultiAssets", }, }, - /** Lookup102: staging_xcm::v2::multiasset::MultiAssets */ + /** Lookup103: staging_xcm::v2::multiasset::MultiAssets */ StagingXcmV2MultiassetMultiAssets: "Vec", - /** Lookup104: staging_xcm::v2::multiasset::MultiAsset */ + /** Lookup105: staging_xcm::v2::multiasset::MultiAsset */ StagingXcmV2MultiAsset: { id: "StagingXcmV2MultiassetAssetId", fun: "StagingXcmV2MultiassetFungibility", }, - /** Lookup105: staging_xcm::v2::multiasset::AssetId */ + /** Lookup106: staging_xcm::v2::multiasset::AssetId */ StagingXcmV2MultiassetAssetId: { _enum: { Concrete: "StagingXcmV2MultiLocation", Abstract: "Bytes", }, }, - /** Lookup106: staging_xcm::v2::multilocation::MultiLocation */ + /** Lookup107: staging_xcm::v2::multilocation::MultiLocation */ StagingXcmV2MultiLocation: { parents: "u8", interior: "StagingXcmV2MultilocationJunctions", }, - /** Lookup107: staging_xcm::v2::multilocation::Junctions */ + /** Lookup108: staging_xcm::v2::multilocation::Junctions */ StagingXcmV2MultilocationJunctions: { _enum: { Here: "Null", @@ -1198,7 +1218,7 @@ export default { X8: "(StagingXcmV2Junction,StagingXcmV2Junction,StagingXcmV2Junction,StagingXcmV2Junction,StagingXcmV2Junction,StagingXcmV2Junction,StagingXcmV2Junction,StagingXcmV2Junction)", }, }, - /** Lookup108: staging_xcm::v2::junction::Junction */ + /** Lookup109: staging_xcm::v2::junction::Junction */ StagingXcmV2Junction: { _enum: { Parachain: "Compact", @@ -1224,7 +1244,7 @@ export default { }, }, }, - /** Lookup109: staging_xcm::v2::NetworkId */ + /** Lookup110: staging_xcm::v2::NetworkId */ StagingXcmV2NetworkId: { _enum: { Any: "Null", @@ -1233,7 +1253,7 @@ export default { Kusama: "Null", }, }, - /** Lookup111: staging_xcm::v2::BodyId */ + /** Lookup112: staging_xcm::v2::BodyId */ StagingXcmV2BodyId: { _enum: { Unit: "Null", @@ -1248,7 +1268,7 @@ export default { Treasury: "Null", }, }, - /** Lookup112: staging_xcm::v2::BodyPart */ + /** Lookup113: staging_xcm::v2::BodyPart */ StagingXcmV2BodyPart: { _enum: { Voice: "Null", @@ -1269,14 +1289,14 @@ export default { }, }, }, - /** Lookup113: staging_xcm::v2::multiasset::Fungibility */ + /** Lookup114: staging_xcm::v2::multiasset::Fungibility */ StagingXcmV2MultiassetFungibility: { _enum: { Fungible: "Compact", NonFungible: "StagingXcmV2MultiassetAssetInstance", }, }, - /** Lookup114: staging_xcm::v2::multiasset::AssetInstance */ + /** Lookup115: staging_xcm::v2::multiasset::AssetInstance */ StagingXcmV2MultiassetAssetInstance: { _enum: { Undefined: "Null", @@ -1288,7 +1308,7 @@ export default { Blob: "Bytes", }, }, - /** Lookup115: staging_xcm::VersionedMultiLocation */ + /** Lookup116: staging_xcm::VersionedMultiLocation */ StagingXcmVersionedMultiLocation: { _enum: { __Unused0: "Null", @@ -1297,7 +1317,7 @@ export default { V3: "StagingXcmV3MultiLocation", }, }, - /** Lookup116: frame_system::Phase */ + /** Lookup117: frame_system::Phase */ FrameSystemPhase: { _enum: { ApplyExtrinsic: "u32", @@ -1305,12 +1325,12 @@ export default { Initialization: "Null", }, }, - /** Lookup120: frame_system::LastRuntimeUpgradeInfo */ + /** Lookup121: frame_system::LastRuntimeUpgradeInfo */ FrameSystemLastRuntimeUpgradeInfo: { specVersion: "Compact", specName: "Text", }, - /** Lookup122: frame_system::pallet::Call */ + /** Lookup123: frame_system::pallet::Call */ FrameSystemCall: { _enum: { remark: { @@ -1343,41 +1363,41 @@ export default { }, }, }, - /** Lookup126: frame_system::limits::BlockWeights */ + /** Lookup127: frame_system::limits::BlockWeights */ FrameSystemLimitsBlockWeights: { baseBlock: "SpWeightsWeightV2Weight", maxBlock: "SpWeightsWeightV2Weight", perClass: "FrameSupportDispatchPerDispatchClassWeightsPerClass", }, - /** Lookup127: frame_support::dispatch::PerDispatchClass */ + /** Lookup128: frame_support::dispatch::PerDispatchClass */ FrameSupportDispatchPerDispatchClassWeightsPerClass: { normal: "FrameSystemLimitsWeightsPerClass", operational: "FrameSystemLimitsWeightsPerClass", mandatory: "FrameSystemLimitsWeightsPerClass", }, - /** Lookup128: frame_system::limits::WeightsPerClass */ + /** Lookup129: frame_system::limits::WeightsPerClass */ FrameSystemLimitsWeightsPerClass: { baseExtrinsic: "SpWeightsWeightV2Weight", maxExtrinsic: "Option", maxTotal: "Option", reserved: "Option", }, - /** Lookup130: frame_system::limits::BlockLength */ + /** Lookup131: frame_system::limits::BlockLength */ FrameSystemLimitsBlockLength: { max: "FrameSupportDispatchPerDispatchClassU32", }, - /** Lookup131: frame_support::dispatch::PerDispatchClass */ + /** Lookup132: frame_support::dispatch::PerDispatchClass */ FrameSupportDispatchPerDispatchClassU32: { normal: "u32", operational: "u32", mandatory: "u32", }, - /** Lookup132: sp_weights::RuntimeDbWeight */ + /** Lookup133: sp_weights::RuntimeDbWeight */ SpWeightsRuntimeDbWeight: { read: "u64", write: "u64", }, - /** Lookup133: sp_version::RuntimeVersion */ + /** Lookup134: sp_version::RuntimeVersion */ SpVersionRuntimeVersion: { specName: "Text", implName: "Text", @@ -1388,7 +1408,7 @@ export default { transactionVersion: "u32", stateVersion: "u8", }, - /** Lookup137: frame_system::pallet::Error */ + /** Lookup138: frame_system::pallet::Error */ FrameSystemError: { _enum: [ "InvalidSpecName", @@ -1399,49 +1419,49 @@ export default { "CallFiltered", ], }, - /** Lookup139: cumulus_pallet_parachain_system::unincluded_segment::Ancestor */ + /** Lookup140: cumulus_pallet_parachain_system::unincluded_segment::Ancestor */ CumulusPalletParachainSystemUnincludedSegmentAncestor: { usedBandwidth: "CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth", paraHeadHash: "Option", consumedGoAheadSignal: "Option", }, - /** Lookup140: cumulus_pallet_parachain_system::unincluded_segment::UsedBandwidth */ + /** Lookup141: cumulus_pallet_parachain_system::unincluded_segment::UsedBandwidth */ CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth: { umpMsgCount: "u32", umpTotalBytes: "u32", hrmpOutgoing: "BTreeMap", }, - /** Lookup142: cumulus_pallet_parachain_system::unincluded_segment::HrmpChannelUpdate */ + /** Lookup143: cumulus_pallet_parachain_system::unincluded_segment::HrmpChannelUpdate */ CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate: { msgCount: "u32", totalBytes: "u32", }, - /** Lookup147: polkadot_primitives::v5::UpgradeGoAhead */ + /** Lookup148: polkadot_primitives::v5::UpgradeGoAhead */ PolkadotPrimitivesV5UpgradeGoAhead: { _enum: ["Abort", "GoAhead"], }, - /** Lookup148: cumulus_pallet_parachain_system::unincluded_segment::SegmentTracker */ + /** Lookup149: cumulus_pallet_parachain_system::unincluded_segment::SegmentTracker */ CumulusPalletParachainSystemUnincludedSegmentSegmentTracker: { usedBandwidth: "CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth", hrmpWatermark: "Option", consumedGoAheadSignal: "Option", }, - /** Lookup149: polkadot_primitives::v5::PersistedValidationData */ + /** Lookup150: polkadot_primitives::v5::PersistedValidationData */ PolkadotPrimitivesV5PersistedValidationData: { parentHead: "Bytes", relayParentNumber: "u32", relayParentStorageRoot: "H256", maxPovSize: "u32", }, - /** Lookup152: polkadot_primitives::v5::UpgradeRestriction */ + /** Lookup153: polkadot_primitives::v5::UpgradeRestriction */ PolkadotPrimitivesV5UpgradeRestriction: { _enum: ["Present"], }, - /** Lookup153: sp_trie::storage_proof::StorageProof */ + /** Lookup154: sp_trie::storage_proof::StorageProof */ SpTrieStorageProof: { trieNodes: "BTreeSet", }, - /** Lookup155: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot */ + /** Lookup156: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot */ CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot: { dmqMqcHead: "H256", relayDispatchQueueRemainingCapacity: @@ -1449,12 +1469,12 @@ export default { ingressChannels: "Vec<(u32,PolkadotPrimitivesV5AbridgedHrmpChannel)>", egressChannels: "Vec<(u32,PolkadotPrimitivesV5AbridgedHrmpChannel)>", }, - /** Lookup156: cumulus_pallet_parachain_system::relay_state_snapshot::RelayDispatchQueueRemainingCapacity */ + /** Lookup157: cumulus_pallet_parachain_system::relay_state_snapshot::RelayDispatchQueueRemainingCapacity */ CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity: { remainingCount: "u32", remainingSize: "u32", }, - /** Lookup159: polkadot_primitives::v5::AbridgedHrmpChannel */ + /** Lookup160: polkadot_primitives::v5::AbridgedHrmpChannel */ PolkadotPrimitivesV5AbridgedHrmpChannel: { maxCapacity: "u32", maxTotalSize: "u32", @@ -1463,7 +1483,7 @@ export default { totalSize: "u32", mqcHead: "Option", }, - /** Lookup160: polkadot_primitives::v5::AbridgedHostConfiguration */ + /** Lookup161: polkadot_primitives::v5::AbridgedHostConfiguration */ PolkadotPrimitivesV5AbridgedHostConfiguration: { maxCodeSize: "u32", maxHeadDataSize: "u32", @@ -1476,22 +1496,22 @@ export default { validationUpgradeDelay: "u32", asyncBackingParams: "PolkadotPrimitivesVstagingAsyncBackingParams", }, - /** Lookup161: polkadot_primitives::vstaging::AsyncBackingParams */ + /** Lookup162: polkadot_primitives::vstaging::AsyncBackingParams */ PolkadotPrimitivesVstagingAsyncBackingParams: { maxCandidateDepth: "u32", allowedAncestryLen: "u32", }, - /** Lookup167: polkadot_core_primitives::OutboundHrmpMessage */ + /** Lookup168: polkadot_core_primitives::OutboundHrmpMessage */ PolkadotCorePrimitivesOutboundHrmpMessage: { recipient: "u32", data: "Bytes", }, - /** Lookup168: cumulus_pallet_parachain_system::CodeUpgradeAuthorization */ + /** Lookup169: cumulus_pallet_parachain_system::CodeUpgradeAuthorization */ CumulusPalletParachainSystemCodeUpgradeAuthorization: { codeHash: "H256", checkVersion: "bool", }, - /** Lookup169: cumulus_pallet_parachain_system::pallet::Call */ + /** Lookup170: cumulus_pallet_parachain_system::pallet::Call */ CumulusPalletParachainSystemCall: { _enum: { set_validation_data: { @@ -1509,24 +1529,24 @@ export default { }, }, }, - /** Lookup170: cumulus_primitives_parachain_inherent::ParachainInherentData */ + /** Lookup171: cumulus_primitives_parachain_inherent::ParachainInherentData */ CumulusPrimitivesParachainInherentParachainInherentData: { validationData: "PolkadotPrimitivesV5PersistedValidationData", relayChainState: "SpTrieStorageProof", downwardMessages: "Vec", horizontalMessages: "BTreeMap>", }, - /** Lookup172: polkadot_core_primitives::InboundDownwardMessage */ + /** Lookup173: polkadot_core_primitives::InboundDownwardMessage */ PolkadotCorePrimitivesInboundDownwardMessage: { sentAt: "u32", msg: "Bytes", }, - /** Lookup175: polkadot_core_primitives::InboundHrmpMessage */ + /** Lookup176: polkadot_core_primitives::InboundHrmpMessage */ PolkadotCorePrimitivesInboundHrmpMessage: { sentAt: "u32", data: "Bytes", }, - /** Lookup178: cumulus_pallet_parachain_system::pallet::Error */ + /** Lookup179: cumulus_pallet_parachain_system::pallet::Error */ CumulusPalletParachainSystemError: { _enum: [ "OverlappingUpgrades", @@ -1539,7 +1559,7 @@ export default { "Unauthorized", ], }, - /** Lookup179: pallet_timestamp::pallet::Call */ + /** Lookup180: pallet_timestamp::pallet::Call */ PalletTimestampCall: { _enum: { set: { @@ -1547,9 +1567,9 @@ export default { }, }, }, - /** Lookup180: parachain_info::pallet::Call */ + /** Lookup181: parachain_info::pallet::Call */ ParachainInfoCall: "Null", - /** Lookup181: pallet_sudo::pallet::Call */ + /** Lookup182: pallet_sudo::pallet::Call */ PalletSudoCall: { _enum: { sudo: { @@ -1571,7 +1591,7 @@ export default { }, }, }, - /** Lookup183: pallet_utility::pallet::Call */ + /** Lookup184: pallet_utility::pallet::Call */ PalletUtilityCall: { _enum: { batch: { @@ -1597,7 +1617,7 @@ export default { }, }, }, - /** Lookup185: dancebox_runtime::OriginCaller */ + /** Lookup186: dancebox_runtime::OriginCaller */ DanceboxRuntimeOriginCaller: { _enum: { system: "FrameSupportDispatchRawOrigin", @@ -1656,7 +1676,7 @@ export default { PolkadotXcm: "PalletXcmOrigin", }, }, - /** Lookup186: frame_support::dispatch::RawOrigin */ + /** Lookup187: frame_support::dispatch::RawOrigin */ FrameSupportDispatchRawOrigin: { _enum: { Root: "Null", @@ -1664,23 +1684,23 @@ export default { None: "Null", }, }, - /** Lookup187: cumulus_pallet_xcm::pallet::Origin */ + /** Lookup188: cumulus_pallet_xcm::pallet::Origin */ CumulusPalletXcmOrigin: { _enum: { Relay: "Null", SiblingParachain: "u32", }, }, - /** Lookup188: pallet_xcm::pallet::Origin */ + /** Lookup189: pallet_xcm::pallet::Origin */ PalletXcmOrigin: { _enum: { Xcm: "StagingXcmV3MultiLocation", Response: "StagingXcmV3MultiLocation", }, }, - /** Lookup189: sp_core::Void */ + /** Lookup190: sp_core::Void */ SpCoreVoid: "Null", - /** Lookup190: pallet_proxy::pallet::Call */ + /** Lookup191: pallet_proxy::pallet::Call */ PalletProxyCall: { _enum: { proxy: { @@ -1731,11 +1751,11 @@ export default { }, }, }, - /** Lookup194: pallet_maintenance_mode::pallet::Call */ + /** Lookup195: pallet_maintenance_mode::pallet::Call */ PalletMaintenanceModeCall: { _enum: ["enter_maintenance_mode", "resume_normal_operation"], }, - /** Lookup195: pallet_balances::pallet::Call */ + /** Lookup196: pallet_balances::pallet::Call */ PalletBalancesCall: { _enum: { transfer_allow_death: { @@ -1777,7 +1797,7 @@ export default { }, }, }, - /** Lookup196: pallet_registrar::pallet::Call */ + /** Lookup197: pallet_registrar::pallet::Call */ PalletRegistrarCall: { _enum: { register: { @@ -1799,7 +1819,7 @@ export default { }, }, }, - /** Lookup197: tp_container_chain_genesis_data::ContainerChainGenesisData */ + /** Lookup198: tp_container_chain_genesis_data::ContainerChainGenesisData */ TpContainerChainGenesisDataContainerChainGenesisData: { storage: "Vec", name: "Bytes", @@ -1808,23 +1828,23 @@ export default { extensions: "Bytes", properties: "TpContainerChainGenesisDataProperties", }, - /** Lookup199: tp_container_chain_genesis_data::ContainerChainGenesisDataItem */ + /** Lookup200: tp_container_chain_genesis_data::ContainerChainGenesisDataItem */ TpContainerChainGenesisDataContainerChainGenesisDataItem: { key: "Bytes", value: "Bytes", }, - /** Lookup201: tp_container_chain_genesis_data::Properties */ + /** Lookup202: tp_container_chain_genesis_data::Properties */ TpContainerChainGenesisDataProperties: { tokenMetadata: "TpContainerChainGenesisDataTokenMetadata", isEthereum: "bool", }, - /** Lookup202: tp_container_chain_genesis_data::TokenMetadata */ + /** Lookup203: tp_container_chain_genesis_data::TokenMetadata */ TpContainerChainGenesisDataTokenMetadata: { tokenSymbol: "Bytes", ss58Format: "u32", tokenDecimals: "u32", }, - /** Lookup207: pallet_configuration::pallet::Call */ + /** Lookup208: pallet_configuration::pallet::Call */ PalletConfigurationCall: { _enum: { set_max_collators: { @@ -1904,9 +1924,9 @@ export default { }, }, }, - /** Lookup208: pallet_collator_assignment::pallet::Call */ + /** Lookup209: pallet_collator_assignment::pallet::Call */ PalletCollatorAssignmentCall: "Null", - /** Lookup209: pallet_author_noting::pallet::Call */ + /** Lookup210: pallet_author_noting::pallet::Call */ PalletAuthorNotingCall: { _enum: { set_latest_author_data: { @@ -1922,13 +1942,27 @@ export default { }, }, }, - /** Lookup210: tp_author_noting_inherent::OwnParachainInherentData */ + /** Lookup211: tp_author_noting_inherent::OwnParachainInherentData */ TpAuthorNotingInherentOwnParachainInherentData: { relayStorageProof: "SpTrieStorageProof", }, - /** Lookup211: pallet_authority_assignment::pallet::Call */ + /** Lookup212: pallet_authority_assignment::pallet::Call */ PalletAuthorityAssignmentCall: "Null", - /** Lookup212: pallet_invulnerables::pallet::Call */ + /** Lookup213: pallet_services_payment::pallet::Call */ + PalletServicesPaymentCall: { + _enum: { + purchase_credits: { + paraId: "u32", + credits: "u32", + maxPricePerCredit: "Option", + }, + set_credits: { + paraId: "u32", + credits: "u32", + }, + }, + }, + /** Lookup215: pallet_invulnerables::pallet::Call */ PalletInvulnerablesCall: { _enum: { set_invulnerables: { @@ -1945,7 +1979,7 @@ export default { }, }, }, - /** Lookup213: pallet_session::pallet::Call */ + /** Lookup216: pallet_session::pallet::Call */ PalletSessionCall: { _enum: { set_keys: { @@ -1958,19 +1992,19 @@ export default { purge_keys: "Null", }, }, - /** Lookup214: dancebox_runtime::SessionKeys */ + /** Lookup217: dancebox_runtime::SessionKeys */ DanceboxRuntimeSessionKeys: { nimbus: "NimbusPrimitivesNimbusCryptoPublic", }, - /** Lookup215: nimbus_primitives::nimbus_crypto::Public */ + /** Lookup218: nimbus_primitives::nimbus_crypto::Public */ NimbusPrimitivesNimbusCryptoPublic: "SpCoreSr25519Public", - /** Lookup216: sp_core::sr25519::Public */ + /** Lookup219: sp_core::sr25519::Public */ SpCoreSr25519Public: "[u8;32]", - /** Lookup217: pallet_author_inherent::pallet::Call */ + /** Lookup220: pallet_author_inherent::pallet::Call */ PalletAuthorInherentCall: { _enum: ["kick_off_authorship_validation"], }, - /** Lookup218: pallet_pooled_staking::pallet::Call */ + /** Lookup221: pallet_pooled_staking::pallet::Call */ PalletPooledStakingCall: { _enum: { rebalance_hold: { @@ -2004,16 +2038,16 @@ export default { }, }, }, - /** Lookup219: pallet_pooled_staking::pallet::AllTargetPool */ + /** Lookup222: pallet_pooled_staking::pallet::AllTargetPool */ PalletPooledStakingAllTargetPool: { _enum: ["Joining", "AutoCompounding", "ManualRewards", "Leaving"], }, - /** Lookup221: pallet_pooled_staking::pallet::PendingOperationQuery */ + /** Lookup224: pallet_pooled_staking::pallet::PendingOperationQuery */ PalletPooledStakingPendingOperationQuery: { delegator: "AccountId32", operation: "PalletPooledStakingPendingOperationKey", }, - /** Lookup222: pallet_pooled_staking::pallet::PendingOperationKey */ + /** Lookup225: pallet_pooled_staking::pallet::PendingOperationKey */ PalletPooledStakingPendingOperationKey: { _enum: { JoiningAutoCompounding: { @@ -2030,14 +2064,14 @@ export default { }, }, }, - /** Lookup223: pallet_pooled_staking::pallet::SharesOrStake */ + /** Lookup226: pallet_pooled_staking::pallet::SharesOrStake */ PalletPooledStakingSharesOrStake: { _enum: { Shares: "u128", Stake: "u128", }, }, - /** Lookup226: cumulus_pallet_xcmp_queue::pallet::Call */ + /** Lookup229: cumulus_pallet_xcmp_queue::pallet::Call */ CumulusPalletXcmpQueueCall: { _enum: { service_overweight: { @@ -2084,7 +2118,7 @@ export default { }, }, }, - /** Lookup227: cumulus_pallet_dmp_queue::pallet::Call */ + /** Lookup230: cumulus_pallet_dmp_queue::pallet::Call */ CumulusPalletDmpQueueCall: { _enum: { service_overweight: { @@ -2093,7 +2127,7 @@ export default { }, }, }, - /** Lookup228: pallet_xcm::pallet::Call */ + /** Lookup231: pallet_xcm::pallet::Call */ PalletXcmCall: { _enum: { send: { @@ -2148,7 +2182,7 @@ export default { }, }, }, - /** Lookup229: staging_xcm::VersionedXcm */ + /** Lookup232: staging_xcm::VersionedXcm */ StagingXcmVersionedXcm: { _enum: { __Unused0: "Null", @@ -2157,9 +2191,9 @@ export default { V3: "StagingXcmV3Xcm", }, }, - /** Lookup230: staging_xcm::v2::Xcm */ + /** Lookup233: staging_xcm::v2::Xcm */ StagingXcmV2Xcm: "Vec", - /** Lookup232: staging_xcm::v2::Instruction */ + /** Lookup235: staging_xcm::v2::Instruction */ StagingXcmV2Instruction: { _enum: { WithdrawAsset: "StagingXcmV2MultiassetMultiAssets", @@ -2255,7 +2289,7 @@ export default { UnsubscribeVersion: "Null", }, }, - /** Lookup233: staging_xcm::v2::Response */ + /** Lookup236: staging_xcm::v2::Response */ StagingXcmV2Response: { _enum: { Null: "Null", @@ -2264,7 +2298,7 @@ export default { Version: "u32", }, }, - /** Lookup236: staging_xcm::v2::traits::Error */ + /** Lookup239: staging_xcm::v2::traits::Error */ StagingXcmV2TraitsError: { _enum: { Overflow: "Null", @@ -2295,14 +2329,14 @@ export default { WeightNotComputable: "Null", }, }, - /** Lookup237: staging_xcm::v2::multiasset::MultiAssetFilter */ + /** Lookup240: staging_xcm::v2::multiasset::MultiAssetFilter */ StagingXcmV2MultiassetMultiAssetFilter: { _enum: { Definite: "StagingXcmV2MultiassetMultiAssets", Wild: "StagingXcmV2MultiassetWildMultiAsset", }, }, - /** Lookup238: staging_xcm::v2::multiasset::WildMultiAsset */ + /** Lookup241: staging_xcm::v2::multiasset::WildMultiAsset */ StagingXcmV2MultiassetWildMultiAsset: { _enum: { All: "Null", @@ -2312,18 +2346,18 @@ export default { }, }, }, - /** Lookup239: staging_xcm::v2::multiasset::WildFungibility */ + /** Lookup242: staging_xcm::v2::multiasset::WildFungibility */ StagingXcmV2MultiassetWildFungibility: { _enum: ["Fungible", "NonFungible"], }, - /** Lookup240: staging_xcm::v2::WeightLimit */ + /** Lookup243: staging_xcm::v2::WeightLimit */ StagingXcmV2WeightLimit: { _enum: { Unlimited: "Null", Limited: "Compact", }, }, - /** Lookup249: pallet_root_testing::pallet::Call */ + /** Lookup252: pallet_root_testing::pallet::Call */ PalletRootTestingCall: { _enum: { fill_block: { @@ -2331,27 +2365,27 @@ export default { }, }, }, - /** Lookup251: pallet_sudo::pallet::Error */ + /** Lookup254: pallet_sudo::pallet::Error */ PalletSudoError: { _enum: ["RequireSudo"], }, - /** Lookup252: pallet_utility::pallet::Error */ + /** Lookup255: pallet_utility::pallet::Error */ PalletUtilityError: { _enum: ["TooManyCalls"], }, - /** Lookup255: pallet_proxy::ProxyDefinition */ + /** Lookup258: pallet_proxy::ProxyDefinition */ PalletProxyProxyDefinition: { delegate: "AccountId32", proxyType: "DanceboxRuntimeProxyType", delay: "u32", }, - /** Lookup259: pallet_proxy::Announcement */ + /** Lookup262: pallet_proxy::Announcement */ PalletProxyAnnouncement: { real: "AccountId32", callHash: "H256", height: "u32", }, - /** Lookup261: pallet_proxy::pallet::Error */ + /** Lookup264: pallet_proxy::pallet::Error */ PalletProxyError: { _enum: [ "TooMany", @@ -2364,39 +2398,39 @@ export default { "NoSelfProxy", ], }, - /** Lookup262: pallet_migrations::pallet::Error */ + /** Lookup265: pallet_migrations::pallet::Error */ PalletMigrationsError: { _enum: ["PreimageMissing", "WrongUpperBound", "PreimageIsTooBig", "PreimageAlreadyExists"], }, - /** Lookup263: pallet_maintenance_mode::pallet::Error */ + /** Lookup266: pallet_maintenance_mode::pallet::Error */ PalletMaintenanceModeError: { _enum: ["AlreadyInMaintenanceMode", "NotInMaintenanceMode"], }, - /** Lookup265: pallet_balances::types::BalanceLock */ + /** Lookup268: pallet_balances::types::BalanceLock */ PalletBalancesBalanceLock: { id: "[u8;8]", amount: "u128", reasons: "PalletBalancesReasons", }, - /** Lookup266: pallet_balances::types::Reasons */ + /** Lookup269: pallet_balances::types::Reasons */ PalletBalancesReasons: { _enum: ["Fee", "Misc", "All"], }, - /** Lookup269: pallet_balances::types::ReserveData */ + /** Lookup272: pallet_balances::types::ReserveData */ PalletBalancesReserveData: { id: "[u8;8]", amount: "u128", }, - /** Lookup273: dancebox_runtime::HoldReason */ + /** Lookup276: dancebox_runtime::HoldReason */ DanceboxRuntimeHoldReason: { _enum: ["PooledStake"], }, - /** Lookup276: pallet_balances::types::IdAmount */ + /** Lookup279: pallet_balances::types::IdAmount */ PalletBalancesIdAmount: { id: "[u8;8]", amount: "u128", }, - /** Lookup278: pallet_balances::pallet::Error */ + /** Lookup281: pallet_balances::pallet::Error */ PalletBalancesError: { _enum: [ "VestingBalance", @@ -2411,16 +2445,16 @@ export default { "TooManyFreezes", ], }, - /** Lookup280: pallet_transaction_payment::Releases */ + /** Lookup283: pallet_transaction_payment::Releases */ PalletTransactionPaymentReleases: { _enum: ["V1Ancient", "V2"], }, - /** Lookup285: pallet_registrar::pallet::DepositInfo */ + /** Lookup288: pallet_registrar::pallet::DepositInfo */ PalletRegistrarDepositInfo: { creator: "AccountId32", deposit: "u128", }, - /** Lookup286: pallet_registrar::pallet::Error */ + /** Lookup289: pallet_registrar::pallet::Error */ PalletRegistrarError: { _enum: [ "ParaIdAlreadyRegistered", @@ -2432,7 +2466,7 @@ export default { "NotSufficientDeposit", ], }, - /** Lookup287: pallet_configuration::HostConfiguration */ + /** Lookup290: pallet_configuration::HostConfiguration */ PalletConfigurationHostConfiguration: { maxCollators: "u32", minOrchestratorCollators: "u32", @@ -2440,21 +2474,21 @@ export default { collatorsPerContainer: "u32", fullRotationPeriod: "u32", }, - /** Lookup290: pallet_configuration::pallet::Error */ + /** Lookup293: pallet_configuration::pallet::Error */ PalletConfigurationError: { _enum: ["InvalidNewValue"], }, - /** Lookup291: tp_collator_assignment::AssignedCollators */ + /** Lookup294: tp_collator_assignment::AssignedCollators */ TpCollatorAssignmentAssignedCollatorsAccountId32: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup296: pallet_author_noting::pallet::ContainerChainBlockInfo */ + /** Lookup299: pallet_author_noting::pallet::ContainerChainBlockInfo */ PalletAuthorNotingContainerChainBlockInfo: { blockNumber: "u32", author: "AccountId32", }, - /** Lookup297: pallet_author_noting::pallet::Error */ + /** Lookup300: pallet_author_noting::pallet::Error */ PalletAuthorNotingError: { _enum: [ "FailedReading", @@ -2466,31 +2500,35 @@ export default { "NonAuraDigest", ], }, - /** Lookup298: tp_collator_assignment::AssignedCollators */ + /** Lookup301: tp_collator_assignment::AssignedCollators */ TpCollatorAssignmentAssignedCollatorsPublic: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup304: pallet_invulnerables::pallet::Error */ + /** Lookup306: pallet_services_payment::pallet::Error */ + PalletServicesPaymentError: { + _enum: ["InsufficientFundsToPurchaseCredits", "InsufficientCredits", "CreditPriceTooExpensive"], + }, + /** Lookup308: pallet_invulnerables::pallet::Error */ PalletInvulnerablesError: { _enum: ["TooManyInvulnerables", "AlreadyInvulnerable", "NotInvulnerable"], }, - /** Lookup309: sp_core::crypto::KeyTypeId */ + /** Lookup313: sp_core::crypto::KeyTypeId */ SpCoreCryptoKeyTypeId: "[u8;4]", - /** Lookup310: pallet_session::pallet::Error */ + /** Lookup314: pallet_session::pallet::Error */ PalletSessionError: { _enum: ["InvalidProof", "NoAssociatedValidatorId", "DuplicatedKey", "NoKeys", "NoAccount"], }, - /** Lookup314: pallet_author_inherent::pallet::Error */ + /** Lookup318: pallet_author_inherent::pallet::Error */ PalletAuthorInherentError: { _enum: ["AuthorAlreadySet", "NoAccountId", "CannotBeAuthor"], }, - /** Lookup316: pallet_pooled_staking::candidate::EligibleCandidate */ + /** Lookup320: pallet_pooled_staking::candidate::EligibleCandidate */ PalletPooledStakingCandidateEligibleCandidate: { candidate: "AccountId32", stake: "u128", }, - /** Lookup319: pallet_pooled_staking::pallet::PoolsKey */ + /** Lookup323: pallet_pooled_staking::pallet::PoolsKey */ PalletPooledStakingPoolsKey: { _enum: { CandidateTotalStake: "Null", @@ -2532,7 +2570,7 @@ export default { }, }, }, - /** Lookup321: pallet_pooled_staking::pallet::Error */ + /** Lookup325: pallet_pooled_staking::pallet::Error */ PalletPooledStakingError: { _enum: { InvalidPalletSetting: "Null", @@ -2551,26 +2589,26 @@ export default { SwapResultsInZeroShares: "Null", }, }, - /** Lookup322: pallet_inflation_rewards::pallet::ChainsToRewardValue */ + /** Lookup326: pallet_inflation_rewards::pallet::ChainsToRewardValue */ PalletInflationRewardsChainsToRewardValue: { paraIds: "Vec", rewardsPerChain: "u128", }, - /** Lookup324: cumulus_pallet_xcmp_queue::InboundChannelDetails */ + /** Lookup328: cumulus_pallet_xcmp_queue::InboundChannelDetails */ CumulusPalletXcmpQueueInboundChannelDetails: { sender: "u32", state: "CumulusPalletXcmpQueueInboundState", messageMetadata: "Vec<(u32,PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat)>", }, - /** Lookup325: cumulus_pallet_xcmp_queue::InboundState */ + /** Lookup329: cumulus_pallet_xcmp_queue::InboundState */ CumulusPalletXcmpQueueInboundState: { _enum: ["Ok", "Suspended"], }, - /** Lookup328: polkadot_parachain_primitives::primitives::XcmpMessageFormat */ + /** Lookup332: polkadot_parachain_primitives::primitives::XcmpMessageFormat */ PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat: { _enum: ["ConcatenatedVersionedXcm", "ConcatenatedEncodedBlob", "Signals"], }, - /** Lookup331: cumulus_pallet_xcmp_queue::OutboundChannelDetails */ + /** Lookup335: cumulus_pallet_xcmp_queue::OutboundChannelDetails */ CumulusPalletXcmpQueueOutboundChannelDetails: { recipient: "u32", state: "CumulusPalletXcmpQueueOutboundState", @@ -2578,11 +2616,11 @@ export default { firstIndex: "u16", lastIndex: "u16", }, - /** Lookup332: cumulus_pallet_xcmp_queue::OutboundState */ + /** Lookup336: cumulus_pallet_xcmp_queue::OutboundState */ CumulusPalletXcmpQueueOutboundState: { _enum: ["Ok", "Suspended"], }, - /** Lookup334: cumulus_pallet_xcmp_queue::QueueConfigData */ + /** Lookup338: cumulus_pallet_xcmp_queue::QueueConfigData */ CumulusPalletXcmpQueueQueueConfigData: { suspendThreshold: "u32", dropThreshold: "u32", @@ -2591,27 +2629,27 @@ export default { weightRestrictDecay: "SpWeightsWeightV2Weight", xcmpMaxIndividualWeight: "SpWeightsWeightV2Weight", }, - /** Lookup336: cumulus_pallet_xcmp_queue::pallet::Error */ + /** Lookup340: cumulus_pallet_xcmp_queue::pallet::Error */ CumulusPalletXcmpQueueError: { _enum: ["FailedToSend", "BadXcmOrigin", "BadXcm", "BadOverweightIndex", "WeightOverLimit"], }, - /** Lookup337: cumulus_pallet_xcm::pallet::Error */ + /** Lookup341: cumulus_pallet_xcm::pallet::Error */ CumulusPalletXcmError: "Null", - /** Lookup338: cumulus_pallet_dmp_queue::ConfigData */ + /** Lookup342: cumulus_pallet_dmp_queue::ConfigData */ CumulusPalletDmpQueueConfigData: { maxIndividual: "SpWeightsWeightV2Weight", }, - /** Lookup339: cumulus_pallet_dmp_queue::PageIndexData */ + /** Lookup343: cumulus_pallet_dmp_queue::PageIndexData */ CumulusPalletDmpQueuePageIndexData: { beginUsed: "u32", endUsed: "u32", overweightCount: "u64", }, - /** Lookup342: cumulus_pallet_dmp_queue::pallet::Error */ + /** Lookup346: cumulus_pallet_dmp_queue::pallet::Error */ CumulusPalletDmpQueueError: { _enum: ["Unknown", "OverLimit"], }, - /** Lookup343: pallet_xcm::pallet::QueryStatus */ + /** Lookup347: pallet_xcm::pallet::QueryStatus */ PalletXcmQueryStatus: { _enum: { Pending: { @@ -2630,7 +2668,7 @@ export default { }, }, }, - /** Lookup347: staging_xcm::VersionedResponse */ + /** Lookup351: staging_xcm::VersionedResponse */ StagingXcmVersionedResponse: { _enum: { __Unused0: "Null", @@ -2639,7 +2677,7 @@ export default { V3: "StagingXcmV3Response", }, }, - /** Lookup353: pallet_xcm::pallet::VersionMigrationStage */ + /** Lookup357: pallet_xcm::pallet::VersionMigrationStage */ PalletXcmVersionMigrationStage: { _enum: { MigrateSupportedVersion: "Null", @@ -2648,7 +2686,7 @@ export default { MigrateAndNotifyOldTargets: "Null", }, }, - /** Lookup355: staging_xcm::VersionedAssetId */ + /** Lookup359: staging_xcm::VersionedAssetId */ StagingXcmVersionedAssetId: { _enum: { __Unused0: "Null", @@ -2657,14 +2695,14 @@ export default { V3: "StagingXcmV3MultiassetAssetId", }, }, - /** Lookup356: pallet_xcm::pallet::RemoteLockedFungibleRecord */ + /** Lookup360: pallet_xcm::pallet::RemoteLockedFungibleRecord */ PalletXcmRemoteLockedFungibleRecord: { amount: "u128", owner: "StagingXcmVersionedMultiLocation", locker: "StagingXcmVersionedMultiLocation", consumers: "Vec<(Null,u128)>", }, - /** Lookup363: pallet_xcm::pallet::Error */ + /** Lookup367: pallet_xcm::pallet::Error */ PalletXcmError: { _enum: [ "Unreachable", @@ -2689,7 +2727,7 @@ export default { "InUse", ], }, - /** Lookup365: sp_runtime::MultiSignature */ + /** Lookup369: sp_runtime::MultiSignature */ SpRuntimeMultiSignature: { _enum: { Ed25519: "SpCoreEd25519Signature", @@ -2697,26 +2735,26 @@ export default { Ecdsa: "SpCoreEcdsaSignature", }, }, - /** Lookup366: sp_core::ed25519::Signature */ + /** Lookup370: sp_core::ed25519::Signature */ SpCoreEd25519Signature: "[u8;64]", - /** Lookup368: sp_core::sr25519::Signature */ + /** Lookup372: sp_core::sr25519::Signature */ SpCoreSr25519Signature: "[u8;64]", - /** Lookup369: sp_core::ecdsa::Signature */ + /** Lookup373: sp_core::ecdsa::Signature */ SpCoreEcdsaSignature: "[u8;65]", - /** Lookup372: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ + /** Lookup376: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ FrameSystemExtensionsCheckNonZeroSender: "Null", - /** Lookup373: frame_system::extensions::check_spec_version::CheckSpecVersion */ + /** Lookup377: frame_system::extensions::check_spec_version::CheckSpecVersion */ FrameSystemExtensionsCheckSpecVersion: "Null", - /** Lookup374: frame_system::extensions::check_tx_version::CheckTxVersion */ + /** Lookup378: frame_system::extensions::check_tx_version::CheckTxVersion */ FrameSystemExtensionsCheckTxVersion: "Null", - /** Lookup375: frame_system::extensions::check_genesis::CheckGenesis */ + /** Lookup379: frame_system::extensions::check_genesis::CheckGenesis */ FrameSystemExtensionsCheckGenesis: "Null", - /** Lookup378: frame_system::extensions::check_nonce::CheckNonce */ + /** Lookup382: frame_system::extensions::check_nonce::CheckNonce */ FrameSystemExtensionsCheckNonce: "Compact", - /** Lookup379: frame_system::extensions::check_weight::CheckWeight */ + /** Lookup383: frame_system::extensions::check_weight::CheckWeight */ FrameSystemExtensionsCheckWeight: "Null", - /** Lookup380: pallet_transaction_payment::ChargeTransactionPayment */ + /** Lookup384: pallet_transaction_payment::ChargeTransactionPayment */ PalletTransactionPaymentChargeTransactionPayment: "Compact", - /** Lookup381: dancebox_runtime::Runtime */ + /** Lookup385: dancebox_runtime::Runtime */ DanceboxRuntimeRuntime: "Null", }; diff --git a/typescript-api/src/dancebox/interfaces/registry.ts b/typescript-api/src/dancebox/interfaces/registry.ts index 2a867a2f8..b6030cf0d 100644 --- a/typescript-api/src/dancebox/interfaces/registry.ts +++ b/typescript-api/src/dancebox/interfaces/registry.ts @@ -113,6 +113,9 @@ import type { PalletRegistrarError, PalletRegistrarEvent, PalletRootTestingCall, + PalletServicesPaymentCall, + PalletServicesPaymentError, + PalletServicesPaymentEvent, PalletSessionCall, PalletSessionError, PalletSessionEvent, @@ -329,6 +332,9 @@ declare module "@polkadot/types/types/registry" { PalletRegistrarError: PalletRegistrarError; PalletRegistrarEvent: PalletRegistrarEvent; PalletRootTestingCall: PalletRootTestingCall; + PalletServicesPaymentCall: PalletServicesPaymentCall; + PalletServicesPaymentError: PalletServicesPaymentError; + PalletServicesPaymentEvent: PalletServicesPaymentEvent; PalletSessionCall: PalletSessionCall; PalletSessionError: PalletSessionError; PalletSessionEvent: PalletSessionEvent; diff --git a/typescript-api/src/dancebox/interfaces/types-lookup.ts b/typescript-api/src/dancebox/interfaces/types-lookup.ts index 6bd731eec..ba5e5c00a 100644 --- a/typescript-api/src/dancebox/interfaces/types-lookup.ts +++ b/typescript-api/src/dancebox/interfaces/types-lookup.ts @@ -608,7 +608,30 @@ declare module "@polkadot/types/lookup" { readonly type: "LatestAuthorChanged" | "RemovedAuthorData"; } - /** @name PalletInvulnerablesEvent (50) */ + /** @name PalletServicesPaymentEvent (50) */ + interface PalletServicesPaymentEvent extends Enum { + readonly isCreditsPurchased: boolean; + readonly asCreditsPurchased: { + readonly paraId: u32; + readonly payer: AccountId32; + readonly fee: u128; + readonly creditsPurchased: u32; + readonly creditsRemaining: u32; + } & Struct; + readonly isCreditBurned: boolean; + readonly asCreditBurned: { + readonly paraId: u32; + readonly creditsRemaining: u32; + } & Struct; + readonly isCreditsSet: boolean; + readonly asCreditsSet: { + readonly paraId: u32; + readonly credits: u32; + } & Struct; + readonly type: "CreditsPurchased" | "CreditBurned" | "CreditsSet"; + } + + /** @name PalletInvulnerablesEvent (51) */ interface PalletInvulnerablesEvent extends Enum { readonly isNewInvulnerables: boolean; readonly asNewInvulnerables: { @@ -629,7 +652,7 @@ declare module "@polkadot/types/lookup" { readonly type: "NewInvulnerables" | "InvulnerableAdded" | "InvulnerableRemoved" | "InvalidInvulnerableSkipped"; } - /** @name PalletSessionEvent (52) */ + /** @name PalletSessionEvent (53) */ interface PalletSessionEvent extends Enum { readonly isNewSession: boolean; readonly asNewSession: { @@ -638,7 +661,7 @@ declare module "@polkadot/types/lookup" { readonly type: "NewSession"; } - /** @name PalletPooledStakingEvent (53) */ + /** @name PalletPooledStakingEvent (54) */ interface PalletPooledStakingEvent extends Enum { readonly isUpdatedCandidatePosition: boolean; readonly asUpdatedCandidatePosition: { @@ -763,14 +786,14 @@ declare module "@polkadot/types/lookup" { | "SwappedPool"; } - /** @name PalletPooledStakingTargetPool (55) */ + /** @name PalletPooledStakingTargetPool (56) */ interface PalletPooledStakingTargetPool extends Enum { readonly isAutoCompounding: boolean; readonly isManualRewards: boolean; readonly type: "AutoCompounding" | "ManualRewards"; } - /** @name PalletInflationRewardsEvent (56) */ + /** @name PalletInflationRewardsEvent (57) */ interface PalletInflationRewardsEvent extends Enum { readonly isRewardedOrchestrator: boolean; readonly asRewardedOrchestrator: { @@ -786,7 +809,7 @@ declare module "@polkadot/types/lookup" { readonly type: "RewardedOrchestrator" | "RewardedContainer"; } - /** @name CumulusPalletXcmpQueueEvent (57) */ + /** @name CumulusPalletXcmpQueueEvent (58) */ interface CumulusPalletXcmpQueueEvent extends Enum { readonly isSuccess: boolean; readonly asSuccess: { @@ -835,7 +858,7 @@ declare module "@polkadot/types/lookup" { | "OverweightServiced"; } - /** @name StagingXcmV3TraitsError (58) */ + /** @name StagingXcmV3TraitsError (59) */ interface StagingXcmV3TraitsError extends Enum { readonly isOverflow: boolean; readonly isUnimplemented: boolean; @@ -922,7 +945,7 @@ declare module "@polkadot/types/lookup" { | "ExceedsStackLimit"; } - /** @name CumulusPalletXcmEvent (59) */ + /** @name CumulusPalletXcmEvent (60) */ interface CumulusPalletXcmEvent extends Enum { readonly isInvalidFormat: boolean; readonly asInvalidFormat: U8aFixed; @@ -933,7 +956,7 @@ declare module "@polkadot/types/lookup" { readonly type: "InvalidFormat" | "UnsupportedVersion" | "ExecutedDownward"; } - /** @name StagingXcmV3TraitsOutcome (60) */ + /** @name StagingXcmV3TraitsOutcome (61) */ interface StagingXcmV3TraitsOutcome extends Enum { readonly isComplete: boolean; readonly asComplete: SpWeightsWeightV2Weight; @@ -944,7 +967,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Complete" | "Incomplete" | "Error"; } - /** @name CumulusPalletDmpQueueEvent (61) */ + /** @name CumulusPalletDmpQueueEvent (62) */ interface CumulusPalletDmpQueueEvent extends Enum { readonly isInvalidFormat: boolean; readonly asInvalidFormat: { @@ -993,7 +1016,7 @@ declare module "@polkadot/types/lookup" { | "MaxMessagesExhausted"; } - /** @name PalletXcmEvent (62) */ + /** @name PalletXcmEvent (63) */ interface PalletXcmEvent extends Enum { readonly isAttempted: boolean; readonly asAttempted: { @@ -1153,13 +1176,13 @@ declare module "@polkadot/types/lookup" { | "AssetsClaimed"; } - /** @name StagingXcmV3MultiLocation (63) */ + /** @name StagingXcmV3MultiLocation (64) */ interface StagingXcmV3MultiLocation extends Struct { readonly parents: u8; readonly interior: StagingXcmV3Junctions; } - /** @name StagingXcmV3Junctions (64) */ + /** @name StagingXcmV3Junctions (65) */ interface StagingXcmV3Junctions extends Enum { readonly isHere: boolean; readonly isX1: boolean; @@ -1219,7 +1242,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Here" | "X1" | "X2" | "X3" | "X4" | "X5" | "X6" | "X7" | "X8"; } - /** @name StagingXcmV3Junction (65) */ + /** @name StagingXcmV3Junction (66) */ interface StagingXcmV3Junction extends Enum { readonly isParachain: boolean; readonly asParachain: Compact; @@ -1268,7 +1291,7 @@ declare module "@polkadot/types/lookup" { | "GlobalConsensus"; } - /** @name StagingXcmV3JunctionNetworkId (68) */ + /** @name StagingXcmV3JunctionNetworkId (69) */ interface StagingXcmV3JunctionNetworkId extends Enum { readonly isByGenesis: boolean; readonly asByGenesis: U8aFixed; @@ -1301,7 +1324,7 @@ declare module "@polkadot/types/lookup" { | "BitcoinCash"; } - /** @name StagingXcmV3JunctionBodyId (71) */ + /** @name StagingXcmV3JunctionBodyId (72) */ interface StagingXcmV3JunctionBodyId extends Enum { readonly isUnit: boolean; readonly isMoniker: boolean; @@ -1328,7 +1351,7 @@ declare module "@polkadot/types/lookup" { | "Treasury"; } - /** @name StagingXcmV3JunctionBodyPart (72) */ + /** @name StagingXcmV3JunctionBodyPart (73) */ interface StagingXcmV3JunctionBodyPart extends Enum { readonly isVoice: boolean; readonly isMembers: boolean; @@ -1353,10 +1376,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Voice" | "Members" | "Fraction" | "AtLeastProportion" | "MoreThanProportion"; } - /** @name StagingXcmV3Xcm (73) */ + /** @name StagingXcmV3Xcm (74) */ interface StagingXcmV3Xcm extends Vec {} - /** @name StagingXcmV3Instruction (75) */ + /** @name StagingXcmV3Instruction (76) */ interface StagingXcmV3Instruction extends Enum { readonly isWithdrawAsset: boolean; readonly asWithdrawAsset: StagingXcmV3MultiassetMultiAssets; @@ -1586,16 +1609,16 @@ declare module "@polkadot/types/lookup" { | "UnpaidExecution"; } - /** @name StagingXcmV3MultiassetMultiAssets (76) */ + /** @name StagingXcmV3MultiassetMultiAssets (77) */ interface StagingXcmV3MultiassetMultiAssets extends Vec {} - /** @name StagingXcmV3MultiAsset (78) */ + /** @name StagingXcmV3MultiAsset (79) */ interface StagingXcmV3MultiAsset extends Struct { readonly id: StagingXcmV3MultiassetAssetId; readonly fun: StagingXcmV3MultiassetFungibility; } - /** @name StagingXcmV3MultiassetAssetId (79) */ + /** @name StagingXcmV3MultiassetAssetId (80) */ interface StagingXcmV3MultiassetAssetId extends Enum { readonly isConcrete: boolean; readonly asConcrete: StagingXcmV3MultiLocation; @@ -1604,7 +1627,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Concrete" | "Abstract"; } - /** @name StagingXcmV3MultiassetFungibility (80) */ + /** @name StagingXcmV3MultiassetFungibility (81) */ interface StagingXcmV3MultiassetFungibility extends Enum { readonly isFungible: boolean; readonly asFungible: Compact; @@ -1613,7 +1636,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Fungible" | "NonFungible"; } - /** @name StagingXcmV3MultiassetAssetInstance (81) */ + /** @name StagingXcmV3MultiassetAssetInstance (82) */ interface StagingXcmV3MultiassetAssetInstance extends Enum { readonly isUndefined: boolean; readonly isIndex: boolean; @@ -1629,7 +1652,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Undefined" | "Index" | "Array4" | "Array8" | "Array16" | "Array32"; } - /** @name StagingXcmV3Response (84) */ + /** @name StagingXcmV3Response (85) */ interface StagingXcmV3Response extends Enum { readonly isNull: boolean; readonly isAssets: boolean; @@ -1645,7 +1668,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Null" | "Assets" | "ExecutionResult" | "Version" | "PalletsInfo" | "DispatchResult"; } - /** @name StagingXcmV3PalletInfo (88) */ + /** @name StagingXcmV3PalletInfo (89) */ interface StagingXcmV3PalletInfo extends Struct { readonly index: Compact; readonly name: Bytes; @@ -1655,7 +1678,7 @@ declare module "@polkadot/types/lookup" { readonly patch: Compact; } - /** @name StagingXcmV3MaybeErrorCode (91) */ + /** @name StagingXcmV3MaybeErrorCode (92) */ interface StagingXcmV3MaybeErrorCode extends Enum { readonly isSuccess: boolean; readonly isError: boolean; @@ -1665,7 +1688,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Success" | "Error" | "TruncatedError"; } - /** @name StagingXcmV2OriginKind (94) */ + /** @name StagingXcmV2OriginKind (95) */ interface StagingXcmV2OriginKind extends Enum { readonly isNative: boolean; readonly isSovereignAccount: boolean; @@ -1674,19 +1697,19 @@ declare module "@polkadot/types/lookup" { readonly type: "Native" | "SovereignAccount" | "Superuser" | "Xcm"; } - /** @name StagingXcmDoubleEncoded (95) */ + /** @name StagingXcmDoubleEncoded (96) */ interface StagingXcmDoubleEncoded extends Struct { readonly encoded: Bytes; } - /** @name StagingXcmV3QueryResponseInfo (96) */ + /** @name StagingXcmV3QueryResponseInfo (97) */ interface StagingXcmV3QueryResponseInfo extends Struct { readonly destination: StagingXcmV3MultiLocation; readonly queryId: Compact; readonly maxWeight: SpWeightsWeightV2Weight; } - /** @name StagingXcmV3MultiassetMultiAssetFilter (97) */ + /** @name StagingXcmV3MultiassetMultiAssetFilter (98) */ interface StagingXcmV3MultiassetMultiAssetFilter extends Enum { readonly isDefinite: boolean; readonly asDefinite: StagingXcmV3MultiassetMultiAssets; @@ -1695,7 +1718,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Definite" | "Wild"; } - /** @name StagingXcmV3MultiassetWildMultiAsset (98) */ + /** @name StagingXcmV3MultiassetWildMultiAsset (99) */ interface StagingXcmV3MultiassetWildMultiAsset extends Enum { readonly isAll: boolean; readonly isAllOf: boolean; @@ -1714,14 +1737,14 @@ declare module "@polkadot/types/lookup" { readonly type: "All" | "AllOf" | "AllCounted" | "AllOfCounted"; } - /** @name StagingXcmV3MultiassetWildFungibility (99) */ + /** @name StagingXcmV3MultiassetWildFungibility (100) */ interface StagingXcmV3MultiassetWildFungibility extends Enum { readonly isFungible: boolean; readonly isNonFungible: boolean; readonly type: "Fungible" | "NonFungible"; } - /** @name StagingXcmV3WeightLimit (100) */ + /** @name StagingXcmV3WeightLimit (101) */ interface StagingXcmV3WeightLimit extends Enum { readonly isUnlimited: boolean; readonly isLimited: boolean; @@ -1729,7 +1752,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Unlimited" | "Limited"; } - /** @name StagingXcmVersionedMultiAssets (101) */ + /** @name StagingXcmVersionedMultiAssets (102) */ interface StagingXcmVersionedMultiAssets extends Enum { readonly isV2: boolean; readonly asV2: StagingXcmV2MultiassetMultiAssets; @@ -1738,16 +1761,16 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3"; } - /** @name StagingXcmV2MultiassetMultiAssets (102) */ + /** @name StagingXcmV2MultiassetMultiAssets (103) */ interface StagingXcmV2MultiassetMultiAssets extends Vec {} - /** @name StagingXcmV2MultiAsset (104) */ + /** @name StagingXcmV2MultiAsset (105) */ interface StagingXcmV2MultiAsset extends Struct { readonly id: StagingXcmV2MultiassetAssetId; readonly fun: StagingXcmV2MultiassetFungibility; } - /** @name StagingXcmV2MultiassetAssetId (105) */ + /** @name StagingXcmV2MultiassetAssetId (106) */ interface StagingXcmV2MultiassetAssetId extends Enum { readonly isConcrete: boolean; readonly asConcrete: StagingXcmV2MultiLocation; @@ -1756,13 +1779,13 @@ declare module "@polkadot/types/lookup" { readonly type: "Concrete" | "Abstract"; } - /** @name StagingXcmV2MultiLocation (106) */ + /** @name StagingXcmV2MultiLocation (107) */ interface StagingXcmV2MultiLocation extends Struct { readonly parents: u8; readonly interior: StagingXcmV2MultilocationJunctions; } - /** @name StagingXcmV2MultilocationJunctions (107) */ + /** @name StagingXcmV2MultilocationJunctions (108) */ interface StagingXcmV2MultilocationJunctions extends Enum { readonly isHere: boolean; readonly isX1: boolean; @@ -1822,7 +1845,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Here" | "X1" | "X2" | "X3" | "X4" | "X5" | "X6" | "X7" | "X8"; } - /** @name StagingXcmV2Junction (108) */ + /** @name StagingXcmV2Junction (109) */ interface StagingXcmV2Junction extends Enum { readonly isParachain: boolean; readonly asParachain: Compact; @@ -1865,7 +1888,7 @@ declare module "@polkadot/types/lookup" { | "Plurality"; } - /** @name StagingXcmV2NetworkId (109) */ + /** @name StagingXcmV2NetworkId (110) */ interface StagingXcmV2NetworkId extends Enum { readonly isAny: boolean; readonly isNamed: boolean; @@ -1875,7 +1898,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Any" | "Named" | "Polkadot" | "Kusama"; } - /** @name StagingXcmV2BodyId (111) */ + /** @name StagingXcmV2BodyId (112) */ interface StagingXcmV2BodyId extends Enum { readonly isUnit: boolean; readonly isNamed: boolean; @@ -1902,7 +1925,7 @@ declare module "@polkadot/types/lookup" { | "Treasury"; } - /** @name StagingXcmV2BodyPart (112) */ + /** @name StagingXcmV2BodyPart (113) */ interface StagingXcmV2BodyPart extends Enum { readonly isVoice: boolean; readonly isMembers: boolean; @@ -1927,7 +1950,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Voice" | "Members" | "Fraction" | "AtLeastProportion" | "MoreThanProportion"; } - /** @name StagingXcmV2MultiassetFungibility (113) */ + /** @name StagingXcmV2MultiassetFungibility (114) */ interface StagingXcmV2MultiassetFungibility extends Enum { readonly isFungible: boolean; readonly asFungible: Compact; @@ -1936,7 +1959,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Fungible" | "NonFungible"; } - /** @name StagingXcmV2MultiassetAssetInstance (114) */ + /** @name StagingXcmV2MultiassetAssetInstance (115) */ interface StagingXcmV2MultiassetAssetInstance extends Enum { readonly isUndefined: boolean; readonly isIndex: boolean; @@ -1954,7 +1977,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Undefined" | "Index" | "Array4" | "Array8" | "Array16" | "Array32" | "Blob"; } - /** @name StagingXcmVersionedMultiLocation (115) */ + /** @name StagingXcmVersionedMultiLocation (116) */ interface StagingXcmVersionedMultiLocation extends Enum { readonly isV2: boolean; readonly asV2: StagingXcmV2MultiLocation; @@ -1963,7 +1986,7 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3"; } - /** @name FrameSystemPhase (116) */ + /** @name FrameSystemPhase (117) */ interface FrameSystemPhase extends Enum { readonly isApplyExtrinsic: boolean; readonly asApplyExtrinsic: u32; @@ -1972,13 +1995,13 @@ declare module "@polkadot/types/lookup" { readonly type: "ApplyExtrinsic" | "Finalization" | "Initialization"; } - /** @name FrameSystemLastRuntimeUpgradeInfo (120) */ + /** @name FrameSystemLastRuntimeUpgradeInfo (121) */ interface FrameSystemLastRuntimeUpgradeInfo extends Struct { readonly specVersion: Compact; readonly specName: Text; } - /** @name FrameSystemCall (122) */ + /** @name FrameSystemCall (123) */ interface FrameSystemCall extends Enum { readonly isRemark: boolean; readonly asRemark: { @@ -2024,21 +2047,21 @@ declare module "@polkadot/types/lookup" { | "RemarkWithEvent"; } - /** @name FrameSystemLimitsBlockWeights (126) */ + /** @name FrameSystemLimitsBlockWeights (127) */ interface FrameSystemLimitsBlockWeights extends Struct { readonly baseBlock: SpWeightsWeightV2Weight; readonly maxBlock: SpWeightsWeightV2Weight; readonly perClass: FrameSupportDispatchPerDispatchClassWeightsPerClass; } - /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (127) */ + /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (128) */ interface FrameSupportDispatchPerDispatchClassWeightsPerClass extends Struct { readonly normal: FrameSystemLimitsWeightsPerClass; readonly operational: FrameSystemLimitsWeightsPerClass; readonly mandatory: FrameSystemLimitsWeightsPerClass; } - /** @name FrameSystemLimitsWeightsPerClass (128) */ + /** @name FrameSystemLimitsWeightsPerClass (129) */ interface FrameSystemLimitsWeightsPerClass extends Struct { readonly baseExtrinsic: SpWeightsWeightV2Weight; readonly maxExtrinsic: Option; @@ -2046,25 +2069,25 @@ declare module "@polkadot/types/lookup" { readonly reserved: Option; } - /** @name FrameSystemLimitsBlockLength (130) */ + /** @name FrameSystemLimitsBlockLength (131) */ interface FrameSystemLimitsBlockLength extends Struct { readonly max: FrameSupportDispatchPerDispatchClassU32; } - /** @name FrameSupportDispatchPerDispatchClassU32 (131) */ + /** @name FrameSupportDispatchPerDispatchClassU32 (132) */ interface FrameSupportDispatchPerDispatchClassU32 extends Struct { readonly normal: u32; readonly operational: u32; readonly mandatory: u32; } - /** @name SpWeightsRuntimeDbWeight (132) */ + /** @name SpWeightsRuntimeDbWeight (133) */ interface SpWeightsRuntimeDbWeight extends Struct { readonly read: u64; readonly write: u64; } - /** @name SpVersionRuntimeVersion (133) */ + /** @name SpVersionRuntimeVersion (134) */ interface SpVersionRuntimeVersion extends Struct { readonly specName: Text; readonly implName: Text; @@ -2076,7 +2099,7 @@ declare module "@polkadot/types/lookup" { readonly stateVersion: u8; } - /** @name FrameSystemError (137) */ + /** @name FrameSystemError (138) */ interface FrameSystemError extends Enum { readonly isInvalidSpecName: boolean; readonly isSpecVersionNeedsToIncrease: boolean; @@ -2093,41 +2116,41 @@ declare module "@polkadot/types/lookup" { | "CallFiltered"; } - /** @name CumulusPalletParachainSystemUnincludedSegmentAncestor (139) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentAncestor (140) */ interface CumulusPalletParachainSystemUnincludedSegmentAncestor extends Struct { readonly usedBandwidth: CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth; readonly paraHeadHash: Option; readonly consumedGoAheadSignal: Option; } - /** @name CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth (140) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth (141) */ interface CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth extends Struct { readonly umpMsgCount: u32; readonly umpTotalBytes: u32; readonly hrmpOutgoing: BTreeMap; } - /** @name CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate (142) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate (143) */ interface CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate extends Struct { readonly msgCount: u32; readonly totalBytes: u32; } - /** @name PolkadotPrimitivesV5UpgradeGoAhead (147) */ + /** @name PolkadotPrimitivesV5UpgradeGoAhead (148) */ interface PolkadotPrimitivesV5UpgradeGoAhead extends Enum { readonly isAbort: boolean; readonly isGoAhead: boolean; readonly type: "Abort" | "GoAhead"; } - /** @name CumulusPalletParachainSystemUnincludedSegmentSegmentTracker (148) */ + /** @name CumulusPalletParachainSystemUnincludedSegmentSegmentTracker (149) */ interface CumulusPalletParachainSystemUnincludedSegmentSegmentTracker extends Struct { readonly usedBandwidth: CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth; readonly hrmpWatermark: Option; readonly consumedGoAheadSignal: Option; } - /** @name PolkadotPrimitivesV5PersistedValidationData (149) */ + /** @name PolkadotPrimitivesV5PersistedValidationData (150) */ interface PolkadotPrimitivesV5PersistedValidationData extends Struct { readonly parentHead: Bytes; readonly relayParentNumber: u32; @@ -2135,18 +2158,18 @@ declare module "@polkadot/types/lookup" { readonly maxPovSize: u32; } - /** @name PolkadotPrimitivesV5UpgradeRestriction (152) */ + /** @name PolkadotPrimitivesV5UpgradeRestriction (153) */ interface PolkadotPrimitivesV5UpgradeRestriction extends Enum { readonly isPresent: boolean; readonly type: "Present"; } - /** @name SpTrieStorageProof (153) */ + /** @name SpTrieStorageProof (154) */ interface SpTrieStorageProof extends Struct { readonly trieNodes: BTreeSet; } - /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (155) */ + /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (156) */ interface CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot extends Struct { readonly dmqMqcHead: H256; readonly relayDispatchQueueRemainingCapacity: CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity; @@ -2154,13 +2177,13 @@ declare module "@polkadot/types/lookup" { readonly egressChannels: Vec>; } - /** @name CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity (156) */ + /** @name CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity (157) */ interface CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity extends Struct { readonly remainingCount: u32; readonly remainingSize: u32; } - /** @name PolkadotPrimitivesV5AbridgedHrmpChannel (159) */ + /** @name PolkadotPrimitivesV5AbridgedHrmpChannel (160) */ interface PolkadotPrimitivesV5AbridgedHrmpChannel extends Struct { readonly maxCapacity: u32; readonly maxTotalSize: u32; @@ -2170,7 +2193,7 @@ declare module "@polkadot/types/lookup" { readonly mqcHead: Option; } - /** @name PolkadotPrimitivesV5AbridgedHostConfiguration (160) */ + /** @name PolkadotPrimitivesV5AbridgedHostConfiguration (161) */ interface PolkadotPrimitivesV5AbridgedHostConfiguration extends Struct { readonly maxCodeSize: u32; readonly maxHeadDataSize: u32; @@ -2184,25 +2207,25 @@ declare module "@polkadot/types/lookup" { readonly asyncBackingParams: PolkadotPrimitivesVstagingAsyncBackingParams; } - /** @name PolkadotPrimitivesVstagingAsyncBackingParams (161) */ + /** @name PolkadotPrimitivesVstagingAsyncBackingParams (162) */ interface PolkadotPrimitivesVstagingAsyncBackingParams extends Struct { readonly maxCandidateDepth: u32; readonly allowedAncestryLen: u32; } - /** @name PolkadotCorePrimitivesOutboundHrmpMessage (167) */ + /** @name PolkadotCorePrimitivesOutboundHrmpMessage (168) */ interface PolkadotCorePrimitivesOutboundHrmpMessage extends Struct { readonly recipient: u32; readonly data: Bytes; } - /** @name CumulusPalletParachainSystemCodeUpgradeAuthorization (168) */ + /** @name CumulusPalletParachainSystemCodeUpgradeAuthorization (169) */ interface CumulusPalletParachainSystemCodeUpgradeAuthorization extends Struct { readonly codeHash: H256; readonly checkVersion: bool; } - /** @name CumulusPalletParachainSystemCall (169) */ + /** @name CumulusPalletParachainSystemCall (170) */ interface CumulusPalletParachainSystemCall extends Enum { readonly isSetValidationData: boolean; readonly asSetValidationData: { @@ -2224,7 +2247,7 @@ declare module "@polkadot/types/lookup" { readonly type: "SetValidationData" | "SudoSendUpwardMessage" | "AuthorizeUpgrade" | "EnactAuthorizedUpgrade"; } - /** @name CumulusPrimitivesParachainInherentParachainInherentData (170) */ + /** @name CumulusPrimitivesParachainInherentParachainInherentData (171) */ interface CumulusPrimitivesParachainInherentParachainInherentData extends Struct { readonly validationData: PolkadotPrimitivesV5PersistedValidationData; readonly relayChainState: SpTrieStorageProof; @@ -2232,19 +2255,19 @@ declare module "@polkadot/types/lookup" { readonly horizontalMessages: BTreeMap>; } - /** @name PolkadotCorePrimitivesInboundDownwardMessage (172) */ + /** @name PolkadotCorePrimitivesInboundDownwardMessage (173) */ interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct { readonly sentAt: u32; readonly msg: Bytes; } - /** @name PolkadotCorePrimitivesInboundHrmpMessage (175) */ + /** @name PolkadotCorePrimitivesInboundHrmpMessage (176) */ interface PolkadotCorePrimitivesInboundHrmpMessage extends Struct { readonly sentAt: u32; readonly data: Bytes; } - /** @name CumulusPalletParachainSystemError (178) */ + /** @name CumulusPalletParachainSystemError (179) */ interface CumulusPalletParachainSystemError extends Enum { readonly isOverlappingUpgrades: boolean; readonly isProhibitedByPolkadot: boolean; @@ -2265,7 +2288,7 @@ declare module "@polkadot/types/lookup" { | "Unauthorized"; } - /** @name PalletTimestampCall (179) */ + /** @name PalletTimestampCall (180) */ interface PalletTimestampCall extends Enum { readonly isSet: boolean; readonly asSet: { @@ -2274,10 +2297,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Set"; } - /** @name ParachainInfoCall (180) */ + /** @name ParachainInfoCall (181) */ type ParachainInfoCall = Null; - /** @name PalletSudoCall (181) */ + /** @name PalletSudoCall (182) */ interface PalletSudoCall extends Enum { readonly isSudo: boolean; readonly asSudo: { @@ -2300,7 +2323,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Sudo" | "SudoUncheckedWeight" | "SetKey" | "SudoAs"; } - /** @name PalletUtilityCall (183) */ + /** @name PalletUtilityCall (184) */ interface PalletUtilityCall extends Enum { readonly isBatch: boolean; readonly asBatch: { @@ -2332,7 +2355,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Batch" | "AsDerivative" | "BatchAll" | "DispatchAs" | "ForceBatch" | "WithWeight"; } - /** @name DanceboxRuntimeOriginCaller (185) */ + /** @name DanceboxRuntimeOriginCaller (186) */ interface DanceboxRuntimeOriginCaller extends Enum { readonly isSystem: boolean; readonly asSystem: FrameSupportDispatchRawOrigin; @@ -2344,7 +2367,7 @@ declare module "@polkadot/types/lookup" { readonly type: "System" | "Void" | "CumulusXcm" | "PolkadotXcm"; } - /** @name FrameSupportDispatchRawOrigin (186) */ + /** @name FrameSupportDispatchRawOrigin (187) */ interface FrameSupportDispatchRawOrigin extends Enum { readonly isRoot: boolean; readonly isSigned: boolean; @@ -2353,7 +2376,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Root" | "Signed" | "None"; } - /** @name CumulusPalletXcmOrigin (187) */ + /** @name CumulusPalletXcmOrigin (188) */ interface CumulusPalletXcmOrigin extends Enum { readonly isRelay: boolean; readonly isSiblingParachain: boolean; @@ -2361,7 +2384,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Relay" | "SiblingParachain"; } - /** @name PalletXcmOrigin (188) */ + /** @name PalletXcmOrigin (189) */ interface PalletXcmOrigin extends Enum { readonly isXcm: boolean; readonly asXcm: StagingXcmV3MultiLocation; @@ -2370,10 +2393,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Xcm" | "Response"; } - /** @name SpCoreVoid (189) */ + /** @name SpCoreVoid (190) */ type SpCoreVoid = Null; - /** @name PalletProxyCall (190) */ + /** @name PalletProxyCall (191) */ interface PalletProxyCall extends Enum { readonly isProxy: boolean; readonly asProxy: { @@ -2443,14 +2466,14 @@ declare module "@polkadot/types/lookup" { | "ProxyAnnounced"; } - /** @name PalletMaintenanceModeCall (194) */ + /** @name PalletMaintenanceModeCall (195) */ interface PalletMaintenanceModeCall extends Enum { readonly isEnterMaintenanceMode: boolean; readonly isResumeNormalOperation: boolean; readonly type: "EnterMaintenanceMode" | "ResumeNormalOperation"; } - /** @name PalletBalancesCall (195) */ + /** @name PalletBalancesCall (196) */ interface PalletBalancesCall extends Enum { readonly isTransferAllowDeath: boolean; readonly asTransferAllowDeath: { @@ -2510,7 +2533,7 @@ declare module "@polkadot/types/lookup" { | "ForceSetBalance"; } - /** @name PalletRegistrarCall (196) */ + /** @name PalletRegistrarCall (197) */ interface PalletRegistrarCall extends Enum { readonly isRegister: boolean; readonly asRegister: { @@ -2537,7 +2560,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Register" | "Deregister" | "MarkValidForCollating" | "SetBootNodes" | "PauseContainerChain"; } - /** @name TpContainerChainGenesisDataContainerChainGenesisData (197) */ + /** @name TpContainerChainGenesisDataContainerChainGenesisData (198) */ interface TpContainerChainGenesisDataContainerChainGenesisData extends Struct { readonly storage: Vec; readonly name: Bytes; @@ -2547,26 +2570,26 @@ declare module "@polkadot/types/lookup" { readonly properties: TpContainerChainGenesisDataProperties; } - /** @name TpContainerChainGenesisDataContainerChainGenesisDataItem (199) */ + /** @name TpContainerChainGenesisDataContainerChainGenesisDataItem (200) */ interface TpContainerChainGenesisDataContainerChainGenesisDataItem extends Struct { readonly key: Bytes; readonly value: Bytes; } - /** @name TpContainerChainGenesisDataProperties (201) */ + /** @name TpContainerChainGenesisDataProperties (202) */ interface TpContainerChainGenesisDataProperties extends Struct { readonly tokenMetadata: TpContainerChainGenesisDataTokenMetadata; readonly isEthereum: bool; } - /** @name TpContainerChainGenesisDataTokenMetadata (202) */ + /** @name TpContainerChainGenesisDataTokenMetadata (203) */ interface TpContainerChainGenesisDataTokenMetadata extends Struct { readonly tokenSymbol: Bytes; readonly ss58Format: u32; readonly tokenDecimals: u32; } - /** @name PalletConfigurationCall (207) */ + /** @name PalletConfigurationCall (208) */ interface PalletConfigurationCall extends Enum { readonly isSetMaxCollators: boolean; readonly asSetMaxCollators: { @@ -2601,10 +2624,10 @@ declare module "@polkadot/types/lookup" { | "SetBypassConsistencyCheck"; } - /** @name PalletCollatorAssignmentCall (208) */ + /** @name PalletCollatorAssignmentCall (209) */ type PalletCollatorAssignmentCall = Null; - /** @name PalletAuthorNotingCall (209) */ + /** @name PalletAuthorNotingCall (210) */ interface PalletAuthorNotingCall extends Enum { readonly isSetLatestAuthorData: boolean; readonly asSetLatestAuthorData: { @@ -2623,15 +2646,31 @@ declare module "@polkadot/types/lookup" { readonly type: "SetLatestAuthorData" | "SetAuthor" | "KillAuthorData"; } - /** @name TpAuthorNotingInherentOwnParachainInherentData (210) */ + /** @name TpAuthorNotingInherentOwnParachainInherentData (211) */ interface TpAuthorNotingInherentOwnParachainInherentData extends Struct { readonly relayStorageProof: SpTrieStorageProof; } - /** @name PalletAuthorityAssignmentCall (211) */ + /** @name PalletAuthorityAssignmentCall (212) */ type PalletAuthorityAssignmentCall = Null; - /** @name PalletInvulnerablesCall (212) */ + /** @name PalletServicesPaymentCall (213) */ + interface PalletServicesPaymentCall extends Enum { + readonly isPurchaseCredits: boolean; + readonly asPurchaseCredits: { + readonly paraId: u32; + readonly credits: u32; + readonly maxPricePerCredit: Option; + } & Struct; + readonly isSetCredits: boolean; + readonly asSetCredits: { + readonly paraId: u32; + readonly credits: u32; + } & Struct; + readonly type: "PurchaseCredits" | "SetCredits"; + } + + /** @name PalletInvulnerablesCall (215) */ interface PalletInvulnerablesCall extends Enum { readonly isSetInvulnerables: boolean; readonly asSetInvulnerables: { @@ -2648,7 +2687,7 @@ declare module "@polkadot/types/lookup" { readonly type: "SetInvulnerables" | "AddInvulnerable" | "RemoveInvulnerable"; } - /** @name PalletSessionCall (213) */ + /** @name PalletSessionCall (216) */ interface PalletSessionCall extends Enum { readonly isSetKeys: boolean; readonly asSetKeys: { @@ -2659,24 +2698,24 @@ declare module "@polkadot/types/lookup" { readonly type: "SetKeys" | "PurgeKeys"; } - /** @name DanceboxRuntimeSessionKeys (214) */ + /** @name DanceboxRuntimeSessionKeys (217) */ interface DanceboxRuntimeSessionKeys extends Struct { readonly nimbus: NimbusPrimitivesNimbusCryptoPublic; } - /** @name NimbusPrimitivesNimbusCryptoPublic (215) */ + /** @name NimbusPrimitivesNimbusCryptoPublic (218) */ interface NimbusPrimitivesNimbusCryptoPublic extends SpCoreSr25519Public {} - /** @name SpCoreSr25519Public (216) */ + /** @name SpCoreSr25519Public (219) */ interface SpCoreSr25519Public extends U8aFixed {} - /** @name PalletAuthorInherentCall (217) */ + /** @name PalletAuthorInherentCall (220) */ interface PalletAuthorInherentCall extends Enum { readonly isKickOffAuthorshipValidation: boolean; readonly type: "KickOffAuthorshipValidation"; } - /** @name PalletPooledStakingCall (218) */ + /** @name PalletPooledStakingCall (221) */ interface PalletPooledStakingCall extends Enum { readonly isRebalanceHold: boolean; readonly asRebalanceHold: { @@ -2724,7 +2763,7 @@ declare module "@polkadot/types/lookup" { | "SwapPool"; } - /** @name PalletPooledStakingAllTargetPool (219) */ + /** @name PalletPooledStakingAllTargetPool (222) */ interface PalletPooledStakingAllTargetPool extends Enum { readonly isJoining: boolean; readonly isAutoCompounding: boolean; @@ -2733,13 +2772,13 @@ declare module "@polkadot/types/lookup" { readonly type: "Joining" | "AutoCompounding" | "ManualRewards" | "Leaving"; } - /** @name PalletPooledStakingPendingOperationQuery (221) */ + /** @name PalletPooledStakingPendingOperationQuery (224) */ interface PalletPooledStakingPendingOperationQuery extends Struct { readonly delegator: AccountId32; readonly operation: PalletPooledStakingPendingOperationKey; } - /** @name PalletPooledStakingPendingOperationKey (222) */ + /** @name PalletPooledStakingPendingOperationKey (225) */ interface PalletPooledStakingPendingOperationKey extends Enum { readonly isJoiningAutoCompounding: boolean; readonly asJoiningAutoCompounding: { @@ -2759,7 +2798,7 @@ declare module "@polkadot/types/lookup" { readonly type: "JoiningAutoCompounding" | "JoiningManualRewards" | "Leaving"; } - /** @name PalletPooledStakingSharesOrStake (223) */ + /** @name PalletPooledStakingSharesOrStake (226) */ interface PalletPooledStakingSharesOrStake extends Enum { readonly isShares: boolean; readonly asShares: u128; @@ -2768,7 +2807,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Shares" | "Stake"; } - /** @name CumulusPalletXcmpQueueCall (226) */ + /** @name CumulusPalletXcmpQueueCall (229) */ interface CumulusPalletXcmpQueueCall extends Enum { readonly isServiceOverweight: boolean; readonly asServiceOverweight: { @@ -2813,7 +2852,7 @@ declare module "@polkadot/types/lookup" { | "UpdateXcmpMaxIndividualWeight"; } - /** @name CumulusPalletDmpQueueCall (227) */ + /** @name CumulusPalletDmpQueueCall (230) */ interface CumulusPalletDmpQueueCall extends Enum { readonly isServiceOverweight: boolean; readonly asServiceOverweight: { @@ -2823,7 +2862,7 @@ declare module "@polkadot/types/lookup" { readonly type: "ServiceOverweight"; } - /** @name PalletXcmCall (228) */ + /** @name PalletXcmCall (231) */ interface PalletXcmCall extends Enum { readonly isSend: boolean; readonly asSend: { @@ -2900,7 +2939,7 @@ declare module "@polkadot/types/lookup" { | "ForceSuspension"; } - /** @name StagingXcmVersionedXcm (229) */ + /** @name StagingXcmVersionedXcm (232) */ interface StagingXcmVersionedXcm extends Enum { readonly isV2: boolean; readonly asV2: StagingXcmV2Xcm; @@ -2909,10 +2948,10 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3"; } - /** @name StagingXcmV2Xcm (230) */ + /** @name StagingXcmV2Xcm (233) */ interface StagingXcmV2Xcm extends Vec {} - /** @name StagingXcmV2Instruction (232) */ + /** @name StagingXcmV2Instruction (235) */ interface StagingXcmV2Instruction extends Enum { readonly isWithdrawAsset: boolean; readonly asWithdrawAsset: StagingXcmV2MultiassetMultiAssets; @@ -3060,7 +3099,7 @@ declare module "@polkadot/types/lookup" { | "UnsubscribeVersion"; } - /** @name StagingXcmV2Response (233) */ + /** @name StagingXcmV2Response (236) */ interface StagingXcmV2Response extends Enum { readonly isNull: boolean; readonly isAssets: boolean; @@ -3072,7 +3111,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Null" | "Assets" | "ExecutionResult" | "Version"; } - /** @name StagingXcmV2TraitsError (236) */ + /** @name StagingXcmV2TraitsError (239) */ interface StagingXcmV2TraitsError extends Enum { readonly isOverflow: boolean; readonly isUnimplemented: boolean; @@ -3131,7 +3170,7 @@ declare module "@polkadot/types/lookup" { | "WeightNotComputable"; } - /** @name StagingXcmV2MultiassetMultiAssetFilter (237) */ + /** @name StagingXcmV2MultiassetMultiAssetFilter (240) */ interface StagingXcmV2MultiassetMultiAssetFilter extends Enum { readonly isDefinite: boolean; readonly asDefinite: StagingXcmV2MultiassetMultiAssets; @@ -3140,7 +3179,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Definite" | "Wild"; } - /** @name StagingXcmV2MultiassetWildMultiAsset (238) */ + /** @name StagingXcmV2MultiassetWildMultiAsset (241) */ interface StagingXcmV2MultiassetWildMultiAsset extends Enum { readonly isAll: boolean; readonly isAllOf: boolean; @@ -3151,14 +3190,14 @@ declare module "@polkadot/types/lookup" { readonly type: "All" | "AllOf"; } - /** @name StagingXcmV2MultiassetWildFungibility (239) */ + /** @name StagingXcmV2MultiassetWildFungibility (242) */ interface StagingXcmV2MultiassetWildFungibility extends Enum { readonly isFungible: boolean; readonly isNonFungible: boolean; readonly type: "Fungible" | "NonFungible"; } - /** @name StagingXcmV2WeightLimit (240) */ + /** @name StagingXcmV2WeightLimit (243) */ interface StagingXcmV2WeightLimit extends Enum { readonly isUnlimited: boolean; readonly isLimited: boolean; @@ -3166,7 +3205,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Unlimited" | "Limited"; } - /** @name PalletRootTestingCall (249) */ + /** @name PalletRootTestingCall (252) */ interface PalletRootTestingCall extends Enum { readonly isFillBlock: boolean; readonly asFillBlock: { @@ -3175,33 +3214,33 @@ declare module "@polkadot/types/lookup" { readonly type: "FillBlock"; } - /** @name PalletSudoError (251) */ + /** @name PalletSudoError (254) */ interface PalletSudoError extends Enum { readonly isRequireSudo: boolean; readonly type: "RequireSudo"; } - /** @name PalletUtilityError (252) */ + /** @name PalletUtilityError (255) */ interface PalletUtilityError extends Enum { readonly isTooManyCalls: boolean; readonly type: "TooManyCalls"; } - /** @name PalletProxyProxyDefinition (255) */ + /** @name PalletProxyProxyDefinition (258) */ interface PalletProxyProxyDefinition extends Struct { readonly delegate: AccountId32; readonly proxyType: DanceboxRuntimeProxyType; readonly delay: u32; } - /** @name PalletProxyAnnouncement (259) */ + /** @name PalletProxyAnnouncement (262) */ interface PalletProxyAnnouncement extends Struct { readonly real: AccountId32; readonly callHash: H256; readonly height: u32; } - /** @name PalletProxyError (261) */ + /** @name PalletProxyError (264) */ interface PalletProxyError extends Enum { readonly isTooMany: boolean; readonly isNotFound: boolean; @@ -3222,7 +3261,7 @@ declare module "@polkadot/types/lookup" { | "NoSelfProxy"; } - /** @name PalletMigrationsError (262) */ + /** @name PalletMigrationsError (265) */ interface PalletMigrationsError extends Enum { readonly isPreimageMissing: boolean; readonly isWrongUpperBound: boolean; @@ -3231,21 +3270,21 @@ declare module "@polkadot/types/lookup" { readonly type: "PreimageMissing" | "WrongUpperBound" | "PreimageIsTooBig" | "PreimageAlreadyExists"; } - /** @name PalletMaintenanceModeError (263) */ + /** @name PalletMaintenanceModeError (266) */ interface PalletMaintenanceModeError extends Enum { readonly isAlreadyInMaintenanceMode: boolean; readonly isNotInMaintenanceMode: boolean; readonly type: "AlreadyInMaintenanceMode" | "NotInMaintenanceMode"; } - /** @name PalletBalancesBalanceLock (265) */ + /** @name PalletBalancesBalanceLock (268) */ interface PalletBalancesBalanceLock extends Struct { readonly id: U8aFixed; readonly amount: u128; readonly reasons: PalletBalancesReasons; } - /** @name PalletBalancesReasons (266) */ + /** @name PalletBalancesReasons (269) */ interface PalletBalancesReasons extends Enum { readonly isFee: boolean; readonly isMisc: boolean; @@ -3253,25 +3292,25 @@ declare module "@polkadot/types/lookup" { readonly type: "Fee" | "Misc" | "All"; } - /** @name PalletBalancesReserveData (269) */ + /** @name PalletBalancesReserveData (272) */ interface PalletBalancesReserveData extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name DanceboxRuntimeHoldReason (273) */ + /** @name DanceboxRuntimeHoldReason (276) */ interface DanceboxRuntimeHoldReason extends Enum { readonly isPooledStake: boolean; readonly type: "PooledStake"; } - /** @name PalletBalancesIdAmount (276) */ + /** @name PalletBalancesIdAmount (279) */ interface PalletBalancesIdAmount extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name PalletBalancesError (278) */ + /** @name PalletBalancesError (281) */ interface PalletBalancesError extends Enum { readonly isVestingBalance: boolean; readonly isLiquidityRestrictions: boolean; @@ -3296,20 +3335,20 @@ declare module "@polkadot/types/lookup" { | "TooManyFreezes"; } - /** @name PalletTransactionPaymentReleases (280) */ + /** @name PalletTransactionPaymentReleases (283) */ interface PalletTransactionPaymentReleases extends Enum { readonly isV1Ancient: boolean; readonly isV2: boolean; readonly type: "V1Ancient" | "V2"; } - /** @name PalletRegistrarDepositInfo (285) */ + /** @name PalletRegistrarDepositInfo (288) */ interface PalletRegistrarDepositInfo extends Struct { readonly creator: AccountId32; readonly deposit: u128; } - /** @name PalletRegistrarError (286) */ + /** @name PalletRegistrarError (289) */ interface PalletRegistrarError extends Enum { readonly isParaIdAlreadyRegistered: boolean; readonly isParaIdAlreadyPaused: boolean; @@ -3328,7 +3367,7 @@ declare module "@polkadot/types/lookup" { | "NotSufficientDeposit"; } - /** @name PalletConfigurationHostConfiguration (287) */ + /** @name PalletConfigurationHostConfiguration (290) */ interface PalletConfigurationHostConfiguration extends Struct { readonly maxCollators: u32; readonly minOrchestratorCollators: u32; @@ -3337,25 +3376,25 @@ declare module "@polkadot/types/lookup" { readonly fullRotationPeriod: u32; } - /** @name PalletConfigurationError (290) */ + /** @name PalletConfigurationError (293) */ interface PalletConfigurationError extends Enum { readonly isInvalidNewValue: boolean; readonly type: "InvalidNewValue"; } - /** @name TpCollatorAssignmentAssignedCollatorsAccountId32 (291) */ + /** @name TpCollatorAssignmentAssignedCollatorsAccountId32 (294) */ interface TpCollatorAssignmentAssignedCollatorsAccountId32 extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name PalletAuthorNotingContainerChainBlockInfo (296) */ + /** @name PalletAuthorNotingContainerChainBlockInfo (299) */ interface PalletAuthorNotingContainerChainBlockInfo extends Struct { readonly blockNumber: u32; readonly author: AccountId32; } - /** @name PalletAuthorNotingError (297) */ + /** @name PalletAuthorNotingError (300) */ interface PalletAuthorNotingError extends Enum { readonly isFailedReading: boolean; readonly isFailedDecodingHeader: boolean; @@ -3374,13 +3413,21 @@ declare module "@polkadot/types/lookup" { | "NonAuraDigest"; } - /** @name TpCollatorAssignmentAssignedCollatorsPublic (298) */ + /** @name TpCollatorAssignmentAssignedCollatorsPublic (301) */ interface TpCollatorAssignmentAssignedCollatorsPublic extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name PalletInvulnerablesError (304) */ + /** @name PalletServicesPaymentError (306) */ + interface PalletServicesPaymentError extends Enum { + readonly isInsufficientFundsToPurchaseCredits: boolean; + readonly isInsufficientCredits: boolean; + readonly isCreditPriceTooExpensive: boolean; + readonly type: "InsufficientFundsToPurchaseCredits" | "InsufficientCredits" | "CreditPriceTooExpensive"; + } + + /** @name PalletInvulnerablesError (308) */ interface PalletInvulnerablesError extends Enum { readonly isTooManyInvulnerables: boolean; readonly isAlreadyInvulnerable: boolean; @@ -3388,10 +3435,10 @@ declare module "@polkadot/types/lookup" { readonly type: "TooManyInvulnerables" | "AlreadyInvulnerable" | "NotInvulnerable"; } - /** @name SpCoreCryptoKeyTypeId (309) */ + /** @name SpCoreCryptoKeyTypeId (313) */ interface SpCoreCryptoKeyTypeId extends U8aFixed {} - /** @name PalletSessionError (310) */ + /** @name PalletSessionError (314) */ interface PalletSessionError extends Enum { readonly isInvalidProof: boolean; readonly isNoAssociatedValidatorId: boolean; @@ -3401,7 +3448,7 @@ declare module "@polkadot/types/lookup" { readonly type: "InvalidProof" | "NoAssociatedValidatorId" | "DuplicatedKey" | "NoKeys" | "NoAccount"; } - /** @name PalletAuthorInherentError (314) */ + /** @name PalletAuthorInherentError (318) */ interface PalletAuthorInherentError extends Enum { readonly isAuthorAlreadySet: boolean; readonly isNoAccountId: boolean; @@ -3409,13 +3456,13 @@ declare module "@polkadot/types/lookup" { readonly type: "AuthorAlreadySet" | "NoAccountId" | "CannotBeAuthor"; } - /** @name PalletPooledStakingCandidateEligibleCandidate (316) */ + /** @name PalletPooledStakingCandidateEligibleCandidate (320) */ interface PalletPooledStakingCandidateEligibleCandidate extends Struct { readonly candidate: AccountId32; readonly stake: u128; } - /** @name PalletPooledStakingPoolsKey (319) */ + /** @name PalletPooledStakingPoolsKey (323) */ interface PalletPooledStakingPoolsKey extends Enum { readonly isCandidateTotalStake: boolean; readonly isJoiningShares: boolean; @@ -3485,7 +3532,7 @@ declare module "@polkadot/types/lookup" { | "LeavingSharesHeldStake"; } - /** @name PalletPooledStakingError (321) */ + /** @name PalletPooledStakingError (325) */ interface PalletPooledStakingError extends Enum { readonly isInvalidPalletSetting: boolean; readonly isDisabledFeature: boolean; @@ -3519,27 +3566,27 @@ declare module "@polkadot/types/lookup" { | "SwapResultsInZeroShares"; } - /** @name PalletInflationRewardsChainsToRewardValue (322) */ + /** @name PalletInflationRewardsChainsToRewardValue (326) */ interface PalletInflationRewardsChainsToRewardValue extends Struct { readonly paraIds: Vec; readonly rewardsPerChain: u128; } - /** @name CumulusPalletXcmpQueueInboundChannelDetails (324) */ + /** @name CumulusPalletXcmpQueueInboundChannelDetails (328) */ interface CumulusPalletXcmpQueueInboundChannelDetails extends Struct { readonly sender: u32; readonly state: CumulusPalletXcmpQueueInboundState; readonly messageMetadata: Vec>; } - /** @name CumulusPalletXcmpQueueInboundState (325) */ + /** @name CumulusPalletXcmpQueueInboundState (329) */ interface CumulusPalletXcmpQueueInboundState extends Enum { readonly isOk: boolean; readonly isSuspended: boolean; readonly type: "Ok" | "Suspended"; } - /** @name PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat (328) */ + /** @name PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat (332) */ interface PolkadotParachainPrimitivesPrimitivesXcmpMessageFormat extends Enum { readonly isConcatenatedVersionedXcm: boolean; readonly isConcatenatedEncodedBlob: boolean; @@ -3547,7 +3594,7 @@ declare module "@polkadot/types/lookup" { readonly type: "ConcatenatedVersionedXcm" | "ConcatenatedEncodedBlob" | "Signals"; } - /** @name CumulusPalletXcmpQueueOutboundChannelDetails (331) */ + /** @name CumulusPalletXcmpQueueOutboundChannelDetails (335) */ interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct { readonly recipient: u32; readonly state: CumulusPalletXcmpQueueOutboundState; @@ -3556,14 +3603,14 @@ declare module "@polkadot/types/lookup" { readonly lastIndex: u16; } - /** @name CumulusPalletXcmpQueueOutboundState (332) */ + /** @name CumulusPalletXcmpQueueOutboundState (336) */ interface CumulusPalletXcmpQueueOutboundState extends Enum { readonly isOk: boolean; readonly isSuspended: boolean; readonly type: "Ok" | "Suspended"; } - /** @name CumulusPalletXcmpQueueQueueConfigData (334) */ + /** @name CumulusPalletXcmpQueueQueueConfigData (338) */ interface CumulusPalletXcmpQueueQueueConfigData extends Struct { readonly suspendThreshold: u32; readonly dropThreshold: u32; @@ -3573,7 +3620,7 @@ declare module "@polkadot/types/lookup" { readonly xcmpMaxIndividualWeight: SpWeightsWeightV2Weight; } - /** @name CumulusPalletXcmpQueueError (336) */ + /** @name CumulusPalletXcmpQueueError (340) */ interface CumulusPalletXcmpQueueError extends Enum { readonly isFailedToSend: boolean; readonly isBadXcmOrigin: boolean; @@ -3583,29 +3630,29 @@ declare module "@polkadot/types/lookup" { readonly type: "FailedToSend" | "BadXcmOrigin" | "BadXcm" | "BadOverweightIndex" | "WeightOverLimit"; } - /** @name CumulusPalletXcmError (337) */ + /** @name CumulusPalletXcmError (341) */ type CumulusPalletXcmError = Null; - /** @name CumulusPalletDmpQueueConfigData (338) */ + /** @name CumulusPalletDmpQueueConfigData (342) */ interface CumulusPalletDmpQueueConfigData extends Struct { readonly maxIndividual: SpWeightsWeightV2Weight; } - /** @name CumulusPalletDmpQueuePageIndexData (339) */ + /** @name CumulusPalletDmpQueuePageIndexData (343) */ interface CumulusPalletDmpQueuePageIndexData extends Struct { readonly beginUsed: u32; readonly endUsed: u32; readonly overweightCount: u64; } - /** @name CumulusPalletDmpQueueError (342) */ + /** @name CumulusPalletDmpQueueError (346) */ interface CumulusPalletDmpQueueError extends Enum { readonly isUnknown: boolean; readonly isOverLimit: boolean; readonly type: "Unknown" | "OverLimit"; } - /** @name PalletXcmQueryStatus (343) */ + /** @name PalletXcmQueryStatus (347) */ interface PalletXcmQueryStatus extends Enum { readonly isPending: boolean; readonly asPending: { @@ -3627,7 +3674,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Pending" | "VersionNotifier" | "Ready"; } - /** @name StagingXcmVersionedResponse (347) */ + /** @name StagingXcmVersionedResponse (351) */ interface StagingXcmVersionedResponse extends Enum { readonly isV2: boolean; readonly asV2: StagingXcmV2Response; @@ -3636,7 +3683,7 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3"; } - /** @name PalletXcmVersionMigrationStage (353) */ + /** @name PalletXcmVersionMigrationStage (357) */ interface PalletXcmVersionMigrationStage extends Enum { readonly isMigrateSupportedVersion: boolean; readonly isMigrateVersionNotifiers: boolean; @@ -3650,14 +3697,14 @@ declare module "@polkadot/types/lookup" { | "MigrateAndNotifyOldTargets"; } - /** @name StagingXcmVersionedAssetId (355) */ + /** @name StagingXcmVersionedAssetId (359) */ interface StagingXcmVersionedAssetId extends Enum { readonly isV3: boolean; readonly asV3: StagingXcmV3MultiassetAssetId; readonly type: "V3"; } - /** @name PalletXcmRemoteLockedFungibleRecord (356) */ + /** @name PalletXcmRemoteLockedFungibleRecord (360) */ interface PalletXcmRemoteLockedFungibleRecord extends Struct { readonly amount: u128; readonly owner: StagingXcmVersionedMultiLocation; @@ -3665,7 +3712,7 @@ declare module "@polkadot/types/lookup" { readonly consumers: Vec>; } - /** @name PalletXcmError (363) */ + /** @name PalletXcmError (367) */ interface PalletXcmError extends Enum { readonly isUnreachable: boolean; readonly isSendFailure: boolean; @@ -3710,7 +3757,7 @@ declare module "@polkadot/types/lookup" { | "InUse"; } - /** @name SpRuntimeMultiSignature (365) */ + /** @name SpRuntimeMultiSignature (369) */ interface SpRuntimeMultiSignature extends Enum { readonly isEd25519: boolean; readonly asEd25519: SpCoreEd25519Signature; @@ -3721,36 +3768,36 @@ declare module "@polkadot/types/lookup" { readonly type: "Ed25519" | "Sr25519" | "Ecdsa"; } - /** @name SpCoreEd25519Signature (366) */ + /** @name SpCoreEd25519Signature (370) */ interface SpCoreEd25519Signature extends U8aFixed {} - /** @name SpCoreSr25519Signature (368) */ + /** @name SpCoreSr25519Signature (372) */ interface SpCoreSr25519Signature extends U8aFixed {} - /** @name SpCoreEcdsaSignature (369) */ + /** @name SpCoreEcdsaSignature (373) */ interface SpCoreEcdsaSignature extends U8aFixed {} - /** @name FrameSystemExtensionsCheckNonZeroSender (372) */ + /** @name FrameSystemExtensionsCheckNonZeroSender (376) */ type FrameSystemExtensionsCheckNonZeroSender = Null; - /** @name FrameSystemExtensionsCheckSpecVersion (373) */ + /** @name FrameSystemExtensionsCheckSpecVersion (377) */ type FrameSystemExtensionsCheckSpecVersion = Null; - /** @name FrameSystemExtensionsCheckTxVersion (374) */ + /** @name FrameSystemExtensionsCheckTxVersion (378) */ type FrameSystemExtensionsCheckTxVersion = Null; - /** @name FrameSystemExtensionsCheckGenesis (375) */ + /** @name FrameSystemExtensionsCheckGenesis (379) */ type FrameSystemExtensionsCheckGenesis = Null; - /** @name FrameSystemExtensionsCheckNonce (378) */ + /** @name FrameSystemExtensionsCheckNonce (382) */ interface FrameSystemExtensionsCheckNonce extends Compact {} - /** @name FrameSystemExtensionsCheckWeight (379) */ + /** @name FrameSystemExtensionsCheckWeight (383) */ type FrameSystemExtensionsCheckWeight = Null; - /** @name PalletTransactionPaymentChargeTransactionPayment (380) */ + /** @name PalletTransactionPaymentChargeTransactionPayment (384) */ interface PalletTransactionPaymentChargeTransactionPayment extends Compact {} - /** @name DanceboxRuntimeRuntime (381) */ + /** @name DanceboxRuntimeRuntime (385) */ type DanceboxRuntimeRuntime = Null; } // declare module