From f6bb1f9d391eed892c762a861b893084952fccd4 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:33:32 +0200 Subject: [PATCH] Data Preservers Assignments (#563) * add assignments * rust tests * update runtimes and tests * migration * allow owner to stop assignment + prevent deletion of assigned profile * switch to btreesets + remove BootNodes storage * benchmarks * force start/stop assignment, refactor normal/forced operations * local benchmark run * real benchmarks * fix clippy errors * typescript api * clippy * fmt * update some ts tests * fix a couple of things * just in case, bring api-augment * fix test * fix zombienet * ts lint and fmt * put bag genesis config with bootnodes * cargo clippy * Fix zombie parathread tests * migration no longer rely on para managers * fix merge * properly record migration weight * move types in distinct file * move trait in primitives * add ts tests for start/stop assignment * Fix zombienet tests that do not run in CI * remove unused config type + update ts api * remove type in mock --------- Co-authored-by: girazoki Co-authored-by: Tomasz Polaczyk --- client/consensus/src/collators/lookahead.rs | 3 +- client/services-payment/src/lib.rs | 4 +- .../nodes/frontier/src/rpc/mod.rs | 2 +- .../runtime-templates/frontier/src/lib.rs | 13 +- node/src/chain_spec/dancebox.rs | 24 +- node/src/chain_spec/flashbox.rs | 25 +- node/src/container_chain_spawner.rs | 7 +- node/src/service.rs | 3 +- node/src/tests/mod.rs | 3 +- pallets/author-noting/src/benchmarks.rs | 4 +- pallets/data-preservers/Cargo.toml | 5 +- pallets/data-preservers/src/benchmarks.rs | 221 ++- pallets/data-preservers/src/lib.rs | 625 +++++---- pallets/data-preservers/src/mock.rs | 196 ++- pallets/data-preservers/src/tests.rs | 1248 ++++++++++++++--- pallets/data-preservers/src/types.rs | 170 +++ pallets/data-preservers/src/weights.rs | 240 ++-- pallets/invulnerables/src/benchmarking.rs | 2 +- pallets/registrar/runtime-api/src/lib.rs | 3 +- pallets/registrar/src/benchmarks.rs | 3 +- pallets/registrar/src/lib.rs | 4 +- pallets/xcm-core-buyer/src/benchmarks.rs | 8 +- pallets/xcm-core-buyer/src/lib.rs | 11 +- pallets/xcm-core-buyer/src/mock.rs | 13 +- pallets/xcm-core-buyer/src/tests.rs | 9 +- pnpm-lock.yaml | 10 +- primitives/traits/src/lib.rs | 42 +- primitives/xcm-core-buyer/src/lib.rs | 12 +- runtime/common/src/benchmarking.rs | 4 +- runtime/common/src/migrations.rs | 165 ++- runtime/dancebox/Cargo.toml | 5 +- runtime/dancebox/src/lib.rs | 198 ++- .../src/weights/pallet_data_preservers.rs | 142 +- runtime/dancebox/src/xcm_config.rs | 12 +- runtime/dancebox/tests/common/mod.rs | 76 +- .../dancebox/tests/common/xcm/core_buyer.rs | 25 +- runtime/dancebox/tests/integration_test.rs | 533 ++++--- runtime/flashbox/Cargo.toml | 5 +- runtime/flashbox/src/lib.rs | 193 ++- .../src/weights/pallet_data_preservers.rs | 142 +- runtime/flashbox/tests/common/mod.rs | 37 +- runtime/flashbox/tests/integration_test.rs | 463 +++--- test/configs/zombieTanssi.json | 2 +- test/configs/zombieTanssiOneNode.json | 1 - test/moonwall.config.json | 9 +- test/scripts/sudoRegisterPara.ts | 49 +- .../test_pallet_data_preservers.ts | 322 ++++- .../registrar/test_registrar_proxy.ts | 18 +- .../registrar/test_registrar_register.ts | 17 +- .../test_registrar_register_parathread.ts | 19 +- .../test_deregister_with_relay_proof.ts | 16 +- .../test_register_with_relay_proof.ts | 18 +- .../xcm-core-buyer/test_xcm_core_buyer.ts | 18 +- test/suites/one-node/test_tanssi_one_node.ts | 33 +- test/suites/para/test_tanssi_containers.ts | 15 +- .../parathreads/test_tanssi_parathreads.ts | 36 +- .../dancebox/interfaces/augment-api-consts.ts | 4 +- .../dancebox/interfaces/augment-api-errors.ts | 8 + .../dancebox/interfaces/augment-api-events.ts | 2 + .../dancebox/interfaces/augment-api-query.ts | 6 +- .../src/dancebox/interfaces/augment-api-tx.ts | 33 +- .../src/dancebox/interfaces/lookup.ts | 326 +++-- .../src/dancebox/interfaces/registry.ts | 6 + .../src/dancebox/interfaces/types-lookup.ts | 361 +++-- .../flashbox/interfaces/augment-api-consts.ts | 4 +- .../flashbox/interfaces/augment-api-errors.ts | 8 + .../flashbox/interfaces/augment-api-events.ts | 2 + .../flashbox/interfaces/augment-api-query.ts | 20 +- .../src/flashbox/interfaces/augment-api-tx.ts | 33 +- .../src/flashbox/interfaces/lookup.ts | 194 ++- .../src/flashbox/interfaces/registry.ts | 6 + .../src/flashbox/interfaces/types-lookup.ts | 229 +-- 72 files changed, 4828 insertions(+), 1897 deletions(-) create mode 100644 pallets/data-preservers/src/types.rs diff --git a/client/consensus/src/collators/lookahead.rs b/client/consensus/src/collators/lookahead.rs index ba45bbe15..6129ddf79 100644 --- a/client/consensus/src/collators/lookahead.rs +++ b/client/consensus/src/collators/lookahead.rs @@ -205,8 +205,7 @@ where &mut params.overseer_handle, &mut params.relay_client, ) - .await - .get(0) + .await.first() { *core_index } else { diff --git a/client/services-payment/src/lib.rs b/client/services-payment/src/lib.rs index 91e2b0da4..c809afdb5 100644 --- a/client/services-payment/src/lib.rs +++ b/client/services-payment/src/lib.rs @@ -68,7 +68,7 @@ where .client .runtime_api() .block_cost(self.client.usage_info().chain.best_hash, para_id) - .map_err(|e| internal_err(e))?; + .map_err(internal_err)?; Ok(cost) } @@ -77,7 +77,7 @@ where .client .runtime_api() .collator_assignment_cost(self.client.usage_info().chain.best_hash, para_id) - .map_err(|e| internal_err(e))?; + .map_err(internal_err)?; Ok(cost) } } diff --git a/container-chains/nodes/frontier/src/rpc/mod.rs b/container-chains/nodes/frontier/src/rpc/mod.rs index 81247ed67..f918e0880 100644 --- a/container-chains/nodes/frontier/src/rpc/mod.rs +++ b/container-chains/nodes/frontier/src/rpc/mod.rs @@ -23,7 +23,6 @@ pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; -use fc_storage::StorageOverride; use { container_chain_template_frontier_runtime::{opaque::Block, AccountId, Hash, Index}, cumulus_client_parachain_inherent::ParachainInherentData, @@ -31,6 +30,7 @@ use { cumulus_test_relay_sproof_builder::RelayStateSproofBuilder, fc_rpc::{EthTask, TxPool}, fc_rpc_core::TxPoolApiServer, + fc_storage::StorageOverride, fp_rpc::EthereumRuntimeRPCApi, futures::StreamExt, jsonrpsee::RpcModule, diff --git a/container-chains/runtime-templates/frontier/src/lib.rs b/container-chains/runtime-templates/frontier/src/lib.rs index 65e1f51de..d017387f0 100644 --- a/container-chains/runtime-templates/frontier/src/lib.rs +++ b/container-chains/runtime-templates/frontier/src/lib.rs @@ -793,12 +793,13 @@ where let deploy_filter: DeployFilter = AddressList::get(); match deploy_filter { - DeployFilter::All => return Ok(()), + DeployFilter::All => Ok(()), DeployFilter::Whitelisted(addresses_vec) => { if !addresses_vec.contains(address) { - return Err(pallet_evm::Error::::CreateOriginNotAllowed); + Err(pallet_evm::Error::::CreateOriginNotAllowed) + } else { + Ok(()) } - return Ok(()); } } } @@ -1366,7 +1367,7 @@ impl_runtime_apis! { ); // verify initial balance - assert_eq!(Balances::free_balance(&who), balance); + assert_eq!(Balances::free_balance(who), balance); // set up local asset let asset_amount = 10u128; @@ -1386,10 +1387,10 @@ impl_runtime_apis! { let verify = Box::new(move || { // verify native balance after transfer, decreased by transferred fee amount // (plus transport fees) - assert!(Balances::free_balance(&who) <= balance - fee_amount); + assert!(Balances::free_balance(who) <= balance - fee_amount); // verify asset balance decreased by exactly transferred amount assert_eq!( - ForeignAssets::balance(asset_id, &who), + ForeignAssets::balance(asset_id, who), initial_asset_amount - asset_amount, ); }); diff --git a/node/src/chain_spec/dancebox.rs b/node/src/chain_spec/dancebox.rs index 1d1c92671..681f15936 100644 --- a/node/src/chain_spec/dancebox.rs +++ b/node/src/chain_spec/dancebox.rs @@ -200,16 +200,26 @@ fn testnet_genesis( .iter() .map(|(para_id, _genesis_data, _boot_nodes)| (*para_id, 1000, 100).into()) .collect(); - let para_id_boot_nodes: Vec<_> = para_ids + let data_preservers_bootnodes: Vec<_> = para_ids .iter() - .map(|(para_id, _genesis_data, boot_nodes)| (*para_id, boot_nodes.clone())) + .flat_map(|(para_id, _genesis_data, bootnodes)| { + bootnodes.clone().into_iter().map(|bootnode| { + ( + *para_id, + AccountId::from([0u8; 32]), + bootnode, + dancebox_runtime::PreserversAssignementPaymentRequest::Free, + dancebox_runtime::PreserversAssignementPaymentWitness::Free, + ) + }) + }) .collect(); let para_ids: Vec<_> = para_ids .into_iter() .map(|(para_id, genesis_data, _boot_nodes)| (para_id, genesis_data)) .collect(); - let accounts_with_ed = vec![ + let accounts_with_ed = [ dancebox_runtime::StakingAccount::get(), dancebox_runtime::ParachainBondAccount::get(), dancebox_runtime::PendingRewardsAccount::get(), @@ -250,10 +260,6 @@ fn testnet_genesis( }, parachain_system: Default::default(), configuration, - data_preservers: DataPreserversConfig { - para_id_boot_nodes, - ..Default::default() - }, registrar: RegistrarConfig { para_ids }, services_payment: ServicesPaymentConfig { para_id_credits }, sudo: SudoConfig { @@ -271,6 +277,10 @@ fn testnet_genesis( transaction_payment: Default::default(), tx_pause: Default::default(), treasury: Default::default(), + data_preservers: DataPreserversConfig { + bootnodes: data_preservers_bootnodes, + ..Default::default() + }, }; serde_json::to_value(g).unwrap() diff --git a/node/src/chain_spec/flashbox.rs b/node/src/chain_spec/flashbox.rs index 48593555c..c4559a0e6 100644 --- a/node/src/chain_spec/flashbox.rs +++ b/node/src/chain_spec/flashbox.rs @@ -200,16 +200,27 @@ fn testnet_genesis( .iter() .map(|(para_id, _genesis_data, _boot_nodes)| (*para_id, 1000, 100).into()) .collect(); - let para_id_boot_nodes: Vec<_> = para_ids + let data_preservers_bootnodes: Vec<_> = para_ids .iter() - .map(|(para_id, _genesis_data, boot_nodes)| (*para_id, boot_nodes.clone())) + .flat_map(|(para_id, _genesis_data, bootnodes)| { + bootnodes.clone().into_iter().map(|bootnode| { + ( + *para_id, + AccountId::from([0u8; 32]), + bootnode, + flashbox_runtime::PreserversAssignementPaymentRequest::Free, + flashbox_runtime::PreserversAssignementPaymentWitness::Free, + ) + }) + }) .collect(); + let para_ids: Vec<_> = para_ids .into_iter() .map(|(para_id, genesis_data, _boot_nodes)| (para_id, genesis_data)) .collect(); - let accounts_with_ed = vec![ + let accounts_with_ed = [ flashbox_runtime::StakingAccount::get(), flashbox_runtime::ParachainBondAccount::get(), flashbox_runtime::PendingRewardsAccount::get(), @@ -250,10 +261,6 @@ fn testnet_genesis( }, parachain_system: Default::default(), configuration, - data_preservers: DataPreserversConfig { - para_id_boot_nodes, - ..Default::default() - }, registrar: RegistrarConfig { para_ids }, services_payment: ServicesPaymentConfig { para_id_credits }, sudo: SudoConfig { @@ -269,6 +276,10 @@ fn testnet_genesis( transaction_payment: Default::default(), tx_pause: Default::default(), treasury: Default::default(), + data_preservers: DataPreserversConfig { + bootnodes: data_preservers_bootnodes, + ..Default::default() + }, }; serde_json::to_value(g).unwrap() diff --git a/node/src/container_chain_spawner.rs b/node/src/container_chain_spawner.rs index 0ed0c3d57..9eacfe6fc 100644 --- a/node/src/container_chain_spawner.rs +++ b/node/src/container_chain_spawner.rs @@ -800,7 +800,7 @@ fn delete_container_chain_db(db_path: &Path) { let _ = std::fs::remove_dir_all(db_path); // Remove all the empty folders inside `simple_container_2002`, including self if let Some(parent) = db_path.ancestors().nth(2) { - let _ = delete_empty_folders_recursive(parent); + delete_empty_folders_recursive(parent); } } @@ -821,7 +821,7 @@ fn delete_empty_folders_recursive(path: &Path) { let path = entry.path(); if path.is_dir() { - let _ = delete_empty_folders_recursive(&path); + delete_empty_folders_recursive(&path); } } @@ -903,8 +903,7 @@ fn check_paritydb_lock_held(db_path: &Path) -> Result { #[cfg(test)] mod tests { - use super::*; - use std::path::PathBuf; + use {super::*, std::path::PathBuf}; // Copy of ContainerChainSpawner with extra assertions for tests, and mocked spawn function. struct MockContainerChainSpawner { diff --git a/node/src/service.rs b/node/src/service.rs index 042ca5452..b8b10afa3 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -316,7 +316,8 @@ async fn start_node_impl( .base .base .import_params - .wasmtime_precompiled = parachain_config.wasmtime_precompiled.clone(); + .wasmtime_precompiled + .clone_from(¶chain_config.wasmtime_precompiled); } } diff --git a/node/src/tests/mod.rs b/node/src/tests/mod.rs index ebd43bfb4..7ee7160a5 100644 --- a/node/src/tests/mod.rs +++ b/node/src/tests/mod.rs @@ -29,9 +29,8 @@ mod panics; fn create_runner() -> Runner { // tanssi-node args should go here, `--dev` is probably enough let cli = Cli::from_iter(["--dev"]); - let runner = cli.create_runner(&cli.run.normalize()).unwrap(); - runner + cli.create_runner(&cli.run.normalize()).unwrap() } // Nice hack from polkadot-sdk to run a unit test in a separate process. diff --git a/pallets/author-noting/src/benchmarks.rs b/pallets/author-noting/src/benchmarks.rs index b721eae0d..0418ffbfb 100644 --- a/pallets/author-noting/src/benchmarks.rs +++ b/pallets/author-noting/src/benchmarks.rs @@ -88,13 +88,13 @@ benchmarks! { let para_id = 1000.into(); let block_number = 1; let author: T::AccountId = account("account id", 0u32, 0u32); - }: _(RawOrigin::Root, para_id, block_number, author, (block_number as u64).into()) + }: _(RawOrigin::Root, para_id, block_number, author, u64::from(block_number).into()) kill_author_data { let para_id = 1000.into(); let block_number = 1; let author: T::AccountId = account("account id", 0u32, 0u32); - assert_ok!(Pallet::::set_author(RawOrigin::Root.into(), para_id, block_number, author, (block_number as u64).into())); + assert_ok!(Pallet::::set_author(RawOrigin::Root.into(), para_id, block_number, author, u64::from(block_number).into())); }: _(RawOrigin::Root, para_id) impl_benchmark_test_suite!( diff --git a/pallets/data-preservers/Cargo.toml b/pallets/data-preservers/Cargo.toml index 54c06048e..2759234f4 100644 --- a/pallets/data-preservers/Cargo.toml +++ b/pallets/data-preservers/Cargo.toml @@ -16,7 +16,7 @@ workspace = true dp-core = { workspace = true } log = { workspace = true } -serde = { workspace = true, optional = true } +serde = { workspace = true, default-features = false, features = [ "derive" ] } tp-traits = { workspace = true } # Substrate @@ -52,8 +52,7 @@ std = [ "pallet-balances/std", "parity-scale-codec/std", "scale-info/std", - "serde", - "serde?/std", + "serde/std", "sp-core/std", "sp-io/std", "sp-runtime/std", diff --git a/pallets/data-preservers/src/benchmarks.rs b/pallets/data-preservers/src/benchmarks.rs index 867013c26..95560050f 100644 --- a/pallets/data-preservers/src/benchmarks.rs +++ b/pallets/data-preservers/src/benchmarks.rs @@ -19,23 +19,48 @@ //! Benchmarking use { crate::{ - Call, Config, Pallet, ParaIdsFilter, Profile, ProfileDeposit, ProfileMode, Profiles, - RegisteredProfile, + AssignmentPayment, Assignments, Call, Config, Pallet, ParaIdsFilter, Profile, ProfileMode, + Profiles, RegisteredProfile, }, frame_benchmarking::v2::*, frame_support::{ traits::{ fungible::{Inspect, Mutate}, - EnsureOrigin, EnsureOriginWithArg, OriginTrait, + EnsureOrigin, EnsureOriginWithArg, }, - BoundedVec, + BoundedBTreeSet, BoundedVec, }, frame_system::RawOrigin, sp_runtime::traits::Zero, - sp_std::vec, - tp_traits::ParaId, + sp_std::{collections::btree_set::BTreeSet, vec}, + tp_traits::{ParaId, StorageDeposit}, }; +macro_rules! bset { + ( $($value:expr),* $(,)? ) => { + { + let mut set = BoundedBTreeSet::new(); + $( + set.try_insert($value).expect("max bound reached"); + )* + set + } + } +} + +macro_rules! set { + () => { BTreeSet::new() }; + ( $($value:expr),* $(,)? ) => { + { + let mut set = BTreeSet::new(); + $( + set.insert($value); + )* + set + } + } +} + const SEED: u32 = 0; fn create_funded_user(string: &'static str, n: u32, balance_factor: u32) -> T::AccountId @@ -54,41 +79,24 @@ where mod benchmarks { use super::*; - #[benchmark] - fn set_boot_nodes(x: Linear<1, 200>, y: Linear<1, 10>) { - // x: url len, y: num boot_nodes - let boot_nodes = BoundedVec::try_from(vec![ - BoundedVec::try_from(vec![b'A'; x as usize]) - .unwrap(); - y as usize - ]) - .unwrap(); - let para_id = ParaId::from(2); - let origin = T::SetBootNodesOrigin::try_successful_origin(¶_id) - .expect("failed to create SetBootNodesOrigin"); - // Worst case is when caller is not root - let raw_origin = origin.as_system_ref(); - assert!(matches!(raw_origin, Some(RawOrigin::Signed(..)))); - - #[extrinsic_call] - Pallet::::set_boot_nodes(origin as T::RuntimeOrigin, para_id, boot_nodes.clone()); - - assert_eq!(Pallet::::boot_nodes(para_id), boot_nodes); - } - #[benchmark] fn create_profile(x: Linear<1, 200>, y: Linear<1, 10>) { // x: url len, y: para ids len let url = BoundedVec::try_from(vec![b'A'; x as usize]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(42); y as usize]).unwrap(); + + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..y { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; - let deposit = T::ProfileDeposit::profile_deposit(&profile).expect("deposit to be computed"); + let deposit = T::ProfileDeposit::compute_deposit(&profile).expect("deposit to be computed"); let caller = create_funded_user::("caller", 1, 1_000_000_000u32); @@ -100,7 +108,8 @@ mod benchmarks { Some(RegisteredProfile { account: caller, deposit, - profile + profile, + assignment: None, }) ); } @@ -109,12 +118,16 @@ mod benchmarks { fn force_create_profile(x: Linear<1, 200>, y: Linear<1, 10>) { // x: url len, y: para ids len let url = BoundedVec::try_from(vec![b'A'; x as usize]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(42); y as usize]).unwrap(); + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..y { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; let owner = create_funded_user::("owner", 1, 1_000_000_000u32); @@ -133,7 +146,8 @@ mod benchmarks { Some(RegisteredProfile { account: owner, deposit: 0u32.into(), - profile + profile, + assignment: None, }) ); } @@ -141,12 +155,16 @@ mod benchmarks { #[benchmark] fn update_profile(x: Linear<1, 200>, y: Linear<1, 10>) { let url = BoundedVec::try_from(vec![b'A'; 10]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(42); 2]).unwrap(); + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..2 { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; let caller = create_funded_user::("caller", 1, 1_000_000_000u32); @@ -156,15 +174,19 @@ mod benchmarks { // x: url len, y: para ids len let url = BoundedVec::try_from(vec![b'B'; x as usize]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(43); y as usize]).unwrap(); + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..y { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; - let deposit = T::ProfileDeposit::profile_deposit(&profile).expect("deposit to be computed"); + let deposit = T::ProfileDeposit::compute_deposit(&profile).expect("deposit to be computed"); #[extrinsic_call] Pallet::::update_profile( @@ -178,7 +200,8 @@ mod benchmarks { Some(RegisteredProfile { account: caller, deposit, - profile + profile, + assignment: None, }) ); } @@ -186,12 +209,16 @@ mod benchmarks { #[benchmark] fn force_update_profile(x: Linear<1, 200>, y: Linear<1, 10>) { let url = BoundedVec::try_from(vec![b'A'; 10]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(42); 2]).unwrap(); + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..2 { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; let caller = create_funded_user::("caller", 1, 1_000_000_000u32); @@ -201,12 +228,16 @@ mod benchmarks { // x: url len, y: para ids len let url = BoundedVec::try_from(vec![b'B'; x as usize]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(43); y as usize]).unwrap(); + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..y { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; let origin_force = T::ForceSetProfileOrigin::try_successful_origin() @@ -224,7 +255,8 @@ mod benchmarks { Some(RegisteredProfile { account: caller, deposit: 0u32.into(), - profile + profile, + assignment: None, }) ); } @@ -232,12 +264,16 @@ mod benchmarks { #[benchmark] fn delete_profile() { let url = BoundedVec::try_from(vec![b'A'; 10]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(42); 2]).unwrap(); + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..2 { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; let caller = create_funded_user::("caller", 1, 1_000_000_000u32); @@ -254,12 +290,16 @@ mod benchmarks { #[benchmark] fn force_delete_profile() { let url = BoundedVec::try_from(vec![b'A'; 10]).unwrap(); - let para_ids = BoundedVec::try_from(vec![ParaId::from(42); 2]).unwrap(); + let mut para_ids = BoundedBTreeSet::new(); + for i in 0..2 { + para_ids.try_insert(ParaId::from(i)).unwrap(); + } let profile = Profile { url, para_ids: ParaIdsFilter::Whitelist(para_ids), mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), }; let caller = create_funded_user::("caller", 1, 1_000_000_000u32); @@ -276,6 +316,103 @@ mod benchmarks { assert_eq!(Profiles::::get(T::ProfileId::zero()), None); } + #[benchmark] + fn start_assignment() { + let url = BoundedVec::try_from(vec![b'A'; 10]).unwrap(); + let para_id = ParaId::from(42); + + let profile = Profile { + url, + para_ids: ParaIdsFilter::Whitelist(bset![para_id]), + mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), + }; + + let caller = create_funded_user::("caller", 1, 1_000_000_000u32); + + Pallet::::create_profile(RawOrigin::Signed(caller.clone()).into(), profile) + .expect("to create profile"); + + let origin = T::AssignmentOrigin::try_successful_origin(¶_id).unwrap(); + + #[extrinsic_call] + Pallet::::start_assignment( + origin as T::RuntimeOrigin, + T::ProfileId::zero(), + para_id, + T::AssignmentPayment::benchmark_assigner_parameter(), + ); + + assert_eq!( + Assignments::::get(para_id).into_inner(), + set![T::ProfileId::zero()] + ); + } + + #[benchmark] + fn stop_assignment() { + let url = BoundedVec::try_from(vec![b'A'; 10]).unwrap(); + let para_id = ParaId::from(42); + + let profile = Profile { + url, + para_ids: ParaIdsFilter::Whitelist(bset![para_id]), + mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), + }; + + let caller = create_funded_user::("caller", 1, 1_000_000_000u32); + + Pallet::::create_profile(RawOrigin::Signed(caller.clone()).into(), profile) + .expect("to create profile"); + + let origin = T::AssignmentOrigin::try_successful_origin(¶_id).unwrap(); + + Pallet::::start_assignment( + origin.clone() as T::RuntimeOrigin, + T::ProfileId::zero(), + para_id, + T::AssignmentPayment::benchmark_assigner_parameter(), + ) + .expect("to assign"); + + #[extrinsic_call] + Pallet::::stop_assignment(origin as T::RuntimeOrigin, T::ProfileId::zero(), para_id); + + assert_eq!(Assignments::::get(para_id).into_inner(), set![]); + } + + #[benchmark] + fn force_start_assignment() { + let url = BoundedVec::try_from(vec![b'A'; 10]).unwrap(); + let para_id = ParaId::from(42); + + let profile = Profile { + url, + para_ids: ParaIdsFilter::Whitelist(bset![para_id]), + mode: ProfileMode::Bootnode, + assignment_request: T::AssignmentPayment::benchmark_provider_request(), + }; + + let caller = create_funded_user::("caller", 1, 1_000_000_000u32); + + Pallet::::create_profile(RawOrigin::Signed(caller.clone()).into(), profile) + .expect("to create profile"); + + #[extrinsic_call] + Pallet::::force_start_assignment( + RawOrigin::Root, + T::ProfileId::zero(), + para_id, + T::AssignmentPayment::benchmark_assignment_witness(), + ); + + assert_eq!( + Assignments::::get(para_id).into_inner(), + set![T::ProfileId::zero()] + ); + } + impl_benchmark_test_suite!( Pallet, crate::mock::ExtBuilder::default().build(), diff --git a/pallets/data-preservers/src/lib.rs b/pallets/data-preservers/src/lib.rs index 8b9f9608c..983fd0adb 100644 --- a/pallets/data-preservers/src/lib.rs +++ b/pallets/data-preservers/src/lib.rs @@ -20,7 +20,9 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub use pallet::*; +mod types; + +pub use {pallet::*, types::*}; #[cfg(test)] mod mock; @@ -30,12 +32,10 @@ mod tests; #[cfg(any(test, feature = "runtime-benchmarks"))] mod benchmarks; + pub mod weights; pub use weights::WeightInfo; -#[cfg(feature = "std")] -use serde::{Deserialize, Serialize}; - use { core::fmt::Debug, dp_core::ParaId, @@ -45,53 +45,79 @@ use { traits::{ fungible::{Balanced, Inspect, MutateHold}, tokens::Precision, - EnsureOriginWithArg, + EitherOfDiverse, EnsureOriginWithArg, }, DefaultNoBound, }, - frame_system::pallet_prelude::*, + frame_system::{pallet_prelude::*, EnsureRoot, EnsureSigned}, parity_scale_codec::FullCodec, sp_runtime::{ - traits::{CheckedAdd, CheckedMul, CheckedSub, Get, One, Zero}, - ArithmeticError, + traits::{CheckedAdd, CheckedSub, Get, One, Zero}, + ArithmeticError, Either, }, sp_std::vec::Vec, + tp_traits::StorageDeposit, }; #[frame_support::pallet] pub mod pallet { use super::*; + /// Balance used by this pallet + pub type BalanceOf = + <::Currency as Inspect<::AccountId>>::Balance; + + pub type ProviderRequestOf = <::AssignmentPayment as AssignmentPayment< + ::AccountId, + >>::ProviderRequest; + + pub type AssignerParameterOf = <::AssignmentPayment as AssignmentPayment< + ::AccountId, + >>::AssignerParameter; + + pub type AssignmentWitnessOf = <::AssignmentPayment as AssignmentPayment< + ::AccountId, + >>::AssignmentWitness; + #[pallet::genesis_config] #[derive(DefaultNoBound)] pub struct GenesisConfig { - /// Para ids - pub para_id_boot_nodes: Vec<(ParaId, Vec>)>, + pub bootnodes: Vec<( + // ParaId the profile will be assigned to + ParaId, + // Owner of the profile + T::AccountId, + // URL of the bootnode + Vec, + // Assignment request + ProviderRequestOf, + // Assignment witness (try_start_assignment is skipped) + AssignmentWitnessOf, + )>, + #[serde(skip)] pub _phantom: PhantomData, } #[pallet::genesis_build] impl BuildGenesisConfig for GenesisConfig { fn build(&self) { - // Sort para ids and detect duplicates, but do it using a vector of - // references to avoid cloning the boot nodes. - let mut para_ids: Vec<&_> = self.para_id_boot_nodes.iter().collect(); - para_ids.sort_by(|a, b| a.0.cmp(&b.0)); - para_ids.dedup_by(|a, b| { - if a.0 == b.0 { - panic!("Duplicate para_id: {}", u32::from(a.0)); - } else { - false - } - }); - - for (para_id, boot_nodes) in para_ids { - let boot_nodes: Vec<_> = boot_nodes - .iter() - .map(|x| BoundedVec::try_from(x.clone()).expect("boot node url too long")) - .collect(); - let boot_nodes = BoundedVec::try_from(boot_nodes).expect("too many boot nodes"); - >::insert(para_id, boot_nodes); + for (para_id, profile_owner, url, request, witness) in self.bootnodes.clone() { + let profile = Profile { + url: url.try_into().expect("should fit in BoundedVec"), + para_ids: ParaIdsFilter::Whitelist({ + let mut set = BoundedBTreeSet::new(); + set.try_insert(para_id).expect("to fit in BoundedBTreeSet"); + set + }), + mode: ProfileMode::Bootnode, + assignment_request: request, + }; + + let profile_id = NextProfileId::::get(); + Pallet::::do_create_profile(profile, profile_owner, Zero::zero()) + .expect("to create profile"); + Pallet::::do_start_assignment(profile_id, para_id, |_| Ok(witness)) + .expect("to start assignment"); } } } @@ -120,22 +146,30 @@ pub mod pallet { + Debug + Eq + CheckedAdd - + One; + + One + + Ord; - // Who can call set_boot_nodes? - type SetBootNodesOrigin: EnsureOriginWithArg; + // Who can call start_assignment/stop_assignment? + type AssignmentOrigin: EnsureOriginWithArg< + Self::RuntimeOrigin, + ParaId, + Success = Self::AccountId, + >; + // Who can call force_X? type ForceSetProfileOrigin: EnsureOrigin; #[pallet::constant] - type MaxBootNodes: Get; + type MaxAssignmentsPerParaId: Get + Clone; #[pallet::constant] - type MaxBootNodeUrlLen: Get; + type MaxNodeUrlLen: Get + Clone; #[pallet::constant] - type MaxParaIdsVecLen: Get; + type MaxParaIdsVecLen: Get + Clone; /// How much must be deposited to register a profile. - type ProfileDeposit: ProfileDeposit, BalanceOf>; + type ProfileDeposit: StorageDeposit, BalanceOf>; + + type AssignmentPayment: AssignmentPayment; type WeightInfo: WeightInfo; } @@ -159,6 +193,14 @@ pub mod pallet { profile_id: T::ProfileId, released_deposit: BalanceOf, }, + AssignmentStarted { + profile_id: T::ProfileId, + para_id: ParaId, + }, + AssignmentStopped { + profile_id: T::ProfileId, + para_id: ParaId, + }, } #[pallet::error] @@ -168,6 +210,17 @@ pub mod pallet { UnknownProfileId, NextProfileIdShouldBeAvailable, + + /// Made for `AssignmentPayment` implementors to report a mismatch between + /// `ProviderRequest` and `AssignerParameter`. + AssignmentPaymentRequestParameterMismatch, + + ProfileAlreadyAssigned, + ProfileNotAssigned, + ProfileIsNotElligibleForParaId, + WrongParaId, + MaxAssignmentsPerParaIdReached, + CantDeleteAssignedProfile, } #[pallet::composite_enum] @@ -175,16 +228,6 @@ pub mod pallet { ProfileDeposit, } - #[pallet::storage] - #[pallet::getter(fn boot_nodes)] - pub type BootNodes = StorageMap< - _, - Blake2_128Concat, - ParaId, - BoundedVec, T::MaxBootNodes>, - ValueQuery, - >; - #[pallet::storage] pub type Profiles = StorageMap<_, Blake2_128Concat, T::ProfileId, RegisteredProfile, OptionQuery>; @@ -192,119 +235,17 @@ pub mod pallet { #[pallet::storage] pub type NextProfileId = StorageValue<_, T::ProfileId, ValueQuery>; - /// Balance used by this pallet - pub type BalanceOf = - <::Currency as Inspect<::AccountId>>::Balance; - - /// Data preserver profile. - #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] - #[derive( - RuntimeDebugNoBound, PartialEqNoBound, EqNoBound, Encode, Decode, CloneNoBound, TypeInfo, - )] - #[scale_info(skip_type_params(T))] - pub struct Profile { - pub url: BoundedVec, - pub para_ids: ParaIdsFilter, - pub mode: ProfileMode, - } - - #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] - #[derive( - RuntimeDebugNoBound, PartialEqNoBound, EqNoBound, Encode, Decode, CloneNoBound, TypeInfo, - )] - #[scale_info(skip_type_params(T))] - pub enum ParaIdsFilter { - AnyParaId, - Whitelist(BoundedVec), - Blacklist(BoundedVec), - } - - impl ParaIdsFilter { - pub fn len(&self) -> usize { - match self { - Self::AnyParaId => 0, - Self::Whitelist(list) | Self::Blacklist(list) => list.len(), - } - } - } - - #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] - #[derive(RuntimeDebug, PartialEq, Eq, Encode, Decode, Clone, TypeInfo)] - pub enum ProfileMode { - Bootnode, - Rpc { supports_ethereum_rpcs: bool }, - } - - /// Profile with additional data: - /// - the account id which created (and manage) the profile - /// - the amount deposited to register the profile - #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] - #[derive( - RuntimeDebugNoBound, PartialEqNoBound, EqNoBound, Encode, Decode, CloneNoBound, TypeInfo, - )] - #[scale_info(skip_type_params(T))] - pub struct RegisteredProfile { - pub account: T::AccountId, - pub deposit: BalanceOf, - pub profile: Profile, - } - - /// Computes the deposit cost of a profile. - pub trait ProfileDeposit { - fn profile_deposit(profile: &Profile) -> Result; - } - - /// Implementation of `ProfileDeposit` based on the size of the SCALE-encoding. - pub struct BytesProfileDeposit(PhantomData<(BaseCost, ByteCost)>); - - impl ProfileDeposit - for BytesProfileDeposit - where - BaseCost: Get, - ByteCost: Get, - Profile: Encode, - Balance: TryFrom + CheckedAdd + CheckedMul, - { - fn profile_deposit(profile: &Profile) -> Result { - let base = BaseCost::get(); - let byte = ByteCost::get(); - let size: Balance = profile - .encoded_size() - .try_into() - .map_err(|_| ArithmeticError::Overflow)?; - - let deposit = byte - .checked_mul(&size) - .ok_or(ArithmeticError::Overflow)? - .checked_add(&base) - .ok_or(ArithmeticError::Overflow)?; - - Ok(deposit) - } - } + #[pallet::storage] + pub type Assignments = StorageMap< + _, + Blake2_128Concat, + ParaId, + BoundedBTreeSet, + ValueQuery, + >; #[pallet::call] impl Pallet { - /// Set boot_nodes for this para id - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::set_boot_nodes( - T::MaxBootNodeUrlLen::get(), - boot_nodes.len() as u32, - ))] - pub fn set_boot_nodes( - origin: OriginFor, - para_id: ParaId, - boot_nodes: BoundedVec, T::MaxBootNodes>, - ) -> DispatchResult { - T::SetBootNodesOrigin::ensure_origin(origin, ¶_id)?; - - BootNodes::::insert(para_id, boot_nodes); - - Self::deposit_event(Event::BootNodesChanged { para_id }); - - Ok(()) - } - #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::create_profile( profile.url.len() as u32, @@ -316,36 +257,10 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let account = ensure_signed(origin)?; - let deposit = T::ProfileDeposit::profile_deposit(&profile)?; + let deposit = T::ProfileDeposit::compute_deposit(&profile)?; T::Currency::hold(&HoldReason::ProfileDeposit.into(), &account, deposit)?; - let id = NextProfileId::::get(); - NextProfileId::::set( - id.checked_add(&One::one()) - .ok_or(ArithmeticError::Overflow)?, - ); - - ensure!( - !Profiles::::contains_key(id), - Error::::NextProfileIdShouldBeAvailable - ); - - Profiles::::insert( - id, - RegisteredProfile { - account: account.clone(), - deposit, - profile, - }, - ); - - Self::deposit_event(Event::ProfileCreated { - account, - profile_id: id, - deposit, - }); - - Ok(().into()) + Self::do_create_profile(profile, account, deposit) } #[pallet::call_index(2)] @@ -360,98 +275,198 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let account = ensure_signed(origin)?; - let Some(existing_profile) = Profiles::::get(profile_id) else { - Err(Error::::UnknownProfileId)? - }; + let new_deposit = T::ProfileDeposit::compute_deposit(&profile)?; + + Self::do_update_profile(profile_id, profile, |existing_profile| { + ensure!( + existing_profile.account == account, + sp_runtime::DispatchError::BadOrigin, + ); + + if let Some(diff) = new_deposit.checked_sub(&existing_profile.deposit) { + T::Currency::hold( + &HoldReason::ProfileDeposit.into(), + &existing_profile.account, + diff, + )?; + } else if let Some(diff) = existing_profile.deposit.checked_sub(&new_deposit) { + T::Currency::release( + &HoldReason::ProfileDeposit.into(), + &existing_profile.account, + diff, + Precision::Exact, + )?; + } - ensure!( - existing_profile.account == account, - sp_runtime::DispatchError::BadOrigin, - ); + Ok(new_deposit) + }) + } + + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::delete_profile())] + pub fn delete_profile( + origin: OriginFor, + profile_id: T::ProfileId, + ) -> DispatchResultWithPostInfo { + let account = ensure_signed(origin)?; - // Update deposit - let new_deposit = T::ProfileDeposit::profile_deposit(&profile)?; + Self::do_delete_profile(profile_id, |profile| { + ensure!( + profile.account == account, + sp_runtime::DispatchError::BadOrigin, + ); - if let Some(diff) = new_deposit.checked_sub(&existing_profile.deposit) { - T::Currency::hold( - &HoldReason::ProfileDeposit.into(), - &existing_profile.account, - diff, - )?; - } else if let Some(diff) = existing_profile.deposit.checked_sub(&new_deposit) { + Ok(().into()) + }) + } + + #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::force_create_profile( + profile.url.len() as u32, + profile.para_ids.len() as u32, + ))] + pub fn force_create_profile( + origin: OriginFor, + profile: Profile, + for_account: T::AccountId, + ) -> DispatchResultWithPostInfo { + T::ForceSetProfileOrigin::ensure_origin(origin)?; + + Self::do_create_profile(profile, for_account, Zero::zero()) + } + + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::force_update_profile( + profile.url.len() as u32, + profile.para_ids.len() as u32, + ))] + pub fn force_update_profile( + origin: OriginFor, + profile_id: T::ProfileId, + profile: Profile, + ) -> DispatchResultWithPostInfo { + T::ForceSetProfileOrigin::ensure_origin(origin)?; + + Self::do_update_profile(profile_id, profile, |existing_profile| { + // We release the previous deposit T::Currency::release( &HoldReason::ProfileDeposit.into(), &existing_profile.account, - diff, + existing_profile.deposit, Precision::Exact, )?; - } - Profiles::::insert( - profile_id, - RegisteredProfile { - account: existing_profile.account, - deposit: new_deposit, - profile, - }, - ); + // New deposit is zero since its forced + Ok(Zero::zero()) + }) + } - Self::deposit_event(Event::ProfileUpdated { - profile_id, - old_deposit: existing_profile.deposit, - new_deposit, - }); + #[pallet::call_index(6)] + #[pallet::weight(T::WeightInfo::force_delete_profile())] + pub fn force_delete_profile( + origin: OriginFor, + profile_id: T::ProfileId, + ) -> DispatchResultWithPostInfo { + T::ForceSetProfileOrigin::ensure_origin(origin)?; - Ok(().into()) + Self::do_delete_profile(profile_id, |_| Ok(().into())) } - #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::delete_profile())] - pub fn delete_profile( + #[pallet::call_index(7)] + #[pallet::weight(T::WeightInfo::start_assignment())] + pub fn start_assignment( origin: OriginFor, profile_id: T::ProfileId, + para_id: ParaId, + assigner_param: AssignerParameterOf, ) -> DispatchResultWithPostInfo { - let account = ensure_signed(origin)?; + let assigner = T::AssignmentOrigin::ensure_origin(origin, ¶_id)?; + + Self::do_start_assignment(profile_id, para_id, |profile| { + T::AssignmentPayment::try_start_assignment( + assigner, + profile.account.clone(), + &profile.profile.assignment_request, + assigner_param, + ) + }) + } - let Some(profile) = Profiles::::get(profile_id) else { - Err(Error::::UnknownProfileId)? + #[pallet::call_index(8)] + #[pallet::weight(T::WeightInfo::stop_assignment())] + pub fn stop_assignment( + origin: OriginFor, + profile_id: T::ProfileId, + para_id: ParaId, + ) -> DispatchResultWithPostInfo { + let caller = EitherOfDiverse::< + // root or para manager can call without being the owner + EitherOfDiverse>, + // otherwise it can be a simple signed account but it will require + // cheking if it is the owner of the profile + EnsureSigned, + >::ensure_origin(origin, ¶_id)?; + + let mut profile = Profiles::::get(profile_id).ok_or(Error::::UnknownProfileId)?; + + match caller { + // root or para id manager is allowed to call + Either::Left(_) => (), + // signed, must be profile owner + Either::Right(account) => ensure!( + profile.account == account, + sp_runtime::DispatchError::BadOrigin + ), + } + + let Some((assignment_para_id, assignment_witness)) = profile.assignment.take() else { + Err(Error::::ProfileNotAssigned)? }; - ensure!( - profile.account == account, - sp_runtime::DispatchError::BadOrigin, - ); + if assignment_para_id != para_id { + Err(Error::::WrongParaId)? + } - T::Currency::release( - &HoldReason::ProfileDeposit.into(), - &profile.account, - profile.deposit, - Precision::Exact, - )?; + T::AssignmentPayment::try_stop_assignment(profile.account.clone(), assignment_witness)?; - Profiles::::remove(profile_id); + Profiles::::insert(profile_id, profile); - Self::deposit_event(Event::ProfileDeleted { + { + let mut assignments = Assignments::::get(para_id); + assignments.remove(&profile_id); + Assignments::::insert(para_id, assignments); + } + + Self::deposit_event(Event::AssignmentStopped { profile_id, - released_deposit: profile.deposit, + para_id, }); Ok(().into()) } - #[pallet::call_index(4)] - #[pallet::weight(T::WeightInfo::force_create_profile( - profile.url.len() as u32, - profile.para_ids.len() as u32, - ))] - pub fn force_create_profile( + #[pallet::call_index(9)] + #[pallet::weight(T::WeightInfo::force_start_assignment())] + pub fn force_start_assignment( origin: OriginFor, - profile: Profile, - for_account: T::AccountId, + profile_id: T::ProfileId, + para_id: ParaId, + assignment_witness: AssignmentWitnessOf, ) -> DispatchResultWithPostInfo { - T::ForceSetProfileOrigin::ensure_origin(origin)?; + ensure_root(origin)?; + Self::do_start_assignment(profile_id, para_id, |_profile| Ok(assignment_witness)) + } + } + + impl Pallet { + fn do_create_profile( + profile: Profile, + account: T::AccountId, + deposit: BalanceOf, + ) -> DispatchResultWithPostInfo { let id = NextProfileId::::get(); + NextProfileId::::set( id.checked_add(&One::one()) .ok_or(ArithmeticError::Overflow)?, @@ -465,75 +480,68 @@ pub mod pallet { Profiles::::insert( id, RegisteredProfile { - account: for_account.clone(), - deposit: Zero::zero(), + account: account.clone(), + deposit, profile, + assignment: None, }, ); Self::deposit_event(Event::ProfileCreated { - account: for_account, + account, profile_id: id, - deposit: Zero::zero(), + deposit, }); Ok(().into()) } - #[pallet::call_index(5)] - #[pallet::weight(T::WeightInfo::force_update_profile( - profile.url.len() as u32, - profile.para_ids.len() as u32, - ))] - pub fn force_update_profile( - origin: OriginFor, + fn do_update_profile( profile_id: T::ProfileId, - profile: Profile, + new_profile: Profile, + update_deposit: impl FnOnce( + &RegisteredProfile, + ) -> Result, DispatchErrorWithPostInfo>, ) -> DispatchResultWithPostInfo { - T::ForceSetProfileOrigin::ensure_origin(origin)?; - let Some(existing_profile) = Profiles::::get(profile_id) else { Err(Error::::UnknownProfileId)? }; - // We release the previous deposit - T::Currency::release( - &HoldReason::ProfileDeposit.into(), - &existing_profile.account, - existing_profile.deposit, - Precision::Exact, - )?; + let new_deposit = update_deposit(&existing_profile)?; Profiles::::insert( profile_id, RegisteredProfile { - account: existing_profile.account, - deposit: Zero::zero(), - profile, + deposit: new_deposit, + profile: new_profile, + ..existing_profile }, ); Self::deposit_event(Event::ProfileUpdated { profile_id, old_deposit: existing_profile.deposit, - new_deposit: Zero::zero(), + new_deposit, }); Ok(().into()) } - #[pallet::call_index(6)] - #[pallet::weight(T::WeightInfo::force_delete_profile())] - pub fn force_delete_profile( - origin: OriginFor, + fn do_delete_profile( profile_id: T::ProfileId, + profile_owner_check: impl FnOnce(&RegisteredProfile) -> DispatchResultWithPostInfo, ) -> DispatchResultWithPostInfo { - T::ForceSetProfileOrigin::ensure_origin(origin)?; - let Some(profile) = Profiles::::get(profile_id) else { Err(Error::::UnknownProfileId)? }; + ensure!( + profile.assignment.is_none(), + Error::::CantDeleteAssignedProfile, + ); + + profile_owner_check(&profile)?; + T::Currency::release( &HoldReason::ProfileDeposit.into(), &profile.account, @@ -550,22 +558,71 @@ pub mod pallet { Ok(().into()) } - } - impl Pallet { - /// Function that will be called when a container chain is deregistered. Cleans up all the storage related to this para_id. + fn do_start_assignment( + profile_id: T::ProfileId, + para_id: ParaId, + witness_producer: impl FnOnce( + &RegisteredProfile, + ) + -> Result, DispatchErrorWithPostInfo>, + ) -> DispatchResultWithPostInfo { + let mut profile = Profiles::::get(profile_id).ok_or(Error::::UnknownProfileId)?; + + if profile.assignment.is_some() { + Err(Error::::ProfileAlreadyAssigned)? + } + + if !profile.profile.para_ids.can_assign(¶_id) { + Err(Error::::ProfileIsNotElligibleForParaId)? + } + + // Add profile id to BoundedVec early in case bound is reached + { + let mut assignments = Assignments::::get(para_id); + + assignments + .try_insert(profile_id) + .map_err(|_| Error::::MaxAssignmentsPerParaIdReached)?; + + Assignments::::insert(para_id, assignments); + } + + let witness = witness_producer(&profile)?; + + profile.assignment = Some((para_id, witness)); + Profiles::::insert(profile_id, profile); + + Self::deposit_event(Event::AssignmentStarted { + profile_id, + para_id, + }); + + Ok(().into()) + } + + pub fn assignments_profiles(para_id: ParaId) -> impl Iterator> { + Assignments::::get(para_id) + .into_iter() + .filter_map(Profiles::::get) + .map(|profile| profile.profile) + } + + /// Function that will be called when a container chain is deregistered. Cleans up all the + /// storage related to this para_id. /// Cannot fail. pub fn para_deregistered(para_id: ParaId) { - BootNodes::::remove(para_id); + Assignments::::remove(para_id); } pub fn check_valid_for_collating(para_id: ParaId) -> DispatchResult { - // To be able to call mark_valid_for_collating, a container chain must have bootnodes - if Pallet::::boot_nodes(para_id).len() > 0 { - Ok(()) - } else { - Err(Error::::NoBootNodes.into()) + if !Self::assignments_profiles(para_id) + .any(|profile| profile.mode == ProfileMode::Bootnode) + { + Err(Error::::NoBootNodes)? } + + Ok(()) } } } diff --git a/pallets/data-preservers/src/mock.rs b/pallets/data-preservers/src/mock.rs index c6e2547b2..26cc38223 100644 --- a/pallets/data-preservers/src/mock.rs +++ b/pallets/data-preservers/src/mock.rs @@ -18,11 +18,13 @@ use { crate::{self as pallet_data_preservers}, dp_core::ParaId, frame_support::{ + dispatch::DispatchErrorWithPostInfo, pallet_prelude::*, parameter_types, traits::{ConstU128, ConstU64, EitherOfDiverse, EnsureOriginWithArg, Everything}, }, frame_system::{EnsureRoot, EnsureSigned, RawOrigin}, + serde::{Deserialize, Serialize}, sp_core::H256, sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, @@ -219,17 +221,203 @@ where } } +pub struct MockContainerChainManager { + _phantom: PhantomData, +} + +impl EnsureOriginWithArg for MockContainerChainManager +where + T: crate::Config, + O: From>, + Result, O>: From, + u64: From, + T::AccountId: From, + O: Clone, +{ + type Success = T::AccountId; + + fn try_origin(o: O, para_id: &ParaId) -> Result { + let origin = as EnsureOriginWithArg>::try_origin( + o.clone(), + para_id, + )?; + + // This check will only pass if both are true: + // * The para_id has a deposit in pallet_registrar + // * The deposit creator is the signed_account + MockData::get() + .container_chain_managers + .get(para_id) + .and_then(|inner| *inner) + .and_then(|manager| { + if manager != u64::from(origin.clone()) { + None + } else { + Some(()) + } + }) + .ok_or(o)?; + + Ok(origin) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin(para_id: &ParaId) -> Result { + // Return container chain manager, or register container chain as ALICE if it does not exist + MockData::mutate(|m| { + m.container_chain_managers + .entry(*para_id) + .or_insert_with(move || { + const ALICE: u64 = 1; + + Some(ALICE) + }); + }); + + // This panics if the container chain was registered by root (None) + let o = MockData::get() + .container_chain_managers + .get(para_id) + .unwrap() + .unwrap(); + + Ok(O::from(RawOrigin::Signed(o.into()))) + } +} + +#[derive( + Serialize, Deserialize, RuntimeDebug, PartialEq, Eq, Encode, Decode, Copy, Clone, TypeInfo, +)] +pub enum ProviderRequest { + Free, + SomeKindOfPayment { + // in this mock the provider requests a fixed amount + amount: Balance, + }, +} + +#[derive( + Serialize, Deserialize, RuntimeDebug, PartialEq, Eq, Encode, Decode, Copy, Clone, TypeInfo, +)] +pub enum AssignerParameter { + Free, + SomeKindOfPayment { + // in this mock the assigner can add funds to the requested amount + extra: Balance, + }, +} + +#[derive( + Serialize, Deserialize, RuntimeDebug, PartialEq, Eq, Encode, Decode, Copy, Clone, TypeInfo, +)] +pub enum AssignmentWitness { + Free, + SomeKindOfPayment { + // in this mock we store requested + extra to ensure `AssignmentPayment` is called + // properly. We also store the payer to perform a second payment while stopping the + // assignement. + payed: Balance, + payer: AccountId, + }, +} + +pub struct AssignmentPayment; + +impl pallet_data_preservers::AssignmentPayment for AssignmentPayment { + /// Providers requests which kind of payment it accepts. + type ProviderRequest = ProviderRequest; + /// Extra parameter the assigner provides. + type AssignerParameter = AssignerParameter; + /// Represents the succesful outcome of the assignment. + type AssignmentWitness = AssignmentWitness; + + fn try_start_assignment( + assigner: AccountId, + provider: AccountId, + request: &Self::ProviderRequest, + extra: Self::AssignerParameter, + ) -> Result { + let witness = match (request, extra) { + (ProviderRequest::Free, AssignerParameter::Free) => AssignmentWitness::Free, + ( + ProviderRequest::SomeKindOfPayment { amount }, + AssignerParameter::SomeKindOfPayment { extra }, + ) => { + let total_amount = amount + extra; + Balances::transfer_allow_death( + RuntimeOrigin::signed(assigner), + provider, + total_amount, + )?; + AssignmentWitness::SomeKindOfPayment { + payed: total_amount, + payer: assigner, + } + } + _ => Err(crate::Error::::AssignmentPaymentRequestParameterMismatch)?, + }; + + Ok(witness) + } + + fn try_stop_assignment( + provider: AccountId, + witness: Self::AssignmentWitness, + ) -> Result<(), DispatchErrorWithPostInfo> { + // for testing purposes there is also a payment at the end of the assignment + match witness { + AssignmentWitness::Free => (), + AssignmentWitness::SomeKindOfPayment { payed, payer } => { + Balances::transfer_allow_death(RuntimeOrigin::signed(payer), provider, payed)?; + } + }; + + Ok(()) + } + + /// Return the values for a free assignment if it is supported. + /// This is required to perform automatic migration from old Bootnodes storage. + fn free_variant_values() -> Option<( + Self::ProviderRequest, + Self::AssignerParameter, + Self::AssignmentWitness, + )> { + Some(( + Self::ProviderRequest::Free, + Self::AssignerParameter::Free, + Self::AssignmentWitness::Free, + )) + } + + // The values returned by the following functions should match with each other. + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_provider_request() -> Self::ProviderRequest { + ProviderRequest::Free + } + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assigner_parameter() -> Self::AssignerParameter { + AssignerParameter::Free + } + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assignment_witness() -> Self::AssignmentWitness { + AssignmentWitness::Free + } +} + impl pallet_data_preservers::Config for Test { type RuntimeEvent = RuntimeEvent; type RuntimeHoldReason = RuntimeHoldReason; type Currency = Balances; type ProfileId = u64; - type SetBootNodesOrigin = MockContainerChainManagerOrRootOrigin>; + type AssignmentPayment = AssignmentPayment; + type AssignmentOrigin = MockContainerChainManager; type ForceSetProfileOrigin = EnsureRoot; - type MaxBootNodes = ConstU32<10>; - type MaxBootNodeUrlLen = ConstU32<200>; + type MaxAssignmentsPerParaId = ConstU32<10>; + type MaxNodeUrlLen = ConstU32<200>; type MaxParaIdsVecLen = ConstU32<20>; - type ProfileDeposit = crate::BytesProfileDeposit, ConstU128<51>>; + type ProfileDeposit = tp_traits::BytesDeposit, ConstU128<51>>; type WeightInfo = (); } diff --git a/pallets/data-preservers/src/tests.rs b/pallets/data-preservers/src/tests.rs index 42fe407f3..53a0c956e 100644 --- a/pallets/data-preservers/src/tests.rs +++ b/pallets/data-preservers/src/tests.rs @@ -18,184 +18,39 @@ use { crate::{mock::*, *}, frame_support::{assert_noop, assert_ok, pallet_prelude::*}, sp_runtime::TokenError, + std::collections::BTreeSet, }; const ALICE: u64 = 1; const BOB: u64 = 2; -#[test] -fn set_boot_nodes_bad_origin() { - ExtBuilder::default().build().execute_with(|| { - // Para 1001 has no manager, Alice cannot set boot nodes - assert_noop!(DataPreservers::set_boot_nodes( - RuntimeOrigin::signed(ALICE), - 1001.into(), - vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9".to_vec().try_into().unwrap() - ].try_into().unwrap() - ), - DispatchError::BadOrigin - ); - }); +fn profile_deposit(profile: &Profile) -> BalanceOf { + ::ProfileDeposit::compute_deposit(profile) + .expect("compute_deposit shouldn't fail") } -#[test] -fn set_boot_nodes_by_root_no_manager() { - ExtBuilder::default().build().execute_with(|| { - // Para 1001 has no manager, root can set boot nodes - let boot_nodes: BoundedVec, _> = vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec() - .try_into() - .unwrap(), - ] - .try_into() - .unwrap(); - assert_ok!(DataPreservers::set_boot_nodes( - RuntimeOrigin::root(), - 1001.into(), - boot_nodes.clone(), - )); - assert_eq!(DataPreservers::boot_nodes(ParaId::from(1001)), boot_nodes); - }); -} - -#[test] -fn set_boot_nodes_by_root_with_manager() { - ExtBuilder::default().build().execute_with(|| { - // Set ALICE as manager of para 1002 - MockData::mutate(|m| { - m.container_chain_managers.insert(1002.into(), Some(ALICE)); - }); - // Root can set bootnodes - let boot_nodes: BoundedVec, _> = vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec() - .try_into() - .unwrap(), - ] - .try_into() - .unwrap(); - assert_ok!(DataPreservers::set_boot_nodes( - RuntimeOrigin::root(), - 1002.into(), - boot_nodes.clone() - )); - assert_eq!(DataPreservers::boot_nodes(ParaId::from(1002)), boot_nodes); - }); -} - -#[test] -fn set_boot_nodes_by_para_id_registrar() { - ExtBuilder::default().build().execute_with(|| { - // Set ALICE as manager of para 1002 - MockData::mutate(|m| { - m.container_chain_managers.insert(1002.into(), Some(ALICE)); - }); - // Alice can set bootnodes - let boot_nodes: BoundedVec, _> = vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec() - .try_into() - .unwrap(), - ] - .try_into() - .unwrap(); - assert_ok!(DataPreservers::set_boot_nodes( - RuntimeOrigin::signed(ALICE), - 1002.into(), - boot_nodes.clone(), - )); - assert_eq!(DataPreservers::boot_nodes(ParaId::from(1002)), boot_nodes); - }); -} - -#[test] -fn set_boot_nodes_by_invalid_user_no_manager() { - ExtBuilder::default().build().execute_with(|| { - // Para 1001 has no manager - MockData::mutate(|m| { - m.container_chain_managers.insert(1002.into(), Some(ALICE)); - }); - // Bob cannot set the bootnodes - assert_noop!(DataPreservers::set_boot_nodes( - RuntimeOrigin::signed(BOB), - 1001.into(), - vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9".to_vec().try_into().unwrap() - ].try_into().unwrap() - ), - DispatchError::BadOrigin - ); - }); -} - -#[test] -fn set_boot_nodes_by_invalid_user() { - ExtBuilder::default().build().execute_with(|| { - // Set ALICE as manager of para 1002 - MockData::mutate(|m| { - m.container_chain_managers.insert(1002.into(), Some(ALICE)); - }); - // Bob cannot set the bootnodes - assert_noop!(DataPreservers::set_boot_nodes( - RuntimeOrigin::signed(BOB), - 1002.into(), - vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9".to_vec().try_into().unwrap() - ].try_into().unwrap() - ), - DispatchError::BadOrigin - ); - - assert_noop!(DataPreservers::set_boot_nodes( - RuntimeOrigin::signed(BOB), - 1003.into(), - vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9".to_vec().try_into().unwrap() - ].try_into().unwrap() - ), - DispatchError::BadOrigin - ); - }); -} - -#[test] -fn set_boot_nodes_by_invalid_user_bad_para_id() { - ExtBuilder::default().build().execute_with(|| { - // Para 1003 does not exist, only root can set bootnodes - assert_noop!(DataPreservers::set_boot_nodes( - RuntimeOrigin::signed(BOB), - 1003.into(), - vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9".to_vec().try_into().unwrap() - ].try_into().unwrap() - ), - DispatchError::BadOrigin - ); - }); +macro_rules! bset { + ( $($value:expr),* $(,)? ) => { + { + let mut set = BoundedBTreeSet::new(); + $( + set.try_insert($value).expect("max bound reached"); + )* + set + } + } } -#[test] -fn set_boot_nodes_bad_para_id() { - // Para 1003 does not exist, only root can set bootnodes - // This is allowed in case we want to set bootnodes before registering the chain - ExtBuilder::default().build().execute_with(|| { - let boot_nodes: BoundedVec, _> = vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec() - .try_into() - .unwrap(), - ] - .try_into() - .unwrap(); - assert_ok!(DataPreservers::set_boot_nodes( - RuntimeOrigin::root(), - 1003.into(), - boot_nodes.clone(), - )); - assert_eq!(DataPreservers::boot_nodes(ParaId::from(1003)), boot_nodes); - }); +macro_rules! set { + ( $($value:expr),* $(,)? ) => { + { + let mut set = BTreeSet::new(); + $( + set.insert($value); + )* + set + } + } } mod create_profile { @@ -211,8 +66,12 @@ mod create_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); // 1_000 base deposit + 51 * 8 bytes deposit + assert_ok!(DataPreservers::create_profile( RuntimeOrigin::signed(ALICE), profile.clone(), @@ -222,8 +81,9 @@ mod create_profile { Profiles::::get(0), Some(RegisteredProfile { account: ALICE, - deposit: 1_357, // 1_000 base deposit + 51 * 7 bytes deposit - profile + deposit, + profile, + assignment: None, }) ); @@ -234,7 +94,7 @@ mod create_profile { vec![Event::ProfileCreated { account: ALICE, profile_id: 0, - deposit: 1_357, + deposit, }] ); }); @@ -250,6 +110,7 @@ mod create_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_noop!( @@ -273,6 +134,7 @@ mod create_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; // Set some profile at next id. (this shouldn't occur but we protect from it @@ -283,6 +145,7 @@ mod create_profile { account: ALICE, deposit: 0, profile: profile.clone(), + assignment: None, }, ); @@ -303,6 +166,7 @@ mod create_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::force_create_profile( @@ -316,7 +180,8 @@ mod create_profile { Some(RegisteredProfile { account: ALICE, deposit: 0, // no deposit when forced - profile + profile, + assignment: None, }) ); @@ -343,6 +208,7 @@ mod create_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_noop!( @@ -369,9 +235,13 @@ mod update_profile { let profile = Profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, + assignment_request: ProviderRequest::Free, mode: ProfileMode::Bootnode, }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + assert_ok!(DataPreservers::create_profile( RuntimeOrigin::signed(ALICE), profile.clone(), @@ -379,12 +249,16 @@ mod update_profile { let profile2 = Profile { url: b"test2".to_vec().try_into().unwrap(), - para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()), + para_ids: ParaIdsFilter::Whitelist(bset![ParaId::from(42)]), mode: ProfileMode::Rpc { supports_ethereum_rpcs: false, }, + assignment_request: ProviderRequest::Free, }; + let deposit2 = profile_deposit(&profile2); + assert_eq!(deposit2, 1_765); + assert_ok!(DataPreservers::update_profile( RuntimeOrigin::signed(ALICE), 0, @@ -395,8 +269,9 @@ mod update_profile { Profiles::::get(0), Some(RegisteredProfile { account: ALICE, - deposit: 1_714, // 1_000 base deposit + 51 * 14 bytes deposit - profile: profile2 + deposit: deposit2, + profile: profile2, + assignment: None, }) ); @@ -406,12 +281,12 @@ mod update_profile { Event::ProfileCreated { account: ALICE, profile_id: 0, - deposit: 1_357, + deposit, }, Event::ProfileUpdated { profile_id: 0, - old_deposit: 1_357, - new_deposit: 1_714, + old_deposit: deposit, + new_deposit: deposit2, } ] ); @@ -421,13 +296,14 @@ mod update_profile { #[test] fn unknown_profile_id() { ExtBuilder::default() - .with_balances(vec![(ALICE, 1_400)]) + .with_balances(vec![(ALICE, 1_000_000_000_000)]) .build() .execute_with(|| { let profile = Profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::create_profile( @@ -437,10 +313,11 @@ mod update_profile { let profile2 = Profile { url: b"test2".to_vec().try_into().unwrap(), - para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()), + para_ids: ParaIdsFilter::Whitelist(bset![ParaId::from(42)]), mode: ProfileMode::Rpc { supports_ethereum_rpcs: false, }, + assignment_request: ProviderRequest::Free, }; assert_noop!( @@ -457,13 +334,14 @@ mod update_profile { #[test] fn wrong_user() { ExtBuilder::default() - .with_balances(vec![(ALICE, 1_400)]) + .with_balances(vec![(ALICE, 1_000_000_000_000)]) .build() .execute_with(|| { let profile = Profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::create_profile( @@ -473,10 +351,11 @@ mod update_profile { let profile2 = Profile { url: b"test2".to_vec().try_into().unwrap(), - para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()), + para_ids: ParaIdsFilter::Whitelist(bset![ParaId::from(42)]), mode: ProfileMode::Rpc { supports_ethereum_rpcs: false, }, + assignment_request: ProviderRequest::Free, }; assert_noop!( @@ -493,13 +372,14 @@ mod update_profile { #[test] fn insufficient_balance_for_new_deposit() { ExtBuilder::default() - .with_balances(vec![(ALICE, 1_400)]) + .with_balances(vec![(ALICE, 1_410)]) // `profile` .build() .execute_with(|| { let profile = Profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::create_profile( @@ -509,10 +389,11 @@ mod update_profile { let profile2 = Profile { url: b"test2".to_vec().try_into().unwrap(), - para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()), + para_ids: ParaIdsFilter::Whitelist(bset![ParaId::from(42)]), mode: ProfileMode::Rpc { supports_ethereum_rpcs: false, }, + assignment_request: ProviderRequest::Free, }; assert_noop!( @@ -536,8 +417,12 @@ mod update_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + assert_ok!(DataPreservers::create_profile( RuntimeOrigin::signed(ALICE), profile.clone(), @@ -545,10 +430,11 @@ mod update_profile { let profile2 = Profile { url: b"test2".to_vec().try_into().unwrap(), - para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()), + para_ids: ParaIdsFilter::Whitelist(bset![ParaId::from(42)]), mode: ProfileMode::Rpc { supports_ethereum_rpcs: false, }, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::force_update_profile( @@ -562,7 +448,8 @@ mod update_profile { Some(RegisteredProfile { account: ALICE, deposit: 0, // forced update release deposit - profile: profile2 + profile: profile2, + assignment: None, }) ); @@ -572,11 +459,11 @@ mod update_profile { Event::ProfileCreated { account: ALICE, profile_id: 0, - deposit: 1_357, + deposit, }, Event::ProfileUpdated { profile_id: 0, - old_deposit: 1_357, + old_deposit: deposit, new_deposit: 0, } ] @@ -594,6 +481,7 @@ mod update_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::create_profile( @@ -603,10 +491,11 @@ mod update_profile { let profile2 = Profile { url: b"test2".to_vec().try_into().unwrap(), - para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()), + para_ids: ParaIdsFilter::Whitelist(bset![ParaId::from(42)]), mode: ProfileMode::Rpc { supports_ethereum_rpcs: false, }, + assignment_request: ProviderRequest::Free, }; assert_noop!( @@ -634,8 +523,12 @@ mod delete_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + assert_ok!(DataPreservers::create_profile( RuntimeOrigin::signed(ALICE), profile.clone(), @@ -654,11 +547,11 @@ mod delete_profile { Event::ProfileCreated { account: ALICE, profile_id: 0, - deposit: 1_357, + deposit, }, Event::ProfileDeleted { profile_id: 0, - released_deposit: 1_357, + released_deposit: deposit, } ] ); @@ -668,13 +561,14 @@ mod delete_profile { #[test] fn unknown_profile_id() { ExtBuilder::default() - .with_balances(vec![(ALICE, 1_400)]) + .with_balances(vec![(ALICE, 1_000_000_000_000)]) .build() .execute_with(|| { let profile = Profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::create_profile( @@ -695,13 +589,14 @@ mod delete_profile { #[test] fn wrong_user() { ExtBuilder::default() - .with_balances(vec![(ALICE, 1_400)]) + .with_balances(vec![(ALICE, 1_000_000_000_000)]) .build() .execute_with(|| { let profile = Profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::create_profile( @@ -729,8 +624,12 @@ mod delete_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + assert_ok!(DataPreservers::create_profile( RuntimeOrigin::signed(ALICE), profile.clone(), @@ -749,11 +648,11 @@ mod delete_profile { Event::ProfileCreated { account: ALICE, profile_id: 0, - deposit: 1_357, + deposit, }, Event::ProfileDeleted { profile_id: 0, - released_deposit: 1_357, + released_deposit: deposit, } ] ); @@ -770,6 +669,7 @@ mod delete_profile { url: b"test".to_vec().try_into().unwrap(), para_ids: ParaIdsFilter::AnyParaId, mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, }; assert_ok!(DataPreservers::create_profile( @@ -783,4 +683,960 @@ mod delete_profile { ); }); } + + #[test] + fn cant_delete_assigned_profile() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + let para_id = ParaId::from(1002); + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_noop!( + DataPreservers::delete_profile(RuntimeOrigin::signed(BOB), 0,), + Error::::CantDeleteAssignedProfile + ); + }); + } + + #[test] + fn cant_force_delete_assigned_profile() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + let para_id = ParaId::from(1002); + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_noop!( + DataPreservers::force_delete_profile(RuntimeOrigin::root(), 0), + Error::::CantDeleteAssignedProfile + ); + }); + } +} + +mod start_assignment { + use super::*; + + #[test] + fn start_assignment_works() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + } + ] + ); + + assert_eq!(Assignments::::get(para_id).into_inner(), set![0]); + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: Some((para_id, AssignmentWitness::Free)), + }) + ); + }); + } + + #[test] + fn start_assignment_works_with_payment() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::SomeKindOfPayment { amount: 1337 }, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 2_224); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::SomeKindOfPayment { extra: 42 } + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + } + ] + ); + + assert_eq!(Assignments::::get(para_id), set![0]); + + let payed = 1337 + 42; + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: Some(( + para_id, + AssignmentWitness::SomeKindOfPayment { + payed, + payer: ALICE + } + )), + }) + ); + + assert_eq!(Balances::free_balance(ALICE), 1_000_000_000_000 - payed); + assert_eq!( + Balances::free_balance(BOB), + 1_000_000_000_000 - deposit + payed + ); + }); + } + + #[test] + fn no_profile() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let para_id = ParaId::from(1002); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + + assert_noop!( + DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + ), + Error::::UnknownProfileId + ); + }); + } + + #[test] + fn not_para_manager() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_noop!( + DataPreservers::start_assignment( + RuntimeOrigin::signed(BOB), + 0, + para_id, + AssignerParameter::Free + ), + DispatchError::BadOrigin + ); + }); + } + + #[test] + fn request_param_mismatch() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_noop!( + DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::SomeKindOfPayment { extra: 42 } + ), + Error::::AssignmentPaymentRequestParameterMismatch + ); + }); + } + + #[test] + fn payment_failure() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_300), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::SomeKindOfPayment { amount: 1337 }, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 2_224); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_noop!( + DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::SomeKindOfPayment { extra: 42 } + ), + TokenError::FundsUnavailable + ); + }); + } +} + +mod stop_assignment { + use super::*; + + #[test] + fn stop_assignment_works() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_ok!(DataPreservers::stop_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + }, + Event::AssignmentStopped { + profile_id: 0, + para_id, + } + ] + ); + + assert!(Assignments::::get(para_id).is_empty()); + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: None, + }) + ); + }); + } + + #[test] + fn stop_assignment_works_after_para_deregistration() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + DataPreservers::para_deregistered(para_id); + assert!(Assignments::::get(para_id).is_empty()); + + assert_ok!(DataPreservers::stop_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + }, + Event::AssignmentStopped { + profile_id: 0, + para_id, + } + ] + ); + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: None, + }) + ); + }); + } + + #[test] + fn stop_assignment_can_be_called_by_profile_owner() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_ok!(DataPreservers::stop_assignment( + RuntimeOrigin::signed(BOB), + 0, + para_id, + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + }, + Event::AssignmentStopped { + profile_id: 0, + para_id, + } + ] + ); + + assert!(Assignments::::get(para_id).is_empty()); + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: None, + }) + ); + }); + } + + #[test] + fn stop_assignment_can_be_called_by_root() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_ok!(DataPreservers::stop_assignment( + RuntimeOrigin::root(), + 0, + para_id, + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + }, + Event::AssignmentStopped { + profile_id: 0, + para_id, + } + ] + ); + + assert!(Assignments::::get(para_id).is_empty()); + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: None, + }) + ); + }); + } + + #[test] + fn stop_assignment_works_with_payment() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::SomeKindOfPayment { amount: 1337 }, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 2_224); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::SomeKindOfPayment { extra: 42 } + )); + + assert_ok!(DataPreservers::stop_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + }, + Event::AssignmentStopped { + profile_id: 0, + para_id, + } + ] + ); + + assert!(Assignments::::get(para_id).is_empty()); + + let payed = (1337 + 42) * 2; + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: None, + }) + ); + + assert_eq!(Balances::free_balance(ALICE), 1_000_000_000_000 - payed); + assert_eq!( + Balances::free_balance(BOB), + 1_000_000_000_000 - deposit + payed + ); + }); + } + + #[test] + fn unknown_profile_id() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_noop!( + DataPreservers::stop_assignment(RuntimeOrigin::signed(ALICE), 1, para_id,), + Error::::UnknownProfileId, + ); + }); + } + + #[test] + fn profile_not_assigned() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + + assert_noop!( + DataPreservers::stop_assignment(RuntimeOrigin::signed(ALICE), 0, para_id,), + Error::::ProfileNotAssigned, + ); + }); + } + + #[test] + fn wrong_para_id() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + let para_id2 = ParaId::from(1003); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + m.container_chain_managers.insert(para_id2, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_noop!( + DataPreservers::stop_assignment(RuntimeOrigin::signed(ALICE), 0, para_id2,), + Error::::WrongParaId + ); + }); + } + + #[test] + fn payment_failure() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_500), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::SomeKindOfPayment { amount: 1337 }, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 2_224); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::SomeKindOfPayment { extra: 42 } + )); + + assert_noop!( + DataPreservers::stop_assignment(RuntimeOrigin::signed(ALICE), 0, para_id,), + TokenError::FundsUnavailable + ); + }); + } +} + +mod force_start_assignment { + use super::*; + + #[test] + fn force_start_assignment_works() { + ExtBuilder::default() + .with_balances(vec![(ALICE, 1_000_000_000_000), (BOB, 1_000_000_000_000)]) + .build() + .execute_with(|| { + let profile = Profile { + url: b"test".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: ProviderRequest::Free, + }; + let deposit = profile_deposit(&profile); + assert_eq!(deposit, 1_408); + + let para_id = ParaId::from(1002); + + assert_ok!(DataPreservers::create_profile( + RuntimeOrigin::signed(BOB), + profile.clone(), + )); + + // Set ALICE as manager of para 1002 + MockData::mutate(|m| { + m.container_chain_managers.insert(para_id, Some(ALICE)); + }); + assert_ok!(DataPreservers::start_assignment( + RuntimeOrigin::signed(ALICE), + 0, + para_id, + AssignerParameter::Free + )); + + assert_eq!( + events(), + vec![ + Event::ProfileCreated { + account: BOB, + profile_id: 0, + deposit, + }, + Event::AssignmentStarted { + profile_id: 0, + para_id, + } + ] + ); + + assert_eq!(Assignments::::get(para_id).into_inner(), set![0]); + + assert_eq!( + Profiles::::get(0), + Some(RegisteredProfile { + account: BOB, + deposit, + profile, + assignment: Some((para_id, AssignmentWitness::Free)), + }) + ); + }); + } } diff --git a/pallets/data-preservers/src/types.rs b/pallets/data-preservers/src/types.rs new file mode 100644 index 000000000..808946de8 --- /dev/null +++ b/pallets/data-preservers/src/types.rs @@ -0,0 +1,170 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tanssi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tanssi. If not, see + +use { + super::*, + core::fmt::Debug, + dp_core::ParaId, + frame_support::{dispatch::DispatchErrorWithPostInfo, pallet_prelude::*}, + parity_scale_codec::FullCodec, + serde::{de::DeserializeOwned, Deserialize, Serialize}, +}; + +/// Data preserver profile. +#[derive( + RuntimeDebugNoBound, + PartialEqNoBound, + EqNoBound, + Encode, + Decode, + CloneNoBound, + TypeInfo, + Serialize, + Deserialize, +)] +#[scale_info(skip_type_params(T))] +pub struct Profile { + pub url: BoundedVec, + pub para_ids: ParaIdsFilter, + pub mode: ProfileMode, + pub assignment_request: ProviderRequestOf, +} + +#[derive( + RuntimeDebugNoBound, + PartialEqNoBound, + EqNoBound, + Encode, + Decode, + CloneNoBound, + TypeInfo, + Serialize, + Deserialize, +)] +#[scale_info(skip_type_params(T))] +pub enum ParaIdsFilter { + AnyParaId, + Whitelist(BoundedBTreeSet), + Blacklist(BoundedBTreeSet), +} + +impl ParaIdsFilter { + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> usize { + match self { + Self::AnyParaId => 0, + Self::Whitelist(list) | Self::Blacklist(list) => list.len(), + } + } + + pub fn can_assign(&self, para_id: &ParaId) -> bool { + match self { + ParaIdsFilter::AnyParaId => true, + ParaIdsFilter::Whitelist(list) => list.contains(para_id), + ParaIdsFilter::Blacklist(list) => !list.contains(para_id), + } + } +} + +#[derive(RuntimeDebug, PartialEq, Eq, Encode, Decode, Clone, TypeInfo, Serialize, Deserialize)] +pub enum ProfileMode { + Bootnode, + Rpc { supports_ethereum_rpcs: bool }, +} + +/// Profile with additional data: +/// - the account id which created (and manage) the profile +/// - the amount deposited to register the profile +#[derive( + RuntimeDebugNoBound, + PartialEqNoBound, + EqNoBound, + Encode, + Decode, + CloneNoBound, + TypeInfo, + Serialize, + Deserialize, +)] +#[scale_info(skip_type_params(T))] +pub struct RegisteredProfile { + pub account: T::AccountId, + pub deposit: BalanceOf, + pub profile: Profile, + /// There can be at most 1 assignment per profile. + pub assignment: Option<(ParaId, AssignmentWitnessOf)>, +} + +/// Allows to process various kinds of payment options for assignments. +pub trait AssignmentPayment { + /// Providers requests which kind of payment it accepts. + type ProviderRequest: FullCodec + + TypeInfo + + Copy + + Clone + + Debug + + Eq + + Serialize + + DeserializeOwned; + /// Extra parameter the assigner provides. + type AssignerParameter: FullCodec + + TypeInfo + + Copy + + Clone + + Debug + + Eq + + Serialize + + DeserializeOwned; + /// Represents the succesful outcome of the assignment. + type AssignmentWitness: FullCodec + + TypeInfo + + Copy + + Clone + + Debug + + Eq + + Serialize + + DeserializeOwned; + + fn try_start_assignment( + assigner: AccountId, + provider: AccountId, + request: &Self::ProviderRequest, + extra: Self::AssignerParameter, + ) -> Result; + + fn try_stop_assignment( + provider: AccountId, + witness: Self::AssignmentWitness, + ) -> Result<(), DispatchErrorWithPostInfo>; + + /// Return the values for a free assignment if it is supported. + /// This is required to perform automatic migration from old Bootnodes storage. + fn free_variant_values() -> Option<( + Self::ProviderRequest, + Self::AssignerParameter, + Self::AssignmentWitness, + )>; + + // The values returned by the following functions should match with each other. + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_provider_request() -> Self::ProviderRequest; + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assigner_parameter() -> Self::AssignerParameter; + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assignment_witness() -> Self::AssignmentWitness; +} diff --git a/pallets/data-preservers/src/weights.rs b/pallets/data-preservers/src/weights.rs index 9e282966b..523906d9c 100644 --- a/pallets/data-preservers/src/weights.rs +++ b/pallets/data-preservers/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_data_preservers //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-05-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-06-07, STEPS: `16`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `pop-os`, CPU: `12th Gen Intel(R) Core(TM) i7-1260P` //! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -35,10 +35,10 @@ // * // --chain=dev // --steps -// 50 +// 16 // --repeat -// 20 -// --template=./benchmarking/frame-weight-pallet-template.hbs +// 1 +// --template=benchmarking/frame-weight-pallet-template.hbs // --json-file // raw.json // --output @@ -53,37 +53,20 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_data_preservers. pub trait WeightInfo { - fn set_boot_nodes(x: u32, y: u32, ) -> Weight; fn create_profile(x: u32, y: u32, ) -> Weight; fn force_create_profile(x: u32, y: u32, ) -> Weight; fn update_profile(x: u32, y: u32, ) -> Weight; fn force_update_profile(x: u32, y: u32, ) -> Weight; fn delete_profile() -> Weight; fn force_delete_profile() -> Weight; + fn start_assignment() -> Weight; + fn stop_assignment() -> Weight; + fn force_start_assignment() -> Weight; } /// Weights for pallet_data_preservers using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) - /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `DataPreservers::BootNodes` (r:0 w:1) - /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `x` is `[1, 200]`. - /// The range of component `y` is `[1, 10]`. - fn set_boot_nodes(x: u32, y: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `195` - // Estimated: `3660` - // Minimum execution time: 10_063_000 picoseconds. - Weight::from_parts(10_198_905, 3660) - // Standard Error: 739 - .saturating_add(Weight::from_parts(2_403, 0).saturating_mul(x.into())) - // Standard Error: 15_425 - .saturating_add(Weight::from_parts(258_908, 0).saturating_mul(y.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -94,12 +77,16 @@ impl WeightInfo for SubstrateWeight { /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn create_profile(_x: u32, _y: u32, ) -> Weight { + fn create_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `182` + // Measured: `109` // Estimated: `3694` - // Minimum execution time: 34_210_000 picoseconds. - Weight::from_parts(43_239_265, 3694) + // Minimum execution time: 47_314_000 picoseconds. + Weight::from_parts(47_311_741, 3694) + // Standard Error: 6_992 + .saturating_add(Weight::from_parts(16_023, 0).saturating_mul(x.into())) + // Standard Error: 147_505 + .saturating_add(Weight::from_parts(152_259, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -111,10 +98,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `y` is `[1, 10]`. fn force_create_profile(_x: u32, _y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `79` - // Estimated: `3544` - // Minimum execution time: 9_075_000 picoseconds. - Weight::from_parts(11_443_644, 3544) + // Measured: `6` + // Estimated: `3471` + // Minimum execution time: 16_415_000 picoseconds. + Weight::from_parts(19_640_708, 3471) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -128,10 +115,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `y` is `[1, 10]`. fn update_profile(_x: u32, _y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 33_842_000 picoseconds. - Weight::from_parts(42_067_126, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 46_710_000 picoseconds. + Weight::from_parts(86_406_571, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -145,10 +132,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `y` is `[1, 10]`. fn force_update_profile(_x: u32, _y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 29_757_000 picoseconds. - Weight::from_parts(34_984_806, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 44_033_000 picoseconds. + Weight::from_parts(47_196_385, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -160,10 +147,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 32_125_000 picoseconds. - Weight::from_parts(35_384_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 44_490_000 picoseconds. + Weight::from_parts(44_490_000, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -175,36 +162,60 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn force_delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 35_189_000 picoseconds. - Weight::from_parts(36_883_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 45_933_000 picoseconds. + Weight::from_parts(45_933_000, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `373` + // Estimated: `3838` + // Minimum execution time: 27_104_000 picoseconds. + Weight::from_parts(27_104_000, 3838) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn stop_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `430` + // Estimated: `3895` + // Minimum execution time: 26_600_000 picoseconds. + Weight::from_parts(26_600_000, 3895) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn force_start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `153` + // Estimated: `3618` + // Minimum execution time: 19_437_000 picoseconds. + Weight::from_parts(19_437_000, 3618) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } } // For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) - /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `DataPreservers::BootNodes` (r:0 w:1) - /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `x` is `[1, 200]`. - /// The range of component `y` is `[1, 10]`. - fn set_boot_nodes(x: u32, y: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `195` - // Estimated: `3660` - // Minimum execution time: 10_063_000 picoseconds. - Weight::from_parts(10_198_905, 3660) - // Standard Error: 739 - .saturating_add(Weight::from_parts(2_403, 0).saturating_mul(x.into())) - // Standard Error: 15_425 - .saturating_add(Weight::from_parts(258_908, 0).saturating_mul(y.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -215,12 +226,16 @@ impl WeightInfo for () { /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn create_profile(_x: u32, _y: u32, ) -> Weight { + fn create_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `182` + // Measured: `109` // Estimated: `3694` - // Minimum execution time: 34_210_000 picoseconds. - Weight::from_parts(43_239_265, 3694) + // Minimum execution time: 47_314_000 picoseconds. + Weight::from_parts(47_311_741, 3694) + // Standard Error: 6_992 + .saturating_add(Weight::from_parts(16_023, 0).saturating_mul(x.into())) + // Standard Error: 147_505 + .saturating_add(Weight::from_parts(152_259, 0).saturating_mul(y.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -232,10 +247,10 @@ impl WeightInfo for () { /// The range of component `y` is `[1, 10]`. fn force_create_profile(_x: u32, _y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `79` - // Estimated: `3544` - // Minimum execution time: 9_075_000 picoseconds. - Weight::from_parts(11_443_644, 3544) + // Measured: `6` + // Estimated: `3471` + // Minimum execution time: 16_415_000 picoseconds. + Weight::from_parts(19_640_708, 3471) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -249,10 +264,10 @@ impl WeightInfo for () { /// The range of component `y` is `[1, 10]`. fn update_profile(_x: u32, _y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 33_842_000 picoseconds. - Weight::from_parts(42_067_126, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 46_710_000 picoseconds. + Weight::from_parts(86_406_571, 3780) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -266,10 +281,10 @@ impl WeightInfo for () { /// The range of component `y` is `[1, 10]`. fn force_update_profile(_x: u32, _y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 29_757_000 picoseconds. - Weight::from_parts(34_984_806, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 44_033_000 picoseconds. + Weight::from_parts(47_196_385, 3780) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -281,10 +296,10 @@ impl WeightInfo for () { /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 32_125_000 picoseconds. - Weight::from_parts(35_384_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 44_490_000 picoseconds. + Weight::from_parts(44_490_000, 3780) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -296,11 +311,54 @@ impl WeightInfo for () { /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn force_delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 35_189_000 picoseconds. - Weight::from_parts(36_883_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 45_933_000 picoseconds. + Weight::from_parts(45_933_000, 3780) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `373` + // Estimated: `3838` + // Minimum execution time: 27_104_000 picoseconds. + Weight::from_parts(27_104_000, 3838) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn stop_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `430` + // Estimated: `3895` + // Minimum execution time: 26_600_000 picoseconds. + Weight::from_parts(26_600_000, 3895) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn force_start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `153` + // Estimated: `3618` + // Minimum execution time: 19_437_000 picoseconds. + Weight::from_parts(19_437_000, 3618) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } } diff --git a/pallets/invulnerables/src/benchmarking.rs b/pallets/invulnerables/src/benchmarking.rs index c1b591dd5..7c58673a7 100644 --- a/pallets/invulnerables/src/benchmarking.rs +++ b/pallets/invulnerables/src/benchmarking.rs @@ -65,7 +65,7 @@ fn keys(c: u32) -> ::Keys { let mut keys = [0u8; 128]; if c > 0 { - let mut rng = rand::rngs::StdRng::seed_from_u64(c as u64); + let mut rng = rand::rngs::StdRng::seed_from_u64(u64::from(c)); rng.fill_bytes(&mut keys); } diff --git a/pallets/registrar/runtime-api/src/lib.rs b/pallets/registrar/runtime-api/src/lib.rs index d06086231..b4261bbd2 100644 --- a/pallets/registrar/runtime-api/src/lib.rs +++ b/pallets/registrar/runtime-api/src/lib.rs @@ -19,8 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] pub use tp_container_chain_genesis_data::ContainerChainGenesisData; -use tp_traits::SlotFrequency; -use {frame_support::traits::Get, scale_info::prelude::vec::Vec}; +use {frame_support::traits::Get, scale_info::prelude::vec::Vec, tp_traits::SlotFrequency}; sp_api::decl_runtime_apis! { pub trait RegistrarApi where diff --git a/pallets/registrar/src/benchmarks.rs b/pallets/registrar/src/benchmarks.rs index 52c8c60a8..b57ebaa0c 100644 --- a/pallets/registrar/src/benchmarks.rs +++ b/pallets/registrar/src/benchmarks.rs @@ -49,8 +49,7 @@ fn create_funded_user( #[benchmarks] mod benchmarks { - use super::*; - use parity_scale_codec::Encode; + use {super::*, parity_scale_codec::Encode}; fn new_genesis_data( storage: Vec, diff --git a/pallets/registrar/src/lib.rs b/pallets/registrar/src/lib.rs index 3f7ee45e1..07809722b 100644 --- a/pallets/registrar/src/lib.rs +++ b/pallets/registrar/src/lib.rs @@ -1312,7 +1312,7 @@ impl EnsureOriginWithArg for EnsureSignedByManager< where T: Config, { - type Success = (); + type Success = T::AccountId; fn try_origin( o: T::RuntimeOrigin, @@ -1325,7 +1325,7 @@ where return Err(frame_system::RawOrigin::Signed(signed_account).into()); } - Ok(()) + Ok(signed_account) } #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/xcm-core-buyer/src/benchmarks.rs b/pallets/xcm-core-buyer/src/benchmarks.rs index 784606c51..73ba72b47 100644 --- a/pallets/xcm-core-buyer/src/benchmarks.rs +++ b/pallets/xcm-core-buyer/src/benchmarks.rs @@ -34,12 +34,14 @@ pub const PLACE_ORDER_WEIGHT_AT_MOST: Weight = Weight::from_parts(1_000_000_000, #[benchmarks(where ::RuntimeOrigin: From)] mod benchmarks { - use crate::{BuyCoreCollatorProof, CheckCollatorValidity}; - use sp_runtime::RuntimeAppPublic; use { super::*, - crate::{InFlightCoreBuyingOrder, PendingBlocks, QueryIdToParaId}, + crate::{ + BuyCoreCollatorProof, CheckCollatorValidity, InFlightCoreBuyingOrder, PendingBlocks, + QueryIdToParaId, + }, frame_system::pallet_prelude::BlockNumberFor, + sp_runtime::RuntimeAppPublic, staging_xcm::{ latest::{MaybeErrorCode, QueryId}, v4::{Location, Response}, diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs index 8b5bd4e4c..04ea7633c 100644 --- a/pallets/xcm-core-buyer/src/lib.rs +++ b/pallets/xcm-core-buyer/src/lib.rs @@ -52,8 +52,7 @@ use { latest::{Asset, Assets, InteriorLocation, Response, Xcm}, prelude::*, }, - tp_traits::LatestAuthorInfoFetcher, - tp_traits::ParathreadParams, + tp_traits::{LatestAuthorInfoFetcher, ParathreadParams}, tp_xcm_core_buyer::BuyCoreCollatorProof, }; @@ -119,10 +118,10 @@ impl AuthorNotingHook for Pallet { #[frame_support::pallet] pub mod pallet { - use super::*; - use nimbus_primitives::SlotBeacon; - use pallet_xcm::ensure_response; - use sp_runtime::RuntimeAppPublic; + use { + super::*, nimbus_primitives::SlotBeacon, pallet_xcm::ensure_response, + sp_runtime::RuntimeAppPublic, + }; #[pallet::pallet] #[pallet::without_storage_info] diff --git a/pallets/xcm-core-buyer/src/mock.rs b/pallets/xcm-core-buyer/src/mock.rs index 07bbe106a..fd01e7ca6 100644 --- a/pallets/xcm-core-buyer/src/mock.rs +++ b/pallets/xcm-core-buyer/src/mock.rs @@ -14,12 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use crate::CheckCollatorValidity; -use nimbus_primitives::NimbusId; -use sp_keystore::testing::MemoryKeystore; -use sp_keystore::KeystoreExt; -use sp_runtime::RuntimeAppPublic; -use tp_traits::{ContainerChainBlockInfo, LatestAuthorInfoFetcher}; +use { + crate::CheckCollatorValidity, + nimbus_primitives::NimbusId, + sp_keystore::{testing::MemoryKeystore, KeystoreExt}, + sp_runtime::RuntimeAppPublic, + tp_traits::{ContainerChainBlockInfo, LatestAuthorInfoFetcher}, +}; use { crate::{ diff --git a/pallets/xcm-core-buyer/src/tests.rs b/pallets/xcm-core-buyer/src/tests.rs index 160a61a96..18a1c04f4 100644 --- a/pallets/xcm-core-buyer/src/tests.rs +++ b/pallets/xcm-core-buyer/src/tests.rs @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use nimbus_primitives::NimbusId; -use sp_runtime::RuntimeAppPublic; -use tp_traits::ContainerChainBlockInfo; use { crate::{mock::*, *}, frame_support::{assert_noop, assert_ok, assert_storage_noop}, - sp_runtime::traits::BadOrigin, + nimbus_primitives::NimbusId, + sp_runtime::{traits::BadOrigin, RuntimeAppPublic}, + tp_traits::ContainerChainBlockInfo, }; #[test] @@ -166,7 +165,7 @@ fn core_buying_proof_is_validated_correctly() { .get(¶_id) .expect("Collator data for test paraid must exists"); assert!( - collator_data.len() >= 1, + !collator_data.is_empty(), "collator data must contain at least one element" ); let collator = collator_data[0].clone(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c29f1e58c..5e7980794 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,15 +6,6 @@ settings: importers: - .: - dependencies: - api-augment:0.400.0: - specifier: link:@tanssi/api-augment:0.400.0 - version: link:@tanssi/api-augment:0.400.0 - api-augment:latest: - specifier: link:@tanssi/api-augment:latest - version: link:@tanssi/api-augment:latest - test: dependencies: '@zombienet/orchestrator': @@ -4854,6 +4845,7 @@ packages: chalk: 3.0.0 diff-match-patch: 1.0.5 dev: true + bundledDependencies: [] /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} diff --git a/primitives/traits/src/lib.rs b/primitives/traits/src/lib.rs index 34412f20b..da5c46c50 100644 --- a/primitives/traits/src/lib.rs +++ b/primitives/traits/src/lib.rs @@ -23,14 +23,19 @@ pub use cumulus_primitives_core::{ relay_chain::{BlockNumber, Slot}, ParaId, }; -use frame_support::pallet_prelude::MaxEncodedLen; -use sp_runtime::app_crypto::sp_core; use { + core::marker::PhantomData, frame_support::{ - pallet_prelude::{Decode, DispatchResultWithPostInfo, Encode, Get, Weight}, + dispatch::DispatchErrorWithPostInfo, + pallet_prelude::{Decode, DispatchResultWithPostInfo, Encode, Get, MaxEncodedLen, Weight}, BoundedVec, }, sp_core::H256, + sp_runtime::{ + app_crypto::sp_core, + traits::{CheckedAdd, CheckedMul}, + ArithmeticError, + }, sp_std::{collections::btree_set::BTreeSet, vec::Vec}, }; @@ -249,3 +254,34 @@ pub struct ContainerChainBlockInfo { pub trait LatestAuthorInfoFetcher { fn get_latest_author_info(para_id: ParaId) -> Option>; } + +pub trait StorageDeposit { + fn compute_deposit(data: &Data) -> Result; +} + +pub struct BytesDeposit(PhantomData<(BaseCost, ByteCost)>); +impl StorageDeposit + for BytesDeposit +where + Data: Encode, + Balance: TryFrom + CheckedAdd + CheckedMul, + BaseCost: Get, + ByteCost: Get, +{ + fn compute_deposit(data: &Data) -> Result { + let base = BaseCost::get(); + let byte = ByteCost::get(); + let size: Balance = data + .encoded_size() + .try_into() + .map_err(|_| ArithmeticError::Overflow)?; + + let deposit = byte + .checked_mul(&size) + .ok_or(ArithmeticError::Overflow)? + .checked_add(&base) + .ok_or(ArithmeticError::Overflow)?; + + Ok(deposit) + } +} diff --git a/primitives/xcm-core-buyer/src/lib.rs b/primitives/xcm-core-buyer/src/lib.rs index 148596fdd..df74a3ce9 100644 --- a/primitives/xcm-core-buyer/src/lib.rs +++ b/primitives/xcm-core-buyer/src/lib.rs @@ -19,10 +19,14 @@ #![cfg_attr(not(feature = "std"), no_std)] -use frame_support::pallet_prelude::{Decode, Encode, TypeInfo}; -use frame_support::{CloneNoBound, DebugNoBound}; -use sp_runtime::RuntimeAppPublic; -use tp_traits::ParaId; +use { + frame_support::{ + pallet_prelude::{Decode, Encode, TypeInfo}, + CloneNoBound, DebugNoBound, + }, + sp_runtime::RuntimeAppPublic, + tp_traits::ParaId, +}; /// Proof that I am a collator, assigned to a para_id, and I can buy a core for that para_id #[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, DebugNoBound, TypeInfo)] diff --git a/runtime/common/src/benchmarking.rs b/runtime/common/src/benchmarking.rs index f631688fb..4af2a647c 100644 --- a/runtime/common/src/benchmarking.rs +++ b/runtime/common/src/benchmarking.rs @@ -24,9 +24,7 @@ where T: pallet_treasury::Config, T::AccountId: From<[u8; 32]>, { - fn create_asset_kind(_seed: u32) -> () { - () - } + fn create_asset_kind(_seed: u32) {} fn create_beneficiary(seed: [u8; 32]) -> T::AccountId { let account: T::AccountId = seed.into(); diff --git a/runtime/common/src/migrations.rs b/runtime/common/src/migrations.rs index 901c48da4..ad946a016 100644 --- a/runtime/common/src/migrations.rs +++ b/runtime/common/src/migrations.rs @@ -36,19 +36,18 @@ #[cfg(feature = "try-runtime")] use frame_support::ensure; -use frame_support::migration::storage_key_iter; use { cumulus_primitives_core::ParaId, frame_support::{ + migration::{clear_storage_prefix, storage_key_iter}, pallet_prelude::GetStorageVersion, traits::{OnRuntimeUpgrade, PalletInfoAccess, StorageVersion}, weights::Weight, - StoragePrefixedMap, + Blake2_128Concat, BoundedVec, StoragePrefixedMap, }, pallet_configuration::{weights::WeightInfo as _, HostConfiguration}, - pallet_foreign_asset_creator::AssetId, - pallet_foreign_asset_creator::{AssetIdToForeignAsset, ForeignAssetToAssetId}, + pallet_foreign_asset_creator::{AssetId, AssetIdToForeignAsset, ForeignAssetToAssetId}, pallet_migrations::{GetMigrations, Migration}, sp_core::Get, sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*}, @@ -431,10 +430,10 @@ where } fn migrate(&self, _available_weight: Weight) -> Weight { - let total_weight = Weight::default(); + let mut total_weight = Weight::default(); for (para_id, deposit) in pallet_registrar::RegistrarDeposit::::iter() { pallet_registrar::ParaManager::::insert(para_id, deposit.creator); - total_weight.saturating_add( + total_weight = total_weight.saturating_add( T::DbWeight::get() .reads(1) .saturating_add(T::DbWeight::get().writes(1)), @@ -489,6 +488,8 @@ where Runtime: pallet_registrar::Config, Runtime: pallet_data_preservers::Config, Runtime: pallet_services_payment::Config, + Runtime: pallet_data_preservers::Config, + Runtime::AccountId: From<[u8; 32]>, { fn get_migrations() -> Vec> { //let migrate_services_payment = @@ -503,6 +504,8 @@ where RegistrarPendingVerificationValueToMap::(Default::default()); let migrate_registrar_manager = RegistrarParaManagerMigration::(Default::default()); + let migrate_data_preservers_assignments = + DataPreserversAssignmentsMigration::(Default::default()); vec![ // Applied in runtime 400 @@ -514,10 +517,153 @@ where Box::new(migrate_add_collator_assignment_credits), Box::new(migrate_registrar_pending_verification), Box::new(migrate_registrar_manager), + Box::new(migrate_data_preservers_assignments), ] } } +pub struct DataPreserversAssignmentsMigration(pub PhantomData); +impl Migration for DataPreserversAssignmentsMigration +where + T: pallet_data_preservers::Config + pallet_registrar::Config, + T::AccountId: From<[u8; 32]>, +{ + fn friendly_name(&self) -> &str { + "TM_DataPreserversAssignmentsMigration" + } + + fn migrate(&self, _available_weight: Weight) -> Weight { + use { + frame_support::BoundedBTreeSet, + frame_system::RawOrigin, + pallet_data_preservers::{AssignmentPayment, ParaIdsFilter, Profile, ProfileMode}, + }; + + let mut total_weight = Weight::default(); + + let (request, _extra, witness) = T::AssignmentPayment::free_variant_values() + .expect("free variant values are necessary to perform migration"); + + let dummy_profile_owner = T::AccountId::from([0u8; 32]); + + let pallet_prefix: &[u8] = b"DataPreservers"; + let storage_item_prefix: &[u8] = b"BootNodes"; + let bootnodes_storage: Vec<_> = storage_key_iter::< + ParaId, + BoundedVec, T::MaxAssignmentsPerParaId>, + Blake2_128Concat, + >(pallet_prefix, storage_item_prefix) + .collect(); + + total_weight = total_weight.saturating_add( + T::DbWeight::get() + .reads(bootnodes_storage.len() as u64) + .saturating_add(T::DbWeight::get().writes(bootnodes_storage.len() as u64)), + ); + + for (para_id, bootnodes) in bootnodes_storage { + for bootnode_url in bootnodes { + let profile = Profile { + url: bootnode_url, + para_ids: ParaIdsFilter::Whitelist({ + let mut set = BoundedBTreeSet::new(); + set.try_insert(para_id).expect("to be in bound"); + set + }), + mode: ProfileMode::Bootnode, + assignment_request: request, + }; + + let profile_id = pallet_data_preservers::NextProfileId::::get(); + + if let Some(weight) = pallet_data_preservers::Pallet::::force_create_profile( + RawOrigin::Root.into(), + profile, + dummy_profile_owner.clone(), + ) + .expect("to create profile") + .actual_weight + { + total_weight = total_weight.saturating_add(weight); + } + + if let Some(weight) = pallet_data_preservers::Pallet::::force_start_assignment( + RawOrigin::Root.into(), + profile_id, + para_id, + witness, + ) + .expect("to start assignment") + .actual_weight + { + total_weight = total_weight.saturating_add(weight); + } + } + } + + let _ = clear_storage_prefix(pallet_prefix, storage_item_prefix, &[], None, None); + + total_weight + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade(&self) -> Result, sp_runtime::DispatchError> { + use parity_scale_codec::Encode; + + let pallet_prefix: &[u8] = b"DataPreservers"; + let storage_item_prefix: &[u8] = b"BootNodes"; + let state: Vec<_> = storage_key_iter::< + ParaId, + BoundedVec, T::MaxAssignmentsPerParaId>, + Blake2_128Concat, + >(pallet_prefix, storage_item_prefix) + .collect(); + + Ok(state.encode()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(&self, state: Vec) -> Result<(), sp_runtime::DispatchError> { + use parity_scale_codec::Decode; + + let pallet_prefix: &[u8] = b"DataPreservers"; + let storage_item_prefix: &[u8] = b"BootNodes"; + + let pre_state: Vec<(ParaId, Vec>)> = + Decode::decode(&mut &state[..]).expect("state to be decoded properly"); + + for (para_id, bootnodes) in pre_state { + let assignments = pallet_data_preservers::Assignments::::get(para_id); + assert_eq!(assignments.len(), bootnodes.len()); + + let profiles: Vec<_> = + pallet_data_preservers::Pallet::::assignments_profiles(para_id).collect(); + + for bootnode in bootnodes { + assert_eq!( + profiles + .iter() + .filter(|profile| profile.url == bootnode) + .count(), + 1 + ); + } + } + + assert_eq!( + storage_key_iter::< + ParaId, + BoundedVec, T::MaxAssignmentsPerParaId>, + Blake2_128Concat, + >(pallet_prefix, storage_item_prefix) + .count(), + 0 + ); + + Ok(()) + } +} + pub struct DanceboxMigrations(PhantomData); impl GetMigrations for DanceboxMigrations @@ -528,12 +674,16 @@ where Runtime: pallet_configuration::Config, Runtime: pallet_services_payment::Config, Runtime: cumulus_pallet_xcmp_queue::Config, + Runtime: pallet_data_preservers::Config, Runtime: pallet_xcm::Config, ::RuntimeHoldReason: From, Runtime: pallet_foreign_asset_creator::Config, ::ForeignAsset: TryFrom, + ::RuntimeHoldReason: + From, + Runtime::AccountId: From<[u8; 32]>, { fn get_migrations() -> Vec> { // let migrate_invulnerables = MigrateInvulnerables::(Default::default()); @@ -556,6 +706,8 @@ where RegistrarPendingVerificationValueToMap::(Default::default()); let migrate_registrar_manager = RegistrarParaManagerMigration::(Default::default()); + let migrate_data_preservers_assignments = + DataPreserversAssignmentsMigration::(Default::default()); let migrate_pallet_xcm_v4 = MigrateToLatestXcmVersion::(Default::default()); let foreign_asset_creator_migration = @@ -585,6 +737,7 @@ where Box::new(migrate_registrar_manager), Box::new(migrate_pallet_xcm_v4), Box::new(foreign_asset_creator_migration), + Box::new(migrate_data_preservers_assignments), ] } } diff --git a/runtime/dancebox/Cargo.toml b/runtime/dancebox/Cargo.toml index 360a96b6d..1bd13abbb 100644 --- a/runtime/dancebox/Cargo.toml +++ b/runtime/dancebox/Cargo.toml @@ -17,7 +17,7 @@ hex-literal = { workspace = true } log = { workspace = true } parity-scale-codec = { workspace = true, features = [ "derive" ] } scale-info = { workspace = true, features = [ "derive" ] } -serde = { workspace = true, optional = true, features = [ "derive" ] } +serde = { workspace = true, features = [ "derive" ] } serde_json = { workspace = true, features = [ "arbitrary_precision" ] } smallvec = { workspace = true } @@ -237,8 +237,7 @@ std = [ "rococo-runtime-constants/std", "rococo-runtime/std", "scale-info/std", - "serde", - "serde?/std", + "serde/std", "serde_json/std", "sp-api/std", "sp-application-crypto/std", diff --git a/runtime/dancebox/src/lib.rs b/runtime/dancebox/src/lib.rs index a8243c93b..71aca8134 100644 --- a/runtime/dancebox/src/lib.rs +++ b/runtime/dancebox/src/lib.rs @@ -33,8 +33,6 @@ pub use sp_runtime::BuildStorage; pub mod weights; -use pallet_xcm_core_buyer::BuyingError; -use tp_traits::SlotFrequency; use { cumulus_pallet_parachain_system::{ RelayChainStateProof, RelayNumberMonotonicallyIncreases, RelaychainDataProvider, @@ -46,7 +44,7 @@ use { }, frame_support::{ construct_runtime, - dispatch::DispatchClass, + dispatch::{DispatchClass, DispatchErrorWithPostInfo}, genesis_builder_helper::{build_state, get_preset}, pallet_prelude::DispatchResult, parameter_types, @@ -76,7 +74,6 @@ use { nimbus_primitives::{NimbusId, SlotBeacon}, pallet_balances::NegativeImbalance, pallet_collator_assignment::{GetRandomnessForNextBlock, RotateCollatorsEveryNSessions}, - pallet_data_preservers::BytesProfileDeposit, pallet_invulnerables::InvulnerableRewardDistribution, pallet_pooled_staking::traits::{IsCandidateEligible, Timer}, pallet_registrar::RegistrarHooks, @@ -85,6 +82,7 @@ use { pallet_session::{SessionManager, ShouldEndSession}, pallet_stream_payment_runtime_api::{StreamPaymentApiError, StreamPaymentApiStatus}, pallet_transaction_payment::FungibleAdapter, + pallet_xcm_core_buyer::BuyingError, polkadot_runtime_common::BlockHashCount, scale_info::{prelude::format, TypeInfo}, smallvec::smallvec, @@ -106,7 +104,7 @@ use { sp_version::RuntimeVersion, tp_traits::{ GetContainerChainAuthor, GetHostConfiguration, GetSessionContainerChains, - RelayStorageRootProvider, RemoveInvulnerables, RemoveParaIdsWithNoCredits, + RelayStorageRootProvider, RemoveInvulnerables, RemoveParaIdsWithNoCredits, SlotFrequency, }, }; pub use { @@ -943,6 +941,128 @@ impl pallet_services_payment::Config for Runtime { parameter_types! { pub const ProfileDepositBaseFee: Balance = currency::STORAGE_ITEM_FEE; pub const ProfileDepositByteFee: Balance = currency::STORAGE_BYTE_FEE; + #[derive(Clone)] + pub const MaxAssignmentsPerParaId: u32 = 10; + #[derive(Clone)] + pub const MaxNodeUrlLen: u32 = 200; +} + +#[derive( + RuntimeDebug, + PartialEq, + Eq, + Encode, + Decode, + Copy, + Clone, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub enum PreserversAssignementPaymentRequest { + Free, + // TODO: Add Stream Payment (with config) +} + +#[derive( + RuntimeDebug, + PartialEq, + Eq, + Encode, + Decode, + Copy, + Clone, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub enum PreserversAssignementPaymentExtra { + Free, + // TODO: Add Stream Payment (with deposit) +} + +#[derive( + RuntimeDebug, + PartialEq, + Eq, + Encode, + Decode, + Copy, + Clone, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub enum PreserversAssignementPaymentWitness { + Free, + // TODO: Add Stream Payment (with stream id) +} + +pub struct PreserversAssignementPayment; + +impl pallet_data_preservers::AssignmentPayment for PreserversAssignementPayment { + /// Providers requests which kind of payment it accepts. + type ProviderRequest = PreserversAssignementPaymentRequest; + /// Extra parameter the assigner provides. + type AssignerParameter = PreserversAssignementPaymentExtra; + /// Represents the succesful outcome of the assignment. + type AssignmentWitness = PreserversAssignementPaymentWitness; + + fn try_start_assignment( + _assigner: AccountId, + _provider: AccountId, + request: &Self::ProviderRequest, + extra: Self::AssignerParameter, + ) -> Result { + let witness = match (request, extra) { + (Self::ProviderRequest::Free, Self::AssignerParameter::Free) => { + Self::AssignmentWitness::Free + } + }; + + Ok(witness) + } + + fn try_stop_assignment( + _provider: AccountId, + witness: Self::AssignmentWitness, + ) -> Result<(), DispatchErrorWithPostInfo> { + match witness { + Self::AssignmentWitness::Free => (), + } + + Ok(()) + } + + /// Return the values for a free assignment if it is supported. + /// This is required to perform automatic migration from old Bootnodes storage. + fn free_variant_values() -> Option<( + Self::ProviderRequest, + Self::AssignerParameter, + Self::AssignmentWitness, + )> { + Some(( + Self::ProviderRequest::Free, + Self::AssignerParameter::Free, + Self::AssignmentWitness::Free, + )) + } + + // The values returned by the following functions should match with each other. + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_provider_request() -> Self::ProviderRequest { + PreserversAssignementPaymentRequest::Free + } + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assigner_parameter() -> Self::AssignerParameter { + PreserversAssignementPaymentExtra::Free + } + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assignment_witness() -> Self::AssignmentWitness { + PreserversAssignementPaymentWitness::Free + } } impl pallet_data_preservers::Config for Runtime { @@ -952,14 +1072,14 @@ impl pallet_data_preservers::Config for Runtime { type WeightInfo = weights::pallet_data_preservers::SubstrateWeight; type ProfileId = u64; - type ProfileDeposit = BytesProfileDeposit; + type ProfileDeposit = tp_traits::BytesDeposit; + type AssignmentPayment = PreserversAssignementPayment; - type SetBootNodesOrigin = - EitherOfDiverse, EnsureRoot>; + type AssignmentOrigin = pallet_registrar::EnsureSignedByManager; type ForceSetProfileOrigin = EnsureRoot; - type MaxBootNodes = MaxBootNodes; - type MaxBootNodeUrlLen = MaxBootNodeUrlLen; + type MaxAssignmentsPerParaId = MaxAssignmentsPerParaId; + type MaxNodeUrlLen = MaxNodeUrlLen; type MaxParaIdsVecLen = MaxLengthParaIds; } @@ -1000,10 +1120,9 @@ impl pallet_invulnerables::Config for Runtime { } parameter_types! { + #[derive(Clone)] pub const MaxLengthParaIds: u32 = 100u32; pub const MaxEncodedGenesisDataSize: u32 = 5_000_000u32; // 5MB - pub const MaxBootNodes: u32 = 10; - pub const MaxBootNodeUrlLen: u32 = 200; } pub struct CurrentSessionIndexGetter; @@ -1057,17 +1176,44 @@ impl RegistrarHooks for DanceboxRegistrarHooks { #[cfg(feature = "runtime-benchmarks")] fn benchmarks_ensure_valid_for_collating(para_id: ParaId) { - use sp_runtime::BoundedVec; - let boot_nodes: BoundedVec, MaxBootNodes> = vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec() - .try_into() - .unwrap(), - ] - .try_into() - .unwrap(); + use { + frame_support::traits::EnsureOriginWithArg, + pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode}, + }; - pallet_data_preservers::BootNodes::::insert(para_id, boot_nodes); + let profile = Profile { + url: b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" + .to_vec() + .try_into() + .expect("to fit in BoundedVec"), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: PreserversAssignementPaymentRequest::Free, + }; + + let profile_id = pallet_data_preservers::NextProfileId::::get(); + let profile_owner = AccountId::new([1u8; 32]); + DataPreservers::force_create_profile(RuntimeOrigin::root(), profile, profile_owner) + .expect("profile create to succeed"); + + let para_manager = + ::AssignmentOrigin::try_successful_origin( + ¶_id, + ) + .expect("should be able to get para manager"); + + DataPreservers::start_assignment( + para_manager, + profile_id, + para_id, + PreserversAssignementPaymentExtra::Free, + ) + .expect("assignement to work"); + + assert!( + pallet_data_preservers::Assignments::::get(para_id).contains(&profile_id), + "profile should be correctly assigned" + ); } } @@ -2293,10 +2439,10 @@ impl_runtime_apis! { /// Fetch boot_nodes for this para id fn boot_nodes(para_id: ParaId) -> Vec> { - // TODO: remember to write migration to move boot nodes from pallet_registrar to pallet_data_preservers - let bounded_vec = DataPreservers::boot_nodes(para_id); - - bounded_vec.into_iter().map(|x| x.into()).collect() + DataPreservers::assignments_profiles(para_id) + .filter(|profile| profile.mode == pallet_data_preservers::ProfileMode::Bootnode) + .map(|profile| profile.url.into()) + .collect() } } diff --git a/runtime/dancebox/src/weights/pallet_data_preservers.rs b/runtime/dancebox/src/weights/pallet_data_preservers.rs index 9c42a0160..6882afb92 100644 --- a/runtime/dancebox/src/weights/pallet_data_preservers.rs +++ b/runtime/dancebox/src/weights/pallet_data_preservers.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_data_preservers //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-05-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-06-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `benchmark-1`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` //! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -54,25 +54,6 @@ use sp_std::marker::PhantomData; /// Weights for pallet_data_preservers using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl pallet_data_preservers::WeightInfo for SubstrateWeight { - /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) - /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `DataPreservers::BootNodes` (r:0 w:1) - /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `x` is `[1, 200]`. - /// The range of component `y` is `[1, 10]`. - fn set_boot_nodes(x: u32, y: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `195` - // Estimated: `3660` - // Minimum execution time: 17_579_000 picoseconds. - Weight::from_parts(15_512_474, 3660) - // Standard Error: 155 - .saturating_add(Weight::from_parts(12_145, 0).saturating_mul(x.into())) - // Standard Error: 3_245 - .saturating_add(Weight::from_parts(444_028, 0).saturating_mul(y.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -83,14 +64,16 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn create_profile(x: u32, _y: u32, ) -> Weight { + fn create_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `182` + // Measured: `109` // Estimated: `3694` - // Minimum execution time: 60_338_000 picoseconds. - Weight::from_parts(61_745_449, 3694) - // Standard Error: 237 - .saturating_add(Weight::from_parts(43, 0).saturating_mul(x.into())) + // Minimum execution time: 56_109_000 picoseconds. + Weight::from_parts(58_318_360, 3694) + // Standard Error: 258 + .saturating_add(Weight::from_parts(261, 0).saturating_mul(x.into())) + // Standard Error: 5_383 + .saturating_add(Weight::from_parts(74_156, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -102,14 +85,14 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// The range of component `y` is `[1, 10]`. fn force_create_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `79` - // Estimated: `3544` - // Minimum execution time: 17_167_000 picoseconds. - Weight::from_parts(17_704_087, 3544) - // Standard Error: 98 - .saturating_add(Weight::from_parts(221, 0).saturating_mul(x.into())) - // Standard Error: 2_053 - .saturating_add(Weight::from_parts(5_369, 0).saturating_mul(y.into())) + // Measured: `6` + // Estimated: `3471` + // Minimum execution time: 14_643_000 picoseconds. + Weight::from_parts(14_901_456, 3471) + // Standard Error: 100 + .saturating_add(Weight::from_parts(903, 0).saturating_mul(x.into())) + // Standard Error: 2_089 + .saturating_add(Weight::from_parts(63_818, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -121,14 +104,16 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn update_profile(x: u32, _y: u32, ) -> Weight { + fn update_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 59_285_000 picoseconds. - Weight::from_parts(60_566_202, 3784) - // Standard Error: 172 - .saturating_add(Weight::from_parts(336, 0).saturating_mul(x.into())) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 58_490_000 picoseconds. + Weight::from_parts(59_766_359, 3780) + // Standard Error: 274 + .saturating_add(Weight::from_parts(1_389, 0).saturating_mul(x.into())) + // Standard Error: 5_731 + .saturating_add(Weight::from_parts(85_589, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -142,14 +127,14 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// The range of component `y` is `[1, 10]`. fn force_update_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 51_519_000 picoseconds. - Weight::from_parts(53_016_751, 3784) - // Standard Error: 202 - .saturating_add(Weight::from_parts(224, 0).saturating_mul(x.into())) - // Standard Error: 4_224 - .saturating_add(Weight::from_parts(17, 0).saturating_mul(y.into())) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 51_654_000 picoseconds. + Weight::from_parts(52_613_318, 3780) + // Standard Error: 209 + .saturating_add(Weight::from_parts(992, 0).saturating_mul(x.into())) + // Standard Error: 4_376 + .saturating_add(Weight::from_parts(70_544, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -161,10 +146,10 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 50_942_000 picoseconds. - Weight::from_parts(51_642_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 50_736_000 picoseconds. + Weight::from_parts(51_395_000, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -176,11 +161,54 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn force_delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 50_872_000 picoseconds. - Weight::from_parts(51_956_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 50_590_000 picoseconds. + Weight::from_parts(51_415_000, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `373` + // Estimated: `3838` + // Minimum execution time: 26_633_000 picoseconds. + Weight::from_parts(27_297_000, 3838) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn stop_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `430` + // Estimated: `3895` + // Minimum execution time: 29_224_000 picoseconds. + Weight::from_parts(29_943_000, 3895) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn force_start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `153` + // Estimated: `3618` + // Minimum execution time: 20_061_000 picoseconds. + Weight::from_parts(20_793_000, 3618) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } } \ No newline at end of file diff --git a/runtime/dancebox/src/xcm_config.rs b/runtime/dancebox/src/xcm_config.rs index d51ff17c9..89a6e6c02 100644 --- a/runtime/dancebox/src/xcm_config.rs +++ b/runtime/dancebox/src/xcm_config.rs @@ -14,10 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use crate::{AuthorNoting, AuthorityMapping, Session}; -use nimbus_primitives::NimbusId; -use pallet_session::ShouldEndSession; -use pallet_xcm_core_buyer::CheckCollatorValidity; #[cfg(feature = "runtime-benchmarks")] use sp_std::{collections::btree_map::BTreeMap, vec}; #[cfg(feature = "runtime-benchmarks")] @@ -30,7 +26,7 @@ use { ParachainSystem, PolkadotXcm, Registrar, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, System, TransactionByteFee, WeightToFee, XcmpQueue, }, - crate::weights, + crate::{weights, AuthorNoting, AuthorityMapping, Session}, cumulus_primitives_core::{AggregateMessageOrigin, ParaId}, frame_support::{ parameter_types, @@ -38,9 +34,11 @@ use { weights::Weight, }, frame_system::{pallet_prelude::BlockNumberFor, EnsureRoot}, + nimbus_primitives::NimbusId, + pallet_session::ShouldEndSession, pallet_xcm::XcmPassthrough, pallet_xcm_core_buyer::{ - GetParathreadMaxCorePrice, GetParathreadParams, GetPurchaseCoreCall, + CheckCollatorValidity, GetParathreadMaxCorePrice, GetParathreadParams, GetPurchaseCoreCall, ParaIdIntoAccountTruncating, XCMNotifier, }, parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}, @@ -487,7 +485,7 @@ parameter_types! { pub const XcmBuyExecutionDotRococo: u128 = XCM_BUY_EXECUTION_COST_ROCOCO; } -pub const XCM_BUY_EXECUTION_COST_ROCOCO: u128 = 70_000_000 + 1_266_663_99; +pub const XCM_BUY_EXECUTION_COST_ROCOCO: u128 = 70_000_000 + 126_666_399; pub struct XCMNotifierImpl; diff --git a/runtime/dancebox/tests/common/mod.rs b/runtime/dancebox/tests/common/mod.rs index 9cec08f8e..b511f3045 100644 --- a/runtime/dancebox/tests/common/mod.rs +++ b/runtime/dancebox/tests/common/mod.rs @@ -19,8 +19,8 @@ use { cumulus_primitives_core::{ParaId, PersistedValidationData}, cumulus_primitives_parachain_inherent::ParachainInherentData, dancebox_runtime::{ - AuthorInherent, BlockProductionCost, CollatorAssignmentCost, MaxBootNodeUrlLen, - MaxBootNodes, MaxLengthTokenSymbol, + AuthorInherent, BlockProductionCost, CollatorAssignmentCost, MaxLengthTokenSymbol, + RuntimeOrigin, }, dp_consensus::runtime_decl_for_tanssi_authority_assignment_api::TanssiAuthorityAssignmentApi, frame_support::{ @@ -36,7 +36,7 @@ use { sp_consensus_aura::AURA_ENGINE_ID, sp_consensus_slots::Slot, sp_core::{Get, Pair}, - sp_runtime::{traits::Dispatchable, BoundedVec, BuildStorage, Digest, DigestItem}, + sp_runtime::{traits::Dispatchable, BuildStorage, Digest, DigestItem}, sp_std::collections::btree_map::BTreeMap, test_relay_sproof_builder::ParaHeaderSproofBuilder, }; @@ -239,9 +239,8 @@ pub fn end_block() { pub fn run_block() -> RunSummary { end_block(); - let summary = start_block(); - summary + start_block() } /// Mock the inherent that sets validation data in ParachainSystem, which @@ -307,7 +306,6 @@ pub fn set_parachain_inherent_data_random_seed(random_seed: [u8; 32]) { pub struct ParaRegistrationParams { para_id: u32, genesis_data: ContainerChainGenesisData, - bootnodes: Vec>, block_production_credits: u32, collator_assignment_credits: u32, } @@ -316,7 +314,6 @@ impl From<( u32, ContainerChainGenesisData, - Vec>, u32, u32, )> for ParaRegistrationParams @@ -325,7 +322,6 @@ impl value: ( u32, ContainerChainGenesisData, - Vec>, u32, u32, ), @@ -333,9 +329,8 @@ impl Self { para_id: value.0, genesis_data: value.1, - bootnodes: value.2, - block_production_credits: value.3, - collator_assignment_credits: value.4, + block_production_credits: value.2, + collator_assignment_credits: value.3, } } } @@ -468,17 +463,6 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - pallet_data_preservers::GenesisConfig:: { - para_id_boot_nodes: self - .para_ids - .into_iter() - .map(|registered_para| (registered_para.para_id.into(), registered_para.bootnodes)) - .collect(), - _phantom: Default::default(), - } - .assimilate_storage(&mut t) - .unwrap(); - pallet_configuration::GenesisConfig:: { config: self.config, ..Default::default() @@ -631,16 +615,6 @@ pub fn empty_genesis_data() -> ContainerChainGenesisData { } } -pub fn dummy_boot_nodes() -> BoundedVec, MaxBootNodes> { - vec![BoundedVec::try_from( - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec(), - ) - .unwrap()] - .try_into() - .unwrap() -} - pub fn current_slot() -> u64 { u64::from( pallet_async_backing::SlotInfo::::get() @@ -691,3 +665,41 @@ pub const CHARLIE: [u8; 32] = [6u8; 32]; pub const DAVE: [u8; 32] = [7u8; 32]; pub const EVE: [u8; 32] = [8u8; 32]; pub const FERDIE: [u8; 32] = [9u8; 32]; + +pub fn set_dummy_boot_node(para_manager: RuntimeOrigin, para_id: ParaId) { + use { + dancebox_runtime::{ + PreserversAssignementPaymentExtra, PreserversAssignementPaymentRequest, RuntimeOrigin, + }, + pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode}, + }; + + let profile = Profile { + url: + b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" + .to_vec() + .try_into() + .expect("to fit in BoundedVec"), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: PreserversAssignementPaymentRequest::Free, + }; + + let profile_id = pallet_data_preservers::NextProfileId::::get(); + let profile_owner = AccountId::new([1u8; 32]); + DataPreservers::force_create_profile(RuntimeOrigin::root(), profile, profile_owner) + .expect("profile create to succeed"); + + DataPreservers::start_assignment( + para_manager, + profile_id, + para_id, + PreserversAssignementPaymentExtra::Free, + ) + .expect("assignement to work"); + + assert!( + pallet_data_preservers::Assignments::::get(para_id).contains(&profile_id), + "profile should be correctly assigned" + ); +} diff --git a/runtime/dancebox/tests/common/xcm/core_buyer.rs b/runtime/dancebox/tests/common/xcm/core_buyer.rs index cfcf9139b..0f2bfd150 100644 --- a/runtime/dancebox/tests/common/xcm/core_buyer.rs +++ b/runtime/dancebox/tests/common/xcm/core_buyer.rs @@ -18,7 +18,7 @@ use { crate::{ assert_expected_events, common::{ - dummy_boot_nodes, empty_genesis_data, run_to_session, start_block, + empty_genesis_data, run_to_session, set_dummy_boot_node, start_block, xcm::{ mocknets::{ DanceboxRococoPara as Dancebox, DanceboxSender, RococoRelay as Rococo, @@ -30,7 +30,7 @@ use { }, core::marker::PhantomData, cumulus_primitives_core::Weight, - dancebox_runtime::{DataPreservers, Registrar, ServicesPayment, XcmCoreBuyer}, + dancebox_runtime::{Registrar, ServicesPayment, XcmCoreBuyer}, frame_support::assert_ok, pallet_xcm_core_buyer::RelayXcmWeightConfigInner, polkadot_runtime_parachains::{ @@ -62,7 +62,7 @@ const PLACE_ORDER_WEIGHT_AT_MOST: Weight = Weight::from_parts(1_000_000_000, 100 fn constants() { // If these constants change, some tests may break assert_eq!(ROCOCO_ED, 100_000_000 / 3); - assert_eq!(BUY_EXECUTION_COST, 70_000_000 + 1_266_663_99); + assert_eq!(BUY_EXECUTION_COST, 70_000_000 + 126_666_399); } /// The tests in this module all use this function to trigger an XCM message to buy a core. @@ -82,11 +82,7 @@ fn do_test(tank_account_balance: u128, set_max_core_price: Option) -> Quer SlotFrequency { min: 1, max: 1 }, empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - alice_origin, - PARATHREAD_ID.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(alice_origin, PARATHREAD_ID.into()); let root_origin = ::RuntimeOrigin::root(); assert_ok!(Registrar::mark_valid_for_collating( root_origin.clone(), @@ -300,20 +296,15 @@ fn assert_query_response( /// Get parathread tank address in relay chain. This is derived from the Dancebox para id and the /// parathread para id. fn get_parathread_tank_relay_address() -> AccountId32 { - let parathread_tank_in_relay = Dancebox::execute_with(|| { + Dancebox::execute_with(|| { let parathread_tank_multilocation = XcmCoreBuyer::relay_relative_multilocation( XcmCoreBuyer::interior_multilocation(PARATHREAD_ID.into()), ) .expect("reanchor failed"); - let parathread_tank_in_relay = - ::SovereignAccountOf::convert_location( - ¶thread_tank_multilocation, - ) - .expect("probably this relay chain does not allow DescendOrigin"); - parathread_tank_in_relay - }); - parathread_tank_in_relay + ::SovereignAccountOf::convert_location(¶thread_tank_multilocation) + .expect("probably this relay chain does not allow DescendOrigin") + }) } fn get_on_demand_base_fee() -> u128 { diff --git a/runtime/dancebox/tests/integration_test.rs b/runtime/dancebox/tests/integration_test.rs index b027af674..a30cf852f 100644 --- a/runtime/dancebox/tests/integration_test.rs +++ b/runtime/dancebox/tests/integration_test.rs @@ -16,32 +16,25 @@ #![cfg(test)] -use dancebox_runtime::xcm_config::ForeignAssetsInstance; -use frame_support::migration::put_storage_value; -use frame_support::storage::generator::StorageMap; -use frame_support::Hashable; -use pallet_foreign_asset_creator::{AssetIdToForeignAsset, ForeignAssetToAssetId}; -use staging_xcm::v3::{ - Junction as V3Junction, Junctions as V3Junctions, MultiLocation as V3MultiLocation, - NetworkId as V3NetworkId, -}; -use std::marker::PhantomData; -use tanssi_runtime_common::migrations::ForeignAssetCreatorMigration; use { common::*, cumulus_primitives_core::ParaId, dancebox_runtime::{ - RewardsCollatorCommission, StreamPayment, StreamPaymentAssetId, TimeUnit, - TransactionPayment, + xcm_config::ForeignAssetsInstance, RewardsCollatorCommission, StreamPayment, + StreamPaymentAssetId, TimeUnit, TransactionPayment, }, dp_consensus::runtime_decl_for_tanssi_authority_assignment_api::TanssiAuthorityAssignmentApiV1, dp_core::well_known_keys, - frame_support::{assert_noop, assert_ok, BoundedVec}, + frame_support::{ + assert_noop, assert_ok, migration::put_storage_value, storage::generator::StorageMap, + BoundedVec, Hashable, + }, frame_system::ConsumedWeight, nimbus_primitives::NIMBUS_KEY_ID, pallet_author_noting_runtime_api::runtime_decl_for_author_noting_api::AuthorNotingApi, pallet_balances::Instance1, pallet_collator_assignment_runtime_api::runtime_decl_for_collator_assignment_api::CollatorAssignmentApi, + pallet_foreign_asset_creator::{AssetIdToForeignAsset, ForeignAssetToAssetId}, pallet_migrations::Migration, pallet_pooled_staking::{ traits::IsCandidateEligible, AllTargetPool, EligibleCandidate, PendingOperationKey, @@ -58,10 +51,17 @@ use { DigestItem, FixedU128, }, sp_std::vec, - staging_xcm::latest::prelude::*, + staging_xcm::{ + latest::prelude::*, + v3::{ + Junction as V3Junction, Junctions as V3Junctions, MultiLocation as V3MultiLocation, + NetworkId as V3NetworkId, + }, + }, + std::marker::PhantomData, tanssi_runtime_common::migrations::{ - MigrateConfigurationParathreads, MigrateServicesPaymentAddCollatorAssignmentCredits, - RegistrarPendingVerificationValueToMap, + ForeignAssetCreatorMigration, MigrateConfigurationParathreads, + MigrateServicesPaymentAddCollatorAssignmentCredits, RegistrarPendingVerificationValueToMap, }, test_relay_sproof_builder::{HeaderAs, ParaHeaderSproofBuilder, ParaHeaderSproofBuilderItem}, tp_traits::{ContainerChainBlockInfo, SlotFrequency}, @@ -103,8 +103,8 @@ fn genesis_balances() { fn genesis_para_registrar() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -119,8 +119,8 @@ fn genesis_para_registrar() { fn genesis_para_registrar_deregister() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -158,8 +158,8 @@ fn genesis_para_registrar_deregister() { fn genesis_para_registrar_runtime_api() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -199,8 +199,8 @@ fn genesis_para_registrar_container_chain_genesis_data_runtime_api() { }; ExtBuilder::default() .with_para_ids(vec![ - (1001, genesis_data_1001.clone(), vec![], u32::MAX, u32::MAX).into(), - (1002, genesis_data_1002.clone(), vec![], u32::MAX, u32::MAX).into(), + (1001, genesis_data_1001.clone(), u32::MAX, u32::MAX).into(), + (1002, genesis_data_1002.clone(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -263,8 +263,8 @@ fn genesis_para_registrar_container_chain_genesis_data_runtime_api() { fn test_author_collation_aura() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -293,8 +293,8 @@ fn test_author_collation_aura_change_of_authorities_on_session() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -369,8 +369,8 @@ fn test_author_collation_aura_add_assigned_to_paras() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -506,11 +506,7 @@ fn test_authors_paras_inserted_a_posteriori() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -525,11 +521,7 @@ fn test_authors_paras_inserted_a_posteriori() { 1002.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1002.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1002.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1002.into() @@ -599,11 +591,7 @@ fn test_authors_paras_inserted_a_posteriori_with_collators_already_assigned() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -667,11 +655,7 @@ fn test_paras_registered_but_zero_credits() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -729,11 +713,7 @@ fn test_paras_registered_but_not_enough_credits() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -812,11 +792,7 @@ fn test_paras_registered_but_only_credits_for_1_session() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -909,8 +885,8 @@ fn test_parachains_deregister_collators_re_assigned() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -971,8 +947,8 @@ fn test_parachains_deregister_collators_config_change_reassigned() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1037,8 +1013,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1106,8 +1082,8 @@ fn test_author_collation_aura_add_assigned_to_paras_runtime_api() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1263,8 +1239,8 @@ fn test_consensus_runtime_api() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1354,8 +1330,8 @@ fn test_consensus_runtime_api_session_changes() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1466,8 +1442,8 @@ fn test_consensus_runtime_api_next_session() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1668,8 +1644,8 @@ fn test_author_noting_not_self_para() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1728,8 +1704,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1775,8 +1751,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1817,8 +1793,8 @@ fn test_author_noting_runtime_api() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1883,8 +1859,8 @@ fn test_collator_assignment_rotation() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1938,8 +1914,8 @@ fn test_session_keys_with_authority_mapping() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2018,8 +1994,8 @@ fn test_session_keys_with_authority_assignment() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2342,8 +2318,8 @@ fn test_staking_no_candidates_in_genesis() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2373,8 +2349,8 @@ fn test_staking_join() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2425,8 +2401,8 @@ fn test_staking_join_no_keys_registered() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() @@ -2481,8 +2457,8 @@ fn test_staking_register_keys_after_joining() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() @@ -2570,8 +2546,8 @@ fn test_staking_join_bad_origin() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2607,8 +2583,8 @@ fn test_staking_join_below_self_delegation_min() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2679,8 +2655,8 @@ fn test_staking_join_no_self_delegation() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2718,8 +2694,8 @@ fn test_staking_join_before_self_delegation() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2788,8 +2764,8 @@ fn test_staking_join_twice_in_same_block() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2857,8 +2833,8 @@ fn test_staking_join_execute_before_time() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2932,8 +2908,8 @@ fn test_staking_join_execute_any_origin() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2991,8 +2967,8 @@ fn test_staking_join_execute_bad_origin() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3059,8 +3035,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3495,8 +3471,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3585,8 +3561,8 @@ fn test_pallet_session_limits_num_validators() { (AccountId::from(CHARLIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .with_config(pallet_configuration::HostConfiguration { max_collators: 2, @@ -3674,8 +3650,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .with_config(pallet_configuration::HostConfiguration { max_collators: 2, @@ -3786,8 +3762,8 @@ fn test_reward_to_staking_candidate() { ]) .with_collators(vec![(AccountId::from(ALICE), 210 * UNIT)]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3893,8 +3869,8 @@ fn test_reward_to_invulnerable() { (AccountId::from(CHARLIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3983,8 +3959,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -4124,8 +4100,8 @@ fn test_collator_assignment_gives_priority_to_invulnerables() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -4356,11 +4332,7 @@ fn test_can_buy_credits_before_registering_para_and_receive_free_credits() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -4400,11 +4372,7 @@ fn test_deregister_and_register_again_does_not_give_free_credits() { 1001.into(), empty_genesis_data() ),); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -4433,11 +4401,7 @@ fn test_deregister_and_register_again_does_not_give_free_credits() { 1001.into(), empty_genesis_data() ),); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -4629,11 +4593,7 @@ fn test_register_parathread() { SlotFrequency { min: 1, max: 1 }, empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 3001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 3001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 3001.into() @@ -4682,11 +4642,7 @@ fn test_ed_plus_block_credit_session_purchase_works() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -4783,11 +4739,7 @@ fn test_ed_plus_block_credit_session_minus_1_purchase_fails() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -4855,11 +4807,7 @@ fn test_reassignment_ed_plus_two_block_credit_session_purchase_works() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -4967,11 +4915,7 @@ fn test_reassignment_ed_plus_two_block_credit_session_minus_1_purchase_fails() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -5070,11 +5014,7 @@ fn test_block_credits_with_purchase_can_be_combined() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -5212,11 +5152,7 @@ fn test_ed_plus_collator_assignment_session_purchase_works() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -5311,11 +5247,7 @@ fn test_ed_plus_collator_assignment_credit_session_minus_1_purchase_fails() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -5382,11 +5314,7 @@ fn test_collator_assignment_credits_with_purchase_can_be_combined() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -5457,11 +5385,7 @@ fn test_block_credits_and_collator_assignation_credits_through_tank() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -5523,11 +5447,7 @@ fn test_migration_services_collator_assignment_payment() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -5538,11 +5458,7 @@ fn test_migration_services_collator_assignment_payment() { 1002.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1002.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1002.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1002.into() @@ -5699,14 +5615,7 @@ fn test_max_collators_uses_pending_value() { (AccountId::from(CHARLIE), 100 * UNIT), (AccountId::from(DAVE), 100 * UNIT), ]) - .with_para_ids(vec![( - 1001, - empty_genesis_data(), - vec![], - u32::MAX, - u32::MAX, - ) - .into()]) + .with_para_ids(vec![(1001, empty_genesis_data(), u32::MAX, u32::MAX).into()]) .with_config(pallet_configuration::HostConfiguration { max_collators: 100, min_orchestrator_collators: 1, @@ -5808,9 +5717,9 @@ fn test_collator_assignment_tip_priority_on_congestion() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -5863,9 +5772,9 @@ fn test_collator_assignment_tip_charged_on_congestion() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -5911,9 +5820,9 @@ fn test_collator_assignment_tip_not_assigned_on_insufficient_balance() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -5964,9 +5873,9 @@ fn test_collator_assignment_tip_only_charge_willing_paras() { (AccountId::from(FERDIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -6036,9 +5945,9 @@ fn test_collator_assignment_tip_withdraw_min_tip() { (AccountId::from(FERDIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -6099,3 +6008,173 @@ fn test_collator_assignment_tip_withdraw_min_tip() { ); }); } + +#[test] +fn test_migration_data_preservers_assignments() { + ExtBuilder::default().build().execute_with(|| { + use { + dancebox_runtime::{MaxAssignmentsPerParaId, MaxNodeUrlLen}, + frame_support::{ + migration::{have_storage_value, put_storage_value}, + Blake2_128Concat, StorageHasher, + }, + pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode, RegisteredProfile}, + sp_runtime::BoundedBTreeSet, + sp_std::collections::btree_set::BTreeSet, + tanssi_runtime_common::migrations::DataPreserversAssignmentsMigration, + }; + + macro_rules! bset { + ( $($value:expr),* $(,)? ) => { + { + let mut set = BoundedBTreeSet::new(); + $( + set.try_insert($value).expect("max bound reached"); + )* + set + } + } + } + + macro_rules! set { + ( $($value:expr),* $(,)? ) => { + { + let mut set = BTreeSet::new(); + $( + set.insert($value); + )* + set + } + } + } + + let account = AccountId::from([0u8; 32]); + let free_request = dancebox_runtime::PreserversAssignementPaymentRequest::Free; + let free_witness = dancebox_runtime::PreserversAssignementPaymentWitness::Free; + + let pallet_prefix: &[u8] = b"DataPreservers"; + let storage_item_prefix: &[u8] = b"BootNodes"; + + // Register 2 parachains + assert_ok!(Registrar::register( + origin_of(ALICE.into()), + 1001.into(), + empty_genesis_data() + )); + assert_ok!(Registrar::register( + origin_of(BOB.into()), + 1002.into(), + empty_genesis_data() + )); + + // Set bootnodes in old storage + let bootnodes: BoundedVec, MaxAssignmentsPerParaId> = vec![ + b"alpha".to_vec().try_into().unwrap(), + b"beta".to_vec().try_into().unwrap(), + ] + .try_into() + .unwrap(); + put_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1001).encode()), + bootnodes, + ); + + let bootnodes: BoundedVec, MaxAssignmentsPerParaId> = vec![ + b"delta".to_vec().try_into().unwrap(), + b"gamma".to_vec().try_into().unwrap(), + ] + .try_into() + .unwrap(); + put_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1002).encode()), + bootnodes, + ); + + // Apply migration + let migration = DataPreserversAssignmentsMigration::(Default::default()); + migration.migrate(Default::default()); + + // Check old storage is empty + assert!(!have_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1001).encode()) + )); + assert!(!have_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1002).encode()) + )); + + // Check new storage + assert_eq!( + pallet_data_preservers::Assignments::::get(ParaId::from(1001)).into_inner(), + set![0, 1] + ); + assert_eq!( + pallet_data_preservers::Assignments::::get(ParaId::from(1002)).into_inner(), + set![2, 3] + ); + assert_eq!(pallet_data_preservers::NextProfileId::::get(), 4); + assert_eq!( + pallet_data_preservers::Profiles::::get(0), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1001.into(), free_witness)), + profile: Profile { + url: b"alpha".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1001.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + assert_eq!( + pallet_data_preservers::Profiles::::get(1), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1001.into(), free_witness)), + profile: Profile { + url: b"beta".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1001.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + assert_eq!( + pallet_data_preservers::Profiles::::get(2), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1002.into(), free_witness)), + profile: Profile { + url: b"delta".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1002.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + assert_eq!( + pallet_data_preservers::Profiles::::get(3), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1002.into(), free_witness)), + profile: Profile { + url: b"gamma".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1002.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + }) +} diff --git a/runtime/flashbox/Cargo.toml b/runtime/flashbox/Cargo.toml index 55ec64c86..524b767ce 100644 --- a/runtime/flashbox/Cargo.toml +++ b/runtime/flashbox/Cargo.toml @@ -17,7 +17,7 @@ hex-literal = { workspace = true } log = { workspace = true } parity-scale-codec = { workspace = true, features = [ "derive" ] } scale-info = { workspace = true, features = [ "derive" ] } -serde = { workspace = true, optional = true, features = [ "derive" ] } +serde = { workspace = true, features = [ "derive" ] } smallvec = { workspace = true } # Own @@ -186,8 +186,7 @@ std = [ "polkadot-runtime-common/std", "polkadot-runtime-parachains/std", "scale-info/std", - "serde", - "serde?/std", + "serde/std", "sp-api/std", "sp-application-crypto/std", "sp-application-crypto/std", diff --git a/runtime/flashbox/src/lib.rs b/runtime/flashbox/src/lib.rs index 51e797894..76864cf9e 100644 --- a/runtime/flashbox/src/lib.rs +++ b/runtime/flashbox/src/lib.rs @@ -39,7 +39,7 @@ use { cumulus_primitives_core::{relay_chain::SessionIndex, BodyId, ParaId}, frame_support::{ construct_runtime, - dispatch::DispatchClass, + dispatch::{DispatchClass, DispatchErrorWithPostInfo}, genesis_builder_helper::{build_state, get_preset}, pallet_prelude::DispatchResult, parameter_types, @@ -68,7 +68,6 @@ use { }, nimbus_primitives::{NimbusId, SlotBeacon}, pallet_balances::NegativeImbalance, - pallet_data_preservers::BytesProfileDeposit, pallet_invulnerables::InvulnerableRewardDistribution, pallet_registrar::RegistrarHooks, pallet_registrar_runtime_api::ContainerChainGenesisData, @@ -798,6 +797,128 @@ impl pallet_services_payment::Config for Runtime { parameter_types! { pub const ProfileDepositBaseFee: Balance = currency::STORAGE_ITEM_FEE; pub const ProfileDepositByteFee: Balance = currency::STORAGE_BYTE_FEE; + #[derive(Clone)] + pub const MaxAssignmentsPerParaId: u32 = 10; + #[derive(Clone)] + pub const MaxNodeUrlLen: u32 = 200; +} + +#[derive( + RuntimeDebug, + PartialEq, + Eq, + Encode, + Decode, + Copy, + Clone, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub enum PreserversAssignementPaymentRequest { + Free, + // TODO: Add Stream Payment (with config) +} + +#[derive( + RuntimeDebug, + PartialEq, + Eq, + Encode, + Decode, + Copy, + Clone, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub enum PreserversAssignementPaymentExtra { + Free, + // TODO: Add Stream Payment (with deposit) +} + +#[derive( + RuntimeDebug, + PartialEq, + Eq, + Encode, + Decode, + Copy, + Clone, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub enum PreserversAssignementPaymentWitness { + Free, + // TODO: Add Stream Payment (with stream id) +} + +pub struct PreserversAssignementPayment; + +impl pallet_data_preservers::AssignmentPayment for PreserversAssignementPayment { + /// Providers requests which kind of payment it accepts. + type ProviderRequest = PreserversAssignementPaymentRequest; + /// Extra parameter the assigner provides. + type AssignerParameter = PreserversAssignementPaymentExtra; + /// Represents the succesful outcome of the assignment. + type AssignmentWitness = PreserversAssignementPaymentWitness; + + fn try_start_assignment( + _assigner: AccountId, + _provider: AccountId, + request: &Self::ProviderRequest, + extra: Self::AssignerParameter, + ) -> Result { + let witness = match (request, extra) { + (Self::ProviderRequest::Free, Self::AssignerParameter::Free) => { + Self::AssignmentWitness::Free + } + }; + + Ok(witness) + } + + fn try_stop_assignment( + _provider: AccountId, + witness: Self::AssignmentWitness, + ) -> Result<(), DispatchErrorWithPostInfo> { + match witness { + Self::AssignmentWitness::Free => (), + } + + Ok(()) + } + + /// Return the values for a free assignment if it is supported. + /// This is required to perform automatic migration from old Bootnodes storage. + fn free_variant_values() -> Option<( + Self::ProviderRequest, + Self::AssignerParameter, + Self::AssignmentWitness, + )> { + Some(( + Self::ProviderRequest::Free, + Self::AssignerParameter::Free, + Self::AssignmentWitness::Free, + )) + } + + // The values returned by the following functions should match with each other. + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_provider_request() -> Self::ProviderRequest { + PreserversAssignementPaymentRequest::Free + } + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assigner_parameter() -> Self::AssignerParameter { + PreserversAssignementPaymentExtra::Free + } + + #[cfg(feature = "runtime-benchmarks")] + fn benchmark_assignment_witness() -> Self::AssignmentWitness { + PreserversAssignementPaymentWitness::Free + } } impl pallet_data_preservers::Config for Runtime { @@ -807,14 +928,14 @@ impl pallet_data_preservers::Config for Runtime { type WeightInfo = weights::pallet_data_preservers::SubstrateWeight; type ProfileId = u64; - type ProfileDeposit = BytesProfileDeposit; + type ProfileDeposit = tp_traits::BytesDeposit; + type AssignmentPayment = PreserversAssignementPayment; - type SetBootNodesOrigin = - EitherOfDiverse, EnsureRoot>; + type AssignmentOrigin = pallet_registrar::EnsureSignedByManager; type ForceSetProfileOrigin = EnsureRoot; - type MaxBootNodes = MaxBootNodes; - type MaxBootNodeUrlLen = MaxBootNodeUrlLen; + type MaxAssignmentsPerParaId = MaxAssignmentsPerParaId; + type MaxNodeUrlLen = MaxNodeUrlLen; type MaxParaIdsVecLen = MaxLengthParaIds; } @@ -855,10 +976,9 @@ impl pallet_invulnerables::Config for Runtime { } parameter_types! { + #[derive(Clone)] pub const MaxLengthParaIds: u32 = 200u32; pub const MaxEncodedGenesisDataSize: u32 = 5_000_000u32; // 5MB - pub const MaxBootNodes: u32 = 10; - pub const MaxBootNodeUrlLen: u32 = 200; } pub struct CurrentSessionIndexGetter; @@ -910,17 +1030,44 @@ impl RegistrarHooks for FlashboxRegistrarHooks { #[cfg(feature = "runtime-benchmarks")] fn benchmarks_ensure_valid_for_collating(para_id: ParaId) { - use sp_runtime::BoundedVec; - let boot_nodes: BoundedVec, MaxBootNodes> = vec![ - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec() - .try_into() - .unwrap(), - ] - .try_into() - .unwrap(); + use { + frame_support::traits::EnsureOriginWithArg, + pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode}, + }; + + let profile = Profile { + url: b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" + .to_vec() + .try_into() + .expect("to fit in BoundedVec"), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: PreserversAssignementPaymentRequest::Free, + }; + + let profile_id = pallet_data_preservers::NextProfileId::::get(); + let profile_owner = AccountId::new([1u8; 32]); + DataPreservers::force_create_profile(RuntimeOrigin::root(), profile, profile_owner) + .expect("profile create to succeed"); + + let para_manager = + ::AssignmentOrigin::try_successful_origin( + ¶_id, + ) + .expect("should be able to get para manager"); - pallet_data_preservers::BootNodes::::insert(para_id, boot_nodes); + DataPreservers::start_assignment( + para_manager, + profile_id, + para_id, + PreserversAssignementPaymentExtra::Free, + ) + .expect("assignement to work"); + + assert!( + pallet_data_preservers::Assignments::::get(para_id).contains(&profile_id), + "profile should be correctly assigned" + ); } } pub struct PalletRelayStorageRootProvider; @@ -1843,10 +1990,10 @@ impl_runtime_apis! { /// Fetch boot_nodes for this para id fn boot_nodes(para_id: ParaId) -> Vec> { - // TODO: remember to write migration to move boot nodes from pallet_registrar to pallet_data_preservers - let bounded_vec = DataPreservers::boot_nodes(para_id); - - bounded_vec.into_iter().map(|x| x.into()).collect() + DataPreservers::assignments_profiles(para_id) + .filter(|profile| profile.mode == pallet_data_preservers::ProfileMode::Bootnode) + .map(|profile| profile.url.into()) + .collect() } } diff --git a/runtime/flashbox/src/weights/pallet_data_preservers.rs b/runtime/flashbox/src/weights/pallet_data_preservers.rs index 27c1f78a7..aebe3f06f 100644 --- a/runtime/flashbox/src/weights/pallet_data_preservers.rs +++ b/runtime/flashbox/src/weights/pallet_data_preservers.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_data_preservers //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-05-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-06-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `benchmark-1`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` //! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("flashbox_dev"), DB CACHE: 1024 @@ -54,25 +54,6 @@ use sp_std::marker::PhantomData; /// Weights for pallet_data_preservers using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl pallet_data_preservers::WeightInfo for SubstrateWeight { - /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) - /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `DataPreservers::BootNodes` (r:0 w:1) - /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `x` is `[1, 200]`. - /// The range of component `y` is `[1, 10]`. - fn set_boot_nodes(x: u32, y: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `195` - // Estimated: `3660` - // Minimum execution time: 16_267_000 picoseconds. - Weight::from_parts(14_208_199, 3660) - // Standard Error: 159 - .saturating_add(Weight::from_parts(11_989, 0).saturating_mul(x.into())) - // Standard Error: 3_322 - .saturating_add(Weight::from_parts(452_756, 0).saturating_mul(y.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -83,14 +64,16 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn create_profile(x: u32, _y: u32, ) -> Weight { + fn create_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `182` + // Measured: `109` // Estimated: `3694` - // Minimum execution time: 59_513_000 picoseconds. - Weight::from_parts(60_845_441, 3694) - // Standard Error: 269 - .saturating_add(Weight::from_parts(1_122, 0).saturating_mul(x.into())) + // Minimum execution time: 56_133_000 picoseconds. + Weight::from_parts(57_491_409, 3694) + // Standard Error: 358 + .saturating_add(Weight::from_parts(2_663, 0).saturating_mul(x.into())) + // Standard Error: 7_478 + .saturating_add(Weight::from_parts(92_438, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -100,14 +83,16 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn force_create_profile(x: u32, _y: u32, ) -> Weight { + fn force_create_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `79` - // Estimated: `3544` - // Minimum execution time: 15_994_000 picoseconds. - Weight::from_parts(16_661_778, 3544) - // Standard Error: 116 - .saturating_add(Weight::from_parts(1_112, 0).saturating_mul(x.into())) + // Measured: `6` + // Estimated: `3471` + // Minimum execution time: 14_001_000 picoseconds. + Weight::from_parts(14_244_237, 3471) + // Standard Error: 100 + .saturating_add(Weight::from_parts(972, 0).saturating_mul(x.into())) + // Standard Error: 2_105 + .saturating_add(Weight::from_parts(74_945, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -119,14 +104,16 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn update_profile(x: u32, _y: u32, ) -> Weight { + fn update_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 58_515_000 picoseconds. - Weight::from_parts(59_596_525, 3784) - // Standard Error: 181 - .saturating_add(Weight::from_parts(1_609, 0).saturating_mul(x.into())) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 58_645_000 picoseconds. + Weight::from_parts(60_210_936, 3780) + // Standard Error: 279 + .saturating_add(Weight::from_parts(866, 0).saturating_mul(x.into())) + // Standard Error: 5_830 + .saturating_add(Weight::from_parts(79_939, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -138,14 +125,16 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) /// The range of component `x` is `[1, 200]`. /// The range of component `y` is `[1, 10]`. - fn force_update_profile(x: u32, _y: u32, ) -> Weight { + fn force_update_profile(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 50_727_000 picoseconds. - Weight::from_parts(52_180_969, 3784) - // Standard Error: 179 - .saturating_add(Weight::from_parts(1_243, 0).saturating_mul(x.into())) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 51_081_000 picoseconds. + Weight::from_parts(52_637_641, 3780) + // Standard Error: 224 + .saturating_add(Weight::from_parts(765, 0).saturating_mul(x.into())) + // Standard Error: 4_670 + .saturating_add(Weight::from_parts(65_007, 0).saturating_mul(y.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -157,10 +146,10 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 50_322_000 picoseconds. - Weight::from_parts(51_297_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 50_715_000 picoseconds. + Weight::from_parts(51_909_000, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -172,11 +161,54 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`) fn force_delete_profile() -> Weight { // Proof Size summary in bytes: - // Measured: `319` - // Estimated: `3784` - // Minimum execution time: 49_809_000 picoseconds. - Weight::from_parts(50_842_000, 3784) + // Measured: `315` + // Estimated: `3780` + // Minimum execution time: 50_569_000 picoseconds. + Weight::from_parts(51_320_000, 3780) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `373` + // Estimated: `3838` + // Minimum execution time: 25_860_000 picoseconds. + Weight::from_parts(26_456_000, 3838) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Registrar::ParaManager` (r:1 w:0) + /// Proof: `Registrar::ParaManager` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn stop_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `430` + // Estimated: `3895` + // Minimum execution time: 28_618_000 picoseconds. + Weight::from_parts(29_250_000, 3895) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `DataPreservers::Profiles` (r:1 w:1) + /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::Assignments` (r:1 w:1) + /// Proof: `DataPreservers::Assignments` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn force_start_assignment() -> Weight { + // Proof Size summary in bytes: + // Measured: `153` + // Estimated: `3618` + // Minimum execution time: 19_759_000 picoseconds. + Weight::from_parts(20_139_000, 3618) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } } \ No newline at end of file diff --git a/runtime/flashbox/tests/common/mod.rs b/runtime/flashbox/tests/common/mod.rs index 27d467130..0a0df2d8c 100644 --- a/runtime/flashbox/tests/common/mod.rs +++ b/runtime/flashbox/tests/common/mod.rs @@ -20,8 +20,7 @@ use { cumulus_primitives_parachain_inherent::ParachainInherentData, dp_consensus::runtime_decl_for_tanssi_authority_assignment_api::TanssiAuthorityAssignmentApi, flashbox_runtime::{ - AuthorInherent, BlockProductionCost, CollatorAssignmentCost, MaxBootNodeUrlLen, - MaxBootNodes, MaxLengthTokenSymbol, + AuthorInherent, BlockProductionCost, CollatorAssignmentCost, MaxLengthTokenSymbol, }, frame_support::{ assert_ok, @@ -36,7 +35,7 @@ use { sp_consensus_aura::AURA_ENGINE_ID, sp_consensus_slots::Slot, sp_core::{Get, Pair}, - sp_runtime::{traits::Dispatchable, BoundedVec, BuildStorage, Digest, DigestItem}, + sp_runtime::{traits::Dispatchable, BuildStorage, Digest, DigestItem}, sp_std::collections::btree_map::BTreeMap, test_relay_sproof_builder::ParaHeaderSproofBuilder, }; @@ -233,9 +232,8 @@ pub fn end_block() { pub fn run_block() -> RunSummary { end_block(); - let summary = start_block(); - summary + start_block() } /// Mock the inherent that sets validation data in ParachainSystem, which @@ -295,7 +293,6 @@ pub fn set_parachain_inherent_data(mock_inherent_data: MockInherentData) { pub struct ParaRegistrationParams { para_id: u32, genesis_data: ContainerChainGenesisData, - bootnodes: Vec>, block_production_credits: u32, collator_assignment_credits: u32, } @@ -304,7 +301,6 @@ impl From<( u32, ContainerChainGenesisData, - Vec>, u32, u32, )> for ParaRegistrationParams @@ -313,7 +309,6 @@ impl value: ( u32, ContainerChainGenesisData, - Vec>, u32, u32, ), @@ -321,9 +316,8 @@ impl Self { para_id: value.0, genesis_data: value.1, - bootnodes: value.2, - block_production_credits: value.3, - collator_assignment_credits: value.4, + block_production_credits: value.2, + collator_assignment_credits: value.3, } } } @@ -444,17 +438,6 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - pallet_data_preservers::GenesisConfig:: { - para_id_boot_nodes: self - .para_ids - .into_iter() - .map(|registered_para| (registered_para.para_id.into(), registered_para.bootnodes)) - .collect(), - _phantom: Default::default(), - } - .assimilate_storage(&mut t) - .unwrap(); - pallet_configuration::GenesisConfig:: { config: self.config, ..Default::default() @@ -593,16 +576,6 @@ pub fn empty_genesis_data() -> ContainerChainGenesisData { } } -pub fn dummy_boot_nodes() -> BoundedVec, MaxBootNodes> { - vec![BoundedVec::try_from( - b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" - .to_vec(), - ) - .unwrap()] - .try_into() - .unwrap() -} - pub fn current_slot() -> u64 { u64::from( pallet_async_backing::SlotInfo::::get() diff --git a/runtime/flashbox/tests/integration_test.rs b/runtime/flashbox/tests/integration_test.rs index ace2d0ce6..4594cdad6 100644 --- a/runtime/flashbox/tests/integration_test.rs +++ b/runtime/flashbox/tests/integration_test.rs @@ -21,7 +21,7 @@ use { cumulus_primitives_core::{ParaId, Weight}, dp_consensus::runtime_decl_for_tanssi_authority_assignment_api::TanssiAuthorityAssignmentApiV1, dp_core::well_known_keys, - flashbox_runtime::{StreamPaymentAssetId, TimeUnit}, + flashbox_runtime::{RuntimeOrigin, StreamPaymentAssetId, TimeUnit}, frame_support::{assert_noop, assert_ok, BoundedVec}, frame_system::ConsumedWeight, nimbus_primitives::NIMBUS_KEY_ID, @@ -48,6 +48,44 @@ mod common; const UNIT: Balance = 1_000_000_000_000_000_000; +fn set_dummy_boot_node(para_manager: RuntimeOrigin, para_id: ParaId) { + use { + flashbox_runtime::{ + PreserversAssignementPaymentExtra, PreserversAssignementPaymentRequest, RuntimeOrigin, + }, + pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode}, + }; + + let profile = Profile { + url: + b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9" + .to_vec() + .try_into() + .expect("to fit in BoundedVec"), + para_ids: ParaIdsFilter::AnyParaId, + mode: ProfileMode::Bootnode, + assignment_request: PreserversAssignementPaymentRequest::Free, + }; + + let profile_id = pallet_data_preservers::NextProfileId::::get(); + let profile_owner = AccountId::new([1u8; 32]); + DataPreservers::force_create_profile(RuntimeOrigin::root(), profile, profile_owner) + .expect("profile create to succeed"); + + DataPreservers::start_assignment( + para_manager, + profile_id, + para_id, + PreserversAssignementPaymentExtra::Free, + ) + .expect("assignement to work"); + + assert!( + pallet_data_preservers::Assignments::::get(para_id).contains(&profile_id), + "profile should be correctly assigned" + ); +} + #[test] fn genesis_balances() { ExtBuilder::default() @@ -80,8 +118,8 @@ fn genesis_balances() { fn genesis_para_registrar() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -96,8 +134,8 @@ fn genesis_para_registrar() { fn genesis_para_registrar_deregister() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -135,8 +173,8 @@ fn genesis_para_registrar_deregister() { fn genesis_para_registrar_runtime_api() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -176,8 +214,8 @@ fn genesis_para_registrar_container_chain_genesis_data_runtime_api() { }; ExtBuilder::default() .with_para_ids(vec![ - (1001, genesis_data_1001.clone(), vec![], u32::MAX, u32::MAX).into(), - (1002, genesis_data_1002.clone(), vec![], u32::MAX, u32::MAX).into(), + (1001, genesis_data_1001.clone(), u32::MAX, u32::MAX).into(), + (1002, genesis_data_1002.clone(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -240,8 +278,8 @@ fn genesis_para_registrar_container_chain_genesis_data_runtime_api() { fn test_author_collation_aura() { ExtBuilder::default() .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -270,8 +308,8 @@ fn test_author_collation_aura_change_of_authorities_on_session() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -346,8 +384,8 @@ fn test_author_collation_aura_add_assigned_to_paras() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -483,11 +521,7 @@ fn test_authors_paras_inserted_a_posteriori() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -502,11 +536,7 @@ fn test_authors_paras_inserted_a_posteriori() { 1002.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1002.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1002.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1002.into() @@ -576,11 +606,7 @@ fn test_authors_paras_inserted_a_posteriori_with_collators_already_assigned() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -644,11 +670,7 @@ fn test_paras_registered_but_zero_credits() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -706,11 +728,7 @@ fn test_paras_registered_but_not_enough_credits() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -789,11 +807,7 @@ fn test_paras_registered_but_only_credits_for_1_session() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -886,8 +900,8 @@ fn test_parachains_deregister_collators_re_assigned() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -948,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1014,8 +1028,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1083,8 +1097,8 @@ fn test_author_collation_aura_add_assigned_to_paras_runtime_api() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1240,8 +1254,8 @@ fn test_consensus_runtime_api() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1331,8 +1345,8 @@ fn test_consensus_runtime_api_session_changes() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1443,8 +1457,8 @@ fn test_consensus_runtime_api_next_session() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1645,8 +1659,8 @@ fn test_author_noting_not_self_para() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1705,8 +1719,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1752,8 +1766,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1794,8 +1808,8 @@ fn test_author_noting_runtime_api() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1862,8 +1876,8 @@ fn test_session_keys_with_authority_mapping() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -1942,8 +1956,8 @@ fn test_session_keys_with_authority_assignment() { (AccountId::from(DAVE), 100_000 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2260,8 +2274,8 @@ fn test_reward_to_invulnerable() { (AccountId::from(CHARLIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2313,8 +2327,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![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -2485,11 +2499,7 @@ fn test_can_buy_credits_before_registering_para_and_receive_free_credits() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -2529,11 +2539,7 @@ fn test_deregister_and_register_again_does_not_give_free_credits() { 1001.into(), empty_genesis_data() ),); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -2562,11 +2568,7 @@ fn test_deregister_and_register_again_does_not_give_free_credits() { 1001.into(), empty_genesis_data() ),); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -2606,11 +2608,7 @@ fn test_register_parathread() { SlotFrequency { min: 1, max: 1 }, empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 3001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 3001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 3001.into() @@ -2659,11 +2657,7 @@ fn test_ed_plus_block_credit_session_purchase_works() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -2760,11 +2754,7 @@ fn test_ed_plus_block_credit_session_minus_1_purchase_fails() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -2832,11 +2822,7 @@ fn test_reassignment_ed_plus_two_block_credit_session_purchase_works() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -2944,11 +2930,7 @@ fn test_reassignment_ed_plus_two_block_credit_session_minus_1_purchase_fails() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -3047,11 +3029,7 @@ fn test_credits_with_purchase_can_be_combined() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -3189,11 +3167,7 @@ fn test_ed_plus_collator_assignment_session_purchase_works() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -3288,11 +3262,7 @@ fn test_ed_plus_collator_assignment_credit_session_minus_1_purchase_fails() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -3359,11 +3329,7 @@ fn test_collator_assignment_credits_with_purchase_can_be_combined() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -3434,11 +3400,7 @@ fn test_block_credits_and_collator_assignation_credits_through_tank() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -3500,11 +3462,7 @@ fn test_migration_services_collator_assignment_payment() { 1001.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1001.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1001.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1001.into() @@ -3515,11 +3473,7 @@ fn test_migration_services_collator_assignment_payment() { 1002.into(), empty_genesis_data() )); - assert_ok!(DataPreservers::set_boot_nodes( - origin_of(ALICE.into()), - 1002.into(), - dummy_boot_nodes() - )); + set_dummy_boot_node(origin_of(ALICE.into()), 1002.into()); assert_ok!(Registrar::mark_valid_for_collating( root_origin(), 1002.into() @@ -3588,14 +3542,7 @@ fn test_max_collators_uses_pending_value() { (AccountId::from(CHARLIE), 100 * UNIT), (AccountId::from(DAVE), 100 * UNIT), ]) - .with_para_ids(vec![( - 1001, - empty_genesis_data(), - vec![], - u32::MAX, - u32::MAX, - ) - .into()]) + .with_para_ids(vec![(1001, empty_genesis_data(), u32::MAX, u32::MAX).into()]) .with_config(pallet_configuration::HostConfiguration { max_collators: 100, min_orchestrator_collators: 1, @@ -3697,9 +3644,9 @@ fn test_collator_assignment_tip_priority_on_congestion() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3752,9 +3699,9 @@ fn test_collator_assignment_tip_charged_on_congestion() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3800,9 +3747,9 @@ fn test_collator_assignment_tip_not_assigned_on_insufficient_balance() { (AccountId::from(DAVE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3853,9 +3800,9 @@ fn test_collator_assignment_tip_only_charge_willing_paras() { (AccountId::from(FERDIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3925,9 +3872,9 @@ fn test_collator_assignment_tip_withdraw_min_tip() { (AccountId::from(FERDIE), 100 * UNIT), ]) .with_para_ids(vec![ - (1001, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1002, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), - (1003, empty_genesis_data(), vec![], u32::MAX, u32::MAX).into(), + (1001, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1002, empty_genesis_data(), u32::MAX, u32::MAX).into(), + (1003, empty_genesis_data(), u32::MAX, u32::MAX).into(), ]) .build() .execute_with(|| { @@ -3988,3 +3935,173 @@ fn test_collator_assignment_tip_withdraw_min_tip() { ); }); } + +#[test] +fn test_migration_data_preservers_assignments() { + ExtBuilder::default().build().execute_with(|| { + use { + flashbox_runtime::{MaxAssignmentsPerParaId, MaxNodeUrlLen}, + frame_support::{ + migration::{have_storage_value, put_storage_value}, + Blake2_128Concat, StorageHasher, + }, + pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode, RegisteredProfile}, + sp_runtime::BoundedBTreeSet, + sp_std::collections::btree_set::BTreeSet, + tanssi_runtime_common::migrations::DataPreserversAssignmentsMigration, + }; + + macro_rules! bset { + ( $($value:expr),* $(,)? ) => { + { + let mut set = BoundedBTreeSet::new(); + $( + set.try_insert($value).expect("max bound reached"); + )* + set + } + } + } + + macro_rules! set { + ( $($value:expr),* $(,)? ) => { + { + let mut set = BTreeSet::new(); + $( + set.insert($value); + )* + set + } + } + } + + let account = AccountId::from([0u8; 32]); + let free_request = flashbox_runtime::PreserversAssignementPaymentRequest::Free; + let free_witness = flashbox_runtime::PreserversAssignementPaymentWitness::Free; + + let pallet_prefix: &[u8] = b"DataPreservers"; + let storage_item_prefix: &[u8] = b"BootNodes"; + + // Register 2 parachains + assert_ok!(Registrar::register( + origin_of(ALICE.into()), + 1001.into(), + empty_genesis_data() + )); + assert_ok!(Registrar::register( + origin_of(BOB.into()), + 1002.into(), + empty_genesis_data() + )); + + // Set bootnodes in old storage + let bootnodes: BoundedVec, MaxAssignmentsPerParaId> = vec![ + b"alpha".to_vec().try_into().unwrap(), + b"beta".to_vec().try_into().unwrap(), + ] + .try_into() + .unwrap(); + put_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1001).encode()), + bootnodes, + ); + + let bootnodes: BoundedVec, MaxAssignmentsPerParaId> = vec![ + b"delta".to_vec().try_into().unwrap(), + b"gamma".to_vec().try_into().unwrap(), + ] + .try_into() + .unwrap(); + put_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1002).encode()), + bootnodes, + ); + + // Apply migration + let migration = DataPreserversAssignmentsMigration::(Default::default()); + migration.migrate(Default::default()); + + // Check old storage is empty + assert!(!have_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1001).encode()) + )); + assert!(!have_storage_value( + pallet_prefix, + storage_item_prefix, + &Blake2_128Concat::hash(&ParaId::from(1002).encode()) + )); + + // Check new storage + assert_eq!( + pallet_data_preservers::Assignments::::get(ParaId::from(1001)).into_inner(), + set![0, 1] + ); + assert_eq!( + pallet_data_preservers::Assignments::::get(ParaId::from(1002)).into_inner(), + set![2, 3] + ); + assert_eq!(pallet_data_preservers::NextProfileId::::get(), 4); + assert_eq!( + pallet_data_preservers::Profiles::::get(0), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1001.into(), free_witness)), + profile: Profile { + url: b"alpha".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1001.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + assert_eq!( + pallet_data_preservers::Profiles::::get(1), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1001.into(), free_witness)), + profile: Profile { + url: b"beta".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1001.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + assert_eq!( + pallet_data_preservers::Profiles::::get(2), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1002.into(), free_witness)), + profile: Profile { + url: b"delta".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1002.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + assert_eq!( + pallet_data_preservers::Profiles::::get(3), + Some(RegisteredProfile { + account: account.clone(), + deposit: 0, + assignment: Some((1002.into(), free_witness)), + profile: Profile { + url: b"gamma".to_vec().try_into().unwrap(), + para_ids: ParaIdsFilter::Whitelist(bset![1002.into()]), + mode: ProfileMode::Bootnode, + assignment_request: free_request, + } + }) + ); + }) +} diff --git a/test/configs/zombieTanssi.json b/test/configs/zombieTanssi.json index 02686dda5..152caf11c 100644 --- a/test/configs/zombieTanssi.json +++ b/test/configs/zombieTanssi.json @@ -18,7 +18,7 @@ }, "scheduler_params": { "scheduling_lookahead": 2 - } + } } } } diff --git a/test/configs/zombieTanssiOneNode.json b/test/configs/zombieTanssiOneNode.json index a8e999a98..91008c35c 100644 --- a/test/configs/zombieTanssiOneNode.json +++ b/test/configs/zombieTanssiOneNode.json @@ -19,7 +19,6 @@ "scheduler_params": { "scheduling_lookahead": 2 } - } } } diff --git a/test/moonwall.config.json b/test/moonwall.config.json index 3a3fcb5b8..4f16a1648 100644 --- a/test/moonwall.config.json +++ b/test/moonwall.config.json @@ -50,7 +50,14 @@ { "name": "tanssi", "binPath": "../target/release/tanssi-node", - "options": ["--chain=dancebox", "--sealing=manual", "--collator", "--dev-service", "--tmp", "--unsafe-force-node-key-generation"], + "options": [ + "--chain=dancebox", + "--sealing=manual", + "--collator", + "--dev-service", + "--tmp", + "--unsafe-force-node-key-generation" + ], "disableDefaultEthProviders": true, "newRpcBehaviour": true } diff --git a/test/scripts/sudoRegisterPara.ts b/test/scripts/sudoRegisterPara.ts index 4419461d6..c322d65b5 100644 --- a/test/scripts/sudoRegisterPara.ts +++ b/test/scripts/sudoRegisterPara.ts @@ -59,9 +59,20 @@ yargs(hideBin(process.argv)) } txs.push(tx1); if (rawSpec.bootNodes?.length) { - const tx2 = api.tx.dataPreservers.setBootNodes(rawSpec.para_id, rawSpec.bootNodes); - const tx2s = api.tx.sudo.sudo(tx2); - txs.push(tx2s); + let profileId = await api.query.dataPreservers.nextProfileId(); + for (const bootnode of rawSpec.bootNodes) { + const profileTx = api.tx.dataPreservers.createProfile({ + url: bootnode, + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + txs.push(profileTx); + + const tx2 = api.tx.dataPreservers.startAssignment(profileId++, rawSpec.para_id, "Free"); + const tx2s = api.tx.sudo.sudo(tx2); + txs.push(tx2s); + } } const tx3 = api.tx.registrar.markValidForCollating(rawSpec.para_id); const tx3s = api.tx.sudo.sudo(tx3); @@ -71,7 +82,7 @@ yargs(hideBin(process.argv)) process.stdout.write(`Sending register transaction (register + markValidForCollating)... `); } else { process.stdout.write( - `Sending register transaction (register + setBootNodes + markValidForCollating)... ` + `Sending register transaction (register + createProfile + startAssignment + markValidForCollating)... ` ); } const txBatch = api.tx.utility.batchAll(txs); @@ -173,9 +184,23 @@ yargs(hideBin(process.argv)) } bootnodes = [...bootnodes, ...argv.bootnode]; - const tx1 = api.tx.dataPreservers.setBootNodes(argv.paraId, bootnodes); - const tx1s = api.tx.sudo.sudo(tx1); - let tx2s = null; + const txs = []; + + let profileId = await api.query.dataPreservers.nextProfileId(); + for (const bootnode of bootnodes) { + const profileTx = api.tx.dataPreservers.createProfile({ + url: bootnode, + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + txs.push(profileTx); + + const tx2 = api.tx.dataPreservers.startAssignment(profileId++, argv.paraId, "Free"); + const tx2s = api.tx.sudo.sudo(tx2); + txs.push(tx2s); + } + if (argv.markValidForCollating) { // Check if not already valid, and only in that case call markValidForCollating const notValidParas = (await api.query.registrar.pendingVerification()) as any; @@ -183,19 +208,15 @@ yargs(hideBin(process.argv)) process.stdout.write(`Will set container chain valid for collating\n`); const tx2 = api.tx.registrar.markValidForCollating(argv.paraId); tx2s = api.tx.sudo.sudo(tx2); + txs.push(tx2s); } else { // ParaId already valid, or not registered at all process.stdout.write(`Not setting container chain valid for collating\n`); } } - let tx; - if (tx2s != null) { - tx = api.tx.utility.batchAll([tx1s, tx2s]); - } else { - tx = tx1s; - } + const batchTx = api.tx.utility.batchAll(txs); process.stdout.write(`Sending transaction... `); - const txHash = await tx.signAndSend(account); + const txHash = await batchTx.signAndSend(account); process.stdout.write(`${txHash.toHex()}\n`); // TODO: this will always print Done, even if the extrinsic has failed process.stdout.write(`Done ✅\n`); diff --git a/test/suites/common-tanssi/pallet-data-preservers/test_pallet_data_preservers.ts b/test/suites/common-tanssi/pallet-data-preservers/test_pallet_data_preservers.ts index 67adcc4b2..f2bdf1e40 100644 --- a/test/suites/common-tanssi/pallet-data-preservers/test_pallet_data_preservers.ts +++ b/test/suites/common-tanssi/pallet-data-preservers/test_pallet_data_preservers.ts @@ -28,6 +28,7 @@ describeSuite({ url: "exemple", paraIds: { whitelist: [42, 43] }, mode: "Bootnode", + assignmentRequest: "Free", }; const tx = polkadotJs.tx.dataPreservers.createProfile(profile); @@ -37,12 +38,14 @@ describeSuite({ const storedProfile = await polkadotJs.query.dataPreservers.profiles(profileId); expect(storedProfile.toJSON()).to.be.deep.equal({ account: general_user_bob.address, - deposit: 10_190_000_000_000, + deposit: 10_200_000_000_000, profile: { url: "0x6578656d706c65", paraIds: { whitelist: [42, 43] }, mode: { bootnode: null }, + assignmentRequest: "Free", }, + assignment: null, }); }, }); @@ -64,12 +67,14 @@ describeSuite({ const storedProfile = await polkadotJs.query.dataPreservers.profiles(++profileId); expect(storedProfile.toJSON()).to.be.deep.equal({ account: general_user_bob.address, - deposit: 10_190_000_000_000, + deposit: 10_200_000_000_000, profile: { url: "0x6578656d706c65", paraIds: { whitelist: [42, 43] }, mode: { bootnode: null }, + assignmentRequest: "Free", }, + assignment: null, }); const profile2 = { @@ -85,12 +90,14 @@ describeSuite({ const storedProfile2 = await polkadotJs.query.dataPreservers.profiles(profileId); expect(storedProfile2.toJSON()).to.be.deep.equal({ account: general_user_bob.address, - deposit: 10_210_000_000_000, + deposit: 10_220_000_000_000, profile: { url: "0x6578656d706c6532", paraIds: { whitelist: [42, 43] }, mode: { rpc: { supportsEthereumRpcs: false } }, + assignmentRequest: "Free", }, + assignment: null, }); }, }); @@ -112,12 +119,14 @@ describeSuite({ const storedProfile = await polkadotJs.query.dataPreservers.profiles(++profileId); expect(storedProfile.toJSON()).to.be.deep.equal({ account: general_user_bob.address, - deposit: 10_190_000_000_000, + deposit: 10_200_000_000_000, profile: { url: "0x6578656d706c65", paraIds: { whitelist: [42, 43] }, mode: { bootnode: null }, + assignmentRequest: "Free", }, + assignment: null, }); const tx2 = polkadotJs.tx.dataPreservers.deleteProfile(profileId); @@ -151,7 +160,9 @@ describeSuite({ url: "0x6578656d706c65", paraIds: { whitelist: [42, 43] }, mode: { bootnode: null }, + assignmentRequest: "Free", }, + assignment: null, }); }, }); @@ -173,12 +184,14 @@ describeSuite({ const storedProfile = await polkadotJs.query.dataPreservers.profiles(++profileId); expect(storedProfile.toJSON()).to.be.deep.equal({ account: general_user_bob.address, - deposit: 10_190_000_000_000, + deposit: 10_200_000_000_000, profile: { url: "0x6578656d706c65", paraIds: { whitelist: [42, 43] }, mode: { bootnode: null }, + assignmentRequest: "Free", }, + assignment: null, }); const profile2 = { @@ -199,7 +212,9 @@ describeSuite({ url: "0x6578656d706c6532", paraIds: { whitelist: [42, 43] }, mode: { rpc: { supportsEthereumRpcs: false } }, + assignmentRequest: "Free", }, + assignment: null, }); }, }); @@ -221,12 +236,14 @@ describeSuite({ const storedProfile = await polkadotJs.query.dataPreservers.profiles(++profileId); expect(storedProfile.toJSON()).to.be.deep.equal({ account: general_user_bob.address, - deposit: 10_190_000_000_000, + deposit: 10_200_000_000_000, profile: { url: "0x6578656d706c65", paraIds: { whitelist: [42, 43] }, mode: { bootnode: null }, + assignmentRequest: "Free", }, + assignment: null, }); const tx2 = polkadotJs.tx.dataPreservers.forceDeleteProfile(profileId); @@ -238,5 +255,298 @@ describeSuite({ expect(storedProfile2.toJSON()).to.be.equal(null); }, }); + + it({ + id: "E07", + title: "Profile can be assigned", + test: async function () { + const paraId = 2002; + const slotFrequency = polkadotJs.createType("TpTraitsSlotFrequency", { + min: 1, + max: 1, + }); + const emptyGenesisData = () => { + const g = polkadotJs.createType("TpContainerChainGenesisDataContainerChainGenesisData", { + storage: [ + { + key: "0x636f6465", + value: "0x010203040506", + }, + ], + name: "0x436f6e7461696e657220436861696e2032303030", + id: "0x636f6e7461696e65722d636861696e2d32303030", + forkId: null, + extensions: "0x", + properties: { + tokenMetadata: { + tokenSymbol: "0x61626364", + ss58Format: 42, + tokenDecimals: 12, + }, + isEthereum: false, + }, + }); + return g; + }; + const containerChainGenesisData = emptyGenesisData(); + + const registerTx = polkadotJs.tx.registrar.registerParathread( + paraId, + slotFrequency, + containerChainGenesisData + ); + await context.createBlock([await registerTx.signAsync(sudo_alice)]); + + const profile = { + url: "exemple", + paraIds: { whitelist: [paraId] }, + mode: "Bootnode", + assignmentRequest: "Free", + }; + + const profileTx = polkadotJs.tx.dataPreservers.createProfile(profile); + await context.createBlock([await profileTx.signAsync(general_user_bob)]); + profileId++; + + const assignTx = polkadotJs.tx.dataPreservers.startAssignment(profileId, paraId, "Free"); + await context.createBlock([await assignTx.signAsync(sudo_alice)]); + + expect((await polkadotJs.query.dataPreservers.assignments(paraId)).toJSON()).to.deep.equal([profileId]); + + const storedProfile = await polkadotJs.query.dataPreservers.profiles(profileId); + expect(storedProfile.toJSON()).to.be.deep.equal({ + account: general_user_bob.address, + deposit: 10_160_000_000_000, + profile: { + url: "0x6578656d706c65", + paraIds: { whitelist: [paraId] }, + mode: { bootnode: null }, + assignmentRequest: "Free", + }, + assignment: [paraId, "Free"], + }); + }, + }); + + it({ + id: "E08", + title: "Profile can be force assigned", + test: async function () { + const paraId = 2003; + const slotFrequency = polkadotJs.createType("TpTraitsSlotFrequency", { + min: 1, + max: 1, + }); + const emptyGenesisData = () => { + const g = polkadotJs.createType("TpContainerChainGenesisDataContainerChainGenesisData", { + storage: [ + { + key: "0x636f6465", + value: "0x010203040506", + }, + ], + name: "0x436f6e7461696e657220436861696e2032303030", + id: "0x636f6e7461696e65722d636861696e2d32303030", + forkId: null, + extensions: "0x", + properties: { + tokenMetadata: { + tokenSymbol: "0x61626364", + ss58Format: 42, + tokenDecimals: 12, + }, + isEthereum: false, + }, + }); + return g; + }; + const containerChainGenesisData = emptyGenesisData(); + + const registerTx = polkadotJs.tx.registrar.registerParathread( + paraId, + slotFrequency, + containerChainGenesisData + ); + await context.createBlock([await registerTx.signAsync(sudo_alice)]); + + const profile = { + url: "exemple", + paraIds: { whitelist: [paraId] }, + mode: "Bootnode", + assignmentRequest: "Free", + }; + + const profileTx = polkadotJs.tx.dataPreservers.createProfile(profile); + await context.createBlock([await profileTx.signAsync(general_user_bob)]); + ++profileId; + + const assignTx = polkadotJs.tx.dataPreservers.forceStartAssignment(profileId, paraId, "Free"); + await context.createBlock([await polkadotJs.tx.sudo.sudo(assignTx).signAsync(sudo_alice)]); + + expect((await polkadotJs.query.dataPreservers.assignments(paraId)).toJSON()).to.deep.equal([profileId]); + + const storedProfile = await polkadotJs.query.dataPreservers.profiles(profileId); + expect(storedProfile.toJSON()).to.be.deep.equal({ + account: general_user_bob.address, + deposit: 10_160_000_000_000, + profile: { + url: "0x6578656d706c65", + paraIds: { whitelist: [paraId] }, + mode: { bootnode: null }, + assignmentRequest: "Free", + }, + assignment: [paraId, "Free"], + }); + }, + }); + + it({ + id: "E09", + title: "Profile can be unassigned", + test: async function () { + const paraId = 2004; + const slotFrequency = polkadotJs.createType("TpTraitsSlotFrequency", { + min: 1, + max: 1, + }); + const emptyGenesisData = () => { + const g = polkadotJs.createType("TpContainerChainGenesisDataContainerChainGenesisData", { + storage: [ + { + key: "0x636f6465", + value: "0x010203040506", + }, + ], + name: "0x436f6e7461696e657220436861696e2032303030", + id: "0x636f6e7461696e65722d636861696e2d32303030", + forkId: null, + extensions: "0x", + properties: { + tokenMetadata: { + tokenSymbol: "0x61626364", + ss58Format: 42, + tokenDecimals: 12, + }, + isEthereum: false, + }, + }); + return g; + }; + const containerChainGenesisData = emptyGenesisData(); + + const registerTx = polkadotJs.tx.registrar.registerParathread( + paraId, + slotFrequency, + containerChainGenesisData + ); + await context.createBlock([await registerTx.signAsync(sudo_alice)]); + + const profile = { + url: "exemple", + paraIds: { whitelist: [paraId] }, + mode: "Bootnode", + assignmentRequest: "Free", + }; + + const profileTx = polkadotJs.tx.dataPreservers.createProfile(profile); + await context.createBlock([await profileTx.signAsync(general_user_bob)]); + profileId++; + + const assignTx = polkadotJs.tx.dataPreservers.startAssignment(profileId, paraId, "Free"); + const unassignTx = polkadotJs.tx.dataPreservers.stopAssignment(profileId, paraId); + await context.createBlock(); + await context.createBlock([await assignTx.signAsync(sudo_alice)]); + await context.createBlock([await unassignTx.signAsync(sudo_alice)]); + + expect((await polkadotJs.query.dataPreservers.assignments(paraId)).toJSON()).to.deep.equal([]); + + const storedProfile = await polkadotJs.query.dataPreservers.profiles(profileId); + expect(storedProfile.toJSON()).to.be.deep.equal({ + account: general_user_bob.address, + deposit: 10_160_000_000_000, + profile: { + url: "0x6578656d706c65", + paraIds: { whitelist: [paraId] }, + mode: { bootnode: null }, + assignmentRequest: "Free", + }, + assignment: null, + }); + }, + }); + + it({ + id: "E09", + title: "Profile can be force unassigned", + test: async function () { + const paraId = 2005; + const slotFrequency = polkadotJs.createType("TpTraitsSlotFrequency", { + min: 1, + max: 1, + }); + const emptyGenesisData = () => { + const g = polkadotJs.createType("TpContainerChainGenesisDataContainerChainGenesisData", { + storage: [ + { + key: "0x636f6465", + value: "0x010203040506", + }, + ], + name: "0x436f6e7461696e657220436861696e2032303030", + id: "0x636f6e7461696e65722d636861696e2d32303030", + forkId: null, + extensions: "0x", + properties: { + tokenMetadata: { + tokenSymbol: "0x61626364", + ss58Format: 42, + tokenDecimals: 12, + }, + isEthereum: false, + }, + }); + return g; + }; + const containerChainGenesisData = emptyGenesisData(); + + const registerTx = polkadotJs.tx.registrar.registerParathread( + paraId, + slotFrequency, + containerChainGenesisData + ); + await context.createBlock([await registerTx.signAsync(sudo_alice)]); + + const profile = { + url: "exemple", + paraIds: { whitelist: [paraId] }, + mode: "Bootnode", + assignmentRequest: "Free", + }; + + const profileTx = polkadotJs.tx.dataPreservers.createProfile(profile); + await context.createBlock([await profileTx.signAsync(general_user_bob)]); + profileId++; + + const assignTx = polkadotJs.tx.dataPreservers.startAssignment(profileId, paraId, "Free"); + const unassignTx = polkadotJs.tx.dataPreservers.stopAssignment(profileId, paraId); + await context.createBlock([await assignTx.signAsync(sudo_alice)]); + await context.createBlock([await polkadotJs.tx.sudo.sudo(unassignTx).signAsync(sudo_alice)]); + + expect((await polkadotJs.query.dataPreservers.assignments(paraId)).toJSON()).to.deep.equal([]); + + const storedProfile = await polkadotJs.query.dataPreservers.profiles(profileId); + expect(storedProfile.toJSON()).to.be.deep.equal({ + account: general_user_bob.address, + deposit: 10_160_000_000_000, + profile: { + url: "0x6578656d706c65", + paraIds: { whitelist: [paraId] }, + mode: { bootnode: null }, + assignmentRequest: "Free", + }, + assignment: null, + }); + }, + }); }, }); diff --git a/test/suites/common-tanssi/registrar/test_registrar_proxy.ts b/test/suites/common-tanssi/registrar/test_registrar_proxy.ts index b15453d15..307c49de9 100644 --- a/test/suites/common-tanssi/registrar/test_registrar_proxy.ts +++ b/test/suites/common-tanssi/registrar/test_registrar_proxy.ts @@ -87,18 +87,24 @@ describeSuite({ // TODO: fix once we have types expect(emptyGenesisData().toJSON()).to.deep.equal(onChainGenesisData.toJSON()); + const profileId = await polkadotJs.query.dataPreservers.nextProfileId(); + const profileTx = polkadotJs.tx.dataPreservers.createProfile({ + url: "dummy", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + // assert we can inject bootnodes with proxy const tx3 = polkadotJs.tx.proxy.proxy( bob.address, null, - polkadotJs.tx.dataPreservers.setBootNodes(2002, ["dummy"]) + polkadotJs.tx.dataPreservers.startAssignment(profileId, 2002, "Free") ); - await context.createBlock([await tx3.signAsync(charlie)]); + await context.createBlock([await profileTx.signAsync(alice), await tx3.signAsync(charlie)]); - // Check that the on chain genesis data is set correctly - const onChainBootnodes = await polkadotJs.query.dataPreservers.bootNodes(2002); - // TODO: fix once we have types - expect(onChainBootnodes.toHuman()).to.deep.equal(["dummy"]); + const assignments = await polkadotJs.query.dataPreservers.assignments(2002); + expect(assignments.toJSON()).to.deep.equal([profileId.toJSON()]); }, }); diff --git a/test/suites/common-tanssi/registrar/test_registrar_register.ts b/test/suites/common-tanssi/registrar/test_registrar_register.ts index 256064332..6cde14d9a 100644 --- a/test/suites/common-tanssi/registrar/test_registrar_register.ts +++ b/test/suites/common-tanssi/registrar/test_registrar_register.ts @@ -11,9 +11,11 @@ describeSuite({ testCases: ({ it, context }) => { let polkadotJs: ApiPromise; let alice: KeyringPair; + let charlie: KeyringPair; beforeAll(() => { alice = context.keyring.alice; + charlie = context.keyring.charlie; polkadotJs = context.polkadotJs(); }); @@ -64,16 +66,23 @@ describeSuite({ return g; }; const containerChainGenesisData = emptyGenesisData(); - const bootNodes = [ - "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", - ]; const tx = polkadotJs.tx.registrar.register(2002, containerChainGenesisData); - const tx2 = polkadotJs.tx.dataPreservers.setBootNodes(2002, bootNodes); + + const profileId = await polkadotJs.query.dataPreservers.nextProfileId(); + const profileTx = polkadotJs.tx.dataPreservers.createProfile({ + url: "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + + const tx2 = polkadotJs.tx.dataPreservers.startAssignment(profileId, 2002, "Free"); const tx3 = polkadotJs.tx.registrar.markValidForCollating(2002); const nonce = await polkadotJs.rpc.system.accountNextIndex(alice.publicKey); await context.createBlock([ await tx.signAsync(alice, { nonce }), + await profileTx.signAsync(charlie), await tx2.signAsync(alice, { nonce: nonce.addn(1) }), await polkadotJs.tx.sudo.sudo(tx3).signAsync(alice, { nonce: nonce.addn(2) }), ]); diff --git a/test/suites/common-tanssi/registrar/test_registrar_register_parathread.ts b/test/suites/common-tanssi/registrar/test_registrar_register_parathread.ts index d0533cf7f..ff7ff75aa 100644 --- a/test/suites/common-tanssi/registrar/test_registrar_register_parathread.ts +++ b/test/suites/common-tanssi/registrar/test_registrar_register_parathread.ts @@ -68,18 +68,25 @@ describeSuite({ return g; }; const containerChainGenesisData = emptyGenesisData(); - const bootNodes = [ - "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", - ]; const tx = polkadotJs.tx.registrar.registerParathread(2002, slotFrequency, containerChainGenesisData); - const tx2 = polkadotJs.tx.dataPreservers.setBootNodes(2002, bootNodes); - const tx3 = polkadotJs.tx.registrar.markValidForCollating(2002); + + const profileId = await polkadotJs.query.dataPreservers.nextProfileId(); + const tx2 = polkadotJs.tx.dataPreservers.createProfile({ + url: "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + + const tx3 = polkadotJs.tx.dataPreservers.startAssignment(profileId, 2002, "Free"); + const tx4 = polkadotJs.tx.registrar.markValidForCollating(2002); const nonce = await polkadotJs.rpc.system.accountNextIndex(alice.publicKey); await context.createBlock([ await tx.signAsync(alice, { nonce }), await tx2.signAsync(alice, { nonce: nonce.addn(1) }), - await polkadotJs.tx.sudo.sudo(tx3).signAsync(alice, { nonce: nonce.addn(2) }), + await tx3.signAsync(alice, { nonce: nonce.addn(2) }), + await polkadotJs.tx.sudo.sudo(tx4).signAsync(alice, { nonce: nonce.addn(3) }), ]); const pendingParas = await polkadotJs.query.registrar.pendingParaIds(); diff --git a/test/suites/dev-tanssi/register-with-relay-proof/test_deregister_with_relay_proof.ts b/test/suites/dev-tanssi/register-with-relay-proof/test_deregister_with_relay_proof.ts index b930d3bdf..c2ba58c00 100644 --- a/test/suites/dev-tanssi/register-with-relay-proof/test_deregister_with_relay_proof.ts +++ b/test/suites/dev-tanssi/register-with-relay-proof/test_deregister_with_relay_proof.ts @@ -54,16 +54,24 @@ describeSuite({ return g; }; const containerChainGenesisData = emptyGenesisData(); - const bootNodes = [ - "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", - ]; const tx = polkadotJs.tx.registrar.register(2003, containerChainGenesisData); - const tx2 = polkadotJs.tx.dataPreservers.setBootNodes(2003, bootNodes); + + const profileId = await polkadotJs.query.dataPreservers.nextProfileId(); + const profileTx = polkadotJs.tx.dataPreservers.createProfile({ + url: "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + + const tx2 = polkadotJs.tx.dataPreservers.startAssignment(profileId, 2003, "Free"); + const tx3 = polkadotJs.tx.registrar.markValidForCollating(2003); const nonce = await polkadotJs.rpc.system.accountNextIndex(alice.publicKey); await context.createBlock([ await tx.signAsync(alice, { nonce }), + await profileTx.signAsync(bob), await tx2.signAsync(alice, { nonce: nonce.addn(1) }), await polkadotJs.tx.sudo.sudo(tx3).signAsync(alice, { nonce: nonce.addn(2) }), ]); diff --git a/test/suites/dev-tanssi/register-with-relay-proof/test_register_with_relay_proof.ts b/test/suites/dev-tanssi/register-with-relay-proof/test_register_with_relay_proof.ts index ab49350a9..1740777b3 100644 --- a/test/suites/dev-tanssi/register-with-relay-proof/test_register_with_relay_proof.ts +++ b/test/suites/dev-tanssi/register-with-relay-proof/test_register_with_relay_proof.ts @@ -11,10 +11,12 @@ describeSuite({ testCases: ({ it, context }) => { let polkadotJs: ApiPromise; let alice: KeyringPair; + let charlie: KeyringPair; let relayManager: KeyringPair; beforeAll(() => { alice = context.keyring.alice; + charlie = context.keyring.charlie; polkadotJs = context.polkadotJs(); // We must generate the same account as in service.rs, using get_ed25519_pairs @@ -74,10 +76,6 @@ describeSuite({ return g; }; const containerChainGenesisData = emptyGenesisData(); - const bootNodes = [ - "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", - ]; - const { relayProofBlockNumber, relayStorageProof } = await fetchStorageProofFromValidationData( polkadotJs ); @@ -106,11 +104,21 @@ describeSuite({ managerSignature, containerChainGenesisData ); - const tx2 = polkadotJs.tx.dataPreservers.setBootNodes(2002, bootNodes); + + const profileId = await polkadotJs.query.dataPreservers.nextProfileId(); + const profileTx = polkadotJs.tx.dataPreservers.createProfile({ + url: "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + + const tx2 = polkadotJs.tx.dataPreservers.startAssignment(profileId, 2002, "Free"); const tx3 = polkadotJs.tx.registrar.markValidForCollating(2002); const nonce = await polkadotJs.rpc.system.accountNextIndex(alice.publicKey); await context.createBlock([ await tx.signAsync(alice, { nonce }), + await profileTx.signAsync(charlie), await tx2.signAsync(alice, { nonce: nonce.addn(1) }), await polkadotJs.tx.sudo.sudo(tx3).signAsync(alice, { nonce: nonce.addn(2) }), ]); diff --git a/test/suites/dev-tanssi/xcm-core-buyer/test_xcm_core_buyer.ts b/test/suites/dev-tanssi/xcm-core-buyer/test_xcm_core_buyer.ts index f4bd703d6..d8c113535 100644 --- a/test/suites/dev-tanssi/xcm-core-buyer/test_xcm_core_buyer.ts +++ b/test/suites/dev-tanssi/xcm-core-buyer/test_xcm_core_buyer.ts @@ -15,12 +15,14 @@ describeSuite({ testCases: ({ it, context }) => { let polkadotJs: ApiPromise; let alice: KeyringPair; + let charlie: KeyringPair; let keyring: Keyring; let collatorNimbusKey: KeyringPair; let collatorAccountKey: KeyringPair; beforeAll(async () => { alice = context.keyring.alice; + charlie = context.keyring.charlie; polkadotJs = context.polkadotJs(); keyring = new Keyring({ type: "sr25519" }); collatorNimbusKey = keyring.addFromUri("//" + "COLLATOR_NIMBUS", { name: "COLLATOR" + " NIMBUS" }); @@ -86,15 +88,20 @@ describeSuite({ return g; }; const containerChainGenesisData = emptyGenesisData(); - const bootNodes = [ - "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", - ]; // Let's disable all other parachains and set parathread collator to 4 // this will make every collator including the one we are registering being assigned to our parathread - const tx = polkadotJs.tx.registrar.registerParathread(2002, slotFrequency, containerChainGenesisData); - const tx2 = polkadotJs.tx.dataPreservers.setBootNodes(2002, bootNodes); + + const profileId = await polkadotJs.query.dataPreservers.nextProfileId(); + const profileTx = polkadotJs.tx.dataPreservers.createProfile({ + url: "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + + const tx2 = polkadotJs.tx.dataPreservers.startAssignment(profileId, 2002, "Free"); const tx3 = polkadotJs.tx.registrar.markValidForCollating(2002); const tx4 = polkadotJs.tx.configuration.setFullRotationPeriod(0); const tx5 = polkadotJs.tx.registrar.deregister(2000); @@ -102,6 +109,7 @@ describeSuite({ const nonce = await polkadotJs.rpc.system.accountNextIndex(alice.publicKey); await context.createBlock([ await tx.signAsync(alice, { nonce }), + await profileTx.signAsync(charlie), await tx2.signAsync(alice, { nonce: nonce.addn(1) }), await polkadotJs.tx.sudo.sudo(tx3).signAsync(alice, { nonce: nonce.addn(2) }), await polkadotJs.tx.sudo.sudo(tx4).signAsync(alice, { nonce: nonce.addn(3) }), diff --git a/test/suites/one-node/test_tanssi_one_node.ts b/test/suites/one-node/test_tanssi_one_node.ts index a3bd553f8..99f8d6057 100644 --- a/test/suites/one-node/test_tanssi_one_node.ts +++ b/test/suites/one-node/test_tanssi_one_node.ts @@ -81,9 +81,18 @@ describeSuite({ const containerChainCollators = ( await paraApi.query.authorityAssignment.collatorContainerChain(currentSession) ).toJSON().containerChains; - // Stop waiting when parathreads have been assigned collators - return containerChainCollators[2000] != undefined && containerChainCollators[2001] != undefined; + // Stop waiting when parathread has been assigned collators + return containerChainCollators[2000] != undefined; }); + + const currentSession = (await paraApi.query.session.currentIndex()).toNumber(); + const containerChainCollators = ( + await paraApi.query.authorityAssignment.collatorContainerChain(currentSession) + ).toJSON().containerChains; + expect( + containerChainCollators[2000] != undefined, + "Failed to register parathread: no collators assigned" + ).to.be.true; }, }); @@ -190,11 +199,21 @@ async function registerEmptyParathread(api, manager, paraId) { tx1 ) ); - const bootNodes = ["/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw"]; - const tx2 = api.tx.dataPreservers.setBootNodes(paraId, bootNodes); - txs.push(tx2); - const tx3 = api.tx.registrar.markValidForCollating(paraId); - txs.push(tx3); + + const profileId = await api.query.dataPreservers.nextProfileId(); + txs.push( + api.tx.dataPreservers.forceCreateProfile( + { + url: "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }, + manager + ) + ); + txs.push(api.tx.dataPreservers.forceStartAssignment(profileId, paraId, "Free")); + txs.push(api.tx.registrar.markValidForCollating(paraId)); return txs; } diff --git a/test/suites/para/test_tanssi_containers.ts b/test/suites/para/test_tanssi_containers.ts index 6d79857cf..c33b82298 100644 --- a/test/suites/para/test_tanssi_containers.ts +++ b/test/suites/para/test_tanssi_containers.ts @@ -243,15 +243,22 @@ describeSuite({ const purchasedCredits = 100000n; const requiredBalance = purchasedCredits * 1_000_000n; const tx2 = paraApi.tx.servicesPayment.purchaseCredits(2002, requiredBalance); - const bootNodes = [ - "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", - ]; - const tx3 = paraApi.tx.dataPreservers.setBootNodes(2002, bootNodes); + + const profileId = await paraApi.query.dataPreservers.nextProfileId(); + const profileTx = paraApi.tx.dataPreservers.createProfile({ + url: "/ip4/127.0.0.1/tcp/33051/ws/p2p/12D3KooWSDsmAa7iFbHdQW4X8B2KbeRYPDLarK6EbevUSYfGkeQw", + paraIds: "AnyParaId", + mode: "Bootnode", + assignmentRequest: "Free", + }); + + const tx3 = paraApi.tx.dataPreservers.forceStartAssignment(profileId, 2002, "Free"); const tx4 = paraApi.tx.registrar.markValidForCollating(2002); // Send the batch transaction: [register, purchaseCredits, sudo(setBootNodes), sudo(markValidForCollating)] const txBatch = paraApi.tx.utility.batchAll([ tx1, tx2, + profileTx, paraApi.tx.sudo.sudo(tx3), paraApi.tx.sudo.sudo(tx4), ]); diff --git a/test/suites/parathreads/test_tanssi_parathreads.ts b/test/suites/parathreads/test_tanssi_parathreads.ts index 0a6482f62..5ed9ba97c 100644 --- a/test/suites/parathreads/test_tanssi_parathreads.ts +++ b/test/suites/parathreads/test_tanssi_parathreads.ts @@ -94,8 +94,9 @@ describeSuite({ test: async function () { const keyring = new Keyring({ type: "sr25519" }); const alice = keyring.addFromUri("//Alice", { name: "Alice default" }); - const txs2000 = await registerParathread(paraApi, alice.address, 2000); - const txs2001 = await registerParathread(paraApi, alice.address, 2001); + const profileIdPtr = [await paraApi.query.dataPreservers.nextProfileId()]; + const txs2000 = await registerParathread(paraApi, alice.address, 2000, profileIdPtr); + const txs2001 = await registerParathread(paraApi, alice.address, 2001, profileIdPtr); const slotFrequency2000 = paraApi.createType("TpTraitsSlotFrequency", { min: 5, @@ -125,6 +126,15 @@ describeSuite({ // Stop waiting when parathreads have been assigned collators return containerChainCollators[2000] != undefined && containerChainCollators[2001] != undefined; }); + + const currentSession = (await paraApi.query.session.currentIndex()).toNumber(); + const containerChainCollators = ( + await paraApi.query.authorityAssignment.collatorContainerChain(currentSession) + ).toJSON().containerChains; + expect( + containerChainCollators[2000] != undefined && containerChainCollators[2001] != undefined, + "Failed to register parathreads: no collators assigned" + ).to.be.true; }, }); @@ -328,7 +338,7 @@ function createCollatorKeyToNameMap(paraApi, collatorNames: string[]): Record; - maxBootNodeUrlLen: u32 & AugmentedConst; + maxAssignmentsPerParaId: u32 & AugmentedConst; + maxNodeUrlLen: u32 & AugmentedConst; maxParaIdsVecLen: u32 & AugmentedConst; /** Generic const */ [key: string]: Codec; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts index 622a19ab0..d34d87da8 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts @@ -78,10 +78,18 @@ declare module "@polkadot/api-base/types/errors" { [key: string]: AugmentedError; }; dataPreservers: { + /** Made for `AssignmentPayment` implementors to report a mismatch between `ProviderRequest` and `AssignerParameter`. */ + AssignmentPaymentRequestParameterMismatch: AugmentedError; + CantDeleteAssignedProfile: AugmentedError; + MaxAssignmentsPerParaIdReached: AugmentedError; NextProfileIdShouldBeAvailable: AugmentedError; /** This container chain does not have any boot nodes */ NoBootNodes: AugmentedError; + ProfileAlreadyAssigned: AugmentedError; + ProfileIsNotElligibleForParaId: AugmentedError; + ProfileNotAssigned: AugmentedError; UnknownProfileId: AugmentedError; + WrongParaId: AugmentedError; /** Generic error */ [key: string]: AugmentedError; }; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-events.ts b/typescript-api/src/dancebox/interfaces/augment-api-events.ts index 9f873becd..cf252fa6b 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-events.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-events.ts @@ -156,6 +156,8 @@ declare module "@polkadot/api-base/types/events" { [key: string]: AugmentedEvent; }; dataPreservers: { + AssignmentStarted: AugmentedEvent; + AssignmentStopped: AugmentedEvent; /** The list of boot_nodes changed. */ BootNodesChanged: AugmentedEvent; ProfileCreated: AugmentedEvent< diff --git a/typescript-api/src/dancebox/interfaces/augment-api-query.ts b/typescript-api/src/dancebox/interfaces/augment-api-query.ts index 5a8d9f9ba..6df00b8fb 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-query.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-query.ts @@ -301,7 +301,11 @@ declare module "@polkadot/api-base/types/storage" { [key: string]: QueryableStorageEntry; }; dataPreservers: { - bootNodes: AugmentedQuery Observable>, [u32]> & + assignments: AugmentedQuery< + ApiType, + (arg: u32 | AnyNumber | Uint8Array) => Observable>, + [u32] + > & QueryableStorageEntry; nextProfileId: AugmentedQuery Observable, []> & QueryableStorageEntry; profiles: AugmentedQuery< diff --git a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts index 7f1c10b7e..7fb765365 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts @@ -19,6 +19,8 @@ import type { CumulusPrimitivesCoreAggregateMessageOrigin, CumulusPrimitivesParachainInherentParachainInherentData, DanceboxRuntimeOriginCaller, + DanceboxRuntimePreserversAssignementPaymentExtra, + DanceboxRuntimePreserversAssignementPaymentWitness, DanceboxRuntimeProxyType, DanceboxRuntimeSessionKeys, DanceboxRuntimeStreamPaymentAssetId, @@ -362,7 +364,7 @@ declare module "@polkadot/api-base/types/submittable" { ( profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array ) => SubmittableExtrinsic, @@ -376,7 +378,7 @@ declare module "@polkadot/api-base/types/submittable" { ( profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array, forAccount: AccountId32 | string | Uint8Array @@ -387,31 +389,46 @@ declare module "@polkadot/api-base/types/submittable" { (profileId: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u64] >; + forceStartAssignment: AugmentedSubmittable< + ( + profileId: u64 | AnyNumber | Uint8Array, + paraId: u32 | AnyNumber | Uint8Array, + assignmentWitness: DanceboxRuntimePreserversAssignementPaymentWitness | "Free" | number | Uint8Array + ) => SubmittableExtrinsic, + [u64, u32, DanceboxRuntimePreserversAssignementPaymentWitness] + >; forceUpdateProfile: AugmentedSubmittable< ( profileId: u64 | AnyNumber | Uint8Array, profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array ) => SubmittableExtrinsic, [u64, PalletDataPreserversProfile] >; - /** Set boot_nodes for this para id */ - setBootNodes: AugmentedSubmittable< + startAssignment: AugmentedSubmittable< ( + profileId: u64 | AnyNumber | Uint8Array, paraId: u32 | AnyNumber | Uint8Array, - bootNodes: Vec | (Bytes | string | Uint8Array)[] + assignerParam: DanceboxRuntimePreserversAssignementPaymentExtra | "Free" | number | Uint8Array + ) => SubmittableExtrinsic, + [u64, u32, DanceboxRuntimePreserversAssignementPaymentExtra] + >; + stopAssignment: AugmentedSubmittable< + ( + profileId: u64 | AnyNumber | Uint8Array, + paraId: u32 | AnyNumber | Uint8Array ) => SubmittableExtrinsic, - [u32, Vec] + [u64, u32] >; updateProfile: AugmentedSubmittable< ( profileId: u64 | AnyNumber | Uint8Array, profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array ) => SubmittableExtrinsic, diff --git a/typescript-api/src/dancebox/interfaces/lookup.ts b/typescript-api/src/dancebox/interfaces/lookup.ts index fe473e668..9c3826e49 100644 --- a/typescript-api/src/dancebox/interfaces/lookup.ts +++ b/typescript-api/src/dancebox/interfaces/lookup.ts @@ -680,6 +680,14 @@ export default { profileId: "u64", releasedDeposit: "u128", }, + AssignmentStarted: { + profileId: "u64", + paraId: "u32", + }, + AssignmentStopped: { + profileId: "u64", + paraId: "u32", + }, }, }, /** Lookup68: pallet_invulnerables::pallet::Event */ @@ -2857,10 +2865,7 @@ export default { /** Lookup310: pallet_data_preservers::pallet::Call */ PalletDataPreserversCall: { _enum: { - set_boot_nodes: { - paraId: "u32", - bootNodes: "Vec", - }, + __Unused0: "Null", create_profile: { profile: "PalletDataPreserversProfile", }, @@ -2882,23 +2887,38 @@ export default { force_delete_profile: { profileId: "u64", }, + start_assignment: { + profileId: "u64", + paraId: "u32", + assignerParam: "DanceboxRuntimePreserversAssignementPaymentExtra", + }, + stop_assignment: { + profileId: "u64", + paraId: "u32", + }, + force_start_assignment: { + profileId: "u64", + paraId: "u32", + assignmentWitness: "DanceboxRuntimePreserversAssignementPaymentWitness", + }, }, }, - /** Lookup314: pallet_data_preservers::pallet::Profile */ + /** Lookup311: pallet_data_preservers::types::Profile */ PalletDataPreserversProfile: { url: "Bytes", paraIds: "PalletDataPreserversParaIdsFilter", mode: "PalletDataPreserversProfileMode", + assignmentRequest: "DanceboxRuntimePreserversAssignementPaymentRequest", }, - /** Lookup315: pallet_data_preservers::pallet::ParaIdsFilter */ + /** Lookup313: pallet_data_preservers::types::ParaIdsFilter */ PalletDataPreserversParaIdsFilter: { _enum: { AnyParaId: "Null", - Whitelist: "Vec", - Blacklist: "Vec", + Whitelist: "BTreeSet", + Blacklist: "BTreeSet", }, }, - /** Lookup317: pallet_data_preservers::pallet::ProfileMode */ + /** Lookup316: pallet_data_preservers::types::ProfileMode */ PalletDataPreserversProfileMode: { _enum: { Bootnode: "Null", @@ -2907,7 +2927,19 @@ export default { }, }, }, - /** Lookup318: pallet_invulnerables::pallet::Call */ + /** Lookup317: dancebox_runtime::PreserversAssignementPaymentRequest */ + DanceboxRuntimePreserversAssignementPaymentRequest: { + _enum: ["Free"], + }, + /** Lookup318: dancebox_runtime::PreserversAssignementPaymentExtra */ + DanceboxRuntimePreserversAssignementPaymentExtra: { + _enum: ["Free"], + }, + /** Lookup319: dancebox_runtime::PreserversAssignementPaymentWitness */ + DanceboxRuntimePreserversAssignementPaymentWitness: { + _enum: ["Free"], + }, + /** Lookup320: pallet_invulnerables::pallet::Call */ PalletInvulnerablesCall: { _enum: { __Unused0: "Null", @@ -2919,7 +2951,7 @@ export default { }, }, }, - /** Lookup319: pallet_session::pallet::Call */ + /** Lookup321: pallet_session::pallet::Call */ PalletSessionCall: { _enum: { set_keys: { @@ -2932,17 +2964,17 @@ export default { purge_keys: "Null", }, }, - /** Lookup320: dancebox_runtime::SessionKeys */ + /** Lookup322: dancebox_runtime::SessionKeys */ DanceboxRuntimeSessionKeys: { nimbus: "NimbusPrimitivesNimbusCryptoPublic", }, - /** Lookup321: nimbus_primitives::nimbus_crypto::Public */ + /** Lookup323: nimbus_primitives::nimbus_crypto::Public */ NimbusPrimitivesNimbusCryptoPublic: "[u8;32]", - /** Lookup322: pallet_author_inherent::pallet::Call */ + /** Lookup324: pallet_author_inherent::pallet::Call */ PalletAuthorInherentCall: { _enum: ["kick_off_authorship_validation"], }, - /** Lookup323: pallet_pooled_staking::pallet::Call */ + /** Lookup325: pallet_pooled_staking::pallet::Call */ PalletPooledStakingCall: { _enum: { rebalance_hold: { @@ -2976,16 +3008,16 @@ export default { }, }, }, - /** Lookup324: pallet_pooled_staking::pallet::AllTargetPool */ + /** Lookup326: pallet_pooled_staking::pallet::AllTargetPool */ PalletPooledStakingAllTargetPool: { _enum: ["Joining", "AutoCompounding", "ManualRewards", "Leaving"], }, - /** Lookup326: pallet_pooled_staking::pallet::PendingOperationQuery */ + /** Lookup328: pallet_pooled_staking::pallet::PendingOperationQuery */ PalletPooledStakingPendingOperationQuery: { delegator: "AccountId32", operation: "PalletPooledStakingPendingOperationKey", }, - /** Lookup327: pallet_pooled_staking::pallet::PendingOperationKey */ + /** Lookup329: pallet_pooled_staking::pallet::PendingOperationKey */ PalletPooledStakingPendingOperationKey: { _enum: { JoiningAutoCompounding: { @@ -3002,14 +3034,14 @@ export default { }, }, }, - /** Lookup328: pallet_pooled_staking::pallet::SharesOrStake */ + /** Lookup330: pallet_pooled_staking::pallet::SharesOrStake */ PalletPooledStakingSharesOrStake: { _enum: { Shares: "u128", Stake: "u128", }, }, - /** Lookup331: pallet_treasury::pallet::Call */ + /** Lookup333: pallet_treasury::pallet::Call */ PalletTreasuryCall: { _enum: { propose_spend: { @@ -3046,7 +3078,7 @@ export default { }, }, }, - /** Lookup332: cumulus_pallet_xcmp_queue::pallet::Call */ + /** Lookup334: cumulus_pallet_xcmp_queue::pallet::Call */ CumulusPalletXcmpQueueCall: { _enum: { __Unused0: "Null", @@ -3072,9 +3104,9 @@ export default { }, }, }, - /** Lookup333: cumulus_pallet_dmp_queue::pallet::Call */ + /** Lookup335: cumulus_pallet_dmp_queue::pallet::Call */ CumulusPalletDmpQueueCall: "Null", - /** Lookup334: pallet_xcm::pallet::Call */ + /** Lookup336: pallet_xcm::pallet::Call */ PalletXcmCall: { _enum: { send: { @@ -3149,7 +3181,7 @@ export default { }, }, }, - /** Lookup335: xcm::VersionedXcm */ + /** Lookup337: xcm::VersionedXcm */ XcmVersionedXcm: { _enum: { __Unused0: "Null", @@ -3159,9 +3191,9 @@ export default { V4: "StagingXcmV4Xcm", }, }, - /** Lookup336: xcm::v2::Xcm */ + /** Lookup338: xcm::v2::Xcm */ XcmV2Xcm: "Vec", - /** Lookup338: xcm::v2::Instruction */ + /** Lookup340: xcm::v2::Instruction */ XcmV2Instruction: { _enum: { WithdrawAsset: "XcmV2MultiassetMultiAssets", @@ -3257,7 +3289,7 @@ export default { UnsubscribeVersion: "Null", }, }, - /** Lookup339: xcm::v2::Response */ + /** Lookup341: xcm::v2::Response */ XcmV2Response: { _enum: { Null: "Null", @@ -3266,7 +3298,7 @@ export default { Version: "u32", }, }, - /** Lookup342: xcm::v2::traits::Error */ + /** Lookup344: xcm::v2::traits::Error */ XcmV2TraitsError: { _enum: { Overflow: "Null", @@ -3297,14 +3329,14 @@ export default { WeightNotComputable: "Null", }, }, - /** Lookup343: xcm::v2::multiasset::MultiAssetFilter */ + /** Lookup345: xcm::v2::multiasset::MultiAssetFilter */ XcmV2MultiassetMultiAssetFilter: { _enum: { Definite: "XcmV2MultiassetMultiAssets", Wild: "XcmV2MultiassetWildMultiAsset", }, }, - /** Lookup344: xcm::v2::multiasset::WildMultiAsset */ + /** Lookup346: xcm::v2::multiasset::WildMultiAsset */ XcmV2MultiassetWildMultiAsset: { _enum: { All: "Null", @@ -3314,20 +3346,20 @@ export default { }, }, }, - /** Lookup345: xcm::v2::multiasset::WildFungibility */ + /** Lookup347: xcm::v2::multiasset::WildFungibility */ XcmV2MultiassetWildFungibility: { _enum: ["Fungible", "NonFungible"], }, - /** Lookup346: xcm::v2::WeightLimit */ + /** Lookup348: xcm::v2::WeightLimit */ XcmV2WeightLimit: { _enum: { Unlimited: "Null", Limited: "Compact", }, }, - /** Lookup347: xcm::v3::Xcm */ + /** Lookup349: xcm::v3::Xcm */ XcmV3Xcm: "Vec", - /** Lookup349: xcm::v3::Instruction */ + /** Lookup351: xcm::v3::Instruction */ XcmV3Instruction: { _enum: { WithdrawAsset: "XcmV3MultiassetMultiAssets", @@ -3467,7 +3499,7 @@ export default { }, }, }, - /** Lookup350: xcm::v3::Response */ + /** Lookup352: xcm::v3::Response */ XcmV3Response: { _enum: { Null: "Null", @@ -3478,7 +3510,7 @@ export default { DispatchResult: "XcmV3MaybeErrorCode", }, }, - /** Lookup352: xcm::v3::PalletInfo */ + /** Lookup354: xcm::v3::PalletInfo */ XcmV3PalletInfo: { index: "Compact", name: "Bytes", @@ -3487,20 +3519,20 @@ export default { minor: "Compact", patch: "Compact", }, - /** Lookup356: xcm::v3::QueryResponseInfo */ + /** Lookup358: xcm::v3::QueryResponseInfo */ XcmV3QueryResponseInfo: { destination: "StagingXcmV3MultiLocation", queryId: "Compact", maxWeight: "SpWeightsWeightV2Weight", }, - /** Lookup357: xcm::v3::multiasset::MultiAssetFilter */ + /** Lookup359: xcm::v3::multiasset::MultiAssetFilter */ XcmV3MultiassetMultiAssetFilter: { _enum: { Definite: "XcmV3MultiassetMultiAssets", Wild: "XcmV3MultiassetWildMultiAsset", }, }, - /** Lookup358: xcm::v3::multiasset::WildMultiAsset */ + /** Lookup360: xcm::v3::multiasset::WildMultiAsset */ XcmV3MultiassetWildMultiAsset: { _enum: { All: "Null", @@ -3516,11 +3548,11 @@ export default { }, }, }, - /** Lookup359: xcm::v3::multiasset::WildFungibility */ + /** Lookup361: xcm::v3::multiasset::WildFungibility */ XcmV3MultiassetWildFungibility: { _enum: ["Fungible", "NonFungible"], }, - /** Lookup371: staging_xcm_executor::traits::asset_transfer::TransferType */ + /** Lookup373: staging_xcm_executor::traits::asset_transfer::TransferType */ StagingXcmExecutorAssetTransferTransferType: { _enum: { Teleport: "Null", @@ -3529,7 +3561,7 @@ export default { RemoteReserve: "XcmVersionedLocation", }, }, - /** Lookup372: xcm::VersionedAssetId */ + /** Lookup374: xcm::VersionedAssetId */ XcmVersionedAssetId: { _enum: { __Unused0: "Null", @@ -3539,7 +3571,7 @@ export default { V4: "StagingXcmV4AssetAssetId", }, }, - /** Lookup373: pallet_assets::pallet::Call */ + /** Lookup375: pallet_assets::pallet::Call */ PalletAssetsCall: { _enum: { create: { @@ -3689,7 +3721,7 @@ export default { }, }, }, - /** Lookup374: pallet_foreign_asset_creator::pallet::Call */ + /** Lookup376: pallet_foreign_asset_creator::pallet::Call */ PalletForeignAssetCreatorCall: { _enum: { create_foreign_asset: { @@ -3711,7 +3743,7 @@ export default { }, }, }, - /** Lookup375: pallet_asset_rate::pallet::Call */ + /** Lookup377: pallet_asset_rate::pallet::Call */ PalletAssetRateCall: { _enum: { create: { @@ -3727,7 +3759,7 @@ export default { }, }, }, - /** Lookup376: pallet_message_queue::pallet::Call */ + /** Lookup378: pallet_message_queue::pallet::Call */ PalletMessageQueueCall: { _enum: { reap_page: { @@ -3742,7 +3774,7 @@ export default { }, }, }, - /** Lookup377: pallet_xcm_core_buyer::pallet::Call */ + /** Lookup379: pallet_xcm_core_buyer::pallet::Call */ PalletXcmCoreBuyerCall: { _enum: { buy_core: { @@ -3771,24 +3803,24 @@ export default { }, }, }, - /** Lookup378: tp_xcm_core_buyer::BuyCoreCollatorProof */ + /** Lookup380: tp_xcm_core_buyer::BuyCoreCollatorProof */ TpXcmCoreBuyerBuyCoreCollatorProof: { nonce: "u64", publicKey: "NimbusPrimitivesNimbusCryptoPublic", signature: "NimbusPrimitivesNimbusCryptoSignature", }, - /** Lookup379: nimbus_primitives::nimbus_crypto::Signature */ + /** Lookup381: nimbus_primitives::nimbus_crypto::Signature */ NimbusPrimitivesNimbusCryptoSignature: "[u8;64]", - /** Lookup381: pallet_xcm_core_buyer::pallet::RelayXcmWeightConfigInner */ + /** Lookup383: pallet_xcm_core_buyer::pallet::RelayXcmWeightConfigInner */ PalletXcmCoreBuyerRelayXcmWeightConfigInner: { buyExecutionCost: "u128", weightAtMost: "SpWeightsWeightV2Weight", }, - /** Lookup383: dancebox_runtime::xcm_config::RelayChain */ + /** Lookup385: dancebox_runtime::xcm_config::RelayChain */ DanceboxRuntimeXcmConfigRelayChain: { _enum: ["Westend", "Rococo"], }, - /** Lookup384: pallet_root_testing::pallet::Call */ + /** Lookup386: pallet_root_testing::pallet::Call */ PalletRootTestingCall: { _enum: { fill_block: { @@ -3797,27 +3829,27 @@ export default { trigger_defensive: "Null", }, }, - /** Lookup385: pallet_sudo::pallet::Error */ + /** Lookup387: pallet_sudo::pallet::Error */ PalletSudoError: { _enum: ["RequireSudo"], }, - /** Lookup386: pallet_utility::pallet::Error */ + /** Lookup388: pallet_utility::pallet::Error */ PalletUtilityError: { _enum: ["TooManyCalls"], }, - /** Lookup389: pallet_proxy::ProxyDefinition */ + /** Lookup391: pallet_proxy::ProxyDefinition */ PalletProxyProxyDefinition: { delegate: "AccountId32", proxyType: "DanceboxRuntimeProxyType", delay: "u32", }, - /** Lookup393: pallet_proxy::Announcement */ + /** Lookup395: pallet_proxy::Announcement */ PalletProxyAnnouncement: { real: "AccountId32", callHash: "H256", height: "u32", }, - /** Lookup395: pallet_proxy::pallet::Error */ + /** Lookup397: pallet_proxy::pallet::Error */ PalletProxyError: { _enum: [ "TooMany", @@ -3830,39 +3862,39 @@ export default { "NoSelfProxy", ], }, - /** Lookup396: pallet_migrations::pallet::Error */ + /** Lookup398: pallet_migrations::pallet::Error */ PalletMigrationsError: { _enum: ["PreimageMissing", "WrongUpperBound", "PreimageIsTooBig", "PreimageAlreadyExists"], }, - /** Lookup397: pallet_maintenance_mode::pallet::Error */ + /** Lookup399: pallet_maintenance_mode::pallet::Error */ PalletMaintenanceModeError: { _enum: ["AlreadyInMaintenanceMode", "NotInMaintenanceMode"], }, - /** Lookup398: pallet_tx_pause::pallet::Error */ + /** Lookup400: pallet_tx_pause::pallet::Error */ PalletTxPauseError: { _enum: ["IsPaused", "IsUnpaused", "Unpausable", "NotFound"], }, - /** Lookup400: pallet_balances::types::BalanceLock */ + /** Lookup402: pallet_balances::types::BalanceLock */ PalletBalancesBalanceLock: { id: "[u8;8]", amount: "u128", reasons: "PalletBalancesReasons", }, - /** Lookup401: pallet_balances::types::Reasons */ + /** Lookup403: pallet_balances::types::Reasons */ PalletBalancesReasons: { _enum: ["Fee", "Misc", "All"], }, - /** Lookup404: pallet_balances::types::ReserveData */ + /** Lookup406: pallet_balances::types::ReserveData */ PalletBalancesReserveData: { id: "[u8;8]", amount: "u128", }, - /** Lookup407: pallet_balances::types::IdAmount */ + /** Lookup409: pallet_balances::types::IdAmount */ PalletBalancesIdAmountRuntimeHoldReason: { id: "DanceboxRuntimeRuntimeHoldReason", amount: "u128", }, - /** Lookup408: dancebox_runtime::RuntimeHoldReason */ + /** Lookup410: dancebox_runtime::RuntimeHoldReason */ DanceboxRuntimeRuntimeHoldReason: { _enum: { __Unused0: "Null", @@ -3902,24 +3934,24 @@ export default { PooledStaking: "PalletPooledStakingHoldReason", }, }, - /** Lookup409: pallet_stream_payment::pallet::HoldReason */ + /** Lookup411: pallet_stream_payment::pallet::HoldReason */ PalletStreamPaymentHoldReason: { _enum: ["StreamPayment", "StreamOpened"], }, - /** Lookup410: pallet_data_preservers::pallet::HoldReason */ + /** Lookup412: pallet_data_preservers::pallet::HoldReason */ PalletDataPreserversHoldReason: { _enum: ["ProfileDeposit"], }, - /** Lookup411: pallet_pooled_staking::pallet::HoldReason */ + /** Lookup413: pallet_pooled_staking::pallet::HoldReason */ PalletPooledStakingHoldReason: { _enum: ["PooledStake"], }, - /** Lookup414: pallet_balances::types::IdAmount */ + /** Lookup416: pallet_balances::types::IdAmount */ PalletBalancesIdAmountRuntimeFreezeReason: { id: "DanceboxRuntimeRuntimeFreezeReason", amount: "u128", }, - /** Lookup415: dancebox_runtime::RuntimeFreezeReason */ + /** Lookup417: dancebox_runtime::RuntimeFreezeReason */ DanceboxRuntimeRuntimeFreezeReason: { _enum: { __Unused0: "Null", @@ -3937,11 +3969,11 @@ export default { StreamPayment: "PalletStreamPaymentFreezeReason", }, }, - /** Lookup416: pallet_stream_payment::pallet::FreezeReason */ + /** Lookup418: pallet_stream_payment::pallet::FreezeReason */ PalletStreamPaymentFreezeReason: { _enum: ["StreamPayment"], }, - /** Lookup418: pallet_balances::pallet::Error */ + /** Lookup420: pallet_balances::pallet::Error */ PalletBalancesError: { _enum: [ "VestingBalance", @@ -3958,12 +3990,12 @@ export default { "DeltaZero", ], }, - /** Lookup419: pallet_transaction_payment::Releases */ + /** Lookup421: pallet_transaction_payment::Releases */ PalletTransactionPaymentReleases: { _enum: ["V1Ancient", "V2"], }, /** - * Lookup420: pallet_stream_payment::pallet::Stream */ PalletStreamPaymentStream: { @@ -3977,7 +4009,7 @@ export default { openingDeposit: "u128", }, /** - * Lookup422: pallet_stream_payment::pallet::ChangeRequest */ PalletStreamPaymentChangeRequest: { @@ -3986,7 +4018,7 @@ export default { newConfig: "PalletStreamPaymentStreamConfig", depositChange: "Option", }, - /** Lookup424: pallet_stream_payment::pallet::Error */ + /** Lookup426: pallet_stream_payment::pallet::Error */ PalletStreamPaymentError: { _enum: [ "UnknownStreamId", @@ -4006,24 +4038,24 @@ export default { "ImmediateDepositChangeRequiresSameAssetId", ], }, - /** Lookup426: pallet_identity::types::Registration> */ + /** Lookup428: pallet_identity::types::Registration> */ PalletIdentityRegistration: { judgements: "Vec<(u32,PalletIdentityJudgement)>", deposit: "u128", info: "PalletIdentityLegacyIdentityInfo", }, - /** Lookup435: pallet_identity::types::RegistrarInfo */ + /** Lookup437: pallet_identity::types::RegistrarInfo */ PalletIdentityRegistrarInfo: { account: "AccountId32", fee: "u128", fields: "u64", }, - /** Lookup437: pallet_identity::types::AuthorityProperties> */ + /** Lookup439: pallet_identity::types::AuthorityProperties> */ PalletIdentityAuthorityProperties: { suffix: "Bytes", allocation: "u32", }, - /** Lookup440: pallet_identity::pallet::Error */ + /** Lookup442: pallet_identity::pallet::Error */ PalletIdentityError: { _enum: [ "TooManySubAccounts", @@ -4054,14 +4086,14 @@ export default { "NotExpired", ], }, - /** Lookup442: pallet_multisig::Multisig */ + /** Lookup444: pallet_multisig::Multisig */ PalletMultisigMultisig: { when: "PalletMultisigTimepoint", deposit: "u128", depositor: "AccountId32", approvals: "Vec", }, - /** Lookup444: pallet_multisig::pallet::Error */ + /** Lookup446: pallet_multisig::pallet::Error */ PalletMultisigError: { _enum: [ "MinimumThreshold", @@ -4080,12 +4112,12 @@ export default { "AlreadyStored", ], }, - /** Lookup452: pallet_registrar::pallet::DepositInfo */ + /** Lookup455: pallet_registrar::pallet::DepositInfo */ PalletRegistrarDepositInfo: { creator: "AccountId32", deposit: "u128", }, - /** Lookup453: pallet_registrar::pallet::Error */ + /** Lookup456: pallet_registrar::pallet::Error */ PalletRegistrarError: { _enum: [ "ParaIdAlreadyRegistered", @@ -4105,7 +4137,7 @@ export default { "ParaStillExistsInRelay", ], }, - /** Lookup454: pallet_configuration::HostConfiguration */ + /** Lookup457: pallet_configuration::HostConfiguration */ PalletConfigurationHostConfiguration: { maxCollators: "u32", minOrchestratorCollators: "u32", @@ -4116,22 +4148,22 @@ export default { parathreadsPerCollator: "u32", targetContainerChainFullness: "Perbill", }, - /** Lookup457: pallet_configuration::pallet::Error */ + /** Lookup460: pallet_configuration::pallet::Error */ PalletConfigurationError: { _enum: ["InvalidNewValue"], }, - /** Lookup458: dp_collator_assignment::AssignedCollators */ + /** Lookup461: dp_collator_assignment::AssignedCollators */ DpCollatorAssignmentAssignedCollatorsAccountId32: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup463: tp_traits::ContainerChainBlockInfo */ + /** Lookup466: tp_traits::ContainerChainBlockInfo */ TpTraitsContainerChainBlockInfo: { blockNumber: "u32", author: "AccountId32", latestSlotNumber: "u64", }, - /** Lookup464: pallet_author_noting::pallet::Error */ + /** Lookup467: pallet_author_noting::pallet::Error */ PalletAuthorNotingError: { _enum: [ "FailedReading", @@ -4143,26 +4175,38 @@ export default { "NonAuraDigest", ], }, - /** Lookup465: dp_collator_assignment::AssignedCollators */ + /** Lookup468: dp_collator_assignment::AssignedCollators */ DpCollatorAssignmentAssignedCollatorsPublic: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup470: pallet_services_payment::pallet::Error */ + /** Lookup473: pallet_services_payment::pallet::Error */ PalletServicesPaymentError: { _enum: ["InsufficientFundsToPurchaseCredits", "InsufficientCredits", "CreditPriceTooExpensive"], }, - /** Lookup471: pallet_data_preservers::pallet::RegisteredProfile */ + /** Lookup474: pallet_data_preservers::types::RegisteredProfile */ PalletDataPreserversRegisteredProfile: { account: "AccountId32", deposit: "u128", profile: "PalletDataPreserversProfile", + assignment: "Option<(u32,DanceboxRuntimePreserversAssignementPaymentWitness)>", }, - /** Lookup472: pallet_data_preservers::pallet::Error */ + /** Lookup480: pallet_data_preservers::pallet::Error */ PalletDataPreserversError: { - _enum: ["NoBootNodes", "UnknownProfileId", "NextProfileIdShouldBeAvailable"], + _enum: [ + "NoBootNodes", + "UnknownProfileId", + "NextProfileIdShouldBeAvailable", + "AssignmentPaymentRequestParameterMismatch", + "ProfileAlreadyAssigned", + "ProfileNotAssigned", + "ProfileIsNotElligibleForParaId", + "WrongParaId", + "MaxAssignmentsPerParaIdReached", + "CantDeleteAssignedProfile", + ], }, - /** Lookup474: pallet_invulnerables::pallet::Error */ + /** Lookup482: pallet_invulnerables::pallet::Error */ PalletInvulnerablesError: { _enum: [ "TooManyInvulnerables", @@ -4172,22 +4216,22 @@ export default { "UnableToDeriveCollatorId", ], }, - /** Lookup479: sp_core::crypto::KeyTypeId */ + /** Lookup487: sp_core::crypto::KeyTypeId */ SpCoreCryptoKeyTypeId: "[u8;4]", - /** Lookup480: pallet_session::pallet::Error */ + /** Lookup488: pallet_session::pallet::Error */ PalletSessionError: { _enum: ["InvalidProof", "NoAssociatedValidatorId", "DuplicatedKey", "NoKeys", "NoAccount"], }, - /** Lookup484: pallet_author_inherent::pallet::Error */ + /** Lookup492: pallet_author_inherent::pallet::Error */ PalletAuthorInherentError: { _enum: ["AuthorAlreadySet", "NoAccountId", "CannotBeAuthor"], }, - /** Lookup486: pallet_pooled_staking::candidate::EligibleCandidate */ + /** Lookup494: pallet_pooled_staking::candidate::EligibleCandidate */ PalletPooledStakingCandidateEligibleCandidate: { candidate: "AccountId32", stake: "u128", }, - /** Lookup489: pallet_pooled_staking::pallet::PoolsKey */ + /** Lookup497: pallet_pooled_staking::pallet::PoolsKey */ PalletPooledStakingPoolsKey: { _enum: { CandidateTotalStake: "Null", @@ -4229,7 +4273,7 @@ export default { }, }, }, - /** Lookup491: pallet_pooled_staking::pallet::Error */ + /** Lookup499: pallet_pooled_staking::pallet::Error */ PalletPooledStakingError: { _enum: { InvalidPalletSetting: "Null", @@ -4248,19 +4292,19 @@ export default { SwapResultsInZeroShares: "Null", }, }, - /** Lookup492: pallet_inflation_rewards::pallet::ChainsToRewardValue */ + /** Lookup500: pallet_inflation_rewards::pallet::ChainsToRewardValue */ PalletInflationRewardsChainsToRewardValue: { paraIds: "Vec", rewardsPerChain: "u128", }, - /** Lookup493: pallet_treasury::Proposal */ + /** Lookup501: pallet_treasury::Proposal */ PalletTreasuryProposal: { proposer: "AccountId32", value: "u128", beneficiary: "AccountId32", bond: "u128", }, - /** Lookup495: pallet_treasury::SpendStatus */ + /** Lookup503: pallet_treasury::SpendStatus */ PalletTreasurySpendStatus: { assetKind: "Null", amount: "u128", @@ -4269,7 +4313,7 @@ export default { expireAt: "u32", status: "PalletTreasuryPaymentState", }, - /** Lookup496: pallet_treasury::PaymentState */ + /** Lookup504: pallet_treasury::PaymentState */ PalletTreasuryPaymentState: { _enum: { Pending: "Null", @@ -4279,9 +4323,9 @@ export default { Failed: "Null", }, }, - /** Lookup498: frame_support::PalletId */ + /** Lookup506: frame_support::PalletId */ FrameSupportPalletId: "[u8;8]", - /** Lookup499: pallet_treasury::pallet::Error */ + /** Lookup507: pallet_treasury::pallet::Error */ PalletTreasuryError: { _enum: [ "InsufficientProposersBalance", @@ -4298,7 +4342,7 @@ export default { "Inconclusive", ], }, - /** Lookup503: cumulus_pallet_xcmp_queue::OutboundChannelDetails */ + /** Lookup510: cumulus_pallet_xcmp_queue::OutboundChannelDetails */ CumulusPalletXcmpQueueOutboundChannelDetails: { recipient: "u32", state: "CumulusPalletXcmpQueueOutboundState", @@ -4306,21 +4350,21 @@ export default { firstIndex: "u16", lastIndex: "u16", }, - /** Lookup504: cumulus_pallet_xcmp_queue::OutboundState */ + /** Lookup511: cumulus_pallet_xcmp_queue::OutboundState */ CumulusPalletXcmpQueueOutboundState: { _enum: ["Ok", "Suspended"], }, - /** Lookup506: cumulus_pallet_xcmp_queue::QueueConfigData */ + /** Lookup513: cumulus_pallet_xcmp_queue::QueueConfigData */ CumulusPalletXcmpQueueQueueConfigData: { suspendThreshold: "u32", dropThreshold: "u32", resumeThreshold: "u32", }, - /** Lookup507: cumulus_pallet_xcmp_queue::pallet::Error */ + /** Lookup514: cumulus_pallet_xcmp_queue::pallet::Error */ CumulusPalletXcmpQueueError: { _enum: ["BadQueueConfig", "AlreadySuspended", "AlreadyResumed"], }, - /** Lookup508: cumulus_pallet_dmp_queue::pallet::MigrationState */ + /** Lookup515: cumulus_pallet_dmp_queue::pallet::MigrationState */ CumulusPalletDmpQueueMigrationState: { _enum: { NotStarted: "Null", @@ -4338,7 +4382,7 @@ export default { Completed: "Null", }, }, - /** Lookup511: pallet_xcm::pallet::QueryStatus */ + /** Lookup518: pallet_xcm::pallet::QueryStatus */ PalletXcmQueryStatus: { _enum: { Pending: { @@ -4357,7 +4401,7 @@ export default { }, }, }, - /** Lookup515: xcm::VersionedResponse */ + /** Lookup522: xcm::VersionedResponse */ XcmVersionedResponse: { _enum: { __Unused0: "Null", @@ -4367,7 +4411,7 @@ export default { V4: "StagingXcmV4Response", }, }, - /** Lookup521: pallet_xcm::pallet::VersionMigrationStage */ + /** Lookup528: pallet_xcm::pallet::VersionMigrationStage */ PalletXcmVersionMigrationStage: { _enum: { MigrateSupportedVersion: "Null", @@ -4376,14 +4420,14 @@ export default { MigrateAndNotifyOldTargets: "Null", }, }, - /** Lookup523: pallet_xcm::pallet::RemoteLockedFungibleRecord */ + /** Lookup530: pallet_xcm::pallet::RemoteLockedFungibleRecord */ PalletXcmRemoteLockedFungibleRecord: { amount: "u128", owner: "XcmVersionedLocation", locker: "XcmVersionedLocation", consumers: "Vec<(Null,u128)>", }, - /** Lookup530: pallet_xcm::pallet::Error */ + /** Lookup537: pallet_xcm::pallet::Error */ PalletXcmError: { _enum: [ "Unreachable", @@ -4413,7 +4457,7 @@ export default { "LocalExecutionIncomplete", ], }, - /** Lookup531: pallet_assets::types::AssetDetails */ + /** Lookup538: pallet_assets::types::AssetDetails */ PalletAssetsAssetDetails: { owner: "AccountId32", issuer: "AccountId32", @@ -4428,22 +4472,22 @@ export default { approvals: "u32", status: "PalletAssetsAssetStatus", }, - /** Lookup532: pallet_assets::types::AssetStatus */ + /** Lookup539: pallet_assets::types::AssetStatus */ PalletAssetsAssetStatus: { _enum: ["Live", "Frozen", "Destroying"], }, - /** Lookup534: pallet_assets::types::AssetAccount */ + /** Lookup541: pallet_assets::types::AssetAccount */ PalletAssetsAssetAccount: { balance: "u128", status: "PalletAssetsAccountStatus", reason: "PalletAssetsExistenceReason", extra: "Null", }, - /** Lookup535: pallet_assets::types::AccountStatus */ + /** Lookup542: pallet_assets::types::AccountStatus */ PalletAssetsAccountStatus: { _enum: ["Liquid", "Frozen", "Blocked"], }, - /** Lookup536: pallet_assets::types::ExistenceReason */ + /** Lookup543: pallet_assets::types::ExistenceReason */ PalletAssetsExistenceReason: { _enum: { Consumer: "Null", @@ -4453,12 +4497,12 @@ export default { DepositFrom: "(AccountId32,u128)", }, }, - /** Lookup538: pallet_assets::types::Approval */ + /** Lookup545: pallet_assets::types::Approval */ PalletAssetsApproval: { amount: "u128", deposit: "u128", }, - /** Lookup539: pallet_assets::types::AssetMetadata> */ + /** Lookup546: pallet_assets::types::AssetMetadata> */ PalletAssetsAssetMetadata: { deposit: "u128", name: "Bytes", @@ -4466,7 +4510,7 @@ export default { decimals: "u8", isFrozen: "bool", }, - /** Lookup541: pallet_assets::pallet::Error */ + /** Lookup548: pallet_assets::pallet::Error */ PalletAssetsError: { _enum: [ "BalanceLow", @@ -4491,15 +4535,15 @@ export default { "CallbackFailed", ], }, - /** Lookup542: pallet_foreign_asset_creator::pallet::Error */ + /** Lookup549: pallet_foreign_asset_creator::pallet::Error */ PalletForeignAssetCreatorError: { _enum: ["AssetAlreadyExists", "AssetDoesNotExist"], }, - /** Lookup543: pallet_asset_rate::pallet::Error */ + /** Lookup550: pallet_asset_rate::pallet::Error */ PalletAssetRateError: { _enum: ["UnknownAssetKind", "AlreadyExists", "Overflow"], }, - /** Lookup544: pallet_message_queue::BookState */ + /** Lookup551: pallet_message_queue::BookState */ PalletMessageQueueBookState: { _alias: { size_: "size", @@ -4511,12 +4555,12 @@ export default { messageCount: "u64", size_: "u64", }, - /** Lookup546: pallet_message_queue::Neighbours */ + /** Lookup553: pallet_message_queue::Neighbours */ PalletMessageQueueNeighbours: { prev: "CumulusPrimitivesCoreAggregateMessageOrigin", next: "CumulusPrimitivesCoreAggregateMessageOrigin", }, - /** Lookup548: pallet_message_queue::Page */ + /** Lookup555: pallet_message_queue::Page */ PalletMessageQueuePage: { remaining: "u32", remainingSize: "u32", @@ -4525,7 +4569,7 @@ export default { last: "u32", heap: "Bytes", }, - /** Lookup550: pallet_message_queue::pallet::Error */ + /** Lookup557: pallet_message_queue::pallet::Error */ PalletMessageQueueError: { _enum: [ "NotReapable", @@ -4539,13 +4583,13 @@ export default { "RecursiveDisallowed", ], }, - /** Lookup551: pallet_xcm_core_buyer::InFlightCoreBuyingOrder */ + /** Lookup558: pallet_xcm_core_buyer::InFlightCoreBuyingOrder */ PalletXcmCoreBuyerInFlightCoreBuyingOrder: { paraId: "u32", queryId: "u64", ttl: "u32", }, - /** Lookup552: pallet_xcm_core_buyer::pallet::Error */ + /** Lookup559: pallet_xcm_core_buyer::pallet::Error */ PalletXcmCoreBuyerError: { _enum: [ "InvalidProof", @@ -4567,20 +4611,20 @@ export default { "InvalidCollatorSignature", ], }, - /** Lookup557: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ + /** Lookup564: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ FrameSystemExtensionsCheckNonZeroSender: "Null", - /** Lookup558: frame_system::extensions::check_spec_version::CheckSpecVersion */ + /** Lookup565: frame_system::extensions::check_spec_version::CheckSpecVersion */ FrameSystemExtensionsCheckSpecVersion: "Null", - /** Lookup559: frame_system::extensions::check_tx_version::CheckTxVersion */ + /** Lookup566: frame_system::extensions::check_tx_version::CheckTxVersion */ FrameSystemExtensionsCheckTxVersion: "Null", - /** Lookup560: frame_system::extensions::check_genesis::CheckGenesis */ + /** Lookup567: frame_system::extensions::check_genesis::CheckGenesis */ FrameSystemExtensionsCheckGenesis: "Null", - /** Lookup563: frame_system::extensions::check_nonce::CheckNonce */ + /** Lookup570: frame_system::extensions::check_nonce::CheckNonce */ FrameSystemExtensionsCheckNonce: "Compact", - /** Lookup564: frame_system::extensions::check_weight::CheckWeight */ + /** Lookup571: frame_system::extensions::check_weight::CheckWeight */ FrameSystemExtensionsCheckWeight: "Null", - /** Lookup565: pallet_transaction_payment::ChargeTransactionPayment */ + /** Lookup572: pallet_transaction_payment::ChargeTransactionPayment */ PalletTransactionPaymentChargeTransactionPayment: "Compact", - /** Lookup566: dancebox_runtime::Runtime */ + /** Lookup573: dancebox_runtime::Runtime */ DanceboxRuntimeRuntime: "Null", }; diff --git a/typescript-api/src/dancebox/interfaces/registry.ts b/typescript-api/src/dancebox/interfaces/registry.ts index d1bc7ae25..bcf2976e7 100644 --- a/typescript-api/src/dancebox/interfaces/registry.ts +++ b/typescript-api/src/dancebox/interfaces/registry.ts @@ -29,6 +29,9 @@ import type { CumulusPrimitivesCoreAggregateMessageOrigin, CumulusPrimitivesParachainInherentParachainInherentData, DanceboxRuntimeOriginCaller, + DanceboxRuntimePreserversAssignementPaymentExtra, + DanceboxRuntimePreserversAssignementPaymentRequest, + DanceboxRuntimePreserversAssignementPaymentWitness, DanceboxRuntimeProxyType, DanceboxRuntimeRuntime, DanceboxRuntimeRuntimeFreezeReason, @@ -339,6 +342,9 @@ declare module "@polkadot/types/types/registry" { CumulusPrimitivesCoreAggregateMessageOrigin: CumulusPrimitivesCoreAggregateMessageOrigin; CumulusPrimitivesParachainInherentParachainInherentData: CumulusPrimitivesParachainInherentParachainInherentData; DanceboxRuntimeOriginCaller: DanceboxRuntimeOriginCaller; + DanceboxRuntimePreserversAssignementPaymentExtra: DanceboxRuntimePreserversAssignementPaymentExtra; + DanceboxRuntimePreserversAssignementPaymentRequest: DanceboxRuntimePreserversAssignementPaymentRequest; + DanceboxRuntimePreserversAssignementPaymentWitness: DanceboxRuntimePreserversAssignementPaymentWitness; DanceboxRuntimeProxyType: DanceboxRuntimeProxyType; DanceboxRuntimeRuntime: DanceboxRuntimeRuntime; DanceboxRuntimeRuntimeFreezeReason: DanceboxRuntimeRuntimeFreezeReason; diff --git a/typescript-api/src/dancebox/interfaces/types-lookup.ts b/typescript-api/src/dancebox/interfaces/types-lookup.ts index 3820ea04c..7a64443f2 100644 --- a/typescript-api/src/dancebox/interfaces/types-lookup.ts +++ b/typescript-api/src/dancebox/interfaces/types-lookup.ts @@ -958,7 +958,23 @@ declare module "@polkadot/types/lookup" { readonly profileId: u64; readonly releasedDeposit: u128; } & Struct; - readonly type: "BootNodesChanged" | "ProfileCreated" | "ProfileUpdated" | "ProfileDeleted"; + readonly isAssignmentStarted: boolean; + readonly asAssignmentStarted: { + readonly profileId: u64; + readonly paraId: u32; + } & Struct; + readonly isAssignmentStopped: boolean; + readonly asAssignmentStopped: { + readonly profileId: u64; + readonly paraId: u32; + } & Struct; + readonly type: + | "BootNodesChanged" + | "ProfileCreated" + | "ProfileUpdated" + | "ProfileDeleted" + | "AssignmentStarted" + | "AssignmentStopped"; } /** @name PalletInvulnerablesEvent (68) */ @@ -3845,11 +3861,6 @@ declare module "@polkadot/types/lookup" { /** @name PalletDataPreserversCall (310) */ interface PalletDataPreserversCall extends Enum { - readonly isSetBootNodes: boolean; - readonly asSetBootNodes: { - readonly paraId: u32; - readonly bootNodes: Vec; - } & Struct; readonly isCreateProfile: boolean; readonly asCreateProfile: { readonly profile: PalletDataPreserversProfile; @@ -3877,34 +3888,54 @@ declare module "@polkadot/types/lookup" { readonly asForceDeleteProfile: { readonly profileId: u64; } & Struct; + readonly isStartAssignment: boolean; + readonly asStartAssignment: { + readonly profileId: u64; + readonly paraId: u32; + readonly assignerParam: DanceboxRuntimePreserversAssignementPaymentExtra; + } & Struct; + readonly isStopAssignment: boolean; + readonly asStopAssignment: { + readonly profileId: u64; + readonly paraId: u32; + } & Struct; + readonly isForceStartAssignment: boolean; + readonly asForceStartAssignment: { + readonly profileId: u64; + readonly paraId: u32; + readonly assignmentWitness: DanceboxRuntimePreserversAssignementPaymentWitness; + } & Struct; readonly type: - | "SetBootNodes" | "CreateProfile" | "UpdateProfile" | "DeleteProfile" | "ForceCreateProfile" | "ForceUpdateProfile" - | "ForceDeleteProfile"; + | "ForceDeleteProfile" + | "StartAssignment" + | "StopAssignment" + | "ForceStartAssignment"; } - /** @name PalletDataPreserversProfile (314) */ + /** @name PalletDataPreserversProfile (311) */ interface PalletDataPreserversProfile extends Struct { readonly url: Bytes; readonly paraIds: PalletDataPreserversParaIdsFilter; readonly mode: PalletDataPreserversProfileMode; + readonly assignmentRequest: DanceboxRuntimePreserversAssignementPaymentRequest; } - /** @name PalletDataPreserversParaIdsFilter (315) */ + /** @name PalletDataPreserversParaIdsFilter (313) */ interface PalletDataPreserversParaIdsFilter extends Enum { readonly isAnyParaId: boolean; readonly isWhitelist: boolean; - readonly asWhitelist: Vec; + readonly asWhitelist: BTreeSet; readonly isBlacklist: boolean; - readonly asBlacklist: Vec; + readonly asBlacklist: BTreeSet; readonly type: "AnyParaId" | "Whitelist" | "Blacklist"; } - /** @name PalletDataPreserversProfileMode (317) */ + /** @name PalletDataPreserversProfileMode (316) */ interface PalletDataPreserversProfileMode extends Enum { readonly isBootnode: boolean; readonly isRpc: boolean; @@ -3914,7 +3945,25 @@ declare module "@polkadot/types/lookup" { readonly type: "Bootnode" | "Rpc"; } - /** @name PalletInvulnerablesCall (318) */ + /** @name DanceboxRuntimePreserversAssignementPaymentRequest (317) */ + interface DanceboxRuntimePreserversAssignementPaymentRequest extends Enum { + readonly isFree: boolean; + readonly type: "Free"; + } + + /** @name DanceboxRuntimePreserversAssignementPaymentExtra (318) */ + interface DanceboxRuntimePreserversAssignementPaymentExtra extends Enum { + readonly isFree: boolean; + readonly type: "Free"; + } + + /** @name DanceboxRuntimePreserversAssignementPaymentWitness (319) */ + interface DanceboxRuntimePreserversAssignementPaymentWitness extends Enum { + readonly isFree: boolean; + readonly type: "Free"; + } + + /** @name PalletInvulnerablesCall (320) */ interface PalletInvulnerablesCall extends Enum { readonly isAddInvulnerable: boolean; readonly asAddInvulnerable: { @@ -3927,7 +3976,7 @@ declare module "@polkadot/types/lookup" { readonly type: "AddInvulnerable" | "RemoveInvulnerable"; } - /** @name PalletSessionCall (319) */ + /** @name PalletSessionCall (321) */ interface PalletSessionCall extends Enum { readonly isSetKeys: boolean; readonly asSetKeys: { @@ -3938,21 +3987,21 @@ declare module "@polkadot/types/lookup" { readonly type: "SetKeys" | "PurgeKeys"; } - /** @name DanceboxRuntimeSessionKeys (320) */ + /** @name DanceboxRuntimeSessionKeys (322) */ interface DanceboxRuntimeSessionKeys extends Struct { readonly nimbus: NimbusPrimitivesNimbusCryptoPublic; } - /** @name NimbusPrimitivesNimbusCryptoPublic (321) */ + /** @name NimbusPrimitivesNimbusCryptoPublic (323) */ interface NimbusPrimitivesNimbusCryptoPublic extends U8aFixed {} - /** @name PalletAuthorInherentCall (322) */ + /** @name PalletAuthorInherentCall (324) */ interface PalletAuthorInherentCall extends Enum { readonly isKickOffAuthorshipValidation: boolean; readonly type: "KickOffAuthorshipValidation"; } - /** @name PalletPooledStakingCall (323) */ + /** @name PalletPooledStakingCall (325) */ interface PalletPooledStakingCall extends Enum { readonly isRebalanceHold: boolean; readonly asRebalanceHold: { @@ -4000,7 +4049,7 @@ declare module "@polkadot/types/lookup" { | "SwapPool"; } - /** @name PalletPooledStakingAllTargetPool (324) */ + /** @name PalletPooledStakingAllTargetPool (326) */ interface PalletPooledStakingAllTargetPool extends Enum { readonly isJoining: boolean; readonly isAutoCompounding: boolean; @@ -4009,13 +4058,13 @@ declare module "@polkadot/types/lookup" { readonly type: "Joining" | "AutoCompounding" | "ManualRewards" | "Leaving"; } - /** @name PalletPooledStakingPendingOperationQuery (326) */ + /** @name PalletPooledStakingPendingOperationQuery (328) */ interface PalletPooledStakingPendingOperationQuery extends Struct { readonly delegator: AccountId32; readonly operation: PalletPooledStakingPendingOperationKey; } - /** @name PalletPooledStakingPendingOperationKey (327) */ + /** @name PalletPooledStakingPendingOperationKey (329) */ interface PalletPooledStakingPendingOperationKey extends Enum { readonly isJoiningAutoCompounding: boolean; readonly asJoiningAutoCompounding: { @@ -4035,7 +4084,7 @@ declare module "@polkadot/types/lookup" { readonly type: "JoiningAutoCompounding" | "JoiningManualRewards" | "Leaving"; } - /** @name PalletPooledStakingSharesOrStake (328) */ + /** @name PalletPooledStakingSharesOrStake (330) */ interface PalletPooledStakingSharesOrStake extends Enum { readonly isShares: boolean; readonly asShares: u128; @@ -4044,7 +4093,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Shares" | "Stake"; } - /** @name PalletTreasuryCall (331) */ + /** @name PalletTreasuryCall (333) */ interface PalletTreasuryCall extends Enum { readonly isProposeSpend: boolean; readonly asProposeSpend: { @@ -4099,7 +4148,7 @@ declare module "@polkadot/types/lookup" { | "VoidSpend"; } - /** @name CumulusPalletXcmpQueueCall (332) */ + /** @name CumulusPalletXcmpQueueCall (334) */ interface CumulusPalletXcmpQueueCall extends Enum { readonly isSuspendXcmExecution: boolean; readonly isResumeXcmExecution: boolean; @@ -4123,10 +4172,10 @@ declare module "@polkadot/types/lookup" { | "UpdateResumeThreshold"; } - /** @name CumulusPalletDmpQueueCall (333) */ + /** @name CumulusPalletDmpQueueCall (335) */ type CumulusPalletDmpQueueCall = Null; - /** @name PalletXcmCall (334) */ + /** @name PalletXcmCall (336) */ interface PalletXcmCall extends Enum { readonly isSend: boolean; readonly asSend: { @@ -4229,7 +4278,7 @@ declare module "@polkadot/types/lookup" { | "TransferAssetsUsingTypeAndThen"; } - /** @name XcmVersionedXcm (335) */ + /** @name XcmVersionedXcm (337) */ interface XcmVersionedXcm extends Enum { readonly isV2: boolean; readonly asV2: XcmV2Xcm; @@ -4240,10 +4289,10 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3" | "V4"; } - /** @name XcmV2Xcm (336) */ + /** @name XcmV2Xcm (338) */ interface XcmV2Xcm extends Vec {} - /** @name XcmV2Instruction (338) */ + /** @name XcmV2Instruction (340) */ interface XcmV2Instruction extends Enum { readonly isWithdrawAsset: boolean; readonly asWithdrawAsset: XcmV2MultiassetMultiAssets; @@ -4391,7 +4440,7 @@ declare module "@polkadot/types/lookup" { | "UnsubscribeVersion"; } - /** @name XcmV2Response (339) */ + /** @name XcmV2Response (341) */ interface XcmV2Response extends Enum { readonly isNull: boolean; readonly isAssets: boolean; @@ -4403,7 +4452,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Null" | "Assets" | "ExecutionResult" | "Version"; } - /** @name XcmV2TraitsError (342) */ + /** @name XcmV2TraitsError (344) */ interface XcmV2TraitsError extends Enum { readonly isOverflow: boolean; readonly isUnimplemented: boolean; @@ -4462,7 +4511,7 @@ declare module "@polkadot/types/lookup" { | "WeightNotComputable"; } - /** @name XcmV2MultiassetMultiAssetFilter (343) */ + /** @name XcmV2MultiassetMultiAssetFilter (345) */ interface XcmV2MultiassetMultiAssetFilter extends Enum { readonly isDefinite: boolean; readonly asDefinite: XcmV2MultiassetMultiAssets; @@ -4471,7 +4520,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Definite" | "Wild"; } - /** @name XcmV2MultiassetWildMultiAsset (344) */ + /** @name XcmV2MultiassetWildMultiAsset (346) */ interface XcmV2MultiassetWildMultiAsset extends Enum { readonly isAll: boolean; readonly isAllOf: boolean; @@ -4482,14 +4531,14 @@ declare module "@polkadot/types/lookup" { readonly type: "All" | "AllOf"; } - /** @name XcmV2MultiassetWildFungibility (345) */ + /** @name XcmV2MultiassetWildFungibility (347) */ interface XcmV2MultiassetWildFungibility extends Enum { readonly isFungible: boolean; readonly isNonFungible: boolean; readonly type: "Fungible" | "NonFungible"; } - /** @name XcmV2WeightLimit (346) */ + /** @name XcmV2WeightLimit (348) */ interface XcmV2WeightLimit extends Enum { readonly isUnlimited: boolean; readonly isLimited: boolean; @@ -4497,10 +4546,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Unlimited" | "Limited"; } - /** @name XcmV3Xcm (347) */ + /** @name XcmV3Xcm (349) */ interface XcmV3Xcm extends Vec {} - /** @name XcmV3Instruction (349) */ + /** @name XcmV3Instruction (351) */ interface XcmV3Instruction extends Enum { readonly isWithdrawAsset: boolean; readonly asWithdrawAsset: XcmV3MultiassetMultiAssets; @@ -4730,7 +4779,7 @@ declare module "@polkadot/types/lookup" { | "UnpaidExecution"; } - /** @name XcmV3Response (350) */ + /** @name XcmV3Response (352) */ interface XcmV3Response extends Enum { readonly isNull: boolean; readonly isAssets: boolean; @@ -4746,7 +4795,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Null" | "Assets" | "ExecutionResult" | "Version" | "PalletsInfo" | "DispatchResult"; } - /** @name XcmV3PalletInfo (352) */ + /** @name XcmV3PalletInfo (354) */ interface XcmV3PalletInfo extends Struct { readonly index: Compact; readonly name: Bytes; @@ -4756,14 +4805,14 @@ declare module "@polkadot/types/lookup" { readonly patch: Compact; } - /** @name XcmV3QueryResponseInfo (356) */ + /** @name XcmV3QueryResponseInfo (358) */ interface XcmV3QueryResponseInfo extends Struct { readonly destination: StagingXcmV3MultiLocation; readonly queryId: Compact; readonly maxWeight: SpWeightsWeightV2Weight; } - /** @name XcmV3MultiassetMultiAssetFilter (357) */ + /** @name XcmV3MultiassetMultiAssetFilter (359) */ interface XcmV3MultiassetMultiAssetFilter extends Enum { readonly isDefinite: boolean; readonly asDefinite: XcmV3MultiassetMultiAssets; @@ -4772,7 +4821,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Definite" | "Wild"; } - /** @name XcmV3MultiassetWildMultiAsset (358) */ + /** @name XcmV3MultiassetWildMultiAsset (360) */ interface XcmV3MultiassetWildMultiAsset extends Enum { readonly isAll: boolean; readonly isAllOf: boolean; @@ -4791,14 +4840,14 @@ declare module "@polkadot/types/lookup" { readonly type: "All" | "AllOf" | "AllCounted" | "AllOfCounted"; } - /** @name XcmV3MultiassetWildFungibility (359) */ + /** @name XcmV3MultiassetWildFungibility (361) */ interface XcmV3MultiassetWildFungibility extends Enum { readonly isFungible: boolean; readonly isNonFungible: boolean; readonly type: "Fungible" | "NonFungible"; } - /** @name StagingXcmExecutorAssetTransferTransferType (371) */ + /** @name StagingXcmExecutorAssetTransferTransferType (373) */ interface StagingXcmExecutorAssetTransferTransferType extends Enum { readonly isTeleport: boolean; readonly isLocalReserve: boolean; @@ -4808,7 +4857,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Teleport" | "LocalReserve" | "DestinationReserve" | "RemoteReserve"; } - /** @name XcmVersionedAssetId (372) */ + /** @name XcmVersionedAssetId (374) */ interface XcmVersionedAssetId extends Enum { readonly isV3: boolean; readonly asV3: XcmV3MultiassetAssetId; @@ -4817,7 +4866,7 @@ declare module "@polkadot/types/lookup" { readonly type: "V3" | "V4"; } - /** @name PalletAssetsCall (373) */ + /** @name PalletAssetsCall (375) */ interface PalletAssetsCall extends Enum { readonly isCreate: boolean; readonly asCreate: { @@ -5031,7 +5080,7 @@ declare module "@polkadot/types/lookup" { | "Block"; } - /** @name PalletForeignAssetCreatorCall (374) */ + /** @name PalletForeignAssetCreatorCall (376) */ interface PalletForeignAssetCreatorCall extends Enum { readonly isCreateForeignAsset: boolean; readonly asCreateForeignAsset: { @@ -5061,7 +5110,7 @@ declare module "@polkadot/types/lookup" { | "DestroyForeignAsset"; } - /** @name PalletAssetRateCall (375) */ + /** @name PalletAssetRateCall (377) */ interface PalletAssetRateCall extends Enum { readonly isCreate: boolean; readonly asCreate: { @@ -5080,7 +5129,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Create" | "Update" | "Remove"; } - /** @name PalletMessageQueueCall (376) */ + /** @name PalletMessageQueueCall (378) */ interface PalletMessageQueueCall extends Enum { readonly isReapPage: boolean; readonly asReapPage: { @@ -5097,7 +5146,7 @@ declare module "@polkadot/types/lookup" { readonly type: "ReapPage" | "ExecuteOverweight"; } - /** @name PalletXcmCoreBuyerCall (377) */ + /** @name PalletXcmCoreBuyerCall (379) */ interface PalletXcmCoreBuyerCall extends Enum { readonly isBuyCore: boolean; readonly asBuyCore: { @@ -5140,30 +5189,30 @@ declare module "@polkadot/types/lookup" { | "CleanUpExpiredInFlightOrders"; } - /** @name TpXcmCoreBuyerBuyCoreCollatorProof (378) */ + /** @name TpXcmCoreBuyerBuyCoreCollatorProof (380) */ interface TpXcmCoreBuyerBuyCoreCollatorProof extends Struct { readonly nonce: u64; readonly publicKey: NimbusPrimitivesNimbusCryptoPublic; readonly signature: NimbusPrimitivesNimbusCryptoSignature; } - /** @name NimbusPrimitivesNimbusCryptoSignature (379) */ + /** @name NimbusPrimitivesNimbusCryptoSignature (381) */ interface NimbusPrimitivesNimbusCryptoSignature extends U8aFixed {} - /** @name PalletXcmCoreBuyerRelayXcmWeightConfigInner (381) */ + /** @name PalletXcmCoreBuyerRelayXcmWeightConfigInner (383) */ interface PalletXcmCoreBuyerRelayXcmWeightConfigInner extends Struct { readonly buyExecutionCost: u128; readonly weightAtMost: SpWeightsWeightV2Weight; } - /** @name DanceboxRuntimeXcmConfigRelayChain (383) */ + /** @name DanceboxRuntimeXcmConfigRelayChain (385) */ interface DanceboxRuntimeXcmConfigRelayChain extends Enum { readonly isWestend: boolean; readonly isRococo: boolean; readonly type: "Westend" | "Rococo"; } - /** @name PalletRootTestingCall (384) */ + /** @name PalletRootTestingCall (386) */ interface PalletRootTestingCall extends Enum { readonly isFillBlock: boolean; readonly asFillBlock: { @@ -5173,33 +5222,33 @@ declare module "@polkadot/types/lookup" { readonly type: "FillBlock" | "TriggerDefensive"; } - /** @name PalletSudoError (385) */ + /** @name PalletSudoError (387) */ interface PalletSudoError extends Enum { readonly isRequireSudo: boolean; readonly type: "RequireSudo"; } - /** @name PalletUtilityError (386) */ + /** @name PalletUtilityError (388) */ interface PalletUtilityError extends Enum { readonly isTooManyCalls: boolean; readonly type: "TooManyCalls"; } - /** @name PalletProxyProxyDefinition (389) */ + /** @name PalletProxyProxyDefinition (391) */ interface PalletProxyProxyDefinition extends Struct { readonly delegate: AccountId32; readonly proxyType: DanceboxRuntimeProxyType; readonly delay: u32; } - /** @name PalletProxyAnnouncement (393) */ + /** @name PalletProxyAnnouncement (395) */ interface PalletProxyAnnouncement extends Struct { readonly real: AccountId32; readonly callHash: H256; readonly height: u32; } - /** @name PalletProxyError (395) */ + /** @name PalletProxyError (397) */ interface PalletProxyError extends Enum { readonly isTooMany: boolean; readonly isNotFound: boolean; @@ -5220,7 +5269,7 @@ declare module "@polkadot/types/lookup" { | "NoSelfProxy"; } - /** @name PalletMigrationsError (396) */ + /** @name PalletMigrationsError (398) */ interface PalletMigrationsError extends Enum { readonly isPreimageMissing: boolean; readonly isWrongUpperBound: boolean; @@ -5229,14 +5278,14 @@ declare module "@polkadot/types/lookup" { readonly type: "PreimageMissing" | "WrongUpperBound" | "PreimageIsTooBig" | "PreimageAlreadyExists"; } - /** @name PalletMaintenanceModeError (397) */ + /** @name PalletMaintenanceModeError (399) */ interface PalletMaintenanceModeError extends Enum { readonly isAlreadyInMaintenanceMode: boolean; readonly isNotInMaintenanceMode: boolean; readonly type: "AlreadyInMaintenanceMode" | "NotInMaintenanceMode"; } - /** @name PalletTxPauseError (398) */ + /** @name PalletTxPauseError (400) */ interface PalletTxPauseError extends Enum { readonly isIsPaused: boolean; readonly isIsUnpaused: boolean; @@ -5245,14 +5294,14 @@ declare module "@polkadot/types/lookup" { readonly type: "IsPaused" | "IsUnpaused" | "Unpausable" | "NotFound"; } - /** @name PalletBalancesBalanceLock (400) */ + /** @name PalletBalancesBalanceLock (402) */ interface PalletBalancesBalanceLock extends Struct { readonly id: U8aFixed; readonly amount: u128; readonly reasons: PalletBalancesReasons; } - /** @name PalletBalancesReasons (401) */ + /** @name PalletBalancesReasons (403) */ interface PalletBalancesReasons extends Enum { readonly isFee: boolean; readonly isMisc: boolean; @@ -5260,19 +5309,19 @@ declare module "@polkadot/types/lookup" { readonly type: "Fee" | "Misc" | "All"; } - /** @name PalletBalancesReserveData (404) */ + /** @name PalletBalancesReserveData (406) */ interface PalletBalancesReserveData extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name PalletBalancesIdAmountRuntimeHoldReason (407) */ + /** @name PalletBalancesIdAmountRuntimeHoldReason (409) */ interface PalletBalancesIdAmountRuntimeHoldReason extends Struct { readonly id: DanceboxRuntimeRuntimeHoldReason; readonly amount: u128; } - /** @name DanceboxRuntimeRuntimeHoldReason (408) */ + /** @name DanceboxRuntimeRuntimeHoldReason (410) */ interface DanceboxRuntimeRuntimeHoldReason extends Enum { readonly isStreamPayment: boolean; readonly asStreamPayment: PalletStreamPaymentHoldReason; @@ -5283,45 +5332,45 @@ declare module "@polkadot/types/lookup" { readonly type: "StreamPayment" | "DataPreservers" | "PooledStaking"; } - /** @name PalletStreamPaymentHoldReason (409) */ + /** @name PalletStreamPaymentHoldReason (411) */ interface PalletStreamPaymentHoldReason extends Enum { readonly isStreamPayment: boolean; readonly isStreamOpened: boolean; readonly type: "StreamPayment" | "StreamOpened"; } - /** @name PalletDataPreserversHoldReason (410) */ + /** @name PalletDataPreserversHoldReason (412) */ interface PalletDataPreserversHoldReason extends Enum { readonly isProfileDeposit: boolean; readonly type: "ProfileDeposit"; } - /** @name PalletPooledStakingHoldReason (411) */ + /** @name PalletPooledStakingHoldReason (413) */ interface PalletPooledStakingHoldReason extends Enum { readonly isPooledStake: boolean; readonly type: "PooledStake"; } - /** @name PalletBalancesIdAmountRuntimeFreezeReason (414) */ + /** @name PalletBalancesIdAmountRuntimeFreezeReason (416) */ interface PalletBalancesIdAmountRuntimeFreezeReason extends Struct { readonly id: DanceboxRuntimeRuntimeFreezeReason; readonly amount: u128; } - /** @name DanceboxRuntimeRuntimeFreezeReason (415) */ + /** @name DanceboxRuntimeRuntimeFreezeReason (417) */ interface DanceboxRuntimeRuntimeFreezeReason extends Enum { readonly isStreamPayment: boolean; readonly asStreamPayment: PalletStreamPaymentFreezeReason; readonly type: "StreamPayment"; } - /** @name PalletStreamPaymentFreezeReason (416) */ + /** @name PalletStreamPaymentFreezeReason (418) */ interface PalletStreamPaymentFreezeReason extends Enum { readonly isStreamPayment: boolean; readonly type: "StreamPayment"; } - /** @name PalletBalancesError (418) */ + /** @name PalletBalancesError (420) */ interface PalletBalancesError extends Enum { readonly isVestingBalance: boolean; readonly isLiquidityRestrictions: boolean; @@ -5350,14 +5399,14 @@ declare module "@polkadot/types/lookup" { | "DeltaZero"; } - /** @name PalletTransactionPaymentReleases (419) */ + /** @name PalletTransactionPaymentReleases (421) */ interface PalletTransactionPaymentReleases extends Enum { readonly isV1Ancient: boolean; readonly isV2: boolean; readonly type: "V1Ancient" | "V2"; } - /** @name PalletStreamPaymentStream (420) */ + /** @name PalletStreamPaymentStream (422) */ interface PalletStreamPaymentStream extends Struct { readonly source: AccountId32; readonly target: AccountId32; @@ -5369,7 +5418,7 @@ declare module "@polkadot/types/lookup" { readonly openingDeposit: u128; } - /** @name PalletStreamPaymentChangeRequest (422) */ + /** @name PalletStreamPaymentChangeRequest (424) */ interface PalletStreamPaymentChangeRequest extends Struct { readonly requester: PalletStreamPaymentParty; readonly kind: PalletStreamPaymentChangeKind; @@ -5377,7 +5426,7 @@ declare module "@polkadot/types/lookup" { readonly depositChange: Option; } - /** @name PalletStreamPaymentError (424) */ + /** @name PalletStreamPaymentError (426) */ interface PalletStreamPaymentError extends Enum { readonly isUnknownStreamId: boolean; readonly isStreamIdOverflow: boolean; @@ -5412,27 +5461,27 @@ declare module "@polkadot/types/lookup" { | "ImmediateDepositChangeRequiresSameAssetId"; } - /** @name PalletIdentityRegistration (426) */ + /** @name PalletIdentityRegistration (428) */ interface PalletIdentityRegistration extends Struct { readonly judgements: Vec>; readonly deposit: u128; readonly info: PalletIdentityLegacyIdentityInfo; } - /** @name PalletIdentityRegistrarInfo (435) */ + /** @name PalletIdentityRegistrarInfo (437) */ interface PalletIdentityRegistrarInfo extends Struct { readonly account: AccountId32; readonly fee: u128; readonly fields: u64; } - /** @name PalletIdentityAuthorityProperties (437) */ + /** @name PalletIdentityAuthorityProperties (439) */ interface PalletIdentityAuthorityProperties extends Struct { readonly suffix: Bytes; readonly allocation: u32; } - /** @name PalletIdentityError (440) */ + /** @name PalletIdentityError (442) */ interface PalletIdentityError extends Enum { readonly isTooManySubAccounts: boolean; readonly isNotFound: boolean; @@ -5489,7 +5538,7 @@ declare module "@polkadot/types/lookup" { | "NotExpired"; } - /** @name PalletMultisigMultisig (442) */ + /** @name PalletMultisigMultisig (444) */ interface PalletMultisigMultisig extends Struct { readonly when: PalletMultisigTimepoint; readonly deposit: u128; @@ -5497,7 +5546,7 @@ declare module "@polkadot/types/lookup" { readonly approvals: Vec; } - /** @name PalletMultisigError (444) */ + /** @name PalletMultisigError (446) */ interface PalletMultisigError extends Enum { readonly isMinimumThreshold: boolean; readonly isAlreadyApproved: boolean; @@ -5530,13 +5579,13 @@ declare module "@polkadot/types/lookup" { | "AlreadyStored"; } - /** @name PalletRegistrarDepositInfo (452) */ + /** @name PalletRegistrarDepositInfo (455) */ interface PalletRegistrarDepositInfo extends Struct { readonly creator: AccountId32; readonly deposit: u128; } - /** @name PalletRegistrarError (453) */ + /** @name PalletRegistrarError (456) */ interface PalletRegistrarError extends Enum { readonly isParaIdAlreadyRegistered: boolean; readonly isParaIdNotRegistered: boolean; @@ -5571,7 +5620,7 @@ declare module "@polkadot/types/lookup" { | "ParaStillExistsInRelay"; } - /** @name PalletConfigurationHostConfiguration (454) */ + /** @name PalletConfigurationHostConfiguration (457) */ interface PalletConfigurationHostConfiguration extends Struct { readonly maxCollators: u32; readonly minOrchestratorCollators: u32; @@ -5583,26 +5632,26 @@ declare module "@polkadot/types/lookup" { readonly targetContainerChainFullness: Perbill; } - /** @name PalletConfigurationError (457) */ + /** @name PalletConfigurationError (460) */ interface PalletConfigurationError extends Enum { readonly isInvalidNewValue: boolean; readonly type: "InvalidNewValue"; } - /** @name DpCollatorAssignmentAssignedCollatorsAccountId32 (458) */ + /** @name DpCollatorAssignmentAssignedCollatorsAccountId32 (461) */ interface DpCollatorAssignmentAssignedCollatorsAccountId32 extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name TpTraitsContainerChainBlockInfo (463) */ + /** @name TpTraitsContainerChainBlockInfo (466) */ interface TpTraitsContainerChainBlockInfo extends Struct { readonly blockNumber: u32; readonly author: AccountId32; readonly latestSlotNumber: u64; } - /** @name PalletAuthorNotingError (464) */ + /** @name PalletAuthorNotingError (467) */ interface PalletAuthorNotingError extends Enum { readonly isFailedReading: boolean; readonly isFailedDecodingHeader: boolean; @@ -5621,13 +5670,13 @@ declare module "@polkadot/types/lookup" { | "NonAuraDigest"; } - /** @name DpCollatorAssignmentAssignedCollatorsPublic (465) */ + /** @name DpCollatorAssignmentAssignedCollatorsPublic (468) */ interface DpCollatorAssignmentAssignedCollatorsPublic extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name PalletServicesPaymentError (470) */ + /** @name PalletServicesPaymentError (473) */ interface PalletServicesPaymentError extends Enum { readonly isInsufficientFundsToPurchaseCredits: boolean; readonly isInsufficientCredits: boolean; @@ -5635,22 +5684,40 @@ declare module "@polkadot/types/lookup" { readonly type: "InsufficientFundsToPurchaseCredits" | "InsufficientCredits" | "CreditPriceTooExpensive"; } - /** @name PalletDataPreserversRegisteredProfile (471) */ + /** @name PalletDataPreserversRegisteredProfile (474) */ interface PalletDataPreserversRegisteredProfile extends Struct { readonly account: AccountId32; readonly deposit: u128; readonly profile: PalletDataPreserversProfile; + readonly assignment: Option>; } - /** @name PalletDataPreserversError (472) */ + /** @name PalletDataPreserversError (480) */ interface PalletDataPreserversError extends Enum { readonly isNoBootNodes: boolean; readonly isUnknownProfileId: boolean; readonly isNextProfileIdShouldBeAvailable: boolean; - readonly type: "NoBootNodes" | "UnknownProfileId" | "NextProfileIdShouldBeAvailable"; - } - - /** @name PalletInvulnerablesError (474) */ + readonly isAssignmentPaymentRequestParameterMismatch: boolean; + readonly isProfileAlreadyAssigned: boolean; + readonly isProfileNotAssigned: boolean; + readonly isProfileIsNotElligibleForParaId: boolean; + readonly isWrongParaId: boolean; + readonly isMaxAssignmentsPerParaIdReached: boolean; + readonly isCantDeleteAssignedProfile: boolean; + readonly type: + | "NoBootNodes" + | "UnknownProfileId" + | "NextProfileIdShouldBeAvailable" + | "AssignmentPaymentRequestParameterMismatch" + | "ProfileAlreadyAssigned" + | "ProfileNotAssigned" + | "ProfileIsNotElligibleForParaId" + | "WrongParaId" + | "MaxAssignmentsPerParaIdReached" + | "CantDeleteAssignedProfile"; + } + + /** @name PalletInvulnerablesError (482) */ interface PalletInvulnerablesError extends Enum { readonly isTooManyInvulnerables: boolean; readonly isAlreadyInvulnerable: boolean; @@ -5665,10 +5732,10 @@ declare module "@polkadot/types/lookup" { | "UnableToDeriveCollatorId"; } - /** @name SpCoreCryptoKeyTypeId (479) */ + /** @name SpCoreCryptoKeyTypeId (487) */ interface SpCoreCryptoKeyTypeId extends U8aFixed {} - /** @name PalletSessionError (480) */ + /** @name PalletSessionError (488) */ interface PalletSessionError extends Enum { readonly isInvalidProof: boolean; readonly isNoAssociatedValidatorId: boolean; @@ -5678,7 +5745,7 @@ declare module "@polkadot/types/lookup" { readonly type: "InvalidProof" | "NoAssociatedValidatorId" | "DuplicatedKey" | "NoKeys" | "NoAccount"; } - /** @name PalletAuthorInherentError (484) */ + /** @name PalletAuthorInherentError (492) */ interface PalletAuthorInherentError extends Enum { readonly isAuthorAlreadySet: boolean; readonly isNoAccountId: boolean; @@ -5686,13 +5753,13 @@ declare module "@polkadot/types/lookup" { readonly type: "AuthorAlreadySet" | "NoAccountId" | "CannotBeAuthor"; } - /** @name PalletPooledStakingCandidateEligibleCandidate (486) */ + /** @name PalletPooledStakingCandidateEligibleCandidate (494) */ interface PalletPooledStakingCandidateEligibleCandidate extends Struct { readonly candidate: AccountId32; readonly stake: u128; } - /** @name PalletPooledStakingPoolsKey (489) */ + /** @name PalletPooledStakingPoolsKey (497) */ interface PalletPooledStakingPoolsKey extends Enum { readonly isCandidateTotalStake: boolean; readonly isJoiningShares: boolean; @@ -5762,7 +5829,7 @@ declare module "@polkadot/types/lookup" { | "LeavingSharesHeldStake"; } - /** @name PalletPooledStakingError (491) */ + /** @name PalletPooledStakingError (499) */ interface PalletPooledStakingError extends Enum { readonly isInvalidPalletSetting: boolean; readonly isDisabledFeature: boolean; @@ -5796,13 +5863,13 @@ declare module "@polkadot/types/lookup" { | "SwapResultsInZeroShares"; } - /** @name PalletInflationRewardsChainsToRewardValue (492) */ + /** @name PalletInflationRewardsChainsToRewardValue (500) */ interface PalletInflationRewardsChainsToRewardValue extends Struct { readonly paraIds: Vec; readonly rewardsPerChain: u128; } - /** @name PalletTreasuryProposal (493) */ + /** @name PalletTreasuryProposal (501) */ interface PalletTreasuryProposal extends Struct { readonly proposer: AccountId32; readonly value: u128; @@ -5810,7 +5877,7 @@ declare module "@polkadot/types/lookup" { readonly bond: u128; } - /** @name PalletTreasurySpendStatus (495) */ + /** @name PalletTreasurySpendStatus (503) */ interface PalletTreasurySpendStatus extends Struct { readonly assetKind: Null; readonly amount: u128; @@ -5820,7 +5887,7 @@ declare module "@polkadot/types/lookup" { readonly status: PalletTreasuryPaymentState; } - /** @name PalletTreasuryPaymentState (496) */ + /** @name PalletTreasuryPaymentState (504) */ interface PalletTreasuryPaymentState extends Enum { readonly isPending: boolean; readonly isAttempted: boolean; @@ -5831,10 +5898,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Pending" | "Attempted" | "Failed"; } - /** @name FrameSupportPalletId (498) */ + /** @name FrameSupportPalletId (506) */ interface FrameSupportPalletId extends U8aFixed {} - /** @name PalletTreasuryError (499) */ + /** @name PalletTreasuryError (507) */ interface PalletTreasuryError extends Enum { readonly isInsufficientProposersBalance: boolean; readonly isInvalidIndex: boolean; @@ -5863,7 +5930,7 @@ declare module "@polkadot/types/lookup" { | "Inconclusive"; } - /** @name CumulusPalletXcmpQueueOutboundChannelDetails (503) */ + /** @name CumulusPalletXcmpQueueOutboundChannelDetails (510) */ interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct { readonly recipient: u32; readonly state: CumulusPalletXcmpQueueOutboundState; @@ -5872,21 +5939,21 @@ declare module "@polkadot/types/lookup" { readonly lastIndex: u16; } - /** @name CumulusPalletXcmpQueueOutboundState (504) */ + /** @name CumulusPalletXcmpQueueOutboundState (511) */ interface CumulusPalletXcmpQueueOutboundState extends Enum { readonly isOk: boolean; readonly isSuspended: boolean; readonly type: "Ok" | "Suspended"; } - /** @name CumulusPalletXcmpQueueQueueConfigData (506) */ + /** @name CumulusPalletXcmpQueueQueueConfigData (513) */ interface CumulusPalletXcmpQueueQueueConfigData extends Struct { readonly suspendThreshold: u32; readonly dropThreshold: u32; readonly resumeThreshold: u32; } - /** @name CumulusPalletXcmpQueueError (507) */ + /** @name CumulusPalletXcmpQueueError (514) */ interface CumulusPalletXcmpQueueError extends Enum { readonly isBadQueueConfig: boolean; readonly isAlreadySuspended: boolean; @@ -5894,7 +5961,7 @@ declare module "@polkadot/types/lookup" { readonly type: "BadQueueConfig" | "AlreadySuspended" | "AlreadyResumed"; } - /** @name CumulusPalletDmpQueueMigrationState (508) */ + /** @name CumulusPalletDmpQueueMigrationState (515) */ interface CumulusPalletDmpQueueMigrationState extends Enum { readonly isNotStarted: boolean; readonly isStartedExport: boolean; @@ -5922,7 +5989,7 @@ declare module "@polkadot/types/lookup" { | "Completed"; } - /** @name PalletXcmQueryStatus (511) */ + /** @name PalletXcmQueryStatus (518) */ interface PalletXcmQueryStatus extends Enum { readonly isPending: boolean; readonly asPending: { @@ -5944,7 +6011,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Pending" | "VersionNotifier" | "Ready"; } - /** @name XcmVersionedResponse (515) */ + /** @name XcmVersionedResponse (522) */ interface XcmVersionedResponse extends Enum { readonly isV2: boolean; readonly asV2: XcmV2Response; @@ -5955,7 +6022,7 @@ declare module "@polkadot/types/lookup" { readonly type: "V2" | "V3" | "V4"; } - /** @name PalletXcmVersionMigrationStage (521) */ + /** @name PalletXcmVersionMigrationStage (528) */ interface PalletXcmVersionMigrationStage extends Enum { readonly isMigrateSupportedVersion: boolean; readonly isMigrateVersionNotifiers: boolean; @@ -5969,7 +6036,7 @@ declare module "@polkadot/types/lookup" { | "MigrateAndNotifyOldTargets"; } - /** @name PalletXcmRemoteLockedFungibleRecord (523) */ + /** @name PalletXcmRemoteLockedFungibleRecord (530) */ interface PalletXcmRemoteLockedFungibleRecord extends Struct { readonly amount: u128; readonly owner: XcmVersionedLocation; @@ -5977,7 +6044,7 @@ declare module "@polkadot/types/lookup" { readonly consumers: Vec>; } - /** @name PalletXcmError (530) */ + /** @name PalletXcmError (537) */ interface PalletXcmError extends Enum { readonly isUnreachable: boolean; readonly isSendFailure: boolean; @@ -6030,7 +6097,7 @@ declare module "@polkadot/types/lookup" { | "LocalExecutionIncomplete"; } - /** @name PalletAssetsAssetDetails (531) */ + /** @name PalletAssetsAssetDetails (538) */ interface PalletAssetsAssetDetails extends Struct { readonly owner: AccountId32; readonly issuer: AccountId32; @@ -6046,7 +6113,7 @@ declare module "@polkadot/types/lookup" { readonly status: PalletAssetsAssetStatus; } - /** @name PalletAssetsAssetStatus (532) */ + /** @name PalletAssetsAssetStatus (539) */ interface PalletAssetsAssetStatus extends Enum { readonly isLive: boolean; readonly isFrozen: boolean; @@ -6054,7 +6121,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Live" | "Frozen" | "Destroying"; } - /** @name PalletAssetsAssetAccount (534) */ + /** @name PalletAssetsAssetAccount (541) */ interface PalletAssetsAssetAccount extends Struct { readonly balance: u128; readonly status: PalletAssetsAccountStatus; @@ -6062,7 +6129,7 @@ declare module "@polkadot/types/lookup" { readonly extra: Null; } - /** @name PalletAssetsAccountStatus (535) */ + /** @name PalletAssetsAccountStatus (542) */ interface PalletAssetsAccountStatus extends Enum { readonly isLiquid: boolean; readonly isFrozen: boolean; @@ -6070,7 +6137,7 @@ declare module "@polkadot/types/lookup" { readonly type: "Liquid" | "Frozen" | "Blocked"; } - /** @name PalletAssetsExistenceReason (536) */ + /** @name PalletAssetsExistenceReason (543) */ interface PalletAssetsExistenceReason extends Enum { readonly isConsumer: boolean; readonly isSufficient: boolean; @@ -6082,13 +6149,13 @@ declare module "@polkadot/types/lookup" { readonly type: "Consumer" | "Sufficient" | "DepositHeld" | "DepositRefunded" | "DepositFrom"; } - /** @name PalletAssetsApproval (538) */ + /** @name PalletAssetsApproval (545) */ interface PalletAssetsApproval extends Struct { readonly amount: u128; readonly deposit: u128; } - /** @name PalletAssetsAssetMetadata (539) */ + /** @name PalletAssetsAssetMetadata (546) */ interface PalletAssetsAssetMetadata extends Struct { readonly deposit: u128; readonly name: Bytes; @@ -6097,7 +6164,7 @@ declare module "@polkadot/types/lookup" { readonly isFrozen: bool; } - /** @name PalletAssetsError (541) */ + /** @name PalletAssetsError (548) */ interface PalletAssetsError extends Enum { readonly isBalanceLow: boolean; readonly isNoAccount: boolean; @@ -6142,14 +6209,14 @@ declare module "@polkadot/types/lookup" { | "CallbackFailed"; } - /** @name PalletForeignAssetCreatorError (542) */ + /** @name PalletForeignAssetCreatorError (549) */ interface PalletForeignAssetCreatorError extends Enum { readonly isAssetAlreadyExists: boolean; readonly isAssetDoesNotExist: boolean; readonly type: "AssetAlreadyExists" | "AssetDoesNotExist"; } - /** @name PalletAssetRateError (543) */ + /** @name PalletAssetRateError (550) */ interface PalletAssetRateError extends Enum { readonly isUnknownAssetKind: boolean; readonly isAlreadyExists: boolean; @@ -6157,7 +6224,7 @@ declare module "@polkadot/types/lookup" { readonly type: "UnknownAssetKind" | "AlreadyExists" | "Overflow"; } - /** @name PalletMessageQueueBookState (544) */ + /** @name PalletMessageQueueBookState (551) */ interface PalletMessageQueueBookState extends Struct { readonly begin: u32; readonly end: u32; @@ -6167,13 +6234,13 @@ declare module "@polkadot/types/lookup" { readonly size_: u64; } - /** @name PalletMessageQueueNeighbours (546) */ + /** @name PalletMessageQueueNeighbours (553) */ interface PalletMessageQueueNeighbours extends Struct { readonly prev: CumulusPrimitivesCoreAggregateMessageOrigin; readonly next: CumulusPrimitivesCoreAggregateMessageOrigin; } - /** @name PalletMessageQueuePage (548) */ + /** @name PalletMessageQueuePage (555) */ interface PalletMessageQueuePage extends Struct { readonly remaining: u32; readonly remainingSize: u32; @@ -6183,7 +6250,7 @@ declare module "@polkadot/types/lookup" { readonly heap: Bytes; } - /** @name PalletMessageQueueError (550) */ + /** @name PalletMessageQueueError (557) */ interface PalletMessageQueueError extends Enum { readonly isNotReapable: boolean; readonly isNoPage: boolean; @@ -6206,14 +6273,14 @@ declare module "@polkadot/types/lookup" { | "RecursiveDisallowed"; } - /** @name PalletXcmCoreBuyerInFlightCoreBuyingOrder (551) */ + /** @name PalletXcmCoreBuyerInFlightCoreBuyingOrder (558) */ interface PalletXcmCoreBuyerInFlightCoreBuyingOrder extends Struct { readonly paraId: u32; readonly queryId: u64; readonly ttl: u32; } - /** @name PalletXcmCoreBuyerError (552) */ + /** @name PalletXcmCoreBuyerError (559) */ interface PalletXcmCoreBuyerError extends Enum { readonly isInvalidProof: boolean; readonly isErrorValidatingXCM: boolean; @@ -6252,27 +6319,27 @@ declare module "@polkadot/types/lookup" { | "InvalidCollatorSignature"; } - /** @name FrameSystemExtensionsCheckNonZeroSender (557) */ + /** @name FrameSystemExtensionsCheckNonZeroSender (564) */ type FrameSystemExtensionsCheckNonZeroSender = Null; - /** @name FrameSystemExtensionsCheckSpecVersion (558) */ + /** @name FrameSystemExtensionsCheckSpecVersion (565) */ type FrameSystemExtensionsCheckSpecVersion = Null; - /** @name FrameSystemExtensionsCheckTxVersion (559) */ + /** @name FrameSystemExtensionsCheckTxVersion (566) */ type FrameSystemExtensionsCheckTxVersion = Null; - /** @name FrameSystemExtensionsCheckGenesis (560) */ + /** @name FrameSystemExtensionsCheckGenesis (567) */ type FrameSystemExtensionsCheckGenesis = Null; - /** @name FrameSystemExtensionsCheckNonce (563) */ + /** @name FrameSystemExtensionsCheckNonce (570) */ interface FrameSystemExtensionsCheckNonce extends Compact {} - /** @name FrameSystemExtensionsCheckWeight (564) */ + /** @name FrameSystemExtensionsCheckWeight (571) */ type FrameSystemExtensionsCheckWeight = Null; - /** @name PalletTransactionPaymentChargeTransactionPayment (565) */ + /** @name PalletTransactionPaymentChargeTransactionPayment (572) */ interface PalletTransactionPaymentChargeTransactionPayment extends Compact {} - /** @name DanceboxRuntimeRuntime (566) */ + /** @name DanceboxRuntimeRuntime (573) */ type DanceboxRuntimeRuntime = Null; } // declare module diff --git a/typescript-api/src/flashbox/interfaces/augment-api-consts.ts b/typescript-api/src/flashbox/interfaces/augment-api-consts.ts index 484589048..ab02921da 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-consts.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-consts.ts @@ -66,8 +66,8 @@ declare module "@polkadot/api-base/types/consts" { [key: string]: Codec; }; dataPreservers: { - maxBootNodes: u32 & AugmentedConst; - maxBootNodeUrlLen: u32 & AugmentedConst; + maxAssignmentsPerParaId: u32 & AugmentedConst; + maxNodeUrlLen: u32 & AugmentedConst; maxParaIdsVecLen: u32 & AugmentedConst; /** Generic const */ [key: string]: Codec; diff --git a/typescript-api/src/flashbox/interfaces/augment-api-errors.ts b/typescript-api/src/flashbox/interfaces/augment-api-errors.ts index a6ebbca5f..96ed843ff 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-errors.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-errors.ts @@ -68,10 +68,18 @@ declare module "@polkadot/api-base/types/errors" { [key: string]: AugmentedError; }; dataPreservers: { + /** Made for `AssignmentPayment` implementors to report a mismatch between `ProviderRequest` and `AssignerParameter`. */ + AssignmentPaymentRequestParameterMismatch: AugmentedError; + CantDeleteAssignedProfile: AugmentedError; + MaxAssignmentsPerParaIdReached: AugmentedError; NextProfileIdShouldBeAvailable: AugmentedError; /** This container chain does not have any boot nodes */ NoBootNodes: AugmentedError; + ProfileAlreadyAssigned: AugmentedError; + ProfileIsNotElligibleForParaId: AugmentedError; + ProfileNotAssigned: AugmentedError; UnknownProfileId: AugmentedError; + WrongParaId: AugmentedError; /** Generic error */ [key: string]: AugmentedError; }; diff --git a/typescript-api/src/flashbox/interfaces/augment-api-events.ts b/typescript-api/src/flashbox/interfaces/augment-api-events.ts index 9b01d6341..5c6a0afe1 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-events.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-events.ts @@ -124,6 +124,8 @@ declare module "@polkadot/api-base/types/events" { [key: string]: AugmentedEvent; }; dataPreservers: { + AssignmentStarted: AugmentedEvent; + AssignmentStopped: AugmentedEvent; /** The list of boot_nodes changed. */ BootNodesChanged: AugmentedEvent; ProfileCreated: AugmentedEvent< diff --git a/typescript-api/src/flashbox/interfaces/augment-api-query.ts b/typescript-api/src/flashbox/interfaces/augment-api-query.ts index 2bb8371d9..d4b38e0d6 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-query.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-query.ts @@ -7,7 +7,19 @@ import "@polkadot/api-base/types/storage"; import type { ApiTypes, AugmentedQuery, QueryableStorageEntry } from "@polkadot/api-base/types"; import type { Data } from "@polkadot/types"; -import type { BTreeMap, Bytes, Null, Option, U8aFixed, Vec, bool, u128, u32, u64 } from "@polkadot/types-codec"; +import type { + BTreeMap, + BTreeSet, + Bytes, + Null, + Option, + U8aFixed, + Vec, + bool, + u128, + u32, + u64, +} from "@polkadot/types-codec"; import type { AnyNumber, ITuple } from "@polkadot/types-codec/types"; import type { AccountId32, H256 } from "@polkadot/types/interfaces/runtime"; import type { @@ -251,7 +263,11 @@ declare module "@polkadot/api-base/types/storage" { [key: string]: QueryableStorageEntry; }; dataPreservers: { - bootNodes: AugmentedQuery Observable>, [u32]> & + assignments: AugmentedQuery< + ApiType, + (arg: u32 | AnyNumber | Uint8Array) => Observable>, + [u32] + > & QueryableStorageEntry; nextProfileId: AugmentedQuery Observable, []> & QueryableStorageEntry; profiles: AugmentedQuery< diff --git a/typescript-api/src/flashbox/interfaces/augment-api-tx.ts b/typescript-api/src/flashbox/interfaces/augment-api-tx.ts index bea500a94..ffc47e3d1 100644 --- a/typescript-api/src/flashbox/interfaces/augment-api-tx.ts +++ b/typescript-api/src/flashbox/interfaces/augment-api-tx.ts @@ -18,6 +18,8 @@ import type { AccountId32, Call, H256, MultiAddress, Perbill } from "@polkadot/t import type { CumulusPrimitivesParachainInherentParachainInherentData, FlashboxRuntimeOriginCaller, + FlashboxRuntimePreserversAssignementPaymentExtra, + FlashboxRuntimePreserversAssignementPaymentWitness, FlashboxRuntimeProxyType, FlashboxRuntimeSessionKeys, FlashboxRuntimeStreamPaymentAssetId, @@ -303,7 +305,7 @@ declare module "@polkadot/api-base/types/submittable" { ( profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array ) => SubmittableExtrinsic, @@ -317,7 +319,7 @@ declare module "@polkadot/api-base/types/submittable" { ( profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array, forAccount: AccountId32 | string | Uint8Array @@ -328,31 +330,46 @@ declare module "@polkadot/api-base/types/submittable" { (profileId: u64 | AnyNumber | Uint8Array) => SubmittableExtrinsic, [u64] >; + forceStartAssignment: AugmentedSubmittable< + ( + profileId: u64 | AnyNumber | Uint8Array, + paraId: u32 | AnyNumber | Uint8Array, + assignmentWitness: FlashboxRuntimePreserversAssignementPaymentWitness | "Free" | number | Uint8Array + ) => SubmittableExtrinsic, + [u64, u32, FlashboxRuntimePreserversAssignementPaymentWitness] + >; forceUpdateProfile: AugmentedSubmittable< ( profileId: u64 | AnyNumber | Uint8Array, profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array ) => SubmittableExtrinsic, [u64, PalletDataPreserversProfile] >; - /** Set boot_nodes for this para id */ - setBootNodes: AugmentedSubmittable< + startAssignment: AugmentedSubmittable< ( + profileId: u64 | AnyNumber | Uint8Array, paraId: u32 | AnyNumber | Uint8Array, - bootNodes: Vec | (Bytes | string | Uint8Array)[] + assignerParam: FlashboxRuntimePreserversAssignementPaymentExtra | "Free" | number | Uint8Array + ) => SubmittableExtrinsic, + [u64, u32, FlashboxRuntimePreserversAssignementPaymentExtra] + >; + stopAssignment: AugmentedSubmittable< + ( + profileId: u64 | AnyNumber | Uint8Array, + paraId: u32 | AnyNumber | Uint8Array ) => SubmittableExtrinsic, - [u32, Vec] + [u64, u32] >; updateProfile: AugmentedSubmittable< ( profileId: u64 | AnyNumber | Uint8Array, profile: | PalletDataPreserversProfile - | { url?: any; paraIds?: any; mode?: any } + | { url?: any; paraIds?: any; mode?: any; assignmentRequest?: any } | string | Uint8Array ) => SubmittableExtrinsic, diff --git a/typescript-api/src/flashbox/interfaces/lookup.ts b/typescript-api/src/flashbox/interfaces/lookup.ts index 82e148812..0a7651dd6 100644 --- a/typescript-api/src/flashbox/interfaces/lookup.ts +++ b/typescript-api/src/flashbox/interfaces/lookup.ts @@ -670,6 +670,14 @@ export default { profileId: "u64", releasedDeposit: "u128", }, + AssignmentStarted: { + profileId: "u64", + paraId: "u32", + }, + AssignmentStopped: { + profileId: "u64", + paraId: "u32", + }, }, }, /** Lookup68: pallet_invulnerables::pallet::Event */ @@ -1641,10 +1649,7 @@ export default { /** Lookup225: pallet_data_preservers::pallet::Call */ PalletDataPreserversCall: { _enum: { - set_boot_nodes: { - paraId: "u32", - bootNodes: "Vec", - }, + __Unused0: "Null", create_profile: { profile: "PalletDataPreserversProfile", }, @@ -1666,23 +1671,38 @@ export default { force_delete_profile: { profileId: "u64", }, + start_assignment: { + profileId: "u64", + paraId: "u32", + assignerParam: "FlashboxRuntimePreserversAssignementPaymentExtra", + }, + stop_assignment: { + profileId: "u64", + paraId: "u32", + }, + force_start_assignment: { + profileId: "u64", + paraId: "u32", + assignmentWitness: "FlashboxRuntimePreserversAssignementPaymentWitness", + }, }, }, - /** Lookup229: pallet_data_preservers::pallet::Profile */ + /** Lookup226: pallet_data_preservers::types::Profile */ PalletDataPreserversProfile: { url: "Bytes", paraIds: "PalletDataPreserversParaIdsFilter", mode: "PalletDataPreserversProfileMode", + assignmentRequest: "FlashboxRuntimePreserversAssignementPaymentRequest", }, - /** Lookup230: pallet_data_preservers::pallet::ParaIdsFilter */ + /** Lookup228: pallet_data_preservers::types::ParaIdsFilter */ PalletDataPreserversParaIdsFilter: { _enum: { AnyParaId: "Null", - Whitelist: "Vec", - Blacklist: "Vec", + Whitelist: "BTreeSet", + Blacklist: "BTreeSet", }, }, - /** Lookup233: pallet_data_preservers::pallet::ProfileMode */ + /** Lookup232: pallet_data_preservers::types::ProfileMode */ PalletDataPreserversProfileMode: { _enum: { Bootnode: "Null", @@ -1691,7 +1711,19 @@ export default { }, }, }, - /** Lookup234: pallet_invulnerables::pallet::Call */ + /** Lookup233: flashbox_runtime::PreserversAssignementPaymentRequest */ + FlashboxRuntimePreserversAssignementPaymentRequest: { + _enum: ["Free"], + }, + /** Lookup234: flashbox_runtime::PreserversAssignementPaymentExtra */ + FlashboxRuntimePreserversAssignementPaymentExtra: { + _enum: ["Free"], + }, + /** Lookup235: flashbox_runtime::PreserversAssignementPaymentWitness */ + FlashboxRuntimePreserversAssignementPaymentWitness: { + _enum: ["Free"], + }, + /** Lookup236: pallet_invulnerables::pallet::Call */ PalletInvulnerablesCall: { _enum: { __Unused0: "Null", @@ -1703,7 +1735,7 @@ export default { }, }, }, - /** Lookup235: pallet_session::pallet::Call */ + /** Lookup237: pallet_session::pallet::Call */ PalletSessionCall: { _enum: { set_keys: { @@ -1716,17 +1748,17 @@ export default { purge_keys: "Null", }, }, - /** Lookup236: flashbox_runtime::SessionKeys */ + /** Lookup238: flashbox_runtime::SessionKeys */ FlashboxRuntimeSessionKeys: { nimbus: "NimbusPrimitivesNimbusCryptoPublic", }, - /** Lookup237: nimbus_primitives::nimbus_crypto::Public */ + /** Lookup239: nimbus_primitives::nimbus_crypto::Public */ NimbusPrimitivesNimbusCryptoPublic: "[u8;32]", - /** Lookup238: pallet_author_inherent::pallet::Call */ + /** Lookup240: pallet_author_inherent::pallet::Call */ PalletAuthorInherentCall: { _enum: ["kick_off_authorship_validation"], }, - /** Lookup239: pallet_treasury::pallet::Call */ + /** Lookup241: pallet_treasury::pallet::Call */ PalletTreasuryCall: { _enum: { propose_spend: { @@ -1763,7 +1795,7 @@ export default { }, }, }, - /** Lookup240: pallet_root_testing::pallet::Call */ + /** Lookup242: pallet_root_testing::pallet::Call */ PalletRootTestingCall: { _enum: { fill_block: { @@ -1772,27 +1804,27 @@ export default { trigger_defensive: "Null", }, }, - /** Lookup241: pallet_sudo::pallet::Error */ + /** Lookup243: pallet_sudo::pallet::Error */ PalletSudoError: { _enum: ["RequireSudo"], }, - /** Lookup242: pallet_utility::pallet::Error */ + /** Lookup244: pallet_utility::pallet::Error */ PalletUtilityError: { _enum: ["TooManyCalls"], }, - /** Lookup245: pallet_proxy::ProxyDefinition */ + /** Lookup247: pallet_proxy::ProxyDefinition */ PalletProxyProxyDefinition: { delegate: "AccountId32", proxyType: "FlashboxRuntimeProxyType", delay: "u32", }, - /** Lookup249: pallet_proxy::Announcement */ + /** Lookup251: pallet_proxy::Announcement */ PalletProxyAnnouncement: { real: "AccountId32", callHash: "H256", height: "u32", }, - /** Lookup251: pallet_proxy::pallet::Error */ + /** Lookup253: pallet_proxy::pallet::Error */ PalletProxyError: { _enum: [ "TooMany", @@ -1805,39 +1837,39 @@ export default { "NoSelfProxy", ], }, - /** Lookup252: pallet_migrations::pallet::Error */ + /** Lookup254: pallet_migrations::pallet::Error */ PalletMigrationsError: { _enum: ["PreimageMissing", "WrongUpperBound", "PreimageIsTooBig", "PreimageAlreadyExists"], }, - /** Lookup253: pallet_maintenance_mode::pallet::Error */ + /** Lookup255: pallet_maintenance_mode::pallet::Error */ PalletMaintenanceModeError: { _enum: ["AlreadyInMaintenanceMode", "NotInMaintenanceMode"], }, - /** Lookup254: pallet_tx_pause::pallet::Error */ + /** Lookup256: pallet_tx_pause::pallet::Error */ PalletTxPauseError: { _enum: ["IsPaused", "IsUnpaused", "Unpausable", "NotFound"], }, - /** Lookup256: pallet_balances::types::BalanceLock */ + /** Lookup258: pallet_balances::types::BalanceLock */ PalletBalancesBalanceLock: { id: "[u8;8]", amount: "u128", reasons: "PalletBalancesReasons", }, - /** Lookup257: pallet_balances::types::Reasons */ + /** Lookup259: pallet_balances::types::Reasons */ PalletBalancesReasons: { _enum: ["Fee", "Misc", "All"], }, - /** Lookup260: pallet_balances::types::ReserveData */ + /** Lookup262: pallet_balances::types::ReserveData */ PalletBalancesReserveData: { id: "[u8;8]", amount: "u128", }, - /** Lookup263: pallet_balances::types::IdAmount */ + /** Lookup265: pallet_balances::types::IdAmount */ PalletBalancesIdAmountRuntimeHoldReason: { id: "FlashboxRuntimeRuntimeHoldReason", amount: "u128", }, - /** Lookup264: flashbox_runtime::RuntimeHoldReason */ + /** Lookup266: flashbox_runtime::RuntimeHoldReason */ FlashboxRuntimeRuntimeHoldReason: { _enum: { __Unused0: "Null", @@ -1870,20 +1902,20 @@ export default { DataPreservers: "PalletDataPreserversHoldReason", }, }, - /** Lookup265: pallet_stream_payment::pallet::HoldReason */ + /** Lookup267: pallet_stream_payment::pallet::HoldReason */ PalletStreamPaymentHoldReason: { _enum: ["StreamPayment", "StreamOpened"], }, - /** Lookup266: pallet_data_preservers::pallet::HoldReason */ + /** Lookup268: pallet_data_preservers::pallet::HoldReason */ PalletDataPreserversHoldReason: { _enum: ["ProfileDeposit"], }, - /** Lookup269: pallet_balances::types::IdAmount */ + /** Lookup271: pallet_balances::types::IdAmount */ PalletBalancesIdAmountRuntimeFreezeReason: { id: "FlashboxRuntimeRuntimeFreezeReason", amount: "u128", }, - /** Lookup270: flashbox_runtime::RuntimeFreezeReason */ + /** Lookup272: flashbox_runtime::RuntimeFreezeReason */ FlashboxRuntimeRuntimeFreezeReason: { _enum: { __Unused0: "Null", @@ -1901,11 +1933,11 @@ export default { StreamPayment: "PalletStreamPaymentFreezeReason", }, }, - /** Lookup271: pallet_stream_payment::pallet::FreezeReason */ + /** Lookup273: pallet_stream_payment::pallet::FreezeReason */ PalletStreamPaymentFreezeReason: { _enum: ["StreamPayment"], }, - /** Lookup273: pallet_balances::pallet::Error */ + /** Lookup275: pallet_balances::pallet::Error */ PalletBalancesError: { _enum: [ "VestingBalance", @@ -1922,12 +1954,12 @@ export default { "DeltaZero", ], }, - /** Lookup274: pallet_transaction_payment::Releases */ + /** Lookup276: pallet_transaction_payment::Releases */ PalletTransactionPaymentReleases: { _enum: ["V1Ancient", "V2"], }, /** - * Lookup275: pallet_stream_payment::pallet::Stream */ PalletStreamPaymentStream: { @@ -1941,7 +1973,7 @@ export default { openingDeposit: "u128", }, /** - * Lookup277: pallet_stream_payment::pallet::ChangeRequest */ PalletStreamPaymentChangeRequest: { @@ -1950,7 +1982,7 @@ export default { newConfig: "PalletStreamPaymentStreamConfig", depositChange: "Option", }, - /** Lookup279: pallet_stream_payment::pallet::Error */ + /** Lookup281: pallet_stream_payment::pallet::Error */ PalletStreamPaymentError: { _enum: [ "UnknownStreamId", @@ -1970,24 +2002,24 @@ export default { "ImmediateDepositChangeRequiresSameAssetId", ], }, - /** Lookup281: pallet_identity::types::Registration> */ + /** Lookup283: pallet_identity::types::Registration> */ PalletIdentityRegistration: { judgements: "Vec<(u32,PalletIdentityJudgement)>", deposit: "u128", info: "PalletIdentityLegacyIdentityInfo", }, - /** Lookup290: pallet_identity::types::RegistrarInfo */ + /** Lookup292: pallet_identity::types::RegistrarInfo */ PalletIdentityRegistrarInfo: { account: "AccountId32", fee: "u128", fields: "u64", }, - /** Lookup292: pallet_identity::types::AuthorityProperties> */ + /** Lookup294: pallet_identity::types::AuthorityProperties> */ PalletIdentityAuthorityProperties: { suffix: "Bytes", allocation: "u32", }, - /** Lookup295: pallet_identity::pallet::Error */ + /** Lookup297: pallet_identity::pallet::Error */ PalletIdentityError: { _enum: [ "TooManySubAccounts", @@ -2018,14 +2050,14 @@ export default { "NotExpired", ], }, - /** Lookup297: pallet_multisig::Multisig */ + /** Lookup299: pallet_multisig::Multisig */ PalletMultisigMultisig: { when: "PalletMultisigTimepoint", deposit: "u128", depositor: "AccountId32", approvals: "Vec", }, - /** Lookup299: pallet_multisig::pallet::Error */ + /** Lookup301: pallet_multisig::pallet::Error */ PalletMultisigError: { _enum: [ "MinimumThreshold", @@ -2044,12 +2076,12 @@ export default { "AlreadyStored", ], }, - /** Lookup307: pallet_registrar::pallet::DepositInfo */ + /** Lookup310: pallet_registrar::pallet::DepositInfo */ PalletRegistrarDepositInfo: { creator: "AccountId32", deposit: "u128", }, - /** Lookup308: pallet_registrar::pallet::Error */ + /** Lookup311: pallet_registrar::pallet::Error */ PalletRegistrarError: { _enum: [ "ParaIdAlreadyRegistered", @@ -2069,7 +2101,7 @@ export default { "ParaStillExistsInRelay", ], }, - /** Lookup309: pallet_configuration::HostConfiguration */ + /** Lookup312: pallet_configuration::HostConfiguration */ PalletConfigurationHostConfiguration: { maxCollators: "u32", minOrchestratorCollators: "u32", @@ -2080,22 +2112,22 @@ export default { parathreadsPerCollator: "u32", targetContainerChainFullness: "Perbill", }, - /** Lookup312: pallet_configuration::pallet::Error */ + /** Lookup315: pallet_configuration::pallet::Error */ PalletConfigurationError: { _enum: ["InvalidNewValue"], }, - /** Lookup313: dp_collator_assignment::AssignedCollators */ + /** Lookup316: dp_collator_assignment::AssignedCollators */ DpCollatorAssignmentAssignedCollatorsAccountId32: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup318: tp_traits::ContainerChainBlockInfo */ + /** Lookup321: tp_traits::ContainerChainBlockInfo */ TpTraitsContainerChainBlockInfo: { blockNumber: "u32", author: "AccountId32", latestSlotNumber: "u64", }, - /** Lookup319: pallet_author_noting::pallet::Error */ + /** Lookup322: pallet_author_noting::pallet::Error */ PalletAuthorNotingError: { _enum: [ "FailedReading", @@ -2107,26 +2139,38 @@ export default { "NonAuraDigest", ], }, - /** Lookup320: dp_collator_assignment::AssignedCollators */ + /** Lookup323: dp_collator_assignment::AssignedCollators */ DpCollatorAssignmentAssignedCollatorsPublic: { orchestratorChain: "Vec", containerChains: "BTreeMap>", }, - /** Lookup325: pallet_services_payment::pallet::Error */ + /** Lookup328: pallet_services_payment::pallet::Error */ PalletServicesPaymentError: { _enum: ["InsufficientFundsToPurchaseCredits", "InsufficientCredits", "CreditPriceTooExpensive"], }, - /** Lookup326: pallet_data_preservers::pallet::RegisteredProfile */ + /** Lookup329: pallet_data_preservers::types::RegisteredProfile */ PalletDataPreserversRegisteredProfile: { account: "AccountId32", deposit: "u128", profile: "PalletDataPreserversProfile", + assignment: "Option<(u32,FlashboxRuntimePreserversAssignementPaymentWitness)>", }, - /** Lookup327: pallet_data_preservers::pallet::Error */ + /** Lookup335: pallet_data_preservers::pallet::Error */ PalletDataPreserversError: { - _enum: ["NoBootNodes", "UnknownProfileId", "NextProfileIdShouldBeAvailable"], + _enum: [ + "NoBootNodes", + "UnknownProfileId", + "NextProfileIdShouldBeAvailable", + "AssignmentPaymentRequestParameterMismatch", + "ProfileAlreadyAssigned", + "ProfileNotAssigned", + "ProfileIsNotElligibleForParaId", + "WrongParaId", + "MaxAssignmentsPerParaIdReached", + "CantDeleteAssignedProfile", + ], }, - /** Lookup329: pallet_invulnerables::pallet::Error */ + /** Lookup337: pallet_invulnerables::pallet::Error */ PalletInvulnerablesError: { _enum: [ "TooManyInvulnerables", @@ -2136,29 +2180,29 @@ export default { "UnableToDeriveCollatorId", ], }, - /** Lookup334: sp_core::crypto::KeyTypeId */ + /** Lookup342: sp_core::crypto::KeyTypeId */ SpCoreCryptoKeyTypeId: "[u8;4]", - /** Lookup335: pallet_session::pallet::Error */ + /** Lookup343: pallet_session::pallet::Error */ PalletSessionError: { _enum: ["InvalidProof", "NoAssociatedValidatorId", "DuplicatedKey", "NoKeys", "NoAccount"], }, - /** Lookup339: pallet_author_inherent::pallet::Error */ + /** Lookup347: pallet_author_inherent::pallet::Error */ PalletAuthorInherentError: { _enum: ["AuthorAlreadySet", "NoAccountId", "CannotBeAuthor"], }, - /** Lookup340: pallet_inflation_rewards::pallet::ChainsToRewardValue */ + /** Lookup348: pallet_inflation_rewards::pallet::ChainsToRewardValue */ PalletInflationRewardsChainsToRewardValue: { paraIds: "Vec", rewardsPerChain: "u128", }, - /** Lookup341: pallet_treasury::Proposal */ + /** Lookup349: pallet_treasury::Proposal */ PalletTreasuryProposal: { proposer: "AccountId32", value: "u128", beneficiary: "AccountId32", bond: "u128", }, - /** Lookup343: pallet_treasury::SpendStatus */ + /** Lookup351: pallet_treasury::SpendStatus */ PalletTreasurySpendStatus: { assetKind: "Null", amount: "u128", @@ -2167,7 +2211,7 @@ export default { expireAt: "u32", status: "PalletTreasuryPaymentState", }, - /** Lookup344: pallet_treasury::PaymentState */ + /** Lookup352: pallet_treasury::PaymentState */ PalletTreasuryPaymentState: { _enum: { Pending: "Null", @@ -2177,9 +2221,9 @@ export default { Failed: "Null", }, }, - /** Lookup346: frame_support::PalletId */ + /** Lookup354: frame_support::PalletId */ FrameSupportPalletId: "[u8;8]", - /** Lookup347: pallet_treasury::pallet::Error */ + /** Lookup355: pallet_treasury::pallet::Error */ PalletTreasuryError: { _enum: [ "InsufficientProposersBalance", @@ -2196,20 +2240,20 @@ export default { "Inconclusive", ], }, - /** Lookup352: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ + /** Lookup360: frame_system::extensions::check_non_zero_sender::CheckNonZeroSender */ FrameSystemExtensionsCheckNonZeroSender: "Null", - /** Lookup353: frame_system::extensions::check_spec_version::CheckSpecVersion */ + /** Lookup361: frame_system::extensions::check_spec_version::CheckSpecVersion */ FrameSystemExtensionsCheckSpecVersion: "Null", - /** Lookup354: frame_system::extensions::check_tx_version::CheckTxVersion */ + /** Lookup362: frame_system::extensions::check_tx_version::CheckTxVersion */ FrameSystemExtensionsCheckTxVersion: "Null", - /** Lookup355: frame_system::extensions::check_genesis::CheckGenesis */ + /** Lookup363: frame_system::extensions::check_genesis::CheckGenesis */ FrameSystemExtensionsCheckGenesis: "Null", - /** Lookup358: frame_system::extensions::check_nonce::CheckNonce */ + /** Lookup366: frame_system::extensions::check_nonce::CheckNonce */ FrameSystemExtensionsCheckNonce: "Compact", - /** Lookup359: frame_system::extensions::check_weight::CheckWeight */ + /** Lookup367: frame_system::extensions::check_weight::CheckWeight */ FrameSystemExtensionsCheckWeight: "Null", - /** Lookup360: pallet_transaction_payment::ChargeTransactionPayment */ + /** Lookup368: pallet_transaction_payment::ChargeTransactionPayment */ PalletTransactionPaymentChargeTransactionPayment: "Compact", - /** Lookup361: flashbox_runtime::Runtime */ + /** Lookup369: flashbox_runtime::Runtime */ FlashboxRuntimeRuntime: "Null", }; diff --git a/typescript-api/src/flashbox/interfaces/registry.ts b/typescript-api/src/flashbox/interfaces/registry.ts index eceab079d..980f90fdd 100644 --- a/typescript-api/src/flashbox/interfaces/registry.ts +++ b/typescript-api/src/flashbox/interfaces/registry.ts @@ -19,6 +19,9 @@ import type { DpCollatorAssignmentAssignedCollatorsAccountId32, DpCollatorAssignmentAssignedCollatorsPublic, FlashboxRuntimeOriginCaller, + FlashboxRuntimePreserversAssignementPaymentExtra, + FlashboxRuntimePreserversAssignementPaymentRequest, + FlashboxRuntimePreserversAssignementPaymentWitness, FlashboxRuntimeProxyType, FlashboxRuntimeRuntime, FlashboxRuntimeRuntimeFreezeReason, @@ -201,6 +204,9 @@ declare module "@polkadot/types/types/registry" { DpCollatorAssignmentAssignedCollatorsAccountId32: DpCollatorAssignmentAssignedCollatorsAccountId32; DpCollatorAssignmentAssignedCollatorsPublic: DpCollatorAssignmentAssignedCollatorsPublic; FlashboxRuntimeOriginCaller: FlashboxRuntimeOriginCaller; + FlashboxRuntimePreserversAssignementPaymentExtra: FlashboxRuntimePreserversAssignementPaymentExtra; + FlashboxRuntimePreserversAssignementPaymentRequest: FlashboxRuntimePreserversAssignementPaymentRequest; + FlashboxRuntimePreserversAssignementPaymentWitness: FlashboxRuntimePreserversAssignementPaymentWitness; FlashboxRuntimeProxyType: FlashboxRuntimeProxyType; FlashboxRuntimeRuntime: FlashboxRuntimeRuntime; FlashboxRuntimeRuntimeFreezeReason: FlashboxRuntimeRuntimeFreezeReason; diff --git a/typescript-api/src/flashbox/interfaces/types-lookup.ts b/typescript-api/src/flashbox/interfaces/types-lookup.ts index 2357bec20..7226c948c 100644 --- a/typescript-api/src/flashbox/interfaces/types-lookup.ts +++ b/typescript-api/src/flashbox/interfaces/types-lookup.ts @@ -956,7 +956,23 @@ declare module "@polkadot/types/lookup" { readonly profileId: u64; readonly releasedDeposit: u128; } & Struct; - readonly type: "BootNodesChanged" | "ProfileCreated" | "ProfileUpdated" | "ProfileDeleted"; + readonly isAssignmentStarted: boolean; + readonly asAssignmentStarted: { + readonly profileId: u64; + readonly paraId: u32; + } & Struct; + readonly isAssignmentStopped: boolean; + readonly asAssignmentStopped: { + readonly profileId: u64; + readonly paraId: u32; + } & Struct; + readonly type: + | "BootNodesChanged" + | "ProfileCreated" + | "ProfileUpdated" + | "ProfileDeleted" + | "AssignmentStarted" + | "AssignmentStopped"; } /** @name PalletInvulnerablesEvent (68) */ @@ -2148,11 +2164,6 @@ declare module "@polkadot/types/lookup" { /** @name PalletDataPreserversCall (225) */ interface PalletDataPreserversCall extends Enum { - readonly isSetBootNodes: boolean; - readonly asSetBootNodes: { - readonly paraId: u32; - readonly bootNodes: Vec; - } & Struct; readonly isCreateProfile: boolean; readonly asCreateProfile: { readonly profile: PalletDataPreserversProfile; @@ -2180,34 +2191,54 @@ declare module "@polkadot/types/lookup" { readonly asForceDeleteProfile: { readonly profileId: u64; } & Struct; + readonly isStartAssignment: boolean; + readonly asStartAssignment: { + readonly profileId: u64; + readonly paraId: u32; + readonly assignerParam: FlashboxRuntimePreserversAssignementPaymentExtra; + } & Struct; + readonly isStopAssignment: boolean; + readonly asStopAssignment: { + readonly profileId: u64; + readonly paraId: u32; + } & Struct; + readonly isForceStartAssignment: boolean; + readonly asForceStartAssignment: { + readonly profileId: u64; + readonly paraId: u32; + readonly assignmentWitness: FlashboxRuntimePreserversAssignementPaymentWitness; + } & Struct; readonly type: - | "SetBootNodes" | "CreateProfile" | "UpdateProfile" | "DeleteProfile" | "ForceCreateProfile" | "ForceUpdateProfile" - | "ForceDeleteProfile"; + | "ForceDeleteProfile" + | "StartAssignment" + | "StopAssignment" + | "ForceStartAssignment"; } - /** @name PalletDataPreserversProfile (229) */ + /** @name PalletDataPreserversProfile (226) */ interface PalletDataPreserversProfile extends Struct { readonly url: Bytes; readonly paraIds: PalletDataPreserversParaIdsFilter; readonly mode: PalletDataPreserversProfileMode; + readonly assignmentRequest: FlashboxRuntimePreserversAssignementPaymentRequest; } - /** @name PalletDataPreserversParaIdsFilter (230) */ + /** @name PalletDataPreserversParaIdsFilter (228) */ interface PalletDataPreserversParaIdsFilter extends Enum { readonly isAnyParaId: boolean; readonly isWhitelist: boolean; - readonly asWhitelist: Vec; + readonly asWhitelist: BTreeSet; readonly isBlacklist: boolean; - readonly asBlacklist: Vec; + readonly asBlacklist: BTreeSet; readonly type: "AnyParaId" | "Whitelist" | "Blacklist"; } - /** @name PalletDataPreserversProfileMode (233) */ + /** @name PalletDataPreserversProfileMode (232) */ interface PalletDataPreserversProfileMode extends Enum { readonly isBootnode: boolean; readonly isRpc: boolean; @@ -2217,7 +2248,25 @@ declare module "@polkadot/types/lookup" { readonly type: "Bootnode" | "Rpc"; } - /** @name PalletInvulnerablesCall (234) */ + /** @name FlashboxRuntimePreserversAssignementPaymentRequest (233) */ + interface FlashboxRuntimePreserversAssignementPaymentRequest extends Enum { + readonly isFree: boolean; + readonly type: "Free"; + } + + /** @name FlashboxRuntimePreserversAssignementPaymentExtra (234) */ + interface FlashboxRuntimePreserversAssignementPaymentExtra extends Enum { + readonly isFree: boolean; + readonly type: "Free"; + } + + /** @name FlashboxRuntimePreserversAssignementPaymentWitness (235) */ + interface FlashboxRuntimePreserversAssignementPaymentWitness extends Enum { + readonly isFree: boolean; + readonly type: "Free"; + } + + /** @name PalletInvulnerablesCall (236) */ interface PalletInvulnerablesCall extends Enum { readonly isAddInvulnerable: boolean; readonly asAddInvulnerable: { @@ -2230,7 +2279,7 @@ declare module "@polkadot/types/lookup" { readonly type: "AddInvulnerable" | "RemoveInvulnerable"; } - /** @name PalletSessionCall (235) */ + /** @name PalletSessionCall (237) */ interface PalletSessionCall extends Enum { readonly isSetKeys: boolean; readonly asSetKeys: { @@ -2241,21 +2290,21 @@ declare module "@polkadot/types/lookup" { readonly type: "SetKeys" | "PurgeKeys"; } - /** @name FlashboxRuntimeSessionKeys (236) */ + /** @name FlashboxRuntimeSessionKeys (238) */ interface FlashboxRuntimeSessionKeys extends Struct { readonly nimbus: NimbusPrimitivesNimbusCryptoPublic; } - /** @name NimbusPrimitivesNimbusCryptoPublic (237) */ + /** @name NimbusPrimitivesNimbusCryptoPublic (239) */ interface NimbusPrimitivesNimbusCryptoPublic extends U8aFixed {} - /** @name PalletAuthorInherentCall (238) */ + /** @name PalletAuthorInherentCall (240) */ interface PalletAuthorInherentCall extends Enum { readonly isKickOffAuthorshipValidation: boolean; readonly type: "KickOffAuthorshipValidation"; } - /** @name PalletTreasuryCall (239) */ + /** @name PalletTreasuryCall (241) */ interface PalletTreasuryCall extends Enum { readonly isProposeSpend: boolean; readonly asProposeSpend: { @@ -2310,7 +2359,7 @@ declare module "@polkadot/types/lookup" { | "VoidSpend"; } - /** @name PalletRootTestingCall (240) */ + /** @name PalletRootTestingCall (242) */ interface PalletRootTestingCall extends Enum { readonly isFillBlock: boolean; readonly asFillBlock: { @@ -2320,33 +2369,33 @@ declare module "@polkadot/types/lookup" { readonly type: "FillBlock" | "TriggerDefensive"; } - /** @name PalletSudoError (241) */ + /** @name PalletSudoError (243) */ interface PalletSudoError extends Enum { readonly isRequireSudo: boolean; readonly type: "RequireSudo"; } - /** @name PalletUtilityError (242) */ + /** @name PalletUtilityError (244) */ interface PalletUtilityError extends Enum { readonly isTooManyCalls: boolean; readonly type: "TooManyCalls"; } - /** @name PalletProxyProxyDefinition (245) */ + /** @name PalletProxyProxyDefinition (247) */ interface PalletProxyProxyDefinition extends Struct { readonly delegate: AccountId32; readonly proxyType: FlashboxRuntimeProxyType; readonly delay: u32; } - /** @name PalletProxyAnnouncement (249) */ + /** @name PalletProxyAnnouncement (251) */ interface PalletProxyAnnouncement extends Struct { readonly real: AccountId32; readonly callHash: H256; readonly height: u32; } - /** @name PalletProxyError (251) */ + /** @name PalletProxyError (253) */ interface PalletProxyError extends Enum { readonly isTooMany: boolean; readonly isNotFound: boolean; @@ -2367,7 +2416,7 @@ declare module "@polkadot/types/lookup" { | "NoSelfProxy"; } - /** @name PalletMigrationsError (252) */ + /** @name PalletMigrationsError (254) */ interface PalletMigrationsError extends Enum { readonly isPreimageMissing: boolean; readonly isWrongUpperBound: boolean; @@ -2376,14 +2425,14 @@ declare module "@polkadot/types/lookup" { readonly type: "PreimageMissing" | "WrongUpperBound" | "PreimageIsTooBig" | "PreimageAlreadyExists"; } - /** @name PalletMaintenanceModeError (253) */ + /** @name PalletMaintenanceModeError (255) */ interface PalletMaintenanceModeError extends Enum { readonly isAlreadyInMaintenanceMode: boolean; readonly isNotInMaintenanceMode: boolean; readonly type: "AlreadyInMaintenanceMode" | "NotInMaintenanceMode"; } - /** @name PalletTxPauseError (254) */ + /** @name PalletTxPauseError (256) */ interface PalletTxPauseError extends Enum { readonly isIsPaused: boolean; readonly isIsUnpaused: boolean; @@ -2392,14 +2441,14 @@ declare module "@polkadot/types/lookup" { readonly type: "IsPaused" | "IsUnpaused" | "Unpausable" | "NotFound"; } - /** @name PalletBalancesBalanceLock (256) */ + /** @name PalletBalancesBalanceLock (258) */ interface PalletBalancesBalanceLock extends Struct { readonly id: U8aFixed; readonly amount: u128; readonly reasons: PalletBalancesReasons; } - /** @name PalletBalancesReasons (257) */ + /** @name PalletBalancesReasons (259) */ interface PalletBalancesReasons extends Enum { readonly isFee: boolean; readonly isMisc: boolean; @@ -2407,19 +2456,19 @@ declare module "@polkadot/types/lookup" { readonly type: "Fee" | "Misc" | "All"; } - /** @name PalletBalancesReserveData (260) */ + /** @name PalletBalancesReserveData (262) */ interface PalletBalancesReserveData extends Struct { readonly id: U8aFixed; readonly amount: u128; } - /** @name PalletBalancesIdAmountRuntimeHoldReason (263) */ + /** @name PalletBalancesIdAmountRuntimeHoldReason (265) */ interface PalletBalancesIdAmountRuntimeHoldReason extends Struct { readonly id: FlashboxRuntimeRuntimeHoldReason; readonly amount: u128; } - /** @name FlashboxRuntimeRuntimeHoldReason (264) */ + /** @name FlashboxRuntimeRuntimeHoldReason (266) */ interface FlashboxRuntimeRuntimeHoldReason extends Enum { readonly isStreamPayment: boolean; readonly asStreamPayment: PalletStreamPaymentHoldReason; @@ -2428,39 +2477,39 @@ declare module "@polkadot/types/lookup" { readonly type: "StreamPayment" | "DataPreservers"; } - /** @name PalletStreamPaymentHoldReason (265) */ + /** @name PalletStreamPaymentHoldReason (267) */ interface PalletStreamPaymentHoldReason extends Enum { readonly isStreamPayment: boolean; readonly isStreamOpened: boolean; readonly type: "StreamPayment" | "StreamOpened"; } - /** @name PalletDataPreserversHoldReason (266) */ + /** @name PalletDataPreserversHoldReason (268) */ interface PalletDataPreserversHoldReason extends Enum { readonly isProfileDeposit: boolean; readonly type: "ProfileDeposit"; } - /** @name PalletBalancesIdAmountRuntimeFreezeReason (269) */ + /** @name PalletBalancesIdAmountRuntimeFreezeReason (271) */ interface PalletBalancesIdAmountRuntimeFreezeReason extends Struct { readonly id: FlashboxRuntimeRuntimeFreezeReason; readonly amount: u128; } - /** @name FlashboxRuntimeRuntimeFreezeReason (270) */ + /** @name FlashboxRuntimeRuntimeFreezeReason (272) */ interface FlashboxRuntimeRuntimeFreezeReason extends Enum { readonly isStreamPayment: boolean; readonly asStreamPayment: PalletStreamPaymentFreezeReason; readonly type: "StreamPayment"; } - /** @name PalletStreamPaymentFreezeReason (271) */ + /** @name PalletStreamPaymentFreezeReason (273) */ interface PalletStreamPaymentFreezeReason extends Enum { readonly isStreamPayment: boolean; readonly type: "StreamPayment"; } - /** @name PalletBalancesError (273) */ + /** @name PalletBalancesError (275) */ interface PalletBalancesError extends Enum { readonly isVestingBalance: boolean; readonly isLiquidityRestrictions: boolean; @@ -2489,14 +2538,14 @@ declare module "@polkadot/types/lookup" { | "DeltaZero"; } - /** @name PalletTransactionPaymentReleases (274) */ + /** @name PalletTransactionPaymentReleases (276) */ interface PalletTransactionPaymentReleases extends Enum { readonly isV1Ancient: boolean; readonly isV2: boolean; readonly type: "V1Ancient" | "V2"; } - /** @name PalletStreamPaymentStream (275) */ + /** @name PalletStreamPaymentStream (277) */ interface PalletStreamPaymentStream extends Struct { readonly source: AccountId32; readonly target: AccountId32; @@ -2508,7 +2557,7 @@ declare module "@polkadot/types/lookup" { readonly openingDeposit: u128; } - /** @name PalletStreamPaymentChangeRequest (277) */ + /** @name PalletStreamPaymentChangeRequest (279) */ interface PalletStreamPaymentChangeRequest extends Struct { readonly requester: PalletStreamPaymentParty; readonly kind: PalletStreamPaymentChangeKind; @@ -2516,7 +2565,7 @@ declare module "@polkadot/types/lookup" { readonly depositChange: Option; } - /** @name PalletStreamPaymentError (279) */ + /** @name PalletStreamPaymentError (281) */ interface PalletStreamPaymentError extends Enum { readonly isUnknownStreamId: boolean; readonly isStreamIdOverflow: boolean; @@ -2551,27 +2600,27 @@ declare module "@polkadot/types/lookup" { | "ImmediateDepositChangeRequiresSameAssetId"; } - /** @name PalletIdentityRegistration (281) */ + /** @name PalletIdentityRegistration (283) */ interface PalletIdentityRegistration extends Struct { readonly judgements: Vec>; readonly deposit: u128; readonly info: PalletIdentityLegacyIdentityInfo; } - /** @name PalletIdentityRegistrarInfo (290) */ + /** @name PalletIdentityRegistrarInfo (292) */ interface PalletIdentityRegistrarInfo extends Struct { readonly account: AccountId32; readonly fee: u128; readonly fields: u64; } - /** @name PalletIdentityAuthorityProperties (292) */ + /** @name PalletIdentityAuthorityProperties (294) */ interface PalletIdentityAuthorityProperties extends Struct { readonly suffix: Bytes; readonly allocation: u32; } - /** @name PalletIdentityError (295) */ + /** @name PalletIdentityError (297) */ interface PalletIdentityError extends Enum { readonly isTooManySubAccounts: boolean; readonly isNotFound: boolean; @@ -2628,7 +2677,7 @@ declare module "@polkadot/types/lookup" { | "NotExpired"; } - /** @name PalletMultisigMultisig (297) */ + /** @name PalletMultisigMultisig (299) */ interface PalletMultisigMultisig extends Struct { readonly when: PalletMultisigTimepoint; readonly deposit: u128; @@ -2636,7 +2685,7 @@ declare module "@polkadot/types/lookup" { readonly approvals: Vec; } - /** @name PalletMultisigError (299) */ + /** @name PalletMultisigError (301) */ interface PalletMultisigError extends Enum { readonly isMinimumThreshold: boolean; readonly isAlreadyApproved: boolean; @@ -2669,13 +2718,13 @@ declare module "@polkadot/types/lookup" { | "AlreadyStored"; } - /** @name PalletRegistrarDepositInfo (307) */ + /** @name PalletRegistrarDepositInfo (310) */ interface PalletRegistrarDepositInfo extends Struct { readonly creator: AccountId32; readonly deposit: u128; } - /** @name PalletRegistrarError (308) */ + /** @name PalletRegistrarError (311) */ interface PalletRegistrarError extends Enum { readonly isParaIdAlreadyRegistered: boolean; readonly isParaIdNotRegistered: boolean; @@ -2710,7 +2759,7 @@ declare module "@polkadot/types/lookup" { | "ParaStillExistsInRelay"; } - /** @name PalletConfigurationHostConfiguration (309) */ + /** @name PalletConfigurationHostConfiguration (312) */ interface PalletConfigurationHostConfiguration extends Struct { readonly maxCollators: u32; readonly minOrchestratorCollators: u32; @@ -2722,26 +2771,26 @@ declare module "@polkadot/types/lookup" { readonly targetContainerChainFullness: Perbill; } - /** @name PalletConfigurationError (312) */ + /** @name PalletConfigurationError (315) */ interface PalletConfigurationError extends Enum { readonly isInvalidNewValue: boolean; readonly type: "InvalidNewValue"; } - /** @name DpCollatorAssignmentAssignedCollatorsAccountId32 (313) */ + /** @name DpCollatorAssignmentAssignedCollatorsAccountId32 (316) */ interface DpCollatorAssignmentAssignedCollatorsAccountId32 extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name TpTraitsContainerChainBlockInfo (318) */ + /** @name TpTraitsContainerChainBlockInfo (321) */ interface TpTraitsContainerChainBlockInfo extends Struct { readonly blockNumber: u32; readonly author: AccountId32; readonly latestSlotNumber: u64; } - /** @name PalletAuthorNotingError (319) */ + /** @name PalletAuthorNotingError (322) */ interface PalletAuthorNotingError extends Enum { readonly isFailedReading: boolean; readonly isFailedDecodingHeader: boolean; @@ -2760,13 +2809,13 @@ declare module "@polkadot/types/lookup" { | "NonAuraDigest"; } - /** @name DpCollatorAssignmentAssignedCollatorsPublic (320) */ + /** @name DpCollatorAssignmentAssignedCollatorsPublic (323) */ interface DpCollatorAssignmentAssignedCollatorsPublic extends Struct { readonly orchestratorChain: Vec; readonly containerChains: BTreeMap>; } - /** @name PalletServicesPaymentError (325) */ + /** @name PalletServicesPaymentError (328) */ interface PalletServicesPaymentError extends Enum { readonly isInsufficientFundsToPurchaseCredits: boolean; readonly isInsufficientCredits: boolean; @@ -2774,22 +2823,40 @@ declare module "@polkadot/types/lookup" { readonly type: "InsufficientFundsToPurchaseCredits" | "InsufficientCredits" | "CreditPriceTooExpensive"; } - /** @name PalletDataPreserversRegisteredProfile (326) */ + /** @name PalletDataPreserversRegisteredProfile (329) */ interface PalletDataPreserversRegisteredProfile extends Struct { readonly account: AccountId32; readonly deposit: u128; readonly profile: PalletDataPreserversProfile; + readonly assignment: Option>; } - /** @name PalletDataPreserversError (327) */ + /** @name PalletDataPreserversError (335) */ interface PalletDataPreserversError extends Enum { readonly isNoBootNodes: boolean; readonly isUnknownProfileId: boolean; readonly isNextProfileIdShouldBeAvailable: boolean; - readonly type: "NoBootNodes" | "UnknownProfileId" | "NextProfileIdShouldBeAvailable"; - } - - /** @name PalletInvulnerablesError (329) */ + readonly isAssignmentPaymentRequestParameterMismatch: boolean; + readonly isProfileAlreadyAssigned: boolean; + readonly isProfileNotAssigned: boolean; + readonly isProfileIsNotElligibleForParaId: boolean; + readonly isWrongParaId: boolean; + readonly isMaxAssignmentsPerParaIdReached: boolean; + readonly isCantDeleteAssignedProfile: boolean; + readonly type: + | "NoBootNodes" + | "UnknownProfileId" + | "NextProfileIdShouldBeAvailable" + | "AssignmentPaymentRequestParameterMismatch" + | "ProfileAlreadyAssigned" + | "ProfileNotAssigned" + | "ProfileIsNotElligibleForParaId" + | "WrongParaId" + | "MaxAssignmentsPerParaIdReached" + | "CantDeleteAssignedProfile"; + } + + /** @name PalletInvulnerablesError (337) */ interface PalletInvulnerablesError extends Enum { readonly isTooManyInvulnerables: boolean; readonly isAlreadyInvulnerable: boolean; @@ -2804,10 +2871,10 @@ declare module "@polkadot/types/lookup" { | "UnableToDeriveCollatorId"; } - /** @name SpCoreCryptoKeyTypeId (334) */ + /** @name SpCoreCryptoKeyTypeId (342) */ interface SpCoreCryptoKeyTypeId extends U8aFixed {} - /** @name PalletSessionError (335) */ + /** @name PalletSessionError (343) */ interface PalletSessionError extends Enum { readonly isInvalidProof: boolean; readonly isNoAssociatedValidatorId: boolean; @@ -2817,7 +2884,7 @@ declare module "@polkadot/types/lookup" { readonly type: "InvalidProof" | "NoAssociatedValidatorId" | "DuplicatedKey" | "NoKeys" | "NoAccount"; } - /** @name PalletAuthorInherentError (339) */ + /** @name PalletAuthorInherentError (347) */ interface PalletAuthorInherentError extends Enum { readonly isAuthorAlreadySet: boolean; readonly isNoAccountId: boolean; @@ -2825,13 +2892,13 @@ declare module "@polkadot/types/lookup" { readonly type: "AuthorAlreadySet" | "NoAccountId" | "CannotBeAuthor"; } - /** @name PalletInflationRewardsChainsToRewardValue (340) */ + /** @name PalletInflationRewardsChainsToRewardValue (348) */ interface PalletInflationRewardsChainsToRewardValue extends Struct { readonly paraIds: Vec; readonly rewardsPerChain: u128; } - /** @name PalletTreasuryProposal (341) */ + /** @name PalletTreasuryProposal (349) */ interface PalletTreasuryProposal extends Struct { readonly proposer: AccountId32; readonly value: u128; @@ -2839,7 +2906,7 @@ declare module "@polkadot/types/lookup" { readonly bond: u128; } - /** @name PalletTreasurySpendStatus (343) */ + /** @name PalletTreasurySpendStatus (351) */ interface PalletTreasurySpendStatus extends Struct { readonly assetKind: Null; readonly amount: u128; @@ -2849,7 +2916,7 @@ declare module "@polkadot/types/lookup" { readonly status: PalletTreasuryPaymentState; } - /** @name PalletTreasuryPaymentState (344) */ + /** @name PalletTreasuryPaymentState (352) */ interface PalletTreasuryPaymentState extends Enum { readonly isPending: boolean; readonly isAttempted: boolean; @@ -2860,10 +2927,10 @@ declare module "@polkadot/types/lookup" { readonly type: "Pending" | "Attempted" | "Failed"; } - /** @name FrameSupportPalletId (346) */ + /** @name FrameSupportPalletId (354) */ interface FrameSupportPalletId extends U8aFixed {} - /** @name PalletTreasuryError (347) */ + /** @name PalletTreasuryError (355) */ interface PalletTreasuryError extends Enum { readonly isInsufficientProposersBalance: boolean; readonly isInvalidIndex: boolean; @@ -2892,27 +2959,27 @@ declare module "@polkadot/types/lookup" { | "Inconclusive"; } - /** @name FrameSystemExtensionsCheckNonZeroSender (352) */ + /** @name FrameSystemExtensionsCheckNonZeroSender (360) */ type FrameSystemExtensionsCheckNonZeroSender = Null; - /** @name FrameSystemExtensionsCheckSpecVersion (353) */ + /** @name FrameSystemExtensionsCheckSpecVersion (361) */ type FrameSystemExtensionsCheckSpecVersion = Null; - /** @name FrameSystemExtensionsCheckTxVersion (354) */ + /** @name FrameSystemExtensionsCheckTxVersion (362) */ type FrameSystemExtensionsCheckTxVersion = Null; - /** @name FrameSystemExtensionsCheckGenesis (355) */ + /** @name FrameSystemExtensionsCheckGenesis (363) */ type FrameSystemExtensionsCheckGenesis = Null; - /** @name FrameSystemExtensionsCheckNonce (358) */ + /** @name FrameSystemExtensionsCheckNonce (366) */ interface FrameSystemExtensionsCheckNonce extends Compact {} - /** @name FrameSystemExtensionsCheckWeight (359) */ + /** @name FrameSystemExtensionsCheckWeight (367) */ type FrameSystemExtensionsCheckWeight = Null; - /** @name PalletTransactionPaymentChargeTransactionPayment (360) */ + /** @name PalletTransactionPaymentChargeTransactionPayment (368) */ interface PalletTransactionPaymentChargeTransactionPayment extends Compact {} - /** @name FlashboxRuntimeRuntime (361) */ + /** @name FlashboxRuntimeRuntime (369) */ type FlashboxRuntimeRuntime = Null; } // declare module