diff --git a/Cargo.lock b/Cargo.lock index 081d27187..f91ef557a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4244,6 +4244,7 @@ dependencies = [ "pallet-membership", "pallet-multisig", "pallet-preimage", + "pallet-proxy", "pallet-registry", "pallet-scheduler", "pallet-subtensor", @@ -4613,6 +4614,21 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-proxy" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-registry" version = "4.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index d559d12b2..e7917c27b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,8 @@ members = [ "integration-tests", "node", - "pallets/subtensor", "pallets/commitments", + "pallets/subtensor", "runtime", ] resolver = "2" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index cad2e98d9..df986d173 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -60,6 +60,9 @@ pallet-membership = { version = "4.0.0-dev", default-features = false, git = "ht # Multisig pallet-multisig = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } +# Proxy Pallet +pallet-proxy = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } + # Scheduler pallet pallet-scheduler = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } pallet-preimage = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" } @@ -106,6 +109,7 @@ std = [ "pallet-utility/std", "pallet-sudo/std", "pallet-multisig/std", + "pallet-proxy/std", "pallet-scheduler/std", "pallet-preimage/std", "pallet-commitments/std", @@ -139,6 +143,7 @@ runtime-benchmarks = [ "pallet-subtensor/runtime-benchmarks", "pallet-collective/runtime-benchmarks", "pallet-membership/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", "pallet-registry/runtime-benchmarks", "pallet-commitments/runtime-benchmarks", "pallet-admin-utils/runtime-benchmarks", @@ -159,6 +164,7 @@ try-runtime = [ "pallet-subtensor/try-runtime", "pallet-collective/try-runtime", "pallet-membership/try-runtime", + "pallet-proxy/try-runtime", "pallet-multisig/try-runtime", "pallet-scheduler/try-runtime", "pallet-preimage/try-runtime", diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 10bfd237b..ef3703ad0 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -6,7 +6,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use codec::Encode; +use codec::{Decode, Encode, MaxEncodedLen}; use pallet_commitments::CanCommit; use pallet_grandpa::{ @@ -17,6 +17,7 @@ use frame_support::pallet_prelude::{DispatchError, DispatchResult, Get}; use frame_system::{EnsureNever, EnsureRoot, RawOrigin}; use pallet_registry::CanRegisterIdentity; +use scale_info::TypeInfo; use smallvec::smallvec; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -40,8 +41,8 @@ use sp_version::RuntimeVersion; pub use frame_support::{ construct_runtime, parameter_types, traits::{ - ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, KeyOwnerProofSystem, PrivilegeCmp, - Randomness, StorageInfo, + ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, InstanceFilter, KeyOwnerProofSystem, + PrivilegeCmp, Randomness, StorageInfo, }, weights::{ constants::{ @@ -50,7 +51,7 @@ pub use frame_support::{ IdentityFee, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }, - StorageValue, + RuntimeDebug, StorageValue, }; pub use frame_system::Call as SystemCall; pub use pallet_balances::Call as BalancesCall; @@ -87,6 +88,13 @@ type MemberCount = u32; pub type Nonce = u32; +// Method used to calculate the fee of an extrinsic +pub const fn deposit(items: u32, bytes: u32) -> Balance { + pub const ITEMS_FEE: Balance = 2_000 * 10_000; + pub const BYTES_FEE: Balance = 100 * 10_000; + items as Balance * ITEMS_FEE + bytes as Balance * BYTES_FEE +} + // Opaque types. These are used by the CLI to instantiate machinery that don't need to know // the specifics of the runtime. They can then be made to be agnostic over specific formats // of data like extrinsics, allowing for them to continue syncing the network through upgrades @@ -472,10 +480,13 @@ impl pallet_sudo::Config for Runtime { } parameter_types! { - // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. - pub const DepositBase: Balance = (1) as Balance * 2_000 * 10_000 + (88 as Balance) * 100 * 10_000; + // According to multisig pallet, key and value size be computed as follows: + // value size is `4 + sizeof((BlockNumber, Balance, AccountId))` bytes + // key size is `32 + sizeof(AccountId)` bytes. + // For our case, One storage item; key size is 32+32=64 bytes; value is size 4+4+8+32 bytes = 48 bytes. + pub const DepositBase: Balance = deposit(1, 112); // Additional storage item size of 32 bytes. - pub const DepositFactor: Balance = (0) as Balance * 2_000 * 10_000 + (32 as Balance) * 100 * 10_000; + pub const DepositFactor: Balance = deposit(0, 32); pub const MaxSignatories: u32 = 100; } @@ -489,6 +500,121 @@ impl pallet_multisig::Config for Runtime { type WeightInfo = pallet_multisig::weights::SubstrateWeight; } +// Proxy Pallet config +parameter_types! { + // One storage item; key size sizeof(AccountId) = 32, value sizeof(Balance) = 8; 40 total + pub const ProxyDepositBase: Balance = deposit(1, 40); + // Adding 32 bytes + sizeof(ProxyType) = 32 + 1 + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u32 = 20; // max num proxies per acct + pub const MaxPending: u32 = 15 * 5; // max blocks pending ~15min + // 16 bytes + pub const AnnouncementDepositBase: Balance = deposit(1, 16); + // 68 bytes per announcement + pub const AnnouncementDepositFactor: Balance = deposit(0, 68); +} + +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + RuntimeDebug, + MaxEncodedLen, + TypeInfo, +)] +pub enum ProxyType { + Any, + Owner, // Subnet owner Calls + NonCritical, + NonTransfer, + Senate, + NonFungibile, // Nothing involving moving TAO + Triumvirate, + Governance, // Both above governance + Staking, + Registration, +} +impl Default for ProxyType { + fn default() -> Self { + Self::Any + } +} // allow all Calls; required to be most permissive +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances(..)), + ProxyType::NonFungibile => !matches!( + c, + RuntimeCall::Balances(..) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::remove_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::burned_register { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::root_register { .. }) + ), + ProxyType::Owner => matches!(c, RuntimeCall::AdminUtils(..)), + ProxyType::NonCritical => !matches!( + c, + RuntimeCall::SubtensorModule(pallet_subtensor::Call::dissolve_network { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::root_register { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::burned_register { .. }) + | RuntimeCall::Triumvirate(..) + ), + ProxyType::Triumvirate => matches!( + c, + RuntimeCall::Triumvirate(..) | RuntimeCall::TriumvirateMembers(..) + ), + ProxyType::Senate => matches!(c, RuntimeCall::SenateMembers(..)), + ProxyType::Governance => matches!( + c, + RuntimeCall::SenateMembers(..) + | RuntimeCall::Triumvirate(..) + | RuntimeCall::TriumvirateMembers(..) + ), + ProxyType::Staking => matches!( + c, + RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::remove_stake { .. }) + ), + ProxyType::Registration => matches!( + c, + RuntimeCall::SubtensorModule(pallet_subtensor::Call::burned_register { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::register { .. }) + ), + } + } + fn is_superset(&self, o: &Self) -> bool { + match (self, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::NonTransfer, _) => true, + (ProxyType::Governance, ProxyType::Triumvirate | ProxyType::Senate) => true, + _ => false, + } + } +} + +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; +} + parameter_types! { pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; @@ -540,8 +666,8 @@ impl pallet_scheduler::Config for Runtime { parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; - pub const PreimageBaseDeposit: Balance = (2) as Balance * 2_000 * 10_000_000 + (64 as Balance) * 100 * 1_000_000; - pub const PreimageByteDeposit: Balance = (0) as Balance * 2_000 * 10_000_000 + (1 as Balance) * 100 * 1_000_000; + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); } impl pallet_preimage::Config for Runtime { @@ -991,6 +1117,7 @@ construct_runtime!( Multisig: pallet_multisig, Preimage: pallet_preimage, Scheduler: pallet_scheduler, + Proxy: pallet_proxy, Registry: pallet_registry, Commitments: pallet_commitments, AdminUtils: pallet_admin_utils