From a8336a40e4fe65e8d6f907002f7ef69e1885e9d4 Mon Sep 17 00:00:00 2001
From: nanocryk <6422796+nanocryk@users.noreply.github.com>
Date: Thu, 23 May 2024 18:41:16 +0200
Subject: [PATCH] Data Preservers Profiles (#551)
* profiles storage and extrinsics
* wip tests
* forced mode + tests
* separate extrinsics for forced
* benchmarks
* real benchmarks
* typescript api
* fix bench test
* fmt
* typescript apis
* wip ts tests
* T::ProfileId + support for blacklists
* fix bench
---
.../nodes/frontier/src/rpc/finality.rs | 14 +-
.../nodes/frontier/src/rpc/mod.rs | 2 +-
.../frontier/src/xcm_config.rs | 12 +-
.../simple/src/xcm_config.rs | 10 +-
pallets/data-preservers/src/benchmarks.rs | 233 ++++++-
pallets/data-preservers/src/lib.rs | 405 +++++++++++-
pallets/data-preservers/src/mock.rs | 52 +-
pallets/data-preservers/src/tests.rs | 604 +++++++++++++++++-
pallets/data-preservers/src/weights.rs | 237 ++++++-
pallets/xcm-core-buyer/src/benchmarks.rs | 14 +-
pallets/xcm-core-buyer/src/lib.rs | 9 +-
pallets/xcm-core-buyer/src/mock.rs | 9 +-
pallets/xcm-core-buyer/src/tests.rs | 3 +-
runtime/common/src/benchmarking.rs | 6 +-
runtime/dancebox/src/lib.rs | 19 +-
.../src/weights/pallet_data_preservers.rs | 124 +++-
runtime/dancebox/src/xcm_config.rs | 11 +-
.../dancebox/tests/common/xcm/core_buyer.rs | 24 +-
.../tests/common/xcm/delivery_fees.rs | 21 +-
.../xcm/foreign_signed_based_sovereign.rs | 17 +-
.../tests/common/xcm/foreign_sovereigns.rs | 17 +-
.../xcm/reserver_transfers_polkadot_xcm.rs | 18 +-
...derivative_reception_container_dancebox.rs | 15 +-
...e_reception_dancebox_frontier_container.rs | 14 +-
...ive_reception_dancebox_simple_container.rs | 15 +-
...ken_derivative_reception_relay_dancebox.rs | 14 +-
...tive_reception_relay_frontier_container.rs | 15 +-
...vative_reception_relay_simple_container.rs | 14 +-
runtime/dancebox/tests/common/xcm/transact.rs | 12 +-
runtime/dancebox/tests/common/xcm/trap.rs | 8 +-
runtime/flashbox/src/lib.rs | 20 +-
.../src/weights/pallet_data_preservers.rs | 118 +++-
.../test_pallet_data_preservers.ts | 242 +++++++
.../dancebox/interfaces/augment-api-consts.ts | 1 +
.../dancebox/interfaces/augment-api-errors.ts | 2 +
.../dancebox/interfaces/augment-api-events.ts | 15 +
.../dancebox/interfaces/augment-api-query.ts | 8 +
.../src/dancebox/interfaces/augment-api-tx.ts | 58 ++
.../src/dancebox/interfaces/lookup.ts | 314 +++++----
.../src/dancebox/interfaces/registry.ts | 10 +
.../src/dancebox/interfaces/types-lookup.ts | 345 ++++++----
.../flashbox/interfaces/augment-api-consts.ts | 1 +
.../flashbox/interfaces/augment-api-errors.ts | 2 +
.../flashbox/interfaces/augment-api-events.ts | 15 +
.../flashbox/interfaces/augment-api-query.ts | 8 +
.../src/flashbox/interfaces/augment-api-tx.ts | 58 ++
.../src/flashbox/interfaces/lookup.ts | 215 +++++--
.../src/flashbox/interfaces/registry.ts | 10 +
.../src/flashbox/interfaces/types-lookup.ts | 233 +++++--
49 files changed, 3071 insertions(+), 572 deletions(-)
create mode 100644 test/suites/common-tanssi/pallet-data-preservers/test_pallet_data_preservers.ts
diff --git a/container-chains/nodes/frontier/src/rpc/finality.rs b/container-chains/nodes/frontier/src/rpc/finality.rs
index 65a2717af..ad7980a2c 100644
--- a/container-chains/nodes/frontier/src/rpc/finality.rs
+++ b/container-chains/nodes/frontier/src/rpc/finality.rs
@@ -14,12 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see .
-use fc_rpc::frontier_backend_client::{self, is_canon};
-use jsonrpsee::{core::RpcResult, proc_macros::rpc};
-use sp_blockchain::HeaderBackend;
-use sp_core::H256;
-use sp_runtime::traits::Block;
-use std::{marker::PhantomData, sync::Arc};
+use {
+ fc_rpc::frontier_backend_client::{self, is_canon},
+ jsonrpsee::{core::RpcResult, proc_macros::rpc},
+ sp_blockchain::HeaderBackend,
+ sp_core::H256,
+ sp_runtime::traits::Block,
+ std::{marker::PhantomData, sync::Arc},
+};
#[rpc(server)]
#[async_trait::async_trait]
diff --git a/container-chains/nodes/frontier/src/rpc/mod.rs b/container-chains/nodes/frontier/src/rpc/mod.rs
index add27065c..1ca53d197 100644
--- a/container-chains/nodes/frontier/src/rpc/mod.rs
+++ b/container-chains/nodes/frontier/src/rpc/mod.rs
@@ -133,12 +133,12 @@ where
C::Api: RuntimeApiCollection,
P: TransactionPool + 'static,
{
- use finality::{FrontierFinality, FrontierFinalityApiServer};
use {
fc_rpc::{
Eth, EthApiServer, EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer, Net,
NetApiServer, Web3, Web3ApiServer,
},
+ finality::{FrontierFinality, FrontierFinalityApiServer},
substrate_frame_rpc_system::{System, SystemApiServer},
};
diff --git a/container-chains/runtime-templates/frontier/src/xcm_config.rs b/container-chains/runtime-templates/frontier/src/xcm_config.rs
index 41639fb94..1b5a3087e 100644
--- a/container-chains/runtime-templates/frontier/src/xcm_config.rs
+++ b/container-chains/runtime-templates/frontier/src/xcm_config.rs
@@ -16,11 +16,13 @@
use {
super::{
- currency::MICROUNIT, precompiles::FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, weights,
- weights::xcm::XcmWeight as XcmGenericWeights, AccountId, AllPalletsWithSystem, AssetRate,
- Balance, Balances, ForeignAssetsCreator, MaintenanceMode, MessageQueue, ParachainInfo,
- ParachainSystem, PolkadotXcm, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent,
- RuntimeOrigin, TransactionByteFee, WeightToFee, XcmpQueue,
+ currency::MICROUNIT,
+ precompiles::FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX,
+ weights::{self, xcm::XcmWeight as XcmGenericWeights},
+ AccountId, AllPalletsWithSystem, AssetRate, Balance, Balances, ForeignAssetsCreator,
+ MaintenanceMode, MessageQueue, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime,
+ RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee,
+ WeightToFee, XcmpQueue,
},
ccp_xcm::SignedToAccountKey20,
cumulus_primitives_core::{AggregateMessageOrigin, ParaId},
diff --git a/container-chains/runtime-templates/simple/src/xcm_config.rs b/container-chains/runtime-templates/simple/src/xcm_config.rs
index 909801e4a..54558d34e 100644
--- a/container-chains/runtime-templates/simple/src/xcm_config.rs
+++ b/container-chains/runtime-templates/simple/src/xcm_config.rs
@@ -16,10 +16,12 @@
use {
super::{
- currency::MICROUNIT, weights, weights::xcm::XcmWeight as XcmGenericWeights, AccountId,
- AllPalletsWithSystem, AssetRate, Balance, Balances, ForeignAssetsCreator, MaintenanceMode,
- MessageQueue, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeBlockWeights,
- RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, XcmpQueue,
+ currency::MICROUNIT,
+ weights::{self, xcm::XcmWeight as XcmGenericWeights},
+ AccountId, AllPalletsWithSystem, AssetRate, Balance, Balances, ForeignAssetsCreator,
+ MaintenanceMode, MessageQueue, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime,
+ RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee,
+ WeightToFee, XcmpQueue,
},
cumulus_primitives_core::{AggregateMessageOrigin, ParaId},
frame_support::{
diff --git a/pallets/data-preservers/src/benchmarks.rs b/pallets/data-preservers/src/benchmarks.rs
index 6a07dd3b1..867013c26 100644
--- a/pallets/data-preservers/src/benchmarks.rs
+++ b/pallets/data-preservers/src/benchmarks.rs
@@ -18,18 +18,39 @@
//! Benchmarking
use {
- crate::{Call, Config, Pallet},
+ crate::{
+ Call, Config, Pallet, ParaIdsFilter, Profile, ProfileDeposit, ProfileMode, Profiles,
+ RegisteredProfile,
+ },
frame_benchmarking::v2::*,
frame_support::{
- traits::{EnsureOriginWithArg, OriginTrait},
+ traits::{
+ fungible::{Inspect, Mutate},
+ EnsureOrigin, EnsureOriginWithArg, OriginTrait,
+ },
BoundedVec,
},
frame_system::RawOrigin,
+ sp_runtime::traits::Zero,
sp_std::vec,
tp_traits::ParaId,
};
-#[benchmarks]
+const SEED: u32 = 0;
+
+fn create_funded_user(string: &'static str, n: u32, balance_factor: u32) -> T::AccountId
+where
+ T::Currency: Mutate,
+{
+ let user = account(string, n, SEED);
+ let balance = ::minimum_balance() * balance_factor.into();
+ let _ = ::set_balance(&user, balance);
+ user
+}
+
+#[benchmarks(
+ where T::Currency: Mutate, T::ProfileId: Zero
+)]
mod benchmarks {
use super::*;
@@ -55,5 +76,209 @@ mod benchmarks {
assert_eq!(Pallet::::boot_nodes(para_id), boot_nodes);
}
- impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);
+ #[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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ let deposit = T::ProfileDeposit::profile_deposit(&profile).expect("deposit to be computed");
+
+ let caller = create_funded_user::("caller", 1, 1_000_000_000u32);
+
+ #[extrinsic_call]
+ Pallet::::create_profile(RawOrigin::Signed(caller.clone()), profile.clone());
+
+ assert_eq!(
+ Profiles::::get(T::ProfileId::zero()),
+ Some(RegisteredProfile {
+ account: caller,
+ deposit,
+ profile
+ })
+ );
+ }
+
+ #[benchmark]
+ 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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ let owner = create_funded_user::("owner", 1, 1_000_000_000u32);
+ let origin_force = T::ForceSetProfileOrigin::try_successful_origin()
+ .expect("failed to create ForceSetProfileOrigin");
+
+ #[extrinsic_call]
+ Pallet::::force_create_profile(
+ origin_force as T::RuntimeOrigin,
+ profile.clone(),
+ owner.clone(),
+ );
+
+ assert_eq!(
+ Profiles::::get(T::ProfileId::zero()),
+ Some(RegisteredProfile {
+ account: owner,
+ deposit: 0u32.into(),
+ profile
+ })
+ );
+ }
+
+ #[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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ let caller = create_funded_user::("caller", 1, 1_000_000_000u32);
+
+ Pallet::::create_profile(RawOrigin::Signed(caller.clone()).into(), profile)
+ .expect("to create profile");
+
+ // 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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ let deposit = T::ProfileDeposit::profile_deposit(&profile).expect("deposit to be computed");
+
+ #[extrinsic_call]
+ Pallet::::update_profile(
+ RawOrigin::Signed(caller.clone()),
+ T::ProfileId::zero(),
+ profile.clone(),
+ );
+
+ assert_eq!(
+ Profiles::::get(T::ProfileId::zero()),
+ Some(RegisteredProfile {
+ account: caller,
+ deposit,
+ profile
+ })
+ );
+ }
+
+ #[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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ let caller = create_funded_user::("caller", 1, 1_000_000_000u32);
+
+ Pallet::::create_profile(RawOrigin::Signed(caller.clone()).into(), profile)
+ .expect("to create profile");
+
+ // 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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ let origin_force = T::ForceSetProfileOrigin::try_successful_origin()
+ .expect("failed to create ForceSetProfileOrigin");
+
+ #[extrinsic_call]
+ Pallet::::force_update_profile(
+ origin_force as T::RuntimeOrigin,
+ T::ProfileId::zero(),
+ profile.clone(),
+ );
+
+ assert_eq!(
+ Profiles::::get(T::ProfileId::zero()),
+ Some(RegisteredProfile {
+ account: caller,
+ deposit: 0u32.into(),
+ profile
+ })
+ );
+ }
+
+ #[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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ 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::::delete_profile(RawOrigin::Signed(caller.clone()), T::ProfileId::zero());
+
+ assert_eq!(Profiles::::get(T::ProfileId::zero()), None);
+ }
+
+ #[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 profile = Profile {
+ url,
+ para_ids: ParaIdsFilter::Whitelist(para_ids),
+ mode: ProfileMode::Bootnode,
+ };
+
+ 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_force = T::ForceSetProfileOrigin::try_successful_origin()
+ .expect("failed to create ForceSetProfileOrigin");
+
+ #[extrinsic_call]
+ Pallet::::force_delete_profile(origin_force as T::RuntimeOrigin, T::ProfileId::zero());
+
+ assert_eq!(Profiles::::get(T::ProfileId::zero()), None);
+ }
+
+ impl_benchmark_test_suite!(
+ Pallet,
+ crate::mock::ExtBuilder::default().build(),
+ crate::mock::Test
+ );
}
diff --git a/pallets/data-preservers/src/lib.rs b/pallets/data-preservers/src/lib.rs
index 5626c3944..8b9f9608c 100644
--- a/pallets/data-preservers/src/lib.rs
+++ b/pallets/data-preservers/src/lib.rs
@@ -33,18 +33,28 @@ mod benchmarks;
pub mod weights;
pub use weights::WeightInfo;
+#[cfg(feature = "std")]
+use serde::{Deserialize, Serialize};
+
use {
+ core::fmt::Debug,
dp_core::ParaId,
frame_support::{
+ dispatch::DispatchErrorWithPostInfo,
pallet_prelude::*,
traits::{
- fungible::{Balanced, Inspect},
+ fungible::{Balanced, Inspect, MutateHold},
+ tokens::Precision,
EnsureOriginWithArg,
},
DefaultNoBound,
},
frame_system::pallet_prelude::*,
- sp_runtime::traits::Get,
+ parity_scale_codec::FullCodec,
+ sp_runtime::{
+ traits::{CheckedAdd, CheckedMul, CheckedSub, Get, One, Zero},
+ ArithmeticError,
+ },
sp_std::vec::Vec,
};
@@ -95,14 +105,37 @@ pub mod pallet {
pub trait Config: frame_system::Config {
/// Overarching event type.
type RuntimeEvent: From> + IsType<::RuntimeEvent>;
- type Currency: Inspect + Balanced;
+
+ type RuntimeHoldReason: From;
+
+ type Currency: Inspect
+ + Balanced
+ + MutateHold;
+
+ type ProfileId: Default
+ + FullCodec
+ + TypeInfo
+ + Copy
+ + Clone
+ + Debug
+ + Eq
+ + CheckedAdd
+ + One;
+
// Who can call set_boot_nodes?
type SetBootNodesOrigin: EnsureOriginWithArg;
+ type ForceSetProfileOrigin: EnsureOrigin;
+
#[pallet::constant]
type MaxBootNodes: Get;
#[pallet::constant]
type MaxBootNodeUrlLen: Get;
+ #[pallet::constant]
+ type MaxParaIdsVecLen: Get;
+
+ /// How much must be deposited to register a profile.
+ type ProfileDeposit: ProfileDeposit, BalanceOf>;
type WeightInfo: WeightInfo;
}
@@ -112,12 +145,34 @@ pub mod pallet {
pub enum Event {
/// The list of boot_nodes changed.
BootNodesChanged { para_id: ParaId },
+ ProfileCreated {
+ account: T::AccountId,
+ profile_id: T::ProfileId,
+ deposit: BalanceOf,
+ },
+ ProfileUpdated {
+ profile_id: T::ProfileId,
+ old_deposit: BalanceOf,
+ new_deposit: BalanceOf,
+ },
+ ProfileDeleted {
+ profile_id: T::ProfileId,
+ released_deposit: BalanceOf,
+ },
}
#[pallet::error]
pub enum Error {
/// This container chain does not have any boot nodes
NoBootNodes,
+
+ UnknownProfileId,
+ NextProfileIdShouldBeAvailable,
+ }
+
+ #[pallet::composite_enum]
+ pub enum HoldReason {
+ ProfileDeposit,
}
#[pallet::storage]
@@ -130,6 +185,104 @@ pub mod pallet {
ValueQuery,
>;
+ #[pallet::storage]
+ pub type Profiles =
+ StorageMap<_, Blake2_128Concat, T::ProfileId, RegisteredProfile, OptionQuery>;
+
+ #[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::call]
impl Pallet {
/// Set boot_nodes for this para id
@@ -151,6 +304,252 @@ pub mod pallet {
Ok(())
}
+
+ #[pallet::call_index(1)]
+ #[pallet::weight(T::WeightInfo::create_profile(
+ profile.url.len() as u32,
+ profile.para_ids.len() as u32,
+ ))]
+ pub fn create_profile(
+ origin: OriginFor,
+ profile: Profile,
+ ) -> DispatchResultWithPostInfo {
+ let account = ensure_signed(origin)?;
+
+ let deposit = T::ProfileDeposit::profile_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())
+ }
+
+ #[pallet::call_index(2)]
+ #[pallet::weight(T::WeightInfo::update_profile(
+ profile.url.len() as u32,
+ profile.para_ids.len() as u32,
+ ))]
+ pub fn update_profile(
+ origin: OriginFor,
+ profile_id: T::ProfileId,
+ profile: Profile,
+ ) -> DispatchResultWithPostInfo {
+ let account = ensure_signed(origin)?;
+
+ let Some(existing_profile) = Profiles::::get(profile_id) else {
+ Err(Error::::UnknownProfileId)?
+ };
+
+ ensure!(
+ existing_profile.account == account,
+ sp_runtime::DispatchError::BadOrigin,
+ );
+
+ // Update deposit
+ let new_deposit = T::ProfileDeposit::profile_deposit(&profile)?;
+
+ 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,
+ )?;
+ }
+
+ Profiles::::insert(
+ profile_id,
+ RegisteredProfile {
+ account: existing_profile.account,
+ deposit: new_deposit,
+ profile,
+ },
+ );
+
+ Self::deposit_event(Event::ProfileUpdated {
+ profile_id,
+ old_deposit: existing_profile.deposit,
+ new_deposit,
+ });
+
+ Ok(().into())
+ }
+
+ #[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)?;
+
+ let Some(profile) = Profiles::::get(profile_id) else {
+ Err(Error::::UnknownProfileId)?
+ };
+
+ ensure!(
+ profile.account == account,
+ sp_runtime::DispatchError::BadOrigin,
+ );
+
+ T::Currency::release(
+ &HoldReason::ProfileDeposit.into(),
+ &profile.account,
+ profile.deposit,
+ Precision::Exact,
+ )?;
+
+ Profiles::::remove(profile_id);
+
+ Self::deposit_event(Event::ProfileDeleted {
+ profile_id,
+ released_deposit: profile.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)?;
+
+ 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: for_account.clone(),
+ deposit: Zero::zero(),
+ profile,
+ },
+ );
+
+ Self::deposit_event(Event::ProfileCreated {
+ account: for_account,
+ profile_id: id,
+ deposit: Zero::zero(),
+ });
+
+ 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,
+ profile_id: T::ProfileId,
+ profile: Profile,
+ ) -> 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,
+ )?;
+
+ Profiles::::insert(
+ profile_id,
+ RegisteredProfile {
+ account: existing_profile.account,
+ deposit: Zero::zero(),
+ profile,
+ },
+ );
+
+ Self::deposit_event(Event::ProfileUpdated {
+ profile_id,
+ old_deposit: existing_profile.deposit,
+ new_deposit: Zero::zero(),
+ });
+
+ Ok(().into())
+ }
+
+ #[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)?;
+
+ let Some(profile) = Profiles::::get(profile_id) else {
+ Err(Error::::UnknownProfileId)?
+ };
+
+ T::Currency::release(
+ &HoldReason::ProfileDeposit.into(),
+ &profile.account,
+ profile.deposit,
+ Precision::Exact,
+ )?;
+
+ Profiles::::remove(profile_id);
+
+ Self::deposit_event(Event::ProfileDeleted {
+ profile_id,
+ released_deposit: profile.deposit,
+ });
+
+ Ok(().into())
+ }
}
impl Pallet {
diff --git a/pallets/data-preservers/src/mock.rs b/pallets/data-preservers/src/mock.rs
index d4f99cfd7..1e0f66864 100644
--- a/pallets/data-preservers/src/mock.rs
+++ b/pallets/data-preservers/src/mock.rs
@@ -20,7 +20,7 @@ use {
frame_support::{
pallet_prelude::*,
parameter_types,
- traits::{ConstU64, EitherOfDiverse, EnsureOriginWithArg, Everything},
+ traits::{ConstU128, ConstU64, EitherOfDiverse, EnsureOriginWithArg, Everything},
},
frame_system::{EnsureRoot, EnsureSigned, RawOrigin},
sp_core::H256,
@@ -88,7 +88,7 @@ impl pallet_balances::Config for Test {
type AccountStore = System;
type FreezeIdentifier = ();
type MaxFreezes = ();
- type RuntimeHoldReason = ();
+ type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = ();
type MaxHolds = ConstU32<5>;
type WeightInfo = ();
@@ -217,24 +217,56 @@ where
impl pallet_data_preservers::Config for Test {
type RuntimeEvent = RuntimeEvent;
+ type RuntimeHoldReason = RuntimeHoldReason;
type Currency = Balances;
+ type ProfileId = u64;
type SetBootNodesOrigin = MockContainerChainManagerOrRootOrigin>;
+ type ForceSetProfileOrigin = EnsureRoot;
type MaxBootNodes = ConstU32<10>;
type MaxBootNodeUrlLen = ConstU32<200>;
+ type MaxParaIdsVecLen = ConstU32<20>;
+ type ProfileDeposit = crate::BytesProfileDeposit, ConstU128<51>>;
type WeightInfo = ();
}
-// Build genesis storage according to the mock runtime.
-pub fn new_test_ext() -> sp_io::TestExternalities {
- let mut t = frame_system::GenesisConfig::::default()
- .build_storage()
- .unwrap();
+#[derive(Default)]
+pub struct ExtBuilder {
+ balances: Vec<(AccountId, Balance)>,
+}
- let balances = vec![(0, 10_000)];
+impl ExtBuilder {
+ pub fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
+ self.balances = balances;
+ self
+ }
+
+ pub fn build(self) -> sp_io::TestExternalities {
+ let mut t = frame_system::GenesisConfig::::default()
+ .build_storage()
+ .unwrap();
- pallet_balances::GenesisConfig:: { balances }
+ pallet_balances::GenesisConfig:: {
+ balances: self.balances,
+ }
.assimilate_storage(&mut t)
.unwrap();
- t.into()
+ let mut ext: sp_io::TestExternalities = t.into();
+ ext.execute_with(|| System::set_block_number(1));
+ ext
+ }
+}
+
+pub(crate) fn events() -> Vec> {
+ System::events()
+ .into_iter()
+ .map(|r| r.event)
+ .filter_map(|e| {
+ if let RuntimeEvent::DataPreservers(inner) = e {
+ Some(inner)
+ } else {
+ None
+ }
+ })
+ .collect::>()
}
diff --git a/pallets/data-preservers/src/tests.rs b/pallets/data-preservers/src/tests.rs
index bc738b2f3..42fe407f3 100644
--- a/pallets/data-preservers/src/tests.rs
+++ b/pallets/data-preservers/src/tests.rs
@@ -17,6 +17,7 @@
use {
crate::{mock::*, *},
frame_support::{assert_noop, assert_ok, pallet_prelude::*},
+ sp_runtime::TokenError,
};
const ALICE: u64 = 1;
@@ -24,7 +25,7 @@ const BOB: u64 = 2;
#[test]
fn set_boot_nodes_bad_origin() {
- new_test_ext().execute_with(|| {
+ ExtBuilder::default().build().execute_with(|| {
// Para 1001 has no manager, Alice cannot set boot nodes
assert_noop!(DataPreservers::set_boot_nodes(
RuntimeOrigin::signed(ALICE),
@@ -40,7 +41,7 @@ fn set_boot_nodes_bad_origin() {
#[test]
fn set_boot_nodes_by_root_no_manager() {
- new_test_ext().execute_with(|| {
+ 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"
@@ -61,7 +62,7 @@ fn set_boot_nodes_by_root_no_manager() {
#[test]
fn set_boot_nodes_by_root_with_manager() {
- new_test_ext().execute_with(|| {
+ ExtBuilder::default().build().execute_with(|| {
// Set ALICE as manager of para 1002
MockData::mutate(|m| {
m.container_chain_managers.insert(1002.into(), Some(ALICE));
@@ -86,7 +87,7 @@ fn set_boot_nodes_by_root_with_manager() {
#[test]
fn set_boot_nodes_by_para_id_registrar() {
- new_test_ext().execute_with(|| {
+ ExtBuilder::default().build().execute_with(|| {
// Set ALICE as manager of para 1002
MockData::mutate(|m| {
m.container_chain_managers.insert(1002.into(), Some(ALICE));
@@ -111,7 +112,7 @@ fn set_boot_nodes_by_para_id_registrar() {
#[test]
fn set_boot_nodes_by_invalid_user_no_manager() {
- new_test_ext().execute_with(|| {
+ ExtBuilder::default().build().execute_with(|| {
// Para 1001 has no manager
MockData::mutate(|m| {
m.container_chain_managers.insert(1002.into(), Some(ALICE));
@@ -131,7 +132,7 @@ fn set_boot_nodes_by_invalid_user_no_manager() {
#[test]
fn set_boot_nodes_by_invalid_user() {
- new_test_ext().execute_with(|| {
+ ExtBuilder::default().build().execute_with(|| {
// Set ALICE as manager of para 1002
MockData::mutate(|m| {
m.container_chain_managers.insert(1002.into(), Some(ALICE));
@@ -161,7 +162,7 @@ fn set_boot_nodes_by_invalid_user() {
#[test]
fn set_boot_nodes_by_invalid_user_bad_para_id() {
- new_test_ext().execute_with(|| {
+ ExtBuilder::default().build().execute_with(|| {
// Para 1003 does not exist, only root can set bootnodes
assert_noop!(DataPreservers::set_boot_nodes(
RuntimeOrigin::signed(BOB),
@@ -179,7 +180,7 @@ fn set_boot_nodes_by_invalid_user_bad_para_id() {
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
- new_test_ext().execute_with(|| {
+ ExtBuilder::default().build().execute_with(|| {
let boot_nodes: BoundedVec, _> = vec![
b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9"
.to_vec()
@@ -196,3 +197,590 @@ fn set_boot_nodes_bad_para_id() {
assert_eq!(DataPreservers::boot_nodes(ParaId::from(1003)), boot_nodes);
});
}
+
+mod create_profile {
+ use super::*;
+
+ #[test]
+ fn create_profile_works() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ assert_eq!(
+ Profiles::::get(0),
+ Some(RegisteredProfile {
+ account: ALICE,
+ deposit: 1_357, // 1_000 base deposit + 51 * 7 bytes deposit
+ profile
+ })
+ );
+
+ assert_eq!(NextProfileId::::get(), 1);
+
+ assert_eq!(
+ events(),
+ vec![Event::ProfileCreated {
+ account: ALICE,
+ profile_id: 0,
+ deposit: 1_357,
+ }]
+ );
+ });
+ }
+
+ #[test]
+ fn insufficient_balance_for_deposit() {
+ ExtBuilder::default()
+ .with_balances(vec![(ALICE, 1_356)])
+ .build()
+ .execute_with(|| {
+ let profile = Profile {
+ url: b"test".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::AnyParaId,
+ mode: ProfileMode::Bootnode,
+ };
+
+ assert_noop!(
+ DataPreservers::create_profile(RuntimeOrigin::signed(ALICE), profile.clone(),),
+ TokenError::FundsUnavailable
+ );
+
+ assert_eq!(Profiles::::get(0), None);
+ assert_eq!(NextProfileId::::get(), 0);
+ assert_eq!(events(), vec![],);
+ });
+ }
+
+ #[test]
+ fn protection_for_existing_profile() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ // Set some profile at next id. (this shouldn't occur but we protect from it
+ // anyway)
+ Profiles::::insert(
+ 0,
+ RegisteredProfile {
+ account: ALICE,
+ deposit: 0,
+ profile: profile.clone(),
+ },
+ );
+
+ assert_noop!(
+ DataPreservers::create_profile(RuntimeOrigin::signed(ALICE), profile.clone(),),
+ Error::::NextProfileIdShouldBeAvailable
+ );
+ });
+ }
+
+ #[test]
+ fn forced_create_profile_works() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::force_create_profile(
+ RuntimeOrigin::root(),
+ profile.clone(),
+ ALICE,
+ ));
+
+ assert_eq!(
+ Profiles::::get(0),
+ Some(RegisteredProfile {
+ account: ALICE,
+ deposit: 0, // no deposit when forced
+ profile
+ })
+ );
+
+ assert_eq!(NextProfileId::::get(), 1);
+
+ assert_eq!(
+ events(),
+ vec![Event::ProfileCreated {
+ account: ALICE,
+ profile_id: 0,
+ deposit: 0, // no deposit when forced
+ }]
+ );
+ });
+ }
+
+ #[test]
+ fn forced_create_profile_filter() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_noop!(
+ DataPreservers::force_create_profile(
+ RuntimeOrigin::signed(BOB),
+ profile.clone(),
+ ALICE,
+ ),
+ sp_runtime::DispatchError::BadOrigin
+ );
+ });
+ }
+}
+
+mod update_profile {
+ use super::*;
+
+ #[test]
+ fn update_profile_works() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ let profile2 = Profile {
+ url: b"test2".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()),
+ mode: ProfileMode::Rpc {
+ supports_ethereum_rpcs: false,
+ },
+ };
+
+ assert_ok!(DataPreservers::update_profile(
+ RuntimeOrigin::signed(ALICE),
+ 0,
+ profile2.clone(),
+ ));
+
+ assert_eq!(
+ Profiles::::get(0),
+ Some(RegisteredProfile {
+ account: ALICE,
+ deposit: 1_714, // 1_000 base deposit + 51 * 14 bytes deposit
+ profile: profile2
+ })
+ );
+
+ assert_eq!(
+ events(),
+ vec![
+ Event::ProfileCreated {
+ account: ALICE,
+ profile_id: 0,
+ deposit: 1_357,
+ },
+ Event::ProfileUpdated {
+ profile_id: 0,
+ old_deposit: 1_357,
+ new_deposit: 1_714,
+ }
+ ]
+ );
+ });
+ }
+
+ #[test]
+ fn unknown_profile_id() {
+ ExtBuilder::default()
+ .with_balances(vec![(ALICE, 1_400)])
+ .build()
+ .execute_with(|| {
+ let profile = Profile {
+ url: b"test".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::AnyParaId,
+ mode: ProfileMode::Bootnode,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ let profile2 = Profile {
+ url: b"test2".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()),
+ mode: ProfileMode::Rpc {
+ supports_ethereum_rpcs: false,
+ },
+ };
+
+ assert_noop!(
+ DataPreservers::update_profile(
+ RuntimeOrigin::signed(ALICE),
+ 1, // wrong profile id
+ profile2.clone(),
+ ),
+ Error::::UnknownProfileId
+ );
+ });
+ }
+
+ #[test]
+ fn wrong_user() {
+ ExtBuilder::default()
+ .with_balances(vec![(ALICE, 1_400)])
+ .build()
+ .execute_with(|| {
+ let profile = Profile {
+ url: b"test".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::AnyParaId,
+ mode: ProfileMode::Bootnode,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ let profile2 = Profile {
+ url: b"test2".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()),
+ mode: ProfileMode::Rpc {
+ supports_ethereum_rpcs: false,
+ },
+ };
+
+ assert_noop!(
+ DataPreservers::update_profile(
+ RuntimeOrigin::signed(BOB), // not the profile's owner
+ 0,
+ profile2.clone(),
+ ),
+ sp_runtime::DispatchError::BadOrigin,
+ );
+ });
+ }
+
+ #[test]
+ fn insufficient_balance_for_new_deposit() {
+ ExtBuilder::default()
+ .with_balances(vec![(ALICE, 1_400)])
+ .build()
+ .execute_with(|| {
+ let profile = Profile {
+ url: b"test".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::AnyParaId,
+ mode: ProfileMode::Bootnode,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ let profile2 = Profile {
+ url: b"test2".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()),
+ mode: ProfileMode::Rpc {
+ supports_ethereum_rpcs: false,
+ },
+ };
+
+ assert_noop!(
+ DataPreservers::update_profile(
+ RuntimeOrigin::signed(ALICE),
+ 0,
+ profile2.clone(),
+ ),
+ TokenError::FundsUnavailable
+ );
+ });
+ }
+
+ #[test]
+ fn forced_update_profile_works() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ let profile2 = Profile {
+ url: b"test2".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()),
+ mode: ProfileMode::Rpc {
+ supports_ethereum_rpcs: false,
+ },
+ };
+
+ assert_ok!(DataPreservers::force_update_profile(
+ RuntimeOrigin::root(),
+ 0,
+ profile2.clone(),
+ ));
+
+ assert_eq!(
+ Profiles::::get(0),
+ Some(RegisteredProfile {
+ account: ALICE,
+ deposit: 0, // forced update release deposit
+ profile: profile2
+ })
+ );
+
+ assert_eq!(
+ events(),
+ vec![
+ Event::ProfileCreated {
+ account: ALICE,
+ profile_id: 0,
+ deposit: 1_357,
+ },
+ Event::ProfileUpdated {
+ profile_id: 0,
+ old_deposit: 1_357,
+ new_deposit: 0,
+ }
+ ]
+ );
+ });
+ }
+
+ #[test]
+ fn forced_update_profile_filter() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ let profile2 = Profile {
+ url: b"test2".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::Whitelist(vec![ParaId::from(42)].try_into().unwrap()),
+ mode: ProfileMode::Rpc {
+ supports_ethereum_rpcs: false,
+ },
+ };
+
+ assert_noop!(
+ DataPreservers::force_update_profile(
+ RuntimeOrigin::signed(ALICE),
+ 0,
+ profile2.clone(),
+ ),
+ sp_runtime::DispatchError::BadOrigin,
+ );
+ });
+ }
+}
+
+mod delete_profile {
+ use super::*;
+
+ #[test]
+ fn delete_profile_works() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ assert_ok!(DataPreservers::delete_profile(
+ RuntimeOrigin::signed(ALICE),
+ 0,
+ ));
+
+ assert_eq!(Profiles::::get(0), None);
+
+ assert_eq!(
+ events(),
+ vec![
+ Event::ProfileCreated {
+ account: ALICE,
+ profile_id: 0,
+ deposit: 1_357,
+ },
+ Event::ProfileDeleted {
+ profile_id: 0,
+ released_deposit: 1_357,
+ }
+ ]
+ );
+ });
+ }
+
+ #[test]
+ fn unknown_profile_id() {
+ ExtBuilder::default()
+ .with_balances(vec![(ALICE, 1_400)])
+ .build()
+ .execute_with(|| {
+ let profile = Profile {
+ url: b"test".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::AnyParaId,
+ mode: ProfileMode::Bootnode,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ assert_noop!(
+ DataPreservers::delete_profile(
+ RuntimeOrigin::signed(ALICE),
+ 1, // wrong profile id
+ ),
+ Error::::UnknownProfileId
+ );
+ });
+ }
+
+ #[test]
+ fn wrong_user() {
+ ExtBuilder::default()
+ .with_balances(vec![(ALICE, 1_400)])
+ .build()
+ .execute_with(|| {
+ let profile = Profile {
+ url: b"test".to_vec().try_into().unwrap(),
+ para_ids: ParaIdsFilter::AnyParaId,
+ mode: ProfileMode::Bootnode,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ assert_noop!(
+ DataPreservers::delete_profile(
+ RuntimeOrigin::signed(BOB), // not the profile's owner
+ 0,
+ ),
+ sp_runtime::DispatchError::BadOrigin,
+ );
+ });
+ }
+
+ #[test]
+ fn forced_delete_profile_works() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ assert_ok!(DataPreservers::force_delete_profile(
+ RuntimeOrigin::root(),
+ 0,
+ ));
+
+ assert_eq!(Profiles::::get(0), None);
+
+ assert_eq!(
+ events(),
+ vec![
+ Event::ProfileCreated {
+ account: ALICE,
+ profile_id: 0,
+ deposit: 1_357,
+ },
+ Event::ProfileDeleted {
+ profile_id: 0,
+ released_deposit: 1_357,
+ }
+ ]
+ );
+ });
+ }
+
+ #[test]
+ fn forced_delete_profile_filter() {
+ ExtBuilder::default()
+ .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,
+ };
+
+ assert_ok!(DataPreservers::create_profile(
+ RuntimeOrigin::signed(ALICE),
+ profile.clone(),
+ ));
+
+ assert_noop!(
+ DataPreservers::force_delete_profile(RuntimeOrigin::signed(ALICE), 0),
+ sp_runtime::DispatchError::BadOrigin,
+ );
+ });
+ }
+}
diff --git a/pallets/data-preservers/src/weights.rs b/pallets/data-preservers/src/weights.rs
index b93d57d1a..9e282966b 100644
--- a/pallets/data-preservers/src/weights.rs
+++ b/pallets/data-preservers/src/weights.rs
@@ -18,10 +18,10 @@
//! Autogenerated weights for pallet_data_preservers
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-12-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-05-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `tomasz-XPS-15-9520`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H`
-//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
+//! HOSTNAME: `pop-os`, CPU: `12th Gen Intel(R) Core(TM) i7-1260P`
+//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
// Executed Command:
// ./target/release/tanssi-node
@@ -33,15 +33,16 @@
// pallet_data_preservers
// --extrinsic
// *
+// --chain=dev
// --steps
// 50
// --repeat
// 20
-// --template=./benchmarking/frame-weight-template.hbs
+// --template=./benchmarking/frame-weight-pallet-template.hbs
// --json-file
// raw.json
// --output
-// weights.rs
+// tmp/pallet_data_preservers.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
@@ -53,6 +54,12 @@ 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;
}
/// Weights for pallet_data_preservers using the Substrate node and recommended hardware.
@@ -68,15 +75,113 @@ impl WeightInfo for SubstrateWeight {
// Proof Size summary in bytes:
// Measured: `195`
// Estimated: `3660`
- // Minimum execution time: 10_703_000 picoseconds.
- Weight::from_parts(9_788_229, 3660)
- // Standard Error: 170
- .saturating_add(Weight::from_parts(7_964, 0).saturating_mul(x.into()))
- // Standard Error: 3_552
- .saturating_add(Weight::from_parts(334_296, 0).saturating_mul(y.into()))
+ // 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)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`)
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `182`
+ // Estimated: `3694`
+ // Minimum execution time: 34_210_000 picoseconds.
+ Weight::from_parts(43_239_265, 3694)
+ .saturating_add(T::DbWeight::get().reads(4_u64))
+ .saturating_add(T::DbWeight::get().writes(4_u64))
+ }
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `79`
+ // Estimated: `3544`
+ // Minimum execution time: 9_075_000 picoseconds.
+ Weight::from_parts(11_443_644, 3544)
+ .saturating_add(T::DbWeight::get().reads(2_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: `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)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `319`
+ // Estimated: `3784`
+ // Minimum execution time: 33_842_000 picoseconds.
+ Weight::from_parts(42_067_126, 3784)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `319`
+ // Estimated: `3784`
+ // Minimum execution time: 29_757_000 picoseconds.
+ Weight::from_parts(34_984_806, 3784)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
}
// For backwards compatibility and tests
@@ -91,13 +196,111 @@ impl WeightInfo for () {
// Proof Size summary in bytes:
// Measured: `195`
// Estimated: `3660`
- // Minimum execution time: 10_703_000 picoseconds.
- Weight::from_parts(9_788_229, 3660)
- // Standard Error: 170
- .saturating_add(Weight::from_parts(7_964, 0).saturating_mul(x.into()))
- // Standard Error: 3_552
- .saturating_add(Weight::from_parts(334_296, 0).saturating_mul(y.into()))
+ // 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)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`)
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `182`
+ // Estimated: `3694`
+ // Minimum execution time: 34_210_000 picoseconds.
+ Weight::from_parts(43_239_265, 3694)
+ .saturating_add(RocksDbWeight::get().reads(4_u64))
+ .saturating_add(RocksDbWeight::get().writes(4_u64))
+ }
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `79`
+ // Estimated: `3544`
+ // Minimum execution time: 9_075_000 picoseconds.
+ Weight::from_parts(11_443_644, 3544)
+ .saturating_add(RocksDbWeight::get().reads(2_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: `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)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `319`
+ // Estimated: `3784`
+ // Minimum execution time: 33_842_000 picoseconds.
+ Weight::from_parts(42_067_126, 3784)
+ .saturating_add(RocksDbWeight::get().reads(3_u64))
+ .saturating_add(RocksDbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `319`
+ // Estimated: `3784`
+ // Minimum execution time: 29_757_000 picoseconds.
+ Weight::from_parts(34_984_806, 3784)
+ .saturating_add(RocksDbWeight::get().reads(3_u64))
+ .saturating_add(RocksDbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(RocksDbWeight::get().reads(3_u64))
+ .saturating_add(RocksDbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(RocksDbWeight::get().reads(3_u64))
+ .saturating_add(RocksDbWeight::get().writes(3_u64))
+ }
}
diff --git a/pallets/xcm-core-buyer/src/benchmarks.rs b/pallets/xcm-core-buyer/src/benchmarks.rs
index 70a6d55a0..3e760fe22 100644
--- a/pallets/xcm-core-buyer/src/benchmarks.rs
+++ b/pallets/xcm-core-buyer/src/benchmarks.rs
@@ -35,11 +35,15 @@ pub const PLACE_ORDER_WEIGHT_AT_MOST: Weight = Weight::from_parts(1_000_000_000,
#[benchmarks(where ::RuntimeOrigin: From)]
mod benchmarks {
- use super::*;
- use crate::{InFlightCoreBuyingOrder, PendingBlocks, QueryIdToParaId};
- use frame_system::pallet_prelude::BlockNumberFor;
- use staging_xcm::latest::{MaybeErrorCode, QueryId};
- use staging_xcm::v3::{MultiLocation, Response};
+ use {
+ super::*,
+ crate::{InFlightCoreBuyingOrder, PendingBlocks, QueryIdToParaId},
+ frame_system::pallet_prelude::BlockNumberFor,
+ staging_xcm::{
+ latest::{MaybeErrorCode, QueryId},
+ v3::{MultiLocation, Response},
+ },
+ };
#[benchmark]
fn force_buy_core() {
diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs
index 05acf15c9..1b6f91698 100644
--- a/pallets/xcm-core-buyer/src/lib.rs
+++ b/pallets/xcm-core-buyer/src/lib.rs
@@ -34,7 +34,6 @@ mod benchmarks;
pub mod weights;
pub use weights::WeightInfo;
-use tp_traits::{AuthorNotingHook, BlockNumber};
use {
dp_core::ParaId,
frame_support::{
@@ -46,12 +45,11 @@ use {
parity_scale_codec::EncodeLike,
sp_runtime::traits::{AccountIdConversion, Convert, Get},
sp_std::{vec, vec::Vec},
- staging_xcm::v3::Response,
staging_xcm::{
prelude::*,
- v3::{InteriorMultiLocation, MultiAsset, MultiAssets, Xcm},
+ v3::{InteriorMultiLocation, MultiAsset, MultiAssets, Response, Xcm},
},
- tp_traits::ParathreadParams,
+ tp_traits::{AuthorNotingHook, BlockNumber, ParathreadParams},
};
pub trait XCMNotifier {
@@ -97,8 +95,7 @@ impl AuthorNotingHook for Pallet {
#[frame_support::pallet]
pub mod pallet {
- use super::*;
- use pallet_xcm::ensure_response;
+ use {super::*, pallet_xcm::ensure_response};
#[pallet::pallet]
#[pallet::without_storage_info]
pub struct Pallet(PhantomData);
diff --git a/pallets/xcm-core-buyer/src/mock.rs b/pallets/xcm-core-buyer/src/mock.rs
index 10ea2e020..0eb07a8df 100644
--- a/pallets/xcm-core-buyer/src/mock.rs
+++ b/pallets/xcm-core-buyer/src/mock.rs
@@ -14,9 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see
-use pallet_xcm::Origin;
-use staging_xcm::prelude::{GlobalConsensus, Parachain, X2};
-use staging_xcm::prelude::{InteriorMultiLocation, NetworkId};
use {
crate::{
self as pallet_xcm_core_buyer, GetParathreadCollators, GetPurchaseCoreCall,
@@ -29,6 +26,7 @@ use {
parameter_types,
traits::{ConstU64, Everything},
},
+ pallet_xcm::Origin,
sp_core::H256,
sp_io::TestExternalities,
sp_runtime::{
@@ -36,8 +34,9 @@ use {
BuildStorage,
},
sp_std::collections::btree_map::BTreeMap,
- staging_xcm::latest::{
- MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash,
+ staging_xcm::{
+ latest::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash},
+ prelude::{GlobalConsensus, InteriorMultiLocation, NetworkId, Parachain, X2},
},
tp_traits::{ParathreadParams, SlotFrequency},
};
diff --git a/pallets/xcm-core-buyer/src/tests.rs b/pallets/xcm-core-buyer/src/tests.rs
index 2d51ca3b1..2d32132fc 100644
--- a/pallets/xcm-core-buyer/src/tests.rs
+++ b/pallets/xcm-core-buyer/src/tests.rs
@@ -14,10 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see
-use frame_support::assert_storage_noop;
use {
crate::{mock::*, *},
- frame_support::{assert_noop, assert_ok},
+ frame_support::{assert_noop, assert_ok, assert_storage_noop},
sp_runtime::traits::BadOrigin,
};
diff --git a/runtime/common/src/benchmarking.rs b/runtime/common/src/benchmarking.rs
index 273f66988..f631688fb 100644
--- a/runtime/common/src/benchmarking.rs
+++ b/runtime/common/src/benchmarking.rs
@@ -14,9 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see
-use frame_support::traits::Currency;
-use pallet_treasury::ArgumentsFactory;
-use sp_std::marker::PhantomData;
+use {
+ frame_support::traits::Currency, pallet_treasury::ArgumentsFactory, sp_std::marker::PhantomData,
+};
pub struct TreasurtBenchmarkHelper(PhantomData);
impl ArgumentsFactory<(), T::AccountId> for TreasurtBenchmarkHelper
diff --git a/runtime/dancebox/src/lib.rs b/runtime/dancebox/src/lib.rs
index 64c88ce6c..75eda0b83 100644
--- a/runtime/dancebox/src/lib.rs
+++ b/runtime/dancebox/src/lib.rs
@@ -68,6 +68,7 @@ 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,
@@ -156,9 +157,10 @@ pub mod currency {
pub const KILODANCE: Balance = 1_000_000_000_000_000;
pub const STORAGE_BYTE_FEE: Balance = 100 * MICRODANCE * SUPPLY_FACTOR;
+ pub const STORAGE_ITEM_FEE: Balance = 100 * MILLIDANCE * SUPPLY_FACTOR;
pub const fn deposit(items: u32, bytes: u32) -> Balance {
- items as Balance * 100 * MILLIDANCE * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
+ items as Balance * STORAGE_ITEM_FEE + (bytes as Balance) * STORAGE_BYTE_FEE
}
}
@@ -924,14 +926,27 @@ impl pallet_services_payment::Config for Runtime {
type WeightInfo = weights::pallet_services_payment::SubstrateWeight;
}
+parameter_types! {
+ pub const ProfileDepositBaseFee: Balance = currency::STORAGE_ITEM_FEE;
+ pub const ProfileDepositByteFee: Balance = currency::STORAGE_BYTE_FEE;
+}
+
impl pallet_data_preservers::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
+ type RuntimeHoldReason = RuntimeHoldReason;
type Currency = Balances;
+ type WeightInfo = weights::pallet_data_preservers::SubstrateWeight;
+
+ type ProfileId = u64;
+ type ProfileDeposit = BytesProfileDeposit;
+
type SetBootNodesOrigin =
EitherOfDiverse, EnsureRoot>;
+ type ForceSetProfileOrigin = EnsureRoot;
+
type MaxBootNodes = MaxBootNodes;
type MaxBootNodeUrlLen = MaxBootNodeUrlLen;
- type WeightInfo = weights::pallet_data_preservers::SubstrateWeight;
+ type MaxParaIdsVecLen = MaxLengthParaIds;
}
impl pallet_author_noting::Config for Runtime {
diff --git a/runtime/dancebox/src/weights/pallet_data_preservers.rs b/runtime/dancebox/src/weights/pallet_data_preservers.rs
index a9ebb563f..9c42a0160 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-04-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-05-21, 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
@@ -64,13 +64,123 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe
// Proof Size summary in bytes:
// Measured: `195`
// Estimated: `3660`
- // Minimum execution time: 17_362_000 picoseconds.
- Weight::from_parts(15_414_530, 3660)
- // Standard Error: 144
- .saturating_add(Weight::from_parts(11_706, 0).saturating_mul(x.into()))
- // Standard Error: 3_020
- .saturating_add(Weight::from_parts(455_376, 0).saturating_mul(y.into()))
+ // 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)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`)
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `182`
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(4_u64))
+ .saturating_add(T::DbWeight::get().writes(4_u64))
+ }
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(2_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: `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)
+ /// 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 {
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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 {
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
}
\ No newline at end of file
diff --git a/runtime/dancebox/src/xcm_config.rs b/runtime/dancebox/src/xcm_config.rs
index 65f5d85af..e9e821ddf 100644
--- a/runtime/dancebox/src/xcm_config.rs
+++ b/runtime/dancebox/src/xcm_config.rs
@@ -14,9 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see
-use frame_system::pallet_prelude::BlockNumberFor;
-use pallet_xcm_core_buyer::XCMNotifier;
-use staging_xcm_builder::TrailingSetTopicAsId;
use {
super::{
currency::MICRODANCE, weights::xcm::XcmWeight as XcmGenericWeights, AccountId,
@@ -33,11 +30,11 @@ use {
traits::{Everything, Nothing, PalletInfoAccess, TransformOrigin},
weights::Weight,
},
- frame_system::EnsureRoot,
+ frame_system::{pallet_prelude::BlockNumberFor, EnsureRoot},
pallet_xcm::XcmPassthrough,
pallet_xcm_core_buyer::{
GetParathreadCollators, GetParathreadMaxCorePrice, GetParathreadParams,
- GetPurchaseCoreCall, ParaIdIntoAccountTruncating,
+ GetPurchaseCoreCall, ParaIdIntoAccountTruncating, XCMNotifier,
},
parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling},
parity_scale_codec::{Decode, Encode},
@@ -52,8 +49,8 @@ use {
AllowTopLevelPaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, FungibleAdapter,
FungiblesAdapter, IsConcrete, NoChecking, ParentIsPreset, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
- SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
- WeightInfoBounds, WithComputedOrigin,
+ SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId,
+ UsingComponents, WeightInfoBounds, WithComputedOrigin,
},
staging_xcm_executor::{traits::JustTry, XcmExecutor},
tp_traits::ParathreadParams,
diff --git a/runtime/dancebox/tests/common/xcm/core_buyer.rs b/runtime/dancebox/tests/common/xcm/core_buyer.rs
index 27e30a9df..11be4e1df 100644
--- a/runtime/dancebox/tests/common/xcm/core_buyer.rs
+++ b/runtime/dancebox/tests/common/xcm/core_buyer.rs
@@ -14,18 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with Tanssi. If not, see
-use crate::assert_expected_events;
-use staging_xcm::latest::{MaybeErrorCode, Response};
-use staging_xcm::v3::QueryId;
use {
- crate::common::{
- dummy_boot_nodes, empty_genesis_data, run_to_session, start_block,
- xcm::{
- mocknets::{
- DanceboxRococoPara as Dancebox, DanceboxSender, RococoRelay as Rococo,
- RococoRelayPallet, RococoSender,
+ crate::{
+ assert_expected_events,
+ common::{
+ dummy_boot_nodes, empty_genesis_data, run_to_session, start_block,
+ xcm::{
+ mocknets::{
+ DanceboxRococoPara as Dancebox, DanceboxSender, RococoRelay as Rococo,
+ RococoRelayPallet, RococoSender,
+ },
+ *,
},
- *,
},
},
core::marker::PhantomData,
@@ -35,6 +35,10 @@ use {
pallet_xcm_core_buyer::RelayXcmWeightConfigInner,
polkadot_runtime_parachains::assigner_on_demand as parachains_assigner_on_demand,
sp_runtime::AccountId32,
+ staging_xcm::{
+ latest::{MaybeErrorCode, Response},
+ v3::QueryId,
+ },
staging_xcm_executor::traits::ConvertLocation,
tp_traits::{ParaId, SlotFrequency},
xcm_emulator::{Chain, RelayChain},
diff --git a/runtime/dancebox/tests/common/xcm/delivery_fees.rs b/runtime/dancebox/tests/common/xcm/delivery_fees.rs
index 2272e8791..3250afc01 100644
--- a/runtime/dancebox/tests/common/xcm/delivery_fees.rs
+++ b/runtime/dancebox/tests/common/xcm/delivery_fees.rs
@@ -15,18 +15,19 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender,
- EthereumSender as FrontierTemplateSender, FrontierTemplatePara as FrontierTemplate,
- FrontierTemplateParaPallet, SimpleTemplatePara as SimpleTemplate,
- SimpleTemplateParaPallet, SimpleTemplateSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender,
+ EthereumSender as FrontierTemplateSender, FrontierTemplatePara as FrontierTemplate,
+ FrontierTemplateParaPallet, SimpleTemplatePara as SimpleTemplate,
+ SimpleTemplateParaPallet, SimpleTemplateSender,
+ },
+ *,
},
- *,
},
- frame_support::assert_ok,
- frame_support::traits::EnsureOrigin,
+ frame_support::{assert_ok, traits::EnsureOrigin},
paste::paste,
staging_xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm},
xcm_emulator::Chain,
diff --git a/runtime/dancebox/tests/common/xcm/foreign_signed_based_sovereign.rs b/runtime/dancebox/tests/common/xcm/foreign_signed_based_sovereign.rs
index 93f29aa99..8c3830dba 100644
--- a/runtime/dancebox/tests/common/xcm/foreign_signed_based_sovereign.rs
+++ b/runtime/dancebox/tests/common/xcm/foreign_signed_based_sovereign.rs
@@ -15,14 +15,17 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxEmptyReceiver, DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender,
- EthereumEmptyReceiver, EthereumSender, FrontierTemplatePara as FrontierTemplate,
- FrontierTemplateParaPallet, WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxEmptyReceiver, DanceboxPara as Dancebox, DanceboxParaPallet,
+ DanceboxSender, EthereumEmptyReceiver, EthereumSender,
+ FrontierTemplatePara as FrontierTemplate, FrontierTemplateParaPallet,
+ WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ },
+ *,
},
- *,
},
container_chain_template_frontier_runtime::currency::UNIT as FRONTIER_DEV,
dancebox_runtime::UNIT as DANCE,
diff --git a/runtime/dancebox/tests/common/xcm/foreign_sovereigns.rs b/runtime/dancebox/tests/common/xcm/foreign_sovereigns.rs
index d0000b3b1..108da6a3e 100644
--- a/runtime/dancebox/tests/common/xcm/foreign_sovereigns.rs
+++ b/runtime/dancebox/tests/common/xcm/foreign_sovereigns.rs
@@ -15,14 +15,17 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxPara as Dancebox, DanceboxParaPallet, EthereumEmptyReceiver, EthereumSender,
- FrontierTemplatePara as FrontierTemplate, FrontierTemplateParaPallet,
- WestendEmptyReceiver, WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxPara as Dancebox, DanceboxParaPallet, EthereumEmptyReceiver,
+ EthereumSender, FrontierTemplatePara as FrontierTemplate,
+ FrontierTemplateParaPallet, WestendEmptyReceiver, WestendRelay as Westend,
+ WestendRelayPallet, WestendSender,
+ },
+ *,
},
- *,
},
container_chain_template_frontier_runtime::currency::UNIT as FRONTIER_DEV,
frame_support::{
diff --git a/runtime/dancebox/tests/common/xcm/reserver_transfers_polkadot_xcm.rs b/runtime/dancebox/tests/common/xcm/reserver_transfers_polkadot_xcm.rs
index ffb945a90..e732ae32c 100644
--- a/runtime/dancebox/tests/common/xcm/reserver_transfers_polkadot_xcm.rs
+++ b/runtime/dancebox/tests/common/xcm/reserver_transfers_polkadot_xcm.rs
@@ -15,15 +15,17 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender,
- SimpleTemplateEmptyReceiver, SimpleTemplatePara as SimpleTemplate,
- SimpleTemplateParaPallet, SimpleTemplateSender, WestendRelay as Westend,
- WestendRelayPallet, WestendSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender,
+ SimpleTemplateEmptyReceiver, SimpleTemplatePara as SimpleTemplate,
+ SimpleTemplateParaPallet, SimpleTemplateSender, WestendRelay as Westend,
+ WestendRelayPallet, WestendSender,
+ },
+ *,
},
- *,
},
frame_support::{
assert_noop, assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_container_dancebox.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_container_dancebox.rs
index 5568869d1..6b5f06b77 100644
--- a/runtime/dancebox/tests/common/xcm/token_derivative_reception_container_dancebox.rs
+++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_container_dancebox.rs
@@ -15,13 +15,16 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxReceiver,
- SimpleTemplatePara as SimpleTemplate, SimpleTemplateParaPallet, SimpleTemplateSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxReceiver,
+ SimpleTemplatePara as SimpleTemplate, SimpleTemplateParaPallet,
+ SimpleTemplateSender,
+ },
+ *,
},
- *,
},
frame_support::{
assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_frontier_container.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_frontier_container.rs
index eac81f7ed..88788ba14 100644
--- a/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_frontier_container.rs
+++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_frontier_container.rs
@@ -15,13 +15,15 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender, EthereumReceiver,
- FrontierTemplatePara as FrontierTemplate, FrontierTemplateParaPallet,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender, EthereumReceiver,
+ FrontierTemplatePara as FrontierTemplate, FrontierTemplateParaPallet,
+ },
+ *,
},
- *,
},
frame_support::{
assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_simple_container.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_simple_container.rs
index 8d4dd06b8..5310c3e13 100644
--- a/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_simple_container.rs
+++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_dancebox_simple_container.rs
@@ -15,13 +15,16 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender,
- SimpleTemplatePara as SimpleTemplate, SimpleTemplateParaPallet, SimpleTemplateReceiver,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxSender,
+ SimpleTemplatePara as SimpleTemplate, SimpleTemplateParaPallet,
+ SimpleTemplateReceiver,
+ },
+ *,
},
- *,
},
frame_support::{
assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_dancebox.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_dancebox.rs
index 6e939af81..158db98fd 100644
--- a/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_dancebox.rs
+++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_dancebox.rs
@@ -15,13 +15,15 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxReceiver,
- WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ DanceboxPara as Dancebox, DanceboxParaPallet, DanceboxReceiver,
+ WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ },
+ *,
},
- *,
},
frame_support::{
assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_frontier_container.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_frontier_container.rs
index cf495c263..f287b3553 100644
--- a/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_frontier_container.rs
+++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_frontier_container.rs
@@ -15,13 +15,16 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- EthereumReceiver, FrontierTemplatePara as FrontierTemplate, FrontierTemplateParaPallet,
- WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ EthereumReceiver, FrontierTemplatePara as FrontierTemplate,
+ FrontierTemplateParaPallet, WestendRelay as Westend, WestendRelayPallet,
+ WestendSender,
+ },
+ *,
},
- *,
},
frame_support::{
assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_simple_container.rs b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_simple_container.rs
index 09374a5a3..0503bb9ae 100644
--- a/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_simple_container.rs
+++ b/runtime/dancebox/tests/common/xcm/token_derivative_reception_relay_simple_container.rs
@@ -15,13 +15,15 @@
// along with Tanssi. If not, see
use {
- crate::assert_expected_events,
- crate::common::xcm::{
- mocknets::{
- SimpleTemplatePara as SimpleTemplate, SimpleTemplateParaPallet, SimpleTemplateReceiver,
- WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ crate::{
+ assert_expected_events,
+ common::xcm::{
+ mocknets::{
+ SimpleTemplatePara as SimpleTemplate, SimpleTemplateParaPallet,
+ SimpleTemplateReceiver, WestendRelay as Westend, WestendRelayPallet, WestendSender,
+ },
+ *,
},
- *,
},
frame_support::{
assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/transact.rs b/runtime/dancebox/tests/common/xcm/transact.rs
index 0abeaaf2d..22949a8c6 100644
--- a/runtime/dancebox/tests/common/xcm/transact.rs
+++ b/runtime/dancebox/tests/common/xcm/transact.rs
@@ -17,11 +17,13 @@
use crate::common::xcm::*;
use {
- crate::assert_expected_events,
- crate::common::xcm::mocknets::{
- DanceboxPara as Dancebox, FrontierTemplatePara as FrontierTemplate,
- FrontierTemplateParaPallet, SimpleTemplatePara as SimpleTemplate, SimpleTemplateParaPallet,
- WestendRelay as Westend, WestendRelayPallet,
+ crate::{
+ assert_expected_events,
+ common::xcm::mocknets::{
+ DanceboxPara as Dancebox, FrontierTemplatePara as FrontierTemplate,
+ FrontierTemplateParaPallet, SimpleTemplatePara as SimpleTemplate,
+ SimpleTemplateParaPallet, WestendRelay as Westend, WestendRelayPallet,
+ },
},
frame_support::{
assert_ok,
diff --git a/runtime/dancebox/tests/common/xcm/trap.rs b/runtime/dancebox/tests/common/xcm/trap.rs
index 11da0ae41..49c433bc3 100644
--- a/runtime/dancebox/tests/common/xcm/trap.rs
+++ b/runtime/dancebox/tests/common/xcm/trap.rs
@@ -17,9 +17,11 @@
use crate::common::xcm::*;
use {
- crate::assert_expected_events,
- crate::common::xcm::mocknets::{
- DanceboxPara as Dancebox, WestendRelay as Westend, WestendRelayPallet,
+ crate::{
+ assert_expected_events,
+ common::xcm::mocknets::{
+ DanceboxPara as Dancebox, WestendRelay as Westend, WestendRelayPallet,
+ },
},
frame_support::{
assert_ok,
diff --git a/runtime/flashbox/src/lib.rs b/runtime/flashbox/src/lib.rs
index 5d75deea7..910b57331 100644
--- a/runtime/flashbox/src/lib.rs
+++ b/runtime/flashbox/src/lib.rs
@@ -65,6 +65,7 @@ use {
},
nimbus_primitives::{NimbusId, SlotBeacon},
pallet_balances::NegativeImbalance,
+ pallet_data_preservers::BytesProfileDeposit,
pallet_invulnerables::InvulnerableRewardDistribution,
pallet_registrar::RegistrarHooks,
pallet_registrar_runtime_api::ContainerChainGenesisData,
@@ -150,9 +151,10 @@ pub mod currency {
pub const KILODANCE: Balance = 1_000_000_000_000_000;
pub const STORAGE_BYTE_FEE: Balance = 100 * MICRODANCE * SUPPLY_FACTOR;
+ pub const STORAGE_ITEM_FEE: Balance = 100 * MILLIDANCE * SUPPLY_FACTOR;
pub const fn deposit(items: u32, bytes: u32) -> Balance {
- items as Balance * 100 * MILLIDANCE * SUPPLY_FACTOR + (bytes as Balance) * STORAGE_BYTE_FEE
+ items as Balance * STORAGE_ITEM_FEE + (bytes as Balance) * STORAGE_BYTE_FEE
}
}
@@ -782,14 +784,28 @@ impl pallet_services_payment::Config for Runtime {
EitherOfDiverse, EnsureRoot>;
type WeightInfo = weights::pallet_services_payment::SubstrateWeight;
}
+
+parameter_types! {
+ pub const ProfileDepositBaseFee: Balance = currency::STORAGE_ITEM_FEE;
+ pub const ProfileDepositByteFee: Balance = currency::STORAGE_BYTE_FEE;
+}
+
impl pallet_data_preservers::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
+ type RuntimeHoldReason = RuntimeHoldReason;
type Currency = Balances;
+ type WeightInfo = weights::pallet_data_preservers::SubstrateWeight;
+
+ type ProfileId = u64;
+ type ProfileDeposit = BytesProfileDeposit;
+
type SetBootNodesOrigin =
EitherOfDiverse, EnsureRoot>;
+ type ForceSetProfileOrigin = EnsureRoot;
+
type MaxBootNodes = MaxBootNodes;
type MaxBootNodeUrlLen = MaxBootNodeUrlLen;
- type WeightInfo = weights::pallet_data_preservers::SubstrateWeight;
+ type MaxParaIdsVecLen = MaxLengthParaIds;
}
impl pallet_author_noting::Config for Runtime {
diff --git a/runtime/flashbox/src/weights/pallet_data_preservers.rs b/runtime/flashbox/src/weights/pallet_data_preservers.rs
index c906acb2d..27c1f78a7 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-04-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-05-21, 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
@@ -64,13 +64,119 @@ impl pallet_data_preservers::WeightInfo for SubstrateWe
// Proof Size summary in bytes:
// Measured: `195`
// Estimated: `3660`
- // Minimum execution time: 16_473_000 picoseconds.
- Weight::from_parts(14_542_746, 3660)
+ // Minimum execution time: 16_267_000 picoseconds.
+ Weight::from_parts(14_208_199, 3660)
// Standard Error: 159
- .saturating_add(Weight::from_parts(12_051, 0).saturating_mul(x.into()))
- // Standard Error: 3_325
- .saturating_add(Weight::from_parts(452_868, 0).saturating_mul(y.into()))
+ .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)
+ /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(229), added: 2704, mode: `MaxEncodedLen`)
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // Proof Size summary in bytes:
+ // Measured: `182`
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(4_u64))
+ .saturating_add(T::DbWeight::get().writes(4_u64))
+ }
+ /// Storage: `DataPreservers::NextProfileId` (r:1 w:1)
+ /// Proof: `DataPreservers::NextProfileId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// 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 {
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(2_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: `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)
+ /// 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 {
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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 {
+ // 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()))
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
+ /// Storage: `DataPreservers::Profiles` (r:1 w:1)
+ /// Proof: `DataPreservers::Profiles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+ /// Storage: `System::Account` (r:1 w:1)
+ /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+ /// Storage: `Balances::Holds` (r:1 w:1)
+ /// 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)
+ .saturating_add(T::DbWeight::get().reads(3_u64))
+ .saturating_add(T::DbWeight::get().writes(3_u64))
+ }
}
\ No newline at end of file
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
new file mode 100644
index 000000000..67adcc4b2
--- /dev/null
+++ b/test/suites/common-tanssi/pallet-data-preservers/test_pallet_data_preservers.ts
@@ -0,0 +1,242 @@
+import "@tanssi/api-augment";
+import { describeSuite, expect, beforeAll } from "@moonwall/cli";
+import { ApiPromise } from "@polkadot/api";
+import { KeyringPair } from "@moonwall/util";
+
+describeSuite({
+ id: "CT1001",
+ title: "Data preservers pallet test suite",
+ foundationMethods: "dev",
+
+ testCases: ({ it, context }) => {
+ let polkadotJs: ApiPromise;
+ let sudo_alice: KeyringPair;
+ let general_user_bob: KeyringPair;
+ let profileId = 0;
+
+ beforeAll(async () => {
+ polkadotJs = context.polkadotJs();
+ sudo_alice = context.keyring.alice;
+ general_user_bob = context.keyring.charlie;
+ });
+
+ it({
+ id: "E01",
+ title: "User can create profile",
+ test: async function () {
+ const profile = {
+ url: "exemple",
+ paraIds: { whitelist: [42, 43] },
+ mode: "Bootnode",
+ };
+
+ const tx = polkadotJs.tx.dataPreservers.createProfile(profile);
+ const signedTx = await tx.signAsync(general_user_bob);
+ await context.createBlock([signedTx]);
+
+ 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,
+ profile: {
+ url: "0x6578656d706c65",
+ paraIds: { whitelist: [42, 43] },
+ mode: { bootnode: null },
+ },
+ });
+ },
+ });
+
+ it({
+ id: "E02",
+ title: "User can update profile",
+ test: async function () {
+ const profile = {
+ url: "exemple",
+ paraIds: { whitelist: [42, 43] },
+ mode: "Bootnode",
+ };
+
+ const tx = polkadotJs.tx.dataPreservers.createProfile(profile);
+ const signedTx = await tx.signAsync(general_user_bob);
+ await context.createBlock([signedTx]);
+
+ 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,
+ profile: {
+ url: "0x6578656d706c65",
+ paraIds: { whitelist: [42, 43] },
+ mode: { bootnode: null },
+ },
+ });
+
+ const profile2 = {
+ url: "exemple2",
+ paraIds: { whitelist: [42, 43] },
+ mode: { Rpc: { supportsEthereumRpcs: false } },
+ };
+
+ const tx2 = polkadotJs.tx.dataPreservers.updateProfile(profileId, profile2);
+ const signedTx2 = await tx2.signAsync(general_user_bob);
+ await context.createBlock([signedTx2]);
+
+ 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,
+ profile: {
+ url: "0x6578656d706c6532",
+ paraIds: { whitelist: [42, 43] },
+ mode: { rpc: { supportsEthereumRpcs: false } },
+ },
+ });
+ },
+ });
+
+ it({
+ id: "E03",
+ title: "User can delete profile",
+ test: async function () {
+ const profile = {
+ url: "exemple",
+ paraIds: { whitelist: [42, 43] },
+ mode: "Bootnode",
+ };
+
+ const tx = polkadotJs.tx.dataPreservers.createProfile(profile);
+ const signedTx = await tx.signAsync(general_user_bob);
+ await context.createBlock([signedTx]);
+
+ 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,
+ profile: {
+ url: "0x6578656d706c65",
+ paraIds: { whitelist: [42, 43] },
+ mode: { bootnode: null },
+ },
+ });
+
+ const tx2 = polkadotJs.tx.dataPreservers.deleteProfile(profileId);
+ const signedTx2 = await tx2.signAsync(general_user_bob);
+ await context.createBlock([signedTx2]);
+
+ const storedProfile2 = await polkadotJs.query.dataPreservers.profiles(profileId);
+ expect(storedProfile2.toJSON()).to.be.equal(null);
+ },
+ });
+
+ it({
+ id: "E04",
+ title: "Root can force create profile",
+ test: async function () {
+ const profile = {
+ url: "exemple",
+ paraIds: { whitelist: [42, 43] },
+ mode: "Bootnode",
+ };
+
+ const tx = polkadotJs.tx.dataPreservers.forceCreateProfile(profile, general_user_bob.address);
+ const signedTx = await polkadotJs.tx.sudo.sudo(tx).signAsync(sudo_alice);
+ await context.createBlock([signedTx]);
+
+ const storedProfile = await polkadotJs.query.dataPreservers.profiles(++profileId);
+ expect(storedProfile.toJSON()).to.be.deep.equal({
+ account: general_user_bob.address,
+ deposit: 0,
+ profile: {
+ url: "0x6578656d706c65",
+ paraIds: { whitelist: [42, 43] },
+ mode: { bootnode: null },
+ },
+ });
+ },
+ });
+
+ it({
+ id: "E05",
+ title: "Root can force update profile",
+ test: async function () {
+ const profile = {
+ url: "exemple",
+ paraIds: { whitelist: [42, 43] },
+ mode: "Bootnode",
+ };
+
+ const tx = polkadotJs.tx.dataPreservers.createProfile(profile);
+ const signedTx = await tx.signAsync(general_user_bob);
+ await context.createBlock([signedTx]);
+
+ 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,
+ profile: {
+ url: "0x6578656d706c65",
+ paraIds: { whitelist: [42, 43] },
+ mode: { bootnode: null },
+ },
+ });
+
+ const profile2 = {
+ url: "exemple2",
+ paraIds: { whitelist: [42, 43] },
+ mode: { Rpc: { supportsEthereumRpcs: false } },
+ };
+
+ const tx2 = polkadotJs.tx.dataPreservers.forceUpdateProfile(profileId, profile2);
+ const signedTx2 = await polkadotJs.tx.sudo.sudo(tx2).signAsync(sudo_alice);
+ await context.createBlock([signedTx2]);
+
+ const storedProfile2 = await polkadotJs.query.dataPreservers.profiles(profileId);
+ expect(storedProfile2.toJSON()).to.be.deep.equal({
+ account: general_user_bob.address,
+ deposit: 0,
+ profile: {
+ url: "0x6578656d706c6532",
+ paraIds: { whitelist: [42, 43] },
+ mode: { rpc: { supportsEthereumRpcs: false } },
+ },
+ });
+ },
+ });
+
+ it({
+ id: "E06",
+ title: "Root can force delete profile",
+ test: async function () {
+ const profile = {
+ url: "exemple",
+ paraIds: { whitelist: [42, 43] },
+ mode: "Bootnode",
+ };
+
+ const tx = polkadotJs.tx.dataPreservers.createProfile(profile);
+ const signedTx = await tx.signAsync(general_user_bob);
+ await context.createBlock([signedTx]);
+
+ 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,
+ profile: {
+ url: "0x6578656d706c65",
+ paraIds: { whitelist: [42, 43] },
+ mode: { bootnode: null },
+ },
+ });
+
+ const tx2 = polkadotJs.tx.dataPreservers.forceDeleteProfile(profileId);
+ const signedTx2 = await polkadotJs.tx.sudo.sudo(tx2).signAsync(sudo_alice);
+ await context.createBlock(); // session boundary block cannot contain tx
+ await context.createBlock([signedTx2]);
+
+ const storedProfile2 = await polkadotJs.query.dataPreservers.profiles(profileId);
+ expect(storedProfile2.toJSON()).to.be.equal(null);
+ },
+ });
+ },
+});
diff --git a/typescript-api/src/dancebox/interfaces/augment-api-consts.ts b/typescript-api/src/dancebox/interfaces/augment-api-consts.ts
index 983e22c32..3bf20a79d 100644
--- a/typescript-api/src/dancebox/interfaces/augment-api-consts.ts
+++ b/typescript-api/src/dancebox/interfaces/augment-api-consts.ts
@@ -64,6 +64,7 @@ declare module "@polkadot/api-base/types/consts" {
dataPreservers: {
maxBootNodes: u32 & AugmentedConst;
maxBootNodeUrlLen: 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 45a6f2dd3..f3a393bcc 100644
--- a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts
+++ b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts
@@ -74,8 +74,10 @@ declare module "@polkadot/api-base/types/errors" {
[key: string]: AugmentedError;
};
dataPreservers: {
+ NextProfileIdShouldBeAvailable: AugmentedError;
/** This container chain does not have any boot nodes */
NoBootNodes: AugmentedError;
+ UnknownProfileId: 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 12fcd135c..4c5566650 100644
--- a/typescript-api/src/dancebox/interfaces/augment-api-events.ts
+++ b/typescript-api/src/dancebox/interfaces/augment-api-events.ts
@@ -156,6 +156,21 @@ declare module "@polkadot/api-base/types/events" {
dataPreservers: {
/** The list of boot_nodes changed. */
BootNodesChanged: AugmentedEvent;
+ ProfileCreated: AugmentedEvent<
+ ApiType,
+ [account: AccountId32, profileId: u64, deposit: u128],
+ { account: AccountId32; profileId: u64; deposit: u128 }
+ >;
+ ProfileDeleted: AugmentedEvent<
+ ApiType,
+ [profileId: u64, releasedDeposit: u128],
+ { profileId: u64; releasedDeposit: u128 }
+ >;
+ ProfileUpdated: AugmentedEvent<
+ ApiType,
+ [profileId: u64, oldDeposit: u128, newDeposit: u128],
+ { profileId: u64; oldDeposit: u128; newDeposit: u128 }
+ >;
/** Generic event */
[key: string]: AugmentedEvent;
};
diff --git a/typescript-api/src/dancebox/interfaces/augment-api-query.ts b/typescript-api/src/dancebox/interfaces/augment-api-query.ts
index 064768587..76d9c0909 100644
--- a/typescript-api/src/dancebox/interfaces/augment-api-query.ts
+++ b/typescript-api/src/dancebox/interfaces/augment-api-query.ts
@@ -53,6 +53,7 @@ import type {
PalletBalancesIdAmountRuntimeHoldReason,
PalletBalancesReserveData,
PalletConfigurationHostConfiguration,
+ PalletDataPreserversRegisteredProfile,
PalletIdentityAuthorityProperties,
PalletIdentityRegistrarInfo,
PalletIdentityRegistration,
@@ -294,6 +295,13 @@ declare module "@polkadot/api-base/types/storage" {
dataPreservers: {
bootNodes: AugmentedQuery Observable>, [u32]> &
QueryableStorageEntry;
+ nextProfileId: AugmentedQuery Observable, []> & QueryableStorageEntry;
+ profiles: AugmentedQuery<
+ ApiType,
+ (arg: u64 | AnyNumber | Uint8Array) => Observable