From 2a17edb3e1f4fefe868079765b5f16339e6cae56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 9 Jan 2025 23:31:03 +0100 Subject: [PATCH 01/43] Add remote proxy pallet --- Cargo.lock | 20 ++ Cargo.toml | 2 + pallets/remote-proxy/Cargo.toml | 41 ++++ pallets/remote-proxy/src/lib.rs | 354 ++++++++++++++++++++++++++++++ pallets/remote-proxy/src/tests.rs | 330 ++++++++++++++++++++++++++++ 5 files changed, 747 insertions(+) create mode 100644 pallets/remote-proxy/Cargo.toml create mode 100644 pallets/remote-proxy/src/lib.rs create mode 100644 pallets/remote-proxy/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 5f7ef41203..ab99702b18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8852,6 +8852,26 @@ dependencies = [ "sp-runtime 39.0.5", ] +[[package]] +name = "pallet-remote-proxy" +version = "1.0.0" +dependencies = [ + "cumulus-pallet-parachain-system", + "cumulus-primitives-core", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-proxy", + "pallet-utility", + "parity-scale-codec", + "scale-info", + "sp-core 34.0.0", + "sp-io 38.0.0", + "sp-runtime 39.0.5", + "sp-state-machine 0.43.0", + "sp-trie 37.0.0", +] + [[package]] name = "pallet-salary" version = "23.0.0" diff --git a/Cargo.toml b/Cargo.toml index de88d7c095..58e210aa23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -229,6 +229,7 @@ sp-offchain = { version = "34.0.0", default-features = false } sp-runtime = { version = "39.0.1", default-features = false } sp-session = { version = "36.0.0", default-features = false } sp-staking = { version = "36.0.0", default-features = false } +sp-state-machine = { version = "0.43.0", default-features = false } sp-std = { version = "14.0.0", default-features = false } sp-storage = { version = "21.0.0", default-features = false } sp-tracing = { version = "17.0.1", default-features = false } @@ -284,6 +285,7 @@ members = [ "integration-tests/emulated/tests/people/people-kusama", "integration-tests/emulated/tests/people/people-polkadot", "integration-tests/zombienet", + "pallets/remote-proxies", "relay/common", "relay/kusama", "relay/kusama/constants", diff --git a/pallets/remote-proxy/Cargo.toml b/pallets/remote-proxy/Cargo.toml new file mode 100644 index 0000000000..cb2978fdf9 --- /dev/null +++ b/pallets/remote-proxy/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "pallet-remote-proxy" +version.workspace = true +authors.workspace = true +edition.workspace = true +repository.workspace = true +license.workspace = true + +[dependencies] +codec = { features = ["derive", "max-encoded-len"], workspace = true } +scale-info = { features = ["derive"], workspace = true } + +cumulus-pallet-parachain-system = { workspace = true } +cumulus-primitives-core = { workspace = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +pallet-proxy = { workspace = true } +sp-core = { workspace = true } +sp-trie = { workspace = true } +sp-runtime = { workspace = true } + +[dev-dependencies] +pallet-balances = { workspace = true } +pallet-utility = { workspace = true } +sp-io = { workspace = true } +sp-state-machine = { workspace = true } + +[features] +default = [ "std" ] + +std = [ + "codec/std", + "cumulus-pallet-parachain-system/std", + "cumulus-primitives-core/std", + "frame-support/std", + "frame-system/std", + "pallet-proxy/std", + "sp-core/std", + "sp-trie/std", + "sp-runtime/std", +] diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs new file mode 100644 index 0000000000..18ff5355a2 --- /dev/null +++ b/pallets/remote-proxy/src/lib.rs @@ -0,0 +1,354 @@ +// Copyright (C) Polkadot Fellows. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +extern crate alloc; + +#[cfg(test)] +mod tests; + +use alloc::vec::Vec; +use codec::{Encode, MaxEncodedLen}; +use frame_support::{storage::storage_prefix, Parameter, StorageHasher, Twox64Concat}; +use pallet_proxy::ProxyDefinition; +use scale_info::TypeInfo; +use sp_core::Hasher; +use sp_runtime::traits::Saturating; + +pub use cumulus_primitives_core::PersistedValidationData; +pub use pallet::*; + +/// The remote proxy interface. +pub trait RemoteProxyInterface { + /// The remote account id. + type RemoteAccountId: Parameter + MaxEncodedLen; + /// The remote proxy type. + type RemoteProxyType: Parameter + MaxEncodedLen; + /// The remote block number. + type RemoteBlockNumber: Parameter + Saturating + MaxEncodedLen + Default; + /// The hash type used by the remote chain. + type Hash: Parameter + MaxEncodedLen; + /// The hasher used by the remote chain. + type Hasher: Hasher; + + /// Get the latest block to storage root mapping. + fn block_to_storage_root( + validation_data: &PersistedValidationData, + ) -> Option<(Self::RemoteBlockNumber, ::Out)>; + + /// The storage key where to find the [`ProxyDefinition`] for the given proxy account in the + /// remote chain. + fn proxy_definition_storage_key(proxy: &Self::RemoteAccountId) -> Vec { + let mut key = storage_prefix("Proxy".as_bytes(), "Proxies".as_bytes()).to_vec(); + proxy.using_encoded(|p| { + key.extend(Twox64Concat::hash(p)); + }); + key + } + + /// Convert the local account id to the remote account id. + /// + /// If the conversion is not possible, return `None`. + fn local_to_remote_account_id(local: &AccountId) -> Option; + + /// Convert the remote proxy definition to the local proxy definition. + /// + /// If the conversion is not possible, return `None`. + fn remote_to_local_proxy_defintion( + remote: ProxyDefinition< + Self::RemoteAccountId, + Self::RemoteProxyType, + Self::RemoteBlockNumber, + >, + ) -> Option>; +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use cumulus_pallet_parachain_system::OnSystemEvent; + use cumulus_primitives_core::PersistedValidationData; + use frame_support::{dispatch_context, pallet_prelude::*, traits::IsSubType}; + use frame_system::pallet_prelude::*; + use sp_runtime::traits::{Dispatchable, StaticLookup, Zero}; + + type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; + + type RemoteBlockNumberOf = <>::RemoteProxy as RemoteProxyInterface< + ::AccountId, + ::ProxyType, + BlockNumberFor, + >>::RemoteBlockNumber; + type RemoteAccountIdOf = <>::RemoteProxy as RemoteProxyInterface< + ::AccountId, + ::ProxyType, + BlockNumberFor, + >>::RemoteAccountId; + type RemoteHasherOf = <>::RemoteProxy as RemoteProxyInterface< + ::AccountId, + ::ProxyType, + BlockNumberFor, + >>::Hasher; + type RemoteHashOf = <>::RemoteProxy as RemoteProxyInterface< + ::AccountId, + ::ProxyType, + BlockNumberFor, + >>::Hash; + type RemoteProxyTypeOf = <>::RemoteProxy as RemoteProxyInterface< + ::AccountId, + ::ProxyType, + BlockNumberFor, + >>::RemoteProxyType; + + #[pallet::pallet] + pub struct Pallet(_); + + /// Stores the last [`Config::MaxStorageRootsToKeep`] block to storage root mappings of the + /// target chain. + #[pallet::storage] + pub type BlockToRoot, I: 'static = ()> = + StorageMap<_, Twox64Concat, RemoteBlockNumberOf, RemoteHashOf, OptionQuery>; + + /// Configuration trait. + #[pallet::config] + pub trait Config: frame_system::Config + pallet_proxy::Config { + /// Maximum number of storage roots to keep in storage. + /// + /// The storage roots are used to validate the remote proofs. The more we keep in storage, + /// the older the proof can be. + type MaxStorageRootsToKeep: Get>; + + /// The interface for interacting with the remote proxy. + type RemoteProxy: RemoteProxyInterface< + Self::AccountId, + Self::ProxyType, + BlockNumberFor, + >; + } + + impl OnSystemEvent for Pallet { + fn on_validation_data(validation_data: &PersistedValidationData) { + let Some((block, hash)) = T::RemoteProxy::block_to_storage_root(&validation_data) + else { + return; + }; + + // Update the block to root mappings. + BlockToRoot::::insert(block.clone(), hash); + BlockToRoot::::remove(block.saturating_sub(T::MaxStorageRootsToKeep::get())); + } + + fn on_validation_code_applied() {} + } + + #[pallet::error] + #[derive(PartialEq)] + pub enum Error { + /// The local account id could not converted to the remote account id. + CouldNotConvertLocalToRemoteAccountId, + /// The anchor block of the remote proof is unknown. + UnknownProofAnchorBlock, + /// The proxy definition could not be found in the proof. + InvalidProof, + /// Failed to decode the remote proxy definition from the proof. + ProxyDefinitionDecodingFailed, + /// Announcement, if made at all, was made too recently. + Unannounced, + /// Could not find any matching proxy definition in the proof. + DidNotFindMatchingProxyDefinition, + /// Proxy proof not registered. + ProxyProofNotRegistered, + } + + /// The remote proxy proof to prove the existence of a proxy account. + #[derive(core::fmt::Debug, Clone, Decode, Encode, TypeInfo, PartialEq, Eq)] + pub enum RemoteProxyProof { + /// Assumes the default proxy storage layout. + V1 { proof: Vec>, block: RemoteBlockNumber }, + } + + #[derive(Default)] + struct RemoteProxyContext { + proofs: Vec>, + } + + #[pallet::call] + impl, I: 'static> Pallet { + #[pallet::call_index(0)] + #[pallet::weight({ + let di = call.get_dispatch_info(); + ( // AccountData for inner call origin accountdata. + T::DbWeight::get().reads_writes(1, 1) + .saturating_add(di.weight), + di.class) + })] + pub fn remote_proxy( + origin: OriginFor, + real: AccountIdLookupOf, + force_proxy_type: Option, + call: Box<::RuntimeCall>, + proof: RemoteProxyProof>, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let real = T::Lookup::lookup(real)?; + + Self::do_remote_proxy(who, real, force_proxy_type, call, proof) + } + + #[pallet::call_index(1)] + #[pallet::weight(0)] + pub fn register_remote_proxy_proof( + origin: OriginFor, + proof: RemoteProxyProof>, + ) -> DispatchResult { + ensure_signed(origin)?; + + dispatch_context::with_context::>, _>( + |context| { + context.or_default().proofs.push(proof); + }, + ); + + Ok(()) + } + + #[pallet::call_index(2)] + #[pallet::weight(0)] + pub fn remote_proxy_with_registered_proof( + origin: OriginFor, + real: AccountIdLookupOf, + force_proxy_type: Option, + call: Box<::RuntimeCall>, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let real = T::Lookup::lookup(real)?; + + let proof = dispatch_context::with_context::< + RemoteProxyContext>, + _, + >(|context| context.or_default().proofs.pop()) + .flatten() + .ok_or_else(|| Error::::ProxyProofNotRegistered)?; + + Self::do_remote_proxy(who, real, force_proxy_type, call, proof) + } + } + + impl, I: 'static> Pallet { + fn do_remote_proxy( + who: T::AccountId, + real: T::AccountId, + force_proxy_type: Option, + call: Box<::RuntimeCall>, + proof: RemoteProxyProof>, + ) -> DispatchResult { + let Some(real_remote) = T::RemoteProxy::local_to_remote_account_id(&real) else { + return Err(Error::::CouldNotConvertLocalToRemoteAccountId.into()); + }; + + let def = match proof { + RemoteProxyProof::V1 { proof, block } => { + let Some(storage_root) = BlockToRoot::::get(block) else { + return Err(Error::::UnknownProofAnchorBlock.into()); + }; + + let key = T::RemoteProxy::proxy_definition_storage_key(&real_remote); + + let db = + sp_trie::StorageProof::new(proof).into_memory_db::>(); + let value = sp_trie::read_trie_value::, _>( + &db, + &storage_root, + &key, + None, + None, + ) + .ok() + .flatten() + .ok_or_else(|| Error::::InvalidProof)?; + + let proxy_definitions = alloc::vec::Vec::< + ProxyDefinition< + RemoteAccountIdOf, + RemoteProxyTypeOf, + RemoteBlockNumberOf, + >, + >::decode(&mut &value[..]) + .map_err(|_| Error::::ProxyDefinitionDecodingFailed)?; + + let f = |x: &ProxyDefinition< + T::AccountId, + T::ProxyType, + BlockNumberFor, + >| + -> bool { + x.delegate == who && + force_proxy_type.as_ref().map_or(true, |y| &x.proxy_type == y) + }; + + proxy_definitions + .into_iter() + .filter_map(|pd| T::RemoteProxy::remote_to_local_proxy_defintion(pd)) + .find(f) + .ok_or_else(|| Error::::DidNotFindMatchingProxyDefinition)? + }, + }; + + ensure!(def.delay.is_zero(), Error::::Unannounced); + + Self::do_proxy(def, real, *call); + + Ok(()) + } + + /// TODO: Make upstream public and use that one. + fn do_proxy( + def: ProxyDefinition>, + real: T::AccountId, + call: ::RuntimeCall, + ) { + use frame_support::traits::{InstanceFilter as _, OriginTrait as _}; + // This is a freshly authenticated new account, the origin restrictions doesn't apply. + let mut origin: T::RuntimeOrigin = frame_system::RawOrigin::Signed(real).into(); + origin.add_filter(move |c: &::RuntimeCall| { + let c = ::RuntimeCall::from_ref(c); + // We make sure the proxy call does access this pallet to change modify proxies. + match c.is_sub_type() { + // Proxy call cannot add or remove a proxy with more permissions than it already + // has. + Some(pallet_proxy::Call::add_proxy { ref proxy_type, .. }) | + Some(pallet_proxy::Call::remove_proxy { ref proxy_type, .. }) + if !def.proxy_type.is_superset(proxy_type) => + false, + // Proxy call cannot remove all proxies or kill pure proxies unless it has full + // permissions. + Some(pallet_proxy::Call::remove_proxies { .. }) | + Some(pallet_proxy::Call::kill_pure { .. }) + if def.proxy_type != T::ProxyType::default() => + false, + _ => def.proxy_type.filter(c), + } + }); + let e = call.dispatch(origin); + frame_system::Pallet::::deposit_event( + ::RuntimeEvent::from( + pallet_proxy::Event::ProxyExecuted { + result: e.map(|_| ()).map_err(|e| e.error), + }, + ), + ); + } + } +} diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs new file mode 100644 index 0000000000..99bee1d6ca --- /dev/null +++ b/pallets/remote-proxy/src/tests.rs @@ -0,0 +1,330 @@ +// Copyright (C) Polkadot Fellows. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +// Tests for Remote Proxy Pallet + +use super::*; +use crate as remote_proxy; +use codec::Decode; +use cumulus_pallet_parachain_system::OnSystemEvent; +use frame_support::{ + assert_err, assert_ok, construct_runtime, derive_impl, + traits::{Contains, Currency}, +}; +use frame_system::Call as SystemCall; +use pallet_balances::Call as BalancesCall; +use pallet_proxy::{Error as ProxyError, Event as ProxyEvent}; +use pallet_utility::Call as UtilityCall; +use sp_core::{ConstU32, ConstU64, H256}; +use sp_io::TestExternalities; +use sp_runtime::{ + traits::{BlakeTwo256, Dispatchable}, + BuildStorage, +}; + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub struct Test { + System: frame_system, + Balances: pallet_balances, + Proxy: pallet_proxy, + Utility: pallet_utility, + RemoteProxy: remote_proxy, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; + type BaseCallFilter = BaseFilter; + type AccountData = pallet_balances::AccountData; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Test { + type ReserveIdentifier = [u8; 8]; + type AccountStore = System; +} + +impl pallet_utility::Config for Test { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; + type WeightInfo = (); +} + +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + MaxEncodedLen, + scale_info::TypeInfo, +)] +pub enum ProxyType { + Any, + JustTransfer, + JustUtility, +} +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} +impl frame_support::traits::InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::JustTransfer => { + matches!( + c, + RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) + ) + }, + ProxyType::JustUtility => matches!(c, RuntimeCall::Utility { .. }), + } + } + fn is_superset(&self, o: &Self) -> bool { + self == &ProxyType::Any || self == o + } +} +pub struct BaseFilter; +impl Contains for BaseFilter { + fn contains(c: &RuntimeCall) -> bool { + match *c { + // Remark is used as a no-op call in the benchmarking + RuntimeCall::System(SystemCall::remark { .. }) => true, + RuntimeCall::System(_) => false, + _ => true, + } + } +} +impl pallet_proxy::Config for Test { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ConstU64<1>; + type ProxyDepositFactor = ConstU64<1>; + type MaxProxies = ConstU32<4>; + type WeightInfo = (); + type CallHasher = BlakeTwo256; + type MaxPending = ConstU32<2>; + type AnnouncementDepositBase = ConstU64<1>; + type AnnouncementDepositFactor = ConstU64<1>; +} + +pub struct RemoteProxyImpl; + +impl crate::RemoteProxyInterface for RemoteProxyImpl { + type RemoteAccountId = u64; + type RemoteProxyType = ProxyType; + type RemoteBlockNumber = u64; + type Hash = H256; + type Hasher = BlakeTwo256; + + fn block_to_storage_root( + validation_data: &PersistedValidationData, + ) -> Option<(Self::RemoteBlockNumber, ::Out)> { + Some((validation_data.relay_parent_number as _, validation_data.relay_parent_storage_root)) + } + + fn local_to_remote_account_id(local: &u64) -> Option { + Some(local.clone()) + } + + fn remote_to_local_proxy_defintion( + remote: ProxyDefinition< + Self::RemoteAccountId, + Self::RemoteProxyType, + Self::RemoteBlockNumber, + >, + ) -> Option> { + Some(remote) + } +} + +impl Config for Test { + type MaxStorageRootsToKeep = ConstU64<10>; + type RemoteProxy = RemoteProxyImpl; +} + +pub fn new_test_ext() -> TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 3)], + } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn call_transfer(dest: u64, value: u64) -> RuntimeCall { + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }) +} + +#[test] +fn remote_proxy_works() { + let mut ext = new_test_ext(); + + ext.execute_with(|| { + Balances::make_free_balance_be(&1, 11); // An extra one for the ED. + assert_ok!(Proxy::create_pure(RuntimeOrigin::signed(1), ProxyType::Any, 0, 0)); + let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); + System::assert_last_event( + ProxyEvent::PureCreated { + pure: anon, + who: 1, + proxy_type: ProxyType::Any, + disambiguation_index: 0, + } + .into(), + ); + }); + + let proof = sp_state_machine::prove_read( + ext.as_backend(), + [pallet_proxy::Proxies::::hashed_key_for(&1)], + ) + .unwrap(); + let root = *ext.as_backend().root(); + + new_test_ext().execute_with(|| { + let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); + let call = Box::new(call_transfer(6, 1)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), anon, 5)); + assert_eq!(Balances::free_balance(6), 0); + assert_err!( + Proxy::proxy(RuntimeOrigin::signed(1), anon, None, call.clone()), + ProxyError::::NotProxy + ); + assert_eq!(Balances::free_balance(6), 0); + + RemoteProxy::on_validation_data(&PersistedValidationData { + parent_head: vec![].into(), + relay_parent_number: 1, + relay_parent_storage_root: root, + max_pov_size: 5000000, + }); + assert_ok!(RemoteProxy::remote_proxy( + RuntimeOrigin::signed(1), + anon, + None, + call.clone(), + RemoteProxyProof::V1 { proof: proof.clone().into_iter_nodes().collect(), block: 1 } + )); + + System::assert_last_event(ProxyEvent::ProxyExecuted { result: Ok(()) }.into()); + assert_eq!(Balances::free_balance(6), 1); + + assert_err!( + RemoteProxy::remote_proxy( + RuntimeOrigin::signed(1), + anon, + None, + call.clone(), + RemoteProxyProof::V1 { proof: proof.into_iter_nodes().collect(), block: 2 } + ), + Error::::UnknownProofAnchorBlock + ); + + assert_err!( + RemoteProxy::remote_proxy( + RuntimeOrigin::signed(1), + anon, + None, + call, + RemoteProxyProof::V1 { proof: Vec::new(), block: 1 } + ), + Error::::InvalidProof + ); + }); +} + +#[test] +fn remote_proxy_register_works() { + let mut ext = new_test_ext(); + + ext.execute_with(|| { + Balances::make_free_balance_be(&1, 11); // An extra one for the ED. + assert_ok!(Proxy::create_pure(RuntimeOrigin::signed(1), ProxyType::Any, 0, 0)); + let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); + System::assert_last_event( + ProxyEvent::PureCreated { + pure: anon, + who: 1, + proxy_type: ProxyType::Any, + disambiguation_index: 0, + } + .into(), + ); + }); + + let proof = sp_state_machine::prove_read( + ext.as_backend(), + [pallet_proxy::Proxies::::hashed_key_for(&1)], + ) + .unwrap(); + let root = *ext.as_backend().root(); + + new_test_ext().execute_with(|| { + let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); + let call = Box::new(call_transfer(6, 1)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), anon, 5)); + assert_eq!(Balances::free_balance(6), 0); + assert_err!( + Proxy::proxy(RuntimeOrigin::signed(1), anon, None, call.clone()), + ProxyError::::NotProxy + ); + assert_eq!(Balances::free_balance(6), 0); + + RemoteProxy::on_validation_data(&PersistedValidationData { + parent_head: vec![].into(), + relay_parent_number: 1, + relay_parent_storage_root: root, + max_pov_size: 5000000, + }); + assert_ok!(RuntimeCall::from(UtilityCall::batch { + calls: vec![ + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon, + force_proxy_type: None, + call, + } + .into() + ] + }) + .dispatch(RuntimeOrigin::signed(1))); + + System::assert_has_event(ProxyEvent::ProxyExecuted { result: Ok(()) }.into()); + assert_eq!(Balances::free_balance(6), 1); + }); +} From 98bf59b8958ea692710fc909c8258a04fd1731ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 11 Jan 2025 10:20:08 +0100 Subject: [PATCH 02/43] More tests --- Cargo.toml | 2 +- pallets/remote-proxy/src/tests.rs | 66 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 58e210aa23..dbd5c3c511 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -285,7 +285,7 @@ members = [ "integration-tests/emulated/tests/people/people-kusama", "integration-tests/emulated/tests/people/people-polkadot", "integration-tests/zombienet", - "pallets/remote-proxies", + "pallets/remote-proxy", "relay/common", "relay/kusama", "relay/kusama/constants", diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index 99bee1d6ca..a2175fa547 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -317,6 +317,72 @@ fn remote_proxy_register_works() { crate::Call::remote_proxy_with_registered_proof { real: anon, force_proxy_type: None, + call: call.clone(), + } + .into() + ] + }) + .dispatch(RuntimeOrigin::signed(1))); + + System::assert_has_event(ProxyEvent::ProxyExecuted { result: Ok(()) }.into()); + System::reset_events(); + assert_eq!(Balances::free_balance(6), 1); + + assert_ok!(RuntimeCall::from(UtilityCall::batch { + calls: vec![ + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + UtilityCall::batch { + calls: vec![crate::Call::remote_proxy_with_registered_proof { + real: anon, + force_proxy_type: None, + call: call.clone(), + } + .into()] + } + .into() + ] + }) + .dispatch(RuntimeOrigin::signed(1))); + + System::assert_has_event(ProxyEvent::ProxyExecuted { result: Ok(()) }.into()); + assert_eq!(Balances::free_balance(6), 2); + + assert_err!( + RuntimeCall::from(UtilityCall::batch_all { + calls: vec![ + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon, + force_proxy_type: None, + call: call.clone(), + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon, + force_proxy_type: None, + call: call.clone(), + } + .into() + ] + }) + .dispatch(RuntimeOrigin::signed(1)) + .map_err(|e| e.error), + Error::::ProxyProofNotRegistered + ); + }); +} call, } .into() From 1a1069c8013930e337c499b2ef7cf35d64ab44a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 13 Jan 2025 22:39:26 +0100 Subject: [PATCH 03/43] More tests --- pallets/remote-proxy/src/tests.rs | 174 ++++++++++++++++++++++++++++-- 1 file changed, 166 insertions(+), 8 deletions(-) diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index a2175fa547..52a2e01348 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -188,7 +188,7 @@ fn call_transfer(dest: u64, value: u64) -> RuntimeCall { fn remote_proxy_works() { let mut ext = new_test_ext(); - ext.execute_with(|| { + let anon = ext.execute_with(|| { Balances::make_free_balance_be(&1, 11); // An extra one for the ED. assert_ok!(Proxy::create_pure(RuntimeOrigin::signed(1), ProxyType::Any, 0, 0)); let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); @@ -201,17 +201,17 @@ fn remote_proxy_works() { } .into(), ); + anon }); let proof = sp_state_machine::prove_read( ext.as_backend(), - [pallet_proxy::Proxies::::hashed_key_for(&1)], + [pallet_proxy::Proxies::::hashed_key_for(anon)], ) .unwrap(); let root = *ext.as_backend().root(); new_test_ext().execute_with(|| { - let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); let call = Box::new(call_transfer(6, 1)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), anon, 5)); assert_eq!(Balances::free_balance(6), 0); @@ -266,7 +266,7 @@ fn remote_proxy_works() { fn remote_proxy_register_works() { let mut ext = new_test_ext(); - ext.execute_with(|| { + let anon = ext.execute_with(|| { Balances::make_free_balance_be(&1, 11); // An extra one for the ED. assert_ok!(Proxy::create_pure(RuntimeOrigin::signed(1), ProxyType::Any, 0, 0)); let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); @@ -279,17 +279,17 @@ fn remote_proxy_register_works() { } .into(), ); + anon }); let proof = sp_state_machine::prove_read( ext.as_backend(), - [pallet_proxy::Proxies::::hashed_key_for(&1)], + [pallet_proxy::Proxies::::hashed_key_for(anon)], ) .unwrap(); let root = *ext.as_backend().root(); new_test_ext().execute_with(|| { - let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); let call = Box::new(call_transfer(6, 1)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), anon, 5)); assert_eq!(Balances::free_balance(6), 0); @@ -383,7 +383,98 @@ fn remote_proxy_register_works() { ); }); } - call, + +#[test] +fn remote_proxy_multiple_register_works() { + let mut ext = new_test_ext(); + + let (anon, anon2) = ext.execute_with(|| { + Balances::make_free_balance_be(&1, 11); // An extra one for the ED. + assert_ok!(Proxy::create_pure(RuntimeOrigin::signed(1), ProxyType::Any, 0, 0)); + let anon = Proxy::pure_account(&1, &ProxyType::Any, 0, None); + System::assert_last_event( + ProxyEvent::PureCreated { + pure: anon, + who: 1, + proxy_type: ProxyType::Any, + disambiguation_index: 0, + } + .into(), + ); + + Balances::make_free_balance_be(&2, 11); // An extra one for the ED. + assert_ok!(Proxy::create_pure(RuntimeOrigin::signed(1), ProxyType::Any, 0, 1)); + let anon2 = Proxy::pure_account(&1, &ProxyType::Any, 1, None); + System::assert_last_event( + ProxyEvent::PureCreated { + pure: anon2, + who: 1, + proxy_type: ProxyType::Any, + disambiguation_index: 1, + } + .into(), + ); + + (anon, anon2) + }); + + let proof = sp_state_machine::prove_read( + ext.as_backend(), + [pallet_proxy::Proxies::::hashed_key_for(anon)], + ) + .unwrap(); + + let proof2 = sp_state_machine::prove_read( + ext.as_backend(), + [pallet_proxy::Proxies::::hashed_key_for(anon2)], + ) + .unwrap(); + + let root = *ext.as_backend().root(); + + new_test_ext().execute_with(|| { + let call = Box::new(call_transfer(6, 1)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), anon, 5)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(4), anon2, 5)); + assert_eq!(Balances::free_balance(6), 0); + assert_err!( + Proxy::proxy(RuntimeOrigin::signed(1), anon, None, call.clone()), + ProxyError::::NotProxy + ); + assert_eq!(Balances::free_balance(6), 0); + + RemoteProxy::on_validation_data(&PersistedValidationData { + parent_head: vec![].into(), + relay_parent_number: 1, + relay_parent_storage_root: root, + max_pov_size: 5000000, + }); + assert_ok!(RuntimeCall::from(UtilityCall::batch { + calls: vec![ + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon, + force_proxy_type: None, + call: call.clone(), + } + .into(), + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof2.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon2, + force_proxy_type: None, + call: call.clone(), } .into() ] @@ -391,6 +482,73 @@ fn remote_proxy_register_works() { .dispatch(RuntimeOrigin::signed(1))); System::assert_has_event(ProxyEvent::ProxyExecuted { result: Ok(()) }.into()); - assert_eq!(Balances::free_balance(6), 1); + System::reset_events(); + assert_eq!(Balances::free_balance(6), 2); + + assert_ok!(RuntimeCall::from(UtilityCall::batch { + calls: vec![ + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof2.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon2, + force_proxy_type: None, + call: call.clone(), + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon, + force_proxy_type: None, + call: call.clone(), + } + .into() + ] + }) + .dispatch(RuntimeOrigin::signed(1))); + + System::assert_has_event(ProxyEvent::ProxyExecuted { result: Ok(()) }.into()); + System::reset_events(); + assert_eq!(Balances::free_balance(6), 4); + + assert_err!( + RuntimeCall::from(UtilityCall::batch_all { + calls: vec![ + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::register_remote_proxy_proof { + proof: RemoteProxyProof::V1 { + proof: proof2.clone().into_iter_nodes().collect(), + block: 1 + } + } + .into(), + crate::Call::remote_proxy_with_registered_proof { + real: anon, + force_proxy_type: None, + call: call.clone(), + } + .into(), + ] + }) + .dispatch(RuntimeOrigin::signed(1)) + .map_err(|e| e.error), + Error::::InvalidProof + ); }); } From e58d3c78a979ae9e9a89abf6bb73638e73e98c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 14 Jan 2025 22:10:47 +0100 Subject: [PATCH 04/43] Docs --- pallets/remote-proxy/src/lib.rs | 38 +++++++++++++++++++++++++++++-- pallets/remote-proxy/src/tests.rs | 27 ++++++++++++---------- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 18ff5355a2..f9650dc9f9 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -176,7 +176,7 @@ pub mod pallet { #[derive(core::fmt::Debug, Clone, Decode, Encode, TypeInfo, PartialEq, Eq)] pub enum RemoteProxyProof { /// Assumes the default proxy storage layout. - V1 { proof: Vec>, block: RemoteBlockNumber }, + RelayChain { proof: Vec>, block: RemoteBlockNumber }, } #[derive(Default)] @@ -186,6 +186,16 @@ pub mod pallet { #[pallet::call] impl, I: 'static> Pallet { + /// Dispatch the given `call` from an account that the sender is authorised on a remote + /// chain. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Parameters: + /// - `real`: The account that the proxy will make a call on behalf of. + /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call. + /// - `call`: The call to be made by the `real` account. + /// - `proof`: The proof from the remote chain about the existence of the proof. #[pallet::call_index(0)] #[pallet::weight({ let di = call.get_dispatch_info(); @@ -207,6 +217,19 @@ pub mod pallet { Self::do_remote_proxy(who, real, force_proxy_type, call, proof) } + /// Register a given remote proxy proof in the current [`dispatch_context`]. + /// + /// The registered remote proof can then be used later in the same context to execute a + /// remote proxy call. This is for example useful when having a multisig operation. The + /// multisig call can use [`Self::remote_proxy_with_registered_proof`] to get an approval by + /// the members of the multisig. The final execution of the multisig call should be at least + /// a batch of `register_remote_proxy_proof` and the multisig call that uses + /// `remote_proxy_with_registered_proof`. This way the final approver can use a recent proof + /// to prove the existence of the remote proxy. Otherwise it would require the multisig + /// members to approve the call in [`Config::MaxStorageRootsToKeep`] amount of time. + /// + /// It is supported to register multiple proofs, but the proofs need to be consumed in the + /// reverse order as they were registered. Basically this means last in, last out. #[pallet::call_index(1)] #[pallet::weight(0)] pub fn register_remote_proxy_proof( @@ -224,6 +247,17 @@ pub mod pallet { Ok(()) } + /// Dispatch the given `call` from an account that the sender is authorised on a remote + /// chain. + /// + /// The dispatch origin for this call must be _Signed_. The difference to + /// [`Self::remote_proxy`] is that the proof nees to registered before using + /// [`Self::register_remote_proxy_proof`] (see for more information). + /// + /// Parameters: + /// - `real`: The account that the proxy will make a call on behalf of. + /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call. + /// - `call`: The call to be made by the `real` account. #[pallet::call_index(2)] #[pallet::weight(0)] pub fn remote_proxy_with_registered_proof( @@ -259,7 +293,7 @@ pub mod pallet { }; let def = match proof { - RemoteProxyProof::V1 { proof, block } => { + RemoteProxyProof::RelayChain { proof, block } => { let Some(storage_root) = BlockToRoot::::get(block) else { return Err(Error::::UnknownProofAnchorBlock.into()); }; diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index 52a2e01348..e3aae7ffad 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -232,7 +232,10 @@ fn remote_proxy_works() { anon, None, call.clone(), - RemoteProxyProof::V1 { proof: proof.clone().into_iter_nodes().collect(), block: 1 } + RemoteProxyProof::RelayChain { + proof: proof.clone().into_iter_nodes().collect(), + block: 1 + } )); System::assert_last_event(ProxyEvent::ProxyExecuted { result: Ok(()) }.into()); @@ -244,7 +247,7 @@ fn remote_proxy_works() { anon, None, call.clone(), - RemoteProxyProof::V1 { proof: proof.into_iter_nodes().collect(), block: 2 } + RemoteProxyProof::RelayChain { proof: proof.into_iter_nodes().collect(), block: 2 } ), Error::::UnknownProofAnchorBlock ); @@ -255,7 +258,7 @@ fn remote_proxy_works() { anon, None, call, - RemoteProxyProof::V1 { proof: Vec::new(), block: 1 } + RemoteProxyProof::RelayChain { proof: Vec::new(), block: 1 } ), Error::::InvalidProof ); @@ -308,7 +311,7 @@ fn remote_proxy_register_works() { assert_ok!(RuntimeCall::from(UtilityCall::batch { calls: vec![ crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof.clone().into_iter_nodes().collect(), block: 1 } @@ -331,7 +334,7 @@ fn remote_proxy_register_works() { assert_ok!(RuntimeCall::from(UtilityCall::batch { calls: vec![ crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof.clone().into_iter_nodes().collect(), block: 1 } @@ -357,7 +360,7 @@ fn remote_proxy_register_works() { RuntimeCall::from(UtilityCall::batch_all { calls: vec![ crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof.clone().into_iter_nodes().collect(), block: 1 } @@ -452,7 +455,7 @@ fn remote_proxy_multiple_register_works() { assert_ok!(RuntimeCall::from(UtilityCall::batch { calls: vec![ crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof.clone().into_iter_nodes().collect(), block: 1 } @@ -465,7 +468,7 @@ fn remote_proxy_multiple_register_works() { } .into(), crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof2.clone().into_iter_nodes().collect(), block: 1 } @@ -488,14 +491,14 @@ fn remote_proxy_multiple_register_works() { assert_ok!(RuntimeCall::from(UtilityCall::batch { calls: vec![ crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof.clone().into_iter_nodes().collect(), block: 1 } } .into(), crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof2.clone().into_iter_nodes().collect(), block: 1 } @@ -525,14 +528,14 @@ fn remote_proxy_multiple_register_works() { RuntimeCall::from(UtilityCall::batch_all { calls: vec![ crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof.clone().into_iter_nodes().collect(), block: 1 } } .into(), crate::Call::register_remote_proxy_proof { - proof: RemoteProxyProof::V1 { + proof: RemoteProxyProof::RelayChain { proof: proof2.clone().into_iter_nodes().collect(), block: 1 } From 67d908b5a4e6415f4c6e9abad574f173060c6419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 14 Jan 2025 23:13:16 +0100 Subject: [PATCH 05/43] Start with benchmarks --- Cargo.lock | 1 + pallets/remote-proxy/Cargo.toml | 13 +++++ pallets/remote-proxy/src/benchmarking.rs | 69 ++++++++++++++++++++++++ pallets/remote-proxy/src/lib.rs | 12 +++++ pallets/remote-proxy/src/tests.rs | 31 +++++++++++ 5 files changed, 126 insertions(+) create mode 100644 pallets/remote-proxy/src/benchmarking.rs diff --git a/Cargo.lock b/Cargo.lock index ab99702b18..7cccf5eb5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8858,6 +8858,7 @@ version = "1.0.0" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", + "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", diff --git a/pallets/remote-proxy/Cargo.toml b/pallets/remote-proxy/Cargo.toml index cb2978fdf9..07fba5f3c7 100644 --- a/pallets/remote-proxy/Cargo.toml +++ b/pallets/remote-proxy/Cargo.toml @@ -12,6 +12,7 @@ scale-info = { features = ["derive"], workspace = true } cumulus-pallet-parachain-system = { workspace = true } cumulus-primitives-core = { workspace = true } +frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } pallet-proxy = { workspace = true } @@ -32,6 +33,7 @@ std = [ "codec/std", "cumulus-pallet-parachain-system/std", "cumulus-primitives-core/std", + "frame-benchmarking/std", "frame-support/std", "frame-system/std", "pallet-proxy/std", @@ -39,3 +41,14 @@ std = [ "sp-trie/std", "sp-runtime/std", ] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "cumulus-pallet-parachain-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] diff --git a/pallets/remote-proxy/src/benchmarking.rs b/pallets/remote-proxy/src/benchmarking.rs new file mode 100644 index 0000000000..9a5ec40726 --- /dev/null +++ b/pallets/remote-proxy/src/benchmarking.rs @@ -0,0 +1,69 @@ +// Copyright (C) Polkadot Fellows. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Benchmarks for Remote Proxy Pallet + +use super::*; +use crate::Pallet as RemoteProxy; +use alloc::{boxed::Box, vec}; +use frame_benchmarking::v2::{account, benchmarks, impl_test_function, whitelisted_caller}; +use frame_support::traits::Currency; +use frame_system::RawOrigin; +use sp_runtime::traits::{Bounded, StaticLookup}; + +const SEED: u32 = 0; + +type BalanceOf = <::Currency as Currency< + ::AccountId, +>>::Balance; + +fn assert_last_event( + generic_event: ::RuntimeEvent, +) { + frame_system::Pallet::::assert_last_event(generic_event.into()); +} + +#[benchmarks] +mod benchmarks { + use super::*; + use frame_benchmarking::BenchmarkError; + + #[benchmark] + fn remote_proxy() -> Result<(), BenchmarkError> { + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("target", 0, SEED); + ::Currency::make_free_balance_be( + &caller, + BalanceOf::::max_value() / 2u32.into(), + ); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + let real_lookup = T::Lookup::unlookup(real.clone()); + let call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![] }.into(); + let (proof, block_number, storage_root) = + T::RemoteProxy::create_remote_proxy_proof(&caller, &real); + BlockToRoot::::insert(block_number, storage_root); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), real_lookup, None, Box::new(call), proof); + + assert_last_event::(pallet_proxy::Event::ProxyExecuted { result: Ok(()) }.into()); + + Ok(()) + } + + impl_benchmark_test_suite!(RemoteProxy, crate::tests::new_test_ext(), crate::tests::Test); +} diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index f9650dc9f9..428eaa10f9 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -16,6 +16,8 @@ extern crate alloc; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; #[cfg(test)] mod tests; @@ -73,6 +75,16 @@ pub trait RemoteProxyInterface { Self::RemoteBlockNumber, >, ) -> Option>; + + /// Create a remote proxy proof to be used in benchmarking. + /// + /// Returns the `proof`, `block_number` and `storage_root`. The later are required to validate + /// the `proof`. + #[cfg(feature = "runtime-benchmarks")] + fn create_remote_proxy_proof( + caller: &AccountId, + proxy: &AccountId, + ) -> (RemoteProxyProof, Self::RemoteBlockNumber, Self::Hash); } #[frame_support::pallet] diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index e3aae7ffad..8cfb8b38e8 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -161,6 +161,37 @@ impl crate::RemoteProxyInterface for RemoteProxyImpl { ) -> Option> { Some(remote) } + + #[cfg(feature = "runtime-benchmarks")] + fn create_remote_proxy_proof( + caller: &u64, + proxy: &u64, + ) -> (RemoteProxyProof, u64, H256) { + use sp_trie::TrieMut; + + let (mut db, mut root) = sp_trie::MemoryDB::::default_with_root(); + let mut trie = + sp_trie::TrieDBMutBuilder::>::new(&mut db, &mut root).build(); + + let proxy_definition = vec![ProxyDefinition:: { + delegate: caller.clone(), + proxy_type: ProxyType::default(), + delay: 0, + }]; + + trie.insert(&Self::proxy_definition_storage_key(proxy), &proxy_definition.encode()) + .unwrap(); + drop(trie); + + ( + RemoteProxyProof::RelayChain { + proof: db.drain().into_values().map(|d| d.0).collect(), + block: 1, + }, + 1, + root, + ) + } } impl Config for Test { From ebb1905e801447a0df50d3350cfc7e559db9de8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 15 Jan 2025 13:14:46 +0100 Subject: [PATCH 06/43] Finish benchmarks --- pallets/remote-proxy/src/benchmarking.rs | 70 +++++++++++++++++++++++- pallets/remote-proxy/src/lib.rs | 39 +++++++++---- pallets/remote-proxy/src/tests.rs | 1 + pallets/remote-proxy/src/weight.rs | 38 +++++++++++++ 4 files changed, 134 insertions(+), 14 deletions(-) create mode 100644 pallets/remote-proxy/src/weight.rs diff --git a/pallets/remote-proxy/src/benchmarking.rs b/pallets/remote-proxy/src/benchmarking.rs index 9a5ec40726..edc3d73839 100644 --- a/pallets/remote-proxy/src/benchmarking.rs +++ b/pallets/remote-proxy/src/benchmarking.rs @@ -18,7 +18,9 @@ use super::*; use crate::Pallet as RemoteProxy; use alloc::{boxed::Box, vec}; -use frame_benchmarking::v2::{account, benchmarks, impl_test_function, whitelisted_caller}; +use frame_benchmarking::v2::{ + account, impl_test_function, instance_benchmarks, whitelisted_caller, +}; use frame_support::traits::Currency; use frame_system::RawOrigin; use sp_runtime::traits::{Bounded, StaticLookup}; @@ -35,7 +37,7 @@ fn assert_last_event( frame_system::Pallet::::assert_last_event(generic_event.into()); } -#[benchmarks] +#[instance_benchmarks] mod benchmarks { use super::*; use frame_benchmarking::BenchmarkError; @@ -55,7 +57,7 @@ mod benchmarks { frame_system::Call::::remark { remark: vec![] }.into(); let (proof, block_number, storage_root) = T::RemoteProxy::create_remote_proxy_proof(&caller, &real); - BlockToRoot::::insert(block_number, storage_root); + BlockToRoot::::insert(block_number, storage_root); #[extrinsic_call] _(RawOrigin::Signed(caller), real_lookup, None, Box::new(call), proof); @@ -65,5 +67,67 @@ mod benchmarks { Ok(()) } + #[benchmark] + fn register_remote_proxy_proof() -> Result<(), BenchmarkError> { + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("target", 0, SEED); + ::Currency::make_free_balance_be( + &caller, + BalanceOf::::max_value() / 2u32.into(), + ); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + let (proof, block_number, storage_root) = + T::RemoteProxy::create_remote_proxy_proof(&caller, &real); + BlockToRoot::::insert(block_number, storage_root); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), proof); + + Ok(()) + } + + #[benchmark] + fn remote_proxy_with_registered_proof() -> Result<(), BenchmarkError> { + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("target", 0, SEED); + ::Currency::make_free_balance_be( + &caller, + BalanceOf::::max_value() / 2u32.into(), + ); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + let real_lookup = T::Lookup::unlookup(real.clone()); + let call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![] }.into(); + let (proof, block_number, storage_root) = + T::RemoteProxy::create_remote_proxy_proof(&caller, &real); + BlockToRoot::::insert(block_number, storage_root); + + #[block] + { + frame_support::dispatch_context::run_in_context(|| { + frame_support::dispatch_context::with_context::< + crate::RemoteProxyContext>, + _, + >(|context| { + context.or_default().proofs.push(proof.clone()); + }); + + RemoteProxy::::remote_proxy_with_registered_proof( + RawOrigin::Signed(caller).into(), + real_lookup, + None, + Box::new(call), + ) + .unwrap() + }) + } + + assert_last_event::(pallet_proxy::Event::ProxyExecuted { result: Ok(()) }.into()); + + Ok(()) + } + impl_benchmark_test_suite!(RemoteProxy, crate::tests::new_test_ext(), crate::tests::Test); } diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 428eaa10f9..c256462ea3 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -20,6 +20,7 @@ extern crate alloc; mod benchmarking; #[cfg(test)] mod tests; +mod weight; use alloc::vec::Vec; use codec::{Encode, MaxEncodedLen}; @@ -31,6 +32,7 @@ use sp_runtime::traits::Saturating; pub use cumulus_primitives_core::PersistedValidationData; pub use pallet::*; +pub use weight::WeightInfo; /// The remote proxy interface. pub trait RemoteProxyInterface { @@ -98,11 +100,12 @@ pub mod pallet { type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; - type RemoteBlockNumberOf = <>::RemoteProxy as RemoteProxyInterface< - ::AccountId, - ::ProxyType, - BlockNumberFor, - >>::RemoteBlockNumber; + pub(crate) type RemoteBlockNumberOf = + <>::RemoteProxy as RemoteProxyInterface< + ::AccountId, + ::ProxyType, + BlockNumberFor, + >>::RemoteBlockNumber; type RemoteAccountIdOf = <>::RemoteProxy as RemoteProxyInterface< ::AccountId, ::ProxyType, @@ -123,6 +126,7 @@ pub mod pallet { ::ProxyType, BlockNumberFor, >>::RemoteProxyType; + type WeightInfoOf = >::WeightInfo; #[pallet::pallet] pub struct Pallet(_); @@ -148,6 +152,9 @@ pub mod pallet { Self::ProxyType, BlockNumberFor, >; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } impl OnSystemEvent for Pallet { @@ -191,9 +198,11 @@ pub mod pallet { RelayChain { proof: Vec>, block: RemoteBlockNumber }, } + /// The dispatch context to keep track of registered proofs. #[derive(Default)] - struct RemoteProxyContext { - proofs: Vec>, + pub(crate) struct RemoteProxyContext { + /// The registered proofs. + pub(crate) proofs: Vec>, } #[pallet::call] @@ -211,8 +220,9 @@ pub mod pallet { #[pallet::call_index(0)] #[pallet::weight({ let di = call.get_dispatch_info(); - ( // AccountData for inner call origin accountdata. - T::DbWeight::get().reads_writes(1, 1) + (WeightInfoOf::::remote_proxy() + // AccountData for inner call origin accountdata. + .saturating_add(T::DbWeight::get().reads_writes(1, 1)) .saturating_add(di.weight), di.class) })] @@ -243,7 +253,7 @@ pub mod pallet { /// It is supported to register multiple proofs, but the proofs need to be consumed in the /// reverse order as they were registered. Basically this means last in, last out. #[pallet::call_index(1)] - #[pallet::weight(0)] + #[pallet::weight({(WeightInfoOf::::register_remote_proxy_proof(), DispatchClass::Normal)})] pub fn register_remote_proxy_proof( origin: OriginFor, proof: RemoteProxyProof>, @@ -271,7 +281,14 @@ pub mod pallet { /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call. /// - `call`: The call to be made by the `real` account. #[pallet::call_index(2)] - #[pallet::weight(0)] + #[pallet::weight({ + let di = call.get_dispatch_info(); + (WeightInfoOf::::remote_proxy_with_registered_proof() + // AccountData for inner call origin accountdata. + .saturating_add(T::DbWeight::get().reads_writes(1, 1)) + .saturating_add(di.weight), + di.class) + })] pub fn remote_proxy_with_registered_proof( origin: OriginFor, real: AccountIdLookupOf, diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index 8cfb8b38e8..5feba5d40d 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -197,6 +197,7 @@ impl crate::RemoteProxyInterface for RemoteProxyImpl { impl Config for Test { type MaxStorageRootsToKeep = ConstU64<10>; type RemoteProxy = RemoteProxyImpl; + type WeightInfo = (); } pub fn new_test_ext() -> TestExternalities { diff --git a/pallets/remote-proxy/src/weight.rs b/pallets/remote-proxy/src/weight.rs new file mode 100644 index 0000000000..738eeab820 --- /dev/null +++ b/pallets/remote-proxy/src/weight.rs @@ -0,0 +1,38 @@ +// Copyright (C) Polkadot Fellows. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use frame_support::weights::Weight; + +/// Weight functions needed for `pallet_remote_proxy`. +pub trait WeightInfo { + fn remote_proxy_with_registered_proof() -> Weight; + fn register_remote_proxy_proof() -> Weight; + fn remote_proxy() -> Weight; +} + +impl WeightInfo for () { + fn remote_proxy_with_registered_proof() -> Weight { + Weight::zero() + } + + fn register_remote_proxy_proof() -> Weight { + Weight::zero() + } + + fn remote_proxy() -> Weight { + Weight::zero() + } +} From ad1f096fa359bb57d0f81370d8e7feb0627ace81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 15 Jan 2025 21:48:56 +0100 Subject: [PATCH 07/43] Implement remote proxy for Polkadot AH --- Cargo.lock | 4 + Cargo.toml | 3 +- pallets/remote-proxy/src/lib.rs | 6 +- relay/polkadot/constants/Cargo.toml | 6 + relay/polkadot/constants/src/lib.rs | 110 ++++++++++++++++++ relay/polkadot/src/lib.rs | 67 +++-------- .../asset-hubs/asset-hub-polkadot/Cargo.toml | 3 + .../asset-hubs/asset-hub-polkadot/src/lib.rs | 49 +++++++- 8 files changed, 193 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7cccf5eb5f..a6e4c6cd8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,6 +794,7 @@ dependencies = [ "pallet-nfts", "pallet-nfts-runtime-api", "pallet-proxy", + "pallet-remote-proxy", "pallet-session", "pallet-timestamp", "pallet-transaction-payment", @@ -10216,8 +10217,11 @@ name = "polkadot-runtime-constants" version = "1.0.0" dependencies = [ "frame-support", + "pallet-remote-proxy", + "parity-scale-codec", "polkadot-primitives 16.0.0", "polkadot-runtime-common", + "scale-info", "smallvec", "sp-core 34.0.0", "sp-runtime 39.0.5", diff --git a/Cargo.toml b/Cargo.toml index dbd5c3c511..b05036748d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -147,6 +147,7 @@ pallet-proxy = { version = "38.0.0", default-features = false } pallet-ranked-collective = { version = "38.0.0", default-features = false } pallet-recovery = { version = "38.0.0", default-features = false } pallet-referenda = { version = "38.0.0", default-features = false } +pallet-remote-proxy = { path = "pallets/remote-proxy", default-features = false } pallet-salary = { version = "23.0.0", default-features = false } pallet-scheduler = { version = "39.0.0", default-features = false } pallet-session = { version = "38.0.0", default-features = false } @@ -234,7 +235,7 @@ sp-std = { version = "14.0.0", default-features = false } sp-storage = { version = "21.0.0", default-features = false } sp-tracing = { version = "17.0.1", default-features = false } sp-transaction-pool = { version = "34.0.0", default-features = false } -sp-trie = { version = "37.0.0" } +sp-trie = { version = "37.0.0", default-features = false } sp-version = { version = "37.0.0", default-features = false } sp-weights = { version = "31.0.0", default-features = false } static_assertions = { version = "1.1.0" } diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index c256462ea3..a3580ef66f 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +#![cfg_attr(not(feature = "std"), no_std)] + extern crate alloc; #[cfg(feature = "runtime-benchmarks")] @@ -22,16 +24,16 @@ mod benchmarking; mod tests; mod weight; -use alloc::vec::Vec; +use alloc::{boxed::Box, vec::Vec}; use codec::{Encode, MaxEncodedLen}; use frame_support::{storage::storage_prefix, Parameter, StorageHasher, Twox64Concat}; -use pallet_proxy::ProxyDefinition; use scale_info::TypeInfo; use sp_core::Hasher; use sp_runtime::traits::Saturating; pub use cumulus_primitives_core::PersistedValidationData; pub use pallet::*; +pub use pallet_proxy::ProxyDefinition; pub use weight::WeightInfo; /// The remote proxy interface. diff --git a/relay/polkadot/constants/Cargo.toml b/relay/polkadot/constants/Cargo.toml index 645d40e475..fd0893aa50 100644 --- a/relay/polkadot/constants/Cargo.toml +++ b/relay/polkadot/constants/Cargo.toml @@ -8,8 +8,11 @@ license.workspace = true [dependencies] smallvec = { workspace = true } +codec = { workspace = true } +scale-info = { workspace = true } frame-support = { workspace = true } +pallet-remote-proxy = { workspace = true } polkadot-primitives = { workspace = true } polkadot-runtime-common = { workspace = true } sp-runtime = { workspace = true } @@ -21,9 +24,12 @@ xcm-builder = { workspace = true } [features] default = ["std"] std = [ + "codec/std", "frame-support/std", + "pallet-remote-proxy/std", "polkadot-primitives/std", "polkadot-runtime-common/std", + "scale-info/std", "sp-core/std", "sp-runtime/std", "sp-weights/std", diff --git a/relay/polkadot/constants/src/lib.rs b/relay/polkadot/constants/src/lib.rs index 3449d98884..368ed30df1 100644 --- a/relay/polkadot/constants/src/lib.rs +++ b/relay/polkadot/constants/src/lib.rs @@ -152,13 +152,95 @@ pub mod system_parachain { /// Polkadot Treasury pallet instance. pub const TREASURY_PALLET_ID: u8 = 19; +pub mod proxy { + use pallet_remote_proxy::ProxyDefinition; + use polkadot_primitives::{AccountId, BlakeTwo256, BlockNumber, Hash}; + use sp_runtime::traits::Convert; + + /// The type used to represent the kinds of proxying allowed. + #[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + codec::Encode, + codec::Decode, + sp_runtime::RuntimeDebug, + codec::MaxEncodedLen, + scale_info::TypeInfo, + Default, + )] + pub enum ProxyType { + #[default] + Any = 0, + NonTransfer = 1, + Governance = 2, + Staking = 3, + // Skip 4 as it is now removed (was SudoBalances) + // Skip 5 as it was IdentityJudgement + CancelProxy = 6, + Auction = 7, + NominationPools = 8, + ParaRegistration = 9, + } + + /// Remote proxy interface that uses the relay chain as remote location. + pub struct RemoteProxyInterface( + core::marker::PhantomData<(LocalProxyType, ProxyDefinitionConverter)>, + ); + + impl< + LocalProxyType, + ProxyDefinitionConverter: Convert< + ProxyDefinition, + Option>, + >, + > pallet_remote_proxy::RemoteProxyInterface + for RemoteProxyInterface + { + type RemoteAccountId = AccountId; + + type RemoteProxyType = ProxyType; + + type RemoteBlockNumber = BlockNumber; + + type Hash = Hash; + + type Hasher = BlakeTwo256; + + fn block_to_storage_root( + validation_data: &polkadot_primitives::PersistedValidationData, + ) -> Option<(Self::RemoteBlockNumber, ::Out)> { + Some((validation_data.relay_parent_number, validation_data.relay_parent_storage_root)) + } + + fn local_to_remote_account_id(local: &AccountId) -> Option { + Some(local.clone()) + } + + fn remote_to_local_proxy_defintion( + remote: ProxyDefinition< + Self::RemoteAccountId, + Self::RemoteProxyType, + Self::RemoteBlockNumber, + >, + ) -> Option> { + ProxyDefinitionConverter::convert(remote) + } + } +} + #[cfg(test)] mod tests { use super::{ currency::{CENTS, DOLLARS, MILLICENTS}, fee::WeightToFee, + proxy::ProxyType, }; use crate::weights::ExtrinsicBaseWeight; + use codec::{Decode, Encode}; use frame_support::weights::WeightToFee as WeightToFeeT; use polkadot_runtime_common::MAXIMUM_BLOCK_WEIGHT; @@ -180,4 +262,32 @@ mod tests { let y = CENTS / 10; assert!(x.max(y) - x.min(y) < MILLICENTS); } + + #[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, sp_runtime::RuntimeDebug, + )] + pub enum OldProxyType { + Any, + NonTransfer, + Governance, + Staking, + SudoBalances, + IdentityJudgement, + } + + #[test] + fn proxy_type_decodes_correctly() { + for (i, j) in vec![ + (OldProxyType::Any, ProxyType::Any), + (OldProxyType::NonTransfer, ProxyType::NonTransfer), + (OldProxyType::Governance, ProxyType::Governance), + (OldProxyType::Staking, ProxyType::Staking), + ] + .into_iter() + { + assert_eq!(i.encode(), j.encode()); + } + assert!(ProxyType::decode(&mut &OldProxyType::SudoBalances.encode()[..]).is_err()); + assert!(ProxyType::decode(&mut &OldProxyType::IdentityJudgement.encode()[..]).is_err()); + } } diff --git a/relay/polkadot/src/lib.rs b/relay/polkadot/src/lib.rs index 4bd27abc7d..1500d2ed1d 100644 --- a/relay/polkadot/src/lib.rs +++ b/relay/polkadot/src/lib.rs @@ -128,7 +128,7 @@ pub use sp_runtime::BuildStorage; /// Constant values used within the runtime. use polkadot_runtime_constants::{ - currency::*, fee::*, system_parachain, time::*, TREASURY_PALLET_ID, + currency::*, fee::*, proxy::ProxyType, system_parachain, time::*, TREASURY_PALLET_ID, }; // Weights used in the runtime. @@ -983,7 +983,10 @@ parameter_types! { pub const MaxPending: u16 = 32; } -/// The type used to represent the kinds of proxying allowed. +/// Transparent wrapper around the actual [`ProxyType`]. +/// +/// This is done to have [`ProxyType`] declared in a different crate (constants) and being able to +/// implement [`InstanceFilter`] in this crate. #[derive( Copy, Clone, @@ -995,60 +998,21 @@ parameter_types! { Decode, RuntimeDebug, MaxEncodedLen, - scale_info::TypeInfo, + Default, )] -pub enum ProxyType { - Any = 0, - NonTransfer = 1, - Governance = 2, - Staking = 3, - // Skip 4 as it is now removed (was SudoBalances) - // Skip 5 as it was IdentityJudgement - CancelProxy = 6, - Auction = 7, - NominationPools = 8, - ParaRegistration = 9, -} +pub struct TransparentProxyType(T); -#[cfg(test)] -mod proxy_type_tests { - use super::*; +impl scale_info::TypeInfo for TransparentProxyType { + type Identity = T::Identity; - #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)] - pub enum OldProxyType { - Any, - NonTransfer, - Governance, - Staking, - SudoBalances, - IdentityJudgement, - } - - #[test] - fn proxy_type_decodes_correctly() { - for (i, j) in vec![ - (OldProxyType::Any, ProxyType::Any), - (OldProxyType::NonTransfer, ProxyType::NonTransfer), - (OldProxyType::Governance, ProxyType::Governance), - (OldProxyType::Staking, ProxyType::Staking), - ] - .into_iter() - { - assert_eq!(i.encode(), j.encode()); - } - assert!(ProxyType::decode(&mut &OldProxyType::SudoBalances.encode()[..]).is_err()); - assert!(ProxyType::decode(&mut &OldProxyType::IdentityJudgement.encode()[..]).is_err()); + fn type_info() -> scale_info::Type { + T::type_info() } } -impl Default for ProxyType { - fn default() -> Self { - Self::Any - } -} -impl InstanceFilter for ProxyType { +impl InstanceFilter for TransparentProxyType { fn filter(&self, c: &RuntimeCall) -> bool { - match self { + match self.0 { ProxyType::Any => true, ProxyType::NonTransfer => matches!( c, @@ -1133,8 +1097,9 @@ impl InstanceFilter for ProxyType { ), } } + fn is_superset(&self, o: &Self) -> bool { - match (self, o) { + match (self.0, o.0) { (x, y) if x == y => true, (ProxyType::Any, _) => true, (_, ProxyType::Any) => false, @@ -1148,7 +1113,7 @@ impl pallet_proxy::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type Currency = Balances; - type ProxyType = ProxyType; + type ProxyType = TransparentProxyType; type ProxyDepositBase = ProxyDepositBase; type ProxyDepositFactor = ProxyDepositFactor; type MaxProxies = MaxProxies; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 1f207ce943..3e17406b36 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -23,6 +23,7 @@ bp-bridge-hub-polkadot = { workspace = true } collectives-polkadot-runtime-constants = { workspace = true } kusama-runtime-constants = { workspace = true } polkadot-runtime-constants = { workspace = true } +pallet-remote-proxy = { workspace = true } # Substrate frame-benchmarking = { optional = true, workspace = true } @@ -133,6 +134,7 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-nfts/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", + "pallet-remote-proxy/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", @@ -218,6 +220,7 @@ std = [ "pallet-nfts-runtime-api/std", "pallet-nfts/std", "pallet-proxy/std", + "pallet-remote-proxy/std", "pallet-session/std", "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 1a14c8a6d1..16e43ed537 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -73,11 +73,13 @@ use assets_common::{ }; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; +use pallet_proxy::ProxyDefinition; +use polkadot_runtime_constants::time::MINUTES; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, ConstU128, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify}, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, ConvertInto, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Permill, }; @@ -956,6 +958,50 @@ impl pallet_asset_conversion::Config for Runtime { >; } +/// Converts from the relay chain proxy type to the local proxy type. +pub struct RelayChainToLocalProxyTypeConverter; + +impl + Convert< + ProxyDefinition, + Option>, + > for RelayChainToLocalProxyTypeConverter +{ + fn convert( + a: ProxyDefinition, + ) -> Option> { + let proxy_type = match a.proxy_type { + polkadot_runtime_constants::proxy::ProxyType::Any => ProxyType::Any, + polkadot_runtime_constants::proxy::ProxyType::NonTransfer => ProxyType::NonTransfer, + // Proxy types that are not supported on AH. + polkadot_runtime_constants::proxy::ProxyType::Governance | + polkadot_runtime_constants::proxy::ProxyType::Staking | + polkadot_runtime_constants::proxy::ProxyType::CancelProxy | + polkadot_runtime_constants::proxy::ProxyType::Auction | + polkadot_runtime_constants::proxy::ProxyType::NominationPools | + polkadot_runtime_constants::proxy::ProxyType::ParaRegistration => return None, + }; + + Some(ProxyDefinition { + delegate: a.delegate, + proxy_type, + // Delays are currently not supported by the remote proxy pallet, but should be + // converted in the future to the block time used by the local proxy pallet. + delay: a.delay, + }) + } +} + +impl pallet_remote_proxy::Config for Runtime { + type MaxStorageRootsToKeep = ConstU32<{ MINUTES * 20 }>; + type RemoteProxy = polkadot_runtime_constants::proxy::RemoteProxyInterface< + ProxyType, + RelayChainToLocalProxyTypeConverter, + >; + //TODO: Run benchmarks and replace. + type WeightInfo = (); +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -992,6 +1038,7 @@ construct_runtime!( Utility: pallet_utility = 40, Multisig: pallet_multisig = 41, Proxy: pallet_proxy = 42, + RemoteProxyRelayChain: pallet_remote_proxy:: = 43, // The main stage. Assets: pallet_assets:: = 50, From 82e49e0283899912cfac1dfe107922a8cbd7c292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 10:16:09 +0100 Subject: [PATCH 08/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Xiliang Chen --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index a3580ef66f..fd8f11518a 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -167,7 +167,7 @@ pub mod pallet { }; // Update the block to root mappings. - BlockToRoot::::insert(block.clone(), hash); + BlockToRoot::::insert(&block, hash); BlockToRoot::::remove(block.saturating_sub(T::MaxStorageRootsToKeep::get())); } From 6ffc856ddcd9a6a585e920f959ab67c59198079f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 11:21:09 +0100 Subject: [PATCH 09/43] FOR THE MIGHTY CLIPPY --- pallets/remote-proxy/src/lib.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index fd8f11518a..c65c8a62c7 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -161,8 +161,7 @@ pub mod pallet { impl OnSystemEvent for Pallet { fn on_validation_data(validation_data: &PersistedValidationData) { - let Some((block, hash)) = T::RemoteProxy::block_to_storage_root(&validation_data) - else { + let Some((block, hash)) = T::RemoteProxy::block_to_storage_root(validation_data) else { return; }; @@ -238,7 +237,7 @@ pub mod pallet { let who = ensure_signed(origin)?; let real = T::Lookup::lookup(real)?; - Self::do_remote_proxy(who, real, force_proxy_type, call, proof) + Self::do_remote_proxy(who, real, force_proxy_type, *call, proof) } /// Register a given remote proxy proof in the current [`dispatch_context`]. @@ -305,9 +304,9 @@ pub mod pallet { _, >(|context| context.or_default().proofs.pop()) .flatten() - .ok_or_else(|| Error::::ProxyProofNotRegistered)?; + .ok_or(Error::::ProxyProofNotRegistered)?; - Self::do_remote_proxy(who, real, force_proxy_type, call, proof) + Self::do_remote_proxy(who, real, force_proxy_type, *call, proof) } } @@ -316,7 +315,7 @@ pub mod pallet { who: T::AccountId, real: T::AccountId, force_proxy_type: Option, - call: Box<::RuntimeCall>, + call: ::RuntimeCall, proof: RemoteProxyProof>, ) -> DispatchResult { let Some(real_remote) = T::RemoteProxy::local_to_remote_account_id(&real) else { @@ -342,7 +341,7 @@ pub mod pallet { ) .ok() .flatten() - .ok_or_else(|| Error::::InvalidProof)?; + .ok_or(Error::::InvalidProof)?; let proxy_definitions = alloc::vec::Vec::< ProxyDefinition< @@ -367,13 +366,13 @@ pub mod pallet { .into_iter() .filter_map(|pd| T::RemoteProxy::remote_to_local_proxy_defintion(pd)) .find(f) - .ok_or_else(|| Error::::DidNotFindMatchingProxyDefinition)? + .ok_or(Error::::DidNotFindMatchingProxyDefinition)? }, }; ensure!(def.delay.is_zero(), Error::::Unannounced); - Self::do_proxy(def, real, *call); + Self::do_proxy(def, real, call); Ok(()) } From 6e3e420e4799102706a40aff05e0312d1b167ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 11:23:27 +0100 Subject: [PATCH 10/43] ZEPTER --- pallets/remote-proxy/Cargo.toml | 42 +++++++++++++++++++-------------- relay/kusama/Cargo.toml | 1 + relay/polkadot/Cargo.toml | 1 + 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/pallets/remote-proxy/Cargo.toml b/pallets/remote-proxy/Cargo.toml index 07fba5f3c7..ef95f5119d 100644 --- a/pallets/remote-proxy/Cargo.toml +++ b/pallets/remote-proxy/Cargo.toml @@ -30,25 +30,31 @@ sp-state-machine = { workspace = true } default = [ "std" ] std = [ - "codec/std", - "cumulus-pallet-parachain-system/std", - "cumulus-primitives-core/std", - "frame-benchmarking/std", - "frame-support/std", - "frame-system/std", - "pallet-proxy/std", - "sp-core/std", - "sp-trie/std", - "sp-runtime/std", + "codec/std", + "cumulus-pallet-parachain-system/std", + "cumulus-primitives-core/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "pallet-proxy/std", + "sp-core/std", + "sp-trie/std", + "sp-runtime/std", + "pallet-balances/std", + "pallet-utility/std", + "scale-info/std", + "sp-io/std", + "sp-state-machine/std" ] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-proxy/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-utility/runtime-benchmarks", - "cumulus-pallet-parachain-system/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "cumulus-pallet-parachain-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks" ] diff --git a/relay/kusama/Cargo.toml b/relay/kusama/Cargo.toml index bbb220140d..67d68bd3d6 100644 --- a/relay/kusama/Cargo.toml +++ b/relay/kusama/Cargo.toml @@ -218,6 +218,7 @@ std = [ "xcm-executor/std", "xcm-runtime-apis/std", "xcm/std", + "sp-trie/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/relay/polkadot/Cargo.toml b/relay/polkadot/Cargo.toml index 823bcf41a3..5fc20f28da 100644 --- a/relay/polkadot/Cargo.toml +++ b/relay/polkadot/Cargo.toml @@ -220,6 +220,7 @@ std = [ "xcm-executor/std", "xcm-runtime-apis/std", "xcm/std", + "sp-trie/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", From 4e559bf4add97d484cea4c40a26f1723b636e019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 11:33:56 +0100 Subject: [PATCH 11/43] No instance --- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 16e43ed537..39ff35e747 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -992,7 +992,7 @@ impl } } -impl pallet_remote_proxy::Config for Runtime { +impl pallet_remote_proxy::Config for Runtime { type MaxStorageRootsToKeep = ConstU32<{ MINUTES * 20 }>; type RemoteProxy = polkadot_runtime_constants::proxy::RemoteProxyInterface< ProxyType, @@ -1038,7 +1038,7 @@ construct_runtime!( Utility: pallet_utility = 40, Multisig: pallet_multisig = 41, Proxy: pallet_proxy = 42, - RemoteProxyRelayChain: pallet_remote_proxy:: = 43, + RemoteProxyRelayChain: pallet_remote_proxy = 43, // The main stage. Assets: pallet_assets:: = 50, From fe69c39325e4cb032a660c3041481b4828228f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 13:11:19 +0100 Subject: [PATCH 12/43] TAPLO --- pallets/remote-proxy/Cargo.toml | 18 +++++++++--------- relay/kusama/Cargo.toml | 2 +- relay/polkadot/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pallets/remote-proxy/Cargo.toml b/pallets/remote-proxy/Cargo.toml index ef95f5119d..e7ef38a20c 100644 --- a/pallets/remote-proxy/Cargo.toml +++ b/pallets/remote-proxy/Cargo.toml @@ -27,7 +27,7 @@ sp-io = { workspace = true } sp-state-machine = { workspace = true } [features] -default = [ "std" ] +default = ["std"] std = [ "codec/std", @@ -36,25 +36,25 @@ std = [ "frame-benchmarking/std", "frame-support/std", "frame-system/std", - "pallet-proxy/std", - "sp-core/std", - "sp-trie/std", - "sp-runtime/std", "pallet-balances/std", + "pallet-proxy/std", "pallet-utility/std", "scale-info/std", + "sp-core/std", "sp-io/std", - "sp-state-machine/std" + "sp-runtime/std", + "sp-state-machine/std", + "sp-trie/std", ] runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-proxy/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", "pallet-utility/runtime-benchmarks", - "cumulus-pallet-parachain-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "cumulus-primitives-core/runtime-benchmarks" ] diff --git a/relay/kusama/Cargo.toml b/relay/kusama/Cargo.toml index 67d68bd3d6..ac43cd1d15 100644 --- a/relay/kusama/Cargo.toml +++ b/relay/kusama/Cargo.toml @@ -212,13 +212,13 @@ std = [ "sp-storage/std", "sp-tracing/std", "sp-transaction-pool/std", + "sp-trie/std", "sp-version/std", "substrate-wasm-builder", "xcm-builder/std", "xcm-executor/std", "xcm-runtime-apis/std", "xcm/std", - "sp-trie/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/relay/polkadot/Cargo.toml b/relay/polkadot/Cargo.toml index 5fc20f28da..315fa6e82b 100644 --- a/relay/polkadot/Cargo.toml +++ b/relay/polkadot/Cargo.toml @@ -214,13 +214,13 @@ std = [ "sp-storage/std", "sp-tracing/std", "sp-transaction-pool/std", + "sp-trie/std", "sp-version/std", "substrate-wasm-builder", "xcm-builder/std", "xcm-executor/std", "xcm-runtime-apis/std", "xcm/std", - "sp-trie/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", From bc69dde1fdcc427e1309eb24decba0fcdb08e232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 13:13:23 +0100 Subject: [PATCH 13/43] MIGHTY CLIPPY PLEASE ACCEPT ME --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index c65c8a62c7..dd70fb0b92 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -364,7 +364,7 @@ pub mod pallet { proxy_definitions .into_iter() - .filter_map(|pd| T::RemoteProxy::remote_to_local_proxy_defintion(pd)) + .filter_map(T::RemoteProxy::remote_to_local_proxy_defintion) .find(f) .ok_or(Error::::DidNotFindMatchingProxyDefinition)? }, From 55f69b1060f151be7284db313c8ab2cbb1bb224d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 16:11:40 +0100 Subject: [PATCH 14/43] Kusama AH implementation --- Cargo.lock | 5 +- relay/kusama/constants/Cargo.toml | 6 ++ relay/kusama/constants/src/lib.rs | 91 +++++++++++++++++++ relay/kusama/src/lib.rs | 51 ++++------- relay/polkadot/constants/src/lib.rs | 2 +- .../asset-hubs/asset-hub-kusama/Cargo.toml | 3 +- .../asset-hubs/asset-hub-kusama/src/lib.rs | 59 ++++++++++-- .../asset-hub-kusama/src/xcm_config.rs | 2 +- 8 files changed, 174 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6e4c6cd8e..4efacf467a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -659,6 +659,7 @@ dependencies = [ "pallet-nfts", "pallet-nfts-runtime-api", "pallet-proxy", + "pallet-remote-proxy", "pallet-session", "pallet-state-trie-migration", "pallet-timestamp", @@ -676,7 +677,6 @@ dependencies = [ "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-runtime-common", - "polkadot-runtime-constants", "primitive-types", "scale-info", "serde_json", @@ -6118,8 +6118,11 @@ name = "kusama-runtime-constants" version = "1.0.0" dependencies = [ "frame-support", + "pallet-remote-proxy", + "parity-scale-codec", "polkadot-primitives 16.0.0", "polkadot-runtime-common", + "scale-info", "smallvec", "sp-core 34.0.0", "sp-runtime 39.0.5", diff --git a/relay/kusama/constants/Cargo.toml b/relay/kusama/constants/Cargo.toml index 1c27740baf..e3e05d76b5 100644 --- a/relay/kusama/constants/Cargo.toml +++ b/relay/kusama/constants/Cargo.toml @@ -8,6 +8,8 @@ license.workspace = true [dependencies] smallvec = { workspace = true } +codec = { workspace = true } +scale-info = { workspace = true } frame-support = { workspace = true } polkadot-primitives = { workspace = true } @@ -15,15 +17,19 @@ polkadot-runtime-common = { workspace = true } sp-runtime = { workspace = true } sp-weights = { workspace = true } sp-core = { workspace = true } +pallet-remote-proxy = { workspace = true } xcm-builder = { workspace = true } [features] default = ["std"] std = [ + "codec/std", "frame-support/std", + "pallet-remote-proxy/std", "polkadot-primitives/std", "polkadot-runtime-common/std", + "scale-info/std", "sp-core/std", "sp-runtime/std", "sp-weights/std", diff --git a/relay/kusama/constants/src/lib.rs b/relay/kusama/constants/src/lib.rs index 1c7049fead..2c31b4ccb6 100644 --- a/relay/kusama/constants/src/lib.rs +++ b/relay/kusama/constants/src/lib.rs @@ -134,6 +134,97 @@ pub mod system_parachain { /// Kusama Treasury pallet instance. pub const TREASURY_PALLET_ID: u8 = 18; +pub mod proxy { + use pallet_remote_proxy::ProxyDefinition; + use polkadot_primitives::{AccountId, BlakeTwo256, BlockNumber, Hash}; + use sp_runtime::traits::Convert; + + /// The type used to represent the kinds of proxying allowed. + #[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + codec::Encode, + codec::Decode, + codec::MaxEncodedLen, + core::fmt::Debug, + scale_info::TypeInfo, + Default, + )] + pub enum ProxyType { + #[codec(index = 0)] + #[default] + Any, + #[codec(index = 1)] + NonTransfer, + #[codec(index = 2)] + Governance, + #[codec(index = 3)] + Staking, + // Index 4 skipped. Formerly `IdentityJudgement`. + #[codec(index = 5)] + CancelProxy, + #[codec(index = 6)] + Auction, + #[codec(index = 7)] + Society, + #[codec(index = 8)] + NominationPools, + #[codec(index = 9)] + Spokesperson, + #[codec(index = 10)] + ParaRegistration, + } + + /// Remote proxy interface that uses the relay chain as remote location. + pub struct RemoteProxyInterface( + core::marker::PhantomData<(LocalProxyType, ProxyDefinitionConverter)>, + ); + + impl< + LocalProxyType, + ProxyDefinitionConverter: Convert< + ProxyDefinition, + Option>, + >, + > pallet_remote_proxy::RemoteProxyInterface + for RemoteProxyInterface + { + type RemoteAccountId = AccountId; + + type RemoteProxyType = ProxyType; + + type RemoteBlockNumber = BlockNumber; + + type Hash = Hash; + + type Hasher = BlakeTwo256; + + fn block_to_storage_root( + validation_data: &polkadot_primitives::PersistedValidationData, + ) -> Option<(Self::RemoteBlockNumber, ::Out)> { + Some((validation_data.relay_parent_number, validation_data.relay_parent_storage_root)) + } + + fn local_to_remote_account_id(local: &AccountId) -> Option { + Some(local.clone()) + } + + fn remote_to_local_proxy_defintion( + remote: ProxyDefinition< + Self::RemoteAccountId, + Self::RemoteProxyType, + Self::RemoteBlockNumber, + >, + ) -> Option> { + ProxyDefinitionConverter::convert(remote) + } + } +} + #[cfg(test)] mod tests { use super::{ diff --git a/relay/kusama/src/lib.rs b/relay/kusama/src/lib.rs index 5252cf8728..2f7fb8c5d7 100644 --- a/relay/kusama/src/lib.rs +++ b/relay/kusama/src/lib.rs @@ -28,7 +28,7 @@ use frame_support::{ traits::EnsureOriginWithArg, weights::constants::{WEIGHT_PROOF_SIZE_PER_KB, WEIGHT_REF_TIME_PER_MICROS}, }; -use kusama_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD; +use kusama_runtime_constants::{proxy::ProxyType, system_parachain::coretime::TIMESLICE_PERIOD}; use pallet_nis::WithMaximumOf; use polkadot_primitives::{ slashing, AccountId, AccountIndex, ApprovalVotingParams, Balance, BlockNumber, CandidateEvent, @@ -1109,7 +1109,10 @@ parameter_types! { pub const MaxPending: u16 = 32; } -/// The type used to represent the kinds of proxying allowed. +/// Transparent wrapper around the actual [`ProxyType`]. +/// +/// This is done to have [`ProxyType`] declared in a different crate (constants) and being able to +/// implement [`InstanceFilter`] in this crate. #[derive( Copy, Clone, @@ -1121,41 +1124,21 @@ parameter_types! { Decode, RuntimeDebug, MaxEncodedLen, - TypeInfo, + Default, )] -pub enum ProxyType { - #[codec(index = 0)] - Any, - #[codec(index = 1)] - NonTransfer, - #[codec(index = 2)] - Governance, - #[codec(index = 3)] - Staking, - // Index 4 skipped. Formerly `IdentityJudgement`. - #[codec(index = 5)] - CancelProxy, - #[codec(index = 6)] - Auction, - #[codec(index = 7)] - Society, - #[codec(index = 8)] - NominationPools, - #[codec(index = 9)] - Spokesperson, - #[codec(index = 10)] - ParaRegistration, -} - -impl Default for ProxyType { - fn default() -> Self { - Self::Any +pub struct TransparentProxyType(ProxyType); + +impl scale_info::TypeInfo for TransparentProxyType { + type Identity = ::Identity; + + fn type_info() -> scale_info::Type { + ProxyType::type_info() } } -impl InstanceFilter for ProxyType { +impl InstanceFilter for TransparentProxyType { fn filter(&self, c: &RuntimeCall) -> bool { - match self { + match self.0 { ProxyType::Any => true, ProxyType::NonTransfer => matches!( c, @@ -1261,7 +1244,7 @@ impl InstanceFilter for ProxyType { } } fn is_superset(&self, o: &Self) -> bool { - match (self, o) { + match (self.0, o.0) { (x, y) if x == y => true, (ProxyType::Any, _) => true, (_, ProxyType::Any) => false, @@ -1275,7 +1258,7 @@ impl pallet_proxy::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; type Currency = Balances; - type ProxyType = ProxyType; + type ProxyType = TransparentProxyType; type ProxyDepositBase = ProxyDepositBase; type ProxyDepositFactor = ProxyDepositFactor; type MaxProxies = MaxProxies; diff --git a/relay/polkadot/constants/src/lib.rs b/relay/polkadot/constants/src/lib.rs index 368ed30df1..a9111bfc3b 100644 --- a/relay/polkadot/constants/src/lib.rs +++ b/relay/polkadot/constants/src/lib.rs @@ -167,7 +167,7 @@ pub mod proxy { PartialOrd, codec::Encode, codec::Decode, - sp_runtime::RuntimeDebug, + core::fmt::Debug, codec::MaxEncodedLen, scale_info::TypeInfo, Default, diff --git a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml index 637720d361..0288f2433a 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml @@ -21,7 +21,7 @@ bp-asset-hub-polkadot = { workspace = true } bp-bridge-hub-kusama = { workspace = true } bp-bridge-hub-polkadot = { workspace = true } kusama-runtime-constants = { workspace = true } -polkadot-runtime-constants = { workspace = true } +pallet-remote-proxy = { workspace = true } # Substrate frame-benchmarking = { optional = true, workspace = true } @@ -246,7 +246,6 @@ std = [ "polkadot-core-primitives/std", "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", - "polkadot-runtime-constants/std", "primitive-types/std", "scale-info/std", "serde_json/std", diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 97e8a256e2..89d283bbcb 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -38,12 +38,15 @@ use assets_common::{ }; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; +use kusama_runtime_constants::time::MINUTES; +use pallet_proxy::ProxyDefinition; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ - AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify, + AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, ConvertInto, + Verify, }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Permill, @@ -519,9 +522,11 @@ parameter_types! { RuntimeDebug, MaxEncodedLen, scale_info::TypeInfo, + Default, )] pub enum ProxyType { /// Fully permissioned proxy. Can execute any call on behalf of _proxied_. + #[default] Any, /// Can execute any call that does not transfer funds or assets. NonTransfer, @@ -536,11 +541,6 @@ pub enum ProxyType { /// Collator selection proxy. Can execute calls related to collator selection mechanism. Collator, } -impl Default for ProxyType { - fn default() -> Self { - Self::Any - } -} impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { @@ -964,6 +964,52 @@ impl pallet_xcm_bridge_hub_router::Config for Runti cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; } +/// Converts from the relay chain proxy type to the local proxy type. +pub struct RelayChainToLocalProxyTypeConverter; + +impl + Convert< + ProxyDefinition, + Option>, + > for RelayChainToLocalProxyTypeConverter +{ + fn convert( + a: ProxyDefinition, + ) -> Option> { + let proxy_type = match a.proxy_type { + kusama_runtime_constants::proxy::ProxyType::Any => ProxyType::Any, + kusama_runtime_constants::proxy::ProxyType::NonTransfer => ProxyType::NonTransfer, + kusama_runtime_constants::proxy::ProxyType::CancelProxy => ProxyType::CancelProxy, + // Proxy types that are not supported on AH. + kusama_runtime_constants::proxy::ProxyType::Governance | + kusama_runtime_constants::proxy::ProxyType::Staking | + kusama_runtime_constants::proxy::ProxyType::Auction | + kusama_runtime_constants::proxy::ProxyType::Spokesperson | + kusama_runtime_constants::proxy::ProxyType::NominationPools | + kusama_runtime_constants::proxy::ProxyType::Society | + kusama_runtime_constants::proxy::ProxyType::ParaRegistration => return None, + }; + + Some(ProxyDefinition { + delegate: a.delegate, + proxy_type, + // Delays are currently not supported by the remote proxy pallet, but should be + // converted in the future to the block time used by the local proxy pallet. + delay: a.delay, + }) + } +} + +impl pallet_remote_proxy::Config for Runtime { + type MaxStorageRootsToKeep = ConstU32<{ MINUTES * 20 }>; + type RemoteProxy = kusama_runtime_constants::proxy::RemoteProxyInterface< + ProxyType, + RelayChainToLocalProxyTypeConverter, + >; + //TODO: Run benchmarks and replace. + type WeightInfo = (); +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -1000,6 +1046,7 @@ construct_runtime!( Utility: pallet_utility = 40, Multisig: pallet_multisig = 41, Proxy: pallet_proxy = 42, + RemoteProxyRelayChain: pallet_remote_proxy = 43, // The main stage. Assets: pallet_assets:: = 50, diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs index 4380ba988b..56e5dae3f4 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs @@ -521,7 +521,7 @@ pub mod bridging { 2, [ GlobalConsensus(PolkadotNetwork::get()), - Parachain(polkadot_runtime_constants::system_parachain::ASSET_HUB_ID), + Parachain(kusama_runtime_constants::system_parachain::ASSET_HUB_ID), ], ); From 7c24ca6049a7af65dac4455c0459e879043c5afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 20:44:18 +0100 Subject: [PATCH 15/43] Make CI happy --- pallets/remote-proxy/Cargo.toml | 2 ++ system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pallets/remote-proxy/Cargo.toml b/pallets/remote-proxy/Cargo.toml index e7ef38a20c..79b1510d36 100644 --- a/pallets/remote-proxy/Cargo.toml +++ b/pallets/remote-proxy/Cargo.toml @@ -47,6 +47,8 @@ std = [ "sp-trie/std", ] +try-runtime = [] + runtime-benchmarks = [ "cumulus-pallet-parachain-system/runtime-benchmarks", "cumulus-primitives-core/runtime-benchmarks", diff --git a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml index 0288f2433a..2246a25ca1 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml @@ -157,6 +157,7 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", + "pallet-remote-proxy/runtime-benchmarks" ] try-runtime = [ "cumulus-pallet-aura-ext/try-runtime", @@ -270,6 +271,7 @@ std = [ "xcm-executor/std", "xcm-runtime-apis/std", "xcm/std", + "pallet-remote-proxy/std" ] # Enable metadata hash generation at compile time for the `CheckMetadataHash` extension. From 7a85c61713c181b810a15c8be6d5026cbe2c183a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 20:59:43 +0100 Subject: [PATCH 16/43] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efc2200872..27acfb12e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - ParaRegistration proxy for Polkadot and Kusama ([polkadot-fellows/runtimes#520](https://github.com/polkadot-fellows/runtimes/pull/520)) +- Adds support for remote proxies on AssetHub Polkadot and AssetHub Kusama ([polkadot-fellows/runtimes#535](https://github.com/polkadot-fellows/runtimes/pull/535)) + ### Changed - Kusama Treasury: remove funding to the Kappa Sigma Mu Society and disable burn ([polkadot-fellows/runtimes#507](https://github.com/polkadot-fellows/runtimes/pull/507)) From 721d437ab0832f3b0ed7640263b2639e0543c481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 21:04:33 +0100 Subject: [PATCH 17/43] Hmm :see_no_evil: --- pallets/remote-proxy/Cargo.toml | 10 +++++++++- .../asset-hubs/asset-hub-kusama/Cargo.toml | 5 +++-- .../asset-hubs/asset-hub-polkadot/Cargo.toml | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pallets/remote-proxy/Cargo.toml b/pallets/remote-proxy/Cargo.toml index 79b1510d36..0ef8d62252 100644 --- a/pallets/remote-proxy/Cargo.toml +++ b/pallets/remote-proxy/Cargo.toml @@ -47,7 +47,15 @@ std = [ "sp-trie/std", ] -try-runtime = [] +try-runtime = [ + "cumulus-pallet-parachain-system/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-balances/try-runtime", + "pallet-proxy/try-runtime", + "pallet-utility/try-runtime", + "sp-runtime/try-runtime", +] runtime-benchmarks = [ "cumulus-pallet-parachain-system/runtime-benchmarks", diff --git a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml index 2246a25ca1..3ebefc1784 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml @@ -141,6 +141,7 @@ runtime-benchmarks = [ "pallet-nft-fractionalization/runtime-benchmarks", "pallet-nfts/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", + "pallet-remote-proxy/runtime-benchmarks", "pallet-state-trie-migration/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", @@ -157,7 +158,6 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", - "pallet-remote-proxy/runtime-benchmarks" ] try-runtime = [ "cumulus-pallet-aura-ext/try-runtime", @@ -180,6 +180,7 @@ try-runtime = [ "pallet-nft-fractionalization/try-runtime", "pallet-nfts/try-runtime", "pallet-proxy/try-runtime", + "pallet-remote-proxy/try-runtime", "pallet-session/try-runtime", "pallet-state-trie-migration/try-runtime", "pallet-timestamp/try-runtime", @@ -231,6 +232,7 @@ std = [ "pallet-nfts-runtime-api/std", "pallet-nfts/std", "pallet-proxy/std", + "pallet-remote-proxy/std", "pallet-session/std", "pallet-state-trie-migration/std", "pallet-timestamp/std", @@ -271,7 +273,6 @@ std = [ "xcm-executor/std", "xcm-runtime-apis/std", "xcm/std", - "pallet-remote-proxy/std" ] # Enable metadata hash generation at compile time for the `CheckMetadataHash` extension. diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 3e17406b36..0c40308bf8 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -171,6 +171,7 @@ try-runtime = [ "pallet-multisig/try-runtime", "pallet-nfts/try-runtime", "pallet-proxy/try-runtime", + "pallet-remote-proxy/try-runtime", "pallet-session/try-runtime", "pallet-timestamp/try-runtime", "pallet-transaction-payment/try-runtime", From 6acd4bd25749c81a34004728a4e38b168489a5d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 16 Jan 2025 21:05:22 +0100 Subject: [PATCH 18/43] ............ --- pallets/remote-proxy/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index 5feba5d40d..e8560038d8 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -149,7 +149,7 @@ impl crate::RemoteProxyInterface for RemoteProxyImpl { } fn local_to_remote_account_id(local: &u64) -> Option { - Some(local.clone()) + Some(*local) } fn remote_to_local_proxy_defintion( From 8bffc523988ce65aeb3b207dfab2c6fdf6685549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 27 Jan 2025 12:35:20 +0100 Subject: [PATCH 19/43] Disable the Polkadot integration --- Cargo.lock | 1 - .../asset-hubs/asset-hub-polkadot/Cargo.toml | 4 -- .../asset-hubs/asset-hub-polkadot/src/lib.rs | 45 ------------------- 3 files changed, 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4efacf467a..e031bc5cea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,7 +794,6 @@ dependencies = [ "pallet-nfts", "pallet-nfts-runtime-api", "pallet-proxy", - "pallet-remote-proxy", "pallet-session", "pallet-timestamp", "pallet-transaction-payment", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 0c40308bf8..1f207ce943 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -23,7 +23,6 @@ bp-bridge-hub-polkadot = { workspace = true } collectives-polkadot-runtime-constants = { workspace = true } kusama-runtime-constants = { workspace = true } polkadot-runtime-constants = { workspace = true } -pallet-remote-proxy = { workspace = true } # Substrate frame-benchmarking = { optional = true, workspace = true } @@ -134,7 +133,6 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-nfts/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", - "pallet-remote-proxy/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", @@ -171,7 +169,6 @@ try-runtime = [ "pallet-multisig/try-runtime", "pallet-nfts/try-runtime", "pallet-proxy/try-runtime", - "pallet-remote-proxy/try-runtime", "pallet-session/try-runtime", "pallet-timestamp/try-runtime", "pallet-transaction-payment/try-runtime", @@ -221,7 +218,6 @@ std = [ "pallet-nfts-runtime-api/std", "pallet-nfts/std", "pallet-proxy/std", - "pallet-remote-proxy/std", "pallet-session/std", "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 39ff35e747..55fd25dfd7 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -958,50 +958,6 @@ impl pallet_asset_conversion::Config for Runtime { >; } -/// Converts from the relay chain proxy type to the local proxy type. -pub struct RelayChainToLocalProxyTypeConverter; - -impl - Convert< - ProxyDefinition, - Option>, - > for RelayChainToLocalProxyTypeConverter -{ - fn convert( - a: ProxyDefinition, - ) -> Option> { - let proxy_type = match a.proxy_type { - polkadot_runtime_constants::proxy::ProxyType::Any => ProxyType::Any, - polkadot_runtime_constants::proxy::ProxyType::NonTransfer => ProxyType::NonTransfer, - // Proxy types that are not supported on AH. - polkadot_runtime_constants::proxy::ProxyType::Governance | - polkadot_runtime_constants::proxy::ProxyType::Staking | - polkadot_runtime_constants::proxy::ProxyType::CancelProxy | - polkadot_runtime_constants::proxy::ProxyType::Auction | - polkadot_runtime_constants::proxy::ProxyType::NominationPools | - polkadot_runtime_constants::proxy::ProxyType::ParaRegistration => return None, - }; - - Some(ProxyDefinition { - delegate: a.delegate, - proxy_type, - // Delays are currently not supported by the remote proxy pallet, but should be - // converted in the future to the block time used by the local proxy pallet. - delay: a.delay, - }) - } -} - -impl pallet_remote_proxy::Config for Runtime { - type MaxStorageRootsToKeep = ConstU32<{ MINUTES * 20 }>; - type RemoteProxy = polkadot_runtime_constants::proxy::RemoteProxyInterface< - ProxyType, - RelayChainToLocalProxyTypeConverter, - >; - //TODO: Run benchmarks and replace. - type WeightInfo = (); -} - // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -1038,7 +994,6 @@ construct_runtime!( Utility: pallet_utility = 40, Multisig: pallet_multisig = 41, Proxy: pallet_proxy = 42, - RemoteProxyRelayChain: pallet_remote_proxy = 43, // The main stage. Assets: pallet_assets:: = 50, From de469a17b5b0274fc72ad5ecabfd96191708ca81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 27 Jan 2025 14:44:44 +0100 Subject: [PATCH 20/43] Docs --- pallets/remote-proxy/src/lib.rs | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index dd70fb0b92..e60d87b169 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -14,6 +14,39 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +//! Remote proxy pallet +//! +//! The pallet provides the functionality for using a proxy on a remote chain. The exact remote +//! location of the proxy depends on the [`RemoteProxyInterface`] implementation provided to this +//! pallet. The underlying implementation works by verifying proofs from the remote location that +//! prove the existence of a proxy. The remote proof is verified against a storage root from the +//! remote location. These storage roots are extracted from the relay chain. So, the security +//! of the proxy depends on the remote location. This means that the remote location should be a +//! trusted chain that for example doesn't create fake proxies. +//! +//! ## Functions +//! +//! The pallet provides the following functions: +//! +//! - [`Pallet::remote_proxy`]: Dispatch a wrapped call using the given proof over the existence of +//! a remote proxy. +//! +//! - [`Pallet::register_remote_proxy_proof`]: Register the given `proof` in the current dispatch. +//! +//! - [`Pallet::remote_proxy_with_registered_proof`]: Use a previously registered `proof` to +//! dispatch the wrapped call. +//! +//! ## Security considerations +//! +//! As explained above the security of the proxy depends on the remote location. So, if the remote +//! location is not trusted, it should not be configured as remote location. When configuring +//! [`MaxStorageRootsToKeep`](Config::MaxStorageRootsToKeep) it should be considered that the +//! lifetime of a proxy will be [`MaxStorageRootsToKeep`](Config::MaxStorageRootsToKeep) in the +//! past. This means when deleting a proxy at the remote location at X, it will take +//! [`MaxStorageRootsToKeep`](Config::MaxStorageRootsToKeep) time until the proxy can not be used +//! anymore. The reason for this is that the caller will be able to provide an old `proof` at which +//! the proxy was still available. + #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; @@ -253,6 +286,23 @@ pub mod pallet { /// /// It is supported to register multiple proofs, but the proofs need to be consumed in the /// reverse order as they were registered. Basically this means last in, last out. + /// + /// The [`dispatch_context`] spans the entire lifetime of a transaction and every call in + /// the transaction gets access to the same context. + /// + /// # Example + /// + /// ``` + /// batch([ + /// register_remote_proxy_proof, + /// as_multisig(remote_proxy_with_registered_proof(transfer)) + /// ]) + /// ``` + /// + /// As `proofs` can not be verified indefinitely (the time the storage roots are stored is + /// limited) this function provides the possibility to provide a "fresh proof" at time of + /// dispatch. As in the example above, this could be useful for multisig operation that + /// depend on multiple members to approve a certain action, which can take multiple days. #[pallet::call_index(1)] #[pallet::weight({(WeightInfoOf::::register_remote_proxy_proof(), DispatchClass::Normal)})] pub fn register_remote_proxy_proof( From c72658de48919ed4ee96410acecce80d92ef5630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 28 Jan 2025 21:05:08 +0100 Subject: [PATCH 21/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Xiliang Chen --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index e60d87b169..7da8b133dd 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -285,7 +285,7 @@ pub mod pallet { /// members to approve the call in [`Config::MaxStorageRootsToKeep`] amount of time. /// /// It is supported to register multiple proofs, but the proofs need to be consumed in the - /// reverse order as they were registered. Basically this means last in, last out. + /// reverse order as they were registered. Basically this means last in, first out. /// /// The [`dispatch_context`] spans the entire lifetime of a transaction and every call in /// the transaction gets access to the same context. From c8f1c0b8226346f80cbc0bc3fb5668b8d04f3023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 29 Jan 2025 13:22:38 +0100 Subject: [PATCH 22/43] Review comments --- CHANGELOG.md | 2 +- pallets/remote-proxy/src/weight.rs | 6 +++--- system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs | 5 +++-- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 2 -- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d760c4e71..d7a49337f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Delegate stake pools in Kusama ([polkadot-fellows/runtimes#540](https://github.com/polkadot-fellows/runtimes/pull/540)) -- Adds support for remote proxies on AssetHub Polkadot and AssetHub Kusama ([polkadot-fellows/runtimes#535](https://github.com/polkadot-fellows/runtimes/pull/535)) +- Adds support for remote proxies on AssetHub Polkadot and AssetHub Kusama. ‼️ Builders: Please read the docs and the implications around the lifetime of a proxy on a remote chain. ‼️ ([polkadot-fellows/runtimes#535](https://github.com/polkadot-fellows/runtimes/pull/535)) ### Changed diff --git a/pallets/remote-proxy/src/weight.rs b/pallets/remote-proxy/src/weight.rs index 738eeab820..2c0f67d735 100644 --- a/pallets/remote-proxy/src/weight.rs +++ b/pallets/remote-proxy/src/weight.rs @@ -25,14 +25,14 @@ pub trait WeightInfo { impl WeightInfo for () { fn remote_proxy_with_registered_proof() -> Weight { - Weight::zero() + Weight::MAX } fn register_remote_proxy_proof() -> Weight { - Weight::zero() + Weight::MAX } fn remote_proxy() -> Weight { - Weight::zero() + Weight::MAX } } diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 541f8b54da..f4bef77579 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -38,7 +38,7 @@ use assets_common::{ }; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; -use kusama_runtime_constants::time::MINUTES; +use kusama_runtime_constants::time::MINUTES as RC_MINUTES; use pallet_proxy::ProxyDefinition; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; @@ -1003,7 +1003,8 @@ impl } impl pallet_remote_proxy::Config for Runtime { - type MaxStorageRootsToKeep = ConstU32<{ MINUTES * 20 }>; + // The time between creating a proof and using the proof in a transaction. + type MaxStorageRootsToKeep = ConstU32<{ RC_MINUTES * 1 }>; type RemoteProxy = kusama_runtime_constants::proxy::RemoteProxyInterface< ProxyType, RelayChainToLocalProxyTypeConverter, diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index a4d09d743e..4b234ddb5b 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -73,8 +73,6 @@ use assets_common::{ }; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; -use pallet_proxy::ProxyDefinition; -use polkadot_runtime_constants::time::MINUTES; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, ConstU128, OpaqueMetadata}; use sp_runtime::{ From be6eb4559a38bb0e052fd2d522a14a10116dba15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 29 Jan 2025 21:26:28 +0100 Subject: [PATCH 23/43] Fix warning --- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 4b234ddb5b..dc045e463b 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -77,7 +77,7 @@ use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, ConstU128, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, ConvertInto, Verify}, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Permill, }; From ae39e244cf1c65a10a04d01b9139cca6886e7b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 29 Jan 2025 22:14:14 +0100 Subject: [PATCH 24/43] Yes clippy --- system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index f4bef77579..9ce6c16801 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -1004,7 +1004,7 @@ impl impl pallet_remote_proxy::Config for Runtime { // The time between creating a proof and using the proof in a transaction. - type MaxStorageRootsToKeep = ConstU32<{ RC_MINUTES * 1 }>; + type MaxStorageRootsToKeep = ConstU32<{ RC_MINUTES }>; type RemoteProxy = kusama_runtime_constants::proxy::RemoteProxyInterface< ProxyType, RelayChainToLocalProxyTypeConverter, From 64974770725dd0a63f66060f8d3d1215716261fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 30 Jan 2025 17:00:29 +0100 Subject: [PATCH 25/43] Fix the benchmarks --- Cargo.lock | 3 ++- relay/kusama/constants/Cargo.toml | 5 +++++ relay/kusama/constants/src/lib.rs | 32 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 64e167b0e6..1da5025948 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -6129,6 +6129,7 @@ dependencies = [ "smallvec", "sp-core 34.0.0", "sp-runtime 39.0.5", + "sp-trie 37.0.0", "sp-weights 31.0.0", "staging-xcm-builder", ] diff --git a/relay/kusama/constants/Cargo.toml b/relay/kusama/constants/Cargo.toml index e3e05d76b5..794d2ed8b8 100644 --- a/relay/kusama/constants/Cargo.toml +++ b/relay/kusama/constants/Cargo.toml @@ -17,6 +17,7 @@ polkadot-runtime-common = { workspace = true } sp-runtime = { workspace = true } sp-weights = { workspace = true } sp-core = { workspace = true } +sp-trie = { workspace = true, optional = true } pallet-remote-proxy = { workspace = true } xcm-builder = { workspace = true } @@ -36,3 +37,7 @@ std = [ "xcm-builder/std", ] fast-runtime = [] +runtime-benchmarks = [ + "sp-trie", + "pallet-remote-proxy/runtime-benchmarks", +] diff --git a/relay/kusama/constants/src/lib.rs b/relay/kusama/constants/src/lib.rs index 2c31b4ccb6..3e274b730d 100644 --- a/relay/kusama/constants/src/lib.rs +++ b/relay/kusama/constants/src/lib.rs @@ -222,6 +222,38 @@ pub mod proxy { ) -> Option> { ProxyDefinitionConverter::convert(remote) } + + #[cfg(feature = "runtime-benchmarks")] + fn create_remote_proxy_proof( + caller: &AccountId, + proxy: &AccountId, + ) -> (pallet_remote_proxy::RemoteProxyProof, BlockNumber, Hash) { + use codec::Encode; + use sp_trie::TrieMut; + + let (mut db, mut root) = sp_trie::MemoryDB::::default_with_root(); + let mut trie = + sp_trie::TrieDBMutBuilder::>::new(&mut db, &mut root).build(); + + let proxy_definition = vec![ProxyDefinition:: { + delegate: caller.clone(), + proxy_type: ProxyType::default(), + delay: 0, + }]; + + trie.insert(&Self::proxy_definition_storage_key(proxy), &proxy_definition.encode()) + .unwrap(); + drop(trie); + + ( + pallet_remote_proxy::RemoteProxyProof::RelayChain { + proof: db.drain().into_values().map(|d| d.0).collect(), + block: 1, + }, + 1, + root, + ) + } } } From cbef781e3e67fd8185f9ad7b30066ad1cad213c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 31 Jan 2025 12:07:11 +0100 Subject: [PATCH 26/43] More fixes --- Cargo.lock | 1 + relay/kusama/Cargo.toml | 1 + relay/kusama/constants/Cargo.toml | 8 ++++- relay/kusama/constants/src/lib.rs | 13 ++++--- relay/polkadot/Cargo.toml | 1 + relay/polkadot/constants/Cargo.toml | 11 ++++++ relay/polkadot/constants/src/lib.rs | 35 +++++++++++++++++++ .../asset-hubs/asset-hub-kusama/Cargo.toml | 1 + .../asset-hubs/asset-hub-polkadot/Cargo.toml | 2 ++ .../bridge-hubs/bridge-hub-kusama/Cargo.toml | 2 ++ .../bridge-hub-polkadot/Cargo.toml | 2 ++ .../collectives-polkadot/Cargo.toml | 1 + .../coretime/coretime-kusama/Cargo.toml | 1 + .../coretime/coretime-polkadot/Cargo.toml | 1 + system-parachains/encointer/Cargo.toml | 1 + .../people/people-kusama/Cargo.toml | 1 + .../people/people-polkadot/Cargo.toml | 1 + 17 files changed, 77 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1da5025948..7f4ec55c78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10239,6 +10239,7 @@ dependencies = [ "smallvec", "sp-core 34.0.0", "sp-runtime 39.0.5", + "sp-trie 37.0.0", "sp-weights 31.0.0", "staging-xcm-builder", ] diff --git a/relay/kusama/Cargo.toml b/relay/kusama/Cargo.toml index ac43cd1d15..05a3dc9f05 100644 --- a/relay/kusama/Cargo.toml +++ b/relay/kusama/Cargo.toml @@ -226,6 +226,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "kusama-runtime-constants/runtime-benchmarks", "pallet-asset-rate/runtime-benchmarks", "pallet-babe/runtime-benchmarks", "pallet-bags-list/runtime-benchmarks", diff --git a/relay/kusama/constants/Cargo.toml b/relay/kusama/constants/Cargo.toml index 794d2ed8b8..d696045292 100644 --- a/relay/kusama/constants/Cargo.toml +++ b/relay/kusama/constants/Cargo.toml @@ -33,11 +33,17 @@ std = [ "scale-info/std", "sp-core/std", "sp-runtime/std", + "sp-trie?/std", "sp-weights/std", "xcm-builder/std", ] fast-runtime = [] runtime-benchmarks = [ - "sp-trie", + "frame-support/runtime-benchmarks", "pallet-remote-proxy/runtime-benchmarks", + "polkadot-primitives/runtime-benchmarks", + "polkadot-runtime-common/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "sp-trie", + "xcm-builder/runtime-benchmarks", ] diff --git a/relay/kusama/constants/src/lib.rs b/relay/kusama/constants/src/lib.rs index 3e274b730d..d3599de887 100644 --- a/relay/kusama/constants/src/lib.rs +++ b/relay/kusama/constants/src/lib.rs @@ -16,6 +16,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + pub mod weights; /// Money matters. @@ -235,11 +237,12 @@ pub mod proxy { let mut trie = sp_trie::TrieDBMutBuilder::>::new(&mut db, &mut root).build(); - let proxy_definition = vec![ProxyDefinition:: { - delegate: caller.clone(), - proxy_type: ProxyType::default(), - delay: 0, - }]; + let proxy_definition = + alloc::vec![ProxyDefinition:: { + delegate: caller.clone(), + proxy_type: ProxyType::default(), + delay: 0, + }]; trie.insert(&Self::proxy_definition_storage_key(proxy), &proxy_definition.encode()) .unwrap(); diff --git a/relay/polkadot/Cargo.toml b/relay/polkadot/Cargo.toml index 315fa6e82b..9ff7367362 100644 --- a/relay/polkadot/Cargo.toml +++ b/relay/polkadot/Cargo.toml @@ -267,6 +267,7 @@ runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", "runtime-parachains/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "sp-staking/runtime-benchmarks", diff --git a/relay/polkadot/constants/Cargo.toml b/relay/polkadot/constants/Cargo.toml index fd0893aa50..708a983635 100644 --- a/relay/polkadot/constants/Cargo.toml +++ b/relay/polkadot/constants/Cargo.toml @@ -18,6 +18,7 @@ polkadot-runtime-common = { workspace = true } sp-runtime = { workspace = true } sp-weights = { workspace = true } sp-core = { workspace = true } +sp-trie = { workspace = true, optional = true } xcm-builder = { workspace = true } @@ -32,7 +33,17 @@ std = [ "scale-info/std", "sp-core/std", "sp-runtime/std", + "sp-trie?/std", "sp-weights/std", "xcm-builder/std", ] fast-runtime = [] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "pallet-remote-proxy/runtime-benchmarks", + "polkadot-primitives/runtime-benchmarks", + "polkadot-runtime-common/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "sp-trie", + "xcm-builder/runtime-benchmarks", +] diff --git a/relay/polkadot/constants/src/lib.rs b/relay/polkadot/constants/src/lib.rs index a9111bfc3b..58daee9b6e 100644 --- a/relay/polkadot/constants/src/lib.rs +++ b/relay/polkadot/constants/src/lib.rs @@ -16,6 +16,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + pub mod weights; pub use self::currency::DOLLARS; @@ -229,6 +231,39 @@ pub mod proxy { ) -> Option> { ProxyDefinitionConverter::convert(remote) } + + #[cfg(feature = "runtime-benchmarks")] + fn create_remote_proxy_proof( + caller: &AccountId, + proxy: &AccountId, + ) -> (pallet_remote_proxy::RemoteProxyProof, BlockNumber, Hash) { + use codec::Encode; + use sp_trie::TrieMut; + + let (mut db, mut root) = sp_trie::MemoryDB::::default_with_root(); + let mut trie = + sp_trie::TrieDBMutBuilder::>::new(&mut db, &mut root).build(); + + let proxy_definition = + alloc::vec![ProxyDefinition:: { + delegate: caller.clone(), + proxy_type: ProxyType::default(), + delay: 0, + }]; + + trie.insert(&Self::proxy_definition_storage_key(proxy), &proxy_definition.encode()) + .unwrap(); + drop(trie); + + ( + pallet_remote_proxy::RemoteProxyProof::RelayChain { + proof: db.drain().into_values().map(|d| d.0).collect(), + block: 1, + }, + 1, + root, + ) + } } } diff --git a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml index 3ebefc1784..cf363e4db3 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml @@ -132,6 +132,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "kusama-runtime-constants/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 1f207ce943..c9785d3c53 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -125,6 +125,7 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "hex-literal", + "kusama-runtime-constants/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -143,6 +144,7 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", "snowbridge-router-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml index e61468c8de..4d3202d932 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml @@ -216,6 +216,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "kusama-runtime-constants/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-bridge-grandpa/runtime-benchmarks", "pallet-bridge-messages/runtime-benchmarks", @@ -232,6 +233,7 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml index 75598dc389..d50d4e38c2 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml @@ -240,6 +240,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "kusama-runtime-constants/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-bridge-grandpa/runtime-benchmarks", "pallet-bridge-messages/runtime-benchmarks", @@ -256,6 +257,7 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", "snowbridge-pallet-ethereum-client-fixtures/runtime-benchmarks", "snowbridge-pallet-ethereum-client/runtime-benchmarks", diff --git a/system-parachains/collectives/collectives-polkadot/Cargo.toml b/system-parachains/collectives/collectives-polkadot/Cargo.toml index 87aeeac0f1..53828ed84c 100644 --- a/system-parachains/collectives/collectives-polkadot/Cargo.toml +++ b/system-parachains/collectives/collectives-polkadot/Cargo.toml @@ -128,6 +128,7 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", diff --git a/system-parachains/coretime/coretime-kusama/Cargo.toml b/system-parachains/coretime/coretime-kusama/Cargo.toml index 618dbf9276..5c359cbe65 100644 --- a/system-parachains/coretime/coretime-kusama/Cargo.toml +++ b/system-parachains/coretime/coretime-kusama/Cargo.toml @@ -161,6 +161,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "kusama-runtime-constants/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-broker/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", diff --git a/system-parachains/coretime/coretime-polkadot/Cargo.toml b/system-parachains/coretime/coretime-polkadot/Cargo.toml index 91ef384c04..c40d9f46c0 100644 --- a/system-parachains/coretime/coretime-polkadot/Cargo.toml +++ b/system-parachains/coretime/coretime-polkadot/Cargo.toml @@ -176,6 +176,7 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", diff --git a/system-parachains/encointer/Cargo.toml b/system-parachains/encointer/Cargo.toml index a6888efe7a..bf1e8402ee 100644 --- a/system-parachains/encointer/Cargo.toml +++ b/system-parachains/encointer/Cargo.toml @@ -127,6 +127,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "kusama-runtime-constants/runtime-benchmarks", "pallet-asset-tx-payment/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", diff --git a/system-parachains/people/people-kusama/Cargo.toml b/system-parachains/people/people-kusama/Cargo.toml index 01005c4ad0..e16508171f 100644 --- a/system-parachains/people/people-kusama/Cargo.toml +++ b/system-parachains/people/people-kusama/Cargo.toml @@ -161,6 +161,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "kusama-runtime-constants/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "pallet-identity/runtime-benchmarks", diff --git a/system-parachains/people/people-polkadot/Cargo.toml b/system-parachains/people/people-polkadot/Cargo.toml index 6826c46ac1..501749e9e3 100644 --- a/system-parachains/people/people-polkadot/Cargo.toml +++ b/system-parachains/people/people-polkadot/Cargo.toml @@ -172,6 +172,7 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", From 2f439f54cbb7ea9467c2bc768b6481b36fffd85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 31 Jan 2025 12:32:46 +0100 Subject: [PATCH 27/43] Embarrassing --- system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 9ce6c16801..dfd4a3f223 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -683,7 +683,7 @@ parameter_types! { impl cumulus_pallet_parachain_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type OnSystemEvent = (); + type OnSystemEvent = RemoteProxyRelayChain; type SelfParaId = parachain_info::Pallet; type DmpQueue = frame_support::traits::EnqueueWithOrigin; type ReservedDmpWeight = ReservedDmpWeight; From 17d82b4f114c576dec995fe001da3c1c6607f2df Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 31 Jan 2025 13:53:17 +0100 Subject: [PATCH 28/43] Features (#572) - [ ] Does not require a CHANGELOG entry --- system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml | 1 + system-parachains/constants/Cargo.toml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml index cf363e4db3..8dc09251b7 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml @@ -156,6 +156,7 @@ runtime-benchmarks = [ "polkadot-runtime-common/runtime-benchmarks", "snowbridge-router-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/constants/Cargo.toml b/system-parachains/constants/Cargo.toml index 17582f7785..77ce47460f 100644 --- a/system-parachains/constants/Cargo.toml +++ b/system-parachains/constants/Cargo.toml @@ -35,3 +35,7 @@ std = [ "sp-std/std", "xcm/std", ] +runtime-benchmarks = [ + "kusama-runtime-constants/runtime-benchmarks", + "polkadot-runtime-constants/runtime-benchmarks", +] \ No newline at end of file From 256737b7a601fbadd18e83ac0b9ea9d720fb883e Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 3 Feb 2025 13:11:33 +0100 Subject: [PATCH 29/43] Benches (#573) - [ ] Does not require a CHANGELOG entry --- .../asset-hubs/asset-hub-kusama/src/lib.rs | 4 +- .../asset-hub-kusama/src/weights/mod.rs | 1 + .../src/weights/pallet_remote_proxy.rs | 80 +++++++++++++++++++ .../asset-hubs/asset-hub-polkadot/Cargo.toml | 1 + .../bridge-hubs/bridge-hub-kusama/Cargo.toml | 1 + .../bridge-hub-polkadot/Cargo.toml | 1 + .../collectives-polkadot/Cargo.toml | 1 + system-parachains/constants/Cargo.toml | 6 +- .../coretime/coretime-kusama/Cargo.toml | 1 + .../coretime/coretime-polkadot/Cargo.toml | 1 + system-parachains/encointer/Cargo.toml | 1 + .../gluttons/glutton-kusama/Cargo.toml | 1 + .../people/people-kusama/Cargo.toml | 1 + .../people/people-polkadot/Cargo.toml | 1 + 14 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_remote_proxy.rs diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index dfd4a3f223..f1c9d7eadd 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -1009,8 +1009,7 @@ impl pallet_remote_proxy::Config for Runtime { ProxyType, RelayChainToLocalProxyTypeConverter, >; - //TODO: Run benchmarks and replace. - type WeightInfo = (); + type WeightInfo = weights::pallet_remote_proxy::WeightInfo; } // Create the runtime by composing the FRAME pallets that were previously configured. @@ -1127,6 +1126,7 @@ mod benches { [pallet_nft_fractionalization, NftFractionalization] [pallet_nfts, Nfts] [pallet_proxy, Proxy] + [pallet_remote_proxy, RemoteProxyRelayChain] [pallet_session, SessionBench::] [pallet_uniques, Uniques] [pallet_utility, Utility] diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs index 4a18c22aca..16aa737336 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs @@ -30,6 +30,7 @@ pub mod pallet_multisig; pub mod pallet_nft_fractionalization; pub mod pallet_nfts; pub mod pallet_proxy; +pub mod pallet_remote_proxy; pub mod pallet_session; pub mod pallet_timestamp; pub mod pallet_uniques; diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_remote_proxy.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_remote_proxy.rs new file mode 100644 index 0000000000..b3d34884c9 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_remote_proxy.rs @@ -0,0 +1,80 @@ +// Copyright (C) Parity Technologies and the various Polkadot contributors, see Contributions.md +// for a list of specific contributors. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for `pallet_remote_proxy` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("./asset-hub-kusama-chain-spec.json")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot-parachain +// benchmark +// pallet +// --chain=./asset-hub-kusama-chain-spec.json +// --steps=50 +// --repeat=20 +// --pallet=pallet_remote_proxy +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./asset-hub-kusama-weights/ +// --header=./file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_remote_proxy`. +pub struct WeightInfo(PhantomData); +impl pallet_remote_proxy::WeightInfo for WeightInfo { + /// Storage: `RemoteProxyRelayChain::BlockToRoot` (r:1 w:0) + /// Proof: `RemoteProxyRelayChain::BlockToRoot` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn remote_proxy() -> Weight { + // Proof Size summary in bytes: + // Measured: `73` + // Estimated: `3509` + // Minimum execution time: 23_880_000 picoseconds. + Weight::from_parts(24_480_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn register_remote_proxy_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_540_000 picoseconds. + Weight::from_parts(4_680_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `RemoteProxyRelayChain::BlockToRoot` (r:1 w:0) + /// Proof: `RemoteProxyRelayChain::BlockToRoot` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn remote_proxy_with_registered_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `73` + // Estimated: `3509` + // Minimum execution time: 23_950_000 picoseconds. + Weight::from_parts(24_310_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index c9785d3c53..a5407b281b 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -147,6 +147,7 @@ runtime-benchmarks = [ "polkadot-runtime-constants/runtime-benchmarks", "snowbridge-router-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml index 4d3202d932..99449a393d 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml @@ -235,6 +235,7 @@ runtime-benchmarks = [ "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml index d50d4e38c2..babee6733f 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml @@ -268,6 +268,7 @@ runtime-benchmarks = [ "snowbridge-runtime-common/runtime-benchmarks", "snowbridge-runtime-test-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/collectives/collectives-polkadot/Cargo.toml b/system-parachains/collectives/collectives-polkadot/Cargo.toml index 53828ed84c..9ecc69471e 100644 --- a/system-parachains/collectives/collectives-polkadot/Cargo.toml +++ b/system-parachains/collectives/collectives-polkadot/Cargo.toml @@ -130,6 +130,7 @@ runtime-benchmarks = [ "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/constants/Cargo.toml b/system-parachains/constants/Cargo.toml index 77ce47460f..050a1a9553 100644 --- a/system-parachains/constants/Cargo.toml +++ b/system-parachains/constants/Cargo.toml @@ -36,6 +36,10 @@ std = [ "xcm/std", ] runtime-benchmarks = [ + "frame-support/runtime-benchmarks", "kusama-runtime-constants/runtime-benchmarks", + "parachains-common/runtime-benchmarks", + "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-constants/runtime-benchmarks", -] \ No newline at end of file + "sp-runtime/runtime-benchmarks", +] diff --git a/system-parachains/coretime/coretime-kusama/Cargo.toml b/system-parachains/coretime/coretime-kusama/Cargo.toml index 5c359cbe65..80198bc89e 100644 --- a/system-parachains/coretime/coretime-kusama/Cargo.toml +++ b/system-parachains/coretime/coretime-kusama/Cargo.toml @@ -176,6 +176,7 @@ runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/coretime/coretime-polkadot/Cargo.toml b/system-parachains/coretime/coretime-polkadot/Cargo.toml index c40d9f46c0..ed605b911e 100644 --- a/system-parachains/coretime/coretime-polkadot/Cargo.toml +++ b/system-parachains/coretime/coretime-polkadot/Cargo.toml @@ -178,6 +178,7 @@ runtime-benchmarks = [ "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/encointer/Cargo.toml b/system-parachains/encointer/Cargo.toml index bf1e8402ee..7ff94568cc 100644 --- a/system-parachains/encointer/Cargo.toml +++ b/system-parachains/encointer/Cargo.toml @@ -154,6 +154,7 @@ runtime-benchmarks = [ "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/gluttons/glutton-kusama/Cargo.toml b/system-parachains/gluttons/glutton-kusama/Cargo.toml index d3aa109541..4a33ce1444 100644 --- a/system-parachains/gluttons/glutton-kusama/Cargo.toml +++ b/system-parachains/gluttons/glutton-kusama/Cargo.toml @@ -67,6 +67,7 @@ runtime-benchmarks = [ "pallet-sudo?/runtime-benchmarks", "parachains-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", ] diff --git a/system-parachains/people/people-kusama/Cargo.toml b/system-parachains/people/people-kusama/Cargo.toml index e16508171f..891dd6297c 100644 --- a/system-parachains/people/people-kusama/Cargo.toml +++ b/system-parachains/people/people-kusama/Cargo.toml @@ -177,6 +177,7 @@ runtime-benchmarks = [ "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", diff --git a/system-parachains/people/people-polkadot/Cargo.toml b/system-parachains/people/people-polkadot/Cargo.toml index 501749e9e3..362ce2a1e1 100644 --- a/system-parachains/people/people-polkadot/Cargo.toml +++ b/system-parachains/people/people-polkadot/Cargo.toml @@ -174,6 +174,7 @@ runtime-benchmarks = [ "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-constants/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "system-parachains-constants/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", "xcm-runtime-apis/runtime-benchmarks", From 5ef3aa31c1b4283b245db36233ef8dbf08cd4657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 3 Feb 2025 22:29:13 +0100 Subject: [PATCH 30/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 7da8b133dd..e4b822eab0 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -292,7 +292,7 @@ pub mod pallet { /// /// # Example /// - /// ``` + /// ```ignore /// batch([ /// register_remote_proxy_proof, /// as_multisig(remote_proxy_with_registered_proof(transfer)) From 979efb2e635a95d4c902033da588708987a747b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 5 Feb 2025 13:52:04 +0100 Subject: [PATCH 31/43] Fix issues --- pallets/remote-proxy/src/lib.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index e4b822eab0..a4cbc0081a 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -172,6 +172,11 @@ pub mod pallet { pub type BlockToRoot, I: 'static = ()> = StorageMap<_, Twox64Concat, RemoteBlockNumberOf, RemoteHashOf, OptionQuery>; + /// Stores the last block that was added to [`BlockToRoot`]. + #[pallet::storage] + pub type MostRecentBlock, I: 'static = ()> = + StorageValue<_, RemoteBlockNumberOf, OptionQuery>; + /// Configuration trait. #[pallet::config] pub trait Config: frame_system::Config + pallet_proxy::Config { @@ -200,7 +205,11 @@ pub mod pallet { // Update the block to root mappings. BlockToRoot::::insert(&block, hash); - BlockToRoot::::remove(block.saturating_sub(T::MaxStorageRootsToKeep::get())); + MostRecentBlock::insert(&block); + + let delete_up_to = block.saturating_sub(T::MaxStorageRootsToKeep::get()); + // If the chain got stuck for longer, we will clean up too old entries over time. + BlockToRoot::::iter_keys().take_while(3, |k| k <= delete_up_to).for_each(BlockToRoot::::remove); } fn on_validation_code_applied() {} @@ -213,6 +222,8 @@ pub mod pallet { CouldNotConvertLocalToRemoteAccountId, /// The anchor block of the remote proof is unknown. UnknownProofAnchorBlock, + /// The anchor block of the remote proof is too old. + ProofAnchorBlockTooOld, /// The proxy definition could not be found in the proof. InvalidProof, /// Failed to decode the remote proxy definition from the proof. @@ -374,6 +385,10 @@ pub mod pallet { let def = match proof { RemoteProxyProof::RelayChain { proof, block } => { + if MostRecentBlock::::get(&block).map_or(true, |b| block <= b.saturating_sub(T::MaxStorageRootsToKeep::get()) { + return Err(Error::::ProofAnchorBlockTooOld.into()); + } + let Some(storage_root) = BlockToRoot::::get(block) else { return Err(Error::::UnknownProofAnchorBlock.into()); }; @@ -427,7 +442,7 @@ pub mod pallet { Ok(()) } - /// TODO: Make upstream public and use that one. + // TODO: Make upstream public and use that one. fn do_proxy( def: ProxyDefinition>, real: T::AccountId, From 6b2e6e52050e99e3df431e8353b93de8d63d8aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 5 Feb 2025 13:58:55 +0100 Subject: [PATCH 32/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index a4cbc0081a..4362a3ab61 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -261,7 +261,7 @@ pub mod pallet { /// - `real`: The account that the proxy will make a call on behalf of. /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call. /// - `call`: The call to be made by the `real` account. - /// - `proof`: The proof from the remote chain about the existence of the proof. + /// - `proof`: The proof from the remote chain about the existence of the proxy. #[pallet::call_index(0)] #[pallet::weight({ let di = call.get_dispatch_info(); From 1930e79a2adfd9e7a843f8925c7b606cea72adda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 5 Feb 2025 13:59:33 +0100 Subject: [PATCH 33/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 4362a3ab61..94c3c7e3ff 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -453,7 +453,7 @@ pub mod pallet { let mut origin: T::RuntimeOrigin = frame_system::RawOrigin::Signed(real).into(); origin.add_filter(move |c: &::RuntimeCall| { let c = ::RuntimeCall::from_ref(c); - // We make sure the proxy call does access this pallet to change modify proxies. + // We make sure the proxy call does not modify proxies. match c.is_sub_type() { // Proxy call cannot add or remove a proxy with more permissions than it already // has. From 7789ad275c670378d26d9464d09a90a047ebb52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 5 Feb 2025 13:59:55 +0100 Subject: [PATCH 34/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 94c3c7e3ff..119d31225f 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -90,7 +90,7 @@ pub trait RemoteProxyInterface { /// The storage key where to find the [`ProxyDefinition`] for the given proxy account in the /// remote chain. fn proxy_definition_storage_key(proxy: &Self::RemoteAccountId) -> Vec { - let mut key = storage_prefix("Proxy".as_bytes(), "Proxies".as_bytes()).to_vec(); + let mut key = storage_prefix(b"Proxy", b"Proxies").to_vec(); proxy.using_encoded(|p| { key.extend(Twox64Concat::hash(p)); }); From f72d00c42ab28a98d71f14ecd933bc4e39b759a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 5 Feb 2025 14:06:32 +0100 Subject: [PATCH 35/43] Update lib.rs --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 119d31225f..6924b55dff 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -385,7 +385,7 @@ pub mod pallet { let def = match proof { RemoteProxyProof::RelayChain { proof, block } => { - if MostRecentBlock::::get(&block).map_or(true, |b| block <= b.saturating_sub(T::MaxStorageRootsToKeep::get()) { + if MostRecentBlock::::get(&block).map_or(true, |b| block <= b.saturating_sub(T::MaxStorageRootsToKeep::get())) { return Err(Error::::ProofAnchorBlockTooOld.into()); } From 2fbb16a40c9fb8a564b1522680b56523dd05a01e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 5 Feb 2025 14:34:46 +0100 Subject: [PATCH 36/43] Update lib.rs --- pallets/remote-proxy/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 6924b55dff..874131d47a 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -205,11 +205,11 @@ pub mod pallet { // Update the block to root mappings. BlockToRoot::::insert(&block, hash); - MostRecentBlock::insert(&block); + MostRecentBlock::put(&block); let delete_up_to = block.saturating_sub(T::MaxStorageRootsToKeep::get()); // If the chain got stuck for longer, we will clean up too old entries over time. - BlockToRoot::::iter_keys().take_while(3, |k| k <= delete_up_to).for_each(BlockToRoot::::remove); + BlockToRoot::::iter_keys().take_while(|k| k <= delete_up_to).for_each(BlockToRoot::::remove); } fn on_validation_code_applied() {} From 969f081fb2719dcc8b39f01c20cea0e02c647b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 7 Feb 2025 12:21:42 +0100 Subject: [PATCH 37/43] Adds failing test --- pallets/remote-proxy/src/benchmarking.rs | 8 ++-- pallets/remote-proxy/src/lib.rs | 18 +++++---- pallets/remote-proxy/src/tests.rs | 47 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/pallets/remote-proxy/src/benchmarking.rs b/pallets/remote-proxy/src/benchmarking.rs index edc3d73839..90f10dc463 100644 --- a/pallets/remote-proxy/src/benchmarking.rs +++ b/pallets/remote-proxy/src/benchmarking.rs @@ -57,7 +57,8 @@ mod benchmarks { frame_system::Call::::remark { remark: vec![] }.into(); let (proof, block_number, storage_root) = T::RemoteProxy::create_remote_proxy_proof(&caller, &real); - BlockToRoot::::insert(block_number, storage_root); + BlockToRoot::::insert(EncodeAsBigEndian::from(block_number.clone()), storage_root); + MostRecentBlock::::put(block_number); #[extrinsic_call] _(RawOrigin::Signed(caller), real_lookup, None, Box::new(call), proof); @@ -79,7 +80,7 @@ mod benchmarks { let real: T::AccountId = whitelisted_caller(); let (proof, block_number, storage_root) = T::RemoteProxy::create_remote_proxy_proof(&caller, &real); - BlockToRoot::::insert(block_number, storage_root); + BlockToRoot::::insert(EncodeAsBigEndian::from(block_number.clone()), storage_root); #[extrinsic_call] _(RawOrigin::Signed(caller), proof); @@ -102,7 +103,8 @@ mod benchmarks { frame_system::Call::::remark { remark: vec![] }.into(); let (proof, block_number, storage_root) = T::RemoteProxy::create_remote_proxy_proof(&caller, &real); - BlockToRoot::::insert(block_number, storage_root); + BlockToRoot::::insert(EncodeAsBigEndian::from(block_number.clone()), storage_root); + MostRecentBlock::::put(block_number); #[block] { diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 874131d47a..6c896fc273 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -76,7 +76,7 @@ pub trait RemoteProxyInterface { /// The remote proxy type. type RemoteProxyType: Parameter + MaxEncodedLen; /// The remote block number. - type RemoteBlockNumber: Parameter + Saturating + MaxEncodedLen + Default; + type RemoteBlockNumber: Parameter + Saturating + MaxEncodedLen + Default + PartialOrd; /// The hash type used by the remote chain. type Hash: Parameter + MaxEncodedLen; /// The hasher used by the remote chain. @@ -197,7 +197,7 @@ pub mod pallet { type WeightInfo: WeightInfo; } - impl OnSystemEvent for Pallet { + impl, I: 'static> OnSystemEvent for Pallet { fn on_validation_data(validation_data: &PersistedValidationData) { let Some((block, hash)) = T::RemoteProxy::block_to_storage_root(validation_data) else { return; @@ -205,11 +205,13 @@ pub mod pallet { // Update the block to root mappings. BlockToRoot::::insert(&block, hash); - MostRecentBlock::put(&block); + MostRecentBlock::::put(&block); let delete_up_to = block.saturating_sub(T::MaxStorageRootsToKeep::get()); // If the chain got stuck for longer, we will clean up too old entries over time. - BlockToRoot::::iter_keys().take_while(|k| k <= delete_up_to).for_each(BlockToRoot::::remove); + BlockToRoot::::iter_keys() + .take_while(|k| *k <= delete_up_to) + .for_each(BlockToRoot::::remove); } fn on_validation_code_applied() {} @@ -385,10 +387,12 @@ pub mod pallet { let def = match proof { RemoteProxyProof::RelayChain { proof, block } => { - if MostRecentBlock::::get(&block).map_or(true, |b| block <= b.saturating_sub(T::MaxStorageRootsToKeep::get())) { + if MostRecentBlock::::get().map_or(true, |b| { + block <= b.saturating_sub(T::MaxStorageRootsToKeep::get()) + }) { return Err(Error::::ProofAnchorBlockTooOld.into()); - } - + } + let Some(storage_root) = BlockToRoot::::get(block) else { return Err(Error::::UnknownProofAnchorBlock.into()); }; diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index e8560038d8..c483a60a72 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -587,3 +587,50 @@ fn remote_proxy_multiple_register_works() { ); }); } + +#[test] +fn clean_up_works_and_old_blocks_are_rejected() { + new_test_ext().execute_with(|| { + let root = H256::zero(); + let call = Box::new(call_transfer(6, 1)); + + for i in 0u64..30u64 { + BlockToRoot::::insert(i, root); + } + + RemoteProxy::on_validation_data(&PersistedValidationData { + parent_head: vec![].into(), + relay_parent_number: 30, + relay_parent_storage_root: root, + max_pov_size: 5000000, + }); + assert!(BlockToRoot::::get(5).is_some()); + assert_err!( + RemoteProxy::remote_proxy( + RuntimeOrigin::signed(1), + 1000, + None, + call.clone(), + RemoteProxyProof::RelayChain { proof: vec![], block: 5 } + ), + Error::::ProofAnchorBlockTooOld + ); + + for i in 31u32..=40u32 { + RemoteProxy::on_validation_data(&PersistedValidationData { + parent_head: vec![].into(), + relay_parent_number: dbg!(i), + relay_parent_storage_root: root, + max_pov_size: 5000000, + }); + } + + for i in 0u64..31u64 { + assert!(BlockToRoot::::get(i).is_none()); + } + + for i in 31u64..42u64 { + assert!(BlockToRoot::::get(i).is_some()); + } + }); +} From f8d4410da17834c12d8adc84717761fc6b8e1ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 7 Feb 2025 21:04:08 +0100 Subject: [PATCH 38/43] Release `1.4.0` --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3acb44b85a..f1572b4712 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Changelog for the runtimes governed by the Polkadot Fellowship. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [Unreleased] +## [1.4.0] 07.02.2025 ### Fixed From bdd9736dd17dee450076fac9b930a9db035fbcbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 26 Feb 2025 11:11:17 +0100 Subject: [PATCH 39/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 6c896fc273..fac3b1bd2a 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -78,7 +78,7 @@ pub trait RemoteProxyInterface { /// The remote block number. type RemoteBlockNumber: Parameter + Saturating + MaxEncodedLen + Default + PartialOrd; /// The hash type used by the remote chain. - type Hash: Parameter + MaxEncodedLen; + type RemoteHash: Parameter + MaxEncodedLen; /// The hasher used by the remote chain. type Hasher: Hasher; From f25b9fd56008d2ae71a3154018411c9c575949df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 26 Feb 2025 11:11:28 +0100 Subject: [PATCH 40/43] Update pallets/remote-proxy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi --- pallets/remote-proxy/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index fac3b1bd2a..ed9bdb4192 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -80,7 +80,7 @@ pub trait RemoteProxyInterface { /// The hash type used by the remote chain. type RemoteHash: Parameter + MaxEncodedLen; /// The hasher used by the remote chain. - type Hasher: Hasher; + type RemoreHasher: Hasher; /// Get the latest block to storage root mapping. fn block_to_storage_root( From 40a8c9e63683322a1edffa3183655217696c3e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 28 Feb 2025 14:56:45 +0100 Subject: [PATCH 41/43] Fixes and some reworks of the internals --- pallets/remote-proxy/src/lib.rs | 71 +++++++++++++++++-------------- pallets/remote-proxy/src/tests.rs | 35 +++++++-------- 2 files changed, 58 insertions(+), 48 deletions(-) diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index ed9bdb4192..99e882bcec 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -76,16 +76,22 @@ pub trait RemoteProxyInterface { /// The remote proxy type. type RemoteProxyType: Parameter + MaxEncodedLen; /// The remote block number. - type RemoteBlockNumber: Parameter + Saturating + MaxEncodedLen + Default + PartialOrd; + type RemoteBlockNumber: Parameter + + Saturating + + MaxEncodedLen + + Default + + PartialOrd + + Ord + + From; /// The hash type used by the remote chain. type RemoteHash: Parameter + MaxEncodedLen; /// The hasher used by the remote chain. - type RemoreHasher: Hasher; + type RemoteHasher: Hasher; /// Get the latest block to storage root mapping. fn block_to_storage_root( validation_data: &PersistedValidationData, - ) -> Option<(Self::RemoteBlockNumber, ::Out)>; + ) -> Option<(Self::RemoteBlockNumber, ::Out)>; /// The storage key where to find the [`ProxyDefinition`] for the given proxy account in the /// remote chain. @@ -150,12 +156,12 @@ pub mod pallet { ::AccountId, ::ProxyType, BlockNumberFor, - >>::Hasher; + >>::RemoteHasher; type RemoteHashOf = <>::RemoteProxy as RemoteProxyInterface< ::AccountId, ::ProxyType, BlockNumberFor, - >>::Hash; + >>::RemoteHash; type RemoteProxyTypeOf = <>::RemoteProxy as RemoteProxyInterface< ::AccountId, ::ProxyType, @@ -169,22 +175,23 @@ pub mod pallet { /// Stores the last [`Config::MaxStorageRootsToKeep`] block to storage root mappings of the /// target chain. #[pallet::storage] - pub type BlockToRoot, I: 'static = ()> = - StorageMap<_, Twox64Concat, RemoteBlockNumberOf, RemoteHashOf, OptionQuery>; - - /// Stores the last block that was added to [`BlockToRoot`]. - #[pallet::storage] - pub type MostRecentBlock, I: 'static = ()> = - StorageValue<_, RemoteBlockNumberOf, OptionQuery>; + pub type BlockToRoot, I: 'static = ()> = StorageValue< + _, + BoundedVec<(RemoteBlockNumberOf, RemoteHashOf), T::MaxStorageRootsToKeep>, + ValueQuery, + >; /// Configuration trait. #[pallet::config] pub trait Config: frame_system::Config + pallet_proxy::Config { - /// Maximum number of storage roots to keep in storage. + /// The maximum number of storage roots to keep. /// /// The storage roots are used to validate the remote proofs. The more we keep in storage, - /// the older the proof can be. - type MaxStorageRootsToKeep: Get>; + /// the older the proof can be. This is not only seen as a maximum number, but also as the + /// maximum difference between the latest and the oldest storage root stored. This means + /// that if the chain for example did not progress for `MaxStorageRootsToKeep` blocks, only + /// the latest added storage root will be available for validating proofs. + type MaxStorageRootsToKeep: Get; /// The interface for interacting with the remote proxy. type RemoteProxy: RemoteProxyInterface< @@ -204,14 +211,19 @@ pub mod pallet { }; // Update the block to root mappings. - BlockToRoot::::insert(&block, hash); - MostRecentBlock::::put(&block); - - let delete_up_to = block.saturating_sub(T::MaxStorageRootsToKeep::get()); - // If the chain got stuck for longer, we will clean up too old entries over time. - BlockToRoot::::iter_keys() - .take_while(|k| *k <= delete_up_to) - .for_each(BlockToRoot::::remove); + BlockToRoot::::mutate(|roots| { + let delete_up_to = + block.clone().saturating_sub(T::MaxStorageRootsToKeep::get().into()); + + while roots.first().is_some_and(|f| f.0 <= delete_up_to) { + roots.remove(0); + } + + // We always remove all the old items before, thus there should always be space in + // the vector. + let _res = roots.try_push((block, hash)); + debug_assert!(_res.is_ok()); + }); } fn on_validation_code_applied() {} @@ -224,8 +236,6 @@ pub mod pallet { CouldNotConvertLocalToRemoteAccountId, /// The anchor block of the remote proof is unknown. UnknownProofAnchorBlock, - /// The anchor block of the remote proof is too old. - ProofAnchorBlockTooOld, /// The proxy definition could not be found in the proof. InvalidProof, /// Failed to decode the remote proxy definition from the proof. @@ -387,13 +397,12 @@ pub mod pallet { let def = match proof { RemoteProxyProof::RelayChain { proof, block } => { - if MostRecentBlock::::get().map_or(true, |b| { - block <= b.saturating_sub(T::MaxStorageRootsToKeep::get()) - }) { - return Err(Error::::ProofAnchorBlockTooOld.into()); - } + let roots = BlockToRoot::::get(); - let Some(storage_root) = BlockToRoot::::get(block) else { + let Ok(storage_root) = roots + .binary_search_by(|(b, _)| b.cmp(&block)) + .map(|pos| roots[pos].1.clone()) + else { return Err(Error::::UnknownProofAnchorBlock.into()); }; diff --git a/pallets/remote-proxy/src/tests.rs b/pallets/remote-proxy/src/tests.rs index c483a60a72..d859c84eeb 100644 --- a/pallets/remote-proxy/src/tests.rs +++ b/pallets/remote-proxy/src/tests.rs @@ -32,7 +32,7 @@ use sp_core::{ConstU32, ConstU64, H256}; use sp_io::TestExternalities; use sp_runtime::{ traits::{BlakeTwo256, Dispatchable}, - BuildStorage, + BoundedVec, BuildStorage, }; type Block = frame_system::mocking::MockBlock; @@ -139,12 +139,12 @@ impl crate::RemoteProxyInterface for RemoteProxyImpl { type RemoteAccountId = u64; type RemoteProxyType = ProxyType; type RemoteBlockNumber = u64; - type Hash = H256; - type Hasher = BlakeTwo256; + type RemoteHash = H256; + type RemoteHasher = BlakeTwo256; fn block_to_storage_root( validation_data: &PersistedValidationData, - ) -> Option<(Self::RemoteBlockNumber, ::Out)> { + ) -> Option<(Self::RemoteBlockNumber, ::Out)> { Some((validation_data.relay_parent_number as _, validation_data.relay_parent_storage_root)) } @@ -195,7 +195,7 @@ impl crate::RemoteProxyInterface for RemoteProxyImpl { } impl Config for Test { - type MaxStorageRootsToKeep = ConstU64<10>; + type MaxStorageRootsToKeep = ConstU32<10>; type RemoteProxy = RemoteProxyImpl; type WeightInfo = (); } @@ -594,9 +594,12 @@ fn clean_up_works_and_old_blocks_are_rejected() { let root = H256::zero(); let call = Box::new(call_transfer(6, 1)); - for i in 0u64..30u64 { - BlockToRoot::::insert(i, root); - } + BlockToRoot::::set(BoundedVec::truncate_from(vec![ + (0, root), + (10, root), + (20, root), + (29, root), + ])); RemoteProxy::on_validation_data(&PersistedValidationData { parent_head: vec![].into(), @@ -604,7 +607,9 @@ fn clean_up_works_and_old_blocks_are_rejected() { relay_parent_storage_root: root, max_pov_size: 5000000, }); - assert!(BlockToRoot::::get(5).is_some()); + BlockToRoot::::get() + .iter() + .for_each(|(b, _)| assert!(*b == 29 || *b == 30)); assert_err!( RemoteProxy::remote_proxy( RuntimeOrigin::signed(1), @@ -613,7 +618,7 @@ fn clean_up_works_and_old_blocks_are_rejected() { call.clone(), RemoteProxyProof::RelayChain { proof: vec![], block: 5 } ), - Error::::ProofAnchorBlockTooOld + Error::::UnknownProofAnchorBlock ); for i in 31u32..=40u32 { @@ -625,12 +630,8 @@ fn clean_up_works_and_old_blocks_are_rejected() { }); } - for i in 0u64..31u64 { - assert!(BlockToRoot::::get(i).is_none()); - } - - for i in 31u64..42u64 { - assert!(BlockToRoot::::get(i).is_some()); - } + BlockToRoot::::get() + .iter() + .for_each(|(b, _)| assert!(*b >= 31 && *b <= 40)); }); } From b9a7eb9947bd0f291e0712311e4dd8748abb64cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 28 Feb 2025 15:35:55 +0100 Subject: [PATCH 42/43] Fixes --- Cargo.lock | 1 + .../chains/parachains/testing/penpal/Cargo.toml | 8 ++++++++ pallets/remote-proxy/src/benchmarking.rs | 13 +++++++------ pallets/remote-proxy/src/lib.rs | 2 +- relay/kusama/constants/src/lib.rs | 6 +++--- relay/polkadot/constants/src/lib.rs | 6 +++--- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 671fb262d7..dadec39626 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9474,6 +9474,7 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", + "hex-literal", "log", "pallet-asset-conversion", "pallet-asset-tx-payment", diff --git a/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml b/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml index a9b5ce3aa6..e98910c078 100644 --- a/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml +++ b/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml @@ -23,3 +23,11 @@ xcm = { workspace = true, default-features = true } # Runtimes kusama-emulated-chain = { workspace = true } polkadot-emulated-chain = { workspace = true } + +[features] +runtime-benchmarks = [ + "cumulus-primitives-core/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "parachains-common/runtime-benchmarks", + "penpal-runtime/runtime-benchmarks" +] diff --git a/pallets/remote-proxy/src/benchmarking.rs b/pallets/remote-proxy/src/benchmarking.rs index 90f10dc463..fb74844d6d 100644 --- a/pallets/remote-proxy/src/benchmarking.rs +++ b/pallets/remote-proxy/src/benchmarking.rs @@ -23,7 +23,10 @@ use frame_benchmarking::v2::{ }; use frame_support::traits::Currency; use frame_system::RawOrigin; -use sp_runtime::traits::{Bounded, StaticLookup}; +use sp_runtime::{ + traits::{Bounded, StaticLookup}, + BoundedVec, +}; const SEED: u32 = 0; @@ -57,8 +60,7 @@ mod benchmarks { frame_system::Call::::remark { remark: vec![] }.into(); let (proof, block_number, storage_root) = T::RemoteProxy::create_remote_proxy_proof(&caller, &real); - BlockToRoot::::insert(EncodeAsBigEndian::from(block_number.clone()), storage_root); - MostRecentBlock::::put(block_number); + BlockToRoot::::set(BoundedVec::truncate_from(vec![(block_number, storage_root)])); #[extrinsic_call] _(RawOrigin::Signed(caller), real_lookup, None, Box::new(call), proof); @@ -80,7 +82,7 @@ mod benchmarks { let real: T::AccountId = whitelisted_caller(); let (proof, block_number, storage_root) = T::RemoteProxy::create_remote_proxy_proof(&caller, &real); - BlockToRoot::::insert(EncodeAsBigEndian::from(block_number.clone()), storage_root); + BlockToRoot::::set(BoundedVec::truncate_from(vec![(block_number, storage_root)])); #[extrinsic_call] _(RawOrigin::Signed(caller), proof); @@ -103,8 +105,7 @@ mod benchmarks { frame_system::Call::::remark { remark: vec![] }.into(); let (proof, block_number, storage_root) = T::RemoteProxy::create_remote_proxy_proof(&caller, &real); - BlockToRoot::::insert(EncodeAsBigEndian::from(block_number.clone()), storage_root); - MostRecentBlock::::put(block_number); + BlockToRoot::::set(BoundedVec::truncate_from(vec![(block_number, storage_root)])); #[block] { diff --git a/pallets/remote-proxy/src/lib.rs b/pallets/remote-proxy/src/lib.rs index 99e882bcec..9b9ed8c0ab 100644 --- a/pallets/remote-proxy/src/lib.rs +++ b/pallets/remote-proxy/src/lib.rs @@ -127,7 +127,7 @@ pub trait RemoteProxyInterface { fn create_remote_proxy_proof( caller: &AccountId, proxy: &AccountId, - ) -> (RemoteProxyProof, Self::RemoteBlockNumber, Self::Hash); + ) -> (RemoteProxyProof, Self::RemoteBlockNumber, Self::RemoteHash); } #[frame_support::pallet] diff --git a/relay/kusama/constants/src/lib.rs b/relay/kusama/constants/src/lib.rs index d3599de887..76bfea46a9 100644 --- a/relay/kusama/constants/src/lib.rs +++ b/relay/kusama/constants/src/lib.rs @@ -201,13 +201,13 @@ pub mod proxy { type RemoteBlockNumber = BlockNumber; - type Hash = Hash; + type RemoteHash = Hash; - type Hasher = BlakeTwo256; + type RemoteHasher = BlakeTwo256; fn block_to_storage_root( validation_data: &polkadot_primitives::PersistedValidationData, - ) -> Option<(Self::RemoteBlockNumber, ::Out)> { + ) -> Option<(Self::RemoteBlockNumber, ::Out)> { Some((validation_data.relay_parent_number, validation_data.relay_parent_storage_root)) } diff --git a/relay/polkadot/constants/src/lib.rs b/relay/polkadot/constants/src/lib.rs index 58daee9b6e..7b5162e595 100644 --- a/relay/polkadot/constants/src/lib.rs +++ b/relay/polkadot/constants/src/lib.rs @@ -208,13 +208,13 @@ pub mod proxy { type RemoteBlockNumber = BlockNumber; - type Hash = Hash; + type RemoteHash = Hash; - type Hasher = BlakeTwo256; + type RemoteHasher = BlakeTwo256; fn block_to_storage_root( validation_data: &polkadot_primitives::PersistedValidationData, - ) -> Option<(Self::RemoteBlockNumber, ::Out)> { + ) -> Option<(Self::RemoteBlockNumber, ::Out)> { Some((validation_data.relay_parent_number, validation_data.relay_parent_storage_root)) } From 44abbdd442edbede2651aa9ff0a73b80e02ed26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 28 Feb 2025 15:40:33 +0100 Subject: [PATCH 43/43] TAPLO --- .../emulated/chains/parachains/testing/penpal/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml b/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml index e98910c078..b31580dd63 100644 --- a/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml +++ b/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml @@ -29,5 +29,5 @@ runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", "frame-support/runtime-benchmarks", "parachains-common/runtime-benchmarks", - "penpal-runtime/runtime-benchmarks" + "penpal-runtime/runtime-benchmarks", ]