From 5264acec0cb0fc871122c6d5e5f385a6b57bf62b Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Date: Sat, 20 Apr 2024 21:57:33 +0200 Subject: [PATCH] feat: pallet proxy (#70) Co-authored-by: Frank Bell --- Cargo.lock | 2 + Cargo.toml | 1 + runtime/common/src/lib.rs | 71 +++++++++++++++++ runtime/devnet/Cargo.toml | 4 + runtime/devnet/src/assets_config.rs | 1 + runtime/devnet/src/lib.rs | 3 + runtime/devnet/src/proxy_config.rs | 109 +++++++++++++++++++++++++++ runtime/testnet/Cargo.toml | 4 + runtime/testnet/src/assets_config.rs | 1 + runtime/testnet/src/lib.rs | 3 + runtime/testnet/src/proxy_config.rs | 109 +++++++++++++++++++++++++++ 11 files changed, 308 insertions(+) create mode 100644 runtime/devnet/src/proxy_config.rs create mode 100644 runtime/testnet/src/proxy_config.rs diff --git a/Cargo.lock b/Cargo.lock index de039f40..4dc89da6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9715,6 +9715,7 @@ dependencies = [ "pallet-nfts", "pallet-nfts-runtime-api", "pallet-preimage", + "pallet-proxy", "pallet-scheduler", "pallet-session", "pallet-sudo", @@ -9787,6 +9788,7 @@ dependencies = [ "pallet-nfts", "pallet-nfts-runtime-api", "pallet-preimage", + "pallet-proxy", "pallet-scheduler", "pallet-session", "pallet-sudo", diff --git a/Cargo.toml b/Cargo.toml index de929205..3f1d6e1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,6 +92,7 @@ pallet-nft-fractionalization = { version = "11.0.0", default-features = false } pallet-nfts = { version = "23.0.0", default-features = false } pallet-nfts-runtime-api = { version = "15.0.0", default-features = false } pallet-preimage = { version = "29.0.0", default-features = false } +pallet-proxy = { version = "29.0.0", default-features = false } pallet-scheduler = { version = "30.0.0", default-features = false } pallet-session = { version = "29.0.0", default-features = false } pallet-sudo = { version = "29.0.0", default-features = false } diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 73c1773e..d8562fdd 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -78,3 +78,74 @@ pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1; /// How many parachain blocks are processed by the relay chain per parent. Limits the /// number of blocks authored per slot. pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; + +/// Proxy commons for Pop runtimes +pub mod proxy { + + use super::{deposit, Balance}; + use codec::{Decode, Encode, MaxEncodedLen}; + use frame_support::parameter_types; + use sp_runtime::RuntimeDebug; + + parameter_types! { + // One storage item; key size 32, value size 8; . + pub const ProxyDepositBase: Balance = deposit(1, 40); + // Additional storage item size of 33 bytes. + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u16 = 32; + // One storage item; key size 32, value size 16 + pub const AnnouncementDepositBase: Balance = deposit(1, 48); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); + pub const MaxPending: u16 = 32; + } + + /// The type used to represent the kinds of proxying allowed. + #[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + RuntimeDebug, + MaxEncodedLen, + scale_info::TypeInfo, + )] + pub enum ProxyType { + /// Fully permissioned proxy. Can execute any call on behalf of _proxied_. + Any, + /// Can execute any call that does not transfer funds or assets. + NonTransfer, + /// Proxy with the ability to reject time-delay proxy announcements. + CancelProxy, + /// Assets proxy. Can execute any call from `assets`, **including asset transfers**. + Assets, + /// Owner proxy. Can execute calls related to asset ownership. + AssetOwner, + /// Asset manager. Can execute calls related to asset management. + AssetManager, + /// Collator selection proxy. Can execute calls related to collator selection mechanism. + Collator, + } + impl Default for ProxyType { + fn default() -> Self { + Self::Any + } + } + + impl ProxyType { + pub fn is_superset(s: &ProxyType, o: &ProxyType) -> bool { + match (s, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::Assets, ProxyType::AssetOwner) => true, + (ProxyType::Assets, ProxyType::AssetManager) => true, + (ProxyType::NonTransfer, ProxyType::Collator) => true, + _ => false, + } + } + } +} diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 7976b1d0..55d9942d 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -47,6 +47,7 @@ pallet-scheduler.workspace = true pallet-session.workspace = true pallet-sudo.workspace = true pallet-preimage.workspace = true +pallet-proxy.workspace = true pallet-timestamp.workspace = true pallet-transaction-payment.workspace = true pallet-transaction-payment-rpc-runtime-api.workspace = true @@ -126,6 +127,7 @@ std = [ "pallet-session/std", "pallet-sudo/std", "pallet-preimage/std", + "pallet-proxy/std", "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", "pallet-transaction-payment/std", @@ -176,6 +178,7 @@ runtime-benchmarks = [ "pallet-scheduler/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", @@ -210,6 +213,7 @@ try-runtime = [ "pallet-session/try-runtime", "pallet-sudo/try-runtime", "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", "pallet-timestamp/try-runtime", "pallet-transaction-payment/try-runtime", "pallet-utility/try-runtime", diff --git a/runtime/devnet/src/assets_config.rs b/runtime/devnet/src/assets_config.rs index f2acffb0..34035c1f 100644 --- a/runtime/devnet/src/assets_config.rs +++ b/runtime/devnet/src/assets_config.rs @@ -96,6 +96,7 @@ impl pallet_nft_fractionalization::Config for Runtime { } pub type TrustBackedAssets = pallet_assets::Instance1; +pub type TrustBackedAssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index ec21432c..95af3a5f 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -9,6 +9,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod assets_config; mod contracts_config; mod extensions; +mod proxy_config; mod weights; pub mod xcm_config; @@ -622,6 +623,8 @@ construct_runtime!( // Contracts Contracts: pallet_contracts = 40, + // Proxy + Proxy: pallet_proxy = 41, // Multisig Multisig: pallet_multisig = 42, // Utility diff --git a/runtime/devnet/src/proxy_config.rs b/runtime/devnet/src/proxy_config.rs new file mode 100644 index 00000000..fad05383 --- /dev/null +++ b/runtime/devnet/src/proxy_config.rs @@ -0,0 +1,109 @@ +use crate::{assets_config::TrustBackedAssetsCall, Balances, Runtime, RuntimeCall, RuntimeEvent}; +use sp_runtime::traits::BlakeTwo256; + +use frame_support::traits::InstanceFilter; +use pop_runtime_common::proxy::{ + AnnouncementDepositBase, AnnouncementDepositFactor, MaxPending, MaxProxies, ProxyDepositBase, + ProxyDepositFactor, ProxyType, +}; + +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => !matches!( + c, + RuntimeCall::Balances { .. } + | RuntimeCall::Assets { .. } + | RuntimeCall::Nfts { .. } + ), + ProxyType::CancelProxy => matches!( + c, + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + ProxyType::Assets => { + matches!( + c, + RuntimeCall::Assets { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + | RuntimeCall::Nfts { .. } + ) + }, + ProxyType::AssetOwner => matches!( + c, + RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + ProxyType::AssetManager => matches!( + c, + RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + ProxyType::Collator => matches!( + c, + RuntimeCall::CollatorSelection { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + } + } + + fn is_superset(&self, o: &Self) -> bool { + ProxyType::is_superset(self, o) + } +} + +impl pallet_proxy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = pallet_proxy::weights::SubstrateWeight; + type MaxPending = MaxPending; + type CallHasher = BlakeTwo256; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +} diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index b215e67e..d68bfd15 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -47,6 +47,7 @@ pallet-scheduler.workspace = true pallet-session.workspace = true pallet-sudo.workspace = true pallet-preimage.workspace = true +pallet-proxy.workspace = true pallet-timestamp.workspace = true pallet-transaction-payment.workspace = true pallet-transaction-payment-rpc-runtime-api.workspace = true @@ -126,6 +127,7 @@ std = [ "pallet-session/std", "pallet-sudo/std", "pallet-preimage/std", + "pallet-proxy/std", "pallet-timestamp/std", "pallet-transaction-payment-rpc-runtime-api/std", "pallet-transaction-payment/std", @@ -176,6 +178,7 @@ runtime-benchmarks = [ "pallet-scheduler/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", @@ -210,6 +213,7 @@ try-runtime = [ "pallet-session/try-runtime", "pallet-sudo/try-runtime", "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", "pallet-timestamp/try-runtime", "pallet-transaction-payment/try-runtime", "pallet-utility/try-runtime", diff --git a/runtime/testnet/src/assets_config.rs b/runtime/testnet/src/assets_config.rs index f2acffb0..34035c1f 100644 --- a/runtime/testnet/src/assets_config.rs +++ b/runtime/testnet/src/assets_config.rs @@ -96,6 +96,7 @@ impl pallet_nft_fractionalization::Config for Runtime { } pub type TrustBackedAssets = pallet_assets::Instance1; +pub type TrustBackedAssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index ec21432c..95af3a5f 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -9,6 +9,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod assets_config; mod contracts_config; mod extensions; +mod proxy_config; mod weights; pub mod xcm_config; @@ -622,6 +623,8 @@ construct_runtime!( // Contracts Contracts: pallet_contracts = 40, + // Proxy + Proxy: pallet_proxy = 41, // Multisig Multisig: pallet_multisig = 42, // Utility diff --git a/runtime/testnet/src/proxy_config.rs b/runtime/testnet/src/proxy_config.rs new file mode 100644 index 00000000..fad05383 --- /dev/null +++ b/runtime/testnet/src/proxy_config.rs @@ -0,0 +1,109 @@ +use crate::{assets_config::TrustBackedAssetsCall, Balances, Runtime, RuntimeCall, RuntimeEvent}; +use sp_runtime::traits::BlakeTwo256; + +use frame_support::traits::InstanceFilter; +use pop_runtime_common::proxy::{ + AnnouncementDepositBase, AnnouncementDepositFactor, MaxPending, MaxProxies, ProxyDepositBase, + ProxyDepositFactor, ProxyType, +}; + +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => !matches!( + c, + RuntimeCall::Balances { .. } + | RuntimeCall::Assets { .. } + | RuntimeCall::Nfts { .. } + ), + ProxyType::CancelProxy => matches!( + c, + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + ProxyType::Assets => { + matches!( + c, + RuntimeCall::Assets { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + | RuntimeCall::Nfts { .. } + ) + }, + ProxyType::AssetOwner => matches!( + c, + RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + ProxyType::AssetManager => matches!( + c, + RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) + | RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + ProxyType::Collator => matches!( + c, + RuntimeCall::CollatorSelection { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + ), + } + } + + fn is_superset(&self, o: &Self) -> bool { + ProxyType::is_superset(self, o) + } +} + +impl pallet_proxy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = pallet_proxy::weights::SubstrateWeight; + type MaxPending = MaxPending; + type CallHasher = BlakeTwo256; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +}